| /* |
| * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #include "webrtc/system_wrappers/source/condition_variable_posix.h" |
| |
| #include <errno.h> |
| #if defined(WEBRTC_LINUX) |
| #include <time.h> |
| #else |
| #include <sys/time.h> |
| #endif |
| |
| #include "webrtc/system_wrappers/source/critical_section_posix.h" |
| |
| namespace webrtc { |
| |
| ConditionVariableWrapper* ConditionVariablePosix::Create() { |
| ConditionVariablePosix* ptr = new ConditionVariablePosix; |
| if (!ptr) { |
| return NULL; |
| } |
| |
| const int error = ptr->Construct(); |
| if (error) { |
| delete ptr; |
| return NULL; |
| } |
| |
| return ptr; |
| } |
| |
| ConditionVariablePosix::ConditionVariablePosix() { |
| } |
| |
| int ConditionVariablePosix::Construct() { |
| #ifdef WEBRTC_CLOCK_TYPE_REALTIME |
| pthread_cond_init(&cond_, NULL); |
| #else |
| int result = 0; |
| pthread_condattr_t cond_attr; |
| result = pthread_condattr_init(&cond_attr); |
| if (result != 0) { |
| return -1; |
| } |
| result = pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC); |
| if (result != 0) { |
| return -1; |
| } |
| result = pthread_cond_init(&cond_, &cond_attr); |
| if (result != 0) { |
| return -1; |
| } |
| result = pthread_condattr_destroy(&cond_attr); |
| if (result != 0) { |
| return -1; |
| } |
| #endif |
| return 0; |
| } |
| |
| ConditionVariablePosix::~ConditionVariablePosix() { |
| pthread_cond_destroy(&cond_); |
| } |
| |
| void ConditionVariablePosix::SleepCS(CriticalSectionWrapper& crit_sect) { |
| CriticalSectionPosix* cs = reinterpret_cast<CriticalSectionPosix*>( |
| &crit_sect); |
| pthread_cond_wait(&cond_, &cs->mutex_); |
| } |
| |
| bool ConditionVariablePosix::SleepCS(CriticalSectionWrapper& crit_sect, |
| unsigned long max_time_inMS) { |
| const unsigned long INFINITE = 0xFFFFFFFF; |
| const int MILLISECONDS_PER_SECOND = 1000; |
| #ifndef WEBRTC_LINUX |
| const int MICROSECONDS_PER_MILLISECOND = 1000; |
| #endif |
| const int NANOSECONDS_PER_SECOND = 1000000000; |
| const int NANOSECONDS_PER_MILLISECOND = 1000000; |
| |
| CriticalSectionPosix* cs = reinterpret_cast<CriticalSectionPosix*>( |
| &crit_sect); |
| |
| if (max_time_inMS != INFINITE) { |
| timespec ts; |
| #ifndef WEBRTC_MAC |
| #ifdef WEBRTC_CLOCK_TYPE_REALTIME |
| clock_gettime(CLOCK_REALTIME, &ts); |
| #else |
| clock_gettime(CLOCK_MONOTONIC, &ts); |
| #endif |
| #else // WEBRTC_MAC |
| struct timeval tv; |
| gettimeofday(&tv, 0); |
| ts.tv_sec = tv.tv_sec; |
| ts.tv_nsec = tv.tv_usec * MICROSECONDS_PER_MILLISECOND; |
| #endif |
| |
| ts.tv_sec += max_time_inMS / MILLISECONDS_PER_SECOND; |
| ts.tv_nsec += |
| (max_time_inMS |
| - ((max_time_inMS / MILLISECONDS_PER_SECOND) * MILLISECONDS_PER_SECOND)) |
| * NANOSECONDS_PER_MILLISECOND; |
| |
| if (ts.tv_nsec >= NANOSECONDS_PER_SECOND) { |
| ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND; |
| ts.tv_nsec %= NANOSECONDS_PER_SECOND; |
| } |
| const int res = pthread_cond_timedwait(&cond_, &cs->mutex_, &ts); |
| return (res == ETIMEDOUT) ? false : true; |
| } else { |
| pthread_cond_wait(&cond_, &cs->mutex_); |
| return true; |
| } |
| } |
| |
| void ConditionVariablePosix::Wake() { |
| pthread_cond_signal(&cond_); |
| } |
| |
| void ConditionVariablePosix::WakeAll() { |
| pthread_cond_broadcast(&cond_); |
| } |
| |
| } // namespace webrtc |