OLD | NEW |
| (Empty) |
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_PUMP_GLIB_H_ | |
6 #define BASE_MESSAGE_PUMP_GLIB_H_ | |
7 | |
8 #include "base/base_export.h" | |
9 #include "base/memory/scoped_ptr.h" | |
10 #include "base/message_pump.h" | |
11 #include "base/observer_list.h" | |
12 #include "base/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 | |
39 // Like MessagePump::Run, but events are routed through dispatcher. | |
40 virtual void RunWithDispatcher(Delegate* delegate, | |
41 MessagePumpDispatcher* dispatcher); | |
42 | |
43 // Internal methods used for processing the pump callbacks. They are | |
44 // public for simplicity but should not be used directly. HandlePrepare | |
45 // is called during the prepare step of glib, and returns a timeout that | |
46 // will be passed to the poll. HandleCheck is called after the poll | |
47 // has completed, and returns whether or not HandleDispatch should be called. | |
48 // HandleDispatch is called if HandleCheck returned true. | |
49 int HandlePrepare(); | |
50 bool HandleCheck(); | |
51 void HandleDispatch(); | |
52 | |
53 // Adds an Observer, which will start receiving notifications immediately. | |
54 void AddObserver(MessagePumpObserver* observer); | |
55 | |
56 // Removes an Observer. It is safe to call this method while an Observer is | |
57 // receiving a notification callback. | |
58 void RemoveObserver(MessagePumpObserver* observer); | |
59 | |
60 // Overridden from MessagePump: | |
61 virtual void Run(Delegate* delegate) OVERRIDE; | |
62 virtual void Quit() OVERRIDE; | |
63 virtual void ScheduleWork() OVERRIDE; | |
64 virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) OVERRIDE; | |
65 | |
66 protected: | |
67 virtual ~MessagePumpGlib(); | |
68 | |
69 // Returns the dispatcher for the current run state (|state_->dispatcher|). | |
70 MessagePumpDispatcher* GetDispatcher(); | |
71 | |
72 ObserverList<MessagePumpObserver>& observers() { return observers_; } | |
73 | |
74 private: | |
75 // We may make recursive calls to Run, so we save state that needs to be | |
76 // separate between them in this structure type. | |
77 struct RunState; | |
78 | |
79 RunState* state_; | |
80 | |
81 // This is a GLib structure that we can add event sources to. We use the | |
82 // default GLib context, which is the one to which all GTK events are | |
83 // dispatched. | |
84 GMainContext* context_; | |
85 | |
86 // This is the time when we need to do delayed work. | |
87 TimeTicks delayed_work_time_; | |
88 | |
89 // The work source. It is shared by all calls to Run and destroyed when | |
90 // the message pump is destroyed. | |
91 GSource* work_source_; | |
92 | |
93 // We use a wakeup pipe to make sure we'll get out of the glib polling phase | |
94 // when another thread has scheduled us to do some work. There is a glib | |
95 // mechanism g_main_context_wakeup, but this won't guarantee that our event's | |
96 // Dispatch() will be called. | |
97 int wakeup_pipe_read_; | |
98 int wakeup_pipe_write_; | |
99 // Use a scoped_ptr to avoid needing the definition of GPollFD in the header. | |
100 scoped_ptr<GPollFD> wakeup_gpollfd_; | |
101 | |
102 // List of observers. | |
103 ObserverList<MessagePumpObserver> observers_; | |
104 | |
105 DISALLOW_COPY_AND_ASSIGN(MessagePumpGlib); | |
106 }; | |
107 | |
108 } // namespace base | |
109 | |
110 #endif // BASE_MESSAGE_PUMP_GLIB_H_ | |
OLD | NEW |