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:
nisse
2017-04-26 01:45:31 -07:00
committed by Commit bot
parent 20a60853a6
commit 7866cfe575
3 changed files with 39 additions and 33 deletions

View File

@ -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()));
}

View File

@ -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

View File

@ -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);