improve the tests
[beanstalkd.git] / sock-linux.c
blob2d1d196419175ec8428380d39b988447befa25f7
1 #include <stdlib.h>
2 #include <errno.h>
3 #include <sys/epoll.h>
4 #include "dat.h"
6 #ifndef EPOLLRDHUP
7 #define EPOLLRDHUP 0x2000
8 #endif
10 static void handle(Socket *s, int events);
12 static Handle tick;
13 static void *tickval;
14 static int epfd;
15 static int ival; // ms
18 void
19 sockinit(Handle f, void *x, int64 ns)
21 tick = f;
22 tickval = x;
23 ival = ns / 1000000;
24 epfd = epoll_create(1);
25 if (epfd == -1) {
26 twarn("epoll_create");
27 exit(1);
32 int
33 sockwant(Socket *s, int rw)
35 int op;
36 struct epoll_event ev = {};
38 if (!s->added && !rw) {
39 return 0;
40 } else if (!s->added && rw) {
41 s->added = 1;
42 op = EPOLL_CTL_ADD;
43 } else if (!rw) {
44 op = EPOLL_CTL_DEL;
45 } else {
46 op = EPOLL_CTL_MOD;
49 switch (rw) {
50 case 'r':
51 ev.events = EPOLLIN;
52 break;
53 case 'w':
54 ev.events = EPOLLOUT;
55 break;
57 ev.events |= EPOLLRDHUP | EPOLLPRI;
58 ev.data.ptr = s;
60 return epoll_ctl(epfd, op, s->fd, &ev);
64 void
65 sockmain()
67 int i, r, n = 1;
68 int64 e, t = nanoseconds();
69 struct epoll_event evs[n];
71 for (;;) {
72 r = epoll_wait(epfd, evs, n, ival);
73 if (r == -1 && errno != EINTR) {
74 twarn("epoll_wait");
75 exit(1);
78 // should tick?
79 e = nanoseconds();
80 if ((e-t) / 1000000 > ival) {
81 tick(tickval, 0);
82 t = e;
85 for (i=0; i<r; i++) {
86 handle(evs[i].data.ptr, evs[i].events);
93 static void
94 handle(Socket *s, int evset)
96 int c = 0;
98 if (evset & (EPOLLHUP|EPOLLRDHUP)) {
99 c = 'h';
100 } else if (evset & EPOLLIN) {
101 c = 'r';
102 } else if (evset & EPOLLOUT) {
103 c = 'w';
106 s->f(s->x, c);