1 // Copyright 2015 The Weave Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef LIBWEAVE_EXAMPLES_PROVIDER_EVENT_TASK_RUNNER_H_ 6 #define LIBWEAVE_EXAMPLES_PROVIDER_EVENT_TASK_RUNNER_H_ 7 8 #include <queue> 9 #include <utility> 10 #include <vector> 11 12 #include <event2/event.h> 13 #include <weave/provider/task_runner.h> 14 15 #include "examples/provider/event_deleter.h" 16 17 namespace weave { 18 namespace examples { 19 20 // Simple task runner implemented with libevent message loop. 21 class EventTaskRunner : public provider::TaskRunner { 22 public: 23 void PostDelayedTask(const tracked_objects::Location& from_here, 24 const base::Closure& task, 25 base::TimeDelta delay) override; 26 27 // Defines the types of I/O completion events that the 28 // application can register to receive on a file descriptor. 29 enum IOEvent : int16_t { 30 kReadable = 0x01, 31 kWriteable = 0x02, 32 kClosed = 0x04, 33 kReadableWriteable = kReadable | kWriteable, 34 kReadableOrClosed = kReadable | kClosed, 35 kAll = kReadableOrClosed | kWriteable, 36 }; 37 38 // Callback type for I/O completion events. 39 // Arguments: 40 // fd - file descriptor that triggered the event 41 // what - combination of IOEvent flags indicating 42 // which event(s) occurred 43 // sender - reference to the EventTaskRunner that 44 // called the IoCompletionCallback 45 using IoCompletionCallback = 46 base::Callback<void(int fd, int16_t what, EventTaskRunner* sender)>; 47 48 // Adds a handler for the specified IO completion events on a file 49 // descriptor. The 'what' parameter is a combination of IOEvent flags. 50 // Only one callback is allowed per file descriptor; calling this function 51 // with an fd that has already been registered will replace the previous 52 // callback with the new one. 53 void AddIoCompletionTask(int fd, 54 int16_t what, 55 const IoCompletionCallback& task); 56 57 // Remove the callback associated with this fd and stop listening for 58 // events related to it. 59 void RemoveIoCompletionTask(int fd); 60 61 event_base* GetEventBase() const { return base_.get(); } 62 63 void Run(); 64 65 private: 66 void ReScheduleEvent(base::TimeDelta delay); 67 static void EventHandler(int, int16_t, void* runner); 68 static void FreeEvent(event* evnt); 69 void Process(); 70 71 static void FdEventHandler(int fd, int16_t what, void* runner); 72 void ProcessFd(int fd, int16_t what); 73 74 using QueueItem = std::pair<std::pair<base::Time, size_t>, base::Closure>; 75 76 struct Greater { 77 bool operator()(const QueueItem& a, const QueueItem& b) const { 78 return a.first > b.first; 79 } 80 }; 81 82 size_t counter_{0}; // Keeps order of tasks with the same time. 83 84 std::priority_queue<QueueItem, 85 std::vector<QueueItem>, 86 EventTaskRunner::Greater> 87 queue_; 88 89 EventPtr<event_base> base_{event_base_new()}; 90 91 EventPtr<event> task_event_{ 92 event_new(base_.get(), -1, EV_TIMEOUT, &EventHandler, this)}; 93 94 std::map<int, std::pair<EventPtr<event>, IoCompletionCallback>> fd_task_map_; 95 }; 96 97 } // namespace examples 98 } // namespace weave 99 100 #endif // LIBWEAVE_EXAMPLES_PROVIDER_EVENT_TASK_RUNNER_H_ 101