ipc/chromium/src/base/message_pump_libevent.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 // Copyright (c) 2006-2008 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.
     5 #ifndef BASE_MESSAGE_PUMP_LIBEVENT_H_
     6 #define BASE_MESSAGE_PUMP_LIBEVENT_H_
     8 #include "base/message_pump.h"
     9 #include "base/time.h"
    10 #include "nsAutoPtr.h"
    12 // Declare structs we need from libevent.h rather than including it
    13 struct event_base;
    14 struct event;
    16 class nsDependentCSubstring;
    18 namespace base {
    20 // Class to monitor sockets and issue callbacks when sockets are ready for I/O
    21 // TODO(dkegel): add support for background file IO somehow
    22 class MessagePumpLibevent : public MessagePump {
    23  public:
    25   // Object returned by WatchFileDescriptor to manage further watching.
    26   class FileDescriptorWatcher {
    27     public:
    28      FileDescriptorWatcher();
    29      ~FileDescriptorWatcher();  // Implicitly calls StopWatchingFileDescriptor.
    31      // NOTE: These methods aren't called StartWatching()/StopWatching() to
    32      // avoid confusion with the win32 ObjectWatcher class.
    34      // Stop watching the FD, always safe to call.  No-op if there's nothing
    35      // to do.
    36      bool StopWatchingFileDescriptor();
    38     private:
    39      // Called by MessagePumpLibevent, ownership of |e| is transferred to this
    40      // object.
    41      void Init(event* e, bool is_persistent);
    43      // Used by MessagePumpLibevent to take ownership of event_.
    44      event *ReleaseEvent();
    45      friend class MessagePumpLibevent;
    47     private:
    48      bool is_persistent_;  // false if this event is one-shot.
    49      event* event_;
    50      DISALLOW_COPY_AND_ASSIGN(FileDescriptorWatcher);
    51   };
    53   // Used with WatchFileDescptor to asynchronously monitor the I/O readiness of
    54   // a File Descriptor.
    55   class Watcher {
    56    public:
    57     virtual ~Watcher() {}
    58     // Called from MessageLoop::Run when an FD can be read from/written to
    59     // without blocking
    60     virtual void OnFileCanReadWithoutBlocking(int fd) = 0;
    61     virtual void OnFileCanWriteWithoutBlocking(int fd) = 0;
    62   };
    64   MessagePumpLibevent();
    65   virtual ~MessagePumpLibevent();
    67   enum Mode {
    68     WATCH_READ = 1 << 0,
    69     WATCH_WRITE = 1 << 1,
    70     WATCH_READ_WRITE = WATCH_READ | WATCH_WRITE
    71   };
    73   // Have the current thread's message loop watch for a a situation in which
    74   // reading/writing to the FD can be performed without Blocking.
    75   // Callers must provide a preallocated FileDescriptorWatcher object which
    76   // can later be used to manage the Lifetime of this event.
    77   // If a FileDescriptorWatcher is passed in which is already attached to
    78   // an event, then the effect is cumulative i.e. after the call |controller|
    79   // will watch both the previous event and the new one.
    80   // If an error occurs while calling this method in a cumulative fashion, the
    81   // event previously attached to |controller| is aborted.
    82   // Returns true on success.
    83   // TODO(dkegel): switch to edge-triggered readiness notification
    84   bool WatchFileDescriptor(int fd,
    85                            bool persistent,
    86                            Mode mode,
    87                            FileDescriptorWatcher *controller,
    88                            Watcher *delegate);
    91   // This is analagous to FileDescriptorWatcher above, which really is
    92   // just a wrapper around libevent's |struct event|.  This class acts
    93   // as a sort of "scoped event watcher" in that it guarantees that
    94   // when this class is out of scope, the signal-event it wraps is
    95   // removed from libevent's guts.
    96   //
    97   // XXX/cjones: this isn't my favorite API, but preserving it in
    98   // order to match code above
    99   class SignalEvent {
   100      friend class MessagePumpLibevent;
   102   public:
   103     SignalEvent();
   104     ~SignalEvent();             // implicitly calls StopCatching()
   106     // Have libevent forget this event.
   107     bool StopCatching();
   109   private:
   110     void Init(event* e);
   111     event* ReleaseEvent();
   113     event* event_;
   115     DISALLOW_COPY_AND_ASSIGN(SignalEvent);
   116   };
   118   class SignalWatcher {
   119   public:
   120     virtual ~SignalWatcher() {}
   121     // Called from MessageLoop::Run when |sig| has been delivered to
   122     // this process
   123     virtual void OnSignal(int sig) = 0;
   124   };
   126   // Have the current thread's message loop catch the signal |sig|.
   127   // Multiple watchers can catch the same signal; they're all notified
   128   // upon its delivery.  Callers must provide a preallocated
   129   // SignalEvent object which can be used to manage the lifetime of
   130   // this event.  Returns true on success.
   131   bool CatchSignal(int sig,
   132                    SignalEvent* sigevent,
   133                    SignalWatcher* delegate);
   136   // MessagePump methods:
   137   virtual void Run(Delegate* delegate);
   138   virtual void Quit();
   139   virtual void ScheduleWork();
   140   virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time);
   142  private:
   144   // Risky part of constructor.  Returns true on success.
   145   bool Init();
   147   // This flag is set to false when Run should return.
   148   bool keep_running_;
   150   // This flag is set when inside Run.
   151   bool in_run_;
   153   // The time at which we should call DoDelayedWork.
   154   TimeTicks delayed_work_time_;
   156   // Libevent dispatcher.  Watches all sockets registered with it, and sends
   157   // readiness callbacks when a socket is ready for I/O.
   158   event_base* event_base_;
   160   // Called by libevent to tell us a registered FD can be read/written to.
   161   static void OnLibeventNotification(int fd, short flags,
   162                                      void* context);
   164   // Called by libevent upon receiving a signal
   165   static void OnLibeventSignalNotification(int sig, short flags,
   166                                            void* context);
   168   // Unix pipe used to implement ScheduleWork()
   169   // ... callback; called by libevent inside Run() when pipe is ready to read
   170   static void OnWakeup(int socket, short flags, void* context);
   171   // ... write end; ScheduleWork() writes a single byte to it
   172   int wakeup_pipe_in_;
   173   // ... read end; OnWakeup reads it and then breaks Run() out of its sleep
   174   int wakeup_pipe_out_;
   175   // ... libevent wrapper for read end
   176   event* wakeup_event_;
   178   DISALLOW_COPY_AND_ASSIGN(MessagePumpLibevent);
   179 };
   181 /**
   182  *  LineWatcher overrides OnFileCanReadWithoutBlocking. It separates the read
   183  *  data by mTerminator and passes each line to OnLineRead.
   184  */
   185 class LineWatcher : public MessagePumpLibevent::Watcher
   186 {
   187 public:
   188   LineWatcher(char aTerminator, int aBufferSize) : mReceivedIndex(0),
   189     mBufferSize(aBufferSize),
   190     mTerminator(aTerminator)
   191   {
   192     mReceiveBuffer = new char[mBufferSize];
   193   }
   195   ~LineWatcher() {}
   197 protected:
   198   /**
   199    * OnError will be called when |read| returns error. Derived class should
   200    * implement this function to handle error cases when needed.
   201    */
   202   virtual void OnError() {}
   203   virtual void OnLineRead(int aFd, nsDependentCSubstring& aMessage) = 0;
   204   virtual void OnFileCanWriteWithoutBlocking(int /* aFd */) {}
   205 private:
   206   virtual void OnFileCanReadWithoutBlocking(int aFd) MOZ_FINAL;
   208   nsAutoPtr<char> mReceiveBuffer;
   209   int mReceivedIndex;
   210   int mBufferSize;
   211   char mTerminator;
   212 };
   213 }  // namespace base
   215 #endif  // BASE_MESSAGE_PUMP_LIBEVENT_H_

mercurial