remove conn from the heap in conn_close
[beanstalkd.git] / sock-bsd.c
blobeb3e3dfa571e04d03c4cb52d72ea84ecb5ce2530
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 struct kevent ev = {};
42 struct timespec ts = {};
44 if (!s->added && !rw) {
45 return 0;
46 } else if (rw) {
47 s->added = 1;
48 ev.flags = EV_ADD;
49 } else {
50 ev.flags = EV_DELETE;
53 switch (rw) {
54 case 'r':
55 ev.filter = EVFILT_READ;
56 break;
57 case 'w':
58 ev.filter = EVFILT_WRITE;
59 break;
60 default:
61 // check only for hangup
62 ev.filter = EVFILT_READ;
63 ev.fflags = NOTE_LOWAT;
64 ev.data = Infinity;
66 ev.ident = s->fd;
67 ev.udata = s;
68 return kevent(kq, &ev, 1, NULL, 0, &ts);
72 void
73 sockmain()
75 int i, r, n = 500;
76 int64 e, t = nanoseconds();
77 struct kevent evs[n];
79 for (;;) {
80 r = kevent(kq, NULL, 0, evs, n, &ivalts);
81 if (r == -1 && errno != EINTR) {
82 twarn("kevent");
83 exit(1);
86 // should tick?
87 e = nanoseconds();
88 if (e-t > ival) {
89 tick(tickval, 0);
90 t = e;
93 for (i=0; i<r; i++) {
94 handle(evs[i].udata, evs[i].filter, evs[i].flags);
101 static void
102 handle(Socket *s, int filt, int flags)
104 if (flags & EV_EOF) {
105 s->f(s->x, 'h');
106 } else if (filt == EVFILT_READ) {
107 s->f(s->x, 'r');
108 } else if (filt == EVFILT_WRITE) {
109 s->f(s->x, 'w');