Home | History | Annotate | Download | only in message_loop
      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 
      5 #ifndef BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_
      6 #define BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_
      7 
      8 #include <memory>
      9 #include <queue>
     10 #include <string>
     11 
     12 #include "base/base_export.h"
     13 #include "base/callback_forward.h"
     14 #include "base/debug/task_annotator.h"
     15 #include "base/gtest_prod_util.h"
     16 #include "base/location.h"
     17 #include "base/macros.h"
     18 #include "base/memory/ref_counted.h"
     19 #include "base/message_loop/incoming_task_queue.h"
     20 #include "base/message_loop/message_loop_task_runner.h"
     21 #include "base/message_loop/message_pump.h"
     22 #include "base/message_loop/timer_slack.h"
     23 #include "base/observer_list.h"
     24 #include "base/pending_task.h"
     25 #include "base/sequenced_task_runner_helpers.h"
     26 #include "base/synchronization/lock.h"
     27 #include "base/time/time.h"
     28 #include "base/tracking_info.h"
     29 #include "build/build_config.h"
     30 
     31 // TODO(sky): these includes should not be necessary. Nuke them.
     32 #if defined(OS_WIN)
     33 #include "base/message_loop/message_pump_win.h"
     34 #elif defined(OS_IOS)
     35 #include "base/message_loop/message_pump_io_ios.h"
     36 #elif defined(OS_POSIX)
     37 #include "base/message_loop/message_pump_libevent.h"
     38 #endif
     39 
     40 namespace base {
     41 
     42 class HistogramBase;
     43 class RunLoop;
     44 class ThreadTaskRunnerHandle;
     45 class WaitableEvent;
     46 
     47 // A MessageLoop is used to process events for a particular thread.  There is
     48 // at most one MessageLoop instance per thread.
     49 //
     50 // Events include at a minimum Task instances submitted to PostTask and its
     51 // variants.  Depending on the type of message pump used by the MessageLoop
     52 // other events such as UI messages may be processed.  On Windows APC calls (as
     53 // time permits) and signals sent to a registered set of HANDLEs may also be
     54 // processed.
     55 //
     56 // NOTE: Unless otherwise specified, a MessageLoop's methods may only be called
     57 // on the thread where the MessageLoop's Run method executes.
     58 //
     59 // NOTE: MessageLoop has task reentrancy protection.  This means that if a
     60 // task is being processed, a second task cannot start until the first task is
     61 // finished.  Reentrancy can happen when processing a task, and an inner
     62 // message pump is created.  That inner pump then processes native messages
     63 // which could implicitly start an inner task.  Inner message pumps are created
     64 // with dialogs (DialogBox), common dialogs (GetOpenFileName), OLE functions
     65 // (DoDragDrop), printer functions (StartDoc) and *many* others.
     66 //
     67 // Sample workaround when inner task processing is needed:
     68 //   HRESULT hr;
     69 //   {
     70 //     MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
     71 //     hr = DoDragDrop(...); // Implicitly runs a modal message loop.
     72 //   }
     73 //   // Process |hr| (the result returned by DoDragDrop()).
     74 //
     75 // Please be SURE your task is reentrant (nestable) and all global variables
     76 // are stable and accessible before calling SetNestableTasksAllowed(true).
     77 //
     78 class BASE_EXPORT MessageLoop : public MessagePump::Delegate {
     79  public:
     80   // A MessageLoop has a particular type, which indicates the set of
     81   // asynchronous events it may process in addition to tasks and timers.
     82   //
     83   // TYPE_DEFAULT
     84   //   This type of ML only supports tasks and timers.
     85   //
     86   // TYPE_UI
     87   //   This type of ML also supports native UI events (e.g., Windows messages).
     88   //   See also MessageLoopForUI.
     89   //
     90   // TYPE_IO
     91   //   This type of ML also supports asynchronous IO.  See also
     92   //   MessageLoopForIO.
     93   //
     94   // TYPE_JAVA
     95   //   This type of ML is backed by a Java message handler which is responsible
     96   //   for running the tasks added to the ML. This is only for use on Android.
     97   //   TYPE_JAVA behaves in essence like TYPE_UI, except during construction
     98   //   where it does not use the main thread specific pump factory.
     99   //
    100   // TYPE_CUSTOM
    101   //   MessagePump was supplied to constructor.
    102   //
    103   enum Type {
    104     TYPE_DEFAULT,
    105     TYPE_UI,
    106     TYPE_CUSTOM,
    107     TYPE_IO,
    108 #if defined(OS_ANDROID)
    109     TYPE_JAVA,
    110 #endif  // defined(OS_ANDROID)
    111   };
    112 
    113   // Normally, it is not necessary to instantiate a MessageLoop.  Instead, it
    114   // is typical to make use of the current thread's MessageLoop instance.
    115   explicit MessageLoop(Type type = TYPE_DEFAULT);
    116   // Creates a TYPE_CUSTOM MessageLoop with the supplied MessagePump, which must
    117   // be non-NULL.
    118   explicit MessageLoop(std::unique_ptr<MessagePump> pump);
    119 
    120   ~MessageLoop() override;
    121 
    122   // Returns the MessageLoop object for the current thread, or null if none.
    123   static MessageLoop* current();
    124 
    125   static void EnableHistogrammer(bool enable_histogrammer);
    126 
    127   typedef std::unique_ptr<MessagePump>(MessagePumpFactory)();
    128   // Uses the given base::MessagePumpForUIFactory to override the default
    129   // MessagePump implementation for 'TYPE_UI'. Returns true if the factory
    130   // was successfully registered.
    131   static bool InitMessagePumpForUIFactory(MessagePumpFactory* factory);
    132 
    133   // Creates the default MessagePump based on |type|. Caller owns return
    134   // value.
    135   static std::unique_ptr<MessagePump> CreateMessagePumpForType(Type type);
    136 
    137   // A DestructionObserver is notified when the current MessageLoop is being
    138   // destroyed.  These observers are notified prior to MessageLoop::current()
    139   // being changed to return NULL.  This gives interested parties the chance to
    140   // do final cleanup that depends on the MessageLoop.
    141   //
    142   // NOTE: Any tasks posted to the MessageLoop during this notification will
    143   // not be run.  Instead, they will be deleted.
    144   //
    145   class BASE_EXPORT DestructionObserver {
    146    public:
    147     virtual void WillDestroyCurrentMessageLoop() = 0;
    148 
    149    protected:
    150     virtual ~DestructionObserver();
    151   };
    152 
    153   // Add a DestructionObserver, which will start receiving notifications
    154   // immediately.
    155   void AddDestructionObserver(DestructionObserver* destruction_observer);
    156 
    157   // Remove a DestructionObserver.  It is safe to call this method while a
    158   // DestructionObserver is receiving a notification callback.
    159   void RemoveDestructionObserver(DestructionObserver* destruction_observer);
    160 
    161   // A NestingObserver is notified when a nested message loop begins. The
    162   // observers are notified before the first task is processed.
    163   class BASE_EXPORT NestingObserver {
    164    public:
    165     virtual void OnBeginNestedMessageLoop() = 0;
    166 
    167    protected:
    168     virtual ~NestingObserver();
    169   };
    170 
    171   void AddNestingObserver(NestingObserver* observer);
    172   void RemoveNestingObserver(NestingObserver* observer);
    173 
    174   // NOTE: Deprecated; prefer task_runner() and the TaskRunner interfaces.
    175   // TODO(skyostil): Remove these functions (crbug.com/465354).
    176   //
    177   // The "PostTask" family of methods call the task's Run method asynchronously
    178   // from within a message loop at some point in the future.
    179   //
    180   // With the PostTask variant, tasks are invoked in FIFO order, inter-mixed
    181   // with normal UI or IO event processing.  With the PostDelayedTask variant,
    182   // tasks are called after at least approximately 'delay_ms' have elapsed.
    183   //
    184   // The NonNestable variants work similarly except that they promise never to
    185   // dispatch the task from a nested invocation of MessageLoop::Run.  Instead,
    186   // such tasks get deferred until the top-most MessageLoop::Run is executing.
    187   //
    188   // The MessageLoop takes ownership of the Task, and deletes it after it has
    189   // been Run().
    190   //
    191   // PostTask(from_here, task) is equivalent to
    192   // PostDelayedTask(from_here, task, 0).
    193   //
    194   // NOTE: These methods may be called on any thread.  The Task will be invoked
    195   // on the thread that executes MessageLoop::Run().
    196   void PostTask(const tracked_objects::Location& from_here,
    197                 const Closure& task);
    198 
    199   void PostDelayedTask(const tracked_objects::Location& from_here,
    200                        const Closure& task,
    201                        TimeDelta delay);
    202 
    203   // A variant on PostTask that deletes the given object.  This is useful
    204   // if the object needs to live until the next run of the MessageLoop (for
    205   // example, deleting a RenderProcessHost from within an IPC callback is not
    206   // good).
    207   //
    208   // NOTE: This method may be called on any thread.  The object will be deleted
    209   // on the thread that executes MessageLoop::Run().
    210   template <class T>
    211   void DeleteSoon(const tracked_objects::Location& from_here, const T* object) {
    212     base::subtle::DeleteHelperInternal<T, void>::DeleteViaSequencedTaskRunner(
    213         this, from_here, object);
    214   }
    215 
    216   // A variant on PostTask that releases the given reference counted object
    217   // (by calling its Release method).  This is useful if the object needs to
    218   // live until the next run of the MessageLoop, or if the object needs to be
    219   // released on a particular thread.
    220   //
    221   // A common pattern is to manually increment the object's reference count
    222   // (AddRef), clear the pointer, then issue a ReleaseSoon.  The reference count
    223   // is incremented manually to ensure clearing the pointer does not trigger a
    224   // delete and to account for the upcoming decrement (ReleaseSoon).  For
    225   // example:
    226   //
    227   // scoped_refptr<Foo> foo = ...
    228   // foo->AddRef();
    229   // Foo* raw_foo = foo.get();
    230   // foo = NULL;
    231   // message_loop->ReleaseSoon(raw_foo);
    232   //
    233   // NOTE: This method may be called on any thread.  The object will be
    234   // released (and thus possibly deleted) on the thread that executes
    235   // MessageLoop::Run().  If this is not the same as the thread that calls
    236   // ReleaseSoon(FROM_HERE, ), then T MUST inherit from
    237   // RefCountedThreadSafe<T>!
    238   template <class T>
    239   void ReleaseSoon(const tracked_objects::Location& from_here,
    240                    const T* object) {
    241     base::subtle::ReleaseHelperInternal<T, void>::ReleaseViaSequencedTaskRunner(
    242         this, from_here, object);
    243   }
    244 
    245   // Deprecated: use RunLoop instead.
    246   // Run the message loop.
    247   void Run();
    248 
    249   // Deprecated: use RunLoop instead.
    250   // Process all pending tasks, windows messages, etc., but don't wait/sleep.
    251   // Return as soon as all items that can be run are taken care of.
    252   void RunUntilIdle();
    253 
    254   // Deprecated: use RunLoop instead.
    255   //
    256   // Signals the Run method to return when it becomes idle. It will continue to
    257   // process pending messages and future messages as long as they are enqueued.
    258   // Warning: if the MessageLoop remains busy, it may never quit. Only use this
    259   // Quit method when looping procedures (such as web pages) have been shut
    260   // down.
    261   //
    262   // This method may only be called on the same thread that called Run, and Run
    263   // must still be on the call stack.
    264   //
    265   // Use QuitClosure variants if you need to Quit another thread's MessageLoop,
    266   // but note that doing so is fairly dangerous if the target thread makes
    267   // nested calls to MessageLoop::Run.  The problem being that you won't know
    268   // which nested run loop you are quitting, so be careful!
    269   void QuitWhenIdle();
    270 
    271   // Deprecated: use RunLoop instead.
    272   //
    273   // This method is a variant of Quit, that does not wait for pending messages
    274   // to be processed before returning from Run.
    275   void QuitNow();
    276 
    277   // Deprecated: use RunLoop instead.
    278   // Construct a Closure that will call QuitWhenIdle(). Useful to schedule an
    279   // arbitrary MessageLoop to QuitWhenIdle.
    280   static Closure QuitWhenIdleClosure();
    281 
    282   // Set the timer slack for this message loop.
    283   void SetTimerSlack(TimerSlack timer_slack) {
    284     pump_->SetTimerSlack(timer_slack);
    285   }
    286 
    287   // Returns true if this loop is |type|. This allows subclasses (especially
    288   // those in tests) to specialize how they are identified.
    289   virtual bool IsType(Type type) const;
    290 
    291   // Returns the type passed to the constructor.
    292   Type type() const { return type_; }
    293 
    294   // Returns the name of the thread this message loop is bound to.
    295   // This function is only valid when this message loop is running and
    296   // BindToCurrentThread has already been called.
    297   std::string GetThreadName() const;
    298 
    299   // Gets the TaskRunner associated with this message loop.
    300   const scoped_refptr<SingleThreadTaskRunner>& task_runner() {
    301     return task_runner_;
    302   }
    303 
    304   // Sets a new TaskRunner for this message loop. The message loop must already
    305   // have been bound to a thread prior to this call, and the task runner must
    306   // belong to that thread. Note that changing the task runner will also affect
    307   // the ThreadTaskRunnerHandle for the target thread. Must be called on the
    308   // thread to which the message loop is bound.
    309   void SetTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner);
    310 
    311   // Enables or disables the recursive task processing. This happens in the case
    312   // of recursive message loops. Some unwanted message loops may occur when
    313   // using common controls or printer functions. By default, recursive task
    314   // processing is disabled.
    315   //
    316   // Please use |ScopedNestableTaskAllower| instead of calling these methods
    317   // directly.  In general, nestable message loops are to be avoided.  They are
    318   // dangerous and difficult to get right, so please use with extreme caution.
    319   //
    320   // The specific case where tasks get queued is:
    321   // - The thread is running a message loop.
    322   // - It receives a task #1 and executes it.
    323   // - The task #1 implicitly starts a message loop, like a MessageBox in the
    324   //   unit test. This can also be StartDoc or GetSaveFileName.
    325   // - The thread receives a task #2 before or while in this second message
    326   //   loop.
    327   // - With NestableTasksAllowed set to true, the task #2 will run right away.
    328   //   Otherwise, it will get executed right after task #1 completes at "thread
    329   //   message loop level".
    330   void SetNestableTasksAllowed(bool allowed);
    331   bool NestableTasksAllowed() const;
    332 
    333   // Enables nestable tasks on |loop| while in scope.
    334   class ScopedNestableTaskAllower {
    335    public:
    336     explicit ScopedNestableTaskAllower(MessageLoop* loop)
    337         : loop_(loop),
    338           old_state_(loop_->NestableTasksAllowed()) {
    339       loop_->SetNestableTasksAllowed(true);
    340     }
    341     ~ScopedNestableTaskAllower() {
    342       loop_->SetNestableTasksAllowed(old_state_);
    343     }
    344 
    345    private:
    346     MessageLoop* loop_;
    347     bool old_state_;
    348   };
    349 
    350   // Returns true if we are currently running a nested message loop.
    351   bool IsNested();
    352 
    353   // A TaskObserver is an object that receives task notifications from the
    354   // MessageLoop.
    355   //
    356   // NOTE: A TaskObserver implementation should be extremely fast!
    357   class BASE_EXPORT TaskObserver {
    358    public:
    359     TaskObserver();
    360 
    361     // This method is called before processing a task.
    362     virtual void WillProcessTask(const PendingTask& pending_task) = 0;
    363 
    364     // This method is called after processing a task.
    365     virtual void DidProcessTask(const PendingTask& pending_task) = 0;
    366 
    367    protected:
    368     virtual ~TaskObserver();
    369   };
    370 
    371   // These functions can only be called on the same thread that |this| is
    372   // running on.
    373   void AddTaskObserver(TaskObserver* task_observer);
    374   void RemoveTaskObserver(TaskObserver* task_observer);
    375 
    376   // Can only be called from the thread that owns the MessageLoop.
    377   bool is_running() const;
    378 
    379   // Returns true if the message loop has high resolution timers enabled.
    380   // Provided for testing.
    381   bool HasHighResolutionTasks();
    382 
    383   // Returns true if the message loop is "idle". Provided for testing.
    384   bool IsIdleForTesting();
    385 
    386   // Returns the TaskAnnotator which is used to add debug information to posted
    387   // tasks.
    388   debug::TaskAnnotator* task_annotator() { return &task_annotator_; }
    389 
    390   // Runs the specified PendingTask.
    391   void RunTask(const PendingTask& pending_task);
    392 
    393 #if defined(OS_WIN)
    394   // TODO (stanisc): crbug.com/596190: Remove this after the signaling issue
    395   // has been investigated.
    396   // This should be used for diagnostic only. If message pump wake-up mechanism
    397   // is based on auto-reset event this call would reset the event to unset
    398   // state.
    399   bool MessagePumpWasSignaled();
    400 #endif
    401 
    402   //----------------------------------------------------------------------------
    403  protected:
    404   std::unique_ptr<MessagePump> pump_;
    405 
    406   using MessagePumpFactoryCallback = Callback<std::unique_ptr<MessagePump>()>;
    407 
    408   // Common protected constructor. Other constructors delegate the
    409   // initialization to this constructor.
    410   // A subclass can invoke this constructor to create a message_loop of a
    411   // specific type with a custom loop. The implementation does not call
    412   // BindToCurrentThread. If this constructor is invoked directly by a subclass,
    413   // then the subclass must subsequently bind the message loop.
    414   MessageLoop(Type type, MessagePumpFactoryCallback pump_factory);
    415 
    416   // Configure various members and bind this message loop to the current thread.
    417   void BindToCurrentThread();
    418 
    419  private:
    420   friend class RunLoop;
    421   friend class internal::IncomingTaskQueue;
    422   friend class ScheduleWorkTest;
    423   friend class Thread;
    424   FRIEND_TEST_ALL_PREFIXES(MessageLoopTest, DeleteUnboundLoop);
    425 
    426   // Creates a MessageLoop without binding to a thread.
    427   // If |type| is TYPE_CUSTOM non-null |pump_factory| must be also given
    428   // to create a message pump for this message loop.  Otherwise a default
    429   // message pump for the |type| is created.
    430   //
    431   // It is valid to call this to create a new message loop on one thread,
    432   // and then pass it to the thread where the message loop actually runs.
    433   // The message loop's BindToCurrentThread() method must be called on the
    434   // thread the message loop runs on, before calling Run().
    435   // Before BindToCurrentThread() is called, only Post*Task() functions can
    436   // be called on the message loop.
    437   static std::unique_ptr<MessageLoop> CreateUnbound(
    438       Type type,
    439       MessagePumpFactoryCallback pump_factory);
    440 
    441   // Sets the ThreadTaskRunnerHandle for the current thread to point to the
    442   // task runner for this message loop.
    443   void SetThreadTaskRunnerHandle();
    444 
    445   // Invokes the actual run loop using the message pump.
    446   void RunHandler();
    447 
    448   // Called to process any delayed non-nestable tasks.
    449   bool ProcessNextDelayedNonNestableTask();
    450 
    451   // Calls RunTask or queues the pending_task on the deferred task list if it
    452   // cannot be run right now.  Returns true if the task was run.
    453   bool DeferOrRunPendingTask(PendingTask pending_task);
    454 
    455   // Adds the pending task to delayed_work_queue_.
    456   void AddToDelayedWorkQueue(PendingTask pending_task);
    457 
    458   // Delete tasks that haven't run yet without running them.  Used in the
    459   // destructor to make sure all the task's destructors get called.  Returns
    460   // true if some work was done.
    461   bool DeletePendingTasks();
    462 
    463   // Loads tasks from the incoming queue to |work_queue_| if the latter is
    464   // empty.
    465   void ReloadWorkQueue();
    466 
    467   // Wakes up the message pump. Can be called on any thread. The caller is
    468   // responsible for synchronizing ScheduleWork() calls.
    469   void ScheduleWork();
    470 
    471   // Start recording histogram info about events and action IF it was enabled
    472   // and IF the statistics recorder can accept a registration of our histogram.
    473   void StartHistogrammer();
    474 
    475   // Add occurrence of event to our histogram, so that we can see what is being
    476   // done in a specific MessageLoop instance (i.e., specific thread).
    477   // If message_histogram_ is NULL, this is a no-op.
    478   void HistogramEvent(int event);
    479 
    480   // Notify observers that a nested message loop is starting.
    481   void NotifyBeginNestedLoop();
    482 
    483   // MessagePump::Delegate methods:
    484   bool DoWork() override;
    485   bool DoDelayedWork(TimeTicks* next_delayed_work_time) override;
    486   bool DoIdleWork() override;
    487 
    488   const Type type_;
    489 
    490   // A list of tasks that need to be processed by this instance.  Note that
    491   // this queue is only accessed (push/pop) by our current thread.
    492   TaskQueue work_queue_;
    493 
    494 #if defined(OS_WIN)
    495   // How many high resolution tasks are in the pending task queue. This value
    496   // increases by N every time we call ReloadWorkQueue() and decreases by 1
    497   // every time we call RunTask() if the task needs a high resolution timer.
    498   int pending_high_res_tasks_;
    499   // Tracks if we have requested high resolution timers. Its only use is to
    500   // turn off the high resolution timer upon loop destruction.
    501   bool in_high_res_mode_;
    502 #endif
    503 
    504   // Contains delayed tasks, sorted by their 'delayed_run_time' property.
    505   DelayedTaskQueue delayed_work_queue_;
    506 
    507   // A recent snapshot of Time::Now(), used to check delayed_work_queue_.
    508   TimeTicks recent_time_;
    509 
    510   // A queue of non-nestable tasks that we had to defer because when it came
    511   // time to execute them we were in a nested message loop.  They will execute
    512   // once we're out of nested message loops.
    513   TaskQueue deferred_non_nestable_work_queue_;
    514 
    515   ObserverList<DestructionObserver> destruction_observers_;
    516 
    517   ObserverList<NestingObserver> nesting_observers_;
    518 
    519   // A recursion block that prevents accidentally running additional tasks when
    520   // insider a (accidentally induced?) nested message pump.
    521   bool nestable_tasks_allowed_;
    522 
    523   // pump_factory_.Run() is called to create a message pump for this loop
    524   // if type_ is TYPE_CUSTOM and pump_ is null.
    525   MessagePumpFactoryCallback pump_factory_;
    526 
    527   // A profiling histogram showing the counts of various messages and events.
    528   HistogramBase* message_histogram_;
    529 
    530   RunLoop* run_loop_;
    531 
    532   ObserverList<TaskObserver> task_observers_;
    533 
    534   debug::TaskAnnotator task_annotator_;
    535 
    536   scoped_refptr<internal::IncomingTaskQueue> incoming_task_queue_;
    537 
    538   // A task runner which we haven't bound to a thread yet.
    539   scoped_refptr<internal::MessageLoopTaskRunner> unbound_task_runner_;
    540 
    541   // The task runner associated with this message loop.
    542   scoped_refptr<SingleThreadTaskRunner> task_runner_;
    543   std::unique_ptr<ThreadTaskRunnerHandle> thread_task_runner_handle_;
    544 
    545   // Id of the thread this message loop is bound to.
    546   PlatformThreadId thread_id_;
    547 
    548   template <class T, class R> friend class base::subtle::DeleteHelperInternal;
    549   template <class T, class R> friend class base::subtle::ReleaseHelperInternal;
    550 
    551   void DeleteSoonInternal(const tracked_objects::Location& from_here,
    552                           void(*deleter)(const void*),
    553                           const void* object);
    554   void ReleaseSoonInternal(const tracked_objects::Location& from_here,
    555                            void(*releaser)(const void*),
    556                            const void* object);
    557 
    558   DISALLOW_COPY_AND_ASSIGN(MessageLoop);
    559 };
    560 
    561 #if !defined(OS_NACL)
    562 
    563 //-----------------------------------------------------------------------------
    564 // MessageLoopForUI extends MessageLoop with methods that are particular to a
    565 // MessageLoop instantiated with TYPE_UI.
    566 //
    567 // This class is typically used like so:
    568 //   MessageLoopForUI::current()->...call some method...
    569 //
    570 class BASE_EXPORT MessageLoopForUI : public MessageLoop {
    571  public:
    572   MessageLoopForUI() : MessageLoop(TYPE_UI) {
    573   }
    574 
    575   explicit MessageLoopForUI(std::unique_ptr<MessagePump> pump);
    576 
    577   // Returns the MessageLoopForUI of the current thread.
    578   static MessageLoopForUI* current() {
    579     MessageLoop* loop = MessageLoop::current();
    580     DCHECK(loop);
    581     DCHECK(loop->IsType(MessageLoop::TYPE_UI));
    582     return static_cast<MessageLoopForUI*>(loop);
    583   }
    584 
    585   static bool IsCurrent() {
    586     MessageLoop* loop = MessageLoop::current();
    587     return loop && loop->IsType(MessageLoop::TYPE_UI);
    588   }
    589 
    590 #if defined(OS_IOS)
    591   // On iOS, the main message loop cannot be Run().  Instead call Attach(),
    592   // which connects this MessageLoop to the UI thread's CFRunLoop and allows
    593   // PostTask() to work.
    594   void Attach();
    595 #endif
    596 
    597 #if defined(OS_ANDROID)
    598   // On Android, the UI message loop is handled by Java side. So Run() should
    599   // never be called. Instead use Start(), which will forward all the native UI
    600   // events to the Java message loop.
    601   void Start();
    602 #endif
    603 
    604 #if defined(USE_OZONE) || (defined(USE_X11) && !defined(USE_GLIB))
    605   // Please see MessagePumpLibevent for definition.
    606   bool WatchFileDescriptor(
    607       int fd,
    608       bool persistent,
    609       MessagePumpLibevent::Mode mode,
    610       MessagePumpLibevent::FileDescriptorWatcher* controller,
    611       MessagePumpLibevent::Watcher* delegate);
    612 #endif
    613 };
    614 
    615 // Do not add any member variables to MessageLoopForUI!  This is important b/c
    616 // MessageLoopForUI is often allocated via MessageLoop(TYPE_UI).  Any extra
    617 // data that you need should be stored on the MessageLoop's pump_ instance.
    618 static_assert(sizeof(MessageLoop) == sizeof(MessageLoopForUI),
    619               "MessageLoopForUI should not have extra member variables");
    620 
    621 #endif  // !defined(OS_NACL)
    622 
    623 //-----------------------------------------------------------------------------
    624 // MessageLoopForIO extends MessageLoop with methods that are particular to a
    625 // MessageLoop instantiated with TYPE_IO.
    626 //
    627 // This class is typically used like so:
    628 //   MessageLoopForIO::current()->...call some method...
    629 //
    630 class BASE_EXPORT MessageLoopForIO : public MessageLoop {
    631  public:
    632   MessageLoopForIO();
    633 
    634   // Returns the MessageLoopForIO of the current thread.
    635   static MessageLoopForIO* current() {
    636     MessageLoop* loop = MessageLoop::current();
    637     DCHECK(loop) << "Can't call MessageLoopForIO::current() when no message "
    638                     "loop was created for this thread. Use "
    639                     " MessageLoop::current() or MessageLoopForIO::IsCurrent().";
    640     DCHECK_EQ(MessageLoop::TYPE_IO, loop->type());
    641     return static_cast<MessageLoopForIO*>(loop);
    642   }
    643 
    644   static bool IsCurrent() {
    645     MessageLoop* loop = MessageLoop::current();
    646     return loop && loop->type() == MessageLoop::TYPE_IO;
    647   }
    648 
    649 #if !defined(OS_NACL_SFI)
    650 
    651 #if defined(OS_WIN)
    652   typedef MessagePumpForIO::IOHandler IOHandler;
    653   typedef MessagePumpForIO::IOContext IOContext;
    654 #elif defined(OS_IOS)
    655   typedef MessagePumpIOSForIO::Watcher Watcher;
    656   typedef MessagePumpIOSForIO::FileDescriptorWatcher
    657       FileDescriptorWatcher;
    658 
    659   enum Mode {
    660     WATCH_READ = MessagePumpIOSForIO::WATCH_READ,
    661     WATCH_WRITE = MessagePumpIOSForIO::WATCH_WRITE,
    662     WATCH_READ_WRITE = MessagePumpIOSForIO::WATCH_READ_WRITE
    663   };
    664 #elif defined(OS_POSIX)
    665   typedef MessagePumpLibevent::Watcher Watcher;
    666   typedef MessagePumpLibevent::FileDescriptorWatcher
    667       FileDescriptorWatcher;
    668 
    669   enum Mode {
    670     WATCH_READ = MessagePumpLibevent::WATCH_READ,
    671     WATCH_WRITE = MessagePumpLibevent::WATCH_WRITE,
    672     WATCH_READ_WRITE = MessagePumpLibevent::WATCH_READ_WRITE
    673   };
    674 #endif
    675 
    676 #if defined(OS_WIN)
    677   // Please see MessagePumpWin for definitions of these methods.
    678   void RegisterIOHandler(HANDLE file, IOHandler* handler);
    679   bool RegisterJobObject(HANDLE job, IOHandler* handler);
    680   bool WaitForIOCompletion(DWORD timeout, IOHandler* filter);
    681 #elif defined(OS_POSIX)
    682   // Please see MessagePumpIOSForIO/MessagePumpLibevent for definition.
    683   bool WatchFileDescriptor(int fd,
    684                            bool persistent,
    685                            Mode mode,
    686                            FileDescriptorWatcher* controller,
    687                            Watcher* delegate);
    688 #endif  // defined(OS_IOS) || defined(OS_POSIX)
    689 #endif  // !defined(OS_NACL_SFI)
    690 };
    691 
    692 // Do not add any member variables to MessageLoopForIO!  This is important b/c
    693 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO).  Any extra
    694 // data that you need should be stored on the MessageLoop's pump_ instance.
    695 static_assert(sizeof(MessageLoop) == sizeof(MessageLoopForIO),
    696               "MessageLoopForIO should not have extra member variables");
    697 
    698 }  // namespace base
    699 
    700 #endif  // BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_
    701