Chromium Code Reviews| Index: base/message_pump_libevent.h |
| diff --git a/base/message_pump_libevent.h b/base/message_pump_libevent.h |
| index b54bc36b6584a65f46a3759d39eaa74c01e22e7f..dab9815e69c8903b2b3b0db5da70f7152d19907d 100644 |
| --- a/base/message_pump_libevent.h |
| +++ b/base/message_pump_libevent.h |
| @@ -6,6 +6,7 @@ |
| #define BASE_MESSAGE_PUMP_LIBEVENT_H_ |
| #include "base/message_pump.h" |
| +#include "base/scoped_ptr.h" |
| #include "base/time.h" |
| // Declare structs we need from libevent.h rather than including it |
| @@ -18,46 +19,71 @@ namespace base { |
| // TODO(dkegel): add support for background file IO somehow |
| class MessagePumpLibevent : public MessagePump { |
| public: |
| - // Used with WatchSocket to asynchronously monitor the I/O readiness of a |
| - // socket. |
| - class Watcher { |
| - public: |
| - virtual ~Watcher() {} |
| - // Called from MessageLoop::Run when a ready socket is detected. |
| - virtual void OnSocketReady(short eventmask) = 0; |
| + |
| + // Object returned by WatchFileDescriptor to manage further watching. |
| + class FileDescriptorWatcher { |
| + public: |
| + FileDescriptorWatcher(); |
| + ~FileDescriptorWatcher(); // Implicitly calls StopWatching. |
|
Mark Mentovai
2008/12/15 21:43:40
Implicitly calls StopWatchingFileDescriptor?
|
| + |
| + // NOTE: These methods aren't called StartWatching()/StopWatching() to |
| + // avoid confusion with the win32 ObjectWatcher class. |
| + |
| + // Stop watching the FD, always safe to call. No-op if there's nothing |
| + // to do. |
| + bool StopWatchingFileDescriptor(); |
| + |
| + private: |
| + // Called by MessagePumpLibevent, ownership of |e| is transferred to this |
| + // object. |
| + void Init(event* e, bool is_persistent); |
| + |
| + // Used by MessagePumpLibevent to take ownership of event_. |
| + event *ReleaseEvent(); |
| + friend class MessagePumpLibevent; |
| + |
| + private: |
| + bool is_persistent_; // false if this event is one-shot. |
| + scoped_ptr<event> event_; |
| + DISALLOW_COPY_AND_ASSIGN(FileDescriptorWatcher); |
| }; |
| - // Used with WatchFileHandle to monitor I/O readiness for a File Handle. |
| - class FileWatcher { |
| + // Used with WatchFileDescptor to asynchronously monitor the I/O readiness of |
| + // a File Descriptor. |
| + class Watcher { |
| public: |
| - virtual ~FileWatcher() {} |
| - // Called from MessageLoop::Run when a non-blocking read/write can be made. |
| - virtual void OnFileReadReady(int fd) = 0; |
| - virtual void OnFileWriteReady(int fd) = 0; |
| + virtual ~Watcher() {} |
| + // Called from MessageLoop::Run when an FD can be read from/written to |
| + // without blocking |
| + virtual void OnFileCanReadWithoutBlocking(int fd) = 0; |
| + virtual void OnFileCanWriteWithoutBlocking(int fd) = 0; |
| }; |
| MessagePumpLibevent(); |
| virtual ~MessagePumpLibevent(); |
| - // Have the current thread's message loop watch for a ready socket. |
| - // Caller must provide a struct event for this socket for libevent's use. |
| - // The event and interest_mask fields are defined in libevent. |
| + enum Mode { |
| + WATCH_READ = 1 << 0, |
| + WATCH_WRITE = 1 << 1, |
| + WATCH_READ_WRITE = WATCH_READ | WATCH_WRITE |
| + }; |
| + |
| + // Have the current thread's message loop watch for a a situation in which |
| + // reading/writing to the FD can be performed without Blocking. |
| + // Callers must provide a preallocated FileDescriptorWatcher object which |
| + // can later be used to manage the Lifetime of this event. |
| + // If a FileDescriptorWatcher is passed in which is already attached to |
| + // an event, then the effect is cumulative i.e. after the call |controller| |
| + // will watch both the previous event and the new one. |
| + // If an error occurs while calling this method in a cumulative fashion, the |
| + // event previously attached to |controller| is aborted. |
| // Returns true on success. |
| - // TODO(dkegel): hide libevent better; abstraction still too leaky |
| - // TODO(dkegel): better error handing |
| // TODO(dkegel): switch to edge-triggered readiness notification |
| - void WatchSocket(int socket, short interest_mask, event* e, Watcher*); |
| - |
| - // TODO(playmobil): Merge this with WatchSocket(). |
| - void WatchFileHandle(int fd, short interest_mask, event* e, FileWatcher*); |
| - |
| - // Stop watching a socket. |
| - // Event was previously initialized by WatchSocket. |
| - void UnwatchSocket(event* e); |
| - |
| - // Stop watching a File Handle. |
| - // Event was previously initialized by WatchFileHandle. |
| - void UnwatchFileHandle(event* e); |
| + bool WatchFileDescriptor(int fd, |
| + bool persistent, |
| + Mode mode, |
| + FileDescriptorWatcher *controller, |
| + Watcher *delegate); |
| // MessagePump methods: |
| virtual void Run(Delegate* delegate); |
| @@ -83,14 +109,9 @@ class MessagePumpLibevent : public MessagePump { |
| // readiness callbacks when a socket is ready for I/O. |
| event_base* event_base_; |
| - // Called by libevent to tell us a registered socket is ready |
| - static void OnReadinessNotification(int socket, short flags, void* context); |
| - |
| - // Called by libevent to tell us a registered fd is ready. |
| - static void OnFileReadReadinessNotification(int fd, short flags, |
| - void* context); |
| - static void OnFileWriteReadinessNotification(int fd, short flags, |
| - void* context); |
| + // Called by libevent to tell us a registered FD can be read/written to. |
| + static void OnLibeventNotification(int fd, short flags, |
| + void* context); |
| // Unix pipe used to implement ScheduleWork() |
| // ... callback; called by libevent inside Run() when pipe is ready to read |