Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /*
     18  *  Encapsulate a condition variable for thread synchronization.
     19  */
     20 
     21 #include "CondVar.h"
     22 #include "NfcJniUtil.h"
     23 
     24 #include <cutils/log.h>
     25 #include <errno.h>
     26 
     27 
     28 /*******************************************************************************
     29 **
     30 ** Function:        CondVar
     31 **
     32 ** Description:     Initialize member variables.
     33 **
     34 ** Returns:         None.
     35 **
     36 *******************************************************************************/
     37 CondVar::CondVar ()
     38 {
     39     pthread_condattr_t attr;
     40     pthread_condattr_init(&attr);
     41     pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
     42     memset (&mCondition, 0, sizeof(mCondition));
     43     int const res = pthread_cond_init (&mCondition, &attr);
     44     if (res)
     45     {
     46         ALOGE ("CondVar::CondVar: fail init; error=0x%X", res);
     47     }
     48 }
     49 
     50 
     51 /*******************************************************************************
     52 **
     53 ** Function:        ~CondVar
     54 **
     55 ** Description:     Cleanup all resources.
     56 **
     57 ** Returns:         None.
     58 **
     59 *******************************************************************************/
     60 CondVar::~CondVar ()
     61 {
     62     int const res = pthread_cond_destroy (&mCondition);
     63     if (res)
     64     {
     65         ALOGE ("CondVar::~CondVar: fail destroy; error=0x%X", res);
     66     }
     67 }
     68 
     69 
     70 /*******************************************************************************
     71 **
     72 ** Function:        wait
     73 **
     74 ** Description:     Block the caller and wait for a condition.
     75 **
     76 ** Returns:         None.
     77 **
     78 *******************************************************************************/
     79 void CondVar::wait (Mutex& mutex)
     80 {
     81     int const res = pthread_cond_wait (&mCondition, mutex.nativeHandle());
     82     if (res)
     83     {
     84         ALOGE ("CondVar::wait: fail wait; error=0x%X", res);
     85     }
     86 }
     87 
     88 
     89 /*******************************************************************************
     90 **
     91 ** Function:        wait
     92 **
     93 ** Description:     Block the caller and wait for a condition.
     94 **                  millisec: Timeout in milliseconds.
     95 **
     96 ** Returns:         True if wait is successful; false if timeout occurs.
     97 **
     98 *******************************************************************************/
     99 bool CondVar::wait (Mutex& mutex, long millisec)
    100 {
    101     bool retVal = false;
    102     struct timespec absoluteTime;
    103 
    104     if (clock_gettime (CLOCK_MONOTONIC, &absoluteTime) == -1)
    105     {
    106         ALOGE ("CondVar::wait: fail get time; errno=0x%X", errno);
    107     }
    108     else
    109     {
    110         absoluteTime.tv_sec += millisec / 1000;
    111         long ns = absoluteTime.tv_nsec + ((millisec % 1000) * 1000000);
    112         if (ns > 1000000000)
    113         {
    114             absoluteTime.tv_sec++;
    115             absoluteTime.tv_nsec = ns - 1000000000;
    116         }
    117         else
    118             absoluteTime.tv_nsec = ns;
    119     }
    120 
    121     int waitResult = pthread_cond_timedwait (&mCondition, mutex.nativeHandle(), &absoluteTime);
    122     if ((waitResult != 0) && (waitResult != ETIMEDOUT))
    123         ALOGE ("CondVar::wait: fail timed wait; error=0x%X", waitResult);
    124     retVal = (waitResult == 0); //waited successfully
    125     return retVal;
    126 }
    127 
    128 
    129 /*******************************************************************************
    130 **
    131 ** Function:        notifyOne
    132 **
    133 ** Description:     Unblock the waiting thread.
    134 **
    135 ** Returns:         None.
    136 **
    137 *******************************************************************************/
    138 void CondVar::notifyOne ()
    139 {
    140     int const res = pthread_cond_signal (&mCondition);
    141     if (res)
    142     {
    143         ALOGE ("CondVar::notifyOne: fail signal; error=0x%X", res);
    144     }
    145 }
    146 
    147