message_pump_glib.h (3165B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 // Copyright (c) 2008 The Chromium Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style license that can be 5 // found in the LICENSE file. 6 7 #ifndef BASE_MESSAGE_PUMP_GLIB_H_ 8 #define BASE_MESSAGE_PUMP_GLIB_H_ 9 10 #include "base/message_pump.h" 11 #include "base/observer_list.h" 12 #include "base/time.h" 13 #include "mozilla/UniquePtr.h" 14 #include "mozilla/Atomics.h" 15 16 typedef struct _GMainContext GMainContext; 17 typedef struct _GPollFD GPollFD; 18 typedef struct _GSource GSource; 19 20 namespace base { 21 22 // This class implements a MessagePump needed for TYPE_UI MessageLoops on 23 // XP_LINUX platforms using GLib. 24 class MessagePumpForUI : public MessagePump { 25 public: 26 MessagePumpForUI(); 27 virtual ~MessagePumpForUI(); 28 29 void Run(Delegate* delegate) override; 30 void Quit() override; 31 void ScheduleWork() override; 32 void ScheduleDelayedWork(const TimeTicks& delayed_work_time) override; 33 34 // Internal methods used for processing the pump callbacks. They are 35 // public for simplicity but should not be used directly. HandlePrepare 36 // is called during the prepare step of glib, and returns a timeout that 37 // will be passed to the poll. HandleCheck is called after the poll 38 // has completed, and returns whether or not HandleDispatch should be called. 39 // HandleDispatch is called if HandleCheck returned true. 40 int HandlePrepare(); 41 bool HandleCheck(); 42 void HandleDispatch(); 43 44 private: 45 // We may make recursive calls to Run, so we save state that needs to be 46 // separate between them in this structure type. 47 struct RunState { 48 Delegate* delegate; 49 50 // Used to flag that the current Run() invocation should return ASAP. 51 bool should_quit; 52 53 // Used to count how many Run() invocations are on the stack. 54 int run_depth; 55 56 // This keeps the state of whether the pump got signaled that there was new 57 // work to be done. Since we eat the message on the wake up pipe as soon as 58 // we get it, we keep that state here to stay consistent. 59 bool has_work; 60 }; 61 62 RunState* state_; 63 64 // This is a GLib structure that we can add event sources to. We use the 65 // default GLib context, which is the one to which all GTK events are 66 // dispatched. 67 GMainContext* context_; 68 69 // This is the time when we need to do delayed work. 70 TimeTicks delayed_work_time_; 71 72 // The work source. It is shared by all calls to Run and destroyed when 73 // the message pump is destroyed. 74 GSource* work_source_; 75 76 // We use a wakeup pipe to make sure we'll get out of the glib polling phase 77 // when another thread has scheduled us to do some work. There is a glib 78 // mechanism g_main_context_wakeup, but this won't guarantee that our event's 79 // Dispatch() will be called. 80 int wakeup_pipe_read_; 81 int wakeup_pipe_write_; 82 // Use an autoptr to avoid needing the definition of GPollFD in the header. 83 mozilla::UniquePtr<GPollFD> wakeup_gpollfd_; 84 85 mozilla::Atomic<bool> pipe_full_; 86 87 DISALLOW_COPY_AND_ASSIGN(MessagePumpForUI); 88 }; 89 90 } // namespace base 91 92 #endif // BASE_MESSAGE_PUMP_GLIB_H_