blob: b0c66fa91eb87e876f18c469671ea66249faf16a [file] [log] [blame]
Brian Silverman801d49c2016-03-20 15:50:22 -07001#include "aos/vision/events/epoll_events.h"
2
Brian Silverman801d49c2016-03-20 15:50:22 -07003#include <fcntl.h>
Parker Schuhb59bf5e2016-12-28 21:09:36 -08004#include <string.h>
Brian Silverman801d49c2016-03-20 15:50:22 -07005#include <sys/epoll.h>
Parker Schuhb59bf5e2016-12-28 21:09:36 -08006#include <sys/socket.h>
7#include <sys/types.h>
Brian Silverman801d49c2016-03-20 15:50:22 -07008#include <vector>
9
Brian Silverman801d49c2016-03-20 15:50:22 -070010#include "aos/common/logging/logging.h"
11
12namespace aos {
13namespace events {
14
Parker Schuhb59bf5e2016-12-28 21:09:36 -080015EpollLoop::EpollLoop() : epoll_fd_(PCHECK(epoll_create1(0))) {}
Brian Silverman801d49c2016-03-20 15:50:22 -070016
Parker Schuhb59bf5e2016-12-28 21:09:36 -080017void EpollLoop::Add(EpollEvent *event) {
18 event->loop_ = this;
19 struct epoll_event temp_event;
20 temp_event.data.ptr = static_cast<void *>(event);
Parker Schuhc1975fc2018-04-07 15:27:07 -070021 temp_event.events = event->events();
Parker Schuhb59bf5e2016-12-28 21:09:36 -080022 PCHECK(epoll_ctl(epoll_fd(), EPOLL_CTL_ADD, event->fd(), &temp_event));
23}
Brian Silverman801d49c2016-03-20 15:50:22 -070024
Parker Schuhb59bf5e2016-12-28 21:09:36 -080025void EpollLoop::Delete(EpollEvent *event) {
Parker Schuhc1975fc2018-04-07 15:27:07 -070026 event->loop_ = nullptr;
Parker Schuhb59bf5e2016-12-28 21:09:36 -080027 PCHECK(epoll_ctl(epoll_fd(), EPOLL_CTL_DEL, event->fd(), NULL));
28}
Brian Silverman801d49c2016-03-20 15:50:22 -070029
Parker Schuhb59bf5e2016-12-28 21:09:36 -080030void EpollLoop::Run() {
31 while (true) {
32 const int timeout = CalculateTimeout();
33 static constexpr size_t kNumberOfEvents = 64;
34 epoll_event events[kNumberOfEvents];
35 const int number_events =
36 PCHECK(epoll_wait(epoll_fd(), events, kNumberOfEvents, timeout));
37
38 for (int i = 0; i < number_events; i++) {
Parker Schuhc1975fc2018-04-07 15:27:07 -070039 static_cast<EpollEvent *>(events[i].data.ptr)->DirectEvent(events[i].events);
Parker Schuhb59bf5e2016-12-28 21:09:36 -080040 }
Brian Silverman801d49c2016-03-20 15:50:22 -070041 }
Parker Schuhb59bf5e2016-12-28 21:09:36 -080042}
Brian Silverman801d49c2016-03-20 15:50:22 -070043
Parker Schuhb59bf5e2016-12-28 21:09:36 -080044void EpollLoop::AddWait(EpollWait *wait) { waits_.push_back(wait); }
Parker Schuhb59bf5e2016-12-28 21:09:36 -080045
46// Calculates the new timeout value to pass to epoll_wait.
47int EpollLoop::CalculateTimeout() {
48 const monotonic_clock::time_point monotonic_now = monotonic_clock::now();
49 int r = -1;
50 for (EpollWait *c : waits_) {
51 const int new_timeout = c->Recalculate(monotonic_now);
52 if (new_timeout >= 0) {
53 if (r < 0 || new_timeout < r) {
54 r = new_timeout;
55 }
56 }
57 }
58 return r;
Brian Silverman801d49c2016-03-20 15:50:22 -070059}
60
61} // namespace events
62} // namespace aos