diff --git a/rtc_base/signalthread.cc b/rtc_base/signalthread.cc index 4bf7d7c4eb..48a677e378 100644 --- a/rtc_base/signalthread.cc +++ b/rtc_base/signalthread.cc @@ -11,6 +11,7 @@ #include "rtc_base/signalthread.h" #include "rtc_base/checks.h" +#include "rtc_base/ptr_util.h" namespace rtc { @@ -124,6 +125,12 @@ void SignalThread::OnMessage(Message *msg) { } } +SignalThread::Worker::Worker(SignalThread* parent) + : Thread(MakeUnique(), /*do_init=*/false), + parent_(parent) { + DoInit(); +} + SignalThread::Worker::~Worker() { Stop(); } diff --git a/rtc_base/signalthread.h b/rtc_base/signalthread.h index 2c11da4507..8daaa0830e 100644 --- a/rtc_base/signalthread.h +++ b/rtc_base/signalthread.h @@ -104,9 +104,7 @@ class SignalThread class Worker : public Thread { public: - explicit Worker(SignalThread* parent) - : Thread(std::unique_ptr(new NullSocketServer())), - parent_(parent) {} + explicit Worker(SignalThread* parent); ~Worker() override; void Run() override; bool IsProcessingMessages() override; diff --git a/rtc_base/thread.cc b/rtc_base/thread.cc index 749334125f..bb7b5919e9 100644 --- a/rtc_base/thread.cc +++ b/rtc_base/thread.cc @@ -124,15 +124,25 @@ Thread::ScopedDisallowBlockingCalls::~ScopedDisallowBlockingCalls() { // DEPRECATED. Thread::Thread() : Thread(SocketServer::CreateDefault()) {} -Thread::Thread(SocketServer* ss) : MessageQueue(ss, false) { - SetName("Thread", this); // default name - DoInit(); -} +Thread::Thread(SocketServer* ss) : Thread(ss, /*do_init=*/true) {} Thread::Thread(std::unique_ptr ss) + : Thread(std::move(ss), /*do_init=*/true) {} + +Thread::Thread(SocketServer* ss, bool do_init) + : MessageQueue(ss, /*do_init=*/false) { + SetName("Thread", this); // default name + if (do_init) { + DoInit(); + } +} + +Thread::Thread(std::unique_ptr ss, bool do_init) : MessageQueue(std::move(ss), false) { SetName("Thread", this); // default name - DoInit(); + if (do_init) { + DoInit(); + } } Thread::~Thread() { @@ -524,7 +534,9 @@ bool Thread::IsRunning() { #endif } -AutoThread::AutoThread() : Thread(SocketServer::CreateDefault()) { +AutoThread::AutoThread() + : Thread(SocketServer::CreateDefault(), /*do_init=*/false) { + DoInit(); if (!ThreadManager::Instance()->CurrentThread()) { ThreadManager::Instance()->SetCurrentThread(this); } @@ -539,7 +551,8 @@ AutoThread::~AutoThread() { } AutoSocketServerThread::AutoSocketServerThread(SocketServer* ss) - : Thread(ss) { + : Thread(ss, /*do_init=*/false) { + DoInit(); old_thread_ = ThreadManager::Instance()->CurrentThread(); // Temporarily set the current thread to nullptr so that we can keep checks // around that catch unintentional pointer overwrites. diff --git a/rtc_base/thread.h b/rtc_base/thread.h index ab6c7b1b50..568764e65b 100644 --- a/rtc_base/thread.h +++ b/rtc_base/thread.h @@ -111,6 +111,11 @@ class RTC_LOCKABLE Thread : public MessageQueue { explicit Thread(SocketServer* ss); explicit Thread(std::unique_ptr ss); + // Constructors meant for subclasses; they should call DoInit themselves and + // pass false for |do_init|, so that DoInit is called only on the fully + // instantiated class, which avoids a vptr data race. + Thread(SocketServer* ss, bool do_init); + Thread(std::unique_ptr ss, bool do_init); // NOTE: ALL SUBCLASSES OF Thread MUST CALL Stop() IN THEIR DESTRUCTORS (or // guarantee Stop() is explicitly called before the subclass is destroyed).