LCOV - code coverage report
Current view: top level - ipc/chromium/src/base - message_pump_libevent.h (source / functions) Hit Total Coverage
Test: output.info Lines: 2 6 33.3 %
Date: 2017-07-14 16:53:18 Functions: 2 8 25.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13