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