1845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/*
2845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Event loop based on Windows events and WaitForMultipleObjects
3845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Copyright (c) 2002-2006, Jouni Malinen <j@w1.fi>
4845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *
5845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * This program is free software; you can redistribute it and/or modify
6845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * it under the terms of the GNU General Public License version 2 as
7845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * published by the Free Software Foundation.
8845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *
9845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * Alternatively, this software may be distributed under the terms of BSD
10845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * license.
11845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project *
12845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project * See README and COPYING for more details.
13845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project */
14845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
15845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "includes.h"
16845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include <winsock2.h>
17845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
18845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "common.h"
19845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#include "eloop.h"
20845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
21845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
22845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstruct eloop_sock {
23845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	int sock;
24845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	void *eloop_data;
25845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	void *user_data;
26845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop_sock_handler handler;
27845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	WSAEVENT event;
28845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project};
29845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
30845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstruct eloop_event {
31845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	void *eloop_data;
32845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	void *user_data;
33845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop_event_handler handler;
34845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	HANDLE event;
35845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project};
36845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
37845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstruct eloop_timeout {
38845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	struct os_time time;
39845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	void *eloop_data;
40845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	void *user_data;
41845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop_timeout_handler handler;
42845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	struct eloop_timeout *next;
43845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project};
44845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
45845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstruct eloop_signal {
46845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	int sig;
47845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	void *user_data;
48845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop_signal_handler handler;
49845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	int signaled;
50845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project};
51845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
52845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstruct eloop_data {
53845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	void *user_data;
54845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
55845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	int max_sock;
56845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	size_t reader_count;
57845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	struct eloop_sock *readers;
58845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
59845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	size_t event_count;
60845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	struct eloop_event *events;
61845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
62845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	struct eloop_timeout *timeout;
63845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
64845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	int signal_count;
65845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	struct eloop_signal *signals;
66845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	int signaled;
67845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	int pending_terminate;
68845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
69845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	int terminate;
70845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	int reader_table_changed;
71845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
72845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	struct eloop_signal term_signal;
73845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	HANDLE term_event;
74845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
75845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	HANDLE *handles;
76845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	size_t num_handles;
77845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project};
78845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
79845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic struct eloop_data eloop;
80845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
81845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
82845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eloop_init(void *user_data)
83845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
84845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	os_memset(&eloop, 0, sizeof(eloop));
85845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.user_data = user_data;
86845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.num_handles = 1;
87845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.handles = os_malloc(eloop.num_handles *
88845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				  sizeof(eloop.handles[0]));
89845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (eloop.handles == NULL)
90845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
91845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
92845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.term_event = CreateEvent(NULL, FALSE, FALSE, NULL);
93845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (eloop.term_event == NULL) {
94845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("CreateEvent() failed: %d\n",
95845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		       (int) GetLastError());
96845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		os_free(eloop.handles);
97845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
98845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
99845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
100845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return 0;
101845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
102845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
103845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
104845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic int eloop_prepare_handles(void)
105845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
106845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	HANDLE *n;
107845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
108845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (eloop.num_handles > eloop.reader_count + eloop.event_count + 8)
109845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return 0;
110845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	n = os_realloc(eloop.handles,
111845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		       eloop.num_handles * 2 * sizeof(eloop.handles[0]));
112845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (n == NULL)
113845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
114845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.handles = n;
115845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.num_handles *= 2;
116845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return 0;
117845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
118845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
119845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
120845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eloop_register_read_sock(int sock, eloop_sock_handler handler,
121845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			     void *eloop_data, void *user_data)
122845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
123845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	WSAEVENT event;
124845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	struct eloop_sock *tmp;
125845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
126845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (eloop_prepare_handles())
127845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
128845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
129845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	event = WSACreateEvent();
130845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (event == WSA_INVALID_EVENT) {
131845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("WSACreateEvent() failed: %d\n", WSAGetLastError());
132845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
133845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
134845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
135845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (WSAEventSelect(sock, event, FD_READ)) {
136845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("WSAEventSelect() failed: %d\n", WSAGetLastError());
137845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		WSACloseEvent(event);
138845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
139845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
140845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	tmp = os_realloc(eloop.readers,
141845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			 (eloop.reader_count + 1) * sizeof(struct eloop_sock));
142845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (tmp == NULL) {
143845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		WSAEventSelect(sock, event, 0);
144845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		WSACloseEvent(event);
145845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
146845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
147845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
148845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	tmp[eloop.reader_count].sock = sock;
149845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	tmp[eloop.reader_count].eloop_data = eloop_data;
150845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	tmp[eloop.reader_count].user_data = user_data;
151845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	tmp[eloop.reader_count].handler = handler;
152845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	tmp[eloop.reader_count].event = event;
153845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.reader_count++;
154845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.readers = tmp;
155845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (sock > eloop.max_sock)
156845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		eloop.max_sock = sock;
157845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.reader_table_changed = 1;
158845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
159845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return 0;
160845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
161845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
162845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
163845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eloop_unregister_read_sock(int sock)
164845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
165845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	size_t i;
166845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
167845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (eloop.readers == NULL || eloop.reader_count == 0)
168845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return;
169845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
170845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	for (i = 0; i < eloop.reader_count; i++) {
171845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (eloop.readers[i].sock == sock)
172845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			break;
173845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
174845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (i == eloop.reader_count)
175845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return;
176845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
177845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	WSAEventSelect(eloop.readers[i].sock, eloop.readers[i].event, 0);
178845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	WSACloseEvent(eloop.readers[i].event);
179845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
180845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (i != eloop.reader_count - 1) {
181845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		os_memmove(&eloop.readers[i], &eloop.readers[i + 1],
182845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			   (eloop.reader_count - i - 1) *
183845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			   sizeof(struct eloop_sock));
184845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
185845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.reader_count--;
186845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.reader_table_changed = 1;
187845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
188845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
189845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
190845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eloop_register_event(void *event, size_t event_size,
191845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			 eloop_event_handler handler,
192845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			 void *eloop_data, void *user_data)
193845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
194845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	struct eloop_event *tmp;
195845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	HANDLE h = event;
196845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
197845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (event_size != sizeof(HANDLE) || h == INVALID_HANDLE_VALUE)
198845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
199845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
200845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (eloop_prepare_handles())
201845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
202845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
203845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	tmp = os_realloc(eloop.events,
204845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			 (eloop.event_count + 1) * sizeof(struct eloop_event));
205845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (tmp == NULL)
206845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
207845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
208845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	tmp[eloop.event_count].eloop_data = eloop_data;
209845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	tmp[eloop.event_count].user_data = user_data;
210845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	tmp[eloop.event_count].handler = handler;
211845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	tmp[eloop.event_count].event = h;
212845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.event_count++;
213845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.events = tmp;
214845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
215845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return 0;
216845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
217845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
218845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
219845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eloop_unregister_event(void *event, size_t event_size)
220845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
221845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	size_t i;
222845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	HANDLE h = event;
223845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
224845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (eloop.events == NULL || eloop.event_count == 0 ||
225845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	    event_size != sizeof(HANDLE))
226845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return;
227845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
228845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	for (i = 0; i < eloop.event_count; i++) {
229845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (eloop.events[i].event == h)
230845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			break;
231845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
232845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (i == eloop.event_count)
233845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return;
234845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
235845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (i != eloop.event_count - 1) {
236845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		os_memmove(&eloop.events[i], &eloop.events[i + 1],
237845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			   (eloop.event_count - i - 1) *
238845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			   sizeof(struct eloop_event));
239845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
240845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.event_count--;
241845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
242845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
243845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
244845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eloop_register_timeout(unsigned int secs, unsigned int usecs,
245845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			   eloop_timeout_handler handler,
246845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			   void *eloop_data, void *user_data)
247845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
248845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	struct eloop_timeout *timeout, *tmp, *prev;
249845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
250845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	timeout = os_malloc(sizeof(*timeout));
251845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (timeout == NULL)
252845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
253845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	os_get_time(&timeout->time);
254845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	timeout->time.sec += secs;
255845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	timeout->time.usec += usecs;
256845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	while (timeout->time.usec >= 1000000) {
257845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		timeout->time.sec++;
258845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		timeout->time.usec -= 1000000;
259845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
260845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	timeout->eloop_data = eloop_data;
261845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	timeout->user_data = user_data;
262845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	timeout->handler = handler;
263845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	timeout->next = NULL;
264845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
265845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (eloop.timeout == NULL) {
266845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		eloop.timeout = timeout;
267845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return 0;
268845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
269845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
270845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	prev = NULL;
271845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	tmp = eloop.timeout;
272845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	while (tmp != NULL) {
273845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (os_time_before(&timeout->time, &tmp->time))
274845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			break;
275845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		prev = tmp;
276845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		tmp = tmp->next;
277845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
278845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
279845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (prev == NULL) {
280845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		timeout->next = eloop.timeout;
281845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		eloop.timeout = timeout;
282845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	} else {
283845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		timeout->next = prev->next;
284845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		prev->next = timeout;
285845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
286845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
287845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return 0;
288845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
289845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
290845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
291845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eloop_cancel_timeout(eloop_timeout_handler handler,
292845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			 void *eloop_data, void *user_data)
293845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
294845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	struct eloop_timeout *timeout, *prev, *next;
295845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	int removed = 0;
296845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
297845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	prev = NULL;
298845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	timeout = eloop.timeout;
299845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	while (timeout != NULL) {
300845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		next = timeout->next;
301845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
302845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (timeout->handler == handler &&
303845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		    (timeout->eloop_data == eloop_data ||
304845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		     eloop_data == ELOOP_ALL_CTX) &&
305845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		    (timeout->user_data == user_data ||
306845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		     user_data == ELOOP_ALL_CTX)) {
307845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			if (prev == NULL)
308845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				eloop.timeout = next;
309845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			else
310845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				prev->next = next;
311845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			os_free(timeout);
312845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			removed++;
313845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		} else
314845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			prev = timeout;
315845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
316845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		timeout = next;
317845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
318845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
319845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return removed;
320845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
321845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
322845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
323dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidtint eloop_is_timeout_registered(eloop_timeout_handler handler,
324dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt				void *eloop_data, void *user_data)
325dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt{
326dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt	struct eloop_timeout *tmp;
327dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt
328dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt	tmp = eloop.timeout;
329dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt	while (tmp != NULL) {
330dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt		if (tmp->handler == handler &&
331dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt		    tmp->eloop_data == eloop_data &&
332dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt		    tmp->user_data == user_data)
333dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt			return 1;
334dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt
335dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt		tmp = tmp->next;
336dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt	}
337dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt
338dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt	return 0;
339dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt}
340dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt
341dc9507e42030320bf0a3dbb7d3f733d43bc94edeDmitry Shmidt
342845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project/* TODO: replace with suitable signal handler */
343845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#if 0
344845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void eloop_handle_signal(int sig)
345845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
346845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	int i;
347845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
348845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.signaled++;
349845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	for (i = 0; i < eloop.signal_count; i++) {
350845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (eloop.signals[i].sig == sig) {
351845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			eloop.signals[i].signaled++;
352845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			break;
353845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		}
354845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
355845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
356845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif
357845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
358845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
359845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic void eloop_process_pending_signals(void)
360845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
361845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	int i;
362845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
363845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (eloop.signaled == 0)
364845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return;
365845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.signaled = 0;
366845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
367845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (eloop.pending_terminate) {
368845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		eloop.pending_terminate = 0;
369845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
370845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
371845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	for (i = 0; i < eloop.signal_count; i++) {
372845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (eloop.signals[i].signaled) {
373845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			eloop.signals[i].signaled = 0;
374845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			eloop.signals[i].handler(eloop.signals[i].sig,
375845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project						 eloop.user_data,
376845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project						 eloop.signals[i].user_data);
377845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		}
378845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
379845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
380845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (eloop.term_signal.signaled) {
381845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		eloop.term_signal.signaled = 0;
382845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		eloop.term_signal.handler(eloop.term_signal.sig,
383845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project					  eloop.user_data,
384845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project					  eloop.term_signal.user_data);
385845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
386845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
387845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
388845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
389845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eloop_register_signal(int sig, eloop_signal_handler handler,
390845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			  void *user_data)
391845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
392845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	struct eloop_signal *tmp;
393845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
394845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	tmp = os_realloc(eloop.signals,
395845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			 (eloop.signal_count + 1) *
396845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			 sizeof(struct eloop_signal));
397845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (tmp == NULL)
398845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
399845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
400845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	tmp[eloop.signal_count].sig = sig;
401845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	tmp[eloop.signal_count].user_data = user_data;
402845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	tmp[eloop.signal_count].handler = handler;
403845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	tmp[eloop.signal_count].signaled = 0;
404845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.signal_count++;
405845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.signals = tmp;
406845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
407845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* TODO: register signal handler */
408845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
409845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return 0;
410845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
411845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
412845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
413845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifndef _WIN32_WCE
414845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectstatic BOOL eloop_handle_console_ctrl(DWORD type)
415845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
416845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	switch (type) {
417845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	case CTRL_C_EVENT:
418845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	case CTRL_BREAK_EVENT:
419845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		eloop.signaled++;
420845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		eloop.term_signal.signaled++;
421845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		SetEvent(eloop.term_event);
422845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return TRUE;
423845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	default:
424845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return FALSE;
425845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
426845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
427845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* _WIN32_WCE */
428845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
429845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
430845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eloop_register_signal_terminate(eloop_signal_handler handler,
431845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				    void *user_data)
432845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
433845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifndef _WIN32_WCE
434845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (SetConsoleCtrlHandler((PHANDLER_ROUTINE) eloop_handle_console_ctrl,
435845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				  TRUE) == 0) {
436845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("SetConsoleCtrlHandler() failed: %d\n",
437845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		       (int) GetLastError());
438845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return -1;
439845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
440845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* _WIN32_WCE */
441845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
442845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.term_signal.handler = handler;
443845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.term_signal.user_data = user_data;
444845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
445845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return 0;
446845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
447845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
448845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
449845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eloop_register_signal_reconfig(eloop_signal_handler handler,
450845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				   void *user_data)
451845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
452845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	/* TODO */
453845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return 0;
454845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
455845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
456845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
457845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eloop_run(void)
458845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
459845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	struct os_time tv, now;
460845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	DWORD count, ret, timeout, err;
461845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	size_t i;
462845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
463845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	while (!eloop.terminate &&
464845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	       (eloop.timeout || eloop.reader_count > 0 ||
465845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		eloop.event_count > 0)) {
466845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (eloop.timeout) {
467845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			os_get_time(&now);
468845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			if (os_time_before(&now, &eloop.timeout->time))
469845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				os_time_sub(&eloop.timeout->time, &now, &tv);
470845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			else
471845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				tv.sec = tv.usec = 0;
472845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		}
473845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
474845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		count = 0;
475845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		for (i = 0; i < eloop.event_count; i++)
476845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			eloop.handles[count++] = eloop.events[i].event;
477845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
478845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		for (i = 0; i < eloop.reader_count; i++)
479845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			eloop.handles[count++] = eloop.readers[i].event;
480845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
481845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (eloop.term_event)
482845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			eloop.handles[count++] = eloop.term_event;
483845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
484845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (eloop.timeout)
485845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			timeout = tv.sec * 1000 + tv.usec / 1000;
486845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		else
487845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			timeout = INFINITE;
488845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
489845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (count > MAXIMUM_WAIT_OBJECTS) {
490845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			printf("WaitForMultipleObjects: Too many events: "
491845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			       "%d > %d (ignoring extra events)\n",
492845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			       (int) count, MAXIMUM_WAIT_OBJECTS);
493845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			count = MAXIMUM_WAIT_OBJECTS;
494845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		}
495845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifdef _WIN32_WCE
496845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		ret = WaitForMultipleObjects(count, eloop.handles, FALSE,
497845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project					     timeout);
498845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#else /* _WIN32_WCE */
499845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		ret = WaitForMultipleObjectsEx(count, eloop.handles, FALSE,
500845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project					       timeout, TRUE);
501845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* _WIN32_WCE */
502845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		err = GetLastError();
503845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
504845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		eloop_process_pending_signals();
505845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
506845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		/* check if some registered timeouts have occurred */
507845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (eloop.timeout) {
508845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			struct eloop_timeout *tmp;
509845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
510845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			os_get_time(&now);
511845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			if (!os_time_before(&now, &eloop.timeout->time)) {
512845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				tmp = eloop.timeout;
513845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				eloop.timeout = eloop.timeout->next;
514845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				tmp->handler(tmp->eloop_data,
515845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project					     tmp->user_data);
516845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				os_free(tmp);
517845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			}
518845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
519845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		}
520845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
521845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (ret == WAIT_FAILED) {
522845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			printf("WaitForMultipleObjects(count=%d) failed: %d\n",
523845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			       (int) count, (int) err);
524845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			os_sleep(1, 0);
525845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			continue;
526845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		}
527845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
528845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#ifndef _WIN32_WCE
529845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (ret == WAIT_IO_COMPLETION)
530845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			continue;
531845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project#endif /* _WIN32_WCE */
532845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
533845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		if (ret == WAIT_TIMEOUT)
534845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			continue;
535845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
536845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		while (ret >= WAIT_OBJECT_0 &&
537845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		       ret < WAIT_OBJECT_0 + eloop.event_count) {
538845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			eloop.events[ret].handler(
539845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				eloop.events[ret].eloop_data,
540845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				eloop.events[ret].user_data);
541845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			ret = WaitForMultipleObjects(eloop.event_count,
542845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project						     eloop.handles, FALSE, 0);
543845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		}
544845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
545845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		eloop.reader_table_changed = 0;
546845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		for (i = 0; i < eloop.reader_count; i++) {
547845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			WSANETWORKEVENTS events;
548845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			if (WSAEnumNetworkEvents(eloop.readers[i].sock,
549845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project						 eloop.readers[i].event,
550845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project						 &events) == 0 &&
551845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			    (events.lNetworkEvents & FD_READ)) {
552845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				eloop.readers[i].handler(
553845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project					eloop.readers[i].sock,
554845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project					eloop.readers[i].eloop_data,
555845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project					eloop.readers[i].user_data);
556845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project				if (eloop.reader_table_changed)
557845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project					break;
558845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project			}
559845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		}
560845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
561845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
562845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
563845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
564845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eloop_terminate(void)
565845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
566845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.terminate = 1;
567845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	SetEvent(eloop.term_event);
568845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
569845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
570845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
571845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eloop_destroy(void)
572845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
573845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	struct eloop_timeout *timeout, *prev;
574845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
575845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	timeout = eloop.timeout;
576845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	while (timeout != NULL) {
577845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		prev = timeout;
578845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		timeout = timeout->next;
579845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		os_free(prev);
580845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
581845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	os_free(eloop.readers);
582845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	os_free(eloop.signals);
583845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (eloop.term_event)
584845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		CloseHandle(eloop.term_event);
585845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	os_free(eloop.handles);
586845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.handles = NULL;
587845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	os_free(eloop.events);
588845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	eloop.events = NULL;
589845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
590845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
591845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
592845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectint eloop_terminated(void)
593845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
594845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return eloop.terminate;
595845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
596845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
597845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
598845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid eloop_wait_for_read_sock(int sock)
599845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
600845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	WSAEVENT event;
601845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
602845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	event = WSACreateEvent();
603845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (event == WSA_INVALID_EVENT) {
604845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("WSACreateEvent() failed: %d\n", WSAGetLastError());
605845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return;
606845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
607845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
608845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	if (WSAEventSelect(sock, event, FD_READ)) {
609845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		printf("WSAEventSelect() failed: %d\n", WSAGetLastError());
610845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		WSACloseEvent(event);
611845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project		return ;
612845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	}
613845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
614845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	WaitForSingleObject(event, INFINITE);
615845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	WSAEventSelect(sock, event, 0);
616845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	WSACloseEvent(event);
617845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
618845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
619845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project
620845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Projectvoid * eloop_get_user_data(void)
621845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project{
622845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project	return eloop.user_data;
623845e0124d42b67ef926fbae32a7f61d2e5109ebdThe Android Open Source Project}
624