1 /* 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef RTC_BASE_THREAD_H_ 12 #define RTC_BASE_THREAD_H_ 13 14 #include <stdint.h> 15 16 #include <list> 17 #include <map> 18 #include <memory> 19 #include <queue> 20 #include <set> 21 #include <string> 22 #include <type_traits> 23 #include <vector> 24 25 #if defined(WEBRTC_POSIX) 26 #include <pthread.h> 27 #endif 28 #include "api/function_view.h" 29 #include "api/task_queue/queued_task.h" 30 #include "api/task_queue/task_queue_base.h" 31 #include "rtc_base/constructor_magic.h" 32 #include "rtc_base/deprecated/recursive_critical_section.h" 33 #include "rtc_base/location.h" 34 #include "rtc_base/message_handler.h" 35 #include "rtc_base/platform_thread_types.h" 36 #include "rtc_base/socket_server.h" 37 #include "rtc_base/system/rtc_export.h" 38 #include "rtc_base/thread_annotations.h" 39 #include "rtc_base/thread_message.h" 40 41 #if defined(WEBRTC_WIN) 42 #include "rtc_base/win32.h" 43 #endif 44 45 namespace rtc { 46 47 class Thread; 48 49 namespace rtc_thread_internal { 50 51 class MessageLikeTask : public MessageData { 52 public: 53 virtual void Run() = 0; 54 }; 55 56 template <class FunctorT> 57 class MessageWithFunctor final : public MessageLikeTask { 58 public: MessageWithFunctor(FunctorT && functor)59 explicit MessageWithFunctor(FunctorT&& functor) 60 : functor_(std::forward<FunctorT>(functor)) {} 61 Run()62 void Run() override { functor_(); } 63 64 private: ~MessageWithFunctor()65 ~MessageWithFunctor() override {} 66 67 typename std::remove_reference<FunctorT>::type functor_; 68 69 RTC_DISALLOW_COPY_AND_ASSIGN(MessageWithFunctor); 70 }; 71 72 } // namespace rtc_thread_internal 73 74 class RTC_EXPORT ThreadManager { 75 public: 76 static const int kForever = -1; 77 78 // Singleton, constructor and destructor are private. 79 static ThreadManager* Instance(); 80 81 static void Add(Thread* message_queue); 82 static void Remove(Thread* message_queue); 83 static void Clear(MessageHandler* handler); 84 85 // TODO(nisse): Delete alias, as soon as downstream code is updated. ProcessAllMessageQueues()86 static void ProcessAllMessageQueues() { ProcessAllMessageQueuesForTesting(); } 87 88 // For testing purposes, for use with a simulated clock. 89 // Ensures that all message queues have processed delayed messages 90 // up until the current point in time. 91 static void ProcessAllMessageQueuesForTesting(); 92 93 Thread* CurrentThread(); 94 void SetCurrentThread(Thread* thread); 95 // Allows changing the current thread, this is intended for tests where we 96 // want to simulate multiple threads running on a single physical thread. 97 void ChangeCurrentThreadForTest(Thread* thread); 98 99 // Returns a thread object with its thread_ ivar set 100 // to whatever the OS uses to represent the thread. 101 // If there already *is* a Thread object corresponding to this thread, 102 // this method will return that. Otherwise it creates a new Thread 103 // object whose wrapped() method will return true, and whose 104 // handle will, on Win32, be opened with only synchronization privileges - 105 // if you need more privilegs, rather than changing this method, please 106 // write additional code to adjust the privileges, or call a different 107 // factory method of your own devising, because this one gets used in 108 // unexpected contexts (like inside browser plugins) and it would be a 109 // shame to break it. It is also conceivable on Win32 that we won't even 110 // be able to get synchronization privileges, in which case the result 111 // will have a null handle. 112 Thread* WrapCurrentThread(); 113 void UnwrapCurrentThread(); 114 115 bool IsMainThread(); 116 117 #if RTC_DCHECK_IS_ON 118 // Registers that a Send operation is to be performed between |source| and 119 // |target|, while checking that this does not cause a send cycle that could 120 // potentially cause a deadlock. 121 void RegisterSendAndCheckForCycles(Thread* source, Thread* target); 122 #endif 123 124 private: 125 ThreadManager(); 126 ~ThreadManager(); 127 128 void SetCurrentThreadInternal(Thread* thread); 129 void AddInternal(Thread* message_queue); 130 void RemoveInternal(Thread* message_queue); 131 void ClearInternal(MessageHandler* handler); 132 void ProcessAllMessageQueuesInternal(); 133 #if RTC_DCHECK_IS_ON 134 void RemoveFromSendGraph(Thread* thread) RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_); 135 #endif 136 137 // This list contains all live Threads. 138 std::vector<Thread*> message_queues_ RTC_GUARDED_BY(crit_); 139 140 // Methods that don't modify the list of message queues may be called in a 141 // re-entrant fashion. "processing_" keeps track of the depth of re-entrant 142 // calls. 143 RecursiveCriticalSection crit_; 144 size_t processing_ RTC_GUARDED_BY(crit_) = 0; 145 #if RTC_DCHECK_IS_ON 146 // Represents all thread seand actions by storing all send targets per thread. 147 // This is used by RegisterSendAndCheckForCycles. This graph has no cycles 148 // since we will trigger a CHECK failure if a cycle is introduced. 149 std::map<Thread*, std::set<Thread*>> send_graph_ RTC_GUARDED_BY(crit_); 150 #endif 151 152 #if defined(WEBRTC_POSIX) 153 pthread_key_t key_; 154 #endif 155 156 #if defined(WEBRTC_WIN) 157 const DWORD key_; 158 #endif 159 160 // The thread to potentially autowrap. 161 const PlatformThreadRef main_thread_ref_; 162 163 RTC_DISALLOW_COPY_AND_ASSIGN(ThreadManager); 164 }; 165 166 // WARNING! SUBCLASSES MUST CALL Stop() IN THEIR DESTRUCTORS! See ~Thread(). 167 168 class RTC_LOCKABLE RTC_EXPORT Thread : public webrtc::TaskQueueBase { 169 public: 170 static const int kForever = -1; 171 172 // Create a new Thread and optionally assign it to the passed 173 // SocketServer. Subclasses that override Clear should pass false for 174 // init_queue and call DoInit() from their constructor to prevent races 175 // with the ThreadManager using the object while the vtable is still 176 // being created. 177 explicit Thread(SocketServer* ss); 178 explicit Thread(std::unique_ptr<SocketServer> ss); 179 180 // Constructors meant for subclasses; they should call DoInit themselves and 181 // pass false for |do_init|, so that DoInit is called only on the fully 182 // instantiated class, which avoids a vptr data race. 183 Thread(SocketServer* ss, bool do_init); 184 Thread(std::unique_ptr<SocketServer> ss, bool do_init); 185 186 // NOTE: ALL SUBCLASSES OF Thread MUST CALL Stop() IN THEIR DESTRUCTORS (or 187 // guarantee Stop() is explicitly called before the subclass is destroyed). 188 // This is required to avoid a data race between the destructor modifying the 189 // vtable, and the Thread::PreRun calling the virtual method Run(). 190 191 // NOTE: SUBCLASSES OF Thread THAT OVERRIDE Clear MUST CALL 192 // DoDestroy() IN THEIR DESTRUCTORS! This is required to avoid a data race 193 // between the destructor modifying the vtable, and the ThreadManager 194 // calling Clear on the object from a different thread. 195 ~Thread() override; 196 197 static std::unique_ptr<Thread> CreateWithSocketServer(); 198 static std::unique_ptr<Thread> Create(); 199 static Thread* Current(); 200 201 // Used to catch performance regressions. Use this to disallow blocking calls 202 // (Invoke) for a given scope. If a synchronous call is made while this is in 203 // effect, an assert will be triggered. 204 // Note that this is a single threaded class. 205 class ScopedDisallowBlockingCalls { 206 public: 207 ScopedDisallowBlockingCalls(); 208 ScopedDisallowBlockingCalls(const ScopedDisallowBlockingCalls&) = delete; 209 ScopedDisallowBlockingCalls& operator=(const ScopedDisallowBlockingCalls&) = 210 delete; 211 ~ScopedDisallowBlockingCalls(); 212 213 private: 214 Thread* const thread_; 215 const bool previous_state_; 216 }; 217 218 SocketServer* socketserver(); 219 220 // Note: The behavior of Thread has changed. When a thread is stopped, 221 // futher Posts and Sends will fail. However, any pending Sends and *ready* 222 // Posts (as opposed to unexpired delayed Posts) will be delivered before 223 // Get (or Peek) returns false. By guaranteeing delivery of those messages, 224 // we eliminate the race condition when an MessageHandler and Thread 225 // may be destroyed independently of each other. 226 virtual void Quit(); 227 virtual bool IsQuitting(); 228 virtual void Restart(); 229 // Not all message queues actually process messages (such as SignalThread). 230 // In those cases, it's important to know, before posting, that it won't be 231 // Processed. Normally, this would be true until IsQuitting() is true. 232 virtual bool IsProcessingMessagesForTesting(); 233 234 // Get() will process I/O until: 235 // 1) A message is available (returns true) 236 // 2) cmsWait seconds have elapsed (returns false) 237 // 3) Stop() is called (returns false) 238 virtual bool Get(Message* pmsg, 239 int cmsWait = kForever, 240 bool process_io = true); 241 virtual bool Peek(Message* pmsg, int cmsWait = 0); 242 // |time_sensitive| is deprecated and should always be false. 243 virtual void Post(const Location& posted_from, 244 MessageHandler* phandler, 245 uint32_t id = 0, 246 MessageData* pdata = nullptr, 247 bool time_sensitive = false); 248 virtual void PostDelayed(const Location& posted_from, 249 int delay_ms, 250 MessageHandler* phandler, 251 uint32_t id = 0, 252 MessageData* pdata = nullptr); 253 virtual void PostAt(const Location& posted_from, 254 int64_t run_at_ms, 255 MessageHandler* phandler, 256 uint32_t id = 0, 257 MessageData* pdata = nullptr); 258 virtual void Clear(MessageHandler* phandler, 259 uint32_t id = MQID_ANY, 260 MessageList* removed = nullptr); 261 virtual void Dispatch(Message* pmsg); 262 263 // Amount of time until the next message can be retrieved 264 virtual int GetDelay(); 265 empty()266 bool empty() const { return size() == 0u; } size()267 size_t size() const { 268 CritScope cs(&crit_); 269 return messages_.size() + delayed_messages_.size() + (fPeekKeep_ ? 1u : 0u); 270 } 271 272 // Internally posts a message which causes the doomed object to be deleted 273 template <class T> Dispose(T * doomed)274 void Dispose(T* doomed) { 275 if (doomed) { 276 Post(RTC_FROM_HERE, nullptr, MQID_DISPOSE, new DisposeData<T>(doomed)); 277 } 278 } 279 280 // When this signal is sent out, any references to this queue should 281 // no longer be used. 282 sigslot::signal0<> SignalQueueDestroyed; 283 284 bool IsCurrent() const; 285 286 // Sleeps the calling thread for the specified number of milliseconds, during 287 // which time no processing is performed. Returns false if sleeping was 288 // interrupted by a signal (POSIX only). 289 static bool SleepMs(int millis); 290 291 // Sets the thread's name, for debugging. Must be called before Start(). 292 // If |obj| is non-null, its value is appended to |name|. name()293 const std::string& name() const { return name_; } 294 bool SetName(const std::string& name, const void* obj); 295 296 // Starts the execution of the thread. 297 bool Start(); 298 299 // Tells the thread to stop and waits until it is joined. 300 // Never call Stop on the current thread. Instead use the inherited Quit 301 // function which will exit the base Thread without terminating the 302 // underlying OS thread. 303 virtual void Stop(); 304 305 // By default, Thread::Run() calls ProcessMessages(kForever). To do other 306 // work, override Run(). To receive and dispatch messages, call 307 // ProcessMessages occasionally. 308 virtual void Run(); 309 310 virtual void Send(const Location& posted_from, 311 MessageHandler* phandler, 312 uint32_t id = 0, 313 MessageData* pdata = nullptr); 314 315 // Convenience method to invoke a functor on another thread. Caller must 316 // provide the |ReturnT| template argument, which cannot (easily) be deduced. 317 // Uses Send() internally, which blocks the current thread until execution 318 // is complete. 319 // Ex: bool result = thread.Invoke<bool>(RTC_FROM_HERE, 320 // &MyFunctionReturningBool); 321 // NOTE: This function can only be called when synchronous calls are allowed. 322 // See ScopedDisallowBlockingCalls for details. 323 // NOTE: Blocking invokes are DISCOURAGED, consider if what you're doing can 324 // be achieved with PostTask() and callbacks instead. 325 template < 326 class ReturnT, 327 typename = typename std::enable_if<!std::is_void<ReturnT>::value>::type> Invoke(const Location & posted_from,FunctionView<ReturnT ()> functor)328 ReturnT Invoke(const Location& posted_from, FunctionView<ReturnT()> functor) { 329 ReturnT result; 330 InvokeInternal(posted_from, [functor, &result] { result = functor(); }); 331 return result; 332 } 333 334 template < 335 class ReturnT, 336 typename = typename std::enable_if<std::is_void<ReturnT>::value>::type> Invoke(const Location & posted_from,FunctionView<void ()> functor)337 void Invoke(const Location& posted_from, FunctionView<void()> functor) { 338 InvokeInternal(posted_from, functor); 339 } 340 341 // Allows invoke to specified |thread|. Thread never will be dereferenced and 342 // will be used only for reference-based comparison, so instance can be safely 343 // deleted. If NDEBUG is defined and DCHECK_ALWAYS_ON is undefined do nothing. 344 void AllowInvokesToThread(Thread* thread); 345 // If NDEBUG is defined and DCHECK_ALWAYS_ON is undefined do nothing. 346 void DisallowAllInvokes(); 347 // Returns true if |target| was allowed by AllowInvokesToThread() or if no 348 // calls were made to AllowInvokesToThread and DisallowAllInvokes. Otherwise 349 // returns false. 350 // If NDEBUG is defined and DCHECK_ALWAYS_ON is undefined always returns true. 351 bool IsInvokeToThreadAllowed(rtc::Thread* target); 352 353 // Posts a task to invoke the functor on |this| thread asynchronously, i.e. 354 // without blocking the thread that invoked PostTask(). Ownership of |functor| 355 // is passed and (usually, see below) destroyed on |this| thread after it is 356 // invoked. 357 // Requirements of FunctorT: 358 // - FunctorT is movable. 359 // - FunctorT implements "T operator()()" or "T operator()() const" for some T 360 // (if T is not void, the return value is discarded on |this| thread). 361 // - FunctorT has a public destructor that can be invoked from |this| thread 362 // after operation() has been invoked. 363 // - The functor must not cause the thread to quit before PostTask() is done. 364 // 365 // Destruction of the functor/task mimics what TaskQueue::PostTask does: If 366 // the task is run, it will be destroyed on |this| thread. However, if there 367 // are pending tasks by the time the Thread is destroyed, or a task is posted 368 // to a thread that is quitting, the task is destroyed immediately, on the 369 // calling thread. Destroying the Thread only blocks for any currently running 370 // task to complete. Note that TQ abstraction is even vaguer on how 371 // destruction happens in these cases, allowing destruction to happen 372 // asynchronously at a later time and on some arbitrary thread. So to ease 373 // migration, don't depend on Thread::PostTask destroying un-run tasks 374 // immediately. 375 // 376 // Example - Calling a class method: 377 // class Foo { 378 // public: 379 // void DoTheThing(); 380 // }; 381 // Foo foo; 382 // thread->PostTask(RTC_FROM_HERE, Bind(&Foo::DoTheThing, &foo)); 383 // 384 // Example - Calling a lambda function: 385 // thread->PostTask(RTC_FROM_HERE, 386 // [&x, &y] { x.TrackComputations(y.Compute()); }); 387 template <class FunctorT> PostTask(const Location & posted_from,FunctorT && functor)388 void PostTask(const Location& posted_from, FunctorT&& functor) { 389 Post(posted_from, GetPostTaskMessageHandler(), /*id=*/0, 390 new rtc_thread_internal::MessageWithFunctor<FunctorT>( 391 std::forward<FunctorT>(functor))); 392 } 393 template <class FunctorT> PostDelayedTask(const Location & posted_from,FunctorT && functor,uint32_t milliseconds)394 void PostDelayedTask(const Location& posted_from, 395 FunctorT&& functor, 396 uint32_t milliseconds) { 397 PostDelayed(posted_from, milliseconds, GetPostTaskMessageHandler(), 398 /*id=*/0, 399 new rtc_thread_internal::MessageWithFunctor<FunctorT>( 400 std::forward<FunctorT>(functor))); 401 } 402 403 // From TaskQueueBase 404 void PostTask(std::unique_ptr<webrtc::QueuedTask> task) override; 405 void PostDelayedTask(std::unique_ptr<webrtc::QueuedTask> task, 406 uint32_t milliseconds) override; 407 void Delete() override; 408 409 // ProcessMessages will process I/O and dispatch messages until: 410 // 1) cms milliseconds have elapsed (returns true) 411 // 2) Stop() is called (returns false) 412 bool ProcessMessages(int cms); 413 414 // Returns true if this is a thread that we created using the standard 415 // constructor, false if it was created by a call to 416 // ThreadManager::WrapCurrentThread(). The main thread of an application 417 // is generally not owned, since the OS representation of the thread 418 // obviously exists before we can get to it. 419 // You cannot call Start on non-owned threads. 420 bool IsOwned(); 421 422 // Expose private method IsRunning() for tests. 423 // 424 // DANGER: this is a terrible public API. Most callers that might want to 425 // call this likely do not have enough control/knowledge of the Thread in 426 // question to guarantee that the returned value remains true for the duration 427 // of whatever code is conditionally executing because of the return value! RunningForTest()428 bool RunningForTest() { return IsRunning(); } 429 430 // These functions are public to avoid injecting test hooks. Don't call them 431 // outside of tests. 432 // This method should be called when thread is created using non standard 433 // method, like derived implementation of rtc::Thread and it can not be 434 // started by calling Start(). This will set started flag to true and 435 // owned to false. This must be called from the current thread. 436 bool WrapCurrent(); 437 void UnwrapCurrent(); 438 439 // Sets the per-thread allow-blocking-calls flag to false; this is 440 // irrevocable. Must be called on this thread. DisallowBlockingCalls()441 void DisallowBlockingCalls() { SetAllowBlockingCalls(false); } 442 443 #ifdef WEBRTC_ANDROID 444 // Sets the per-thread allow-blocking-calls flag to true, sidestepping the 445 // invariants upheld by DisallowBlockingCalls() and 446 // ScopedDisallowBlockingCalls. Must be called on this thread. DEPRECATED_AllowBlockingCalls()447 void DEPRECATED_AllowBlockingCalls() { SetAllowBlockingCalls(true); } 448 #endif 449 450 protected: 451 class CurrentThreadSetter : CurrentTaskQueueSetter { 452 public: CurrentThreadSetter(Thread * thread)453 explicit CurrentThreadSetter(Thread* thread) 454 : CurrentTaskQueueSetter(thread), 455 manager_(rtc::ThreadManager::Instance()), 456 previous_(manager_->CurrentThread()) { 457 manager_->ChangeCurrentThreadForTest(thread); 458 } ~CurrentThreadSetter()459 ~CurrentThreadSetter() { manager_->ChangeCurrentThreadForTest(previous_); } 460 461 private: 462 rtc::ThreadManager* const manager_; 463 rtc::Thread* const previous_; 464 }; 465 466 // DelayedMessage goes into a priority queue, sorted by trigger time. Messages 467 // with the same trigger time are processed in num_ (FIFO) order. 468 class DelayedMessage { 469 public: DelayedMessage(int64_t delay,int64_t run_time_ms,uint32_t num,const Message & msg)470 DelayedMessage(int64_t delay, 471 int64_t run_time_ms, 472 uint32_t num, 473 const Message& msg) 474 : delay_ms_(delay), 475 run_time_ms_(run_time_ms), 476 message_number_(num), 477 msg_(msg) {} 478 479 bool operator<(const DelayedMessage& dmsg) const { 480 return (dmsg.run_time_ms_ < run_time_ms_) || 481 ((dmsg.run_time_ms_ == run_time_ms_) && 482 (dmsg.message_number_ < message_number_)); 483 } 484 485 int64_t delay_ms_; // for debugging 486 int64_t run_time_ms_; 487 // Monotonicaly incrementing number used for ordering of messages 488 // targeted to execute at the same time. 489 uint32_t message_number_; 490 Message msg_; 491 }; 492 493 class PriorityQueue : public std::priority_queue<DelayedMessage> { 494 public: container()495 container_type& container() { return c; } reheap()496 void reheap() { make_heap(c.begin(), c.end(), comp); } 497 }; 498 499 void DoDelayPost(const Location& posted_from, 500 int64_t cmsDelay, 501 int64_t tstamp, 502 MessageHandler* phandler, 503 uint32_t id, 504 MessageData* pdata); 505 506 // Perform initialization, subclasses must call this from their constructor 507 // if false was passed as init_queue to the Thread constructor. 508 void DoInit(); 509 510 // Does not take any lock. Must be called either while holding crit_, or by 511 // the destructor (by definition, the latter has exclusive access). 512 void ClearInternal(MessageHandler* phandler, 513 uint32_t id, 514 MessageList* removed) RTC_EXCLUSIVE_LOCKS_REQUIRED(&crit_); 515 516 // Perform cleanup; subclasses must call this from the destructor, 517 // and are not expected to actually hold the lock. 518 void DoDestroy() RTC_EXCLUSIVE_LOCKS_REQUIRED(&crit_); 519 520 void WakeUpSocketServer(); 521 522 // Same as WrapCurrent except that it never fails as it does not try to 523 // acquire the synchronization access of the thread. The caller should never 524 // call Stop() or Join() on this thread. 525 void SafeWrapCurrent(); 526 527 // Blocks the calling thread until this thread has terminated. 528 void Join(); 529 530 static void AssertBlockingIsAllowedOnCurrentThread(); 531 532 friend class ScopedDisallowBlockingCalls; 533 CritForTest()534 RecursiveCriticalSection* CritForTest() { return &crit_; } 535 536 private: 537 class QueuedTaskHandler final : public MessageHandler { 538 public: 539 void OnMessage(Message* msg) override; 540 }; 541 542 // Sets the per-thread allow-blocking-calls flag and returns the previous 543 // value. Must be called on this thread. 544 bool SetAllowBlockingCalls(bool allow); 545 546 #if defined(WEBRTC_WIN) 547 static DWORD WINAPI PreRun(LPVOID context); 548 #else 549 static void* PreRun(void* pv); 550 #endif 551 552 // ThreadManager calls this instead WrapCurrent() because 553 // ThreadManager::Instance() cannot be used while ThreadManager is 554 // being created. 555 // The method tries to get synchronization rights of the thread on Windows if 556 // |need_synchronize_access| is true. 557 bool WrapCurrentWithThreadManager(ThreadManager* thread_manager, 558 bool need_synchronize_access); 559 560 // Return true if the thread is currently running. 561 bool IsRunning(); 562 563 void InvokeInternal(const Location& posted_from, 564 rtc::FunctionView<void()> functor); 565 566 // Called by the ThreadManager when being set as the current thread. 567 void EnsureIsCurrentTaskQueue(); 568 569 // Called by the ThreadManager when being unset as the current thread. 570 void ClearCurrentTaskQueue(); 571 572 // Returns a static-lifetime MessageHandler which runs message with 573 // MessageLikeTask payload data. 574 static MessageHandler* GetPostTaskMessageHandler(); 575 576 bool fPeekKeep_; 577 Message msgPeek_; 578 MessageList messages_ RTC_GUARDED_BY(crit_); 579 PriorityQueue delayed_messages_ RTC_GUARDED_BY(crit_); 580 uint32_t delayed_next_num_ RTC_GUARDED_BY(crit_); 581 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) 582 std::vector<Thread*> allowed_threads_ RTC_GUARDED_BY(this); 583 bool invoke_policy_enabled_ RTC_GUARDED_BY(this) = false; 584 #endif 585 RecursiveCriticalSection crit_; 586 bool fInitialized_; 587 bool fDestroyed_; 588 589 volatile int stop_; 590 591 // The SocketServer might not be owned by Thread. 592 SocketServer* const ss_; 593 // Used if SocketServer ownership lies with |this|. 594 std::unique_ptr<SocketServer> own_ss_; 595 596 std::string name_; 597 598 // TODO(tommi): Add thread checks for proper use of control methods. 599 // Ideally we should be able to just use PlatformThread. 600 601 #if defined(WEBRTC_POSIX) 602 pthread_t thread_ = 0; 603 #endif 604 605 #if defined(WEBRTC_WIN) 606 HANDLE thread_ = nullptr; 607 DWORD thread_id_ = 0; 608 #endif 609 610 // Indicates whether or not ownership of the worker thread lies with 611 // this instance or not. (i.e. owned_ == !wrapped). 612 // Must only be modified when the worker thread is not running. 613 bool owned_ = true; 614 615 // Only touched from the worker thread itself. 616 bool blocking_calls_allowed_ = true; 617 618 // Runs webrtc::QueuedTask posted to the Thread. 619 QueuedTaskHandler queued_task_handler_; 620 std::unique_ptr<TaskQueueBase::CurrentTaskQueueSetter> 621 task_queue_registration_; 622 623 friend class ThreadManager; 624 625 RTC_DISALLOW_COPY_AND_ASSIGN(Thread); 626 }; 627 628 // AutoThread automatically installs itself at construction 629 // uninstalls at destruction, if a Thread object is 630 // _not already_ associated with the current OS thread. 631 632 class AutoThread : public Thread { 633 public: 634 AutoThread(); 635 ~AutoThread() override; 636 637 private: 638 RTC_DISALLOW_COPY_AND_ASSIGN(AutoThread); 639 }; 640 641 // AutoSocketServerThread automatically installs itself at 642 // construction and uninstalls at destruction. If a Thread object is 643 // already associated with the current OS thread, it is temporarily 644 // disassociated and restored by the destructor. 645 646 class AutoSocketServerThread : public Thread { 647 public: 648 explicit AutoSocketServerThread(SocketServer* ss); 649 ~AutoSocketServerThread() override; 650 651 private: 652 rtc::Thread* old_thread_; 653 654 RTC_DISALLOW_COPY_AND_ASSIGN(AutoSocketServerThread); 655 }; 656 } // namespace rtc 657 658 #endif // RTC_BASE_THREAD_H_ 659