• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
SetTimerSlack(TimerSlack timer_slack)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.
type()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.
task_runner()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:
ScopedNestableTaskAllower(MessageLoop * loop)266     explicit ScopedNestableTaskAllower(MessageLoop* loop)
267         : loop_(loop),
268           old_state_(loop_->NestableTasksAllowed()) {
269       loop_->SetNestableTasksAllowed(true);
270     }
~ScopedNestableTaskAllower()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.
task_annotator()318   debug::TaskAnnotator* task_annotator() { return &task_annotator_; }
319 
320   // Runs the specified PendingTask.
321   void RunTask(PendingTask* pending_task);
322 
nesting_allowed()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.
DisallowNesting()327   void DisallowNesting() { allow_nesting_ = false; }
328 
329   // Disallow task observers. After this is called, calling
330   // Add/RemoveTaskObserver() on this MessageLoop will crash.
DisallowTaskObservers()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:
MessageLoopForUI()497   MessageLoopForUI() : MessageLoop(TYPE_UI) {
498   }
499 
500   explicit MessageLoopForUI(std::unique_ptr<MessagePump> pump);
501 
502   // Returns the MessageLoopForUI of the current thread.
current()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 
IsCurrent()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:
MessageLoopForIO()562   MessageLoopForIO() : MessageLoop(TYPE_IO) {
563   }
564 
565   // Returns the MessageLoopForIO of the current thread.
current()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 
IsCurrent()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