OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 previous_state_(thread_->SetAllowBlockingCalls(false)) { | 133 previous_state_(thread_->SetAllowBlockingCalls(false)) { |
134 } | 134 } |
135 | 135 |
136 Thread::ScopedDisallowBlockingCalls::~ScopedDisallowBlockingCalls() { | 136 Thread::ScopedDisallowBlockingCalls::~ScopedDisallowBlockingCalls() { |
137 ASSERT(thread_->IsCurrent()); | 137 ASSERT(thread_->IsCurrent()); |
138 thread_->SetAllowBlockingCalls(previous_state_); | 138 thread_->SetAllowBlockingCalls(previous_state_); |
139 } | 139 } |
140 | 140 |
141 Thread::Thread(SocketServer* ss) | 141 Thread::Thread(SocketServer* ss) |
142 : MessageQueue(ss), | 142 : MessageQueue(ss), |
143 priority_(PRIORITY_NORMAL), | |
144 running_(true, false), | 143 running_(true, false), |
145 #if defined(WEBRTC_WIN) | 144 #if defined(WEBRTC_WIN) |
146 thread_(NULL), | 145 thread_(NULL), |
147 thread_id_(0), | 146 thread_id_(0), |
148 #endif | 147 #endif |
149 owned_(true), | 148 owned_(true), |
150 blocking_calls_allowed_(true) { | 149 blocking_calls_allowed_(true) { |
151 SetName("Thread", this); // default name | 150 SetName("Thread", this); // default name |
152 } | 151 } |
153 | 152 |
(...skipping 27 matching lines...) Expand all Loading... |
181 if (running()) return false; | 180 if (running()) return false; |
182 name_ = name; | 181 name_ = name; |
183 if (obj) { | 182 if (obj) { |
184 char buf[16]; | 183 char buf[16]; |
185 sprintfn(buf, sizeof(buf), " 0x%p", obj); | 184 sprintfn(buf, sizeof(buf), " 0x%p", obj); |
186 name_ += buf; | 185 name_ += buf; |
187 } | 186 } |
188 return true; | 187 return true; |
189 } | 188 } |
190 | 189 |
191 bool Thread::SetPriority(ThreadPriority priority) { | |
192 #if defined(WEBRTC_WIN) | |
193 if (running()) { | |
194 ASSERT(thread_ != NULL); | |
195 BOOL ret = FALSE; | |
196 if (priority == PRIORITY_NORMAL) { | |
197 ret = ::SetThreadPriority(thread_, THREAD_PRIORITY_NORMAL); | |
198 } else if (priority == PRIORITY_HIGH) { | |
199 ret = ::SetThreadPriority(thread_, THREAD_PRIORITY_HIGHEST); | |
200 } else if (priority == PRIORITY_ABOVE_NORMAL) { | |
201 ret = ::SetThreadPriority(thread_, THREAD_PRIORITY_ABOVE_NORMAL); | |
202 } else if (priority == PRIORITY_IDLE) { | |
203 ret = ::SetThreadPriority(thread_, THREAD_PRIORITY_IDLE); | |
204 } | |
205 if (!ret) { | |
206 return false; | |
207 } | |
208 } | |
209 priority_ = priority; | |
210 return true; | |
211 #else | |
212 // TODO: Implement for Linux/Mac if possible. | |
213 if (running()) return false; | |
214 priority_ = priority; | |
215 return true; | |
216 #endif | |
217 } | |
218 | |
219 bool Thread::Start(Runnable* runnable) { | 190 bool Thread::Start(Runnable* runnable) { |
220 ASSERT(owned_); | 191 ASSERT(owned_); |
221 if (!owned_) return false; | 192 if (!owned_) return false; |
222 ASSERT(!running()); | 193 ASSERT(!running()); |
223 if (running()) return false; | 194 if (running()) return false; |
224 | 195 |
225 Restart(); // reset fStop_ if the thread is being restarted | 196 Restart(); // reset fStop_ if the thread is being restarted |
226 | 197 |
227 // Make sure that ThreadManager is created on the main thread before | 198 // Make sure that ThreadManager is created on the main thread before |
228 // we start a new thread. | 199 // we start a new thread. |
229 ThreadManager::Instance(); | 200 ThreadManager::Instance(); |
230 | 201 |
231 ThreadInit* init = new ThreadInit; | 202 ThreadInit* init = new ThreadInit; |
232 init->thread = this; | 203 init->thread = this; |
233 init->runnable = runnable; | 204 init->runnable = runnable; |
234 #if defined(WEBRTC_WIN) | 205 #if defined(WEBRTC_WIN) |
235 DWORD flags = 0; | 206 thread_ = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PreRun, init, 0, |
236 if (priority_ != PRIORITY_NORMAL) { | |
237 flags = CREATE_SUSPENDED; | |
238 } | |
239 thread_ = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PreRun, init, flags, | |
240 &thread_id_); | 207 &thread_id_); |
241 if (thread_) { | 208 if (thread_) { |
242 running_.Set(); | 209 running_.Set(); |
243 if (priority_ != PRIORITY_NORMAL) { | |
244 SetPriority(priority_); | |
245 ::ResumeThread(thread_); | |
246 } | |
247 } else { | 210 } else { |
248 return false; | 211 return false; |
249 } | 212 } |
250 #elif defined(WEBRTC_POSIX) | 213 #elif defined(WEBRTC_POSIX) |
251 pthread_attr_t attr; | 214 pthread_attr_t attr; |
252 pthread_attr_init(&attr); | 215 pthread_attr_init(&attr); |
253 | 216 |
254 // Thread priorities are not supported in NaCl. | |
255 #if !defined(__native_client__) | |
256 if (priority_ != PRIORITY_NORMAL) { | |
257 if (priority_ == PRIORITY_IDLE) { | |
258 // There is no POSIX-standard way to set a below-normal priority for an | |
259 // individual thread (only whole process), so let's not support it. | |
260 LOG(LS_WARNING) << "PRIORITY_IDLE not supported"; | |
261 } else { | |
262 // Set real-time round-robin policy. | |
263 if (pthread_attr_setschedpolicy(&attr, SCHED_RR) != 0) { | |
264 LOG(LS_ERROR) << "pthread_attr_setschedpolicy"; | |
265 } | |
266 struct sched_param param; | |
267 if (pthread_attr_getschedparam(&attr, ¶m) != 0) { | |
268 LOG(LS_ERROR) << "pthread_attr_getschedparam"; | |
269 } else { | |
270 // The numbers here are arbitrary. | |
271 if (priority_ == PRIORITY_HIGH) { | |
272 param.sched_priority = 6; // 6 = HIGH | |
273 } else { | |
274 ASSERT(priority_ == PRIORITY_ABOVE_NORMAL); | |
275 param.sched_priority = 4; // 4 = ABOVE_NORMAL | |
276 } | |
277 if (pthread_attr_setschedparam(&attr, ¶m) != 0) { | |
278 LOG(LS_ERROR) << "pthread_attr_setschedparam"; | |
279 } | |
280 } | |
281 } | |
282 } | |
283 #endif // !defined(__native_client__) | |
284 | |
285 int error_code = pthread_create(&thread_, &attr, PreRun, init); | 217 int error_code = pthread_create(&thread_, &attr, PreRun, init); |
286 if (0 != error_code) { | 218 if (0 != error_code) { |
287 LOG(LS_ERROR) << "Unable to create pthread, error " << error_code; | 219 LOG(LS_ERROR) << "Unable to create pthread, error " << error_code; |
288 return false; | 220 return false; |
289 } | 221 } |
290 running_.Set(); | 222 running_.Set(); |
291 #endif | 223 #endif |
292 return true; | 224 return true; |
293 } | 225 } |
294 | 226 |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 if (SUCCEEDED(hr)) { | 531 if (SUCCEEDED(hr)) { |
600 Thread::Run(); | 532 Thread::Run(); |
601 CoUninitialize(); | 533 CoUninitialize(); |
602 } else { | 534 } else { |
603 LOG(LS_ERROR) << "CoInitialize failed, hr=" << hr; | 535 LOG(LS_ERROR) << "CoInitialize failed, hr=" << hr; |
604 } | 536 } |
605 } | 537 } |
606 #endif | 538 #endif |
607 | 539 |
608 } // namespace rtc | 540 } // namespace rtc |
OLD | NEW |