blob: b21304245cd832d70ff33c23ee2403327c2f076f [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
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
pbos@webrtc.orgacaf3a12013-05-27 15:07:45 +000011#include "webrtc/system_wrappers/source/condition_variable_posix.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +000013#include <errno.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000014#if defined(WEBRTC_LINUX)
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000015#include <time.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000016#else
17#include <sys/time.h>
18#endif
19
pbos@webrtc.orgacaf3a12013-05-27 15:07:45 +000020#include "webrtc/system_wrappers/source/critical_section_posix.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000021
22namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000023
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +000024ConditionVariableWrapper* ConditionVariablePosix::Create() {
25 ConditionVariablePosix* ptr = new ConditionVariablePosix;
26 if (!ptr) {
27 return NULL;
28 }
niklase@google.com470e71d2011-07-07 08:21:25 +000029
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +000030 const int error = ptr->Construct();
31 if (error) {
32 delete ptr;
33 return NULL;
34 }
35
36 return ptr;
niklase@google.com470e71d2011-07-07 08:21:25 +000037}
38
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +000039ConditionVariablePosix::ConditionVariablePosix() {
niklase@google.com470e71d2011-07-07 08:21:25 +000040}
41
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +000042int ConditionVariablePosix::Construct() {
niklase@google.com470e71d2011-07-07 08:21:25 +000043#ifdef WEBRTC_CLOCK_TYPE_REALTIME
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +000044 pthread_cond_init(&cond_, NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +000045#else
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +000046 int result = 0;
47 pthread_condattr_t cond_attr;
48 result = pthread_condattr_init(&cond_attr);
49 if (result != 0) {
50 return -1;
51 }
52 result = pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
53 if (result != 0) {
54 return -1;
55 }
56 result = pthread_cond_init(&cond_, &cond_attr);
57 if (result != 0) {
58 return -1;
59 }
60 result = pthread_condattr_destroy(&cond_attr);
61 if (result != 0) {
62 return -1;
63 }
niklase@google.com470e71d2011-07-07 08:21:25 +000064#endif
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +000065 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000066}
67
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +000068ConditionVariablePosix::~ConditionVariablePosix() {
69 pthread_cond_destroy(&cond_);
niklase@google.com470e71d2011-07-07 08:21:25 +000070}
71
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +000072void ConditionVariablePosix::SleepCS(CriticalSectionWrapper& crit_sect) {
73 CriticalSectionPosix* cs = reinterpret_cast<CriticalSectionPosix*>(
74 &crit_sect);
phoglund@webrtc.org99f7c912012-11-30 10:44:49 +000075 pthread_cond_wait(&cond_, &cs->mutex_);
niklase@google.com470e71d2011-07-07 08:21:25 +000076}
77
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +000078bool ConditionVariablePosix::SleepCS(CriticalSectionWrapper& crit_sect,
79 unsigned long max_time_inMS) {
80 const unsigned long INFINITE = 0xFFFFFFFF;
81 const int MILLISECONDS_PER_SECOND = 1000;
niklase@google.com470e71d2011-07-07 08:21:25 +000082#ifndef WEBRTC_LINUX
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +000083 const int MICROSECONDS_PER_MILLISECOND = 1000;
niklase@google.com470e71d2011-07-07 08:21:25 +000084#endif
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +000085 const int NANOSECONDS_PER_SECOND = 1000000000;
86 const int NANOSECONDS_PER_MILLISECOND = 1000000;
niklase@google.com470e71d2011-07-07 08:21:25 +000087
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +000088 CriticalSectionPosix* cs = reinterpret_cast<CriticalSectionPosix*>(
89 &crit_sect);
niklase@google.com470e71d2011-07-07 08:21:25 +000090
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +000091 if (max_time_inMS != INFINITE) {
92 timespec ts;
niklase@google.com470e71d2011-07-07 08:21:25 +000093#ifndef WEBRTC_MAC
94#ifdef WEBRTC_CLOCK_TYPE_REALTIME
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +000095 clock_gettime(CLOCK_REALTIME, &ts);
niklase@google.com470e71d2011-07-07 08:21:25 +000096#else
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +000097 clock_gettime(CLOCK_MONOTONIC, &ts);
niklase@google.com470e71d2011-07-07 08:21:25 +000098#endif
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +000099#else // WEBRTC_MAC
100 struct timeval tv;
101 gettimeofday(&tv, 0);
102 ts.tv_sec = tv.tv_sec;
103 ts.tv_nsec = tv.tv_usec * MICROSECONDS_PER_MILLISECOND;
niklase@google.com470e71d2011-07-07 08:21:25 +0000104#endif
105
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +0000106 ts.tv_sec += max_time_inMS / MILLISECONDS_PER_SECOND;
107 ts.tv_nsec +=
108 (max_time_inMS
109 - ((max_time_inMS / MILLISECONDS_PER_SECOND) * MILLISECONDS_PER_SECOND))
110 * NANOSECONDS_PER_MILLISECOND;
niklase@google.com470e71d2011-07-07 08:21:25 +0000111
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +0000112 if (ts.tv_nsec >= NANOSECONDS_PER_SECOND) {
113 ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
114 ts.tv_nsec %= NANOSECONDS_PER_SECOND;
niklase@google.com470e71d2011-07-07 08:21:25 +0000115 }
phoglund@webrtc.org99f7c912012-11-30 10:44:49 +0000116 const int res = pthread_cond_timedwait(&cond_, &cs->mutex_, &ts);
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +0000117 return (res == ETIMEDOUT) ? false : true;
118 } else {
phoglund@webrtc.org99f7c912012-11-30 10:44:49 +0000119 pthread_cond_wait(&cond_, &cs->mutex_);
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +0000120 return true;
121 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000122}
123
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +0000124void ConditionVariablePosix::Wake() {
125 pthread_cond_signal(&cond_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000126}
127
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +0000128void ConditionVariablePosix::WakeAll() {
129 pthread_cond_broadcast(&cond_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000130}
phoglund@webrtc.orga36d75a2012-11-14 09:55:04 +0000131
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000132} // namespace webrtc