• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /*
18  *  Encapsulate a condition variable for thread synchronization.
19  */
20 
21 #include "CondVar.h"
22 #include "NfcJniUtil.h"
23 
24 #include <cutils/log.h>
25 #include <errno.h>
26 
27 
28 /*******************************************************************************
29 **
30 ** Function:        CondVar
31 **
32 ** Description:     Initialize member variables.
33 **
34 ** Returns:         None.
35 **
36 *******************************************************************************/
CondVar()37 CondVar::CondVar ()
38 {
39     memset (&mCondition, 0, sizeof(mCondition));
40     int const res = pthread_cond_init (&mCondition, NULL);
41     if (res)
42     {
43         ALOGE ("CondVar::CondVar: fail init; error=0x%X", res);
44     }
45 }
46 
47 
48 /*******************************************************************************
49 **
50 ** Function:        ~CondVar
51 **
52 ** Description:     Cleanup all resources.
53 **
54 ** Returns:         None.
55 **
56 *******************************************************************************/
~CondVar()57 CondVar::~CondVar ()
58 {
59     int const res = pthread_cond_destroy (&mCondition);
60     if (res)
61     {
62         ALOGE ("CondVar::~CondVar: fail destroy; error=0x%X", res);
63     }
64 }
65 
66 
67 /*******************************************************************************
68 **
69 ** Function:        wait
70 **
71 ** Description:     Block the caller and wait for a condition.
72 **
73 ** Returns:         None.
74 **
75 *******************************************************************************/
wait(Mutex & mutex)76 void CondVar::wait (Mutex& mutex)
77 {
78     int const res = pthread_cond_wait (&mCondition, mutex.nativeHandle());
79     if (res)
80     {
81         ALOGE ("CondVar::wait: fail wait; error=0x%X", res);
82     }
83 }
84 
85 
86 /*******************************************************************************
87 **
88 ** Function:        wait
89 **
90 ** Description:     Block the caller and wait for a condition.
91 **                  millisec: Timeout in milliseconds.
92 **
93 ** Returns:         True if wait is successful; false if timeout occurs.
94 **
95 *******************************************************************************/
wait(Mutex & mutex,long millisec)96 bool CondVar::wait (Mutex& mutex, long millisec)
97 {
98     bool retVal = false;
99     struct timespec absoluteTime;
100 
101     if (clock_gettime (CLOCK_MONOTONIC, &absoluteTime) == -1)
102     {
103         ALOGE ("CondVar::wait: fail get time; errno=0x%X", errno);
104     }
105     else
106     {
107         absoluteTime.tv_sec += millisec / 1000;
108         long ns = absoluteTime.tv_nsec + ((millisec % 1000) * 1000000);
109         if (ns > 1000000000)
110         {
111             absoluteTime.tv_sec++;
112             absoluteTime.tv_nsec = ns - 1000000000;
113         }
114         else
115             absoluteTime.tv_nsec = ns;
116     }
117 
118     //pthread_cond_timedwait_monotonic_np() is an Android-specific function
119     //declared in /development/ndk/platforms/android-9/include/pthread.h;
120     //it uses monotonic clock.
121     //the standard pthread_cond_timedwait() uses realtime clock.
122     int waitResult = pthread_cond_timedwait_monotonic_np (&mCondition, mutex.nativeHandle(), &absoluteTime);
123     if ((waitResult != 0) && (waitResult != ETIMEDOUT))
124         ALOGE ("CondVar::wait: fail timed wait; error=0x%X", waitResult);
125     retVal = (waitResult == 0); //waited successfully
126     return retVal;
127 }
128 
129 
130 /*******************************************************************************
131 **
132 ** Function:        notifyOne
133 **
134 ** Description:     Unblock the waiting thread.
135 **
136 ** Returns:         None.
137 **
138 *******************************************************************************/
notifyOne()139 void CondVar::notifyOne ()
140 {
141     int const res = pthread_cond_signal (&mCondition);
142     if (res)
143     {
144         ALOGE ("CondVar::notifyOne: fail signal; error=0x%X", res);
145     }
146 }
147 
148