blob: 16941eb3502b93088d875dceaa986736e42ec007 [file] [log] [blame]
[email protected]f2ebbf062012-04-06 03:14:301// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
[email protected]295039bd2008-08-15 04:32:574
5#ifndef BASE_MESSAGE_PUMP_H_
6#define BASE_MESSAGE_PUMP_H_
[email protected]32b76ef2010-07-26 23:08:247#pragma once
[email protected]295039bd2008-08-15 04:32:578
[email protected]0bea7252011-08-05 15:34:009#include "base/base_export.h"
[email protected]3b63f8f42011-03-28 01:54:1510#include "base/memory/ref_counted.h"
[email protected]295039bd2008-08-15 04:32:5711
[email protected]295039bd2008-08-15 04:32:5712namespace base {
13
[email protected]7e7fab42010-11-06 22:23:2914class TimeTicks;
[email protected]e1acf6f2008-10-27 20:43:3315
[email protected]0bea7252011-08-05 15:34:0016class BASE_EXPORT MessagePump : public RefCountedThreadSafe<MessagePump> {
[email protected]295039bd2008-08-15 04:32:5717 public:
18 // Please see the comments above the Run method for an illustration of how
19 // these delegate methods are used.
[email protected]0bea7252011-08-05 15:34:0020 class BASE_EXPORT Delegate {
[email protected]295039bd2008-08-15 04:32:5721 public:
[email protected]b16ef312008-08-19 18:36:2322 virtual ~Delegate() {}
23
[email protected]295039bd2008-08-15 04:32:5724 // Called from within Run in response to ScheduleWork or when the message
25 // pump would otherwise call DoDelayedWork. Returns true to indicate that
[email protected]4554c232011-02-17 19:25:0426 // work was done. DoDelayedWork will still be called if DoWork returns
27 // true, but DoIdleWork will not.
[email protected]295039bd2008-08-15 04:32:5728 virtual bool DoWork() = 0;
29
30 // Called from within Run in response to ScheduleDelayedWork or when the
31 // message pump would otherwise sleep waiting for more work. Returns true
32 // to indicate that delayed work was done. DoIdleWork will not be called
[email protected]b24250fc2008-08-20 06:30:5833 // if DoDelayedWork returns true. Upon return |next_delayed_work_time|
34 // indicates the time when DoDelayedWork should be called again. If
35 // |next_delayed_work_time| is null (per Time::is_null), then the queue of
36 // future delayed work (timer events) is currently empty, and no additional
37 // calls to this function need to be scheduled.
[email protected]7e7fab42010-11-06 22:23:2938 virtual bool DoDelayedWork(TimeTicks* next_delayed_work_time) = 0;
[email protected]295039bd2008-08-15 04:32:5739
40 // Called from within Run just before the message pump goes to sleep.
41 // Returns true to indicate that idle work was done.
42 virtual bool DoIdleWork() = 0;
43 };
44
[email protected]d4799a32010-09-28 22:54:5845 MessagePump();
[email protected]52a261f2009-03-03 15:01:1246
[email protected]295039bd2008-08-15 04:32:5747 // The Run method is called to enter the message pump's run loop.
48 //
49 // Within the method, the message pump is responsible for processing native
50 // messages as well as for giving cycles to the delegate periodically. The
51 // message pump should take care to mix delegate callbacks with native
52 // message processing so neither type of event starves the other of cycles.
53 //
54 // The anatomy of a typical run loop:
55 //
56 // for (;;) {
57 // bool did_work = DoInternalWork();
58 // if (should_quit_)
59 // break;
[email protected]9bcbf472008-08-30 00:22:4860 //
[email protected]295039bd2008-08-15 04:32:5761 // did_work |= delegate_->DoWork();
62 // if (should_quit_)
63 // break;
[email protected]295039bd2008-08-15 04:32:5764 //
[email protected]4554c232011-02-17 19:25:0465 // TimeTicks next_time;
66 // did_work |= delegate_->DoDelayedWork(&next_time);
[email protected]295039bd2008-08-15 04:32:5767 // if (should_quit_)
68 // break;
[email protected]9bcbf472008-08-30 00:22:4869 //
[email protected]295039bd2008-08-15 04:32:5770 // if (did_work)
71 // continue;
72 //
73 // did_work = delegate_->DoIdleWork();
74 // if (should_quit_)
75 // break;
[email protected]9bcbf472008-08-30 00:22:4876 //
[email protected]295039bd2008-08-15 04:32:5777 // if (did_work)
78 // continue;
79 //
80 // WaitForWork();
81 // }
82 //
83 // Here, DoInternalWork is some private method of the message pump that is
84 // responsible for dispatching the next UI message or notifying the next IO
85 // completion (for example). WaitForWork is a private method that simply
86 // blocks until there is more work of any type to do.
87 //
[email protected]9bcbf472008-08-30 00:22:4888 // Notice that the run loop cycles between calling DoInternalWork, DoWork,
[email protected]4554c232011-02-17 19:25:0489 // and DoDelayedWork methods. This helps ensure that none of these work
90 // queues starve the others. This is important for message pumps that are
91 // used to drive animations, for example.
[email protected]295039bd2008-08-15 04:32:5792 //
93 // Notice also that after each callout to foreign code, the run loop checks
94 // to see if it should quit. The Quit method is responsible for setting this
95 // flag. No further work is done once the quit flag is set.
96 //
97 // NOTE: Care must be taken to handle Run being called again from within any
98 // of the callouts to foreign code. Native message pumps may also need to
99 // deal with other native message pumps being run outside their control
100 // (e.g., the MessageBox API on Windows pumps UI messages!). To be specific,
101 // the callouts (DoWork and DoDelayedWork) MUST still be provided even in
102 // nested sub-loops that are "seemingly" outside the control of this message
103 // pump. DoWork in particular must never be starved for time slices unless
104 // it returns false (meaning it has run out of things to do).
[email protected]52a261f2009-03-03 15:01:12105 //
[email protected]295039bd2008-08-15 04:32:57106 virtual void Run(Delegate* delegate) = 0;
107
108 // Quit immediately from the most recently entered run loop. This method may
109 // only be used on the thread that called Run.
110 virtual void Quit() = 0;
111
112 // Schedule a DoWork callback to happen reasonably soon. Does nothing if a
113 // DoWork callback is already scheduled. This method may be called from any
114 // thread. Once this call is made, DoWork should not be "starved" at least
115 // until it returns a value of false.
116 virtual void ScheduleWork() = 0;
117
[email protected]b24250fc2008-08-20 06:30:58118 // Schedule a DoDelayedWork callback to happen at the specified time,
[email protected]295039bd2008-08-15 04:32:57119 // cancelling any pending DoDelayedWork callback. This method may only be
120 // used on the thread that called Run.
[email protected]7e7fab42010-11-06 22:23:29121 virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) = 0;
[email protected]f2ebbf062012-04-06 03:14:30122
123 protected:
124 virtual ~MessagePump();
125 friend class RefCountedThreadSafe<MessagePump>;
[email protected]295039bd2008-08-15 04:32:57126};
127
128} // namespace base
129
130#endif // BASE_MESSAGE_PUMP_H_