tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

message_pump_libevent.h (4843B)


      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 
     13 // Declare structs we need from libevent.h rather than including it
     14 struct event_base;
     15 struct event;
     16 
     17 namespace base {
     18 
     19 // Class to monitor sockets and issue callbacks when sockets are ready for I/O
     20 // TODO(dkegel): add support for background file IO somehow
     21 class MessagePumpLibevent : public MessagePump {
     22 public:
     23  // Object returned by WatchFileDescriptor to manage further watching.
     24  class FileDescriptorWatcher {
     25   public:
     26    FileDescriptorWatcher();
     27    ~FileDescriptorWatcher();  // Implicitly calls StopWatchingFileDescriptor.
     28 
     29    // NOTE: These methods aren't called StartWatching()/StopWatching() to
     30    // avoid confusion with the win32 ObjectWatcher class.
     31 
     32    // Stop watching the FD, always safe to call.  No-op if there's nothing
     33    // to do.
     34    bool StopWatchingFileDescriptor();
     35 
     36   private:
     37    // Called by MessagePumpLibevent, ownership of |e| is transferred to this
     38    // object.
     39    void Init(event* e, bool is_persistent);
     40 
     41    // Used by MessagePumpLibevent to take ownership of event_.
     42    event* ReleaseEvent();
     43    friend class MessagePumpLibevent;
     44 
     45   private:
     46    bool is_persistent_;  // false if this event is one-shot.
     47    event* event_;
     48    DISALLOW_COPY_AND_ASSIGN(FileDescriptorWatcher);
     49  };
     50 
     51  // Used with WatchFileDescptor to asynchronously monitor the I/O readiness of
     52  // a File Descriptor.
     53  class Watcher {
     54   public:
     55    virtual ~Watcher() {}
     56    // Called from MessageLoop::Run when an FD can be read from/written to
     57    // without blocking
     58    virtual void OnFileCanReadWithoutBlocking(int fd) = 0;
     59    virtual void OnFileCanWriteWithoutBlocking(int fd) = 0;
     60  };
     61 
     62  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, bool persistent, Mode mode,
     82                           FileDescriptorWatcher* controller,
     83                           Watcher* delegate);
     84 
     85  // MessagePump methods:
     86  virtual void Run(Delegate* delegate) override;
     87  virtual void Quit() override;
     88  virtual void ScheduleWork() override;
     89  virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) override;
     90 
     91 protected:
     92  virtual ~MessagePumpLibevent();
     93 
     94 private:
     95  // Risky part of constructor.  Returns true on success.
     96  bool Init();
     97 
     98  // This flag is set to false when Run should return.
     99  bool keep_running_;
    100 
    101  // This flag is set when inside Run.
    102  bool in_run_;
    103 
    104  // The time at which we should call DoDelayedWork.
    105  TimeTicks delayed_work_time_;
    106 
    107  // Libevent dispatcher.  Watches all sockets registered with it, and sends
    108  // readiness callbacks when a socket is ready for I/O.
    109  event_base* event_base_;
    110 
    111  // Called by libevent to tell us a registered FD can be read/written to.
    112  static void OnLibeventNotification(int fd, short flags, void* context);
    113 
    114  // Unix pipe used to implement ScheduleWork()
    115  // ... callback; called by libevent inside Run() when pipe is ready to read
    116  static void OnWakeup(int socket, short flags, void* context);
    117  // ... write end; ScheduleWork() writes a single byte to it
    118  int wakeup_pipe_in_;
    119  // ... read end; OnWakeup reads it and then breaks Run() out of its sleep
    120  int wakeup_pipe_out_;
    121  // ... libevent wrapper for read end
    122  event* wakeup_event_;
    123 
    124  // Set to false when calling event_base_loop and to true when either of the
    125  // OnWakeup, OnLibeventNotification or OnLibeventSignalNotification callbacks
    126  // is called.
    127  // Used to ensure our calls to profiler_thread_sleep and profiler_thread_wake
    128  // are paired correctly.
    129  static bool awake_;
    130 
    131  DISALLOW_COPY_AND_ASSIGN(MessagePumpLibevent);
    132 };
    133 
    134 }  // namespace base
    135 
    136 #endif  // BASE_MESSAGE_PUMP_LIBEVENT_H_