LCOV - code coverage report
Current view: directory - ipc/chromium/src/base - message_loop.h (source / functions) Found Hit Coverage
Test: app.info Lines: 37 13 35.1 %
Date: 2012-06-02 Functions: 21 8 38.1 %

       1                 : // Copyright (c) 2006-2008 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_H_
       6                 : #define BASE_MESSAGE_LOOP_H_
       7                 : 
       8                 : #include <deque>
       9                 : #include <queue>
      10                 : #include <string>
      11                 : #include <vector>
      12                 : 
      13                 : #include <map>
      14                 : #include "base/lock.h"
      15                 : #include "base/message_pump.h"
      16                 : #include "base/observer_list.h"
      17                 : #include "base/ref_counted.h"
      18                 : #include "base/scoped_ptr.h"
      19                 : #include "base/task.h"
      20                 : #include "base/timer.h"
      21                 : 
      22                 : #if defined(OS_WIN)
      23                 : // We need this to declare base::MessagePumpWin::Dispatcher, which we should
      24                 : // really just eliminate.
      25                 : #include "base/message_pump_win.h"
      26                 : #elif defined(OS_POSIX)
      27                 : #include "base/message_pump_libevent.h"
      28                 : #endif
      29                 : 
      30                 : namespace mozilla {
      31                 : namespace ipc {
      32                 : 
      33                 : class DoWorkRunnable;
      34                 : 
      35                 : } /* namespace ipc */
      36                 : } /* namespace mozilla */
      37                 : 
      38                 : // A MessageLoop is used to process events for a particular thread.  There is
      39                 : // at most one MessageLoop instance per thread.
      40                 : //
      41                 : // Events include at a minimum Task instances submitted to PostTask or those
      42                 : // managed by TimerManager.  Depending on the type of message pump used by the
      43                 : // MessageLoop other events such as UI messages may be processed.  On Windows
      44                 : // APC calls (as time permits) and signals sent to a registered set of HANDLEs
      45                 : // may also be processed.
      46                 : //
      47                 : // NOTE: Unless otherwise specified, a MessageLoop's methods may only be called
      48                 : // on the thread where the MessageLoop's Run method executes.
      49                 : //
      50                 : // NOTE: MessageLoop has task reentrancy protection.  This means that if a
      51                 : // task is being processed, a second task cannot start until the first task is
      52                 : // finished.  Reentrancy can happen when processing a task, and an inner
      53                 : // message pump is created.  That inner pump then processes native messages
      54                 : // which could implicitly start an inner task.  Inner message pumps are created
      55                 : // with dialogs (DialogBox), common dialogs (GetOpenFileName), OLE functions
      56                 : // (DoDragDrop), printer functions (StartDoc) and *many* others.
      57                 : //
      58                 : // Sample workaround when inner task processing is needed:
      59                 : //   bool old_state = MessageLoop::current()->NestableTasksAllowed();
      60                 : //   MessageLoop::current()->SetNestableTasksAllowed(true);
      61                 : //   HRESULT hr = DoDragDrop(...); // Implicitly runs a modal message loop here.
      62                 : //   MessageLoop::current()->SetNestableTasksAllowed(old_state);
      63                 : //   // Process hr  (the result returned by DoDragDrop().
      64                 : //
      65                 : // Please be SURE your task is reentrant (nestable) and all global variables
      66                 : // are stable and accessible before calling SetNestableTasksAllowed(true).
      67                 : //
      68                 : class MessageLoop : public base::MessagePump::Delegate {
      69                 : 
      70                 :   friend class mozilla::ipc::DoWorkRunnable;
      71                 : 
      72                 : public:
      73                 :   // A DestructionObserver is notified when the current MessageLoop is being
      74                 :   // destroyed.  These obsevers are notified prior to MessageLoop::current()
      75                 :   // being changed to return NULL.  This gives interested parties the chance to
      76                 :   // do final cleanup that depends on the MessageLoop.
      77                 :   //
      78                 :   // NOTE: Any tasks posted to the MessageLoop during this notification will
      79                 :   // not be run.  Instead, they will be deleted.
      80                 :   //
      81               2 :   class DestructionObserver {
      82                 :    public:
      83               0 :     virtual ~DestructionObserver() {}
      84                 :     virtual void WillDestroyCurrentMessageLoop() = 0;
      85                 :   };
      86                 : 
      87                 :   // Add a DestructionObserver, which will start receiving notifications
      88                 :   // immediately.
      89                 :   void AddDestructionObserver(DestructionObserver* destruction_observer);
      90                 : 
      91                 :   // Remove a DestructionObserver.  It is safe to call this method while a
      92                 :   // DestructionObserver is receiving a notification callback.
      93                 :   void RemoveDestructionObserver(DestructionObserver* destruction_observer);
      94                 : 
      95                 :   // The "PostTask" family of methods call the task's Run method asynchronously
      96                 :   // from within a message loop at some point in the future.
      97                 :   //
      98                 :   // With the PostTask variant, tasks are invoked in FIFO order, inter-mixed
      99                 :   // with normal UI or IO event processing.  With the PostDelayedTask variant,
     100                 :   // tasks are called after at least approximately 'delay_ms' have elapsed.
     101                 :   //
     102                 :   // The NonNestable variants work similarly except that they promise never to
     103                 :   // dispatch the task from a nested invocation of MessageLoop::Run.  Instead,
     104                 :   // such tasks get deferred until the top-most MessageLoop::Run is executing.
     105                 :   //
     106                 :   // The MessageLoop takes ownership of the Task, and deletes it after it has
     107                 :   // been Run().
     108                 :   //
     109                 :   // NOTE: These methods may be called on any thread.  The Task will be invoked
     110                 :   // on the thread that executes MessageLoop::Run().
     111                 : 
     112                 :   void PostTask(
     113                 :       const tracked_objects::Location& from_here, Task* task);
     114                 : 
     115                 :   void PostDelayedTask(
     116                 :       const tracked_objects::Location& from_here, Task* task, int delay_ms);
     117                 : 
     118                 :   void PostNonNestableTask(
     119                 :       const tracked_objects::Location& from_here, Task* task);
     120                 : 
     121                 :   void PostNonNestableDelayedTask(
     122                 :       const tracked_objects::Location& from_here, Task* task, int delay_ms);
     123                 : 
     124                 :   // A variant on PostTask that deletes the given object.  This is useful
     125                 :   // if the object needs to live until the next run of the MessageLoop (for
     126                 :   // example, deleting a RenderProcessHost from within an IPC callback is not
     127                 :   // good).
     128                 :   //
     129                 :   // NOTE: This method may be called on any thread.  The object will be deleted
     130                 :   // on the thread that executes MessageLoop::Run().  If this is not the same
     131                 :   // as the thread that calls PostDelayedTask(FROM_HERE, ), then T MUST inherit
     132                 :   // from RefCountedThreadSafe<T>!
     133                 :   template <class T>
     134                 :   void DeleteSoon(const tracked_objects::Location& from_here, T* object) {
     135                 :     PostNonNestableTask(from_here, new DeleteTask<T>(object));
     136                 :   }
     137                 : 
     138                 :   // A variant on PostTask that releases the given reference counted object
     139                 :   // (by calling its Release method).  This is useful if the object needs to
     140                 :   // live until the next run of the MessageLoop, or if the object needs to be
     141                 :   // released on a particular thread.
     142                 :   //
     143                 :   // NOTE: This method may be called on any thread.  The object will be
     144                 :   // released (and thus possibly deleted) on the thread that executes
     145                 :   // MessageLoop::Run().  If this is not the same as the thread that calls
     146                 :   // PostDelayedTask(FROM_HERE, ), then T MUST inherit from
     147                 :   // RefCountedThreadSafe<T>!
     148                 :   template <class T>
     149                 :   void ReleaseSoon(const tracked_objects::Location& from_here, T* object) {
     150                 :     PostNonNestableTask(from_here, new ReleaseTask<T>(object));
     151                 :   }
     152                 : 
     153                 :   // Run the message loop.
     154                 :   void Run();
     155                 : 
     156                 :   // Process all pending tasks, windows messages, etc., but don't wait/sleep.
     157                 :   // Return as soon as all items that can be run are taken care of.
     158                 :   void RunAllPending();
     159                 : 
     160                 :   // Signals the Run method to return after it is done processing all pending
     161                 :   // messages.  This method may only be called on the same thread that called
     162                 :   // Run, and Run must still be on the call stack.
     163                 :   //
     164                 :   // Use QuitTask if you need to Quit another thread's MessageLoop, but note
     165                 :   // that doing so is fairly dangerous if the target thread makes nested calls
     166                 :   // to MessageLoop::Run.  The problem being that you won't know which nested
     167                 :   // run loop you are quiting, so be careful!
     168                 :   //
     169                 :   void Quit();
     170                 : 
     171                 :   // Invokes Quit on the current MessageLoop when run.  Useful to schedule an
     172                 :   // arbitrary MessageLoop to Quit.
     173               0 :   class QuitTask : public Task {
     174                 :    public:
     175               0 :     virtual void Run() {
     176               0 :       MessageLoop::current()->Quit();
     177               0 :     }
     178                 :   };
     179                 : 
     180                 :   // A MessageLoop has a particular type, which indicates the set of
     181                 :   // asynchronous events it may process in addition to tasks and timers.
     182                 :   //
     183                 :   // TYPE_DEFAULT
     184                 :   //   This type of ML only supports tasks and timers.
     185                 :   //
     186                 :   // TYPE_UI
     187                 :   //   This type of ML also supports native UI events (e.g., Windows messages).
     188                 :   //   See also MessageLoopForUI.
     189                 :   //
     190                 :   // TYPE_IO
     191                 :   //   This type of ML also supports asynchronous IO.  See also
     192                 :   //   MessageLoopForIO.
     193                 :   //
     194                 :   // TYPE_MOZILLA_CHILD
     195                 :   //   This type of ML is used in Mozilla child processes which initialize
     196                 :   //   XPCOM and use the gecko event loop.
     197                 :   //
     198                 :   // TYPE_MOZILLA_UI
     199                 :   //   This type of ML is used in Mozilla parent processes which initialize
     200                 :   //   XPCOM and use the gecko event loop.
     201                 :   //
     202                 :   enum Type {
     203                 :     TYPE_DEFAULT,
     204                 :     TYPE_UI,
     205                 :     TYPE_IO,
     206                 :     TYPE_MOZILLA_CHILD,
     207                 :     TYPE_MOZILLA_UI
     208                 :   };
     209                 : 
     210                 :   // Normally, it is not necessary to instantiate a MessageLoop.  Instead, it
     211                 :   // is typical to make use of the current thread's MessageLoop instance.
     212                 :   explicit MessageLoop(Type type = TYPE_DEFAULT);
     213                 :   ~MessageLoop();
     214                 : 
     215                 :   // Returns the type passed to the constructor.
     216               0 :   Type type() const { return type_; }
     217                 : 
     218                 :   // Optional call to connect the thread name with this loop.
     219            1420 :   void set_thread_name(const std::string& thread_name) {
     220            1420 :     DCHECK(thread_name_.empty()) << "Should not rename this thread!";
     221            1420 :     thread_name_ = thread_name;
     222            1420 :   }
     223               0 :   const std::string& thread_name() const { return thread_name_; }
     224                 : 
     225                 :   // Returns the MessageLoop object for the current thread, or null if none.
     226                 :   static MessageLoop* current();
     227                 : 
     228                 :   // Enables or disables the recursive task processing. This happens in the case
     229                 :   // of recursive message loops. Some unwanted message loop may occurs when
     230                 :   // using common controls or printer functions. By default, recursive task
     231                 :   // processing is disabled.
     232                 :   //
     233                 :   // The specific case where tasks get queued is:
     234                 :   // - The thread is running a message loop.
     235                 :   // - It receives a task #1 and execute it.
     236                 :   // - The task #1 implicitly start a message loop, like a MessageBox in the
     237                 :   //   unit test. This can also be StartDoc or GetSaveFileName.
     238                 :   // - The thread receives a task #2 before or while in this second message
     239                 :   //   loop.
     240                 :   // - With NestableTasksAllowed set to true, the task #2 will run right away.
     241                 :   //   Otherwise, it will get executed right after task #1 completes at "thread
     242                 :   //   message loop level".
     243                 :   void SetNestableTasksAllowed(bool allowed);
     244                 :   void ScheduleWork();
     245                 :   bool NestableTasksAllowed() const;
     246                 : 
     247                 :   // Enables or disables the restoration during an exception of the unhandled
     248                 :   // exception filter that was active when Run() was called. This can happen
     249                 :   // if some third party code call SetUnhandledExceptionFilter() and never
     250                 :   // restores the previous filter.
     251               0 :   void set_exception_restoration(bool restore) {
     252               0 :     exception_restoration_ = restore;
     253               0 :   }
     254                 : 
     255                 : #if defined(OS_WIN)
     256                 :   void set_os_modal_loop(bool os_modal_loop) {
     257                 :     os_modal_loop_ = os_modal_loop;
     258                 :   }
     259                 : 
     260                 :   bool & os_modal_loop() {
     261                 :     return os_modal_loop_;
     262                 :   }
     263                 : #endif  // OS_WIN
     264                 : 
     265                 :   //----------------------------------------------------------------------------
     266                 :  protected:
     267            1420 :   struct RunState {
     268                 :     // Used to count how many Run() invocations are on the stack.
     269                 :     int run_depth;
     270                 : 
     271                 :     // Used to record that Quit() was called, or that we should quit the pump
     272                 :     // once it becomes idle.
     273                 :     bool quit_received;
     274                 : 
     275                 : #if defined(OS_WIN)
     276                 :     base::MessagePumpWin::Dispatcher* dispatcher;
     277                 : #endif
     278                 :   };
     279                 : 
     280                 :   class AutoRunState : RunState {
     281                 :    public:
     282                 :     explicit AutoRunState(MessageLoop* loop);
     283                 :     ~AutoRunState();
     284                 :    private:
     285                 :     MessageLoop* loop_;
     286                 :     RunState* previous_state_;
     287                 :   };
     288                 : 
     289                 :   // This structure is copied around by value.
     290            1419 :   struct PendingTask {
     291                 :     Task* task;                   // The task to run.
     292                 :     base::Time delayed_run_time;  // The time when the task should be run.
     293                 :     int sequence_num;             // Used to facilitate sorting by run time.
     294                 :     bool nestable;                // True if OK to dispatch from a nested loop.
     295                 : 
     296            1419 :     PendingTask(Task* task, bool nestable)
     297            1419 :         : task(task), sequence_num(0), nestable(nestable) {
     298            1419 :     }
     299                 : 
     300                 :     // Used to support sorting.
     301                 :     bool operator<(const PendingTask& other) const;
     302                 :   };
     303                 : 
     304                 :   typedef std::queue<PendingTask> TaskQueue;
     305                 :   typedef std::priority_queue<PendingTask> DelayedTaskQueue;
     306                 : 
     307                 : #if defined(OS_WIN)
     308                 :   base::MessagePumpWin* pump_win() {
     309                 :     return static_cast<base::MessagePumpWin*>(pump_.get());
     310                 :   }
     311                 : #elif defined(OS_POSIX)
     312               0 :   base::MessagePumpLibevent* pump_libevent() {
     313               0 :     return static_cast<base::MessagePumpLibevent*>(pump_.get());
     314                 :   }
     315                 : #endif
     316                 : 
     317                 :   // A function to encapsulate all the exception handling capability in the
     318                 :   // stacks around the running of a main message loop.  It will run the message
     319                 :   // loop in a SEH try block or not depending on the set_SEH_restoration()
     320                 :   // flag.
     321                 :   void RunHandler();
     322                 : 
     323                 :   // A surrounding stack frame around the running of the message loop that
     324                 :   // supports all saving and restoring of state, as is needed for any/all (ugly)
     325                 :   // recursive calls.
     326                 :   void RunInternal();
     327                 : 
     328                 :   // Called to process any delayed non-nestable tasks.
     329                 :   bool ProcessNextDelayedNonNestableTask();
     330                 : 
     331                 :   //----------------------------------------------------------------------------
     332                 :   // Run a work_queue_ task or new_task, and delete it (if it was processed by
     333                 :   // PostTask). If there are queued tasks, the oldest one is executed and
     334                 :   // new_task is queued. new_task is optional and can be NULL. In this NULL
     335                 :   // case, the method will run one pending task (if any exist). Returns true if
     336                 :   // it executes a task.  Queued tasks accumulate only when there is a
     337                 :   // non-nestable task currently processing, in which case the new_task is
     338                 :   // appended to the list work_queue_.  Such re-entrancy generally happens when
     339                 :   // an unrequested message pump (typical of a native dialog) is executing in
     340                 :   // the context of a task.
     341                 :   bool QueueOrRunTask(Task* new_task);
     342                 : 
     343                 :   // Runs the specified task and deletes it.
     344                 :   void RunTask(Task* task);
     345                 : 
     346                 :   // Calls RunTask or queues the pending_task on the deferred task list if it
     347                 :   // cannot be run right now.  Returns true if the task was run.
     348                 :   bool DeferOrRunPendingTask(const PendingTask& pending_task);
     349                 : 
     350                 :   // Adds the pending task to delayed_work_queue_.
     351                 :   void AddToDelayedWorkQueue(const PendingTask& pending_task);
     352                 : 
     353                 :   // Load tasks from the incoming_queue_ into work_queue_ if the latter is
     354                 :   // empty.  The former requires a lock to access, while the latter is directly
     355                 :   // accessible on this thread.
     356                 :   void ReloadWorkQueue();
     357                 : 
     358                 :   // Delete tasks that haven't run yet without running them.  Used in the
     359                 :   // destructor to make sure all the task's destructors get called.  Returns
     360                 :   // true if some work was done.
     361                 :   bool DeletePendingTasks();
     362                 : 
     363                 :   // Post a task to our incomming queue.
     364                 :   void PostTask_Helper(const tracked_objects::Location& from_here, Task* task,
     365                 :                        int delay_ms, bool nestable);
     366                 : 
     367                 :   // base::MessagePump::Delegate methods:
     368                 :   virtual bool DoWork();
     369                 :   virtual bool DoDelayedWork(base::Time* next_delayed_work_time);
     370                 :   virtual bool DoIdleWork();
     371                 : 
     372                 :   Type type_;
     373                 : 
     374                 :   // A list of tasks that need to be processed by this instance.  Note that
     375                 :   // this queue is only accessed (push/pop) by our current thread.
     376                 :   TaskQueue work_queue_;
     377                 : 
     378                 :   // Contains delayed tasks, sorted by their 'delayed_run_time' property.
     379                 :   DelayedTaskQueue delayed_work_queue_;
     380                 : 
     381                 :   // A queue of non-nestable tasks that we had to defer because when it came
     382                 :   // time to execute them we were in a nested message loop.  They will execute
     383                 :   // once we're out of nested message loops.
     384                 :   TaskQueue deferred_non_nestable_work_queue_;
     385                 : 
     386                 :   scoped_refptr<base::MessagePump> pump_;
     387                 : 
     388                 :   base::ObserverList<DestructionObserver> destruction_observers_;
     389                 : 
     390                 :   // A recursion block that prevents accidentally running additonal tasks when
     391                 :   // insider a (accidentally induced?) nested message pump.
     392                 :   bool nestable_tasks_allowed_;
     393                 : 
     394                 :   bool exception_restoration_;
     395                 : 
     396                 :   std::string thread_name_;
     397                 : 
     398                 :   // A null terminated list which creates an incoming_queue of tasks that are
     399                 :   // aquired under a mutex for processing on this instance's thread. These tasks
     400                 :   // have not yet been sorted out into items for our work_queue_ vs items that
     401                 :   // will be handled by the TimerManager.
     402                 :   TaskQueue incoming_queue_;
     403                 :   // Protect access to incoming_queue_.
     404                 :   Lock incoming_queue_lock_;
     405                 : 
     406                 :   RunState* state_;
     407                 : 
     408                 : #if defined(OS_WIN)
     409                 :   // Should be set to true before calling Windows APIs like TrackPopupMenu, etc
     410                 :   // which enter a modal message loop.
     411                 :   bool os_modal_loop_;
     412                 : #endif
     413                 : 
     414                 :   // The next sequence number to use for delayed tasks.
     415                 :   int next_sequence_num_;
     416                 : 
     417                 :   DISALLOW_COPY_AND_ASSIGN(MessageLoop);
     418                 : };
     419                 : 
     420                 : //-----------------------------------------------------------------------------
     421                 : // MessageLoopForUI extends MessageLoop with methods that are particular to a
     422                 : // MessageLoop instantiated with TYPE_UI.
     423                 : //
     424                 : // This class is typically used like so:
     425                 : //   MessageLoopForUI::current()->...call some method...
     426                 : //
     427            5676 : class MessageLoopForUI : public MessageLoop {
     428                 :  public:
     429            1419 :   MessageLoopForUI(Type type=TYPE_UI) : MessageLoop(type) {
     430            1419 :   }
     431                 : 
     432                 :   // Returns the MessageLoopForUI of the current thread.
     433               0 :   static MessageLoopForUI* current() {
     434               0 :     MessageLoop* loop = MessageLoop::current();
     435               0 :     if (!loop)
     436               0 :       return NULL;
     437               0 :     Type type = loop->type();
     438               0 :     DCHECK(type == MessageLoop::TYPE_UI ||
     439                 :            type == MessageLoop::TYPE_MOZILLA_UI ||
     440               0 :            type == MessageLoop::TYPE_MOZILLA_CHILD);
     441               0 :     return static_cast<MessageLoopForUI*>(loop);
     442                 :   }
     443                 : 
     444                 : #if defined(OS_WIN)
     445                 :   typedef base::MessagePumpWin::Dispatcher Dispatcher;
     446                 :   typedef base::MessagePumpWin::Observer Observer;
     447                 : 
     448                 :   // Please see MessagePumpWin for definitions of these methods.
     449                 :   void Run(Dispatcher* dispatcher);
     450                 :   void AddObserver(Observer* observer);
     451                 :   void RemoveObserver(Observer* observer);
     452                 :   void WillProcessMessage(const MSG& message);
     453                 :   void DidProcessMessage(const MSG& message);
     454                 :   void PumpOutPendingPaintMessages();
     455                 : 
     456                 :  protected:
     457                 :   // TODO(rvargas): Make this platform independent.
     458                 :   base::MessagePumpForUI* pump_ui() {
     459                 :     return static_cast<base::MessagePumpForUI*>(pump_.get());
     460                 :   }
     461                 : #endif  // defined(OS_WIN)
     462                 : };
     463                 : 
     464                 : // Do not add any member variables to MessageLoopForUI!  This is important b/c
     465                 : // MessageLoopForUI is often allocated via MessageLoop(TYPE_UI).  Any extra
     466                 : // data that you need should be stored on the MessageLoop's pump_ instance.
     467                 : COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForUI),
     468                 :                MessageLoopForUI_should_not_have_extra_member_variables);
     469                 : 
     470                 : //-----------------------------------------------------------------------------
     471                 : // MessageLoopForIO extends MessageLoop with methods that are particular to a
     472                 : // MessageLoop instantiated with TYPE_IO.
     473                 : //
     474                 : // This class is typically used like so:
     475                 : //   MessageLoopForIO::current()->...call some method...
     476                 : //
     477                 : class MessageLoopForIO : public MessageLoop {
     478                 :  public:
     479                 :   MessageLoopForIO() : MessageLoop(TYPE_IO) {
     480                 :   }
     481                 : 
     482                 :   // Returns the MessageLoopForIO of the current thread.
     483               0 :   static MessageLoopForIO* current() {
     484               0 :     MessageLoop* loop = MessageLoop::current();
     485               0 :     DCHECK_EQ(MessageLoop::TYPE_IO, loop->type());
     486               0 :     return static_cast<MessageLoopForIO*>(loop);
     487                 :   }
     488                 : 
     489                 : #if defined(OS_WIN)
     490                 :   typedef base::MessagePumpForIO::IOHandler IOHandler;
     491                 :   typedef base::MessagePumpForIO::IOContext IOContext;
     492                 : 
     493                 :   // Please see MessagePumpWin for definitions of these methods.
     494                 :   void RegisterIOHandler(HANDLE file_handle, IOHandler* handler);
     495                 :   bool WaitForIOCompletion(DWORD timeout, IOHandler* filter);
     496                 : 
     497                 :  protected:
     498                 :   // TODO(rvargas): Make this platform independent.
     499                 :   base::MessagePumpForIO* pump_io() {
     500                 :     return static_cast<base::MessagePumpForIO*>(pump_.get());
     501                 :   }
     502                 : 
     503                 : #elif defined(OS_POSIX)
     504                 :   typedef base::MessagePumpLibevent::Watcher Watcher;
     505                 :   typedef base::MessagePumpLibevent::FileDescriptorWatcher
     506                 :       FileDescriptorWatcher;
     507                 : 
     508                 :   enum Mode {
     509                 :     WATCH_READ = base::MessagePumpLibevent::WATCH_READ,
     510                 :     WATCH_WRITE = base::MessagePumpLibevent::WATCH_WRITE,
     511                 :     WATCH_READ_WRITE = base::MessagePumpLibevent::WATCH_READ_WRITE
     512                 :   };
     513                 : 
     514                 :   // Please see MessagePumpLibevent for definition.
     515                 :   bool WatchFileDescriptor(int fd,
     516                 :                            bool persistent,
     517                 :                            Mode mode,
     518                 :                            FileDescriptorWatcher *controller,
     519                 :                            Watcher *delegate);
     520                 : 
     521                 :   typedef base::MessagePumpLibevent::SignalEvent SignalEvent;
     522                 :   typedef base::MessagePumpLibevent::SignalWatcher SignalWatcher;
     523                 :   bool CatchSignal(int sig,
     524                 :                    SignalEvent* sigevent,
     525                 :                    SignalWatcher* delegate);
     526                 : 
     527                 : #endif  // defined(OS_POSIX)
     528                 : };
     529                 : 
     530                 : // Do not add any member variables to MessageLoopForIO!  This is important b/c
     531                 : // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO).  Any extra
     532                 : // data that you need should be stored on the MessageLoop's pump_ instance.
     533                 : COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO),
     534                 :                MessageLoopForIO_should_not_have_extra_member_variables);
     535                 : 
     536                 : #endif  // BASE_MESSAGE_LOOP_H_

Generated by: LCOV version 1.7