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