aura  0.1
 All Data Structures Functions Variables Modules Pages
eventsys-epoll.c
1 #include <aura/aura.h>
2 #include <aura/private.h>
3 #include <sys/epoll.h>
4 #include <sys/time.h>
5 #include <unistd.h>
6 #include <sys/eventfd.h>
7 
8 struct aura_epoll_data {
9  int epollfd;
10  struct aura_pollfds evtfd;
11  void *loopdata;
12 };
13 
14 void *aura_eventsys_backend_create(void *loopdata)
15 {
16  struct aura_epoll_data *epd = calloc(1, sizeof(*epd));
17  if (!epd)
18  return NULL;
19  epd->loopdata = loopdata;
20  epd->epollfd = epoll_create(7);
21  if (!epd->epollfd)
22  goto errfreeepd;
23 
24  /* We use eventfd here to interrupt things */
25 
26  epd->evtfd.fd = eventfd(0, EFD_NONBLOCK);
27  epd->evtfd.events = EPOLLIN;
28  if (-1 == epd->evtfd.fd)
29  goto errepolldestroy;
30 
31  aura_eventsys_backend_fd_action(epd, &epd->evtfd, AURA_FD_ADDED);
32 
33  return epd;
34 errepolldestroy:
35  close(epd->epollfd);
36 errfreeepd:
37  free(epd);
38  return NULL;
39 }
40 
41 void aura_eventsys_backend_destroy(void *backend)
42 {
43  struct aura_epoll_data *epd = backend;
44  close(epd->epollfd);
45  close(epd->evtfd.fd);
46  free(epd);
47 }
48 
49 void aura_eventsys_backend_fd_action(void *backend, const struct aura_pollfds *ap, int action)
50 {
51  struct aura_node *node = ap->node;
52  struct epoll_event ev;
53  struct aura_epoll_data *epd = backend;
54  ((struct aura_pollfds *)ap)->magic = 0xdeadbeaf;
55  int ret;
56  int op = (action == AURA_FD_ADDED) ? EPOLL_CTL_ADD : EPOLL_CTL_DEL;
57  slog(4, SLOG_DEBUG, "epoll: Descriptor %d %s to/from epoll",
58  ap->fd, (action == AURA_FD_ADDED) ? "added" : "removed");
59  ev.events = ap->events;
60  ev.data.ptr = (void *) ap;
61  ret = epoll_ctl(epd->epollfd, op, ap->fd, &ev);
62  if (ret != 0)
63  BUG(node, "Event System failed to add/remove a descriptor");
64 }
65 
66 #define NUM_EVTS 1
67 int aura_eventsys_backend_wait(void *backend, int timeout_ms)
68 {
69  struct aura_epoll_data *epd = backend;
70  struct epoll_event ev[NUM_EVTS];
71  int i;
72  int ret = epoll_wait(epd->epollfd, ev, NUM_EVTS, timeout_ms);
73 
74  slog(4, SLOG_LIVE, "epoll: reported %d events", ret);
75  if (ret < 0) {
76  slog(0, SLOG_ERROR, "epoll: returned -1: %s", strerror(errno));
77  aura_panic(NULL);
78  return -1; /* Never reached */
79  }
80 
81  for (i = 0; i< ret; i++) {
82  struct aura_pollfds *ap;
83  ap = ev[i].data.ptr;
84  if (ap == &epd->evtfd) {
85  /* Read out our event */
86  uint64_t tmp;
87  ap = NULL;
88  read(epd->evtfd.fd, &tmp, sizeof(uint64_t));
89  } else
90  ap->events = ev[i].events;
91 
92  slog(4, SLOG_LIVE, "events: %s %s %s",
93  (ev[i].events & EPOLLIN) ? "IN" : "",
94  (ev[i].events & EPOLLOUT) ? "OUT" : "",
95  (ev[i].events & EPOLLPRI) ? "PRI" : ""
96  );
97 
98  aura_eventloop_report_event(epd->loopdata, ap);
99  }
100  return ret;
101 }
102 
103 void aura_eventsys_backend_interrupt(void *backend)
104 {
105  struct aura_epoll_data *epd = backend;
106  uint64_t tmp = 1;
107  write(epd->evtfd.fd, &tmp, sizeof(uint64_t));
108 }