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
);
46 int max_sock
, reader_count
;
47 struct eloop_sock
*readers
;
49 struct eloop_timeout
*timeout
;
52 struct eloop_signal
*signals
;
54 int pending_terminate
;
57 int reader_table_changed
;
60 static struct eloop_data eloop
;
63 int eloop_init(void *user_data
)
65 memset(&eloop
, 0, sizeof(eloop
));
66 eloop
.user_data
= user_data
;
71 int eloop_register_read_sock(int sock
,
72 void (*handler
)(int sock
, void *eloop_ctx
,
74 void *eloop_data
, void *user_data
)
76 struct eloop_sock
*tmp
;
78 tmp
= (struct eloop_sock
*)
79 realloc(eloop
.readers
,
80 (eloop
.reader_count
+ 1) * sizeof(struct eloop_sock
));
84 tmp
[eloop
.reader_count
].sock
= sock
;
85 tmp
[eloop
.reader_count
].eloop_data
= eloop_data
;
86 tmp
[eloop
.reader_count
].user_data
= user_data
;
87 tmp
[eloop
.reader_count
].handler
= handler
;
90 if (sock
> eloop
.max_sock
)
91 eloop
.max_sock
= sock
;
92 eloop
.reader_table_changed
= 1;
98 void eloop_unregister_read_sock(int sock
)
102 if (eloop
.readers
== NULL
|| eloop
.reader_count
== 0)
105 for (i
= 0; i
< eloop
.reader_count
; i
++) {
106 if (eloop
.readers
[i
].sock
== sock
)
109 if (i
== eloop
.reader_count
)
111 if (i
!= eloop
.reader_count
- 1) {
112 memmove(&eloop
.readers
[i
], &eloop
.readers
[i
+ 1],
113 (eloop
.reader_count
- i
- 1) *
114 sizeof(struct eloop_sock
));
116 eloop
.reader_count
--;
117 eloop
.reader_table_changed
= 1;
121 int eloop_register_timeout(unsigned int secs
, unsigned int usecs
,
122 void (*handler
)(void *eloop_ctx
, void *timeout_ctx
),
123 void *eloop_data
, void *user_data
)
125 struct eloop_timeout
*timeout
, *tmp
, *prev
;
127 timeout
= (struct eloop_timeout
*) malloc(sizeof(*timeout
));
130 os_get_time(&timeout
->time
);
131 timeout
->time
.sec
+= secs
;
132 timeout
->time
.usec
+= usecs
;
133 while (timeout
->time
.usec
>= 1000000) {
135 timeout
->time
.usec
-= 1000000;
137 timeout
->eloop_data
= eloop_data
;
138 timeout
->user_data
= user_data
;
139 timeout
->handler
= handler
;
140 timeout
->next
= NULL
;
142 if (eloop
.timeout
== NULL
) {
143 eloop
.timeout
= timeout
;
149 while (tmp
!= NULL
) {
150 if (os_time_before(&timeout
->time
, &tmp
->time
))
157 timeout
->next
= eloop
.timeout
;
158 eloop
.timeout
= timeout
;
160 timeout
->next
= prev
->next
;
161 prev
->next
= timeout
;
168 int eloop_cancel_timeout(void (*handler
)(void *eloop_ctx
, void *sock_ctx
),
169 void *eloop_data
, void *user_data
)
171 struct eloop_timeout
*timeout
, *prev
, *next
;
175 timeout
= eloop
.timeout
;
176 while (timeout
!= NULL
) {
177 next
= timeout
->next
;
179 if (timeout
->handler
== handler
&&
180 (timeout
->eloop_data
== eloop_data
||
181 eloop_data
== ELOOP_ALL_CTX
) &&
182 (timeout
->user_data
== user_data
||
183 user_data
== ELOOP_ALL_CTX
)) {
185 eloop
.timeout
= next
;
200 /* TODO: replace with suitable signal handler */
202 static void eloop_handle_signal(int sig
)
207 for (i
= 0; i
< eloop
.signal_count
; i
++) {
208 if (eloop
.signals
[i
].sig
== sig
) {
209 eloop
.signals
[i
].signaled
++;
217 static void eloop_process_pending_signals(void)
221 if (eloop
.signaled
== 0)
225 if (eloop
.pending_terminate
) {
226 eloop
.pending_terminate
= 0;
229 for (i
= 0; i
< eloop
.signal_count
; i
++) {
230 if (eloop
.signals
[i
].signaled
) {
231 eloop
.signals
[i
].signaled
= 0;
232 eloop
.signals
[i
].handler(eloop
.signals
[i
].sig
,
234 eloop
.signals
[i
].user_data
);
240 int eloop_register_signal(int sig
,
241 void (*handler
)(int sig
, void *eloop_ctx
,
245 struct eloop_signal
*tmp
;
247 tmp
= (struct eloop_signal
*)
248 realloc(eloop
.signals
,
249 (eloop
.signal_count
+ 1) *
250 sizeof(struct eloop_signal
));
254 tmp
[eloop
.signal_count
].sig
= sig
;
255 tmp
[eloop
.signal_count
].user_data
= user_data
;
256 tmp
[eloop
.signal_count
].handler
= handler
;
257 tmp
[eloop
.signal_count
].signaled
= 0;
258 eloop
.signal_count
++;
261 /* TODO: register signal handler */
267 int eloop_register_signal_terminate(void (*handler
)(int sig
, void *eloop_ctx
,
272 /* TODO: for example */
273 int ret
= eloop_register_signal(SIGINT
, handler
, user_data
);
275 ret
= eloop_register_signal(SIGTERM
, handler
, user_data
);
282 int eloop_register_signal_reconfig(void (*handler
)(int sig
, void *eloop_ctx
,
287 /* TODO: for example */
288 return eloop_register_signal(SIGHUP
, handler
, user_data
);
297 struct os_time tv
, now
;
299 while (!eloop
.terminate
&&
300 (eloop
.timeout
|| eloop
.reader_count
> 0)) {
303 if (os_time_before(&now
, &eloop
.timeout
->time
))
304 os_time_sub(&eloop
.timeout
->time
, &now
, &tv
);
306 tv
.sec
= tv
.usec
= 0;
310 * TODO: wait for any event (read socket ready, timeout (tv),
313 os_sleep(1, 0); /* just a dummy wait for testing */
315 eloop_process_pending_signals();
317 /* check if some registered timeouts have occurred */
319 struct eloop_timeout
*tmp
;
322 if (!os_time_before(&now
, &eloop
.timeout
->time
)) {
324 eloop
.timeout
= eloop
.timeout
->next
;
325 tmp
->handler(tmp
->eloop_data
,
332 eloop
.reader_table_changed
= 0;
333 for (i
= 0; i
< eloop
.reader_count
; i
++) {
335 * TODO: call each handler that has pending data to
338 if (0 /* TODO: eloop.readers[i].sock ready */) {
339 eloop
.readers
[i
].handler(
340 eloop
.readers
[i
].sock
,
341 eloop
.readers
[i
].eloop_data
,
342 eloop
.readers
[i
].user_data
);
343 if (eloop
.reader_table_changed
)
351 void eloop_terminate(void)
357 void eloop_destroy(void)
359 struct eloop_timeout
*timeout
, *prev
;
361 timeout
= eloop
.timeout
;
362 while (timeout
!= NULL
) {
364 timeout
= timeout
->next
;
372 int eloop_terminated(void)
374 return eloop
.terminate
;
378 void eloop_wait_for_read_sock(int sock
)
381 * TODO: wait for the file descriptor to have something available for
387 void * eloop_get_user_data(void)
389 return eloop
.user_data
;