add changelog for 1.13
[beanstalkd.git] / linux.c
blob1c5670a8dd39e3e277fd8846338506b2a4b7bcae
1 #define _XOPEN_SOURCE 600
3 #include "dat.h"
4 #include <unistd.h>
5 #include <sys/types.h>
6 #include <stdint.h>
7 #include <fcntl.h>
8 #include <stdlib.h>
9 #include <errno.h>
10 #include <sys/epoll.h>
12 #ifndef EPOLLRDHUP
13 #define EPOLLRDHUP 0x2000
14 #endif
16 static int epfd;
19 int
20 sockinit(void)
22 epfd = epoll_create(1);
23 if (epfd == -1) {
24 twarn("epoll_create");
25 return -1;
27 return 0;
31 int
32 sockwant(Socket *s, int rw)
34 int op;
36 if (!s->added && !rw) {
37 return 0;
38 } else if (!s->added && rw) {
39 s->added = 1;
40 op = EPOLL_CTL_ADD;
41 } else if (!rw) {
42 op = EPOLL_CTL_DEL;
43 } else {
44 op = EPOLL_CTL_MOD;
47 struct epoll_event ev = {.events=0};
48 switch (rw) {
49 case 'r':
50 ev.events = EPOLLIN;
51 break;
52 case 'w':
53 ev.events = EPOLLOUT;
54 break;
56 ev.events |= EPOLLRDHUP | EPOLLPRI;
57 ev.data.ptr = s;
59 return epoll_ctl(epfd, op, s->fd, &ev);
63 int
64 socknext(Socket **s, int64 timeout)
66 int r;
67 struct epoll_event ev = {.events=0};
69 r = epoll_wait(epfd, &ev, 1, (int)(timeout/1000000));
70 if (r == -1 && errno != EINTR) {
71 twarn("epoll_wait");
72 exit(1);
75 if (r > 0) {
76 *s = ev.data.ptr;
77 if (ev.events & (EPOLLHUP|EPOLLRDHUP)) {
78 return 'h';
79 } else if (ev.events & EPOLLIN) {
80 return 'r';
81 } else if (ev.events & EPOLLOUT) {
82 return 'w';
85 return 0;