1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file. 4*635a8641SAndroid Build Coastguard Worker 5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_H_ 6*635a8641SAndroid Build Coastguard Worker #define BASE_MESSAGE_LOOP_MESSAGE_PUMP_H_ 7*635a8641SAndroid Build Coastguard Worker 8*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h" 9*635a8641SAndroid Build Coastguard Worker #include "base/message_loop/timer_slack.h" 10*635a8641SAndroid Build Coastguard Worker #include "base/sequence_checker.h" 11*635a8641SAndroid Build Coastguard Worker 12*635a8641SAndroid Build Coastguard Worker namespace base { 13*635a8641SAndroid Build Coastguard Worker 14*635a8641SAndroid Build Coastguard Worker class TimeTicks; 15*635a8641SAndroid Build Coastguard Worker 16*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT MessagePump { 17*635a8641SAndroid Build Coastguard Worker public: 18*635a8641SAndroid Build Coastguard Worker // Please see the comments above the Run method for an illustration of how 19*635a8641SAndroid Build Coastguard Worker // these delegate methods are used. 20*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT Delegate { 21*635a8641SAndroid Build Coastguard Worker public: 22*635a8641SAndroid Build Coastguard Worker virtual ~Delegate() = default; 23*635a8641SAndroid Build Coastguard Worker 24*635a8641SAndroid Build Coastguard Worker // Called from within Run in response to ScheduleWork or when the message 25*635a8641SAndroid Build Coastguard Worker // pump would otherwise call DoDelayedWork. Returns true to indicate that 26*635a8641SAndroid Build Coastguard Worker // work was done. DoDelayedWork will still be called if DoWork returns 27*635a8641SAndroid Build Coastguard Worker // true, but DoIdleWork will not. 28*635a8641SAndroid Build Coastguard Worker virtual bool DoWork() = 0; 29*635a8641SAndroid Build Coastguard Worker 30*635a8641SAndroid Build Coastguard Worker // Called from within Run in response to ScheduleDelayedWork or when the 31*635a8641SAndroid Build Coastguard Worker // message pump would otherwise sleep waiting for more work. Returns true 32*635a8641SAndroid Build Coastguard Worker // to indicate that delayed work was done. DoIdleWork will not be called 33*635a8641SAndroid Build Coastguard Worker // if DoDelayedWork returns true. Upon return |next_delayed_work_time| 34*635a8641SAndroid Build Coastguard Worker // indicates the time when DoDelayedWork should be called again. If 35*635a8641SAndroid Build Coastguard Worker // |next_delayed_work_time| is null (per Time::is_null), then the queue of 36*635a8641SAndroid Build Coastguard Worker // future delayed work (timer events) is currently empty, and no additional 37*635a8641SAndroid Build Coastguard Worker // calls to this function need to be scheduled. 38*635a8641SAndroid Build Coastguard Worker virtual bool DoDelayedWork(TimeTicks* next_delayed_work_time) = 0; 39*635a8641SAndroid Build Coastguard Worker 40*635a8641SAndroid Build Coastguard Worker // Called from within Run just before the message pump goes to sleep. 41*635a8641SAndroid Build Coastguard Worker // Returns true to indicate that idle work was done. Returning false means 42*635a8641SAndroid Build Coastguard Worker // the pump will now wait. 43*635a8641SAndroid Build Coastguard Worker virtual bool DoIdleWork() = 0; 44*635a8641SAndroid Build Coastguard Worker }; 45*635a8641SAndroid Build Coastguard Worker 46*635a8641SAndroid Build Coastguard Worker MessagePump(); 47*635a8641SAndroid Build Coastguard Worker virtual ~MessagePump(); 48*635a8641SAndroid Build Coastguard Worker 49*635a8641SAndroid Build Coastguard Worker // The Run method is called to enter the message pump's run loop. 50*635a8641SAndroid Build Coastguard Worker // 51*635a8641SAndroid Build Coastguard Worker // Within the method, the message pump is responsible for processing native 52*635a8641SAndroid Build Coastguard Worker // messages as well as for giving cycles to the delegate periodically. The 53*635a8641SAndroid Build Coastguard Worker // message pump should take care to mix delegate callbacks with native 54*635a8641SAndroid Build Coastguard Worker // message processing so neither type of event starves the other of cycles. 55*635a8641SAndroid Build Coastguard Worker // 56*635a8641SAndroid Build Coastguard Worker // The anatomy of a typical run loop: 57*635a8641SAndroid Build Coastguard Worker // 58*635a8641SAndroid Build Coastguard Worker // for (;;) { 59*635a8641SAndroid Build Coastguard Worker // bool did_work = DoInternalWork(); 60*635a8641SAndroid Build Coastguard Worker // if (should_quit_) 61*635a8641SAndroid Build Coastguard Worker // break; 62*635a8641SAndroid Build Coastguard Worker // 63*635a8641SAndroid Build Coastguard Worker // did_work |= delegate_->DoWork(); 64*635a8641SAndroid Build Coastguard Worker // if (should_quit_) 65*635a8641SAndroid Build Coastguard Worker // break; 66*635a8641SAndroid Build Coastguard Worker // 67*635a8641SAndroid Build Coastguard Worker // TimeTicks next_time; 68*635a8641SAndroid Build Coastguard Worker // did_work |= delegate_->DoDelayedWork(&next_time); 69*635a8641SAndroid Build Coastguard Worker // if (should_quit_) 70*635a8641SAndroid Build Coastguard Worker // break; 71*635a8641SAndroid Build Coastguard Worker // 72*635a8641SAndroid Build Coastguard Worker // if (did_work) 73*635a8641SAndroid Build Coastguard Worker // continue; 74*635a8641SAndroid Build Coastguard Worker // 75*635a8641SAndroid Build Coastguard Worker // did_work = delegate_->DoIdleWork(); 76*635a8641SAndroid Build Coastguard Worker // if (should_quit_) 77*635a8641SAndroid Build Coastguard Worker // break; 78*635a8641SAndroid Build Coastguard Worker // 79*635a8641SAndroid Build Coastguard Worker // if (did_work) 80*635a8641SAndroid Build Coastguard Worker // continue; 81*635a8641SAndroid Build Coastguard Worker // 82*635a8641SAndroid Build Coastguard Worker // WaitForWork(); 83*635a8641SAndroid Build Coastguard Worker // } 84*635a8641SAndroid Build Coastguard Worker // 85*635a8641SAndroid Build Coastguard Worker // Here, DoInternalWork is some private method of the message pump that is 86*635a8641SAndroid Build Coastguard Worker // responsible for dispatching the next UI message or notifying the next IO 87*635a8641SAndroid Build Coastguard Worker // completion (for example). WaitForWork is a private method that simply 88*635a8641SAndroid Build Coastguard Worker // blocks until there is more work of any type to do. 89*635a8641SAndroid Build Coastguard Worker // 90*635a8641SAndroid Build Coastguard Worker // Notice that the run loop cycles between calling DoInternalWork, DoWork, 91*635a8641SAndroid Build Coastguard Worker // and DoDelayedWork methods. This helps ensure that none of these work 92*635a8641SAndroid Build Coastguard Worker // queues starve the others. This is important for message pumps that are 93*635a8641SAndroid Build Coastguard Worker // used to drive animations, for example. 94*635a8641SAndroid Build Coastguard Worker // 95*635a8641SAndroid Build Coastguard Worker // Notice also that after each callout to foreign code, the run loop checks 96*635a8641SAndroid Build Coastguard Worker // to see if it should quit. The Quit method is responsible for setting this 97*635a8641SAndroid Build Coastguard Worker // flag. No further work is done once the quit flag is set. 98*635a8641SAndroid Build Coastguard Worker // 99*635a8641SAndroid Build Coastguard Worker // NOTE: Care must be taken to handle Run being called again from within any 100*635a8641SAndroid Build Coastguard Worker // of the callouts to foreign code. Native message pumps may also need to 101*635a8641SAndroid Build Coastguard Worker // deal with other native message pumps being run outside their control 102*635a8641SAndroid Build Coastguard Worker // (e.g., the MessageBox API on Windows pumps UI messages!). To be specific, 103*635a8641SAndroid Build Coastguard Worker // the callouts (DoWork and DoDelayedWork) MUST still be provided even in 104*635a8641SAndroid Build Coastguard Worker // nested sub-loops that are "seemingly" outside the control of this message 105*635a8641SAndroid Build Coastguard Worker // pump. DoWork in particular must never be starved for time slices unless 106*635a8641SAndroid Build Coastguard Worker // it returns false (meaning it has run out of things to do). 107*635a8641SAndroid Build Coastguard Worker // 108*635a8641SAndroid Build Coastguard Worker virtual void Run(Delegate* delegate) = 0; 109*635a8641SAndroid Build Coastguard Worker 110*635a8641SAndroid Build Coastguard Worker // Quit immediately from the most recently entered run loop. This method may 111*635a8641SAndroid Build Coastguard Worker // only be used on the thread that called Run. 112*635a8641SAndroid Build Coastguard Worker virtual void Quit() = 0; 113*635a8641SAndroid Build Coastguard Worker 114*635a8641SAndroid Build Coastguard Worker // Schedule a DoWork callback to happen reasonably soon. Does nothing if a 115*635a8641SAndroid Build Coastguard Worker // DoWork callback is already scheduled. This method may be called from any 116*635a8641SAndroid Build Coastguard Worker // thread. Once this call is made, DoWork should not be "starved" at least 117*635a8641SAndroid Build Coastguard Worker // until it returns a value of false. 118*635a8641SAndroid Build Coastguard Worker virtual void ScheduleWork() = 0; 119*635a8641SAndroid Build Coastguard Worker 120*635a8641SAndroid Build Coastguard Worker // Schedule a DoDelayedWork callback to happen at the specified time, 121*635a8641SAndroid Build Coastguard Worker // cancelling any pending DoDelayedWork callback. This method may only be 122*635a8641SAndroid Build Coastguard Worker // used on the thread that called Run. 123*635a8641SAndroid Build Coastguard Worker virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) = 0; 124*635a8641SAndroid Build Coastguard Worker 125*635a8641SAndroid Build Coastguard Worker // Sets the timer slack to the specified value. 126*635a8641SAndroid Build Coastguard Worker virtual void SetTimerSlack(TimerSlack timer_slack); 127*635a8641SAndroid Build Coastguard Worker }; 128*635a8641SAndroid Build Coastguard Worker 129*635a8641SAndroid Build Coastguard Worker } // namespace base 130*635a8641SAndroid Build Coastguard Worker 131*635a8641SAndroid Build Coastguard Worker #endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_H_ 132