1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #ifndef RTC_BASE_THREAD_H_ 12*d9f75844SAndroid Build Coastguard Worker #define RTC_BASE_THREAD_H_ 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker #include <stdint.h> 15*d9f75844SAndroid Build Coastguard Worker 16*d9f75844SAndroid Build Coastguard Worker #include <list> 17*d9f75844SAndroid Build Coastguard Worker #include <map> 18*d9f75844SAndroid Build Coastguard Worker #include <memory> 19*d9f75844SAndroid Build Coastguard Worker #include <queue> 20*d9f75844SAndroid Build Coastguard Worker #include <set> 21*d9f75844SAndroid Build Coastguard Worker #include <string> 22*d9f75844SAndroid Build Coastguard Worker #include <type_traits> 23*d9f75844SAndroid Build Coastguard Worker #include <utility> 24*d9f75844SAndroid Build Coastguard Worker #include <vector> 25*d9f75844SAndroid Build Coastguard Worker 26*d9f75844SAndroid Build Coastguard Worker #include "absl/strings/string_view.h" 27*d9f75844SAndroid Build Coastguard Worker 28*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_POSIX) 29*d9f75844SAndroid Build Coastguard Worker #include <pthread.h> 30*d9f75844SAndroid Build Coastguard Worker #endif 31*d9f75844SAndroid Build Coastguard Worker #include "absl/base/attributes.h" 32*d9f75844SAndroid Build Coastguard Worker #include "absl/functional/any_invocable.h" 33*d9f75844SAndroid Build Coastguard Worker #include "api/function_view.h" 34*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/task_queue_base.h" 35*d9f75844SAndroid Build Coastguard Worker #include "api/units/time_delta.h" 36*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h" 37*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/deprecated/recursive_critical_section.h" 38*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/platform_thread_types.h" 39*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/socket_server.h" 40*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/synchronization/mutex.h" 41*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/rtc_export.h" 42*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread_annotations.h" 43*d9f75844SAndroid Build Coastguard Worker 44*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN) 45*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/win32.h" 46*d9f75844SAndroid Build Coastguard Worker #endif 47*d9f75844SAndroid Build Coastguard Worker 48*d9f75844SAndroid Build Coastguard Worker #if RTC_DCHECK_IS_ON 49*d9f75844SAndroid Build Coastguard Worker // Counts how many `Thread::BlockingCall` are made from within a scope and logs 50*d9f75844SAndroid Build Coastguard Worker // the number of blocking calls at the end of the scope. 51*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_THREAD_BLOCK_COUNT() \ 52*d9f75844SAndroid Build Coastguard Worker rtc::Thread::ScopedCountBlockingCalls blocked_call_count_printer( \ 53*d9f75844SAndroid Build Coastguard Worker [func = __func__](uint32_t actual_block, uint32_t could_block) { \ 54*d9f75844SAndroid Build Coastguard Worker auto total = actual_block + could_block; \ 55*d9f75844SAndroid Build Coastguard Worker if (total) { \ 56*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_WARNING) << "Blocking " << func << ": total=" << total \ 57*d9f75844SAndroid Build Coastguard Worker << " (actual=" << actual_block \ 58*d9f75844SAndroid Build Coastguard Worker << ", could=" << could_block << ")"; \ 59*d9f75844SAndroid Build Coastguard Worker } \ 60*d9f75844SAndroid Build Coastguard Worker }) 61*d9f75844SAndroid Build Coastguard Worker 62*d9f75844SAndroid Build Coastguard Worker // Adds an RTC_DCHECK_LE that checks that the number of blocking calls are 63*d9f75844SAndroid Build Coastguard Worker // less than or equal to a specific value. Use to avoid regressing in the 64*d9f75844SAndroid Build Coastguard Worker // number of blocking thread calls. 65*d9f75844SAndroid Build Coastguard Worker // Note: Use of this macro, requires RTC_LOG_THREAD_BLOCK_COUNT() to be called 66*d9f75844SAndroid Build Coastguard Worker // first. 67*d9f75844SAndroid Build Coastguard Worker #define RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(x) \ 68*d9f75844SAndroid Build Coastguard Worker do { \ 69*d9f75844SAndroid Build Coastguard Worker blocked_call_count_printer.set_minimum_call_count_for_callback(x + 1); \ 70*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_LE(blocked_call_count_printer.GetTotalBlockedCallCount(), x); \ 71*d9f75844SAndroid Build Coastguard Worker } while (0) 72*d9f75844SAndroid Build Coastguard Worker #else 73*d9f75844SAndroid Build Coastguard Worker #define RTC_LOG_THREAD_BLOCK_COUNT() 74*d9f75844SAndroid Build Coastguard Worker #define RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(x) 75*d9f75844SAndroid Build Coastguard Worker #endif 76*d9f75844SAndroid Build Coastguard Worker 77*d9f75844SAndroid Build Coastguard Worker namespace rtc { 78*d9f75844SAndroid Build Coastguard Worker 79*d9f75844SAndroid Build Coastguard Worker class Thread; 80*d9f75844SAndroid Build Coastguard Worker 81*d9f75844SAndroid Build Coastguard Worker class RTC_EXPORT ThreadManager { 82*d9f75844SAndroid Build Coastguard Worker public: 83*d9f75844SAndroid Build Coastguard Worker static const int kForever = -1; 84*d9f75844SAndroid Build Coastguard Worker 85*d9f75844SAndroid Build Coastguard Worker // Singleton, constructor and destructor are private. 86*d9f75844SAndroid Build Coastguard Worker static ThreadManager* Instance(); 87*d9f75844SAndroid Build Coastguard Worker 88*d9f75844SAndroid Build Coastguard Worker static void Add(Thread* message_queue); 89*d9f75844SAndroid Build Coastguard Worker static void Remove(Thread* message_queue); 90*d9f75844SAndroid Build Coastguard Worker 91*d9f75844SAndroid Build Coastguard Worker // For testing purposes, for use with a simulated clock. 92*d9f75844SAndroid Build Coastguard Worker // Ensures that all message queues have processed delayed messages 93*d9f75844SAndroid Build Coastguard Worker // up until the current point in time. 94*d9f75844SAndroid Build Coastguard Worker static void ProcessAllMessageQueuesForTesting(); 95*d9f75844SAndroid Build Coastguard Worker 96*d9f75844SAndroid Build Coastguard Worker Thread* CurrentThread(); 97*d9f75844SAndroid Build Coastguard Worker void SetCurrentThread(Thread* thread); 98*d9f75844SAndroid Build Coastguard Worker // Allows changing the current thread, this is intended for tests where we 99*d9f75844SAndroid Build Coastguard Worker // want to simulate multiple threads running on a single physical thread. 100*d9f75844SAndroid Build Coastguard Worker void ChangeCurrentThreadForTest(Thread* thread); 101*d9f75844SAndroid Build Coastguard Worker 102*d9f75844SAndroid Build Coastguard Worker // Returns a thread object with its thread_ ivar set 103*d9f75844SAndroid Build Coastguard Worker // to whatever the OS uses to represent the thread. 104*d9f75844SAndroid Build Coastguard Worker // If there already *is* a Thread object corresponding to this thread, 105*d9f75844SAndroid Build Coastguard Worker // this method will return that. Otherwise it creates a new Thread 106*d9f75844SAndroid Build Coastguard Worker // object whose wrapped() method will return true, and whose 107*d9f75844SAndroid Build Coastguard Worker // handle will, on Win32, be opened with only synchronization privileges - 108*d9f75844SAndroid Build Coastguard Worker // if you need more privilegs, rather than changing this method, please 109*d9f75844SAndroid Build Coastguard Worker // write additional code to adjust the privileges, or call a different 110*d9f75844SAndroid Build Coastguard Worker // factory method of your own devising, because this one gets used in 111*d9f75844SAndroid Build Coastguard Worker // unexpected contexts (like inside browser plugins) and it would be a 112*d9f75844SAndroid Build Coastguard Worker // shame to break it. It is also conceivable on Win32 that we won't even 113*d9f75844SAndroid Build Coastguard Worker // be able to get synchronization privileges, in which case the result 114*d9f75844SAndroid Build Coastguard Worker // will have a null handle. 115*d9f75844SAndroid Build Coastguard Worker Thread* WrapCurrentThread(); 116*d9f75844SAndroid Build Coastguard Worker void UnwrapCurrentThread(); 117*d9f75844SAndroid Build Coastguard Worker 118*d9f75844SAndroid Build Coastguard Worker #if RTC_DCHECK_IS_ON 119*d9f75844SAndroid Build Coastguard Worker // Registers that a Send operation is to be performed between `source` and 120*d9f75844SAndroid Build Coastguard Worker // `target`, while checking that this does not cause a send cycle that could 121*d9f75844SAndroid Build Coastguard Worker // potentially cause a deadlock. 122*d9f75844SAndroid Build Coastguard Worker void RegisterSendAndCheckForCycles(Thread* source, Thread* target); 123*d9f75844SAndroid Build Coastguard Worker #endif 124*d9f75844SAndroid Build Coastguard Worker 125*d9f75844SAndroid Build Coastguard Worker private: 126*d9f75844SAndroid Build Coastguard Worker ThreadManager(); 127*d9f75844SAndroid Build Coastguard Worker ~ThreadManager(); 128*d9f75844SAndroid Build Coastguard Worker 129*d9f75844SAndroid Build Coastguard Worker ThreadManager(const ThreadManager&) = delete; 130*d9f75844SAndroid Build Coastguard Worker ThreadManager& operator=(const ThreadManager&) = delete; 131*d9f75844SAndroid Build Coastguard Worker 132*d9f75844SAndroid Build Coastguard Worker void SetCurrentThreadInternal(Thread* thread); 133*d9f75844SAndroid Build Coastguard Worker void AddInternal(Thread* message_queue); 134*d9f75844SAndroid Build Coastguard Worker void RemoveInternal(Thread* message_queue); 135*d9f75844SAndroid Build Coastguard Worker void ProcessAllMessageQueuesInternal(); 136*d9f75844SAndroid Build Coastguard Worker #if RTC_DCHECK_IS_ON 137*d9f75844SAndroid Build Coastguard Worker void RemoveFromSendGraph(Thread* thread) RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_); 138*d9f75844SAndroid Build Coastguard Worker #endif 139*d9f75844SAndroid Build Coastguard Worker 140*d9f75844SAndroid Build Coastguard Worker // This list contains all live Threads. 141*d9f75844SAndroid Build Coastguard Worker std::vector<Thread*> message_queues_ RTC_GUARDED_BY(crit_); 142*d9f75844SAndroid Build Coastguard Worker 143*d9f75844SAndroid Build Coastguard Worker // Methods that don't modify the list of message queues may be called in a 144*d9f75844SAndroid Build Coastguard Worker // re-entrant fashion. "processing_" keeps track of the depth of re-entrant 145*d9f75844SAndroid Build Coastguard Worker // calls. 146*d9f75844SAndroid Build Coastguard Worker RecursiveCriticalSection crit_; 147*d9f75844SAndroid Build Coastguard Worker size_t processing_ RTC_GUARDED_BY(crit_) = 0; 148*d9f75844SAndroid Build Coastguard Worker #if RTC_DCHECK_IS_ON 149*d9f75844SAndroid Build Coastguard Worker // Represents all thread seand actions by storing all send targets per thread. 150*d9f75844SAndroid Build Coastguard Worker // This is used by RegisterSendAndCheckForCycles. This graph has no cycles 151*d9f75844SAndroid Build Coastguard Worker // since we will trigger a CHECK failure if a cycle is introduced. 152*d9f75844SAndroid Build Coastguard Worker std::map<Thread*, std::set<Thread*>> send_graph_ RTC_GUARDED_BY(crit_); 153*d9f75844SAndroid Build Coastguard Worker #endif 154*d9f75844SAndroid Build Coastguard Worker 155*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_POSIX) 156*d9f75844SAndroid Build Coastguard Worker pthread_key_t key_; 157*d9f75844SAndroid Build Coastguard Worker #endif 158*d9f75844SAndroid Build Coastguard Worker 159*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN) 160*d9f75844SAndroid Build Coastguard Worker const DWORD key_; 161*d9f75844SAndroid Build Coastguard Worker #endif 162*d9f75844SAndroid Build Coastguard Worker }; 163*d9f75844SAndroid Build Coastguard Worker 164*d9f75844SAndroid Build Coastguard Worker // WARNING! SUBCLASSES MUST CALL Stop() IN THEIR DESTRUCTORS! See ~Thread(). 165*d9f75844SAndroid Build Coastguard Worker 166*d9f75844SAndroid Build Coastguard Worker class RTC_LOCKABLE RTC_EXPORT Thread : public webrtc::TaskQueueBase { 167*d9f75844SAndroid Build Coastguard Worker public: 168*d9f75844SAndroid Build Coastguard Worker static const int kForever = -1; 169*d9f75844SAndroid Build Coastguard Worker 170*d9f75844SAndroid Build Coastguard Worker // Create a new Thread and optionally assign it to the passed 171*d9f75844SAndroid Build Coastguard Worker // SocketServer. Subclasses that override Clear should pass false for 172*d9f75844SAndroid Build Coastguard Worker // init_queue and call DoInit() from their constructor to prevent races 173*d9f75844SAndroid Build Coastguard Worker // with the ThreadManager using the object while the vtable is still 174*d9f75844SAndroid Build Coastguard Worker // being created. 175*d9f75844SAndroid Build Coastguard Worker explicit Thread(SocketServer* ss); 176*d9f75844SAndroid Build Coastguard Worker explicit Thread(std::unique_ptr<SocketServer> ss); 177*d9f75844SAndroid Build Coastguard Worker 178*d9f75844SAndroid Build Coastguard Worker // Constructors meant for subclasses; they should call DoInit themselves and 179*d9f75844SAndroid Build Coastguard Worker // pass false for `do_init`, so that DoInit is called only on the fully 180*d9f75844SAndroid Build Coastguard Worker // instantiated class, which avoids a vptr data race. 181*d9f75844SAndroid Build Coastguard Worker Thread(SocketServer* ss, bool do_init); 182*d9f75844SAndroid Build Coastguard Worker Thread(std::unique_ptr<SocketServer> ss, bool do_init); 183*d9f75844SAndroid Build Coastguard Worker 184*d9f75844SAndroid Build Coastguard Worker // NOTE: ALL SUBCLASSES OF Thread MUST CALL Stop() IN THEIR DESTRUCTORS (or 185*d9f75844SAndroid Build Coastguard Worker // guarantee Stop() is explicitly called before the subclass is destroyed). 186*d9f75844SAndroid Build Coastguard Worker // This is required to avoid a data race between the destructor modifying the 187*d9f75844SAndroid Build Coastguard Worker // vtable, and the Thread::PreRun calling the virtual method Run(). 188*d9f75844SAndroid Build Coastguard Worker 189*d9f75844SAndroid Build Coastguard Worker // NOTE: SUBCLASSES OF Thread THAT OVERRIDE Clear MUST CALL 190*d9f75844SAndroid Build Coastguard Worker // DoDestroy() IN THEIR DESTRUCTORS! This is required to avoid a data race 191*d9f75844SAndroid Build Coastguard Worker // between the destructor modifying the vtable, and the ThreadManager 192*d9f75844SAndroid Build Coastguard Worker // calling Clear on the object from a different thread. 193*d9f75844SAndroid Build Coastguard Worker ~Thread() override; 194*d9f75844SAndroid Build Coastguard Worker 195*d9f75844SAndroid Build Coastguard Worker Thread(const Thread&) = delete; 196*d9f75844SAndroid Build Coastguard Worker Thread& operator=(const Thread&) = delete; 197*d9f75844SAndroid Build Coastguard Worker 198*d9f75844SAndroid Build Coastguard Worker static std::unique_ptr<Thread> CreateWithSocketServer(); 199*d9f75844SAndroid Build Coastguard Worker static std::unique_ptr<Thread> Create(); 200*d9f75844SAndroid Build Coastguard Worker static Thread* Current(); 201*d9f75844SAndroid Build Coastguard Worker 202*d9f75844SAndroid Build Coastguard Worker // Used to catch performance regressions. Use this to disallow BlockingCall 203*d9f75844SAndroid Build Coastguard Worker // for a given scope. If a synchronous call is made while this is in 204*d9f75844SAndroid Build Coastguard Worker // effect, an assert will be triggered. 205*d9f75844SAndroid Build Coastguard Worker // Note that this is a single threaded class. 206*d9f75844SAndroid Build Coastguard Worker class ScopedDisallowBlockingCalls { 207*d9f75844SAndroid Build Coastguard Worker public: 208*d9f75844SAndroid Build Coastguard Worker ScopedDisallowBlockingCalls(); 209*d9f75844SAndroid Build Coastguard Worker ScopedDisallowBlockingCalls(const ScopedDisallowBlockingCalls&) = delete; 210*d9f75844SAndroid Build Coastguard Worker ScopedDisallowBlockingCalls& operator=(const ScopedDisallowBlockingCalls&) = 211*d9f75844SAndroid Build Coastguard Worker delete; 212*d9f75844SAndroid Build Coastguard Worker ~ScopedDisallowBlockingCalls(); 213*d9f75844SAndroid Build Coastguard Worker 214*d9f75844SAndroid Build Coastguard Worker private: 215*d9f75844SAndroid Build Coastguard Worker Thread* const thread_; 216*d9f75844SAndroid Build Coastguard Worker const bool previous_state_; 217*d9f75844SAndroid Build Coastguard Worker }; 218*d9f75844SAndroid Build Coastguard Worker 219*d9f75844SAndroid Build Coastguard Worker #if RTC_DCHECK_IS_ON 220*d9f75844SAndroid Build Coastguard Worker class ScopedCountBlockingCalls { 221*d9f75844SAndroid Build Coastguard Worker public: 222*d9f75844SAndroid Build Coastguard Worker ScopedCountBlockingCalls(std::function<void(uint32_t, uint32_t)> callback); 223*d9f75844SAndroid Build Coastguard Worker ScopedCountBlockingCalls(const ScopedDisallowBlockingCalls&) = delete; 224*d9f75844SAndroid Build Coastguard Worker ScopedCountBlockingCalls& operator=(const ScopedDisallowBlockingCalls&) = 225*d9f75844SAndroid Build Coastguard Worker delete; 226*d9f75844SAndroid Build Coastguard Worker ~ScopedCountBlockingCalls(); 227*d9f75844SAndroid Build Coastguard Worker 228*d9f75844SAndroid Build Coastguard Worker uint32_t GetBlockingCallCount() const; 229*d9f75844SAndroid Build Coastguard Worker uint32_t GetCouldBeBlockingCallCount() const; 230*d9f75844SAndroid Build Coastguard Worker uint32_t GetTotalBlockedCallCount() const; 231*d9f75844SAndroid Build Coastguard Worker set_minimum_call_count_for_callback(uint32_t minimum)232*d9f75844SAndroid Build Coastguard Worker void set_minimum_call_count_for_callback(uint32_t minimum) { 233*d9f75844SAndroid Build Coastguard Worker min_blocking_calls_for_callback_ = minimum; 234*d9f75844SAndroid Build Coastguard Worker } 235*d9f75844SAndroid Build Coastguard Worker 236*d9f75844SAndroid Build Coastguard Worker private: 237*d9f75844SAndroid Build Coastguard Worker Thread* const thread_; 238*d9f75844SAndroid Build Coastguard Worker const uint32_t base_blocking_call_count_; 239*d9f75844SAndroid Build Coastguard Worker const uint32_t base_could_be_blocking_call_count_; 240*d9f75844SAndroid Build Coastguard Worker // The minimum number of blocking calls required in order to issue the 241*d9f75844SAndroid Build Coastguard Worker // result_callback_. This is used by RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN to 242*d9f75844SAndroid Build Coastguard Worker // tame log spam. 243*d9f75844SAndroid Build Coastguard Worker // By default we always issue the callback, regardless of callback count. 244*d9f75844SAndroid Build Coastguard Worker uint32_t min_blocking_calls_for_callback_ = 0; 245*d9f75844SAndroid Build Coastguard Worker std::function<void(uint32_t, uint32_t)> result_callback_; 246*d9f75844SAndroid Build Coastguard Worker }; 247*d9f75844SAndroid Build Coastguard Worker 248*d9f75844SAndroid Build Coastguard Worker uint32_t GetBlockingCallCount() const; 249*d9f75844SAndroid Build Coastguard Worker uint32_t GetCouldBeBlockingCallCount() const; 250*d9f75844SAndroid Build Coastguard Worker #endif 251*d9f75844SAndroid Build Coastguard Worker 252*d9f75844SAndroid Build Coastguard Worker SocketServer* socketserver(); 253*d9f75844SAndroid Build Coastguard Worker 254*d9f75844SAndroid Build Coastguard Worker // Note: The behavior of Thread has changed. When a thread is stopped, 255*d9f75844SAndroid Build Coastguard Worker // futher Posts and Sends will fail. However, any pending Sends and *ready* 256*d9f75844SAndroid Build Coastguard Worker // Posts (as opposed to unexpired delayed Posts) will be delivered before 257*d9f75844SAndroid Build Coastguard Worker // Get (or Peek) returns false. By guaranteeing delivery of those messages, 258*d9f75844SAndroid Build Coastguard Worker // we eliminate the race condition when an MessageHandler and Thread 259*d9f75844SAndroid Build Coastguard Worker // may be destroyed independently of each other. 260*d9f75844SAndroid Build Coastguard Worker virtual void Quit(); 261*d9f75844SAndroid Build Coastguard Worker virtual bool IsQuitting(); 262*d9f75844SAndroid Build Coastguard Worker virtual void Restart(); 263*d9f75844SAndroid Build Coastguard Worker // Not all message queues actually process messages (such as SignalThread). 264*d9f75844SAndroid Build Coastguard Worker // In those cases, it's important to know, before posting, that it won't be 265*d9f75844SAndroid Build Coastguard Worker // Processed. Normally, this would be true until IsQuitting() is true. 266*d9f75844SAndroid Build Coastguard Worker virtual bool IsProcessingMessagesForTesting(); 267*d9f75844SAndroid Build Coastguard Worker 268*d9f75844SAndroid Build Coastguard Worker // Amount of time until the next message can be retrieved 269*d9f75844SAndroid Build Coastguard Worker virtual int GetDelay(); 270*d9f75844SAndroid Build Coastguard Worker empty()271*d9f75844SAndroid Build Coastguard Worker bool empty() const { return size() == 0u; } size()272*d9f75844SAndroid Build Coastguard Worker size_t size() const { 273*d9f75844SAndroid Build Coastguard Worker webrtc::MutexLock lock(&mutex_); 274*d9f75844SAndroid Build Coastguard Worker return messages_.size() + delayed_messages_.size(); 275*d9f75844SAndroid Build Coastguard Worker } 276*d9f75844SAndroid Build Coastguard Worker 277*d9f75844SAndroid Build Coastguard Worker bool IsCurrent() const; 278*d9f75844SAndroid Build Coastguard Worker 279*d9f75844SAndroid Build Coastguard Worker // Sleeps the calling thread for the specified number of milliseconds, during 280*d9f75844SAndroid Build Coastguard Worker // which time no processing is performed. Returns false if sleeping was 281*d9f75844SAndroid Build Coastguard Worker // interrupted by a signal (POSIX only). 282*d9f75844SAndroid Build Coastguard Worker static bool SleepMs(int millis); 283*d9f75844SAndroid Build Coastguard Worker 284*d9f75844SAndroid Build Coastguard Worker // Sets the thread's name, for debugging. Must be called before Start(). 285*d9f75844SAndroid Build Coastguard Worker // If `obj` is non-null, its value is appended to `name`. name()286*d9f75844SAndroid Build Coastguard Worker const std::string& name() const { return name_; } 287*d9f75844SAndroid Build Coastguard Worker bool SetName(absl::string_view name, const void* obj); 288*d9f75844SAndroid Build Coastguard Worker 289*d9f75844SAndroid Build Coastguard Worker // Sets the expected processing time in ms. The thread will write 290*d9f75844SAndroid Build Coastguard Worker // log messages when Dispatch() takes more time than this. 291*d9f75844SAndroid Build Coastguard Worker // Default is 50 ms. 292*d9f75844SAndroid Build Coastguard Worker void SetDispatchWarningMs(int deadline); 293*d9f75844SAndroid Build Coastguard Worker 294*d9f75844SAndroid Build Coastguard Worker // Starts the execution of the thread. 295*d9f75844SAndroid Build Coastguard Worker bool Start(); 296*d9f75844SAndroid Build Coastguard Worker 297*d9f75844SAndroid Build Coastguard Worker // Tells the thread to stop and waits until it is joined. 298*d9f75844SAndroid Build Coastguard Worker // Never call Stop on the current thread. Instead use the inherited Quit 299*d9f75844SAndroid Build Coastguard Worker // function which will exit the base Thread without terminating the 300*d9f75844SAndroid Build Coastguard Worker // underlying OS thread. 301*d9f75844SAndroid Build Coastguard Worker virtual void Stop(); 302*d9f75844SAndroid Build Coastguard Worker 303*d9f75844SAndroid Build Coastguard Worker // By default, Thread::Run() calls ProcessMessages(kForever). To do other 304*d9f75844SAndroid Build Coastguard Worker // work, override Run(). To receive and dispatch messages, call 305*d9f75844SAndroid Build Coastguard Worker // ProcessMessages occasionally. 306*d9f75844SAndroid Build Coastguard Worker virtual void Run(); 307*d9f75844SAndroid Build Coastguard Worker 308*d9f75844SAndroid Build Coastguard Worker // Convenience method to invoke a functor on another thread. 309*d9f75844SAndroid Build Coastguard Worker // Blocks the current thread until execution is complete. 310*d9f75844SAndroid Build Coastguard Worker // Ex: thread.BlockingCall([&] { result = MyFunctionReturningBool(); }); 311*d9f75844SAndroid Build Coastguard Worker // NOTE: This function can only be called when synchronous calls are allowed. 312*d9f75844SAndroid Build Coastguard Worker // See ScopedDisallowBlockingCalls for details. 313*d9f75844SAndroid Build Coastguard Worker // NOTE: Blocking calls are DISCOURAGED, consider if what you're doing can 314*d9f75844SAndroid Build Coastguard Worker // be achieved with PostTask() and callbacks instead. 315*d9f75844SAndroid Build Coastguard Worker virtual void BlockingCall(FunctionView<void()> functor); 316*d9f75844SAndroid Build Coastguard Worker 317*d9f75844SAndroid Build Coastguard Worker template <typename Functor, 318*d9f75844SAndroid Build Coastguard Worker typename ReturnT = std::invoke_result_t<Functor>, 319*d9f75844SAndroid Build Coastguard Worker typename = typename std::enable_if_t<!std::is_void_v<ReturnT>>> BlockingCall(Functor && functor)320*d9f75844SAndroid Build Coastguard Worker ReturnT BlockingCall(Functor&& functor) { 321*d9f75844SAndroid Build Coastguard Worker ReturnT result; 322*d9f75844SAndroid Build Coastguard Worker BlockingCall([&] { result = std::forward<Functor>(functor)(); }); 323*d9f75844SAndroid Build Coastguard Worker return result; 324*d9f75844SAndroid Build Coastguard Worker } 325*d9f75844SAndroid Build Coastguard Worker 326*d9f75844SAndroid Build Coastguard Worker // Allows BlockingCall to specified `thread`. Thread never will be 327*d9f75844SAndroid Build Coastguard Worker // dereferenced and will be used only for reference-based comparison, so 328*d9f75844SAndroid Build Coastguard Worker // instance can be safely deleted. If NDEBUG is defined and RTC_DCHECK_IS_ON 329*d9f75844SAndroid Build Coastguard Worker // is undefined do nothing. 330*d9f75844SAndroid Build Coastguard Worker void AllowInvokesToThread(Thread* thread); 331*d9f75844SAndroid Build Coastguard Worker 332*d9f75844SAndroid Build Coastguard Worker // If NDEBUG is defined and RTC_DCHECK_IS_ON is undefined do nothing. 333*d9f75844SAndroid Build Coastguard Worker void DisallowAllInvokes(); 334*d9f75844SAndroid Build Coastguard Worker // Returns true if `target` was allowed by AllowInvokesToThread() or if no 335*d9f75844SAndroid Build Coastguard Worker // calls were made to AllowInvokesToThread and DisallowAllInvokes. Otherwise 336*d9f75844SAndroid Build Coastguard Worker // returns false. 337*d9f75844SAndroid Build Coastguard Worker // If NDEBUG is defined and RTC_DCHECK_IS_ON is undefined always returns 338*d9f75844SAndroid Build Coastguard Worker // true. 339*d9f75844SAndroid Build Coastguard Worker bool IsInvokeToThreadAllowed(rtc::Thread* target); 340*d9f75844SAndroid Build Coastguard Worker 341*d9f75844SAndroid Build Coastguard Worker // From TaskQueueBase 342*d9f75844SAndroid Build Coastguard Worker void Delete() override; 343*d9f75844SAndroid Build Coastguard Worker void PostTask(absl::AnyInvocable<void() &&> task) override; 344*d9f75844SAndroid Build Coastguard Worker void PostDelayedTask(absl::AnyInvocable<void() &&> task, 345*d9f75844SAndroid Build Coastguard Worker webrtc::TimeDelta delay) override; 346*d9f75844SAndroid Build Coastguard Worker void PostDelayedHighPrecisionTask(absl::AnyInvocable<void() &&> task, 347*d9f75844SAndroid Build Coastguard Worker webrtc::TimeDelta delay) override; 348*d9f75844SAndroid Build Coastguard Worker 349*d9f75844SAndroid Build Coastguard Worker // ProcessMessages will process I/O and dispatch messages until: 350*d9f75844SAndroid Build Coastguard Worker // 1) cms milliseconds have elapsed (returns true) 351*d9f75844SAndroid Build Coastguard Worker // 2) Stop() is called (returns false) 352*d9f75844SAndroid Build Coastguard Worker bool ProcessMessages(int cms); 353*d9f75844SAndroid Build Coastguard Worker 354*d9f75844SAndroid Build Coastguard Worker // Returns true if this is a thread that we created using the standard 355*d9f75844SAndroid Build Coastguard Worker // constructor, false if it was created by a call to 356*d9f75844SAndroid Build Coastguard Worker // ThreadManager::WrapCurrentThread(). The main thread of an application 357*d9f75844SAndroid Build Coastguard Worker // is generally not owned, since the OS representation of the thread 358*d9f75844SAndroid Build Coastguard Worker // obviously exists before we can get to it. 359*d9f75844SAndroid Build Coastguard Worker // You cannot call Start on non-owned threads. 360*d9f75844SAndroid Build Coastguard Worker bool IsOwned(); 361*d9f75844SAndroid Build Coastguard Worker 362*d9f75844SAndroid Build Coastguard Worker // Expose private method IsRunning() for tests. 363*d9f75844SAndroid Build Coastguard Worker // 364*d9f75844SAndroid Build Coastguard Worker // DANGER: this is a terrible public API. Most callers that might want to 365*d9f75844SAndroid Build Coastguard Worker // call this likely do not have enough control/knowledge of the Thread in 366*d9f75844SAndroid Build Coastguard Worker // question to guarantee that the returned value remains true for the duration 367*d9f75844SAndroid Build Coastguard Worker // of whatever code is conditionally executing because of the return value! RunningForTest()368*d9f75844SAndroid Build Coastguard Worker bool RunningForTest() { return IsRunning(); } 369*d9f75844SAndroid Build Coastguard Worker 370*d9f75844SAndroid Build Coastguard Worker // These functions are public to avoid injecting test hooks. Don't call them 371*d9f75844SAndroid Build Coastguard Worker // outside of tests. 372*d9f75844SAndroid Build Coastguard Worker // This method should be called when thread is created using non standard 373*d9f75844SAndroid Build Coastguard Worker // method, like derived implementation of rtc::Thread and it can not be 374*d9f75844SAndroid Build Coastguard Worker // started by calling Start(). This will set started flag to true and 375*d9f75844SAndroid Build Coastguard Worker // owned to false. This must be called from the current thread. 376*d9f75844SAndroid Build Coastguard Worker bool WrapCurrent(); 377*d9f75844SAndroid Build Coastguard Worker void UnwrapCurrent(); 378*d9f75844SAndroid Build Coastguard Worker 379*d9f75844SAndroid Build Coastguard Worker // Sets the per-thread allow-blocking-calls flag to false; this is 380*d9f75844SAndroid Build Coastguard Worker // irrevocable. Must be called on this thread. DisallowBlockingCalls()381*d9f75844SAndroid Build Coastguard Worker void DisallowBlockingCalls() { SetAllowBlockingCalls(false); } 382*d9f75844SAndroid Build Coastguard Worker 383*d9f75844SAndroid Build Coastguard Worker protected: 384*d9f75844SAndroid Build Coastguard Worker class CurrentThreadSetter : CurrentTaskQueueSetter { 385*d9f75844SAndroid Build Coastguard Worker public: CurrentThreadSetter(Thread * thread)386*d9f75844SAndroid Build Coastguard Worker explicit CurrentThreadSetter(Thread* thread) 387*d9f75844SAndroid Build Coastguard Worker : CurrentTaskQueueSetter(thread), 388*d9f75844SAndroid Build Coastguard Worker manager_(rtc::ThreadManager::Instance()), 389*d9f75844SAndroid Build Coastguard Worker previous_(manager_->CurrentThread()) { 390*d9f75844SAndroid Build Coastguard Worker manager_->ChangeCurrentThreadForTest(thread); 391*d9f75844SAndroid Build Coastguard Worker } ~CurrentThreadSetter()392*d9f75844SAndroid Build Coastguard Worker ~CurrentThreadSetter() { manager_->ChangeCurrentThreadForTest(previous_); } 393*d9f75844SAndroid Build Coastguard Worker 394*d9f75844SAndroid Build Coastguard Worker private: 395*d9f75844SAndroid Build Coastguard Worker rtc::ThreadManager* const manager_; 396*d9f75844SAndroid Build Coastguard Worker rtc::Thread* const previous_; 397*d9f75844SAndroid Build Coastguard Worker }; 398*d9f75844SAndroid Build Coastguard Worker 399*d9f75844SAndroid Build Coastguard Worker // DelayedMessage goes into a priority queue, sorted by trigger time. Messages 400*d9f75844SAndroid Build Coastguard Worker // with the same trigger time are processed in num_ (FIFO) order. 401*d9f75844SAndroid Build Coastguard Worker struct DelayedMessage { 402*d9f75844SAndroid Build Coastguard Worker bool operator<(const DelayedMessage& dmsg) const { 403*d9f75844SAndroid Build Coastguard Worker return (dmsg.run_time_ms < run_time_ms) || 404*d9f75844SAndroid Build Coastguard Worker ((dmsg.run_time_ms == run_time_ms) && 405*d9f75844SAndroid Build Coastguard Worker (dmsg.message_number < message_number)); 406*d9f75844SAndroid Build Coastguard Worker } 407*d9f75844SAndroid Build Coastguard Worker 408*d9f75844SAndroid Build Coastguard Worker int64_t delay_ms; // for debugging 409*d9f75844SAndroid Build Coastguard Worker int64_t run_time_ms; 410*d9f75844SAndroid Build Coastguard Worker // Monotonicaly incrementing number used for ordering of messages 411*d9f75844SAndroid Build Coastguard Worker // targeted to execute at the same time. 412*d9f75844SAndroid Build Coastguard Worker uint32_t message_number; 413*d9f75844SAndroid Build Coastguard Worker // std::priority_queue doesn't allow to extract elements, but functor 414*d9f75844SAndroid Build Coastguard Worker // is move-only and thus need to be changed when pulled out of the 415*d9f75844SAndroid Build Coastguard Worker // priority queue. That is ok because `functor` doesn't affect operator< 416*d9f75844SAndroid Build Coastguard Worker mutable absl::AnyInvocable<void() &&> functor; 417*d9f75844SAndroid Build Coastguard Worker }; 418*d9f75844SAndroid Build Coastguard Worker 419*d9f75844SAndroid Build Coastguard Worker // Perform initialization, subclasses must call this from their constructor 420*d9f75844SAndroid Build Coastguard Worker // if false was passed as init_queue to the Thread constructor. 421*d9f75844SAndroid Build Coastguard Worker void DoInit(); 422*d9f75844SAndroid Build Coastguard Worker 423*d9f75844SAndroid Build Coastguard Worker // Perform cleanup; subclasses must call this from the destructor, 424*d9f75844SAndroid Build Coastguard Worker // and are not expected to actually hold the lock. 425*d9f75844SAndroid Build Coastguard Worker void DoDestroy() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 426*d9f75844SAndroid Build Coastguard Worker 427*d9f75844SAndroid Build Coastguard Worker void WakeUpSocketServer(); 428*d9f75844SAndroid Build Coastguard Worker 429*d9f75844SAndroid Build Coastguard Worker // Same as WrapCurrent except that it never fails as it does not try to 430*d9f75844SAndroid Build Coastguard Worker // acquire the synchronization access of the thread. The caller should never 431*d9f75844SAndroid Build Coastguard Worker // call Stop() or Join() on this thread. 432*d9f75844SAndroid Build Coastguard Worker void SafeWrapCurrent(); 433*d9f75844SAndroid Build Coastguard Worker 434*d9f75844SAndroid Build Coastguard Worker // Blocks the calling thread until this thread has terminated. 435*d9f75844SAndroid Build Coastguard Worker void Join(); 436*d9f75844SAndroid Build Coastguard Worker 437*d9f75844SAndroid Build Coastguard Worker static void AssertBlockingIsAllowedOnCurrentThread(); 438*d9f75844SAndroid Build Coastguard Worker 439*d9f75844SAndroid Build Coastguard Worker friend class ScopedDisallowBlockingCalls; 440*d9f75844SAndroid Build Coastguard Worker 441*d9f75844SAndroid Build Coastguard Worker private: 442*d9f75844SAndroid Build Coastguard Worker static const int kSlowDispatchLoggingThreshold = 50; // 50 ms 443*d9f75844SAndroid Build Coastguard Worker 444*d9f75844SAndroid Build Coastguard Worker // Get() will process I/O until: 445*d9f75844SAndroid Build Coastguard Worker // 1) A task is available (returns it) 446*d9f75844SAndroid Build Coastguard Worker // 2) cmsWait seconds have elapsed (returns empty task) 447*d9f75844SAndroid Build Coastguard Worker // 3) Stop() is called (returns empty task) 448*d9f75844SAndroid Build Coastguard Worker absl::AnyInvocable<void() &&> Get(int cmsWait); 449*d9f75844SAndroid Build Coastguard Worker void Dispatch(absl::AnyInvocable<void() &&> task); 450*d9f75844SAndroid Build Coastguard Worker 451*d9f75844SAndroid Build Coastguard Worker // Sets the per-thread allow-blocking-calls flag and returns the previous 452*d9f75844SAndroid Build Coastguard Worker // value. Must be called on this thread. 453*d9f75844SAndroid Build Coastguard Worker bool SetAllowBlockingCalls(bool allow); 454*d9f75844SAndroid Build Coastguard Worker 455*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN) 456*d9f75844SAndroid Build Coastguard Worker static DWORD WINAPI PreRun(LPVOID context); 457*d9f75844SAndroid Build Coastguard Worker #else 458*d9f75844SAndroid Build Coastguard Worker static void* PreRun(void* pv); 459*d9f75844SAndroid Build Coastguard Worker #endif 460*d9f75844SAndroid Build Coastguard Worker 461*d9f75844SAndroid Build Coastguard Worker // ThreadManager calls this instead WrapCurrent() because 462*d9f75844SAndroid Build Coastguard Worker // ThreadManager::Instance() cannot be used while ThreadManager is 463*d9f75844SAndroid Build Coastguard Worker // being created. 464*d9f75844SAndroid Build Coastguard Worker // The method tries to get synchronization rights of the thread on Windows if 465*d9f75844SAndroid Build Coastguard Worker // `need_synchronize_access` is true. 466*d9f75844SAndroid Build Coastguard Worker bool WrapCurrentWithThreadManager(ThreadManager* thread_manager, 467*d9f75844SAndroid Build Coastguard Worker bool need_synchronize_access); 468*d9f75844SAndroid Build Coastguard Worker 469*d9f75844SAndroid Build Coastguard Worker // Return true if the thread is currently running. 470*d9f75844SAndroid Build Coastguard Worker bool IsRunning(); 471*d9f75844SAndroid Build Coastguard Worker 472*d9f75844SAndroid Build Coastguard Worker // Called by the ThreadManager when being set as the current thread. 473*d9f75844SAndroid Build Coastguard Worker void EnsureIsCurrentTaskQueue(); 474*d9f75844SAndroid Build Coastguard Worker 475*d9f75844SAndroid Build Coastguard Worker // Called by the ThreadManager when being unset as the current thread. 476*d9f75844SAndroid Build Coastguard Worker void ClearCurrentTaskQueue(); 477*d9f75844SAndroid Build Coastguard Worker 478*d9f75844SAndroid Build Coastguard Worker std::queue<absl::AnyInvocable<void() &&>> messages_ RTC_GUARDED_BY(mutex_); 479*d9f75844SAndroid Build Coastguard Worker std::priority_queue<DelayedMessage> delayed_messages_ RTC_GUARDED_BY(mutex_); 480*d9f75844SAndroid Build Coastguard Worker uint32_t delayed_next_num_ RTC_GUARDED_BY(mutex_); 481*d9f75844SAndroid Build Coastguard Worker #if RTC_DCHECK_IS_ON 482*d9f75844SAndroid Build Coastguard Worker uint32_t blocking_call_count_ RTC_GUARDED_BY(this) = 0; 483*d9f75844SAndroid Build Coastguard Worker uint32_t could_be_blocking_call_count_ RTC_GUARDED_BY(this) = 0; 484*d9f75844SAndroid Build Coastguard Worker std::vector<Thread*> allowed_threads_ RTC_GUARDED_BY(this); 485*d9f75844SAndroid Build Coastguard Worker bool invoke_policy_enabled_ RTC_GUARDED_BY(this) = false; 486*d9f75844SAndroid Build Coastguard Worker #endif 487*d9f75844SAndroid Build Coastguard Worker mutable webrtc::Mutex mutex_; 488*d9f75844SAndroid Build Coastguard Worker bool fInitialized_; 489*d9f75844SAndroid Build Coastguard Worker bool fDestroyed_; 490*d9f75844SAndroid Build Coastguard Worker 491*d9f75844SAndroid Build Coastguard Worker std::atomic<int> stop_; 492*d9f75844SAndroid Build Coastguard Worker 493*d9f75844SAndroid Build Coastguard Worker // The SocketServer might not be owned by Thread. 494*d9f75844SAndroid Build Coastguard Worker SocketServer* const ss_; 495*d9f75844SAndroid Build Coastguard Worker // Used if SocketServer ownership lies with `this`. 496*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<SocketServer> own_ss_; 497*d9f75844SAndroid Build Coastguard Worker 498*d9f75844SAndroid Build Coastguard Worker std::string name_; 499*d9f75844SAndroid Build Coastguard Worker 500*d9f75844SAndroid Build Coastguard Worker // TODO(tommi): Add thread checks for proper use of control methods. 501*d9f75844SAndroid Build Coastguard Worker // Ideally we should be able to just use PlatformThread. 502*d9f75844SAndroid Build Coastguard Worker 503*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_POSIX) 504*d9f75844SAndroid Build Coastguard Worker pthread_t thread_ = 0; 505*d9f75844SAndroid Build Coastguard Worker #endif 506*d9f75844SAndroid Build Coastguard Worker 507*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN) 508*d9f75844SAndroid Build Coastguard Worker HANDLE thread_ = nullptr; 509*d9f75844SAndroid Build Coastguard Worker DWORD thread_id_ = 0; 510*d9f75844SAndroid Build Coastguard Worker #endif 511*d9f75844SAndroid Build Coastguard Worker 512*d9f75844SAndroid Build Coastguard Worker // Indicates whether or not ownership of the worker thread lies with 513*d9f75844SAndroid Build Coastguard Worker // this instance or not. (i.e. owned_ == !wrapped). 514*d9f75844SAndroid Build Coastguard Worker // Must only be modified when the worker thread is not running. 515*d9f75844SAndroid Build Coastguard Worker bool owned_ = true; 516*d9f75844SAndroid Build Coastguard Worker 517*d9f75844SAndroid Build Coastguard Worker // Only touched from the worker thread itself. 518*d9f75844SAndroid Build Coastguard Worker bool blocking_calls_allowed_ = true; 519*d9f75844SAndroid Build Coastguard Worker 520*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<TaskQueueBase::CurrentTaskQueueSetter> 521*d9f75844SAndroid Build Coastguard Worker task_queue_registration_; 522*d9f75844SAndroid Build Coastguard Worker 523*d9f75844SAndroid Build Coastguard Worker friend class ThreadManager; 524*d9f75844SAndroid Build Coastguard Worker 525*d9f75844SAndroid Build Coastguard Worker int dispatch_warning_ms_ RTC_GUARDED_BY(this) = kSlowDispatchLoggingThreshold; 526*d9f75844SAndroid Build Coastguard Worker }; 527*d9f75844SAndroid Build Coastguard Worker 528*d9f75844SAndroid Build Coastguard Worker // AutoThread automatically installs itself at construction 529*d9f75844SAndroid Build Coastguard Worker // uninstalls at destruction, if a Thread object is 530*d9f75844SAndroid Build Coastguard Worker // _not already_ associated with the current OS thread. 531*d9f75844SAndroid Build Coastguard Worker // 532*d9f75844SAndroid Build Coastguard Worker // NOTE: *** This class should only be used by tests *** 533*d9f75844SAndroid Build Coastguard Worker // 534*d9f75844SAndroid Build Coastguard Worker class AutoThread : public Thread { 535*d9f75844SAndroid Build Coastguard Worker public: 536*d9f75844SAndroid Build Coastguard Worker AutoThread(); 537*d9f75844SAndroid Build Coastguard Worker ~AutoThread() override; 538*d9f75844SAndroid Build Coastguard Worker 539*d9f75844SAndroid Build Coastguard Worker AutoThread(const AutoThread&) = delete; 540*d9f75844SAndroid Build Coastguard Worker AutoThread& operator=(const AutoThread&) = delete; 541*d9f75844SAndroid Build Coastguard Worker }; 542*d9f75844SAndroid Build Coastguard Worker 543*d9f75844SAndroid Build Coastguard Worker // AutoSocketServerThread automatically installs itself at 544*d9f75844SAndroid Build Coastguard Worker // construction and uninstalls at destruction. If a Thread object is 545*d9f75844SAndroid Build Coastguard Worker // already associated with the current OS thread, it is temporarily 546*d9f75844SAndroid Build Coastguard Worker // disassociated and restored by the destructor. 547*d9f75844SAndroid Build Coastguard Worker 548*d9f75844SAndroid Build Coastguard Worker class AutoSocketServerThread : public Thread { 549*d9f75844SAndroid Build Coastguard Worker public: 550*d9f75844SAndroid Build Coastguard Worker explicit AutoSocketServerThread(SocketServer* ss); 551*d9f75844SAndroid Build Coastguard Worker ~AutoSocketServerThread() override; 552*d9f75844SAndroid Build Coastguard Worker 553*d9f75844SAndroid Build Coastguard Worker AutoSocketServerThread(const AutoSocketServerThread&) = delete; 554*d9f75844SAndroid Build Coastguard Worker AutoSocketServerThread& operator=(const AutoSocketServerThread&) = delete; 555*d9f75844SAndroid Build Coastguard Worker 556*d9f75844SAndroid Build Coastguard Worker private: 557*d9f75844SAndroid Build Coastguard Worker rtc::Thread* old_thread_; 558*d9f75844SAndroid Build Coastguard Worker }; 559*d9f75844SAndroid Build Coastguard Worker } // namespace rtc 560*d9f75844SAndroid Build Coastguard Worker 561*d9f75844SAndroid Build Coastguard Worker #endif // RTC_BASE_THREAD_H_ 562