| 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 |
| 11 #include "webrtc/base/thread.h" | 11 #include "webrtc/base/thread.h" |
| 12 | 12 |
| 13 #ifndef __has_feature | |
| 14 #define __has_feature(x) 0 // Compatibility with non-clang or LLVM compilers. | |
| 15 #endif // __has_feature | |
| 16 | |
| 17 #if defined(WEBRTC_WIN) | 13 #if defined(WEBRTC_WIN) |
| 18 #include <comdef.h> | 14 #include <comdef.h> |
| 19 #elif defined(WEBRTC_POSIX) | 15 #elif defined(WEBRTC_POSIX) |
| 20 #include <time.h> | 16 #include <time.h> |
| 21 #endif | 17 #endif |
| 22 | 18 |
| 23 #include "webrtc/base/checks.h" | 19 #include "webrtc/base/checks.h" |
| 24 #include "webrtc/base/logging.h" | 20 #include "webrtc/base/logging.h" |
| 25 #include "webrtc/base/nullsocketserver.h" | 21 #include "webrtc/base/nullsocketserver.h" |
| 26 #include "webrtc/base/platform_thread.h" | 22 #include "webrtc/base/platform_thread.h" |
| 27 #include "webrtc/base/stringutils.h" | 23 #include "webrtc/base/stringutils.h" |
| 28 #include "webrtc/base/timeutils.h" | 24 #include "webrtc/base/timeutils.h" |
| 29 #include "webrtc/base/trace_event.h" | 25 #include "webrtc/base/trace_event.h" |
| 30 | 26 |
| 31 #if !__has_feature(objc_arc) && (defined(WEBRTC_MAC)) | 27 #if defined(WEBRTC_MAC) |
| 32 #include "webrtc/base/maccocoathreadhelper.h" | 28 #include "webrtc/base/maccocoathreadhelper.h" |
| 33 #include "webrtc/base/scoped_autorelease_pool.h" | 29 #include "webrtc/base/scoped_autorelease_pool.h" |
| 34 #endif | 30 #endif |
| 35 | 31 |
| 36 namespace rtc { | 32 namespace rtc { |
| 37 | 33 |
| 38 ThreadManager* ThreadManager::Instance() { | 34 ThreadManager* ThreadManager::Instance() { |
| 39 RTC_DEFINE_STATIC_LOCAL(ThreadManager, thread_manager, ()); | 35 RTC_DEFINE_STATIC_LOCAL(ThreadManager, thread_manager, ()); |
| 40 return &thread_manager; | 36 return &thread_manager; |
| 41 } | 37 } |
| 42 | 38 |
| 43 // static | 39 // static |
| 44 Thread* Thread::Current() { | 40 Thread* Thread::Current() { |
| 45 return ThreadManager::Instance()->CurrentThread(); | 41 return ThreadManager::Instance()->CurrentThread(); |
| 46 } | 42 } |
| 47 | 43 |
| 48 #if defined(WEBRTC_POSIX) | 44 #if defined(WEBRTC_POSIX) |
| 49 ThreadManager::ThreadManager() { | 45 ThreadManager::ThreadManager() { |
| 50 pthread_key_create(&key_, NULL); | 46 pthread_key_create(&key_, NULL); |
| 51 #ifndef NO_MAIN_THREAD_WRAPPING | 47 #ifndef NO_MAIN_THREAD_WRAPPING |
| 52 WrapCurrentThread(); | 48 WrapCurrentThread(); |
| 53 #endif | 49 #endif |
| 54 #if !__has_feature(objc_arc) && (defined(WEBRTC_MAC)) | 50 #if defined(WEBRTC_MAC) |
| 55 // Under Automatic Reference Counting (ARC), you cannot use autorelease pools | 51 // This is necessary to alert the cocoa runtime of the fact that |
| 56 // directly. Instead, you use @autoreleasepool blocks instead. Also, we are | 52 // we are running in a multithreaded environment. |
| 57 // maintaining thread safety using immutability within context of GCD dispatch | |
| 58 // queues in this case. | |
| 59 InitCocoaMultiThreading(); | 53 InitCocoaMultiThreading(); |
| 60 #endif | 54 #endif |
| 61 } | 55 } |
| 62 | 56 |
| 63 ThreadManager::~ThreadManager() { | 57 ThreadManager::~ThreadManager() { |
| 64 #if __has_feature(objc_arc) | 58 #if defined(WEBRTC_MAC) |
| 65 @autoreleasepool | |
| 66 #elif defined(WEBRTC_MAC) | |
| 67 // This is called during exit, at which point apparently no NSAutoreleasePools | 59 // This is called during exit, at which point apparently no NSAutoreleasePools |
| 68 // are available; but we might still need them to do cleanup (or we get the | 60 // are available; but we might still need them to do cleanup (or we get the |
| 69 // "no autoreleasepool in place, just leaking" warning when exiting). | 61 // "no autoreleasepool in place, just leaking" warning when exiting). |
| 70 ScopedAutoreleasePool pool; | 62 ScopedAutoreleasePool pool; |
| 71 #endif | 63 #endif |
| 72 { | 64 UnwrapCurrentThread(); |
| 73 UnwrapCurrentThread(); | 65 pthread_key_delete(key_); |
| 74 pthread_key_delete(key_); | |
| 75 } | |
| 76 } | 66 } |
| 77 | 67 |
| 78 Thread *ThreadManager::CurrentThread() { | 68 Thread *ThreadManager::CurrentThread() { |
| 79 return static_cast<Thread *>(pthread_getspecific(key_)); | 69 return static_cast<Thread *>(pthread_getspecific(key_)); |
| 80 } | 70 } |
| 81 | 71 |
| 82 void ThreadManager::SetCurrentThread(Thread *thread) { | 72 void ThreadManager::SetCurrentThread(Thread *thread) { |
| 83 pthread_setspecific(key_, thread); | 73 pthread_setspecific(key_, thread); |
| 84 } | 74 } |
| 85 #endif | 75 #endif |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 | 299 |
| 310 // static | 300 // static |
| 311 #if defined(WEBRTC_WIN) | 301 #if defined(WEBRTC_WIN) |
| 312 DWORD WINAPI Thread::PreRun(LPVOID pv) { | 302 DWORD WINAPI Thread::PreRun(LPVOID pv) { |
| 313 #else | 303 #else |
| 314 void* Thread::PreRun(void* pv) { | 304 void* Thread::PreRun(void* pv) { |
| 315 #endif | 305 #endif |
| 316 ThreadInit* init = static_cast<ThreadInit*>(pv); | 306 ThreadInit* init = static_cast<ThreadInit*>(pv); |
| 317 ThreadManager::Instance()->SetCurrentThread(init->thread); | 307 ThreadManager::Instance()->SetCurrentThread(init->thread); |
| 318 rtc::SetCurrentThreadName(init->thread->name_.c_str()); | 308 rtc::SetCurrentThreadName(init->thread->name_.c_str()); |
| 319 #if __has_feature(objc_arc) | 309 #if defined(WEBRTC_MAC) |
| 320 @autoreleasepool | |
| 321 #elif defined(WEBRTC_MAC) | |
| 322 // Make sure the new thread has an autoreleasepool | 310 // Make sure the new thread has an autoreleasepool |
| 323 ScopedAutoreleasePool pool; | 311 ScopedAutoreleasePool pool; |
| 324 #endif | 312 #endif |
| 325 { | 313 if (init->runnable) { |
| 326 if (init->runnable) { | 314 init->runnable->Run(init->thread); |
| 327 init->runnable->Run(init->thread); | 315 } else { |
| 328 } else { | 316 init->thread->Run(); |
| 329 init->thread->Run(); | 317 } |
| 330 } | 318 delete init; |
| 331 delete init; | |
| 332 #ifdef WEBRTC_WIN | 319 #ifdef WEBRTC_WIN |
| 333 return 0; | 320 return 0; |
| 334 #else | 321 #else |
| 335 return nullptr; | 322 return nullptr; |
| 336 #endif | 323 #endif |
| 337 } | |
| 338 } | 324 } |
| 339 | 325 |
| 340 void Thread::Run() { | 326 void Thread::Run() { |
| 341 ProcessMessages(kForever); | 327 ProcessMessages(kForever); |
| 342 } | 328 } |
| 343 | 329 |
| 344 bool Thread::IsOwned() { | 330 bool Thread::IsOwned() { |
| 345 return owned_; | 331 return owned_; |
| 346 } | 332 } |
| 347 | 333 |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 } | 476 } |
| 491 | 477 |
| 492 MessageQueue::Clear(phandler, id, removed); | 478 MessageQueue::Clear(phandler, id, removed); |
| 493 } | 479 } |
| 494 | 480 |
| 495 bool Thread::ProcessMessages(int cmsLoop) { | 481 bool Thread::ProcessMessages(int cmsLoop) { |
| 496 int64_t msEnd = (kForever == cmsLoop) ? 0 : TimeAfter(cmsLoop); | 482 int64_t msEnd = (kForever == cmsLoop) ? 0 : TimeAfter(cmsLoop); |
| 497 int cmsNext = cmsLoop; | 483 int cmsNext = cmsLoop; |
| 498 | 484 |
| 499 while (true) { | 485 while (true) { |
| 500 #if __has_feature(objc_arc) | 486 #if defined(WEBRTC_MAC) |
| 501 @autoreleasepool | |
| 502 #elif defined(WEBRTC_MAC) | |
| 503 // see: http://developer.apple.com/library/mac/#documentation/Cocoa/Referenc
e/Foundation/Classes/NSAutoreleasePool_Class/Reference/Reference.html | 487 // see: http://developer.apple.com/library/mac/#documentation/Cocoa/Referenc
e/Foundation/Classes/NSAutoreleasePool_Class/Reference/Reference.html |
| 504 // Each thread is supposed to have an autorelease pool. Also for event loops | 488 // Each thread is supposed to have an autorelease pool. Also for event loops |
| 505 // like this, autorelease pool needs to be created and drained/released | 489 // like this, autorelease pool needs to be created and drained/released |
| 506 // for each cycle. | 490 // for each cycle. |
| 507 ScopedAutoreleasePool pool; | 491 ScopedAutoreleasePool pool; |
| 508 #endif | 492 #endif |
| 509 { | 493 Message msg; |
| 510 Message msg; | 494 if (!Get(&msg, cmsNext)) |
| 511 if (!Get(&msg, cmsNext)) | 495 return !IsQuitting(); |
| 512 return !IsQuitting(); | 496 Dispatch(&msg); |
| 513 Dispatch(&msg); | |
| 514 | 497 |
| 515 if (cmsLoop != kForever) { | 498 if (cmsLoop != kForever) { |
| 516 cmsNext = static_cast<int>(TimeUntil(msEnd)); | 499 cmsNext = static_cast<int>(TimeUntil(msEnd)); |
| 517 if (cmsNext < 0) | 500 if (cmsNext < 0) |
| 518 return true; | 501 return true; |
| 519 } | |
| 520 } | 502 } |
| 521 } | 503 } |
| 522 } | 504 } |
| 523 | 505 |
| 524 bool Thread::WrapCurrentWithThreadManager(ThreadManager* thread_manager, | 506 bool Thread::WrapCurrentWithThreadManager(ThreadManager* thread_manager, |
| 525 bool need_synchronize_access) { | 507 bool need_synchronize_access) { |
| 526 if (running()) | 508 if (running()) |
| 527 return false; | 509 return false; |
| 528 | 510 |
| 529 #if defined(WEBRTC_WIN) | 511 #if defined(WEBRTC_WIN) |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 571 if (SUCCEEDED(hr)) { | 553 if (SUCCEEDED(hr)) { |
| 572 Thread::Run(); | 554 Thread::Run(); |
| 573 CoUninitialize(); | 555 CoUninitialize(); |
| 574 } else { | 556 } else { |
| 575 LOG(LS_ERROR) << "CoInitialize failed, hr=" << hr; | 557 LOG(LS_ERROR) << "CoInitialize failed, hr=" << hr; |
| 576 } | 558 } |
| 577 } | 559 } |
| 578 #endif | 560 #endif |
| 579 | 561 |
| 580 } // namespace rtc | 562 } // namespace rtc |
| OLD | NEW |