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
40namespace base {
41
42class HistogramBase;
43class RunLoop;
44class ThreadTaskRunnerHandle;
45class 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//
78class 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//
570class 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.
618static_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//
630class 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.
695static_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