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