1 // Copyright (c) 2012 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_MESSAGE_PUMP_GLIB_H_ 6 #define BASE_MESSAGE_LOOP_MESSAGE_PUMP_GLIB_H_ 7 8 #include "base/base_export.h" 9 #include "base/memory/scoped_ptr.h" 10 #include "base/message_loop/message_pump.h" 11 #include "base/observer_list.h" 12 #include "base/time/time.h" 13 14 typedef struct _GMainContext GMainContext; 15 typedef struct _GPollFD GPollFD; 16 typedef struct _GSource GSource; 17 18 namespace base { 19 20 // MessagePumpObserver is notified prior to an event being dispatched. As 21 // Observers are notified of every change, they have to be FAST! The platform 22 // specific implementation of the class is in message_pump_gtk/message_pump_x. 23 class MessagePumpObserver; 24 25 // MessagePumpDispatcher is used during a nested invocation of Run to dispatch 26 // events. If Run is invoked with a non-NULL MessagePumpDispatcher, MessageLoop 27 // does not dispatch events (or invoke gtk_main_do_event), rather every event is 28 // passed to Dispatcher's Dispatch method for dispatch. It is up to the 29 // Dispatcher to dispatch, or not, the event. The platform specific 30 // implementation of the class is in message_pump_gtk/message_pump_x. 31 class MessagePumpDispatcher; 32 33 // This class implements a base MessagePump needed for TYPE_UI MessageLoops on 34 // platforms using GLib. 35 class BASE_EXPORT MessagePumpGlib : public MessagePump { 36 public: 37 MessagePumpGlib(); 38 virtual ~MessagePumpGlib(); 39 40 // Like MessagePump::Run, but events are routed through dispatcher. 41 virtual void RunWithDispatcher(Delegate* delegate, 42 MessagePumpDispatcher* dispatcher); 43 44 // Internal methods used for processing the pump callbacks. They are 45 // public for simplicity but should not be used directly. HandlePrepare 46 // is called during the prepare step of glib, and returns a timeout that 47 // will be passed to the poll. HandleCheck is called after the poll 48 // has completed, and returns whether or not HandleDispatch should be called. 49 // HandleDispatch is called if HandleCheck returned true. 50 int HandlePrepare(); 51 bool HandleCheck(); 52 void HandleDispatch(); 53 54 // Adds an Observer, which will start receiving notifications immediately. 55 void AddObserver(MessagePumpObserver* observer); 56 57 // Removes an Observer. It is safe to call this method while an Observer is 58 // receiving a notification callback. 59 void RemoveObserver(MessagePumpObserver* observer); 60 61 // Overridden from MessagePump: 62 virtual void Run(Delegate* delegate) OVERRIDE; 63 virtual void Quit() OVERRIDE; 64 virtual void ScheduleWork() OVERRIDE; 65 virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) OVERRIDE; 66 67 protected: 68 // Returns the dispatcher for the current run state (|state_->dispatcher|). 69 MessagePumpDispatcher* GetDispatcher(); 70 71 ObserverList<MessagePumpObserver>& observers() { return observers_; } 72 73 private: 74 // We may make recursive calls to Run, so we save state that needs to be 75 // separate between them in this structure type. 76 struct RunState; 77 78 RunState* state_; 79 80 // This is a GLib structure that we can add event sources to. We use the 81 // default GLib context, which is the one to which all GTK events are 82 // dispatched. 83 GMainContext* context_; 84 85 // This is the time when we need to do delayed work. 86 TimeTicks delayed_work_time_; 87 88 // The work source. It is shared by all calls to Run and destroyed when 89 // the message pump is destroyed. 90 GSource* work_source_; 91 92 // We use a wakeup pipe to make sure we'll get out of the glib polling phase 93 // when another thread has scheduled us to do some work. There is a glib 94 // mechanism g_main_context_wakeup, but this won't guarantee that our event's 95 // Dispatch() will be called. 96 int wakeup_pipe_read_; 97 int wakeup_pipe_write_; 98 // Use a scoped_ptr to avoid needing the definition of GPollFD in the header. 99 scoped_ptr<GPollFD> wakeup_gpollfd_; 100 101 // List of observers. 102 ObserverList<MessagePumpObserver> observers_; 103 104 DISALLOW_COPY_AND_ASSIGN(MessagePumpGlib); 105 }; 106 107 } // namespace base 108 109 #endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_GLIB_H_ 110