18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Event loop based on Windows events and WaitForMultipleObjects
34b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h"
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <winsock2.h>
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h"
134b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt#include "list.h"
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h"
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eloop_sock {
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int sock;
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	void *eloop_data;
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	void *user_data;
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_sock_handler handler;
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	WSAEVENT event;
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eloop_event {
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	void *eloop_data;
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	void *user_data;
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_event_handler handler;
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	HANDLE event;
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eloop_timeout {
334b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	struct dl_list list;
34fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt	struct os_reltime time;
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	void *eloop_data;
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	void *user_data;
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_timeout_handler handler;
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eloop_signal {
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int sig;
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	void *user_data;
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_signal_handler handler;
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int signaled;
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eloop_data {
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int max_sock;
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t reader_count;
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct eloop_sock *readers;
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t event_count;
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct eloop_event *events;
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
554b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	struct dl_list timeout;
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int signal_count;
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct eloop_signal *signals;
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int signaled;
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int pending_terminate;
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int terminate;
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int reader_table_changed;
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct eloop_signal term_signal;
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	HANDLE term_event;
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	HANDLE *handles;
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t num_handles;
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct eloop_data eloop;
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eloop_init(void)
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&eloop, 0, sizeof(eloop));
784b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	dl_list_init(&eloop.timeout);
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.num_handles = 1;
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.handles = os_malloc(eloop.num_handles *
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  sizeof(eloop.handles[0]));
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eloop.handles == NULL)
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.term_event = CreateEvent(NULL, FALSE, FALSE, NULL);
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eloop.term_event == NULL) {
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		printf("CreateEvent() failed: %d\n",
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		       (int) GetLastError());
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(eloop.handles);
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eloop_prepare_handles(void)
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	HANDLE *n;
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eloop.num_handles > eloop.reader_count + eloop.event_count + 8)
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
10361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	n = os_realloc_array(eloop.handles, eloop.num_handles * 2,
10461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			     sizeof(eloop.handles[0]));
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (n == NULL)
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.handles = n;
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.num_handles *= 2;
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eloop_register_read_sock(int sock, eloop_sock_handler handler,
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     void *eloop_data, void *user_data)
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	WSAEVENT event;
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct eloop_sock *tmp;
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eloop_prepare_handles())
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	event = WSACreateEvent();
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (event == WSA_INVALID_EVENT) {
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		printf("WSACreateEvent() failed: %d\n", WSAGetLastError());
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (WSAEventSelect(sock, event, FD_READ)) {
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		printf("WSAEventSelect() failed: %d\n", WSAGetLastError());
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		WSACloseEvent(event);
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	tmp = os_realloc_array(eloop.readers, eloop.reader_count + 1,
13461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			       sizeof(struct eloop_sock));
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tmp == NULL) {
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		WSAEventSelect(sock, event, 0);
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		WSACloseEvent(event);
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tmp[eloop.reader_count].sock = sock;
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tmp[eloop.reader_count].eloop_data = eloop_data;
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tmp[eloop.reader_count].user_data = user_data;
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tmp[eloop.reader_count].handler = handler;
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tmp[eloop.reader_count].event = event;
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.reader_count++;
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.readers = tmp;
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (sock > eloop.max_sock)
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop.max_sock = sock;
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.reader_table_changed = 1;
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eloop_unregister_read_sock(int sock)
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t i;
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eloop.readers == NULL || eloop.reader_count == 0)
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < eloop.reader_count; i++) {
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (eloop.readers[i].sock == sock)
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (i == eloop.reader_count)
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	WSAEventSelect(eloop.readers[i].sock, eloop.readers[i].event, 0);
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	WSACloseEvent(eloop.readers[i].event);
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (i != eloop.reader_count - 1) {
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memmove(&eloop.readers[i], &eloop.readers[i + 1],
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   (eloop.reader_count - i - 1) *
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   sizeof(struct eloop_sock));
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.reader_count--;
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.reader_table_changed = 1;
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eloop_register_event(void *event, size_t event_size,
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 eloop_event_handler handler,
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 void *eloop_data, void *user_data)
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct eloop_event *tmp;
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	HANDLE h = event;
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (event_size != sizeof(HANDLE) || h == INVALID_HANDLE_VALUE)
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eloop_prepare_handles())
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	tmp = os_realloc_array(eloop.events, eloop.event_count + 1,
19761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			       sizeof(struct eloop_event));
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tmp == NULL)
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tmp[eloop.event_count].eloop_data = eloop_data;
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tmp[eloop.event_count].user_data = user_data;
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tmp[eloop.event_count].handler = handler;
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tmp[eloop.event_count].event = h;
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.event_count++;
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.events = tmp;
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eloop_unregister_event(void *event, size_t event_size)
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t i;
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	HANDLE h = event;
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eloop.events == NULL || eloop.event_count == 0 ||
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    event_size != sizeof(HANDLE))
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < eloop.event_count; i++) {
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (eloop.events[i].event == h)
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (i == eloop.event_count)
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (i != eloop.event_count - 1) {
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memmove(&eloop.events[i], &eloop.events[i + 1],
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   (eloop.event_count - i - 1) *
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   sizeof(struct eloop_event));
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.event_count--;
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eloop_register_timeout(unsigned int secs, unsigned int usecs,
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   eloop_timeout_handler handler,
2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   void *eloop_data, void *user_data)
2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2414b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	struct eloop_timeout *timeout, *tmp;
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_time_t now_sec;
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2444b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	timeout = os_zalloc(sizeof(*timeout));
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (timeout == NULL)
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
247fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt	if (os_get_reltime(&timeout->time) < 0) {
2484b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		os_free(timeout);
2494b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		return -1;
2504b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	}
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	now_sec = timeout->time.sec;
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	timeout->time.sec += secs;
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (timeout->time.sec < now_sec) {
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Integer overflow - assume long enough timeout to be assumed
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * to be infinite, i.e., the timeout would never happen.
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "ELOOP: Too long timeout (secs=%u) to "
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "ever happen - ignore it", secs);
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(timeout);
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	timeout->time.usec += usecs;
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (timeout->time.usec >= 1000000) {
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		timeout->time.sec++;
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		timeout->time.usec -= 1000000;
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	timeout->eloop_data = eloop_data;
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	timeout->user_data = user_data;
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	timeout->handler = handler;
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2724b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	/* Maintain timeouts in order of increasing time */
2734b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
274fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt		if (os_reltime_before(&timeout->time, &tmp->time)) {
2754b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt			dl_list_add(tmp->list.prev, &timeout->list);
2764b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt			return 0;
2774b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		}
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2794b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	dl_list_add_tail(&eloop.timeout, &timeout->list);
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2814b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	return 0;
2824b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt}
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2854b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidtstatic void eloop_remove_timeout(struct eloop_timeout *timeout)
2864b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt{
2874b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	dl_list_del(&timeout->list);
2884b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	os_free(timeout);
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eloop_cancel_timeout(eloop_timeout_handler handler,
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 void *eloop_data, void *user_data)
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2954b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	struct eloop_timeout *timeout, *prev;
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int removed = 0;
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2984b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	dl_list_for_each_safe(timeout, prev, &eloop.timeout,
2994b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt			      struct eloop_timeout, list) {
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (timeout->handler == handler &&
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (timeout->eloop_data == eloop_data ||
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     eloop_data == ELOOP_ALL_CTX) &&
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (timeout->user_data == user_data ||
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     user_data == ELOOP_ALL_CTX)) {
3054b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt			eloop_remove_timeout(timeout);
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			removed++;
3074b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		}
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return removed;
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3144b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidtint eloop_cancel_timeout_one(eloop_timeout_handler handler,
3154b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt			     void *eloop_data, void *user_data,
316fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt			     struct os_reltime *remaining)
3174b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt{
3184b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	struct eloop_timeout *timeout, *prev;
3194b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	int removed = 0;
320fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt	struct os_reltime now;
3214b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt
322fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt	os_get_reltime(&now);
3234b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	remaining->sec = remaining->usec = 0;
3244b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt
3254b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	dl_list_for_each_safe(timeout, prev, &eloop.timeout,
3264b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt			      struct eloop_timeout, list) {
3274b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		if (timeout->handler == handler &&
3284b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		    (timeout->eloop_data == eloop_data) &&
3294b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		    (timeout->user_data == user_data)) {
3304b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt			removed = 1;
331fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt			if (os_reltime_before(&now, &timeout->time))
332fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt				os_reltime_sub(&timeout->time, &now, remaining);
3334b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt			eloop_remove_timeout(timeout);
3344b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt			break;
3354b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		}
3364b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	}
3374b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	return removed;
3384b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt}
3394b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt
3404b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eloop_is_timeout_registered(eloop_timeout_handler handler,
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				void *eloop_data, void *user_data)
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct eloop_timeout *tmp;
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3464b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (tmp->handler == handler &&
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    tmp->eloop_data == eloop_data &&
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    tmp->user_data == user_data)
3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 1;
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
357e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtint eloop_deplete_timeout(unsigned int req_secs, unsigned int req_usecs,
358e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt			  eloop_timeout_handler handler, void *eloop_data,
359e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt			  void *user_data)
360e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{
361fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt	struct os_reltime now, requested, remaining;
362e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt	struct eloop_timeout *tmp;
363e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt
364e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt	dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
365e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt		if (tmp->handler == handler &&
366e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt		    tmp->eloop_data == eloop_data &&
367e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt		    tmp->user_data == user_data) {
368e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt			requested.sec = req_secs;
369e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt			requested.usec = req_usecs;
370fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt			os_get_reltime(&now);
371fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt			os_reltime_sub(&tmp->time, &now, &remaining);
372fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt			if (os_reltime_before(&requested, &remaining)) {
373e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt				eloop_cancel_timeout(handler, eloop_data,
374e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt						     user_data);
375e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt				eloop_register_timeout(requested.sec,
376e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt						       requested.usec,
377e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt						       handler, eloop_data,
378e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt						       user_data);
379e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt				return 1;
380e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt			}
381fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			return 0;
382e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt		}
383e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt	}
384e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt
385fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	return -1;
386e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt}
387e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt
388e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt
3895460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidtint eloop_replenish_timeout(unsigned int req_secs, unsigned int req_usecs,
3905460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			    eloop_timeout_handler handler, void *eloop_data,
3915460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			    void *user_data)
3925460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt{
393fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt	struct os_reltime now, requested, remaining;
3945460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt	struct eloop_timeout *tmp;
3955460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt
3965460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt	dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
3975460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt		if (tmp->handler == handler &&
3985460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt		    tmp->eloop_data == eloop_data &&
3995460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt		    tmp->user_data == user_data) {
4005460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			requested.sec = req_secs;
4015460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			requested.usec = req_usecs;
402fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt			os_get_reltime(&now);
403fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt			os_reltime_sub(&tmp->time, &now, &remaining);
404fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt			if (os_reltime_before(&remaining, &requested)) {
4055460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt				eloop_cancel_timeout(handler, eloop_data,
4065460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt						     user_data);
4075460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt				eloop_register_timeout(requested.sec,
4085460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt						       requested.usec,
4095460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt						       handler, eloop_data,
4105460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt						       user_data);
4115460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt				return 1;
4125460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt			}
413fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			return 0;
4145460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt		}
4155460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt	}
4165460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt
417fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	return -1;
4185460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt}
4195460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt
4205460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt
4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* TODO: replace with suitable signal handler */
4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if 0
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eloop_handle_signal(int sig)
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.signaled++;
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < eloop.signal_count; i++) {
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (eloop.signals[i].sig == sig) {
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eloop.signals[i].signaled++;
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eloop_process_pending_signals(void)
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eloop.signaled == 0)
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.signaled = 0;
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eloop.pending_terminate) {
4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop.pending_terminate = 0;
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < eloop.signal_count; i++) {
4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (eloop.signals[i].signaled) {
4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eloop.signals[i].signaled = 0;
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eloop.signals[i].handler(eloop.signals[i].sig,
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 eloop.signals[i].user_data);
4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eloop.term_signal.signaled) {
4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop.term_signal.signaled = 0;
4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop.term_signal.handler(eloop.term_signal.sig,
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  eloop.term_signal.user_data);
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eloop_register_signal(int sig, eloop_signal_handler handler,
4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  void *user_data)
4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct eloop_signal *tmp;
4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
47161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	tmp = os_realloc_array(eloop.signals, eloop.signal_count + 1,
47261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			       sizeof(struct eloop_signal));
4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tmp == NULL)
4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tmp[eloop.signal_count].sig = sig;
4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tmp[eloop.signal_count].user_data = user_data;
4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tmp[eloop.signal_count].handler = handler;
4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tmp[eloop.signal_count].signaled = 0;
4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.signal_count++;
4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.signals = tmp;
4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* TODO: register signal handler */
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef _WIN32_WCE
4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic BOOL eloop_handle_console_ctrl(DWORD type)
4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (type) {
4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case CTRL_C_EVENT:
4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case CTRL_BREAK_EVENT:
4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop.signaled++;
4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop.term_signal.signaled++;
4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		SetEvent(eloop.term_event);
4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return TRUE;
4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return FALSE;
5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */
5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eloop_register_signal_terminate(eloop_signal_handler handler,
5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    void *user_data)
5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef _WIN32_WCE
5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (SetConsoleCtrlHandler((PHANDLER_ROUTINE) eloop_handle_console_ctrl,
5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  TRUE) == 0) {
5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		printf("SetConsoleCtrlHandler() failed: %d\n",
5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		       (int) GetLastError());
5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */
5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.term_signal.handler = handler;
5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.term_signal.user_data = user_data;
5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eloop_register_signal_reconfig(eloop_signal_handler handler,
5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   void *user_data)
5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* TODO */
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eloop_run(void)
5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
535fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt	struct os_reltime tv, now;
5364b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	DWORD count, ret, timeout_val, err;
5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t i;
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (!eloop.terminate &&
5404b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	       (!dl_list_empty(&eloop.timeout) || eloop.reader_count > 0 ||
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop.event_count > 0)) {
5424b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		struct eloop_timeout *timeout;
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		tv.sec = tv.usec = 0;
5444b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		timeout = dl_list_first(&eloop.timeout, struct eloop_timeout,
5454b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt					list);
5464b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		if (timeout) {
547fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt			os_get_reltime(&now);
548fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt			if (os_reltime_before(&now, &timeout->time))
549fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt				os_reltime_sub(&timeout->time, &now, &tv);
5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		count = 0;
5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (i = 0; i < eloop.event_count; i++)
5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eloop.handles[count++] = eloop.events[i].event;
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (i = 0; i < eloop.reader_count; i++)
5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eloop.handles[count++] = eloop.readers[i].event;
5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (eloop.term_event)
5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eloop.handles[count++] = eloop.term_event;
5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5624b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		if (timeout)
5634b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt			timeout_val = tv.sec * 1000 + tv.usec / 1000;
5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
5654b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt			timeout_val = INFINITE;
5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (count > MAXIMUM_WAIT_OBJECTS) {
5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			printf("WaitForMultipleObjects: Too many events: "
5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			       "%d > %d (ignoring extra events)\n",
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			       (int) count, MAXIMUM_WAIT_OBJECTS);
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			count = MAXIMUM_WAIT_OBJECTS;
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE
5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = WaitForMultipleObjects(count, eloop.handles, FALSE,
5754b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt					     timeout_val);
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* _WIN32_WCE */
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = WaitForMultipleObjectsEx(count, eloop.handles, FALSE,
5784b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt					       timeout_val, TRUE);
5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */
5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		err = GetLastError();
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop_process_pending_signals();
5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* check if some registered timeouts have occurred */
5854b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		timeout = dl_list_first(&eloop.timeout, struct eloop_timeout,
5864b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt					list);
5874b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		if (timeout) {
588fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt			os_get_reltime(&now);
589fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt			if (!os_reltime_before(&now, &timeout->time)) {
5904b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt				void *eloop_data = timeout->eloop_data;
5914b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt				void *user_data = timeout->user_data;
5924b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt				eloop_timeout_handler handler =
5934b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt					timeout->handler;
5944b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt				eloop_remove_timeout(timeout);
5954b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt				handler(eloop_data, user_data);
5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret == WAIT_FAILED) {
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			printf("WaitForMultipleObjects(count=%d) failed: %d\n",
6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			       (int) count, (int) err);
6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_sleep(1, 0);
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef _WIN32_WCE
6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret == WAIT_IO_COMPLETION)
6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */
6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret == WAIT_TIMEOUT)
6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (ret >= WAIT_OBJECT_0 &&
6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		       ret < WAIT_OBJECT_0 + eloop.event_count) {
6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eloop.events[ret].handler(
6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				eloop.events[ret].eloop_data,
6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				eloop.events[ret].user_data);
6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ret = WaitForMultipleObjects(eloop.event_count,
6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						     eloop.handles, FALSE, 0);
6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop.reader_table_changed = 0;
6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (i = 0; i < eloop.reader_count; i++) {
6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			WSANETWORKEVENTS events;
6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (WSAEnumNetworkEvents(eloop.readers[i].sock,
6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 eloop.readers[i].event,
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 &events) == 0 &&
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    (events.lNetworkEvents & FD_READ)) {
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				eloop.readers[i].handler(
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					eloop.readers[i].sock,
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					eloop.readers[i].eloop_data,
6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					eloop.readers[i].user_data);
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (eloop.reader_table_changed)
6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					break;
6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eloop_terminate(void)
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.terminate = 1;
6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	SetEvent(eloop.term_event);
6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eloop_destroy(void)
6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct eloop_timeout *timeout, *prev;
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6544b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	dl_list_for_each_safe(timeout, prev, &eloop.timeout,
6554b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt			      struct eloop_timeout, list) {
6564b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		eloop_remove_timeout(timeout);
6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(eloop.readers);
6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(eloop.signals);
6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eloop.term_event)
6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		CloseHandle(eloop.term_event);
6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(eloop.handles);
6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.handles = NULL;
6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(eloop.events);
6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop.events = NULL;
6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eloop_terminated(void)
6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return eloop.terminate;
6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eloop_wait_for_read_sock(int sock)
6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	WSAEVENT event;
6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	event = WSACreateEvent();
6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (event == WSA_INVALID_EVENT) {
6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		printf("WSACreateEvent() failed: %d\n", WSAGetLastError());
6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (WSAEventSelect(sock, event, FD_READ)) {
6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		printf("WSAEventSelect() failed: %d\n", WSAGetLastError());
6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		WSACloseEvent(event);
6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return ;
6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	WaitForSingleObject(event, INFINITE);
6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	WSAEventSelect(sock, event, 0);
6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	WSACloseEvent(event);
6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
695