2 * Event loop - empty template (basic structure, but no OS specific operations)
3 * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
25 void (*handler
)(int sock
, void *eloop_ctx
, void *sock_ctx
);
28 struct eloop_timeout
{
32 void (*handler
)(void *eloop_ctx
, void *sock_ctx
);
33 struct eloop_timeout
*next
;
39 void (*handler
)(int sig
, void *eloop_ctx
, void *signal_ctx
);
44 int max_sock
, reader_count
;
45 struct eloop_sock
*readers
;
47 struct eloop_timeout
*timeout
;
50 struct eloop_signal
*signals
;
52 int pending_terminate
;
55 int reader_table_changed
;
58 static struct eloop_data eloop
;
63 memset(&eloop
, 0, sizeof(eloop
));
68 int eloop_register_read_sock(int sock
,
69 void (*handler
)(int sock
, void *eloop_ctx
,
71 void *eloop_data
, void *user_data
)
73 struct eloop_sock
*tmp
;
75 tmp
= (struct eloop_sock
*)
76 realloc(eloop
.readers
,
77 (eloop
.reader_count
+ 1) * sizeof(struct eloop_sock
));
81 tmp
[eloop
.reader_count
].sock
= sock
;
82 tmp
[eloop
.reader_count
].eloop_data
= eloop_data
;
83 tmp
[eloop
.reader_count
].user_data
= user_data
;
84 tmp
[eloop
.reader_count
].handler
= handler
;
87 if (sock
> eloop
.max_sock
)
88 eloop
.max_sock
= sock
;
89 eloop
.reader_table_changed
= 1;
95 void eloop_unregister_read_sock(int sock
)
99 if (eloop
.readers
== NULL
|| eloop
.reader_count
== 0)
102 for (i
= 0; i
< eloop
.reader_count
; i
++) {
103 if (eloop
.readers
[i
].sock
== sock
)
106 if (i
== eloop
.reader_count
)
108 if (i
!= eloop
.reader_count
- 1) {
109 memmove(&eloop
.readers
[i
], &eloop
.readers
[i
+ 1],
110 (eloop
.reader_count
- i
- 1) *
111 sizeof(struct eloop_sock
));
113 eloop
.reader_count
--;
114 eloop
.reader_table_changed
= 1;
118 int eloop_register_timeout(unsigned int secs
, unsigned int usecs
,
119 void (*handler
)(void *eloop_ctx
, void *timeout_ctx
),
120 void *eloop_data
, void *user_data
)
122 struct eloop_timeout
*timeout
, *tmp
, *prev
;
124 timeout
= (struct eloop_timeout
*) malloc(sizeof(*timeout
));
127 os_get_time(&timeout
->time
);
128 timeout
->time
.sec
+= secs
;
129 timeout
->time
.usec
+= usecs
;
130 while (timeout
->time
.usec
>= 1000000) {
132 timeout
->time
.usec
-= 1000000;
134 timeout
->eloop_data
= eloop_data
;
135 timeout
->user_data
= user_data
;
136 timeout
->handler
= handler
;
137 timeout
->next
= NULL
;
139 if (eloop
.timeout
== NULL
) {
140 eloop
.timeout
= timeout
;
146 while (tmp
!= NULL
) {
147 if (os_time_before(&timeout
->time
, &tmp
->time
))
154 timeout
->next
= eloop
.timeout
;
155 eloop
.timeout
= timeout
;
157 timeout
->next
= prev
->next
;
158 prev
->next
= timeout
;
165 int eloop_cancel_timeout(void (*handler
)(void *eloop_ctx
, void *sock_ctx
),
166 void *eloop_data
, void *user_data
)
168 struct eloop_timeout
*timeout
, *prev
, *next
;
172 timeout
= eloop
.timeout
;
173 while (timeout
!= NULL
) {
174 next
= timeout
->next
;
176 if (timeout
->handler
== handler
&&
177 (timeout
->eloop_data
== eloop_data
||
178 eloop_data
== ELOOP_ALL_CTX
) &&
179 (timeout
->user_data
== user_data
||
180 user_data
== ELOOP_ALL_CTX
)) {
182 eloop
.timeout
= next
;
197 int eloop_is_timeout_registered(void (*handler
)(void *eloop_ctx
,
199 void *eloop_data
, void *user_data
)
201 struct eloop_timeout
*tmp
;
204 while (tmp
!= NULL
) {
205 if (tmp
->handler
== handler
&&
206 tmp
->eloop_data
== eloop_data
&&
207 tmp
->user_data
== user_data
)
217 /* TODO: replace with suitable signal handler */
219 static void eloop_handle_signal(int sig
)
224 for (i
= 0; i
< eloop
.signal_count
; i
++) {
225 if (eloop
.signals
[i
].sig
== sig
) {
226 eloop
.signals
[i
].signaled
++;
234 static void eloop_process_pending_signals(void)
238 if (eloop
.signaled
== 0)
242 if (eloop
.pending_terminate
) {
243 eloop
.pending_terminate
= 0;
246 for (i
= 0; i
< eloop
.signal_count
; i
++) {
247 if (eloop
.signals
[i
].signaled
) {
248 eloop
.signals
[i
].signaled
= 0;
249 eloop
.signals
[i
].handler(eloop
.signals
[i
].sig
,
251 eloop
.signals
[i
].user_data
);
257 int eloop_register_signal(int sig
,
258 void (*handler
)(int sig
, void *eloop_ctx
,
262 struct eloop_signal
*tmp
;
264 tmp
= (struct eloop_signal
*)
265 realloc(eloop
.signals
,
266 (eloop
.signal_count
+ 1) *
267 sizeof(struct eloop_signal
));
271 tmp
[eloop
.signal_count
].sig
= sig
;
272 tmp
[eloop
.signal_count
].user_data
= user_data
;
273 tmp
[eloop
.signal_count
].handler
= handler
;
274 tmp
[eloop
.signal_count
].signaled
= 0;
275 eloop
.signal_count
++;
278 /* TODO: register signal handler */
284 int eloop_register_signal_terminate(void (*handler
)(int sig
, void *eloop_ctx
,
289 /* TODO: for example */
290 int ret
= eloop_register_signal(SIGINT
, handler
, user_data
);
292 ret
= eloop_register_signal(SIGTERM
, handler
, user_data
);
299 int eloop_register_signal_reconfig(void (*handler
)(int sig
, void *eloop_ctx
,
304 /* TODO: for example */
305 return eloop_register_signal(SIGHUP
, handler
, user_data
);
314 struct os_time tv
, now
;
316 while (!eloop
.terminate
&&
317 (eloop
.timeout
|| eloop
.reader_count
> 0)) {
320 if (os_time_before(&now
, &eloop
.timeout
->time
))
321 os_time_sub(&eloop
.timeout
->time
, &now
, &tv
);
323 tv
.sec
= tv
.usec
= 0;
327 * TODO: wait for any event (read socket ready, timeout (tv),
330 os_sleep(1, 0); /* just a dummy wait for testing */
332 eloop_process_pending_signals();
334 /* check if some registered timeouts have occurred */
336 struct eloop_timeout
*tmp
;
339 if (!os_time_before(&now
, &eloop
.timeout
->time
)) {
341 eloop
.timeout
= eloop
.timeout
->next
;
342 tmp
->handler(tmp
->eloop_data
,
349 eloop
.reader_table_changed
= 0;
350 for (i
= 0; i
< eloop
.reader_count
; i
++) {
352 * TODO: call each handler that has pending data to
355 if (0 /* TODO: eloop.readers[i].sock ready */) {
356 eloop
.readers
[i
].handler(
357 eloop
.readers
[i
].sock
,
358 eloop
.readers
[i
].eloop_data
,
359 eloop
.readers
[i
].user_data
);
360 if (eloop
.reader_table_changed
)
368 void eloop_terminate(void)
374 void eloop_destroy(void)
376 struct eloop_timeout
*timeout
, *prev
;
378 timeout
= eloop
.timeout
;
379 while (timeout
!= NULL
) {
381 timeout
= timeout
->next
;
389 int eloop_terminated(void)
391 return eloop
.terminate
;
395 void eloop_wait_for_read_sock(int sock
)
398 * TODO: wait for the file descriptor to have something available for