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 |