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