Chromium Code Reviews| 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 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 85 #else | 85 #else |
| 86 struct ThreadAttributes { | 86 struct ThreadAttributes { |
| 87 ThreadAttributes() { pthread_attr_init(&attr); } | 87 ThreadAttributes() { pthread_attr_init(&attr); } |
| 88 ~ThreadAttributes() { pthread_attr_destroy(&attr); } | 88 ~ThreadAttributes() { pthread_attr_destroy(&attr); } |
| 89 pthread_attr_t* operator&() { return &attr; } | 89 pthread_attr_t* operator&() { return &attr; } |
| 90 pthread_attr_t attr; | 90 pthread_attr_t attr; |
| 91 }; | 91 }; |
| 92 #endif // defined(WEBRTC_WIN) | 92 #endif // defined(WEBRTC_WIN) |
| 93 } | 93 } |
| 94 | 94 |
| 95 PlatformThread::PlatformThread(ThreadRunFunctionDeprecated func, | |
| 96 void* obj, | |
| 97 const char* thread_name) | |
| 98 : run_function_deprecated_(func), | |
| 99 obj_(obj), | |
| 100 name_(thread_name ? thread_name : "webrtc") { | |
| 101 RTC_DCHECK(func); | |
| 102 RTC_DCHECK(name_.length() < 64); | |
|
the sun
2017/02/22 13:42:57
Where's the limit of 64 from? To my knowledge, the
tommi
2017/02/22 15:04:00
15 sounds good to me. I think we break that though
the sun
2017/02/22 16:31:30
sgtm
| |
| 103 worker_thread_checker_.DetachFromThread(); | |
| 104 } | |
| 105 | |
| 95 PlatformThread::PlatformThread(ThreadRunFunction func, | 106 PlatformThread::PlatformThread(ThreadRunFunction func, |
| 96 void* obj, | 107 void* obj, |
| 97 const char* thread_name) | 108 const char* thread_name, |
| 98 : run_function_(func), | 109 ThreadPriority priority /*= kNormalPriority*/) |
| 99 obj_(obj), | 110 : run_function_(func), priority_(priority), obj_(obj), name_(thread_name) { |
| 100 name_(thread_name ? thread_name : "webrtc") { | |
| 101 RTC_DCHECK(func); | 111 RTC_DCHECK(func); |
| 112 RTC_DCHECK(!name_.empty()); | |
| 102 RTC_DCHECK(name_.length() < 64); | 113 RTC_DCHECK(name_.length() < 64); |
| 114 worker_thread_checker_.DetachFromThread(); | |
| 103 } | 115 } |
| 104 | 116 |
| 105 PlatformThread::~PlatformThread() { | 117 PlatformThread::~PlatformThread() { |
| 106 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 118 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 107 #if defined(WEBRTC_WIN) | 119 #if defined(WEBRTC_WIN) |
| 108 RTC_DCHECK(!thread_); | 120 RTC_DCHECK(!thread_); |
| 109 RTC_DCHECK(!thread_id_); | 121 RTC_DCHECK(!thread_id_); |
| 110 #endif // defined(WEBRTC_WIN) | 122 #endif // defined(WEBRTC_WIN) |
| 111 } | 123 } |
| 112 | 124 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 173 #if defined(WEBRTC_WIN) | 185 #if defined(WEBRTC_WIN) |
| 174 // Set stop_ to |true| on the worker thread. | 186 // Set stop_ to |true| on the worker thread. |
| 175 bool queued = QueueAPC(&RaiseFlag, reinterpret_cast<ULONG_PTR>(&stop_)); | 187 bool queued = QueueAPC(&RaiseFlag, reinterpret_cast<ULONG_PTR>(&stop_)); |
| 176 // Queuing the APC can fail if the thread is being terminated. | 188 // Queuing the APC can fail if the thread is being terminated. |
| 177 RTC_CHECK(queued || GetLastError() == ERROR_GEN_FAILURE); | 189 RTC_CHECK(queued || GetLastError() == ERROR_GEN_FAILURE); |
| 178 WaitForSingleObject(thread_, INFINITE); | 190 WaitForSingleObject(thread_, INFINITE); |
| 179 CloseHandle(thread_); | 191 CloseHandle(thread_); |
| 180 thread_ = nullptr; | 192 thread_ = nullptr; |
| 181 thread_id_ = 0; | 193 thread_id_ = 0; |
| 182 #else | 194 #else |
| 183 RTC_CHECK_EQ(1, AtomicOps::Increment(&stop_flag_)); | 195 if (!run_function_) |
| 196 RTC_CHECK_EQ(1, AtomicOps::Increment(&stop_flag_)); | |
| 184 RTC_CHECK_EQ(0, pthread_join(thread_, nullptr)); | 197 RTC_CHECK_EQ(0, pthread_join(thread_, nullptr)); |
| 185 AtomicOps::ReleaseStore(&stop_flag_, 0); | 198 if (!run_function_) |
| 199 AtomicOps::ReleaseStore(&stop_flag_, 0); | |
| 186 thread_ = 0; | 200 thread_ = 0; |
| 187 #endif // defined(WEBRTC_WIN) | 201 #endif // defined(WEBRTC_WIN) |
| 202 worker_thread_checker_.DetachFromThread(); | |
| 188 } | 203 } |
| 189 | 204 |
| 190 // TODO(tommi): Deprecate the loop behavior in PlatformThread. | 205 // TODO(tommi): Deprecate the loop behavior in PlatformThread. |
| 191 // * Introduce a new callback type that returns void. | 206 // * Introduce a new callback type that returns void. |
| 192 // * Remove potential for a busy loop in PlatformThread. | 207 // * Remove potential for a busy loop in PlatformThread. |
| 193 // * Delegate the responsibility for how to stop the thread, to the | 208 // * Delegate the responsibility for how to stop the thread, to the |
| 194 // implementation that actually uses the thread. | 209 // implementation that actually uses the thread. |
| 195 // All implementations will need to be aware of how the thread should be stopped | 210 // 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. | 211 // and encouraging a busy polling loop, can be costly in terms of power and cpu. |
| 197 void PlatformThread::Run() { | 212 void PlatformThread::Run() { |
| 198 if (!name_.empty()) | 213 // Attach the worker thread checker to this thread. |
| 199 rtc::SetCurrentThreadName(name_.c_str()); | 214 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 215 rtc::SetCurrentThreadName(name_.c_str()); | |
| 216 | |
| 217 if (run_function_) { | |
| 218 SetPriority(priority_); | |
| 219 run_function_(obj_); | |
| 220 return; | |
| 221 } | |
| 222 // TODO(tommi): Delete the below. | |
| 200 #if !defined(WEBRTC_MAC) && !defined(WEBRTC_WIN) | 223 #if !defined(WEBRTC_MAC) && !defined(WEBRTC_WIN) |
| 201 const struct timespec ts_null = {0}; | 224 const struct timespec ts_null = {0}; |
| 202 #endif | 225 #endif |
| 203 do { | 226 do { |
| 204 // The interface contract of Start/Stop is that for a successful call to | 227 // The interface contract of Start/Stop is that for a successful call to |
| 205 // Start, there should be at least one call to the run function. So we | 228 // Start, there should be at least one call to the run function. So we |
| 206 // call the function before checking |stop_|. | 229 // call the function before checking |stop_|. |
| 207 if (!run_function_(obj_)) | 230 if (!run_function_deprecated_(obj_)) |
| 208 break; | 231 break; |
| 209 #if defined(WEBRTC_WIN) | 232 #if defined(WEBRTC_WIN) |
| 210 // Alertable sleep to permit RaiseFlag to run and update |stop_|. | 233 // Alertable sleep to permit RaiseFlag to run and update |stop_|. |
| 211 SleepEx(0, true); | 234 SleepEx(0, true); |
| 212 } while (!stop_); | 235 } while (!stop_); |
| 213 #else | 236 #else |
| 214 #if defined(WEBRTC_MAC) | 237 #if defined(WEBRTC_MAC) |
| 215 sched_yield(); | 238 sched_yield(); |
| 216 #else | 239 #else |
| 217 nanosleep(&ts_null, nullptr); | 240 nanosleep(&ts_null, nullptr); |
| 218 #endif | 241 #endif |
| 219 } while (!AtomicOps::AcquireLoad(&stop_flag_)); | 242 } while (!AtomicOps::AcquireLoad(&stop_flag_)); |
| 220 #endif // defined(WEBRTC_WIN) | 243 #endif // defined(WEBRTC_WIN) |
| 221 } | 244 } |
| 222 | 245 |
| 223 bool PlatformThread::SetPriority(ThreadPriority priority) { | 246 bool PlatformThread::SetPriority(ThreadPriority priority) { |
| 224 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 247 #if RTC_DCHECK_IS_ON |
| 225 RTC_DCHECK(IsRunning()); | 248 if (run_function_) { |
| 249 // The non-deprecated way of how this function gets called, is that it must | |
| 250 // be called on the worker thread itself. | |
| 251 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
| 252 } else { | |
| 253 // In the case of deprecated use of this method, it must be called on the | |
| 254 // same thread as the PlatformThread object is constructed on. | |
| 255 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
| 256 RTC_DCHECK(IsRunning()); | |
| 257 } | |
| 258 #endif | |
| 259 | |
| 226 #if defined(WEBRTC_WIN) | 260 #if defined(WEBRTC_WIN) |
| 227 return SetThreadPriority(thread_, priority) != FALSE; | 261 return SetThreadPriority(thread_, priority) != FALSE; |
| 228 #elif defined(__native_client__) | 262 #elif defined(__native_client__) |
| 229 // Setting thread priorities is not supported in NaCl. | 263 // Setting thread priorities is not supported in NaCl. |
| 230 return true; | 264 return true; |
| 231 #elif defined(WEBRTC_CHROMIUM_BUILD) && defined(WEBRTC_LINUX) | 265 #elif defined(WEBRTC_CHROMIUM_BUILD) && defined(WEBRTC_LINUX) |
| 232 // TODO(tommi): Switch to the same mechanism as Chromium uses for changing | 266 // TODO(tommi): Switch to the same mechanism as Chromium uses for changing |
| 233 // thread priorities. | 267 // thread priorities. |
| 234 return true; | 268 return true; |
| 235 #else | 269 #else |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 277 #if defined(WEBRTC_WIN) | 311 #if defined(WEBRTC_WIN) |
| 278 bool PlatformThread::QueueAPC(PAPCFUNC function, ULONG_PTR data) { | 312 bool PlatformThread::QueueAPC(PAPCFUNC function, ULONG_PTR data) { |
| 279 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 313 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 280 RTC_DCHECK(IsRunning()); | 314 RTC_DCHECK(IsRunning()); |
| 281 | 315 |
| 282 return QueueUserAPC(function, thread_, data) != FALSE; | 316 return QueueUserAPC(function, thread_, data) != FALSE; |
| 283 } | 317 } |
| 284 #endif | 318 #endif |
| 285 | 319 |
| 286 } // namespace rtc | 320 } // namespace rtc |
| OLD | NEW |