• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetEventBase()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 {
operatorGreater77     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