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 #include <errno.h> 24 25 26 /******************************************************************************* 27 ** 28 ** Function: CondVar 29 ** 30 ** Description: Initialize member variables. 31 ** 32 ** Returns: None. 33 ** 34 *******************************************************************************/ 35 CondVar::CondVar () 36 { 37 memset (&mCondition, 0, sizeof(mCondition)); 38 int const res = pthread_cond_init (&mCondition, NULL); 39 if (res) 40 { 41 ALOGE ("CondVar::CondVar: fail init; error=0x%X", res); 42 } 43 } 44 45 46 /******************************************************************************* 47 ** 48 ** Function: ~CondVar 49 ** 50 ** Description: Cleanup all resources. 51 ** 52 ** Returns: None. 53 ** 54 *******************************************************************************/ 55 CondVar::~CondVar () 56 { 57 int const res = pthread_cond_destroy (&mCondition); 58 if (res) 59 { 60 ALOGE ("CondVar::~CondVar: fail destroy; error=0x%X", res); 61 } 62 } 63 64 65 /******************************************************************************* 66 ** 67 ** Function: wait 68 ** 69 ** Description: Block the caller and wait for a condition. 70 ** 71 ** Returns: None. 72 ** 73 *******************************************************************************/ 74 void CondVar::wait (Mutex& mutex) 75 { 76 int const res = pthread_cond_wait (&mCondition, mutex.nativeHandle()); 77 if (res) 78 { 79 ALOGE ("CondVar::wait: fail wait; error=0x%X", res); 80 } 81 } 82 83 84 /******************************************************************************* 85 ** 86 ** Function: wait 87 ** 88 ** Description: Block the caller and wait for a condition. 89 ** millisec: Timeout in milliseconds. 90 ** 91 ** Returns: True if wait is successful; false if timeout occurs. 92 ** 93 *******************************************************************************/ 94 bool CondVar::wait (Mutex& mutex, long millisec) 95 { 96 bool retVal = false; 97 struct timespec absoluteTime; 98 99 if (clock_gettime (CLOCK_MONOTONIC, &absoluteTime) == -1) 100 { 101 ALOGE ("CondVar::wait: fail get time; errno=0x%X", errno); 102 } 103 else 104 { 105 absoluteTime.tv_sec += millisec / 1000; 106 long ns = absoluteTime.tv_nsec + ((millisec % 1000) * 1000000); 107 if (ns > 1000000000) 108 { 109 absoluteTime.tv_sec++; 110 absoluteTime.tv_nsec = ns - 1000000000; 111 } 112 else 113 absoluteTime.tv_nsec = ns; 114 } 115 116 //pthread_cond_timedwait_monotonic_np() is an Android-specific function 117 //declared in /development/ndk/platforms/android-9/include/pthread.h; 118 //it uses monotonic clock. 119 //the standard pthread_cond_timedwait() uses realtime clock. 120 int waitResult = pthread_cond_timedwait_monotonic_np (&mCondition, mutex.nativeHandle(), &absoluteTime); 121 if ((waitResult != 0) && (waitResult != ETIMEDOUT)) 122 ALOGE ("CondVar::wait: fail timed wait; error=0x%X", waitResult); 123 retVal = (waitResult == 0); //waited successfully 124 return retVal; 125 } 126 127 128 /******************************************************************************* 129 ** 130 ** Function: notifyOne 131 ** 132 ** Description: Unblock the waiting thread. 133 ** 134 ** Returns: None. 135 ** 136 *******************************************************************************/ 137 void CondVar::notifyOne () 138 { 139 int const res = pthread_cond_signal (&mCondition); 140 if (res) 141 { 142 ALOGE ("CondVar::notifyOne: fail signal; error=0x%X", res); 143 } 144 } 145 146