OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/base/platform_thread.h" | 11 #include "webrtc/base/platform_thread.h" |
12 | 12 |
13 #include "webrtc/base/atomicops.h" | |
13 #include "webrtc/base/checks.h" | 14 #include "webrtc/base/checks.h" |
14 | 15 |
15 #if defined(WEBRTC_LINUX) | 16 #if defined(WEBRTC_LINUX) |
16 #include <sys/prctl.h> | 17 #include <sys/prctl.h> |
17 #include <sys/syscall.h> | 18 #include <sys/syscall.h> |
18 #endif | 19 #endif |
19 | 20 |
20 namespace rtc { | 21 namespace rtc { |
21 | 22 |
22 PlatformThreadId CurrentThreadId() { | 23 PlatformThreadId CurrentThreadId() { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
89 pthread_attr_t attr; | 90 pthread_attr_t attr; |
90 }; | 91 }; |
91 #endif // defined(WEBRTC_WIN) | 92 #endif // defined(WEBRTC_WIN) |
92 } | 93 } |
93 | 94 |
94 PlatformThread::PlatformThread(ThreadRunFunction func, | 95 PlatformThread::PlatformThread(ThreadRunFunction func, |
95 void* obj, | 96 void* obj, |
96 const char* thread_name) | 97 const char* thread_name) |
97 : run_function_(func), | 98 : run_function_(func), |
98 obj_(obj), | 99 obj_(obj), |
99 name_(thread_name ? thread_name : "webrtc"), | 100 name_(thread_name ? thread_name : "webrtc") { |
100 #if defined(WEBRTC_WIN) | |
101 stop_(false), | |
102 thread_(NULL), | |
103 thread_id_(0) { | |
104 #else | |
105 stop_event_(false, false), | |
106 thread_(0) { | |
107 #endif // defined(WEBRTC_WIN) | |
108 RTC_DCHECK(func); | 101 RTC_DCHECK(func); |
109 RTC_DCHECK(name_.length() < 64); | 102 RTC_DCHECK(name_.length() < 64); |
110 } | 103 } |
111 | 104 |
112 PlatformThread::~PlatformThread() { | 105 PlatformThread::~PlatformThread() { |
113 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 106 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
114 #if defined(WEBRTC_WIN) | 107 #if defined(WEBRTC_WIN) |
115 RTC_DCHECK(!thread_); | 108 RTC_DCHECK(!thread_); |
116 RTC_DCHECK(!thread_id_); | 109 RTC_DCHECK(!thread_id_); |
117 #endif // defined(WEBRTC_WIN) | 110 #endif // defined(WEBRTC_WIN) |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
180 #if defined(WEBRTC_WIN) | 173 #if defined(WEBRTC_WIN) |
181 // Set stop_ to |true| on the worker thread. | 174 // Set stop_ to |true| on the worker thread. |
182 bool queued = QueueAPC(&RaiseFlag, reinterpret_cast<ULONG_PTR>(&stop_)); | 175 bool queued = QueueAPC(&RaiseFlag, reinterpret_cast<ULONG_PTR>(&stop_)); |
183 // Queuing the APC can fail if the thread is being terminated. | 176 // Queuing the APC can fail if the thread is being terminated. |
184 RTC_CHECK(queued || GetLastError() == ERROR_GEN_FAILURE); | 177 RTC_CHECK(queued || GetLastError() == ERROR_GEN_FAILURE); |
185 WaitForSingleObject(thread_, INFINITE); | 178 WaitForSingleObject(thread_, INFINITE); |
186 CloseHandle(thread_); | 179 CloseHandle(thread_); |
187 thread_ = nullptr; | 180 thread_ = nullptr; |
188 thread_id_ = 0; | 181 thread_id_ = 0; |
189 #else | 182 #else |
190 stop_event_.Set(); | 183 RTC_CHECK_EQ(1, AtomicOps::Increment(&stop_flag_)); |
191 RTC_CHECK_EQ(0, pthread_join(thread_, nullptr)); | 184 RTC_CHECK_EQ(0, pthread_join(thread_, nullptr)); |
185 AtomicOps::ReleaseStore(&stop_flag_, 0); | |
192 thread_ = 0; | 186 thread_ = 0; |
193 #endif // defined(WEBRTC_WIN) | 187 #endif // defined(WEBRTC_WIN) |
194 } | 188 } |
195 | 189 |
196 void PlatformThread::Run() { | 190 void PlatformThread::Run() { |
197 if (!name_.empty()) | 191 if (!name_.empty()) |
198 rtc::SetCurrentThreadName(name_.c_str()); | 192 rtc::SetCurrentThreadName(name_.c_str()); |
199 do { | 193 do { |
200 // The interface contract of Start/Stop is that for a successful call to | 194 // The interface contract of Start/Stop is that for a successful call to |
201 // Start, there should be at least one call to the run function. So we | 195 // Start, there should be at least one call to the run function. So we |
202 // call the function before checking |stop_|. | 196 // call the function before checking |stop_|. |
203 if (!run_function_(obj_)) | 197 if (!run_function_(obj_)) |
204 break; | 198 break; |
205 #if defined(WEBRTC_WIN) | 199 #if defined(WEBRTC_WIN) |
206 // Alertable sleep to permit RaiseFlag to run and update |stop_|. | 200 // Alertable sleep to permit RaiseFlag to run and update |stop_|. |
207 SleepEx(0, true); | 201 SleepEx(0, true); |
208 } while (!stop_); | 202 } while (!stop_); |
209 #else | 203 #else |
the sun
2017/02/18 23:18:25
Do we want to give up the reminder of our time sli
| |
210 } while (!stop_event_.Wait(0)); | 204 } while (!AtomicOps::AcquireLoad(&stop_flag_)); |
211 #endif // defined(WEBRTC_WIN) | 205 #endif // defined(WEBRTC_WIN) |
212 } | 206 } |
213 | 207 |
214 bool PlatformThread::SetPriority(ThreadPriority priority) { | 208 bool PlatformThread::SetPriority(ThreadPriority priority) { |
215 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 209 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
216 RTC_DCHECK(IsRunning()); | 210 RTC_DCHECK(IsRunning()); |
217 #if defined(WEBRTC_WIN) | 211 #if defined(WEBRTC_WIN) |
218 return SetThreadPriority(thread_, priority) != FALSE; | 212 return SetThreadPriority(thread_, priority) != FALSE; |
219 #elif defined(__native_client__) | 213 #elif defined(__native_client__) |
220 // Setting thread priorities is not supported in NaCl. | 214 // Setting thread priorities is not supported in NaCl. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
268 #if defined(WEBRTC_WIN) | 262 #if defined(WEBRTC_WIN) |
269 bool PlatformThread::QueueAPC(PAPCFUNC function, ULONG_PTR data) { | 263 bool PlatformThread::QueueAPC(PAPCFUNC function, ULONG_PTR data) { |
270 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 264 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
271 RTC_DCHECK(IsRunning()); | 265 RTC_DCHECK(IsRunning()); |
272 | 266 |
273 return QueueUserAPC(function, thread_, data) != FALSE; | 267 return QueueUserAPC(function, thread_, data) != FALSE; |
274 } | 268 } |
275 #endif | 269 #endif |
276 | 270 |
277 } // namespace rtc | 271 } // namespace rtc |
OLD | NEW |