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*******************************************************************************/ 39CondVar::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*******************************************************************************/ 59CondVar::~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*******************************************************************************/ 75void 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*******************************************************************************/ 92bool 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*******************************************************************************/ 125void 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