message_pump_glib.h revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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
14typedef struct _GMainContext GMainContext;
15typedef struct _GPollFD GPollFD;
16typedef struct _GSource GSource;
17
18namespace 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.
23class 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.
31class MessagePumpDispatcher;
32
33// This class implements a base MessagePump needed for TYPE_UI MessageLoops on
34// platforms using GLib.
35class 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  // Overridden from MessagePump:
55  virtual void Run(Delegate* delegate) OVERRIDE;
56  virtual void Quit() OVERRIDE;
57  virtual void ScheduleWork() OVERRIDE;
58  virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) OVERRIDE;
59
60 protected:
61  // Returns the dispatcher for the current run state (|state_->dispatcher|).
62  MessagePumpDispatcher* GetDispatcher();
63
64  bool ShouldQuit() const;
65
66 private:
67  // We may make recursive calls to Run, so we save state that needs to be
68  // separate between them in this structure type.
69  struct RunState;
70
71  RunState* state_;
72
73  // This is a GLib structure that we can add event sources to.  We use the
74  // default GLib context, which is the one to which all GTK events are
75  // dispatched.
76  GMainContext* context_;
77
78  // This is the time when we need to do delayed work.
79  TimeTicks delayed_work_time_;
80
81  // The work source.  It is shared by all calls to Run and destroyed when
82  // the message pump is destroyed.
83  GSource* work_source_;
84
85  // We use a wakeup pipe to make sure we'll get out of the glib polling phase
86  // when another thread has scheduled us to do some work.  There is a glib
87  // mechanism g_main_context_wakeup, but this won't guarantee that our event's
88  // Dispatch() will be called.
89  int wakeup_pipe_read_;
90  int wakeup_pipe_write_;
91  // Use a scoped_ptr to avoid needing the definition of GPollFD in the header.
92  scoped_ptr<GPollFD> wakeup_gpollfd_;
93
94  DISALLOW_COPY_AND_ASSIGN(MessagePumpGlib);
95};
96
97}  // namespace base
98
99#endif  // BASE_MESSAGE_LOOP_MESSAGE_PUMP_GLIB_H_
100