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