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}
diff --git a/webrtc/base/thread.cc b/webrtc/base/thread.cc
index b5be475..9a71c1a 100644
--- a/webrtc/base/thread.cc
+++ b/webrtc/base/thread.cc
@@ -31,23 +31,32 @@
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 @@
#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 @@
}
}
+bool ThreadManager::IsMainThread() {
+ return IsThreadRefEqual(CurrentThreadRef(), main_thread_ref_);
+}
+
Thread::ScopedDisallowBlockingCalls::ScopedDisallowBlockingCalls()
: thread_(Thread::Current()),
previous_state_(thread_->SetAllowBlockingCalls(false)) {
@@ -142,6 +148,10 @@
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()));
}