message_loop.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_
  5. #define BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_
  6. #include <memory>
  7. #include <string>
  8. #include "base/base_export.h"
  9. #include "base/callback_forward.h"
  10. #include "base/gtest_prod_util.h"
  11. #include "base/macros.h"
  12. #include "base/memory/scoped_refptr.h"
  13. #include "base/message_loop/message_pump_type.h"
  14. #include "base/message_loop/timer_slack.h"
  15. #include "base/pending_task.h"
  16. #include "base/run_loop.h"
  17. #include "base/threading/thread_checker.h"
  18. #include "base/time/time.h"
  19. #include "build/build_config.h"
  20. namespace base {
  21. class MessagePump;
  22. class TaskObserver;
  23. namespace sequence_manager {
  24. class TaskQueue;
  25. namespace internal {
  26. class SequenceManagerImpl;
  27. } // namespace internal
  28. } // namespace sequence_manager
  29. // A MessageLoop is used to process events for a particular thread. There is
  30. // at most one MessageLoop instance per thread.
  31. //
  32. // Events include at a minimum Task instances submitted to the MessageLoop's
  33. // TaskRunner. Depending on the Type of message pump used by the MessageLoop
  34. // other events such as UI messages may be processed. On Windows APC calls (as
  35. // time permits) and signals sent to a registered set of HANDLEs may also be
  36. // processed.
  37. //
  38. // The MessageLoop's API should only be used directly by its owner (and users
  39. // which the owner opts to share a MessageLoop* with). Other ways to access
  40. // subsets of the MessageLoop API:
  41. // - base::RunLoop : Drive the MessageLoop from the thread it's bound to.
  42. // - base::Thread/SequencedTaskRunnerHandle : Post back to the MessageLoop
  43. // from a task running on it.
  44. // - SequenceLocalStorageSlot : Bind external state to this MessageLoop.
  45. // - base::MessageLoopCurrent : Access statically exposed APIs of this
  46. // MessageLoop.
  47. // - Embedders may provide their own static accessors to post tasks on
  48. // specific loops (e.g. content::BrowserThreads).
  49. //
  50. // NOTE: Unless otherwise specified, a MessageLoop's methods may only be called
  51. // on the thread where the MessageLoop's Run method executes.
  52. //
  53. // NOTE: MessageLoop has task reentrancy protection. This means that if a
  54. // task is being processed, a second task cannot start until the first task is
  55. // finished. Reentrancy can happen when processing a task, and an inner
  56. // message pump is created. That inner pump then processes native messages
  57. // which could implicitly start an inner task. Inner message pumps are created
  58. // with dialogs (DialogBox), common dialogs (GetOpenFileName), OLE functions
  59. // (DoDragDrop), printer functions (StartDoc) and *many* others.
  60. //
  61. // Sample workaround when inner task processing is needed:
  62. // HRESULT hr;
  63. // {
  64. // MessageLoopCurrent::ScopedNestableTaskAllower allow;
  65. // hr = DoDragDrop(...); // Implicitly runs a modal message loop.
  66. // }
  67. // // Process |hr| (the result returned by DoDragDrop()).
  68. //
  69. // Please be SURE your task is reentrant (nestable) and all global variables
  70. // are stable and accessible before calling SetNestableTasksAllowed(true).
  71. //
  72. // DEPRECATED: Use a SingleThreadTaskExecutor instead or TaskEnvironment
  73. // for tests. TODO(https://crbug.com/891670/) remove this class.
  74. class BASE_EXPORT MessageLoop {
  75. public:
  76. // Normally, it is not necessary to instantiate a MessageLoop. Instead, it
  77. // is typical to make use of the current thread's MessageLoop instance.
  78. explicit MessageLoop(MessagePumpType type = MessagePumpType::DEFAULT);
  79. // Creates a MessageLoop with the supplied MessagePump, which must be
  80. // non-null.
  81. explicit MessageLoop(std::unique_ptr<MessagePump> custom_pump);
  82. virtual ~MessageLoop();
  83. // Set the timer slack for this message loop.
  84. void SetTimerSlack(TimerSlack timer_slack);
  85. // Returns true if this loop's pump is |type|. This allows subclasses
  86. // (especially those in tests) to specialize how they are identified.
  87. virtual bool IsType(MessagePumpType type) const;
  88. // Returns the type passed to the constructor.
  89. MessagePumpType type() const { return type_; }
  90. // Sets a new TaskRunner for this message loop. If the message loop was
  91. // already bound, this must be called on the thread to which it is bound.
  92. void SetTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner);
  93. // Gets the TaskRunner associated with this message loop.
  94. scoped_refptr<SingleThreadTaskRunner> task_runner() const;
  95. // These functions can only be called on the same thread that |this| is
  96. // running on.
  97. // These functions must not be called from a TaskObserver callback.
  98. void AddTaskObserver(TaskObserver* task_observer);
  99. void RemoveTaskObserver(TaskObserver* task_observer);
  100. // Returns true if the message loop is idle (ignoring delayed tasks). This is
  101. // the same condition which triggers DoWork() to return false: i.e.
  102. // out of tasks which can be processed at the current run-level -- there might
  103. // be deferred non-nestable tasks remaining if currently in a nested run
  104. // level.
  105. // TODO(alexclarke): Make this const when MessageLoopImpl goes away.
  106. bool IsIdleForTesting();
  107. //----------------------------------------------------------------------------
  108. protected:
  109. // Returns true if this is the active MessageLoop for the current thread.
  110. bool IsBoundToCurrentThread() const;
  111. using MessagePumpFactoryCallback =
  112. OnceCallback<std::unique_ptr<MessagePump>()>;
  113. // Common protected constructor. Other constructors delegate the
  114. // initialization to this constructor.
  115. // A subclass can invoke this constructor to create a message_loop of a
  116. // specific type with a custom loop. The implementation does not call
  117. // BindToCurrentThread. If this constructor is invoked directly by a subclass,
  118. // then the subclass must subsequently bind the message loop.
  119. MessageLoop(MessagePumpType type, std::unique_ptr<MessagePump> pump);
  120. // Configure various members and bind this message loop to the current thread.
  121. void BindToCurrentThread();
  122. // A raw pointer to the MessagePump handed-off to |sequence_manager_|.
  123. // Valid for the lifetime of |sequence_manager_|.
  124. MessagePump* pump_ = nullptr;
  125. // TODO(crbug.com/891670): We shouldn't publicly expose all of
  126. // SequenceManagerImpl.
  127. const std::unique_ptr<sequence_manager::internal::SequenceManagerImpl>
  128. sequence_manager_;
  129. // SequenceManager requires an explicit initialisation of the default task
  130. // queue.
  131. const scoped_refptr<sequence_manager::TaskQueue> default_task_queue_;
  132. private:
  133. friend class MessageLoopTypedTest;
  134. friend class ScheduleWorkTest;
  135. friend class Thread;
  136. friend class sequence_manager::internal::SequenceManagerImpl;
  137. FRIEND_TEST_ALL_PREFIXES(MessageLoopTest, DeleteUnboundLoop);
  138. // Creates a MessageLoop without binding to a thread.
  139. //
  140. // It is valid to call this to create a new message loop on one thread,
  141. // and then pass it to the thread where the message loop actually runs.
  142. // The message loop's BindToCurrentThread() method must be called on the
  143. // thread the message loop runs on, before calling Run().
  144. // Before BindToCurrentThread() is called, only Post*Task() functions can
  145. // be called on the message loop.
  146. static std::unique_ptr<MessageLoop> CreateUnbound(MessagePumpType type);
  147. static std::unique_ptr<MessageLoop> CreateUnbound(
  148. std::unique_ptr<MessagePump> pump);
  149. scoped_refptr<sequence_manager::TaskQueue> CreateDefaultTaskQueue();
  150. std::unique_ptr<MessagePump> CreateMessagePump();
  151. sequence_manager::internal::SequenceManagerImpl* GetSequenceManagerImpl()
  152. const {
  153. return sequence_manager_.get();
  154. }
  155. const MessagePumpType type_;
  156. // If set this will be returned by the next call to CreateMessagePump().
  157. // This is only set if |type_| is TYPE_CUSTOM and |pump_| is null.
  158. std::unique_ptr<MessagePump> custom_pump_;
  159. // Id of the thread this message loop is bound to. Initialized once when the
  160. // MessageLoop is bound to its thread and constant forever after.
  161. PlatformThreadId thread_id_ = kInvalidThreadId;
  162. // Verifies that calls are made on the thread on which BindToCurrentThread()
  163. // was invoked.
  164. THREAD_CHECKER(bound_thread_checker_);
  165. DISALLOW_COPY_AND_ASSIGN(MessageLoop);
  166. };
  167. } // namespace base
  168. #endif // BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_