ipc/chromium/src/base/message_pump_glib.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/ipc/chromium/src/base/message_pump_glib.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,142 @@
     1.4 +// Copyright (c) 2008 The Chromium Authors. All rights reserved.
     1.5 +// Use of this source code is governed by a BSD-style license that can be
     1.6 +// found in the LICENSE file.
     1.7 +
     1.8 +#ifndef BASE_MESSAGE_PUMP_GLIB_H_
     1.9 +#define BASE_MESSAGE_PUMP_GLIB_H_
    1.10 +
    1.11 +#include "base/message_pump.h"
    1.12 +#include "base/observer_list.h"
    1.13 +#include "base/scoped_ptr.h"
    1.14 +#include "base/time.h"
    1.15 +
    1.16 +typedef union _GdkEvent GdkEvent;
    1.17 +typedef struct _GMainContext GMainContext;
    1.18 +typedef struct _GPollFD GPollFD;
    1.19 +typedef struct _GSource GSource;
    1.20 +
    1.21 +namespace base {
    1.22 +
    1.23 +// This class implements a MessagePump needed for TYPE_UI MessageLoops on
    1.24 +// OS_LINUX platforms using GLib.
    1.25 +class MessagePumpForUI : public MessagePump {
    1.26 + public:
    1.27 +  // Observer is notified prior to a GdkEvent event being dispatched. As
    1.28 +  // Observers are notified of every change, they have to be FAST!
    1.29 +  class Observer {
    1.30 +   public:
    1.31 +    virtual ~Observer() {}
    1.32 +
    1.33 +    // This method is called before processing a message.
    1.34 +    virtual void WillProcessEvent(GdkEvent* event) = 0;
    1.35 +
    1.36 +    // This method is called after processing a message.
    1.37 +    virtual void DidProcessEvent(GdkEvent* event) = 0;
    1.38 +  };
    1.39 +
    1.40 +  // Dispatcher is used during a nested invocation of Run to dispatch events.
    1.41 +  // If Run is invoked with a non-NULL Dispatcher, MessageLoop does not
    1.42 +  // dispatch events (or invoke gtk_main_do_event), rather every event is
    1.43 +  // passed to Dispatcher's Dispatch method for dispatch. It is up to the
    1.44 +  // Dispatcher to dispatch, or not, the event.
    1.45 +  //
    1.46 +  // The nested loop is exited by either posting a quit, or returning false
    1.47 +  // from Dispatch.
    1.48 +  class Dispatcher {
    1.49 +   public:
    1.50 +    virtual ~Dispatcher() {}
    1.51 +    // Dispatches the event. If true is returned processing continues as
    1.52 +    // normal. If false is returned, the nested loop exits immediately.
    1.53 +    virtual bool Dispatch(GdkEvent* event) = 0;
    1.54 +  };
    1.55 +
    1.56 +  MessagePumpForUI();
    1.57 +  virtual ~MessagePumpForUI();
    1.58 +
    1.59 +  // Like MessagePump::Run, but GdkEvent objects are routed through dispatcher.
    1.60 +  virtual void RunWithDispatcher(Delegate* delegate, Dispatcher* dispatcher);
    1.61 +
    1.62 +  virtual void Run(Delegate* delegate) { RunWithDispatcher(delegate, NULL); }
    1.63 +  virtual void Quit();
    1.64 +  virtual void ScheduleWork();
    1.65 +  virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time);
    1.66 +
    1.67 +  // Internal methods used for processing the pump callbacks.  They are
    1.68 +  // public for simplicity but should not be used directly.  HandlePrepare
    1.69 +  // is called during the prepare step of glib, and returns a timeout that
    1.70 +  // will be passed to the poll. HandleCheck is called after the poll
    1.71 +  // has completed, and returns whether or not HandleDispatch should be called.
    1.72 +  // HandleDispatch is called if HandleCheck returned true.
    1.73 +  int HandlePrepare();
    1.74 +  bool HandleCheck();
    1.75 +  void HandleDispatch();
    1.76 +
    1.77 +  // Adds an Observer, which will start receiving notifications immediately.
    1.78 +  void AddObserver(Observer* observer);
    1.79 +
    1.80 +  // Removes an Observer.  It is safe to call this method while an Observer is
    1.81 +  // receiving a notification callback.
    1.82 +  void RemoveObserver(Observer* observer);
    1.83 +
    1.84 + private:
    1.85 +  // We may make recursive calls to Run, so we save state that needs to be
    1.86 +  // separate between them in this structure type.
    1.87 +  struct RunState {
    1.88 +    Delegate* delegate;
    1.89 +    Dispatcher* dispatcher;
    1.90 +
    1.91 +    // Used to flag that the current Run() invocation should return ASAP.
    1.92 +    bool should_quit;
    1.93 +
    1.94 +    // Used to count how many Run() invocations are on the stack.
    1.95 +    int run_depth;
    1.96 +
    1.97 +    // This keeps the state of whether the pump got signaled that there was new
    1.98 +    // work to be done. Since we eat the message on the wake up pipe as soon as
    1.99 +    // we get it, we keep that state here to stay consistent.
   1.100 +    bool has_work;
   1.101 +  };
   1.102 +
   1.103 +  // Invoked from EventDispatcher. Notifies all observers we're about to
   1.104 +  // process an event.
   1.105 +  void WillProcessEvent(GdkEvent* event);
   1.106 +
   1.107 +  // Invoked from EventDispatcher. Notifies all observers we processed an
   1.108 +  // event.
   1.109 +  void DidProcessEvent(GdkEvent* event);
   1.110 +
   1.111 +  // Callback prior to gdk dispatching an event.
   1.112 +  static void EventDispatcher(GdkEvent* event, void* data);
   1.113 +
   1.114 +  RunState* state_;
   1.115 +
   1.116 +  // This is a GLib structure that we can add event sources to.  We use the
   1.117 +  // default GLib context, which is the one to which all GTK events are
   1.118 +  // dispatched.
   1.119 +  GMainContext* context_;
   1.120 +
   1.121 +  // This is the time when we need to do delayed work.
   1.122 +  TimeTicks delayed_work_time_;
   1.123 +
   1.124 +  // The work source.  It is shared by all calls to Run and destroyed when
   1.125 +  // the message pump is destroyed.
   1.126 +  GSource* work_source_;
   1.127 +
   1.128 +  // We use a wakeup pipe to make sure we'll get out of the glib polling phase
   1.129 +  // when another thread has scheduled us to do some work.  There is a glib
   1.130 +  // mechanism g_main_context_wakeup, but this won't guarantee that our event's
   1.131 +  // Dispatch() will be called.
   1.132 +  int wakeup_pipe_read_;
   1.133 +  int wakeup_pipe_write_;
   1.134 +  // Use a scoped_ptr to avoid needing the definition of GPollFD in the header.
   1.135 +  scoped_ptr<GPollFD> wakeup_gpollfd_;
   1.136 +
   1.137 +  // List of observers.
   1.138 +  ObserverList<Observer> observers_;
   1.139 +
   1.140 +  DISALLOW_COPY_AND_ASSIGN(MessagePumpForUI);
   1.141 +};
   1.142 +
   1.143 +}  // namespace base
   1.144 +
   1.145 +#endif  // BASE_MESSAGE_PUMP_GLIB_H_

mercurial