1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include <stdio.h>
30 #include <stdlib.h>
31
32 #include "../util/atomic.h"
33
34 #include "event_bsd.h"
35
36 EVHandler* evhandler_create(EventHandlerConfig *cfg) {
37 EVHandler *ev = malloc(
sizeof(EVHandler));
38 ev->current =
0;
39 ev->instances = calloc(cfg->nthreads,
sizeof(
void*));
40 ev->numins = cfg->nthreads;
41
42 for(
int i=
0;i<cfg->nthreads;i++) {
43 EventHandler *handler = malloc(
sizeof(EventHandler));
44 ev->instances[i] = handler;
45
46 handler->kqueue = kqueue();
47 if(handler->kqueue ==
0) {
48
49 return NULL;
50 }
51
52 SYS_THREAD t = systhread_start(
53 0,
54 0,
55 (thrstartfunc)ev_handle_events,
56 handler);
57 systhread_detach(t);
58 }
59
60 return ev;
61 }
62
63
64 void ev_handle_events(EventHandler *ev) {
65 struct timespec timeout;
66 timeout.tv_nsec =
0;
67 timeout.tv_sec =
600;
68
69 struct kevent events[
64];
70 struct kevent changes[
64];
71 int numchanges =
0;
72
73 for(;;) {
74
75 int nev = kevent(ev->kqueue, changes, numchanges, events,
64, &timeout);
76 if(nev == -
1) {
77
78 perror(
"kevent");
79 continue;
80 }
81
82 numchanges =
0;
83 for(
int i=
0;i<nev;i++) {
84 Event *event = (Event*)events[i].udata;
85 if(event->fn) {
86 int ep = event->events;
87 if(event->fn(ev, event)) {
88 if(event->events != ep) {
89 changes[numchanges++].filter = ev_convert2sys_events(ep);
90 }
91 }
else if(event->finish) {
92 changes[numchanges++].filter = ev_convert2sys_events(ep);
93 event->finish(ev, event);
94 }
95 }
96 }
97 }
98 }
99
100 int ev_convert2sys_events(
int events) {
101 int e =
0;
102 if((events &
EVENT_POLLIN) ==
EVENT_POLLIN) {
103 e |=
EVFILT_READ;
104 }
105 if((events &
EVENT_POLLOUT) ==
EVENT_POLLOUT) {
106 e |=
EVFILT_WRITE;
107 }
108 return e;
109 }
110
111 int ev_pollin(EventHandler *h,
int fd, Event *event) {
112 event->events =
EVENT_POLLIN;
113 struct kevent kev;
114 EV_SET(&kev, fd,
EVFILT_READ,
EV_ADD,
0,
0, event);
115 return kevent(h->kqueue, &kev,
1,
NULL,
0,
NULL);
116 }
117
118 int ev_pollout(EventHandler *h,
int fd, Event *event) {
119 event->events =
EVENT_POLLOUT;
120 struct kevent kev;
121 EV_SET(&kev, fd,
EVFILT_WRITE,
EV_ADD,
0,
0, event);
122 return kevent(h->kqueue, &kev,
1,
NULL,
0,
NULL);
123 }
124
125 int event_send(EventHandler *h, Event *event) {
126 return 0;
127 }
128