ipc/chromium/src/base/message_pump.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/ipc/chromium/src/base/message_pump.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,130 @@
     1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
     1.5 +// Use of this source code is governed by a BSD-style license that can be
     1.6 +// found in the LICENSE file.
     1.7 +
     1.8 +#ifndef BASE_MESSAGE_PUMP_H_
     1.9 +#define BASE_MESSAGE_PUMP_H_
    1.10 +
    1.11 +#include "base/ref_counted.h"
    1.12 +
    1.13 +namespace base {
    1.14 +
    1.15 +class TimeTicks;
    1.16 +
    1.17 +class MessagePump : public RefCountedThreadSafe<MessagePump> {
    1.18 + public:
    1.19 +  // Please see the comments above the Run method for an illustration of how
    1.20 +  // these delegate methods are used.
    1.21 +  class Delegate {
    1.22 +   public:
    1.23 +    virtual ~Delegate() {}
    1.24 +
    1.25 +    // Called from within Run in response to ScheduleWork or when the message
    1.26 +    // pump would otherwise call DoDelayedWork.  Returns true to indicate that
    1.27 +    // work was done.  DoDelayedWork will not be called if DoWork returns true.
    1.28 +    virtual bool DoWork() = 0;
    1.29 +
    1.30 +    // Called from within Run in response to ScheduleDelayedWork or when the
    1.31 +    // message pump would otherwise sleep waiting for more work.  Returns true
    1.32 +    // to indicate that delayed work was done.  DoIdleWork will not be called
    1.33 +    // if DoDelayedWork returns true.  Upon return |next_delayed_work_time|
    1.34 +    // indicates the time when DoDelayedWork should be called again.  If
    1.35 +    // |next_delayed_work_time| is null (per Time::is_null), then the queue of
    1.36 +    // future delayed work (timer events) is currently empty, and no additional
    1.37 +    // calls to this function need to be scheduled.
    1.38 +    virtual bool DoDelayedWork(TimeTicks* next_delayed_work_time) = 0;
    1.39 +
    1.40 +    // Called from within Run just before the message pump goes to sleep.
    1.41 +    // Returns true to indicate that idle work was done.
    1.42 +    virtual bool DoIdleWork() = 0;
    1.43 +  };
    1.44 +
    1.45 +  virtual ~MessagePump() {}
    1.46 +
    1.47 +  // The Run method is called to enter the message pump's run loop.
    1.48 +  //
    1.49 +  // Within the method, the message pump is responsible for processing native
    1.50 +  // messages as well as for giving cycles to the delegate periodically.  The
    1.51 +  // message pump should take care to mix delegate callbacks with native
    1.52 +  // message processing so neither type of event starves the other of cycles.
    1.53 +  //
    1.54 +  // The anatomy of a typical run loop:
    1.55 +  //
    1.56 +  //   for (;;) {
    1.57 +  //     bool did_work = DoInternalWork();
    1.58 +  //     if (should_quit_)
    1.59 +  //       break;
    1.60 +  //
    1.61 +  //     did_work |= delegate_->DoWork();
    1.62 +  //     if (should_quit_)
    1.63 +  //       break;
    1.64 +  //
    1.65 +  //     did_work |= delegate_->DoDelayedWork();
    1.66 +  //     if (should_quit_)
    1.67 +  //       break;
    1.68 +  //
    1.69 +  //     if (did_work)
    1.70 +  //       continue;
    1.71 +  //
    1.72 +  //     did_work = delegate_->DoIdleWork();
    1.73 +  //     if (should_quit_)
    1.74 +  //       break;
    1.75 +  //
    1.76 +  //     if (did_work)
    1.77 +  //       continue;
    1.78 +  //
    1.79 +  //     WaitForWork();
    1.80 +  //   }
    1.81 +  //
    1.82 +  // Here, DoInternalWork is some private method of the message pump that is
    1.83 +  // responsible for dispatching the next UI message or notifying the next IO
    1.84 +  // completion (for example).  WaitForWork is a private method that simply
    1.85 +  // blocks until there is more work of any type to do.
    1.86 +  //
    1.87 +  // Notice that the run loop cycles between calling DoInternalWork, DoWork,
    1.88 +  // and DoDelayedWork methods.  This helps ensure that neither work queue
    1.89 +  // starves the other.  This is important for message pumps that are used to
    1.90 +  // drive animations, for example.
    1.91 +  //
    1.92 +  // Notice also that after each callout to foreign code, the run loop checks
    1.93 +  // to see if it should quit.  The Quit method is responsible for setting this
    1.94 +  // flag.  No further work is done once the quit flag is set.
    1.95 +  //
    1.96 +  // NOTE: Care must be taken to handle Run being called again from within any
    1.97 +  // of the callouts to foreign code.  Native message pumps may also need to
    1.98 +  // deal with other native message pumps being run outside their control
    1.99 +  // (e.g., the MessageBox API on Windows pumps UI messages!).  To be specific,
   1.100 +  // the callouts (DoWork and DoDelayedWork) MUST still be provided even in
   1.101 +  // nested sub-loops that are "seemingly" outside the control of this message
   1.102 +  // pump.  DoWork in particular must never be starved for time slices unless
   1.103 +  // it returns false (meaning it has run out of things to do).
   1.104 +  //
   1.105 +  virtual void Run(Delegate* delegate) = 0;
   1.106 +
   1.107 +  // Quit immediately from the most recently entered run loop.  This method may
   1.108 +  // only be used on the thread that called Run.
   1.109 +  virtual void Quit() = 0;
   1.110 +
   1.111 +  // Schedule a DoWork callback to happen reasonably soon.  Does nothing if a
   1.112 +  // DoWork callback is already scheduled.  This method may be called from any
   1.113 +  // thread.  Once this call is made, DoWork should not be "starved" at least
   1.114 +  // until it returns a value of false.
   1.115 +  virtual void ScheduleWork() = 0;
   1.116 +
   1.117 +  // This method may only called from the thread that called Run.
   1.118 +  //
   1.119 +  // Ensure that DoWork will be called if a nested loop is entered.
   1.120 +  // If a MessagePump can already guarantee that DoWork will be called
   1.121 +  // "reasonably soon", this method can be a no-op to avoid expensive
   1.122 +  // atomic tests and/or syscalls required for ScheduleWork().
   1.123 +  virtual void ScheduleWorkForNestedLoop() { ScheduleWork(); };
   1.124 +
   1.125 +  // Schedule a DoDelayedWork callback to happen at the specified time,
   1.126 +  // cancelling any pending DoDelayedWork callback.  This method may only be
   1.127 +  // used on the thread that called Run.
   1.128 +  virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) = 0;
   1.129 +};
   1.130 +
   1.131 +}  // namespace base
   1.132 +
   1.133 +#endif  // BASE_MESSAGE_PUMP_H_

mercurial