32 #include "../config.h"
37 #include <sys/types.h>
38 #include <sys/queue.h>
46 #define RB_AUGMENT(x) (void)(x)
50 #include "event-internal.h"
52 #define XFREE(ptr) do { if (ptr) free(ptr); } while(0)
54 extern struct event_list timequeue;
55 extern struct event_list addqueue;
57 extern struct event_list signalqueue;
65 int evsigcaught[NSIG];
66 volatile sig_atomic_t signal_caught = 0;
68 volatile double SIGFPE_REQ = 0.0f;
71 static void signal_handler(
int sig);
73 void signal_process(
void);
74 int signal_recalc(
void);
82 struct event *read_event;
83 struct event *write_event;
89 if (a->sock < b->sock)
91 else if (a->sock > b->sock)
106 unsigned signals_are_broken : 1;
113 int win32_insert (
void *,
struct event *);
114 int win32_del (
void *,
struct event *);
116 void win32_dealloc (
struct event_base *,
void *);
128 #define FD_SET_ALLOC_SIZE(n) ((sizeof(struct win_fd_set) + ((n)-1)*sizeof(SOCKET)))
131 realloc_fd_sets(
struct win32op *op,
size_t new_size)
135 assert(new_size >= op->readset_in->fd_count &&
136 new_size >= op->writeset_in->fd_count);
137 assert(new_size >= 1);
139 size = FD_SET_ALLOC_SIZE(new_size);
140 if (!(op->readset_in = realloc(op->readset_in, size)))
142 if (!(op->writeset_in = realloc(op->writeset_in, size)))
144 if (!(op->readset_out = realloc(op->readset_out, size)))
146 if (!(op->exset_out = realloc(op->exset_out, size)))
148 if (!(op->writeset_out = realloc(op->writeset_out, size)))
150 op->fd_setsz = new_size;
155 timeval_to_ms(
struct timeval *tv)
157 return ((tv->tv_sec * 1000) + (tv->tv_usec / 1000));
161 get_event_entry(
struct win32op *op, SOCKET s,
int create)
165 val = RB_FIND(event_map, &op->event_root, &key);
168 if (!(val = calloc(1,
sizeof(
struct event_entry)))) {
169 event_warn(
"%s: calloc", __func__);
173 val->read_pos = val->write_pos = -1;
174 RB_INSERT(event_map, &op->event_root, val);
181 SOCKET s = ent->sock;
182 struct win_fd_set *
set = read ? op->readset_in : op->writeset_in;
184 if (ent->read_pos >= 0)
187 if (ent->write_pos >= 0)
190 if (set->fd_count == op->fd_setsz) {
191 if (realloc_fd_sets(op, op->fd_setsz*2))
194 set = read ? op->readset_in : op->writeset_in;
196 set->fd_array[
set->fd_count] = s;
198 ent->read_pos =
set->fd_count;
200 ent->write_pos =
set->fd_count;
201 return (set->fd_count++);
208 struct win_fd_set *
set = read ? op->readset_in : op->writeset_in;
218 if (--set->fd_count != i) {
221 s2 =
set->fd_array[
i] =
set->fd_array[
set->fd_count];
222 ent2 = get_event_entry(op, s2, 0);
239 if (!(winop = calloc(1,
sizeof(
struct win32op))))
241 winop->fd_setsz = NEVENT;
242 size = FD_SET_ALLOC_SIZE(NEVENT);
243 if (!(winop->readset_in = malloc(size)))
245 if (!(winop->writeset_in = malloc(size)))
247 if (!(winop->readset_out = malloc(size)))
249 if (!(winop->writeset_out = malloc(size)))
251 if (!(winop->exset_out = malloc(size)))
253 RB_INIT(&winop->event_root);
254 winop->readset_in->fd_count = winop->writeset_in->fd_count = 0;
255 winop->readset_out->fd_count = winop->writeset_out->fd_count
256 = winop->exset_out->fd_count = 0;
258 if (evsignal_init(_base) < 0)
259 winop->signals_are_broken = 1;
263 XFREE(winop->readset_in);
264 XFREE(winop->writeset_in);
265 XFREE(winop->readset_out);
266 XFREE(winop->writeset_out);
267 XFREE(winop->exset_out);
273 win32_insert(
void *op,
struct event *ev)
278 if (ev->ev_events & EV_SIGNAL) {
279 if (win32op->signals_are_broken)
281 return (evsignal_add(ev));
283 if (!(ev->ev_events & (EV_READ|EV_WRITE)))
285 ent = get_event_entry(win32op, ev->ev_fd, 1);
289 event_debug((
"%s: adding event for %d", __func__, (
int)ev->ev_fd));
290 if (ev->ev_events & EV_READ) {
291 if (do_fd_set(win32op, ent, 1)<0)
293 ent->read_event = ev;
295 if (ev->ev_events & EV_WRITE) {
296 if (do_fd_set(win32op, ent, 0)<0)
298 ent->write_event = ev;
304 win32_del(
void *op,
struct event *ev)
306 struct win32op *win32op = op;
309 if (ev->ev_events & EV_SIGNAL)
310 return (evsignal_del(ev));
312 if (!(ent = get_event_entry(win32op, ev->ev_fd, 0)))
314 event_debug((
"%s: Removing event for %d", __func__, ev->ev_fd));
315 if (ev == ent->read_event) {
316 do_fd_clear(win32op, ent, 1);
317 ent->read_event = NULL;
319 if (ev == ent->write_event) {
320 do_fd_clear(win32op, ent, 0);
321 ent->write_event = NULL;
323 if (!ent->read_event && !ent->write_event) {
324 RB_REMOVE(event_map, &win32op->event_root, ent);
334 out->fd_count = in->fd_count;
335 memcpy(out->fd_array, in->fd_array, in->fd_count * (
sizeof(SOCKET)));
350 win32_dispatch(
struct event_base *base,
void *op,
353 struct win32op *win32op = op;
360 fd_set_copy(win32op->readset_out, win32op->readset_in);
361 fd_set_copy(win32op->exset_out, win32op->readset_in);
362 fd_set_copy(win32op->writeset_out, win32op->writeset_in);
365 (win32op->readset_out->fd_count > win32op->writeset_out->fd_count) ?
366 win32op->readset_out->fd_count : win32op->writeset_out->fd_count;
370 Sleep(timeval_to_ms(tv));
371 evsignal_process(base);
375 res = select(fd_count,
376 (
struct fd_set*)win32op->readset_out,
377 (
struct fd_set*)win32op->writeset_out,
378 (
struct fd_set*)win32op->exset_out, tv);
380 event_debug((
"%s: select returned %d", __func__, res));
383 evsignal_process(base);
385 }
else if (base->sig.evsignal_caught) {
386 evsignal_process(base);
389 if (win32op->readset_out->fd_count) {
390 i = rand() % win32op->readset_out->fd_count;
391 for (j=0; j<win32op->readset_out->fd_count; ++j) {
392 if (++i >= win32op->readset_out->fd_count)
394 s = win32op->readset_out->fd_array[
i];
395 if ((ent = get_event_entry(win32op, s, 0)) && ent->read_event)
396 event_active(ent->read_event, EV_READ, 1);
399 if (win32op->exset_out->fd_count) {
400 i = rand() % win32op->exset_out->fd_count;
401 for (j=0; j<win32op->exset_out->fd_count; ++j) {
402 if (++i >= win32op->exset_out->fd_count)
404 s = win32op->exset_out->fd_array[
i];
405 if ((ent = get_event_entry(win32op, s, 0)) && ent->read_event)
406 event_active(ent->read_event, EV_READ, 1);
409 if (win32op->writeset_out->fd_count) {
410 i = rand() % win32op->writeset_out->fd_count;
411 for (j=0; j<win32op->writeset_out->fd_count; ++j) {
412 if (++i >= win32op->exset_out->fd_count)
414 s = win32op->writeset_out->fd_array[
i];
415 if ((ent = get_event_entry(win32op, s, 0)) && ent->write_event)
416 event_active(ent->write_event, EV_WRITE, 1);
425 win32_dealloc(
struct event_base *_base,
void *arg)
427 struct win32op *win32op = arg;
429 evsignal_dealloc(_base);
430 if (win32op->readset_in)
431 free(win32op->readset_in);
432 if (win32op->writeset_in)
433 free(win32op->writeset_in);
434 if (win32op->readset_out)
435 free(win32op->readset_out);
436 if (win32op->writeset_out)
437 free(win32op->writeset_out);
438 if (win32op->exset_out)
439 free(win32op->exset_out);
442 memset(win32op, 0,
sizeof(win32op));
448 signal_handler(
int sig)
460 TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
461 if((
int)signal(EVENT_SIGNAL(ev), signal_handler) == -1)
473 TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
474 ncalls = evsigcaught[EVENT_SIGNAL(ev)];
476 if (!(ev->ev_events & EV_PERSIST))
478 event_active(ev, EV_SIGNAL, ncalls);
482 memset(evsigcaught, 0,
sizeof(evsigcaught));