Add fd event support to EventTaskRunner
This change allows applications to perform
general I/O completion handling as part of the
Run() loop, rather than just timeout completion.
Change-Id: Idce97a33f7a35348ac5a7d226491f9907edc3405
Reviewed-on: https://weave-review.googlesource.com/1447
Reviewed-by: Vitaly Buka <vitalybuka@google.com>
diff --git a/examples/provider/event_task_runner.h b/examples/provider/event_task_runner.h
index 473441e..7291314 100644
--- a/examples/provider/event_task_runner.h
+++ b/examples/provider/event_task_runner.h
@@ -10,9 +10,10 @@
#include <vector>
#include <event2/event.h>
-
#include <weave/provider/task_runner.h>
+#include "examples/provider/event_deleter.h"
+
namespace weave {
namespace examples {
@@ -23,6 +24,40 @@
const base::Closure& task,
base::TimeDelta delay) override;
+ // Defines the types of I/O completion events that the
+ // application can register to receive on a file descriptor.
+ enum IOEvent : int16_t {
+ kReadable = 0x01,
+ kWriteable = 0x02,
+ kClosed = 0x04,
+ kReadableWriteable = kReadable | kWriteable,
+ kReadableOrClosed = kReadable | kClosed,
+ kAll = kReadableOrClosed | kWriteable,
+ };
+
+ // Callback type for I/O completion events.
+ // Arguments:
+ // fd - file descriptor that triggered the event
+ // what - combination of IOEvent flags indicating
+ // which event(s) occurred
+ // sender - reference to the EventTaskRunner that
+ // called the IoCompletionCallback
+ using IoCompletionCallback =
+ base::Callback<void(int fd, int16_t what, EventTaskRunner* sender)>;
+
+ // Adds a handler for the specified IO completion events on a file
+ // descriptor. The 'what' parameter is a combination of IOEvent flags.
+ // Only one callback is allowed per file descriptor; calling this function
+ // with an fd that has already been registered will replace the previous
+ // callback with the new one.
+ void AddIoCompletionTask(int fd,
+ int16_t what,
+ const IoCompletionCallback& task);
+
+ // Remove the callback associated with this fd and stop listening for
+ // events related to it.
+ void RemoveIoCompletionTask(int fd);
+
event_base* GetEventBase() const { return base_.get(); }
void Run();
@@ -33,6 +68,9 @@
static void FreeEvent(event* evnt);
void Process();
+ static void FdEventHandler(int fd, int16_t what, void* runner);
+ void ProcessFd(int fd, int16_t what);
+
using QueueItem = std::pair<std::pair<base::Time, size_t>, base::Closure>;
struct Greater {
@@ -47,10 +85,12 @@
std::vector<QueueItem>,
EventTaskRunner::Greater> queue_;
- std::unique_ptr<event_base, decltype(&event_base_free)> base_{
- event_base_new(), &event_base_free};
- std::unique_ptr<event, decltype(&FreeEvent)> task_event_{
- event_new(base_.get(), -1, EV_TIMEOUT, &EventHandler, this), &FreeEvent};
+ EventPtr<event_base> base_{event_base_new()};
+
+ EventPtr<event> task_event_{
+ event_new(base_.get(), -1, EV_TIMEOUT, &EventHandler, this)};
+
+ std::map<int, std::pair<EventPtr<event>, IoCompletionCallback>> fd_task_map_;
};
} // namespace examples