eloop_win.c revision 209139
1209139Srpaulo/* 2209139Srpaulo * Event loop based on Windows events and WaitForMultipleObjects 3209139Srpaulo * Copyright (c) 2002-2006, Jouni Malinen <j@w1.fi> 4209139Srpaulo * 5209139Srpaulo * This program is free software; you can redistribute it and/or modify 6209139Srpaulo * it under the terms of the GNU General Public License version 2 as 7209139Srpaulo * published by the Free Software Foundation. 8209139Srpaulo * 9209139Srpaulo * Alternatively, this software may be distributed under the terms of BSD 10209139Srpaulo * license. 11209139Srpaulo * 12209139Srpaulo * See README and COPYING for more details. 13209139Srpaulo */ 14209139Srpaulo 15209139Srpaulo#include "includes.h" 16209139Srpaulo#include <winsock2.h> 17209139Srpaulo 18209139Srpaulo#include "common.h" 19209139Srpaulo#include "eloop.h" 20209139Srpaulo 21209139Srpaulo 22209139Srpaulostruct eloop_sock { 23209139Srpaulo int sock; 24209139Srpaulo void *eloop_data; 25209139Srpaulo void *user_data; 26209139Srpaulo eloop_sock_handler handler; 27209139Srpaulo WSAEVENT event; 28209139Srpaulo}; 29209139Srpaulo 30209139Srpaulostruct eloop_event { 31209139Srpaulo void *eloop_data; 32209139Srpaulo void *user_data; 33209139Srpaulo eloop_event_handler handler; 34209139Srpaulo HANDLE event; 35209139Srpaulo}; 36209139Srpaulo 37209139Srpaulostruct eloop_timeout { 38209139Srpaulo struct os_time time; 39209139Srpaulo void *eloop_data; 40209139Srpaulo void *user_data; 41209139Srpaulo eloop_timeout_handler handler; 42209139Srpaulo struct eloop_timeout *next; 43209139Srpaulo}; 44209139Srpaulo 45209139Srpaulostruct eloop_signal { 46209139Srpaulo int sig; 47209139Srpaulo void *user_data; 48209139Srpaulo eloop_signal_handler handler; 49209139Srpaulo int signaled; 50209139Srpaulo}; 51209139Srpaulo 52209139Srpaulostruct eloop_data { 53209139Srpaulo void *user_data; 54209139Srpaulo 55209139Srpaulo int max_sock; 56209139Srpaulo size_t reader_count; 57209139Srpaulo struct eloop_sock *readers; 58209139Srpaulo 59209139Srpaulo size_t event_count; 60209139Srpaulo struct eloop_event *events; 61209139Srpaulo 62209139Srpaulo struct eloop_timeout *timeout; 63209139Srpaulo 64209139Srpaulo int signal_count; 65209139Srpaulo struct eloop_signal *signals; 66209139Srpaulo int signaled; 67209139Srpaulo int pending_terminate; 68209139Srpaulo 69209139Srpaulo int terminate; 70209139Srpaulo int reader_table_changed; 71209139Srpaulo 72209139Srpaulo struct eloop_signal term_signal; 73209139Srpaulo HANDLE term_event; 74209139Srpaulo 75209139Srpaulo HANDLE *handles; 76209139Srpaulo size_t num_handles; 77209139Srpaulo}; 78209139Srpaulo 79209139Srpaulostatic struct eloop_data eloop; 80209139Srpaulo 81209139Srpaulo 82209139Srpauloint eloop_init(void *user_data) 83209139Srpaulo{ 84209139Srpaulo os_memset(&eloop, 0, sizeof(eloop)); 85209139Srpaulo eloop.user_data = user_data; 86209139Srpaulo eloop.num_handles = 1; 87209139Srpaulo eloop.handles = os_malloc(eloop.num_handles * 88209139Srpaulo sizeof(eloop.handles[0])); 89209139Srpaulo if (eloop.handles == NULL) 90209139Srpaulo return -1; 91209139Srpaulo 92209139Srpaulo eloop.term_event = CreateEvent(NULL, FALSE, FALSE, NULL); 93209139Srpaulo if (eloop.term_event == NULL) { 94209139Srpaulo printf("CreateEvent() failed: %d\n", 95209139Srpaulo (int) GetLastError()); 96209139Srpaulo os_free(eloop.handles); 97209139Srpaulo return -1; 98209139Srpaulo } 99209139Srpaulo 100209139Srpaulo return 0; 101209139Srpaulo} 102209139Srpaulo 103209139Srpaulo 104209139Srpaulostatic int eloop_prepare_handles(void) 105209139Srpaulo{ 106209139Srpaulo HANDLE *n; 107209139Srpaulo 108209139Srpaulo if (eloop.num_handles > eloop.reader_count + eloop.event_count + 8) 109209139Srpaulo return 0; 110209139Srpaulo n = os_realloc(eloop.handles, 111209139Srpaulo eloop.num_handles * 2 * sizeof(eloop.handles[0])); 112209139Srpaulo if (n == NULL) 113209139Srpaulo return -1; 114209139Srpaulo eloop.handles = n; 115209139Srpaulo eloop.num_handles *= 2; 116209139Srpaulo return 0; 117209139Srpaulo} 118209139Srpaulo 119209139Srpaulo 120209139Srpauloint eloop_register_read_sock(int sock, eloop_sock_handler handler, 121209139Srpaulo void *eloop_data, void *user_data) 122209139Srpaulo{ 123209139Srpaulo WSAEVENT event; 124209139Srpaulo struct eloop_sock *tmp; 125209139Srpaulo 126209139Srpaulo if (eloop_prepare_handles()) 127209139Srpaulo return -1; 128209139Srpaulo 129209139Srpaulo event = WSACreateEvent(); 130209139Srpaulo if (event == WSA_INVALID_EVENT) { 131209139Srpaulo printf("WSACreateEvent() failed: %d\n", WSAGetLastError()); 132209139Srpaulo return -1; 133209139Srpaulo } 134209139Srpaulo 135209139Srpaulo if (WSAEventSelect(sock, event, FD_READ)) { 136209139Srpaulo printf("WSAEventSelect() failed: %d\n", WSAGetLastError()); 137209139Srpaulo WSACloseEvent(event); 138209139Srpaulo return -1; 139209139Srpaulo } 140209139Srpaulo tmp = os_realloc(eloop.readers, 141209139Srpaulo (eloop.reader_count + 1) * sizeof(struct eloop_sock)); 142209139Srpaulo if (tmp == NULL) { 143209139Srpaulo WSAEventSelect(sock, event, 0); 144209139Srpaulo WSACloseEvent(event); 145209139Srpaulo return -1; 146209139Srpaulo } 147209139Srpaulo 148209139Srpaulo tmp[eloop.reader_count].sock = sock; 149209139Srpaulo tmp[eloop.reader_count].eloop_data = eloop_data; 150209139Srpaulo tmp[eloop.reader_count].user_data = user_data; 151209139Srpaulo tmp[eloop.reader_count].handler = handler; 152209139Srpaulo tmp[eloop.reader_count].event = event; 153209139Srpaulo eloop.reader_count++; 154209139Srpaulo eloop.readers = tmp; 155209139Srpaulo if (sock > eloop.max_sock) 156209139Srpaulo eloop.max_sock = sock; 157209139Srpaulo eloop.reader_table_changed = 1; 158209139Srpaulo 159209139Srpaulo return 0; 160209139Srpaulo} 161209139Srpaulo 162209139Srpaulo 163209139Srpaulovoid eloop_unregister_read_sock(int sock) 164209139Srpaulo{ 165209139Srpaulo size_t i; 166209139Srpaulo 167209139Srpaulo if (eloop.readers == NULL || eloop.reader_count == 0) 168209139Srpaulo return; 169209139Srpaulo 170209139Srpaulo for (i = 0; i < eloop.reader_count; i++) { 171209139Srpaulo if (eloop.readers[i].sock == sock) 172209139Srpaulo break; 173209139Srpaulo } 174209139Srpaulo if (i == eloop.reader_count) 175209139Srpaulo return; 176209139Srpaulo 177209139Srpaulo WSAEventSelect(eloop.readers[i].sock, eloop.readers[i].event, 0); 178209139Srpaulo WSACloseEvent(eloop.readers[i].event); 179209139Srpaulo 180209139Srpaulo if (i != eloop.reader_count - 1) { 181209139Srpaulo os_memmove(&eloop.readers[i], &eloop.readers[i + 1], 182209139Srpaulo (eloop.reader_count - i - 1) * 183209139Srpaulo sizeof(struct eloop_sock)); 184209139Srpaulo } 185209139Srpaulo eloop.reader_count--; 186209139Srpaulo eloop.reader_table_changed = 1; 187209139Srpaulo} 188209139Srpaulo 189209139Srpaulo 190209139Srpauloint eloop_register_event(void *event, size_t event_size, 191209139Srpaulo eloop_event_handler handler, 192209139Srpaulo void *eloop_data, void *user_data) 193209139Srpaulo{ 194209139Srpaulo struct eloop_event *tmp; 195209139Srpaulo HANDLE h = event; 196209139Srpaulo 197209139Srpaulo if (event_size != sizeof(HANDLE) || h == INVALID_HANDLE_VALUE) 198209139Srpaulo return -1; 199209139Srpaulo 200209139Srpaulo if (eloop_prepare_handles()) 201209139Srpaulo return -1; 202209139Srpaulo 203209139Srpaulo tmp = os_realloc(eloop.events, 204209139Srpaulo (eloop.event_count + 1) * sizeof(struct eloop_event)); 205209139Srpaulo if (tmp == NULL) 206209139Srpaulo return -1; 207209139Srpaulo 208209139Srpaulo tmp[eloop.event_count].eloop_data = eloop_data; 209209139Srpaulo tmp[eloop.event_count].user_data = user_data; 210209139Srpaulo tmp[eloop.event_count].handler = handler; 211209139Srpaulo tmp[eloop.event_count].event = h; 212209139Srpaulo eloop.event_count++; 213209139Srpaulo eloop.events = tmp; 214209139Srpaulo 215209139Srpaulo return 0; 216209139Srpaulo} 217209139Srpaulo 218209139Srpaulo 219209139Srpaulovoid eloop_unregister_event(void *event, size_t event_size) 220209139Srpaulo{ 221209139Srpaulo size_t i; 222209139Srpaulo HANDLE h = event; 223209139Srpaulo 224209139Srpaulo if (eloop.events == NULL || eloop.event_count == 0 || 225209139Srpaulo event_size != sizeof(HANDLE)) 226209139Srpaulo return; 227209139Srpaulo 228209139Srpaulo for (i = 0; i < eloop.event_count; i++) { 229209139Srpaulo if (eloop.events[i].event == h) 230209139Srpaulo break; 231209139Srpaulo } 232209139Srpaulo if (i == eloop.event_count) 233209139Srpaulo return; 234209139Srpaulo 235209139Srpaulo if (i != eloop.event_count - 1) { 236209139Srpaulo os_memmove(&eloop.events[i], &eloop.events[i + 1], 237209139Srpaulo (eloop.event_count - i - 1) * 238209139Srpaulo sizeof(struct eloop_event)); 239209139Srpaulo } 240209139Srpaulo eloop.event_count--; 241209139Srpaulo} 242209139Srpaulo 243209139Srpaulo 244209139Srpauloint eloop_register_timeout(unsigned int secs, unsigned int usecs, 245209139Srpaulo eloop_timeout_handler handler, 246209139Srpaulo void *eloop_data, void *user_data) 247209139Srpaulo{ 248209139Srpaulo struct eloop_timeout *timeout, *tmp, *prev; 249209139Srpaulo 250209139Srpaulo timeout = os_malloc(sizeof(*timeout)); 251209139Srpaulo if (timeout == NULL) 252209139Srpaulo return -1; 253209139Srpaulo os_get_time(&timeout->time); 254209139Srpaulo timeout->time.sec += secs; 255209139Srpaulo timeout->time.usec += usecs; 256209139Srpaulo while (timeout->time.usec >= 1000000) { 257209139Srpaulo timeout->time.sec++; 258209139Srpaulo timeout->time.usec -= 1000000; 259209139Srpaulo } 260209139Srpaulo timeout->eloop_data = eloop_data; 261209139Srpaulo timeout->user_data = user_data; 262209139Srpaulo timeout->handler = handler; 263209139Srpaulo timeout->next = NULL; 264209139Srpaulo 265209139Srpaulo if (eloop.timeout == NULL) { 266209139Srpaulo eloop.timeout = timeout; 267209139Srpaulo return 0; 268209139Srpaulo } 269209139Srpaulo 270209139Srpaulo prev = NULL; 271209139Srpaulo tmp = eloop.timeout; 272209139Srpaulo while (tmp != NULL) { 273209139Srpaulo if (os_time_before(&timeout->time, &tmp->time)) 274209139Srpaulo break; 275209139Srpaulo prev = tmp; 276209139Srpaulo tmp = tmp->next; 277209139Srpaulo } 278209139Srpaulo 279209139Srpaulo if (prev == NULL) { 280209139Srpaulo timeout->next = eloop.timeout; 281209139Srpaulo eloop.timeout = timeout; 282209139Srpaulo } else { 283209139Srpaulo timeout->next = prev->next; 284209139Srpaulo prev->next = timeout; 285209139Srpaulo } 286209139Srpaulo 287209139Srpaulo return 0; 288209139Srpaulo} 289209139Srpaulo 290209139Srpaulo 291209139Srpauloint eloop_cancel_timeout(eloop_timeout_handler handler, 292209139Srpaulo void *eloop_data, void *user_data) 293209139Srpaulo{ 294209139Srpaulo struct eloop_timeout *timeout, *prev, *next; 295209139Srpaulo int removed = 0; 296209139Srpaulo 297209139Srpaulo prev = NULL; 298209139Srpaulo timeout = eloop.timeout; 299209139Srpaulo while (timeout != NULL) { 300209139Srpaulo next = timeout->next; 301209139Srpaulo 302209139Srpaulo if (timeout->handler == handler && 303209139Srpaulo (timeout->eloop_data == eloop_data || 304209139Srpaulo eloop_data == ELOOP_ALL_CTX) && 305209139Srpaulo (timeout->user_data == user_data || 306209139Srpaulo user_data == ELOOP_ALL_CTX)) { 307209139Srpaulo if (prev == NULL) 308209139Srpaulo eloop.timeout = next; 309209139Srpaulo else 310209139Srpaulo prev->next = next; 311209139Srpaulo os_free(timeout); 312209139Srpaulo removed++; 313209139Srpaulo } else 314209139Srpaulo prev = timeout; 315209139Srpaulo 316209139Srpaulo timeout = next; 317209139Srpaulo } 318209139Srpaulo 319209139Srpaulo return removed; 320209139Srpaulo} 321209139Srpaulo 322209139Srpaulo 323209139Srpauloint eloop_is_timeout_registered(eloop_timeout_handler handler, 324209139Srpaulo void *eloop_data, void *user_data) 325209139Srpaulo{ 326209139Srpaulo struct eloop_timeout *tmp; 327209139Srpaulo 328209139Srpaulo tmp = eloop.timeout; 329209139Srpaulo while (tmp != NULL) { 330209139Srpaulo if (tmp->handler == handler && 331209139Srpaulo tmp->eloop_data == eloop_data && 332209139Srpaulo tmp->user_data == user_data) 333209139Srpaulo return 1; 334209139Srpaulo 335209139Srpaulo tmp = tmp->next; 336209139Srpaulo } 337209139Srpaulo 338209139Srpaulo return 0; 339209139Srpaulo} 340209139Srpaulo 341209139Srpaulo 342209139Srpaulo/* TODO: replace with suitable signal handler */ 343209139Srpaulo#if 0 344209139Srpaulostatic void eloop_handle_signal(int sig) 345209139Srpaulo{ 346209139Srpaulo int i; 347209139Srpaulo 348209139Srpaulo eloop.signaled++; 349209139Srpaulo for (i = 0; i < eloop.signal_count; i++) { 350209139Srpaulo if (eloop.signals[i].sig == sig) { 351209139Srpaulo eloop.signals[i].signaled++; 352209139Srpaulo break; 353209139Srpaulo } 354209139Srpaulo } 355209139Srpaulo} 356209139Srpaulo#endif 357209139Srpaulo 358209139Srpaulo 359209139Srpaulostatic void eloop_process_pending_signals(void) 360209139Srpaulo{ 361209139Srpaulo int i; 362209139Srpaulo 363209139Srpaulo if (eloop.signaled == 0) 364209139Srpaulo return; 365209139Srpaulo eloop.signaled = 0; 366209139Srpaulo 367209139Srpaulo if (eloop.pending_terminate) { 368209139Srpaulo eloop.pending_terminate = 0; 369209139Srpaulo } 370209139Srpaulo 371209139Srpaulo for (i = 0; i < eloop.signal_count; i++) { 372209139Srpaulo if (eloop.signals[i].signaled) { 373209139Srpaulo eloop.signals[i].signaled = 0; 374209139Srpaulo eloop.signals[i].handler(eloop.signals[i].sig, 375209139Srpaulo eloop.user_data, 376209139Srpaulo eloop.signals[i].user_data); 377209139Srpaulo } 378209139Srpaulo } 379209139Srpaulo 380209139Srpaulo if (eloop.term_signal.signaled) { 381209139Srpaulo eloop.term_signal.signaled = 0; 382209139Srpaulo eloop.term_signal.handler(eloop.term_signal.sig, 383209139Srpaulo eloop.user_data, 384209139Srpaulo eloop.term_signal.user_data); 385209139Srpaulo } 386209139Srpaulo} 387209139Srpaulo 388209139Srpaulo 389209139Srpauloint eloop_register_signal(int sig, eloop_signal_handler handler, 390209139Srpaulo void *user_data) 391209139Srpaulo{ 392209139Srpaulo struct eloop_signal *tmp; 393209139Srpaulo 394209139Srpaulo tmp = os_realloc(eloop.signals, 395209139Srpaulo (eloop.signal_count + 1) * 396209139Srpaulo sizeof(struct eloop_signal)); 397209139Srpaulo if (tmp == NULL) 398209139Srpaulo return -1; 399209139Srpaulo 400209139Srpaulo tmp[eloop.signal_count].sig = sig; 401209139Srpaulo tmp[eloop.signal_count].user_data = user_data; 402209139Srpaulo tmp[eloop.signal_count].handler = handler; 403209139Srpaulo tmp[eloop.signal_count].signaled = 0; 404209139Srpaulo eloop.signal_count++; 405209139Srpaulo eloop.signals = tmp; 406209139Srpaulo 407209139Srpaulo /* TODO: register signal handler */ 408209139Srpaulo 409209139Srpaulo return 0; 410209139Srpaulo} 411209139Srpaulo 412209139Srpaulo 413209139Srpaulo#ifndef _WIN32_WCE 414209139Srpaulostatic BOOL eloop_handle_console_ctrl(DWORD type) 415209139Srpaulo{ 416209139Srpaulo switch (type) { 417209139Srpaulo case CTRL_C_EVENT: 418209139Srpaulo case CTRL_BREAK_EVENT: 419209139Srpaulo eloop.signaled++; 420209139Srpaulo eloop.term_signal.signaled++; 421209139Srpaulo SetEvent(eloop.term_event); 422209139Srpaulo return TRUE; 423209139Srpaulo default: 424209139Srpaulo return FALSE; 425209139Srpaulo } 426209139Srpaulo} 427209139Srpaulo#endif /* _WIN32_WCE */ 428209139Srpaulo 429209139Srpaulo 430209139Srpauloint eloop_register_signal_terminate(eloop_signal_handler handler, 431209139Srpaulo void *user_data) 432209139Srpaulo{ 433209139Srpaulo#ifndef _WIN32_WCE 434209139Srpaulo if (SetConsoleCtrlHandler((PHANDLER_ROUTINE) eloop_handle_console_ctrl, 435209139Srpaulo TRUE) == 0) { 436209139Srpaulo printf("SetConsoleCtrlHandler() failed: %d\n", 437209139Srpaulo (int) GetLastError()); 438209139Srpaulo return -1; 439209139Srpaulo } 440209139Srpaulo#endif /* _WIN32_WCE */ 441209139Srpaulo 442209139Srpaulo eloop.term_signal.handler = handler; 443209139Srpaulo eloop.term_signal.user_data = user_data; 444209139Srpaulo 445209139Srpaulo return 0; 446209139Srpaulo} 447209139Srpaulo 448209139Srpaulo 449209139Srpauloint eloop_register_signal_reconfig(eloop_signal_handler handler, 450209139Srpaulo void *user_data) 451209139Srpaulo{ 452209139Srpaulo /* TODO */ 453209139Srpaulo return 0; 454209139Srpaulo} 455209139Srpaulo 456209139Srpaulo 457209139Srpaulovoid eloop_run(void) 458209139Srpaulo{ 459209139Srpaulo struct os_time tv, now; 460209139Srpaulo DWORD count, ret, timeout, err; 461209139Srpaulo size_t i; 462209139Srpaulo 463209139Srpaulo while (!eloop.terminate && 464209139Srpaulo (eloop.timeout || eloop.reader_count > 0 || 465209139Srpaulo eloop.event_count > 0)) { 466209139Srpaulo tv.sec = tv.usec = 0; 467209139Srpaulo if (eloop.timeout) { 468209139Srpaulo os_get_time(&now); 469209139Srpaulo if (os_time_before(&now, &eloop.timeout->time)) 470209139Srpaulo os_time_sub(&eloop.timeout->time, &now, &tv); 471209139Srpaulo } 472209139Srpaulo 473209139Srpaulo count = 0; 474209139Srpaulo for (i = 0; i < eloop.event_count; i++) 475209139Srpaulo eloop.handles[count++] = eloop.events[i].event; 476209139Srpaulo 477209139Srpaulo for (i = 0; i < eloop.reader_count; i++) 478209139Srpaulo eloop.handles[count++] = eloop.readers[i].event; 479209139Srpaulo 480209139Srpaulo if (eloop.term_event) 481209139Srpaulo eloop.handles[count++] = eloop.term_event; 482209139Srpaulo 483209139Srpaulo if (eloop.timeout) 484209139Srpaulo timeout = tv.sec * 1000 + tv.usec / 1000; 485209139Srpaulo else 486209139Srpaulo timeout = INFINITE; 487209139Srpaulo 488209139Srpaulo if (count > MAXIMUM_WAIT_OBJECTS) { 489209139Srpaulo printf("WaitForMultipleObjects: Too many events: " 490209139Srpaulo "%d > %d (ignoring extra events)\n", 491209139Srpaulo (int) count, MAXIMUM_WAIT_OBJECTS); 492209139Srpaulo count = MAXIMUM_WAIT_OBJECTS; 493209139Srpaulo } 494209139Srpaulo#ifdef _WIN32_WCE 495209139Srpaulo ret = WaitForMultipleObjects(count, eloop.handles, FALSE, 496209139Srpaulo timeout); 497209139Srpaulo#else /* _WIN32_WCE */ 498209139Srpaulo ret = WaitForMultipleObjectsEx(count, eloop.handles, FALSE, 499209139Srpaulo timeout, TRUE); 500209139Srpaulo#endif /* _WIN32_WCE */ 501209139Srpaulo err = GetLastError(); 502209139Srpaulo 503209139Srpaulo eloop_process_pending_signals(); 504209139Srpaulo 505209139Srpaulo /* check if some registered timeouts have occurred */ 506209139Srpaulo if (eloop.timeout) { 507209139Srpaulo struct eloop_timeout *tmp; 508209139Srpaulo 509209139Srpaulo os_get_time(&now); 510209139Srpaulo if (!os_time_before(&now, &eloop.timeout->time)) { 511209139Srpaulo tmp = eloop.timeout; 512209139Srpaulo eloop.timeout = eloop.timeout->next; 513209139Srpaulo tmp->handler(tmp->eloop_data, 514209139Srpaulo tmp->user_data); 515209139Srpaulo os_free(tmp); 516209139Srpaulo } 517209139Srpaulo 518209139Srpaulo } 519209139Srpaulo 520209139Srpaulo if (ret == WAIT_FAILED) { 521209139Srpaulo printf("WaitForMultipleObjects(count=%d) failed: %d\n", 522209139Srpaulo (int) count, (int) err); 523209139Srpaulo os_sleep(1, 0); 524209139Srpaulo continue; 525209139Srpaulo } 526209139Srpaulo 527209139Srpaulo#ifndef _WIN32_WCE 528209139Srpaulo if (ret == WAIT_IO_COMPLETION) 529209139Srpaulo continue; 530209139Srpaulo#endif /* _WIN32_WCE */ 531209139Srpaulo 532209139Srpaulo if (ret == WAIT_TIMEOUT) 533209139Srpaulo continue; 534209139Srpaulo 535209139Srpaulo while (ret >= WAIT_OBJECT_0 && 536209139Srpaulo ret < WAIT_OBJECT_0 + eloop.event_count) { 537209139Srpaulo eloop.events[ret].handler( 538209139Srpaulo eloop.events[ret].eloop_data, 539209139Srpaulo eloop.events[ret].user_data); 540209139Srpaulo ret = WaitForMultipleObjects(eloop.event_count, 541209139Srpaulo eloop.handles, FALSE, 0); 542209139Srpaulo } 543209139Srpaulo 544209139Srpaulo eloop.reader_table_changed = 0; 545209139Srpaulo for (i = 0; i < eloop.reader_count; i++) { 546209139Srpaulo WSANETWORKEVENTS events; 547209139Srpaulo if (WSAEnumNetworkEvents(eloop.readers[i].sock, 548209139Srpaulo eloop.readers[i].event, 549209139Srpaulo &events) == 0 && 550209139Srpaulo (events.lNetworkEvents & FD_READ)) { 551209139Srpaulo eloop.readers[i].handler( 552209139Srpaulo eloop.readers[i].sock, 553209139Srpaulo eloop.readers[i].eloop_data, 554209139Srpaulo eloop.readers[i].user_data); 555209139Srpaulo if (eloop.reader_table_changed) 556209139Srpaulo break; 557209139Srpaulo } 558209139Srpaulo } 559209139Srpaulo } 560209139Srpaulo} 561209139Srpaulo 562209139Srpaulo 563209139Srpaulovoid eloop_terminate(void) 564209139Srpaulo{ 565209139Srpaulo eloop.terminate = 1; 566209139Srpaulo SetEvent(eloop.term_event); 567209139Srpaulo} 568209139Srpaulo 569209139Srpaulo 570209139Srpaulovoid eloop_destroy(void) 571209139Srpaulo{ 572209139Srpaulo struct eloop_timeout *timeout, *prev; 573209139Srpaulo 574209139Srpaulo timeout = eloop.timeout; 575209139Srpaulo while (timeout != NULL) { 576209139Srpaulo prev = timeout; 577209139Srpaulo timeout = timeout->next; 578209139Srpaulo os_free(prev); 579209139Srpaulo } 580209139Srpaulo os_free(eloop.readers); 581209139Srpaulo os_free(eloop.signals); 582209139Srpaulo if (eloop.term_event) 583209139Srpaulo CloseHandle(eloop.term_event); 584209139Srpaulo os_free(eloop.handles); 585209139Srpaulo eloop.handles = NULL; 586209139Srpaulo os_free(eloop.events); 587209139Srpaulo eloop.events = NULL; 588209139Srpaulo} 589209139Srpaulo 590209139Srpaulo 591209139Srpauloint eloop_terminated(void) 592209139Srpaulo{ 593209139Srpaulo return eloop.terminate; 594209139Srpaulo} 595209139Srpaulo 596209139Srpaulo 597209139Srpaulovoid eloop_wait_for_read_sock(int sock) 598209139Srpaulo{ 599209139Srpaulo WSAEVENT event; 600209139Srpaulo 601209139Srpaulo event = WSACreateEvent(); 602209139Srpaulo if (event == WSA_INVALID_EVENT) { 603209139Srpaulo printf("WSACreateEvent() failed: %d\n", WSAGetLastError()); 604209139Srpaulo return; 605209139Srpaulo } 606209139Srpaulo 607209139Srpaulo if (WSAEventSelect(sock, event, FD_READ)) { 608209139Srpaulo printf("WSAEventSelect() failed: %d\n", WSAGetLastError()); 609209139Srpaulo WSACloseEvent(event); 610209139Srpaulo return ; 611209139Srpaulo } 612209139Srpaulo 613209139Srpaulo WaitForSingleObject(event, INFINITE); 614209139Srpaulo WSAEventSelect(sock, event, 0); 615209139Srpaulo WSACloseEvent(event); 616209139Srpaulo} 617209139Srpaulo 618209139Srpaulo 619209139Srpaulovoid * eloop_get_user_data(void) 620209139Srpaulo{ 621209139Srpaulo return eloop.user_data; 622209139Srpaulo} 623