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