LCOV - code coverage report
Current view: directory - ipc/chromium/src/base - message_pump_libevent.h (source / functions) Found Hit Coverage
Test: app.info Lines: 4 1 25.0 %
Date: 2012-06-02 Functions: 6 1 16.7 %

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

Generated by: LCOV version 1.7