#include <stdio.h>
#include <stdlib.h>
#include "../util/atomic.h"
#include "event_bsd.h"
EVHandler* evhandler_create(EventHandlerConfig *cfg) {
EVHandler *ev = malloc(
sizeof(EVHandler));
ev->current =
0;
ev->instances = calloc(cfg->nthreads,
sizeof(
void*));
ev->numins = cfg->nthreads;
for(
int i=
0;i<cfg->nthreads;i++) {
EventHandler *handler = malloc(
sizeof(EventHandler));
ev->instances[i] = handler;
handler->kqueue = kqueue();
if(handler->kqueue ==
0) {
return NULL;
}
SYS_THREAD t = systhread_start(
0,
0,
(thrstartfunc)ev_handle_events,
handler);
systhread_detach(t);
}
return ev;
}
void ev_handle_events(EventHandler *ev) {
struct timespec timeout;
timeout.tv_nsec =
0;
timeout.tv_sec =
600;
struct kevent events[
64];
struct kevent changes[
64];
int numchanges =
0;
for(;;) {
int nev = kevent(ev->kqueue, changes, numchanges, events,
64, &timeout);
if(nev == -
1) {
perror(
"kevent");
continue;
}
numchanges =
0;
for(
int i=
0;i<nev;i++) {
Event *event = (Event*)events[i].udata;
if(event->fn) {
int ep = event->events;
if(event->fn(ev, event)) {
if(event->events != ep) {
changes[numchanges++].filter = ev_convert2sys_events(ep);
}
}
else if(event->finish) {
changes[numchanges++].filter = ev_convert2sys_events(ep);
event->finish(ev, event);
}
}
}
}
}
int ev_convert2sys_events(
int events) {
int e =
0;
if((events &
EVENT_POLLIN) ==
EVENT_POLLIN) {
e |=
EVFILT_READ;
}
if((events &
EVENT_POLLOUT) ==
EVENT_POLLOUT) {
e |=
EVFILT_WRITE;
}
return e;
}
int ev_pollin(EventHandler *h,
int fd, Event *event) {
event->events =
EVENT_POLLIN;
struct kevent kev;
EV_SET(&kev, fd,
EVFILT_READ,
EV_ADD,
0,
0, event);
return kevent(h->kqueue, &kev,
1,
NULL,
0,
NULL);
}
int ev_pollout(EventHandler *h,
int fd, Event *event) {
event->events =
EVENT_POLLOUT;
struct kevent kev;
EV_SET(&kev, fd,
EVFILT_WRITE,
EV_ADD,
0,
0, event);
return kevent(h->kqueue, &kev,
1,
NULL,
0,
NULL);
}
int event_send(EventHandler *h, Event *event) {
return 0;
}