Vitaly Buka | 4615e0d | 2015-10-14 15:35:12 -0700 | [diff] [blame] | 1 | // Copyright 2015 The Weave Authors. All rights reserved. |
Vitaly Buka | 17b0a8a | 2015-08-31 19:12:35 -0700 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Johan Euphrosine | 3523fdd | 2015-10-14 20:46:05 -0700 | [diff] [blame] | 5 | #include "examples/provider/event_task_runner.h" |
Vitaly Buka | 17b0a8a | 2015-08-31 19:12:35 -0700 | [diff] [blame] | 6 | |
| 7 | #include <signal.h> |
| 8 | |
| 9 | namespace weave { |
| 10 | namespace examples { |
| 11 | |
| 12 | namespace { |
| 13 | event_base* g_event_base = nullptr; |
| 14 | } |
| 15 | |
| 16 | void EventTaskRunner::PostDelayedTask( |
| 17 | const tracked_objects::Location& from_here, |
| 18 | const base::Closure& task, |
| 19 | base::TimeDelta delay) { |
| 20 | base::Time new_time = base::Time::Now() + delay; |
| 21 | if (queue_.empty() || new_time < queue_.top().first.first) { |
| 22 | ReScheduleEvent(delay); |
| 23 | } |
| 24 | queue_.emplace(std::make_pair(new_time, ++counter_), task); |
| 25 | } |
| 26 | |
ilewis | f1fa93d | 2015-11-09 09:01:11 -0800 | [diff] [blame] | 27 | void EventTaskRunner::AddIoCompletionTask( |
| 28 | int fd, |
| 29 | int16_t what, |
| 30 | const EventTaskRunner::IoCompletionCallback& task) { |
| 31 | int16_t flags = EV_PERSIST | EV_ET; |
| 32 | flags |= (what & kReadable) ? EV_READ : 0; |
| 33 | flags |= (what & kWriteable) ? EV_WRITE : 0; |
| 34 | flags |= (what & kClosed) ? EV_CLOSED : 0; |
| 35 | event* ioevent = event_new(base_.get(), fd, flags, FdEventHandler, this); |
| 36 | EventPtr<event> ioeventPtr{ioevent}; |
Vitaly Buka | 52d006a | 2015-11-21 17:14:51 -0800 | [diff] [blame] | 37 | fd_task_map_.insert( |
| 38 | std::make_pair(fd, std::make_pair(std::move(ioeventPtr), task))); |
ilewis | f1fa93d | 2015-11-09 09:01:11 -0800 | [diff] [blame] | 39 | event_add(ioevent, nullptr); |
| 40 | } |
| 41 | |
| 42 | void EventTaskRunner::RemoveIoCompletionTask(int fd) { |
| 43 | fd_task_map_.erase(fd); |
| 44 | } |
| 45 | |
Vitaly Buka | 17b0a8a | 2015-08-31 19:12:35 -0700 | [diff] [blame] | 46 | void EventTaskRunner::Run() { |
| 47 | g_event_base = base_.get(); |
| 48 | |
| 49 | struct sigaction sa = {}; |
| 50 | sa.sa_handler = [](int signal) { |
| 51 | event_base_loopexit(g_event_base, nullptr); |
| 52 | }; |
| 53 | sigfillset(&sa.sa_mask); |
| 54 | sigaction(SIGINT, &sa, nullptr); |
| 55 | |
| 56 | event_base_loop(g_event_base, EVLOOP_NO_EXIT_ON_EMPTY); |
| 57 | g_event_base = nullptr; |
| 58 | } |
| 59 | |
| 60 | void EventTaskRunner::ReScheduleEvent(base::TimeDelta delay) { |
| 61 | timespec ts = delay.ToTimeSpec(); |
| 62 | timeval tv = {ts.tv_sec, ts.tv_nsec / 1000}; |
| 63 | event_add(task_event_.get(), &tv); |
| 64 | } |
| 65 | |
ilewis | f1fa93d | 2015-11-09 09:01:11 -0800 | [diff] [blame] | 66 | void EventTaskRunner::EventHandler(int /* fd */, |
| 67 | int16_t /* what */, |
| 68 | void* runner) { |
Vitaly Buka | 17b0a8a | 2015-08-31 19:12:35 -0700 | [diff] [blame] | 69 | static_cast<EventTaskRunner*>(runner)->Process(); |
| 70 | } |
| 71 | |
| 72 | void EventTaskRunner::FreeEvent(event* evnt) { |
| 73 | event_del(evnt); |
| 74 | event_free(evnt); |
| 75 | } |
| 76 | |
| 77 | void EventTaskRunner::Process() { |
| 78 | while (!queue_.empty() && queue_.top().first.first <= base::Time::Now()) { |
| 79 | auto cb = queue_.top().second; |
| 80 | queue_.pop(); |
| 81 | cb.Run(); |
| 82 | } |
| 83 | if (!queue_.empty()) { |
| 84 | base::TimeDelta delta = std::max( |
| 85 | base::TimeDelta(), queue_.top().first.first - base::Time::Now()); |
| 86 | ReScheduleEvent(delta); |
| 87 | } |
| 88 | } |
| 89 | |
ilewis | f1fa93d | 2015-11-09 09:01:11 -0800 | [diff] [blame] | 90 | void EventTaskRunner::FdEventHandler(int fd, int16_t what, void* runner) { |
| 91 | static_cast<EventTaskRunner*>(runner)->ProcessFd(fd, what); |
| 92 | } |
| 93 | |
| 94 | void EventTaskRunner::ProcessFd(int fd, int16_t what) { |
| 95 | auto it = fd_task_map_.find(fd); |
| 96 | if (it != fd_task_map_.end()) { |
| 97 | const IoCompletionCallback& callback = it->second.second; |
| 98 | callback.Run(fd, what, this); |
| 99 | } |
| 100 | } |
| 101 | |
Vitaly Buka | 17b0a8a | 2015-08-31 19:12:35 -0700 | [diff] [blame] | 102 | } // namespace examples |
| 103 | } // namespace weave |