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