update README and man page
[beanstalkd.git] / sock-bsd.c
blob50002a0802e19d74e59bb44adb10dd6ca570e9dc
1 #include <stdlib.h>
2 #include <errno.h>
3 #include <sys/types.h>
4 #include <sys/event.h>
5 #include <sys/time.h>
6 #include "dat.h"
8 enum
10 Infinity = 1 << 30
13 static void handle(Socket*, int, int);
15 static Handle tick;
16 static void *tickval;
17 static int kq;
18 static int64 ival;
19 static struct timespec ivalts;
22 void
23 sockinit(Handle f, void *x, int64 ns)
25 tick = f;
26 tickval = x;
27 ival = ns;
28 ivalts.tv_sec = ns / 1000000000;
29 ivalts.tv_nsec = ns % 1000000000;
30 kq = kqueue();
31 if (kq == -1) {
32 twarn("kqueue");
33 exit(1);
38 int
39 sockwant(Socket *s, int rw)
41 int n = 0;
42 struct kevent evs[2] = {}, *ev = evs;
43 struct timespec ts = {};
45 if (s->added) {
46 ev->ident = s->fd;
47 ev->filter = s->added;
48 ev->flags = EV_DELETE;
49 ev++;
50 n++;
53 if (rw) {
54 ev->ident = s->fd;
55 switch (rw) {
56 case 'r':
57 ev->filter = EVFILT_READ;
58 break;
59 case 'w':
60 ev->filter = EVFILT_WRITE;
61 break;
62 default:
63 // check only for hangup
64 ev->filter = EVFILT_READ;
65 ev->fflags = NOTE_LOWAT;
66 ev->data = Infinity;
68 ev->flags = EV_ADD;
69 ev->udata = s;
70 s->added = ev->filter;
71 ev++;
72 n++;
75 return kevent(kq, evs, n, NULL, 0, &ts);
79 void
80 sockmain()
82 int i, r, n = 1;
83 int64 e, t = nanoseconds();
84 struct kevent evs[n];
86 for (;;) {
87 r = kevent(kq, NULL, 0, evs, n, &ivalts);
88 if (r == -1 && errno != EINTR) {
89 twarn("kevent");
90 exit(1);
93 // should tick?
94 e = nanoseconds();
95 if (e-t > ival) {
96 tick(tickval, 0);
97 t = e;
100 for (i=0; i<r; i++) {
101 handle(evs[i].udata, evs[i].filter, evs[i].flags);
108 static void
109 handle(Socket *s, int filt, int flags)
111 if (flags & EV_EOF) {
112 s->f(s->x, 'h');
113 } else if (filt == EVFILT_READ) {
114 s->f(s->x, 'r');
115 } else if (filt == EVFILT_WRITE) {
116 s->f(s->x, 'w');