OLD | NEW |
| (Empty) |
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 "webrtc/system_wrappers/source/condition_variable_posix.h" | |
12 | |
13 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | |
14 | |
15 #include <errno.h> | |
16 #if defined(WEBRTC_LINUX) | |
17 #include <time.h> | |
18 #else | |
19 #include <sys/time.h> | |
20 #endif | |
21 | |
22 namespace webrtc { | |
23 | |
24 ConditionVariableWrapper* ConditionVariablePosix::Create() { | |
25 ConditionVariablePosix* ptr = new ConditionVariablePosix; | |
26 if (!ptr) { | |
27 return NULL; | |
28 } | |
29 | |
30 const int error = ptr->Construct(); | |
31 if (error) { | |
32 delete ptr; | |
33 return NULL; | |
34 } | |
35 | |
36 return ptr; | |
37 } | |
38 | |
39 ConditionVariablePosix::ConditionVariablePosix() { | |
40 } | |
41 | |
42 int ConditionVariablePosix::Construct() { | |
43 #ifdef WEBRTC_CLOCK_TYPE_REALTIME | |
44 pthread_cond_init(&cond_, NULL); | |
45 #else | |
46 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 } | |
64 #endif | |
65 return 0; | |
66 } | |
67 | |
68 ConditionVariablePosix::~ConditionVariablePosix() { | |
69 pthread_cond_destroy(&cond_); | |
70 } | |
71 | |
72 void ConditionVariablePosix::SleepCS(CriticalSectionWrapper& crit_sect) { | |
73 pthread_cond_wait(&cond_, &crit_sect.mutex_); | |
74 } | |
75 | |
76 bool ConditionVariablePosix::SleepCS(CriticalSectionWrapper& crit_sect, | |
77 unsigned long max_time_inMS) { | |
78 const unsigned long INFINITE = 0xFFFFFFFF; | |
79 const int MILLISECONDS_PER_SECOND = 1000; | |
80 #ifndef WEBRTC_LINUX | |
81 const int MICROSECONDS_PER_MILLISECOND = 1000; | |
82 #endif | |
83 const int NANOSECONDS_PER_SECOND = 1000000000; | |
84 const int NANOSECONDS_PER_MILLISECOND = 1000000; | |
85 | |
86 if (max_time_inMS != INFINITE) { | |
87 timespec ts; | |
88 #ifndef WEBRTC_MAC | |
89 #ifdef WEBRTC_CLOCK_TYPE_REALTIME | |
90 clock_gettime(CLOCK_REALTIME, &ts); | |
91 #else | |
92 clock_gettime(CLOCK_MONOTONIC, &ts); | |
93 #endif | |
94 #else // WEBRTC_MAC | |
95 struct timeval tv; | |
96 gettimeofday(&tv, 0); | |
97 ts.tv_sec = tv.tv_sec; | |
98 ts.tv_nsec = tv.tv_usec * MICROSECONDS_PER_MILLISECOND; | |
99 #endif | |
100 | |
101 ts.tv_sec += max_time_inMS / MILLISECONDS_PER_SECOND; | |
102 ts.tv_nsec += | |
103 (max_time_inMS | |
104 - ((max_time_inMS / MILLISECONDS_PER_SECOND) * MILLISECONDS_PER_SECOND)) | |
105 * NANOSECONDS_PER_MILLISECOND; | |
106 | |
107 if (ts.tv_nsec >= NANOSECONDS_PER_SECOND) { | |
108 ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND; | |
109 ts.tv_nsec %= NANOSECONDS_PER_SECOND; | |
110 } | |
111 const int res = pthread_cond_timedwait(&cond_, &crit_sect.mutex_, &ts); | |
112 return (res == ETIMEDOUT) ? false : true; | |
113 } else { | |
114 pthread_cond_wait(&cond_, &crit_sect.mutex_); | |
115 return true; | |
116 } | |
117 } | |
118 | |
119 void ConditionVariablePosix::Wake() { | |
120 pthread_cond_signal(&cond_); | |
121 } | |
122 | |
123 void ConditionVariablePosix::WakeAll() { | |
124 pthread_cond_broadcast(&cond_); | |
125 } | |
126 | |
127 } // namespace webrtc | |
OLD | NEW |