blob: 97f9db93a9a0678af4081b9e9700a0da9817eb34 [file] [log] [blame]
Vitaly Buka4615e0d2015-10-14 15:35:12 -07001// Copyright 2015 The Weave Authors. All rights reserved.
Vitaly Buka17b0a8a2015-08-31 19:12:35 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Johan Euphrosine3523fdd2015-10-14 20:46:05 -07005#ifndef LIBWEAVE_EXAMPLES_PROVIDER_EVENT_TASK_RUNNER_H_
6#define LIBWEAVE_EXAMPLES_PROVIDER_EVENT_TASK_RUNNER_H_
Vitaly Buka17b0a8a2015-08-31 19:12:35 -07007
8#include <queue>
9#include <utility>
10#include <vector>
11
12#include <event2/event.h>
Vitaly Buka1e363672015-09-25 14:01:16 -070013#include <weave/provider/task_runner.h>
Vitaly Buka17b0a8a2015-08-31 19:12:35 -070014
ilewisf1fa93d2015-11-09 09:01:11 -080015#include "examples/provider/event_deleter.h"
16
Vitaly Buka17b0a8a2015-08-31 19:12:35 -070017namespace weave {
18namespace examples {
19
20// Simple task runner implemented with libevent message loop.
Vitaly Buka1e363672015-09-25 14:01:16 -070021class EventTaskRunner : public provider::TaskRunner {
Vitaly Buka17b0a8a2015-08-31 19:12:35 -070022 public:
23 void PostDelayedTask(const tracked_objects::Location& from_here,
24 const base::Closure& task,
25 base::TimeDelta delay) override;
26
ilewisf1fa93d2015-11-09 09:01:11 -080027 // 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
Vitaly Buka17b0a8a2015-08-31 19:12:35 -070061 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
ilewisf1fa93d2015-11-09 09:01:11 -080071 static void FdEventHandler(int fd, int16_t what, void* runner);
72 void ProcessFd(int fd, int16_t what);
73
Vitaly Buka17b0a8a2015-08-31 19:12:35 -070074 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>,
Vitaly Buka34668e72015-12-15 14:46:47 -080086 EventTaskRunner::Greater>
87 queue_;
Vitaly Buka17b0a8a2015-08-31 19:12:35 -070088
ilewisf1fa93d2015-11-09 09:01:11 -080089 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_;
Vitaly Buka17b0a8a2015-08-31 19:12:35 -070095};
96
97} // namespace examples
98} // namespace weave
99
Johan Euphrosine3523fdd2015-10-14 20:46:05 -0700100#endif // LIBWEAVE_EXAMPLES_PROVIDER_EVENT_TASK_RUNNER_H_