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