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