blob: e87d82ac97250bec2a9b0b7fba742be1d6e31199 [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
2 * Event loop based on Windows events and WaitForMultipleObjects
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08003 * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004 *
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07007 */
8
9#include "includes.h"
10#include <winsock2.h>
11
12#include "common.h"
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -080013#include "list.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070014#include "eloop.h"
15
16
17struct eloop_sock {
18 int sock;
19 void *eloop_data;
20 void *user_data;
21 eloop_sock_handler handler;
22 WSAEVENT event;
23};
24
25struct eloop_event {
26 void *eloop_data;
27 void *user_data;
28 eloop_event_handler handler;
29 HANDLE event;
30};
31
32struct eloop_timeout {
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -080033 struct dl_list list;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070034 struct os_time time;
35 void *eloop_data;
36 void *user_data;
37 eloop_timeout_handler handler;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070038};
39
40struct eloop_signal {
41 int sig;
42 void *user_data;
43 eloop_signal_handler handler;
44 int signaled;
45};
46
47struct eloop_data {
48 int max_sock;
49 size_t reader_count;
50 struct eloop_sock *readers;
51
52 size_t event_count;
53 struct eloop_event *events;
54
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -080055 struct dl_list timeout;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070056
57 int signal_count;
58 struct eloop_signal *signals;
59 int signaled;
60 int pending_terminate;
61
62 int terminate;
63 int reader_table_changed;
64
65 struct eloop_signal term_signal;
66 HANDLE term_event;
67
68 HANDLE *handles;
69 size_t num_handles;
70};
71
72static struct eloop_data eloop;
73
74
75int eloop_init(void)
76{
77 os_memset(&eloop, 0, sizeof(eloop));
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -080078 dl_list_init(&eloop.timeout);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070079 eloop.num_handles = 1;
80 eloop.handles = os_malloc(eloop.num_handles *
81 sizeof(eloop.handles[0]));
82 if (eloop.handles == NULL)
83 return -1;
84
85 eloop.term_event = CreateEvent(NULL, FALSE, FALSE, NULL);
86 if (eloop.term_event == NULL) {
87 printf("CreateEvent() failed: %d\n",
88 (int) GetLastError());
89 os_free(eloop.handles);
90 return -1;
91 }
92
93 return 0;
94}
95
96
97static int eloop_prepare_handles(void)
98{
99 HANDLE *n;
100
101 if (eloop.num_handles > eloop.reader_count + eloop.event_count + 8)
102 return 0;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700103 n = os_realloc_array(eloop.handles, eloop.num_handles * 2,
104 sizeof(eloop.handles[0]));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700105 if (n == NULL)
106 return -1;
107 eloop.handles = n;
108 eloop.num_handles *= 2;
109 return 0;
110}
111
112
113int eloop_register_read_sock(int sock, eloop_sock_handler handler,
114 void *eloop_data, void *user_data)
115{
116 WSAEVENT event;
117 struct eloop_sock *tmp;
118
119 if (eloop_prepare_handles())
120 return -1;
121
122 event = WSACreateEvent();
123 if (event == WSA_INVALID_EVENT) {
124 printf("WSACreateEvent() failed: %d\n", WSAGetLastError());
125 return -1;
126 }
127
128 if (WSAEventSelect(sock, event, FD_READ)) {
129 printf("WSAEventSelect() failed: %d\n", WSAGetLastError());
130 WSACloseEvent(event);
131 return -1;
132 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700133 tmp = os_realloc_array(eloop.readers, eloop.reader_count + 1,
134 sizeof(struct eloop_sock));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700135 if (tmp == NULL) {
136 WSAEventSelect(sock, event, 0);
137 WSACloseEvent(event);
138 return -1;
139 }
140
141 tmp[eloop.reader_count].sock = sock;
142 tmp[eloop.reader_count].eloop_data = eloop_data;
143 tmp[eloop.reader_count].user_data = user_data;
144 tmp[eloop.reader_count].handler = handler;
145 tmp[eloop.reader_count].event = event;
146 eloop.reader_count++;
147 eloop.readers = tmp;
148 if (sock > eloop.max_sock)
149 eloop.max_sock = sock;
150 eloop.reader_table_changed = 1;
151
152 return 0;
153}
154
155
156void eloop_unregister_read_sock(int sock)
157{
158 size_t i;
159
160 if (eloop.readers == NULL || eloop.reader_count == 0)
161 return;
162
163 for (i = 0; i < eloop.reader_count; i++) {
164 if (eloop.readers[i].sock == sock)
165 break;
166 }
167 if (i == eloop.reader_count)
168 return;
169
170 WSAEventSelect(eloop.readers[i].sock, eloop.readers[i].event, 0);
171 WSACloseEvent(eloop.readers[i].event);
172
173 if (i != eloop.reader_count - 1) {
174 os_memmove(&eloop.readers[i], &eloop.readers[i + 1],
175 (eloop.reader_count - i - 1) *
176 sizeof(struct eloop_sock));
177 }
178 eloop.reader_count--;
179 eloop.reader_table_changed = 1;
180}
181
182
183int eloop_register_event(void *event, size_t event_size,
184 eloop_event_handler handler,
185 void *eloop_data, void *user_data)
186{
187 struct eloop_event *tmp;
188 HANDLE h = event;
189
190 if (event_size != sizeof(HANDLE) || h == INVALID_HANDLE_VALUE)
191 return -1;
192
193 if (eloop_prepare_handles())
194 return -1;
195
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700196 tmp = os_realloc_array(eloop.events, eloop.event_count + 1,
197 sizeof(struct eloop_event));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700198 if (tmp == NULL)
199 return -1;
200
201 tmp[eloop.event_count].eloop_data = eloop_data;
202 tmp[eloop.event_count].user_data = user_data;
203 tmp[eloop.event_count].handler = handler;
204 tmp[eloop.event_count].event = h;
205 eloop.event_count++;
206 eloop.events = tmp;
207
208 return 0;
209}
210
211
212void eloop_unregister_event(void *event, size_t event_size)
213{
214 size_t i;
215 HANDLE h = event;
216
217 if (eloop.events == NULL || eloop.event_count == 0 ||
218 event_size != sizeof(HANDLE))
219 return;
220
221 for (i = 0; i < eloop.event_count; i++) {
222 if (eloop.events[i].event == h)
223 break;
224 }
225 if (i == eloop.event_count)
226 return;
227
228 if (i != eloop.event_count - 1) {
229 os_memmove(&eloop.events[i], &eloop.events[i + 1],
230 (eloop.event_count - i - 1) *
231 sizeof(struct eloop_event));
232 }
233 eloop.event_count--;
234}
235
236
237int eloop_register_timeout(unsigned int secs, unsigned int usecs,
238 eloop_timeout_handler handler,
239 void *eloop_data, void *user_data)
240{
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800241 struct eloop_timeout *timeout, *tmp;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700242 os_time_t now_sec;
243
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800244 timeout = os_zalloc(sizeof(*timeout));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700245 if (timeout == NULL)
246 return -1;
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800247 if (os_get_time(&timeout->time) < 0) {
248 os_free(timeout);
249 return -1;
250 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700251 now_sec = timeout->time.sec;
252 timeout->time.sec += secs;
253 if (timeout->time.sec < now_sec) {
254 /*
255 * Integer overflow - assume long enough timeout to be assumed
256 * to be infinite, i.e., the timeout would never happen.
257 */
258 wpa_printf(MSG_DEBUG, "ELOOP: Too long timeout (secs=%u) to "
259 "ever happen - ignore it", secs);
260 os_free(timeout);
261 return 0;
262 }
263 timeout->time.usec += usecs;
264 while (timeout->time.usec >= 1000000) {
265 timeout->time.sec++;
266 timeout->time.usec -= 1000000;
267 }
268 timeout->eloop_data = eloop_data;
269 timeout->user_data = user_data;
270 timeout->handler = handler;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700271
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800272 /* Maintain timeouts in order of increasing time */
273 dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
274 if (os_time_before(&timeout->time, &tmp->time)) {
275 dl_list_add(tmp->list.prev, &timeout->list);
276 return 0;
277 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700278 }
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800279 dl_list_add_tail(&eloop.timeout, &timeout->list);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700280
281 return 0;
282}
283
284
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800285static void eloop_remove_timeout(struct eloop_timeout *timeout)
286{
287 dl_list_del(&timeout->list);
288 os_free(timeout);
289}
290
291
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700292int eloop_cancel_timeout(eloop_timeout_handler handler,
293 void *eloop_data, void *user_data)
294{
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800295 struct eloop_timeout *timeout, *prev;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700296 int removed = 0;
297
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800298 dl_list_for_each_safe(timeout, prev, &eloop.timeout,
299 struct eloop_timeout, list) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700300 if (timeout->handler == handler &&
301 (timeout->eloop_data == eloop_data ||
302 eloop_data == ELOOP_ALL_CTX) &&
303 (timeout->user_data == user_data ||
304 user_data == ELOOP_ALL_CTX)) {
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800305 eloop_remove_timeout(timeout);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700306 removed++;
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800307 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700308 }
309
310 return removed;
311}
312
313
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800314int eloop_cancel_timeout_one(eloop_timeout_handler handler,
315 void *eloop_data, void *user_data,
316 struct os_time *remaining)
317{
318 struct eloop_timeout *timeout, *prev;
319 int removed = 0;
320 struct os_time now;
321
322 os_get_time(&now);
323 remaining->sec = remaining->usec = 0;
324
325 dl_list_for_each_safe(timeout, prev, &eloop.timeout,
326 struct eloop_timeout, list) {
327 if (timeout->handler == handler &&
328 (timeout->eloop_data == eloop_data) &&
329 (timeout->user_data == user_data)) {
330 removed = 1;
331 if (os_time_before(&now, &timeout->time))
332 os_time_sub(&timeout->time, &now, remaining);
333 eloop_remove_timeout(timeout);
334 break;
335 }
336 }
337 return removed;
338}
339
340
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700341int eloop_is_timeout_registered(eloop_timeout_handler handler,
342 void *eloop_data, void *user_data)
343{
344 struct eloop_timeout *tmp;
345
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800346 dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700347 if (tmp->handler == handler &&
348 tmp->eloop_data == eloop_data &&
349 tmp->user_data == user_data)
350 return 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700351 }
352
353 return 0;
354}
355
356
Dmitry Shmidte0e48dc2013-11-18 12:00:06 -0800357int eloop_deplete_timeout(unsigned int req_secs, unsigned int req_usecs,
358 eloop_timeout_handler handler, void *eloop_data,
359 void *user_data)
360{
361 struct os_time now, requested, remaining;
362 struct eloop_timeout *tmp;
363
364 dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
365 if (tmp->handler == handler &&
366 tmp->eloop_data == eloop_data &&
367 tmp->user_data == user_data) {
368 requested.sec = req_secs;
369 requested.usec = req_usecs;
370 os_get_time(&now);
371 os_time_sub(&tmp->time, &now, &remaining);
372 if (os_time_before(&requested, &remaining)) {
373 eloop_cancel_timeout(handler, eloop_data,
374 user_data);
375 eloop_register_timeout(requested.sec,
376 requested.usec,
377 handler, eloop_data,
378 user_data);
379 return 1;
380 }
381 }
382 }
383
384 return 0;
385}
386
387
Dmitry Shmidt54605472013-11-08 11:10:19 -0800388int eloop_replenish_timeout(unsigned int req_secs, unsigned int req_usecs,
389 eloop_timeout_handler handler, void *eloop_data,
390 void *user_data)
391{
392 struct os_time now, requested, remaining;
393 struct eloop_timeout *tmp;
394
395 dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
396 if (tmp->handler == handler &&
397 tmp->eloop_data == eloop_data &&
398 tmp->user_data == user_data) {
399 requested.sec = req_secs;
400 requested.usec = req_usecs;
401 os_get_time(&now);
402 os_time_sub(&tmp->time, &now, &remaining);
403 if (os_time_before(&remaining, &requested)) {
404 eloop_cancel_timeout(handler, eloop_data,
405 user_data);
406 eloop_register_timeout(requested.sec,
407 requested.usec,
408 handler, eloop_data,
409 user_data);
410 return 1;
411 }
412 }
413 }
414
415 return 0;
416}
417
418
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700419/* TODO: replace with suitable signal handler */
420#if 0
421static void eloop_handle_signal(int sig)
422{
423 int i;
424
425 eloop.signaled++;
426 for (i = 0; i < eloop.signal_count; i++) {
427 if (eloop.signals[i].sig == sig) {
428 eloop.signals[i].signaled++;
429 break;
430 }
431 }
432}
433#endif
434
435
436static void eloop_process_pending_signals(void)
437{
438 int i;
439
440 if (eloop.signaled == 0)
441 return;
442 eloop.signaled = 0;
443
444 if (eloop.pending_terminate) {
445 eloop.pending_terminate = 0;
446 }
447
448 for (i = 0; i < eloop.signal_count; i++) {
449 if (eloop.signals[i].signaled) {
450 eloop.signals[i].signaled = 0;
451 eloop.signals[i].handler(eloop.signals[i].sig,
452 eloop.signals[i].user_data);
453 }
454 }
455
456 if (eloop.term_signal.signaled) {
457 eloop.term_signal.signaled = 0;
458 eloop.term_signal.handler(eloop.term_signal.sig,
459 eloop.term_signal.user_data);
460 }
461}
462
463
464int eloop_register_signal(int sig, eloop_signal_handler handler,
465 void *user_data)
466{
467 struct eloop_signal *tmp;
468
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700469 tmp = os_realloc_array(eloop.signals, eloop.signal_count + 1,
470 sizeof(struct eloop_signal));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700471 if (tmp == NULL)
472 return -1;
473
474 tmp[eloop.signal_count].sig = sig;
475 tmp[eloop.signal_count].user_data = user_data;
476 tmp[eloop.signal_count].handler = handler;
477 tmp[eloop.signal_count].signaled = 0;
478 eloop.signal_count++;
479 eloop.signals = tmp;
480
481 /* TODO: register signal handler */
482
483 return 0;
484}
485
486
487#ifndef _WIN32_WCE
488static BOOL eloop_handle_console_ctrl(DWORD type)
489{
490 switch (type) {
491 case CTRL_C_EVENT:
492 case CTRL_BREAK_EVENT:
493 eloop.signaled++;
494 eloop.term_signal.signaled++;
495 SetEvent(eloop.term_event);
496 return TRUE;
497 default:
498 return FALSE;
499 }
500}
501#endif /* _WIN32_WCE */
502
503
504int eloop_register_signal_terminate(eloop_signal_handler handler,
505 void *user_data)
506{
507#ifndef _WIN32_WCE
508 if (SetConsoleCtrlHandler((PHANDLER_ROUTINE) eloop_handle_console_ctrl,
509 TRUE) == 0) {
510 printf("SetConsoleCtrlHandler() failed: %d\n",
511 (int) GetLastError());
512 return -1;
513 }
514#endif /* _WIN32_WCE */
515
516 eloop.term_signal.handler = handler;
517 eloop.term_signal.user_data = user_data;
518
519 return 0;
520}
521
522
523int eloop_register_signal_reconfig(eloop_signal_handler handler,
524 void *user_data)
525{
526 /* TODO */
527 return 0;
528}
529
530
531void eloop_run(void)
532{
533 struct os_time tv, now;
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800534 DWORD count, ret, timeout_val, err;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700535 size_t i;
536
537 while (!eloop.terminate &&
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800538 (!dl_list_empty(&eloop.timeout) || eloop.reader_count > 0 ||
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700539 eloop.event_count > 0)) {
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800540 struct eloop_timeout *timeout;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700541 tv.sec = tv.usec = 0;
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800542 timeout = dl_list_first(&eloop.timeout, struct eloop_timeout,
543 list);
544 if (timeout) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700545 os_get_time(&now);
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800546 if (os_time_before(&now, &timeout->time))
547 os_time_sub(&timeout->time, &now, &tv);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700548 }
549
550 count = 0;
551 for (i = 0; i < eloop.event_count; i++)
552 eloop.handles[count++] = eloop.events[i].event;
553
554 for (i = 0; i < eloop.reader_count; i++)
555 eloop.handles[count++] = eloop.readers[i].event;
556
557 if (eloop.term_event)
558 eloop.handles[count++] = eloop.term_event;
559
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800560 if (timeout)
561 timeout_val = tv.sec * 1000 + tv.usec / 1000;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700562 else
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800563 timeout_val = INFINITE;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700564
565 if (count > MAXIMUM_WAIT_OBJECTS) {
566 printf("WaitForMultipleObjects: Too many events: "
567 "%d > %d (ignoring extra events)\n",
568 (int) count, MAXIMUM_WAIT_OBJECTS);
569 count = MAXIMUM_WAIT_OBJECTS;
570 }
571#ifdef _WIN32_WCE
572 ret = WaitForMultipleObjects(count, eloop.handles, FALSE,
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800573 timeout_val);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700574#else /* _WIN32_WCE */
575 ret = WaitForMultipleObjectsEx(count, eloop.handles, FALSE,
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800576 timeout_val, TRUE);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700577#endif /* _WIN32_WCE */
578 err = GetLastError();
579
580 eloop_process_pending_signals();
581
582 /* check if some registered timeouts have occurred */
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800583 timeout = dl_list_first(&eloop.timeout, struct eloop_timeout,
584 list);
585 if (timeout) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700586 os_get_time(&now);
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800587 if (!os_time_before(&now, &timeout->time)) {
588 void *eloop_data = timeout->eloop_data;
589 void *user_data = timeout->user_data;
590 eloop_timeout_handler handler =
591 timeout->handler;
592 eloop_remove_timeout(timeout);
593 handler(eloop_data, user_data);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700594 }
595
596 }
597
598 if (ret == WAIT_FAILED) {
599 printf("WaitForMultipleObjects(count=%d) failed: %d\n",
600 (int) count, (int) err);
601 os_sleep(1, 0);
602 continue;
603 }
604
605#ifndef _WIN32_WCE
606 if (ret == WAIT_IO_COMPLETION)
607 continue;
608#endif /* _WIN32_WCE */
609
610 if (ret == WAIT_TIMEOUT)
611 continue;
612
613 while (ret >= WAIT_OBJECT_0 &&
614 ret < WAIT_OBJECT_0 + eloop.event_count) {
615 eloop.events[ret].handler(
616 eloop.events[ret].eloop_data,
617 eloop.events[ret].user_data);
618 ret = WaitForMultipleObjects(eloop.event_count,
619 eloop.handles, FALSE, 0);
620 }
621
622 eloop.reader_table_changed = 0;
623 for (i = 0; i < eloop.reader_count; i++) {
624 WSANETWORKEVENTS events;
625 if (WSAEnumNetworkEvents(eloop.readers[i].sock,
626 eloop.readers[i].event,
627 &events) == 0 &&
628 (events.lNetworkEvents & FD_READ)) {
629 eloop.readers[i].handler(
630 eloop.readers[i].sock,
631 eloop.readers[i].eloop_data,
632 eloop.readers[i].user_data);
633 if (eloop.reader_table_changed)
634 break;
635 }
636 }
637 }
638}
639
640
641void eloop_terminate(void)
642{
643 eloop.terminate = 1;
644 SetEvent(eloop.term_event);
645}
646
647
648void eloop_destroy(void)
649{
650 struct eloop_timeout *timeout, *prev;
651
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -0800652 dl_list_for_each_safe(timeout, prev, &eloop.timeout,
653 struct eloop_timeout, list) {
654 eloop_remove_timeout(timeout);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700655 }
656 os_free(eloop.readers);
657 os_free(eloop.signals);
658 if (eloop.term_event)
659 CloseHandle(eloop.term_event);
660 os_free(eloop.handles);
661 eloop.handles = NULL;
662 os_free(eloop.events);
663 eloop.events = NULL;
664}
665
666
667int eloop_terminated(void)
668{
669 return eloop.terminate;
670}
671
672
673void eloop_wait_for_read_sock(int sock)
674{
675 WSAEVENT event;
676
677 event = WSACreateEvent();
678 if (event == WSA_INVALID_EVENT) {
679 printf("WSACreateEvent() failed: %d\n", WSAGetLastError());
680 return;
681 }
682
683 if (WSAEventSelect(sock, event, FD_READ)) {
684 printf("WSAEventSelect() failed: %d\n", WSAGetLastError());
685 WSACloseEvent(event);
686 return ;
687 }
688
689 WaitForSingleObject(event, INFINITE);
690 WSAEventSelect(sock, event, 0);
691 WSACloseEvent(event);
692}