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