-void event_flush_output(void) {
- for splay_each(io_t, io, &io_tree)
- if(FD_ISSET(io->fd, &writefds))
- io->cb(io->data, IO_WRITE);
+ WSAEVENT* events = xmalloc(event_count * sizeof(*events));
+ DWORD event_index = 0;
+ for splay_each(io_t, io, &io_tree) {
+ events[event_index] = io->event;
+ event_index++;
+ }
+
+ DWORD result = WSAWaitForMultipleEvents(event_count, events, FALSE, timeout_ms, FALSE);
+
+ WSAEVENT event;
+ if (result >= WSA_WAIT_EVENT_0 && result < WSA_WAIT_EVENT_0 + event_count)
+ event = events[result - WSA_WAIT_EVENT_0];
+ free(events);
+ if (result == WSA_WAIT_TIMEOUT)
+ continue;
+ if (result < WSA_WAIT_EVENT_0 || result >= WSA_WAIT_EVENT_0 + event_count)
+ return false;
+
+ io_t *io = splay_search(&io_tree, &((io_t){.event = event}));
+ if (!io)
+ abort();
+
+ if (io->fd == -1) {
+ io->cb(io->data, 0);
+ } else {
+ WSANETWORKEVENTS network_events;
+ if (WSAEnumNetworkEvents(io->fd, io->event, &network_events) != 0)
+ return false;
+ if (network_events.lNetworkEvents & WRITE_EVENTS)
+ io->cb(io->data, IO_WRITE);
+ if (network_events.lNetworkEvents & READ_EVENTS)
+ io->cb(io->data, IO_READ);
+ }
+ }
+#endif
+
+ return true;