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