~ubuntu-branches/ubuntu/gutsy/wpasupplicant/gutsy

« back to all changes in this revision

Viewing changes to eloop_none.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2007-08-26 16:06:57 UTC
  • mto: This revision was merged to the branch mainline in revision 26.
  • Revision ID: james.westby@ubuntu.com-20070826160657-mxk5ivjjh65ptxlr
Tags: upstream-0.6.0+0.5.8
ImportĀ upstreamĀ versionĀ 0.6.0+0.5.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Event loop - empty template (basic structure, but no OS specific operations)
 
3
 * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
 
4
 *
 
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.
 
8
 *
 
9
 * Alternatively, this software may be distributed under the terms of BSD
 
10
 * license.
 
11
 *
 
12
 * See README and COPYING for more details.
 
13
 */
 
14
 
 
15
#include "includes.h"
 
16
 
 
17
#include "common.h"
 
18
#include "eloop.h"
 
19
 
 
20
 
 
21
struct eloop_sock {
 
22
        int sock;
 
23
        void *eloop_data;
 
24
        void *user_data;
 
25
        void (*handler)(int sock, void *eloop_ctx, void *sock_ctx);
 
26
};
 
27
 
 
28
struct eloop_timeout {
 
29
        struct os_time time;
 
30
        void *eloop_data;
 
31
        void *user_data;
 
32
        void (*handler)(void *eloop_ctx, void *sock_ctx);
 
33
        struct eloop_timeout *next;
 
34
};
 
35
 
 
36
struct eloop_signal {
 
37
        int sig;
 
38
        void *user_data;
 
39
        void (*handler)(int sig, void *eloop_ctx, void *signal_ctx);
 
40
        int signaled;
 
41
};
 
42
 
 
43
struct eloop_data {
 
44
        void *user_data;
 
45
 
 
46
        int max_sock, reader_count;
 
47
        struct eloop_sock *readers;
 
48
 
 
49
        struct eloop_timeout *timeout;
 
50
 
 
51
        int signal_count;
 
52
        struct eloop_signal *signals;
 
53
        int signaled;
 
54
        int pending_terminate;
 
55
 
 
56
        int terminate;
 
57
        int reader_table_changed;
 
58
};
 
59
 
 
60
static struct eloop_data eloop;
 
61
 
 
62
 
 
63
int eloop_init(void *user_data)
 
64
{
 
65
        memset(&eloop, 0, sizeof(eloop));
 
66
        eloop.user_data = user_data;
 
67
        return 0;
 
68
}
 
69
 
 
70
 
 
71
int eloop_register_read_sock(int sock,
 
72
                             void (*handler)(int sock, void *eloop_ctx,
 
73
                                             void *sock_ctx),
 
74
                             void *eloop_data, void *user_data)
 
75
{
 
76
        struct eloop_sock *tmp;
 
77
 
 
78
        tmp = (struct eloop_sock *)
 
79
                realloc(eloop.readers,
 
80
                        (eloop.reader_count + 1) * sizeof(struct eloop_sock));
 
81
        if (tmp == NULL)
 
82
                return -1;
 
83
 
 
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;
 
88
        eloop.reader_count++;
 
89
        eloop.readers = tmp;
 
90
        if (sock > eloop.max_sock)
 
91
                eloop.max_sock = sock;
 
92
        eloop.reader_table_changed = 1;
 
93
 
 
94
        return 0;
 
95
}
 
96
 
 
97
 
 
98
void eloop_unregister_read_sock(int sock)
 
99
{
 
100
        int i;
 
101
 
 
102
        if (eloop.readers == NULL || eloop.reader_count == 0)
 
103
                return;
 
104
 
 
105
        for (i = 0; i < eloop.reader_count; i++) {
 
106
                if (eloop.readers[i].sock == sock)
 
107
                        break;
 
108
        }
 
109
        if (i == eloop.reader_count)
 
110
                return;
 
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));
 
115
        }
 
116
        eloop.reader_count--;
 
117
        eloop.reader_table_changed = 1;
 
118
}
 
119
 
 
120
 
 
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)
 
124
{
 
125
        struct eloop_timeout *timeout, *tmp, *prev;
 
126
 
 
127
        timeout = (struct eloop_timeout *) malloc(sizeof(*timeout));
 
128
        if (timeout == NULL)
 
129
                return -1;
 
130
        os_get_time(&timeout->time);
 
131
        timeout->time.sec += secs;
 
132
        timeout->time.usec += usecs;
 
133
        while (timeout->time.usec >= 1000000) {
 
134
                timeout->time.sec++;
 
135
                timeout->time.usec -= 1000000;
 
136
        }
 
137
        timeout->eloop_data = eloop_data;
 
138
        timeout->user_data = user_data;
 
139
        timeout->handler = handler;
 
140
        timeout->next = NULL;
 
141
 
 
142
        if (eloop.timeout == NULL) {
 
143
                eloop.timeout = timeout;
 
144
                return 0;
 
145
        }
 
146
 
 
147
        prev = NULL;
 
148
        tmp = eloop.timeout;
 
149
        while (tmp != NULL) {
 
150
                if (os_time_before(&timeout->time, &tmp->time))
 
151
                        break;
 
152
                prev = tmp;
 
153
                tmp = tmp->next;
 
154
        }
 
155
 
 
156
        if (prev == NULL) {
 
157
                timeout->next = eloop.timeout;
 
158
                eloop.timeout = timeout;
 
159
        } else {
 
160
                timeout->next = prev->next;
 
161
                prev->next = timeout;
 
162
        }
 
163
 
 
164
        return 0;
 
165
}
 
166
 
 
167
 
 
168
int eloop_cancel_timeout(void (*handler)(void *eloop_ctx, void *sock_ctx),
 
169
                         void *eloop_data, void *user_data)
 
170
{
 
171
        struct eloop_timeout *timeout, *prev, *next;
 
172
        int removed = 0;
 
173
 
 
174
        prev = NULL;
 
175
        timeout = eloop.timeout;
 
176
        while (timeout != NULL) {
 
177
                next = timeout->next;
 
178
 
 
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)) {
 
184
                        if (prev == NULL)
 
185
                                eloop.timeout = next;
 
186
                        else
 
187
                                prev->next = next;
 
188
                        free(timeout);
 
189
                        removed++;
 
190
                } else
 
191
                        prev = timeout;
 
192
 
 
193
                timeout = next;
 
194
        }
 
195
 
 
196
        return removed;
 
197
}
 
198
 
 
199
 
 
200
/* TODO: replace with suitable signal handler */
 
201
#if 0
 
202
static void eloop_handle_signal(int sig)
 
203
{
 
204
        int i;
 
205
 
 
206
        eloop.signaled++;
 
207
        for (i = 0; i < eloop.signal_count; i++) {
 
208
                if (eloop.signals[i].sig == sig) {
 
209
                        eloop.signals[i].signaled++;
 
210
                        break;
 
211
                }
 
212
        }
 
213
}
 
214
#endif
 
215
 
 
216
 
 
217
static void eloop_process_pending_signals(void)
 
218
{
 
219
        int i;
 
220
 
 
221
        if (eloop.signaled == 0)
 
222
                return;
 
223
        eloop.signaled = 0;
 
224
 
 
225
        if (eloop.pending_terminate) {
 
226
                eloop.pending_terminate = 0;
 
227
        }
 
228
 
 
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,
 
233
                                                 eloop.user_data,
 
234
                                                 eloop.signals[i].user_data);
 
235
                }
 
236
        }
 
237
}
 
238
 
 
239
 
 
240
int eloop_register_signal(int sig,
 
241
                          void (*handler)(int sig, void *eloop_ctx,
 
242
                                          void *signal_ctx),
 
243
                          void *user_data)
 
244
{
 
245
        struct eloop_signal *tmp;
 
246
 
 
247
        tmp = (struct eloop_signal *)
 
248
                realloc(eloop.signals,
 
249
                        (eloop.signal_count + 1) *
 
250
                        sizeof(struct eloop_signal));
 
251
        if (tmp == NULL)
 
252
                return -1;
 
253
 
 
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++;
 
259
        eloop.signals = tmp;
 
260
 
 
261
        /* TODO: register signal handler */
 
262
 
 
263
        return 0;
 
264
}
 
265
 
 
266
 
 
267
int eloop_register_signal_terminate(void (*handler)(int sig, void *eloop_ctx,
 
268
                                                    void *signal_ctx),
 
269
                                    void *user_data)
 
270
{
 
271
#if 0
 
272
        /* TODO: for example */
 
273
        int ret = eloop_register_signal(SIGINT, handler, user_data);
 
274
        if (ret == 0)
 
275
                ret = eloop_register_signal(SIGTERM, handler, user_data);
 
276
        return ret;
 
277
#endif
 
278
        return 0;
 
279
}
 
280
 
 
281
 
 
282
int eloop_register_signal_reconfig(void (*handler)(int sig, void *eloop_ctx,
 
283
                                                   void *signal_ctx),
 
284
                                   void *user_data)
 
285
{
 
286
#if 0
 
287
        /* TODO: for example */
 
288
        return eloop_register_signal(SIGHUP, handler, user_data);
 
289
#endif
 
290
        return 0;
 
291
}
 
292
 
 
293
 
 
294
void eloop_run(void)
 
295
{
 
296
        int i;
 
297
        struct os_time tv, now;
 
298
 
 
299
        while (!eloop.terminate &&
 
300
                (eloop.timeout || eloop.reader_count > 0)) {
 
301
                if (eloop.timeout) {
 
302
                        os_get_time(&now);
 
303
                        if (os_time_before(&now, &eloop.timeout->time))
 
304
                                os_time_sub(&eloop.timeout->time, &now, &tv);
 
305
                        else
 
306
                                tv.sec = tv.usec = 0;
 
307
                }
 
308
 
 
309
                /*
 
310
                 * TODO: wait for any event (read socket ready, timeout (tv),
 
311
                 * signal
 
312
                 */
 
313
                os_sleep(1, 0); /* just a dummy wait for testing */
 
314
 
 
315
                eloop_process_pending_signals();
 
316
 
 
317
                /* check if some registered timeouts have occurred */
 
318
                if (eloop.timeout) {
 
319
                        struct eloop_timeout *tmp;
 
320
 
 
321
                        os_get_time(&now);
 
322
                        if (!os_time_before(&now, &eloop.timeout->time)) {
 
323
                                tmp = eloop.timeout;
 
324
                                eloop.timeout = eloop.timeout->next;
 
325
                                tmp->handler(tmp->eloop_data,
 
326
                                             tmp->user_data);
 
327
                                free(tmp);
 
328
                        }
 
329
 
 
330
                }
 
331
 
 
332
                eloop.reader_table_changed = 0;
 
333
                for (i = 0; i < eloop.reader_count; i++) {
 
334
                        /*
 
335
                         * TODO: call each handler that has pending data to
 
336
                         * read
 
337
                         */
 
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)
 
344
                                        break;
 
345
                        }
 
346
                }
 
347
        }
 
348
}
 
349
 
 
350
 
 
351
void eloop_terminate(void)
 
352
{
 
353
        eloop.terminate = 1;
 
354
}
 
355
 
 
356
 
 
357
void eloop_destroy(void)
 
358
{
 
359
        struct eloop_timeout *timeout, *prev;
 
360
 
 
361
        timeout = eloop.timeout;
 
362
        while (timeout != NULL) {
 
363
                prev = timeout;
 
364
                timeout = timeout->next;
 
365
                free(prev);
 
366
        }
 
367
        free(eloop.readers);
 
368
        free(eloop.signals);
 
369
}
 
370
 
 
371
 
 
372
int eloop_terminated(void)
 
373
{
 
374
        return eloop.terminate;
 
375
}
 
376
 
 
377
 
 
378
void eloop_wait_for_read_sock(int sock)
 
379
{
 
380
        /*
 
381
         * TODO: wait for the file descriptor to have something available for
 
382
         * reading
 
383
         */
 
384
}
 
385
 
 
386
 
 
387
void * eloop_get_user_data(void)
 
388
{
 
389
        return eloop.user_data;
 
390
}