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

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

Issue 2784483002: Add Darwin thread.h implementation. (Closed)
Patch Set: Make ThreadInit private to rtc::Thread Created 3 years, 8 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
« no previous file with comments | « webrtc/base/thread.h ('k') | webrtc/base/thread_darwin.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
11 #include "webrtc/base/thread.h" 11 #include "webrtc/base/thread.h"
12 12
13 #if defined(WEBRTC_WIN) 13 #if defined(WEBRTC_WIN)
14 #include <comdef.h> 14 #include <comdef.h>
15 #elif defined(WEBRTC_POSIX) 15 #elif defined(WEBRTC_POSIX)
16 #include <time.h> 16 #include <time.h>
17 #endif 17 #endif
18 18
19 #include "webrtc/base/checks.h" 19 #include "webrtc/base/checks.h"
20 #include "webrtc/base/logging.h" 20 #include "webrtc/base/logging.h"
21 #include "webrtc/base/nullsocketserver.h" 21 #include "webrtc/base/nullsocketserver.h"
22 #include "webrtc/base/platform_thread.h" 22 #include "webrtc/base/platform_thread.h"
23 #include "webrtc/base/stringutils.h" 23 #include "webrtc/base/stringutils.h"
24 #include "webrtc/base/timeutils.h" 24 #include "webrtc/base/timeutils.h"
25 #include "webrtc/base/trace_event.h" 25 #include "webrtc/base/trace_event.h"
26 26
27 #if defined(WEBRTC_MAC)
28 #include "webrtc/base/maccocoathreadhelper.h"
29 #include "webrtc/base/scoped_autorelease_pool.h"
30 #endif
31
32 namespace rtc { 27 namespace rtc {
33 28
34 ThreadManager* ThreadManager::Instance() { 29 ThreadManager* ThreadManager::Instance() {
35 RTC_DEFINE_STATIC_LOCAL(ThreadManager, thread_manager, ()); 30 RTC_DEFINE_STATIC_LOCAL(ThreadManager, thread_manager, ());
36 return &thread_manager; 31 return &thread_manager;
37 } 32 }
38 33
39 // static 34 // static
40 Thread* Thread::Current() { 35 Thread* Thread::Current() {
41 return ThreadManager::Instance()->CurrentThread(); 36 return ThreadManager::Instance()->CurrentThread();
42 } 37 }
43 38
44 #if defined(WEBRTC_POSIX) 39 #if defined(WEBRTC_POSIX)
40 #if !defined(WEBRTC_MAC)
45 ThreadManager::ThreadManager() { 41 ThreadManager::ThreadManager() {
46 pthread_key_create(&key_, nullptr); 42 pthread_key_create(&key_, nullptr);
47 #ifndef NO_MAIN_THREAD_WRAPPING 43 #ifndef NO_MAIN_THREAD_WRAPPING
48 WrapCurrentThread(); 44 WrapCurrentThread();
49 #endif 45 #endif
50 #if defined(WEBRTC_MAC)
51 // This is necessary to alert the cocoa runtime of the fact that
52 // we are running in a multithreaded environment.
53 InitCocoaMultiThreading();
54 #endif
55 } 46 }
56 47
57 ThreadManager::~ThreadManager() { 48 ThreadManager::~ThreadManager() {
58 #if defined(WEBRTC_MAC)
59 // This is called during exit, at which point apparently no NSAutoreleasePools
60 // are available; but we might still need them to do cleanup (or we get the
61 // "no autoreleasepool in place, just leaking" warning when exiting).
62 ScopedAutoreleasePool pool;
63 #endif
64 UnwrapCurrentThread(); 49 UnwrapCurrentThread();
65 pthread_key_delete(key_); 50 pthread_key_delete(key_);
66 } 51 }
52 #endif
67 53
68 Thread *ThreadManager::CurrentThread() { 54 Thread *ThreadManager::CurrentThread() {
69 return static_cast<Thread *>(pthread_getspecific(key_)); 55 return static_cast<Thread *>(pthread_getspecific(key_));
70 } 56 }
71 57
72 void ThreadManager::SetCurrentThread(Thread *thread) { 58 void ThreadManager::SetCurrentThread(Thread *thread) {
73 pthread_setspecific(key_, thread); 59 pthread_setspecific(key_, thread);
74 } 60 }
75 #endif 61 #endif
76 62
(...skipping 29 matching lines...) Expand all
106 } 92 }
107 93
108 void ThreadManager::UnwrapCurrentThread() { 94 void ThreadManager::UnwrapCurrentThread() {
109 Thread* t = CurrentThread(); 95 Thread* t = CurrentThread();
110 if (t && !(t->IsOwned())) { 96 if (t && !(t->IsOwned())) {
111 t->UnwrapCurrent(); 97 t->UnwrapCurrent();
112 delete t; 98 delete t;
113 } 99 }
114 } 100 }
115 101
116 struct ThreadInit {
117 Thread* thread;
118 Runnable* runnable;
119 };
120
121 Thread::ScopedDisallowBlockingCalls::ScopedDisallowBlockingCalls() 102 Thread::ScopedDisallowBlockingCalls::ScopedDisallowBlockingCalls()
122 : thread_(Thread::Current()), 103 : thread_(Thread::Current()),
123 previous_state_(thread_->SetAllowBlockingCalls(false)) { 104 previous_state_(thread_->SetAllowBlockingCalls(false)) {
124 } 105 }
125 106
126 Thread::ScopedDisallowBlockingCalls::~ScopedDisallowBlockingCalls() { 107 Thread::ScopedDisallowBlockingCalls::~ScopedDisallowBlockingCalls() {
127 RTC_DCHECK(thread_->IsCurrent()); 108 RTC_DCHECK(thread_->IsCurrent());
128 thread_->SetAllowBlockingCalls(previous_state_); 109 thread_->SetAllowBlockingCalls(previous_state_);
129 } 110 }
130 111
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 272
292 // static 273 // static
293 void Thread::AssertBlockingIsAllowedOnCurrentThread() { 274 void Thread::AssertBlockingIsAllowedOnCurrentThread() {
294 #if !defined(NDEBUG) 275 #if !defined(NDEBUG)
295 Thread* current = Thread::Current(); 276 Thread* current = Thread::Current();
296 RTC_DCHECK(!current || current->blocking_calls_allowed_); 277 RTC_DCHECK(!current || current->blocking_calls_allowed_);
297 #endif 278 #endif
298 } 279 }
299 280
300 // static 281 // static
282 #if !defined(WEBRTC_MAC)
301 #if defined(WEBRTC_WIN) 283 #if defined(WEBRTC_WIN)
302 DWORD WINAPI Thread::PreRun(LPVOID pv) { 284 DWORD WINAPI Thread::PreRun(LPVOID pv) {
303 #else 285 #else
304 void* Thread::PreRun(void* pv) { 286 void* Thread::PreRun(void* pv) {
305 #endif 287 #endif
306 ThreadInit* init = static_cast<ThreadInit*>(pv); 288 ThreadInit* init = static_cast<ThreadInit*>(pv);
307 ThreadManager::Instance()->SetCurrentThread(init->thread); 289 ThreadManager::Instance()->SetCurrentThread(init->thread);
308 rtc::SetCurrentThreadName(init->thread->name_.c_str()); 290 rtc::SetCurrentThreadName(init->thread->name_.c_str());
309 #if defined(WEBRTC_MAC)
310 // Make sure the new thread has an autoreleasepool
311 ScopedAutoreleasePool pool;
312 #endif
313 if (init->runnable) { 291 if (init->runnable) {
314 init->runnable->Run(init->thread); 292 init->runnable->Run(init->thread);
315 } else { 293 } else {
316 init->thread->Run(); 294 init->thread->Run();
317 } 295 }
318 delete init; 296 delete init;
319 #ifdef WEBRTC_WIN 297 #ifdef WEBRTC_WIN
320 return 0; 298 return 0;
321 #else 299 #else
322 return nullptr; 300 return nullptr;
323 #endif 301 #endif
324 } 302 }
303 #endif
325 304
326 void Thread::Run() { 305 void Thread::Run() {
327 ProcessMessages(kForever); 306 ProcessMessages(kForever);
328 } 307 }
329 308
330 bool Thread::IsOwned() { 309 bool Thread::IsOwned() {
331 return owned_; 310 return owned_;
332 } 311 }
333 312
334 void Thread::Stop() { 313 void Thread::Stop() {
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 *smsg.ready = true; 450 *smsg.ready = true;
472 smsg.thread->socketserver()->WakeUp(); 451 smsg.thread->socketserver()->WakeUp();
473 continue; 452 continue;
474 } 453 }
475 ++iter; 454 ++iter;
476 } 455 }
477 456
478 MessageQueue::Clear(phandler, id, removed); 457 MessageQueue::Clear(phandler, id, removed);
479 } 458 }
480 459
460 #if !defined(WEBRTC_MAC)
461 // Note that these methods have a separate implementation for mac and ios
462 // defined in webrtc/base/thread_darwin.mm.
481 bool Thread::ProcessMessages(int cmsLoop) { 463 bool Thread::ProcessMessages(int cmsLoop) {
482 int64_t msEnd = (kForever == cmsLoop) ? 0 : TimeAfter(cmsLoop); 464 int64_t msEnd = (kForever == cmsLoop) ? 0 : TimeAfter(cmsLoop);
483 int cmsNext = cmsLoop; 465 int cmsNext = cmsLoop;
484 466
485 while (true) { 467 while (true) {
486 #if defined(WEBRTC_MAC)
487 // see: http://developer.apple.com/library/mac/#documentation/Cocoa/Referenc e/Foundation/Classes/NSAutoreleasePool_Class/Reference/Reference.html
488 // Each thread is supposed to have an autorelease pool. Also for event loops
489 // like this, autorelease pool needs to be created and drained/released
490 // for each cycle.
491 ScopedAutoreleasePool pool;
492 #endif
493 Message msg; 468 Message msg;
494 if (!Get(&msg, cmsNext)) 469 if (!Get(&msg, cmsNext))
495 return !IsQuitting(); 470 return !IsQuitting();
496 Dispatch(&msg); 471 Dispatch(&msg);
497 472
498 if (cmsLoop != kForever) { 473 if (cmsLoop != kForever) {
499 cmsNext = static_cast<int>(TimeUntil(msEnd)); 474 cmsNext = static_cast<int>(TimeUntil(msEnd));
500 if (cmsNext < 0) 475 if (cmsNext < 0)
501 return true; 476 return true;
502 } 477 }
503 } 478 }
504 } 479 }
480 #endif
505 481
506 bool Thread::WrapCurrentWithThreadManager(ThreadManager* thread_manager, 482 bool Thread::WrapCurrentWithThreadManager(ThreadManager* thread_manager,
507 bool need_synchronize_access) { 483 bool need_synchronize_access) {
508 if (running()) 484 if (running())
509 return false; 485 return false;
510 486
511 #if defined(WEBRTC_WIN) 487 #if defined(WEBRTC_WIN)
512 if (need_synchronize_access) { 488 if (need_synchronize_access) {
513 // We explicitly ask for no rights other than synchronization. 489 // We explicitly ask for no rights other than synchronization.
514 // This gives us the best chance of succeeding. 490 // This gives us the best chance of succeeding.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 if (SUCCEEDED(hr)) { 529 if (SUCCEEDED(hr)) {
554 Thread::Run(); 530 Thread::Run();
555 CoUninitialize(); 531 CoUninitialize();
556 } else { 532 } else {
557 LOG(LS_ERROR) << "CoInitialize failed, hr=" << hr; 533 LOG(LS_ERROR) << "CoInitialize failed, hr=" << hr;
558 } 534 }
559 } 535 }
560 #endif 536 #endif
561 537
562 } // namespace rtc 538 } // namespace rtc
OLDNEW
« no previous file with comments | « webrtc/base/thread.h ('k') | webrtc/base/thread_darwin.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698