Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(500)

Side by Side Diff: webrtc/base/platform_thread.cc

Issue 2708433002: Replace the stop_event_ in PlatformThread with an atomic flag (Closed)
Patch Set: Now hitting 'save' before committing the TODO Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
190 // TODO(tommi): Deprecate the loop behavior in PlatformThread.
191 // * Introduce a new callback type that returns void.
192 // * Remove potential for a busy loop in PlatformThread.
193 // * Delegate the responsibility for how to stop the thread, to the
194 // implementation that actually uses the thread.
195 // All implementations will need to be aware of how the thread should be stopped
196 // and encouraging a busy polling loop, can be costly in terms of power and cpu.
196 void PlatformThread::Run() { 197 void PlatformThread::Run() {
197 if (!name_.empty()) 198 if (!name_.empty())
198 rtc::SetCurrentThreadName(name_.c_str()); 199 rtc::SetCurrentThreadName(name_.c_str());
200 #if !defined(WEBRTC_MAC) && !defined(WEBRTC_WIN)
201 const struct timespec ts_null = {0};
202 #endif
199 do { 203 do {
200 // The interface contract of Start/Stop is that for a successful call to 204 // 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 205 // Start, there should be at least one call to the run function. So we
202 // call the function before checking |stop_|. 206 // call the function before checking |stop_|.
203 if (!run_function_(obj_)) 207 if (!run_function_(obj_))
204 break; 208 break;
205 #if defined(WEBRTC_WIN) 209 #if defined(WEBRTC_WIN)
206 // Alertable sleep to permit RaiseFlag to run and update |stop_|. 210 // Alertable sleep to permit RaiseFlag to run and update |stop_|.
207 SleepEx(0, true); 211 SleepEx(0, true);
208 } while (!stop_); 212 } while (!stop_);
209 #else 213 #else
210 } while (!stop_event_.Wait(0)); 214 #if defined(WEBRTC_MAC)
215 sched_yield();
216 #else
217 nanosleep(&ts_null, nullptr);
218 #endif
219 } while (!AtomicOps::AcquireLoad(&stop_flag_));
211 #endif // defined(WEBRTC_WIN) 220 #endif // defined(WEBRTC_WIN)
212 } 221 }
213 222
214 bool PlatformThread::SetPriority(ThreadPriority priority) { 223 bool PlatformThread::SetPriority(ThreadPriority priority) {
215 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 224 RTC_DCHECK(thread_checker_.CalledOnValidThread());
216 RTC_DCHECK(IsRunning()); 225 RTC_DCHECK(IsRunning());
217 #if defined(WEBRTC_WIN) 226 #if defined(WEBRTC_WIN)
218 return SetThreadPriority(thread_, priority) != FALSE; 227 return SetThreadPriority(thread_, priority) != FALSE;
219 #elif defined(__native_client__) 228 #elif defined(__native_client__)
220 // Setting thread priorities is not supported in NaCl. 229 // Setting thread priorities is not supported in NaCl.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 #if defined(WEBRTC_WIN) 277 #if defined(WEBRTC_WIN)
269 bool PlatformThread::QueueAPC(PAPCFUNC function, ULONG_PTR data) { 278 bool PlatformThread::QueueAPC(PAPCFUNC function, ULONG_PTR data) {
270 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 279 RTC_DCHECK(thread_checker_.CalledOnValidThread());
271 RTC_DCHECK(IsRunning()); 280 RTC_DCHECK(IsRunning());
272 281
273 return QueueUserAPC(function, thread_, data) != FALSE; 282 return QueueUserAPC(function, thread_, data) != FALSE;
274 } 283 }
275 #endif 284 #endif
276 285
277 } // namespace rtc 286 } // namespace rtc
OLDNEW
« no previous file with comments | « webrtc/base/platform_thread.h ('k') | webrtc/modules/utility/source/process_thread_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698