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