blob: f8a097d3ce2e96a15454e20c5088ae3e3df2778d [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// 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.
[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
9#include "base/ref_counted.h"
10
[email protected]295039bd2008-08-15 04:32:5711namespace base {
12
[email protected]e1acf6f2008-10-27 20:43:3313class Time;
14
[email protected]295039bd2008-08-15 04:32:5715class MessagePump : public RefCountedThreadSafe<MessagePump> {
16 public:
17 // Please see the comments above the Run method for an illustration of how
18 // these delegate methods are used.
19 class Delegate {
20 public:
[email protected]b16ef312008-08-19 18:36:2321 virtual ~Delegate() {}
22
[email protected]295039bd2008-08-15 04:32:5723 // Called from within Run in response to ScheduleWork or when the message
24 // pump would otherwise call DoDelayedWork. Returns true to indicate that
25 // work was done. DoDelayedWork will not be called if DoWork returns true.
26 virtual bool DoWork() = 0;
27
28 // Called from within Run in response to ScheduleDelayedWork or when the
29 // message pump would otherwise sleep waiting for more work. Returns true
30 // to indicate that delayed work was done. DoIdleWork will not be called
[email protected]b24250fc2008-08-20 06:30:5831 // if DoDelayedWork returns true. Upon return |next_delayed_work_time|
32 // indicates the time when DoDelayedWork should be called again. If
33 // |next_delayed_work_time| is null (per Time::is_null), then the queue of
34 // future delayed work (timer events) is currently empty, and no additional
35 // calls to this function need to be scheduled.
36 virtual bool DoDelayedWork(Time* next_delayed_work_time) = 0;
[email protected]295039bd2008-08-15 04:32:5737
38 // Called from within Run just before the message pump goes to sleep.
39 // Returns true to indicate that idle work was done.
40 virtual bool DoIdleWork() = 0;
41 };
42
[email protected]d4799a32010-09-28 22:54:5843 MessagePump();
44 virtual ~MessagePump();
[email protected]52a261f2009-03-03 15:01:1245
[email protected]295039bd2008-08-15 04:32:5746 // The Run method is called to enter the message pump's run loop.
47 //
48 // Within the method, the message pump is responsible for processing native
49 // messages as well as for giving cycles to the delegate periodically. The
50 // message pump should take care to mix delegate callbacks with native
51 // message processing so neither type of event starves the other of cycles.
52 //
53 // The anatomy of a typical run loop:
54 //
55 // for (;;) {
56 // bool did_work = DoInternalWork();
57 // if (should_quit_)
58 // break;
[email protected]9bcbf472008-08-30 00:22:4859 //
[email protected]295039bd2008-08-15 04:32:5760 // did_work |= delegate_->DoWork();
61 // if (should_quit_)
62 // break;
[email protected]295039bd2008-08-15 04:32:5763 //
[email protected]9bcbf472008-08-30 00:22:4864 // did_work |= delegate_->DoDelayedWork();
[email protected]295039bd2008-08-15 04:32:5765 // if (should_quit_)
66 // break;
[email protected]9bcbf472008-08-30 00:22:4867 //
[email protected]295039bd2008-08-15 04:32:5768 // if (did_work)
69 // continue;
70 //
71 // did_work = delegate_->DoIdleWork();
72 // if (should_quit_)
73 // break;
[email protected]9bcbf472008-08-30 00:22:4874 //
[email protected]295039bd2008-08-15 04:32:5775 // if (did_work)
76 // continue;
77 //
78 // WaitForWork();
79 // }
80 //
81 // Here, DoInternalWork is some private method of the message pump that is
82 // responsible for dispatching the next UI message or notifying the next IO
83 // completion (for example). WaitForWork is a private method that simply
84 // blocks until there is more work of any type to do.
85 //
[email protected]9bcbf472008-08-30 00:22:4886 // Notice that the run loop cycles between calling DoInternalWork, DoWork,
87 // and DoDelayedWork methods. This helps ensure that neither work queue
88 // starves the other. This is important for message pumps that are used to
89 // drive animations, for example.
[email protected]295039bd2008-08-15 04:32:5790 //
91 // Notice also that after each callout to foreign code, the run loop checks
92 // to see if it should quit. The Quit method is responsible for setting this
93 // flag. No further work is done once the quit flag is set.
94 //
95 // NOTE: Care must be taken to handle Run being called again from within any
96 // of the callouts to foreign code. Native message pumps may also need to
97 // deal with other native message pumps being run outside their control
98 // (e.g., the MessageBox API on Windows pumps UI messages!). To be specific,
99 // the callouts (DoWork and DoDelayedWork) MUST still be provided even in
100 // nested sub-loops that are "seemingly" outside the control of this message
101 // pump. DoWork in particular must never be starved for time slices unless
102 // it returns false (meaning it has run out of things to do).
[email protected]52a261f2009-03-03 15:01:12103 //
[email protected]295039bd2008-08-15 04:32:57104 virtual void Run(Delegate* delegate) = 0;
105
106 // Quit immediately from the most recently entered run loop. This method may
107 // only be used on the thread that called Run.
108 virtual void Quit() = 0;
109
110 // Schedule a DoWork callback to happen reasonably soon. Does nothing if a
111 // DoWork callback is already scheduled. This method may be called from any
112 // thread. Once this call is made, DoWork should not be "starved" at least
113 // until it returns a value of false.
114 virtual void ScheduleWork() = 0;
115
[email protected]b24250fc2008-08-20 06:30:58116 // Schedule a DoDelayedWork callback to happen at the specified time,
[email protected]295039bd2008-08-15 04:32:57117 // cancelling any pending DoDelayedWork callback. This method may only be
118 // used on the thread that called Run.
[email protected]b24250fc2008-08-20 06:30:58119 virtual void ScheduleDelayedWork(const Time& delayed_work_time) = 0;
[email protected]295039bd2008-08-15 04:32:57120};
121
122} // namespace base
123
124#endif // BASE_MESSAGE_PUMP_H_