Move autowrap from ThreadManager constructor to Thread::Current.
This is in preparation for a WrapCurrentThread method, or AutoThread constructor, taking a socket server as argument, to eliminate the need for the MessageQueue::set_socketserver method and its lock. No intended change in behaviour; the ThreadManager constructor records the calling thread id, and autowrap is still restricted to that thread. Behavior when NO_MAIN_THREAD_WRAPPING is defined is also unchanged. Also makes the ThreadManager a singleton, with private constructor and destructor. And marks its destructor as RTC_NOTREACHED, since by the documentation for RTC_DEFINE_STATIC_LOCAL, the intention is to leak the object and never destruct it. BUG=webrtc:7501 Review-Url: https://codereview.webrtc.org/2833993003 Cr-Commit-Position: refs/heads/master@{#17879}
This commit is contained in:
@ -31,23 +31,32 @@ ThreadManager* ThreadManager::Instance() {
|
||||
return &thread_manager;
|
||||
}
|
||||
|
||||
ThreadManager::~ThreadManager() {
|
||||
// By above RTC_DEFINE_STATIC_LOCAL.
|
||||
RTC_NOTREACHED() << "ThreadManager should never be destructed.";
|
||||
}
|
||||
|
||||
// static
|
||||
Thread* Thread::Current() {
|
||||
return ThreadManager::Instance()->CurrentThread();
|
||||
ThreadManager* manager = ThreadManager::Instance();
|
||||
Thread* thread = manager->CurrentThread();
|
||||
|
||||
#ifndef NO_MAIN_THREAD_WRAPPING
|
||||
// Only autowrap the thread which instantiated the ThreadManager.
|
||||
if (!thread && manager->IsMainThread()) {
|
||||
thread = new Thread();
|
||||
thread->WrapCurrentWithThreadManager(manager, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
#if defined(WEBRTC_POSIX)
|
||||
#if !defined(WEBRTC_MAC)
|
||||
ThreadManager::ThreadManager() {
|
||||
main_thread_ref_ = CurrentThreadRef();
|
||||
pthread_key_create(&key_, nullptr);
|
||||
#ifndef NO_MAIN_THREAD_WRAPPING
|
||||
WrapCurrentThread();
|
||||
#endif
|
||||
}
|
||||
|
||||
ThreadManager::~ThreadManager() {
|
||||
UnwrapCurrentThread();
|
||||
pthread_key_delete(key_);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -62,15 +71,8 @@ void ThreadManager::SetCurrentThread(Thread *thread) {
|
||||
|
||||
#if defined(WEBRTC_WIN)
|
||||
ThreadManager::ThreadManager() {
|
||||
main_thread_ref_ = CurrentThreadRef();
|
||||
key_ = TlsAlloc();
|
||||
#ifndef NO_MAIN_THREAD_WRAPPING
|
||||
WrapCurrentThread();
|
||||
#endif
|
||||
}
|
||||
|
||||
ThreadManager::~ThreadManager() {
|
||||
UnwrapCurrentThread();
|
||||
TlsFree(key_);
|
||||
}
|
||||
|
||||
Thread *ThreadManager::CurrentThread() {
|
||||
@ -99,6 +101,10 @@ void ThreadManager::UnwrapCurrentThread() {
|
||||
}
|
||||
}
|
||||
|
||||
bool ThreadManager::IsMainThread() {
|
||||
return IsThreadRefEqual(CurrentThreadRef(), main_thread_ref_);
|
||||
}
|
||||
|
||||
Thread::ScopedDisallowBlockingCalls::ScopedDisallowBlockingCalls()
|
||||
: thread_(Thread::Current()),
|
||||
previous_state_(thread_->SetAllowBlockingCalls(false)) {
|
||||
@ -142,6 +148,10 @@ Thread::~Thread() {
|
||||
DoDestroy();
|
||||
}
|
||||
|
||||
bool Thread::IsCurrent() const {
|
||||
return ThreadManager::Instance()->CurrentThread() == this;
|
||||
}
|
||||
|
||||
std::unique_ptr<Thread> Thread::CreateWithSocketServer() {
|
||||
return std::unique_ptr<Thread>(new Thread(SocketServer::CreateDefault()));
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/event.h"
|
||||
#include "webrtc/base/messagequeue.h"
|
||||
#include "webrtc/base/platform_thread_types.h"
|
||||
|
||||
#if defined(WEBRTC_WIN)
|
||||
#include "webrtc/base/win32.h"
|
||||
@ -36,9 +37,7 @@ class ThreadManager {
|
||||
public:
|
||||
static const int kForever = -1;
|
||||
|
||||
ThreadManager();
|
||||
~ThreadManager();
|
||||
|
||||
// Singleton, constructor and destructor are private.
|
||||
static ThreadManager* Instance();
|
||||
|
||||
Thread* CurrentThread();
|
||||
@ -60,7 +59,12 @@ class ThreadManager {
|
||||
Thread *WrapCurrentThread();
|
||||
void UnwrapCurrentThread();
|
||||
|
||||
bool IsMainThread();
|
||||
|
||||
private:
|
||||
ThreadManager();
|
||||
~ThreadManager();
|
||||
|
||||
#if defined(WEBRTC_POSIX)
|
||||
pthread_key_t key_;
|
||||
#endif
|
||||
@ -69,6 +73,9 @@ class ThreadManager {
|
||||
DWORD key_;
|
||||
#endif
|
||||
|
||||
// The thread to potentially autowrap.
|
||||
PlatformThreadRef main_thread_ref_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(ThreadManager);
|
||||
};
|
||||
|
||||
@ -123,9 +130,7 @@ class LOCKABLE Thread : public MessageQueue {
|
||||
const bool previous_state_;
|
||||
};
|
||||
|
||||
bool IsCurrent() const {
|
||||
return Current() == this;
|
||||
}
|
||||
bool IsCurrent() const;
|
||||
|
||||
// Sleeps the calling thread for the specified number of milliseconds, during
|
||||
// which time no processing is performed. Returns false if sleeping was
|
||||
|
||||
@ -39,22 +39,13 @@ void InitCocoaMultiThreading() {
|
||||
namespace rtc {
|
||||
|
||||
ThreadManager::ThreadManager() {
|
||||
main_thread_ref_ = CurrentThreadRef();
|
||||
pthread_key_create(&key_, nullptr);
|
||||
#ifndef NO_MAIN_THREAD_WRAPPING
|
||||
WrapCurrentThread();
|
||||
#endif
|
||||
// This is necessary to alert the cocoa runtime of the fact that
|
||||
// we are running in a multithreaded environment.
|
||||
InitCocoaMultiThreading();
|
||||
}
|
||||
|
||||
ThreadManager::~ThreadManager() {
|
||||
@autoreleasepool {
|
||||
UnwrapCurrentThread();
|
||||
pthread_key_delete(key_);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void* Thread::PreRun(void* pv) {
|
||||
ThreadInit* init = static_cast<ThreadInit*>(pv);
|
||||
|
||||
Reference in New Issue
Block a user