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 |