signal_thread.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. #ifndef RTC_BASE_DEPRECATED_SIGNAL_THREAD_H_
  11. #define RTC_BASE_DEPRECATED_SIGNAL_THREAD_H_
  12. #include <string>
  13. #include "rtc_base/checks.h"
  14. #include "rtc_base/constructor_magic.h"
  15. #include "rtc_base/deprecated/recursive_critical_section.h"
  16. #include "rtc_base/deprecation.h"
  17. #include "rtc_base/message_handler.h"
  18. #include "rtc_base/third_party/sigslot/sigslot.h"
  19. #include "rtc_base/thread.h"
  20. #include "rtc_base/thread_annotations.h"
  21. namespace rtc {
  22. ///////////////////////////////////////////////////////////////////////////////
  23. // NOTE: this class has been deprecated. Do not use for new code. New code
  24. // should use factilities exposed by api/task_queue/ instead.
  25. //
  26. // SignalThread - Base class for worker threads. The main thread should call
  27. // Start() to begin work, and then follow one of these models:
  28. // Normal: Wait for SignalWorkDone, and then call Release to destroy.
  29. // Cancellation: Call Release(true), to abort the worker thread.
  30. // Fire-and-forget: Call Release(false), which allows the thread to run to
  31. // completion, and then self-destruct without further notification.
  32. // Periodic tasks: Wait for SignalWorkDone, then eventually call Start()
  33. // again to repeat the task. When the instance isn't needed anymore,
  34. // call Release. DoWork, OnWorkStart and OnWorkStop are called again,
  35. // on a new thread.
  36. // The subclass should override DoWork() to perform the background task. By
  37. // periodically calling ContinueWork(), it can check for cancellation.
  38. // OnWorkStart and OnWorkDone can be overridden to do pre- or post-work
  39. // tasks in the context of the main thread.
  40. ///////////////////////////////////////////////////////////////////////////////
  41. class DEPRECATED_SignalThread : public sigslot::has_slots<>,
  42. protected MessageHandlerAutoCleanup {
  43. public:
  44. DEPRECATED_SignalThread();
  45. // Context: Main Thread. Call before Start to change the worker's name.
  46. bool SetName(const std::string& name, const void* obj);
  47. // Context: Main Thread. Call to begin the worker thread.
  48. void Start();
  49. // Context: Main Thread. If the worker thread is not running, deletes the
  50. // object immediately. Otherwise, asks the worker thread to abort processing,
  51. // and schedules the object to be deleted once the worker exits.
  52. // SignalWorkDone will not be signalled. If wait is true, does not return
  53. // until the thread is deleted.
  54. void Destroy(bool wait);
  55. // Context: Main Thread. If the worker thread is complete, deletes the
  56. // object immediately. Otherwise, schedules the object to be deleted once
  57. // the worker thread completes. SignalWorkDone will be signalled.
  58. void Release();
  59. // Context: Main Thread. Signalled when work is complete.
  60. sigslot::signal1<DEPRECATED_SignalThread*> SignalWorkDone;
  61. enum { ST_MSG_WORKER_DONE, ST_MSG_FIRST_AVAILABLE };
  62. protected:
  63. ~DEPRECATED_SignalThread() override;
  64. Thread* worker() { return &worker_; }
  65. // Context: Main Thread. Subclass should override to do pre-work setup.
  66. virtual void OnWorkStart() {}
  67. // Context: Worker Thread. Subclass should override to do work.
  68. virtual void DoWork() = 0;
  69. // Context: Worker Thread. Subclass should call periodically to
  70. // dispatch messages and determine if the thread should terminate.
  71. bool ContinueWork();
  72. // Context: Worker Thread. Subclass should override when extra work is
  73. // needed to abort the worker thread.
  74. virtual void OnWorkStop() {}
  75. // Context: Main Thread. Subclass should override to do post-work cleanup.
  76. virtual void OnWorkDone() {}
  77. // Context: Any Thread. If subclass overrides, be sure to call the base
  78. // implementation. Do not use (message_id < ST_MSG_FIRST_AVAILABLE)
  79. void OnMessage(Message* msg) override;
  80. private:
  81. enum State {
  82. kInit, // Initialized, but not started
  83. kRunning, // Started and doing work
  84. kReleasing, // Same as running, but to be deleted when work is done
  85. kComplete, // Work is done
  86. kStopping, // Work is being interrupted
  87. };
  88. class Worker : public Thread {
  89. public:
  90. explicit Worker(DEPRECATED_SignalThread* parent);
  91. Worker() = delete;
  92. Worker(const Worker&) = delete;
  93. Worker& operator=(const Worker&) = delete;
  94. ~Worker() override;
  95. void Run() override;
  96. bool IsProcessingMessagesForTesting() override;
  97. private:
  98. DEPRECATED_SignalThread* parent_;
  99. };
  100. class RTC_SCOPED_LOCKABLE EnterExit {
  101. public:
  102. explicit EnterExit(DEPRECATED_SignalThread* t)
  103. RTC_EXCLUSIVE_LOCK_FUNCTION(t->cs_)
  104. : t_(t) {
  105. t_->cs_.Enter();
  106. // If refcount_ is zero then the object has already been deleted and we
  107. // will be double-deleting it in ~EnterExit()! (shouldn't happen)
  108. RTC_DCHECK_NE(0, t_->refcount_);
  109. ++t_->refcount_;
  110. }
  111. EnterExit() = delete;
  112. EnterExit(const EnterExit&) = delete;
  113. EnterExit& operator=(const EnterExit&) = delete;
  114. ~EnterExit() RTC_UNLOCK_FUNCTION() {
  115. bool d = (0 == --t_->refcount_);
  116. t_->cs_.Leave();
  117. if (d)
  118. delete t_;
  119. }
  120. private:
  121. DEPRECATED_SignalThread* t_;
  122. };
  123. void Run();
  124. void OnMainThreadDestroyed();
  125. Thread* main_;
  126. Worker worker_;
  127. RecursiveCriticalSection cs_;
  128. State state_ RTC_GUARDED_BY(cs_);
  129. int refcount_ RTC_GUARDED_BY(cs_);
  130. bool destroy_called_ RTC_GUARDED_BY(cs_) = false;
  131. RTC_DISALLOW_COPY_AND_ASSIGN(DEPRECATED_SignalThread);
  132. };
  133. typedef RTC_DEPRECATED DEPRECATED_SignalThread SignalThread;
  134. ///////////////////////////////////////////////////////////////////////////////
  135. } // namespace rtc
  136. #endif // RTC_BASE_DEPRECATED_SIGNAL_THREAD_H_