1/* 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include "condition_variable_posix.h" 12 13#if defined(WEBRTC_LINUX) 14#include <ctime> 15#else 16#include <sys/time.h> 17#endif 18 19#include <errno.h> 20 21#include "critical_section_posix.h" 22 23namespace webrtc { 24ConditionVariableWrapper* ConditionVariablePosix::Create() 25{ 26 ConditionVariablePosix* ptr = new ConditionVariablePosix; 27 if (!ptr) 28 { 29 return NULL; 30 } 31 32 const int error = ptr->Construct(); 33 if (error) 34 { 35 delete ptr; 36 return NULL; 37 } 38 39 return ptr; 40} 41 42ConditionVariablePosix::ConditionVariablePosix() 43{ 44} 45 46int ConditionVariablePosix::Construct() 47{ 48 int result = 0; 49#ifdef WEBRTC_CLOCK_TYPE_REALTIME 50 result = pthread_cond_init(&_cond, NULL); 51#else 52 pthread_condattr_t condAttr; 53 result = pthread_condattr_init(&condAttr); 54 if (result != 0) 55 { 56 return -1; 57 } 58 result = pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC); 59 if (result != 0) 60 { 61 return -1; 62 } 63 result = pthread_cond_init(&_cond, &condAttr); 64 if (result != 0) 65 { 66 return -1; 67 } 68 result = pthread_condattr_destroy(&condAttr); 69 if (result != 0) 70 { 71 return -1; 72 } 73#endif 74 return 0; 75} 76 77ConditionVariablePosix::~ConditionVariablePosix() 78{ 79 pthread_cond_destroy(&_cond); 80} 81 82void ConditionVariablePosix::SleepCS(CriticalSectionWrapper& critSect) 83{ 84 CriticalSectionPosix* cs = reinterpret_cast<CriticalSectionPosix*>( 85 &critSect); 86 pthread_cond_wait(&_cond, &cs->_mutex); 87} 88 89 90bool 91ConditionVariablePosix::SleepCS( 92 CriticalSectionWrapper& critSect, 93 unsigned long maxTimeInMS) 94{ 95 const unsigned long INFINITE = 0xFFFFFFFF; 96 97 const int MILLISECONDS_PER_SECOND = 1000; 98#ifndef WEBRTC_LINUX 99 const int MICROSECONDS_PER_MILLISECOND = 1000; 100#endif 101 const int NANOSECONDS_PER_SECOND = 1000000000; 102 const int NANOSECONDS_PER_MILLISECOND = 1000000; 103 104 CriticalSectionPosix* cs = reinterpret_cast<CriticalSectionPosix*>( 105 &critSect); 106 107 if (maxTimeInMS != INFINITE) 108 { 109 timespec ts; 110#ifndef WEBRTC_MAC 111#ifdef WEBRTC_CLOCK_TYPE_REALTIME 112 clock_gettime(CLOCK_REALTIME, &ts); 113#else 114 clock_gettime(CLOCK_MONOTONIC, &ts); 115#endif 116#else 117 struct timeval tv; 118 gettimeofday(&tv, 0); 119 ts.tv_sec = tv.tv_sec; 120 ts.tv_nsec = tv.tv_usec * MICROSECONDS_PER_MILLISECOND; 121#endif 122 123 ts.tv_sec += maxTimeInMS / MILLISECONDS_PER_SECOND; 124 ts.tv_nsec += (maxTimeInMS - ((maxTimeInMS / MILLISECONDS_PER_SECOND)* 125 MILLISECONDS_PER_SECOND)) * NANOSECONDS_PER_MILLISECOND; 126 127 if (ts.tv_nsec >= NANOSECONDS_PER_SECOND) 128 { 129 ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND; 130 ts.tv_nsec %= NANOSECONDS_PER_SECOND; 131 } 132 const int res = pthread_cond_timedwait(&_cond, &cs->_mutex, &ts); 133 return (res == ETIMEDOUT) ? false : true; 134 } 135 else 136 { 137 pthread_cond_wait(&_cond, &cs->_mutex); 138 return true; 139 } 140} 141 142void ConditionVariablePosix::Wake() 143{ 144 pthread_cond_signal(&_cond); 145} 146 147void ConditionVariablePosix::WakeAll() 148{ 149 pthread_cond_broadcast(&_cond); 150} 151} // namespace webrtc 152