eloop_none.c
Go to the documentation of this file.
00001 /*
00002  * Event loop - empty template (basic structure, but no OS specific operations)
00003  * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 #include "includes.h"
00016 
00017 #include "common.h"
00018 #include "eloop.h"
00019 
00020 
00021 struct eloop_sock {
00022         int sock;
00023         void *eloop_data;
00024         void *user_data;
00025         void (*handler)(int sock, void *eloop_ctx, void *sock_ctx);
00026 };
00027 
00028 struct eloop_timeout {
00029         struct os_time time;
00030         void *eloop_data;
00031         void *user_data;
00032         void (*handler)(void *eloop_ctx, void *sock_ctx);
00033         struct eloop_timeout *next;
00034 };
00035 
00036 struct eloop_signal {
00037         int sig;
00038         void *user_data;
00039         void (*handler)(int sig, void *eloop_ctx, void *signal_ctx);
00040         int signaled;
00041 };
00042 
00043 struct eloop_data {
00044         int max_sock, reader_count;
00045         struct eloop_sock *readers;
00046 
00047         struct eloop_timeout *timeout;
00048 
00049         int signal_count;
00050         struct eloop_signal *signals;
00051         int signaled;
00052         int pending_terminate;
00053 
00054         int terminate;
00055         int reader_table_changed;
00056 };
00057 
00058 static struct eloop_data eloop;
00059 
00060 
00061 int eloop_init(void)
00062 {
00063         memset(&eloop, 0, sizeof(eloop));
00064         return 0;
00065 }
00066 
00067 
00068 int eloop_register_read_sock(int sock,
00069                              void (*handler)(int sock, void *eloop_ctx,
00070                                              void *sock_ctx),
00071                              void *eloop_data, void *user_data)
00072 {
00073         struct eloop_sock *tmp;
00074 
00075         tmp = (struct eloop_sock *)
00076                 realloc(eloop.readers,
00077                         (eloop.reader_count + 1) * sizeof(struct eloop_sock));
00078         if (tmp == NULL)
00079                 return -1;
00080 
00081         tmp[eloop.reader_count].sock = sock;
00082         tmp[eloop.reader_count].eloop_data = eloop_data;
00083         tmp[eloop.reader_count].user_data = user_data;
00084         tmp[eloop.reader_count].handler = handler;
00085         eloop.reader_count++;
00086         eloop.readers = tmp;
00087         if (sock > eloop.max_sock)
00088                 eloop.max_sock = sock;
00089         eloop.reader_table_changed = 1;
00090 
00091         return 0;
00092 }
00093 
00094 
00095 void eloop_unregister_read_sock(int sock)
00096 {
00097         int i;
00098 
00099         if (eloop.readers == NULL || eloop.reader_count == 0)
00100                 return;
00101 
00102         for (i = 0; i < eloop.reader_count; i++) {
00103                 if (eloop.readers[i].sock == sock)
00104                         break;
00105         }
00106         if (i == eloop.reader_count)
00107                 return;
00108         if (i != eloop.reader_count - 1) {
00109                 memmove(&eloop.readers[i], &eloop.readers[i + 1],
00110                         (eloop.reader_count - i - 1) *
00111                         sizeof(struct eloop_sock));
00112         }
00113         eloop.reader_count--;
00114         eloop.reader_table_changed = 1;
00115 }
00116 
00117 
00118 int eloop_register_timeout(unsigned int secs, unsigned int usecs,
00119                            void (*handler)(void *eloop_ctx, void *timeout_ctx),
00120                            void *eloop_data, void *user_data)
00121 {
00122         struct eloop_timeout *timeout, *tmp, *prev;
00123 
00124         timeout = (struct eloop_timeout *) malloc(sizeof(*timeout));
00125         if (timeout == NULL)
00126                 return -1;
00127         os_get_time(&timeout->time);
00128         timeout->time.sec += secs;
00129         timeout->time.usec += usecs;
00130         while (timeout->time.usec >= 1000000) {
00131                 timeout->time.sec++;
00132                 timeout->time.usec -= 1000000;
00133         }
00134         timeout->eloop_data = eloop_data;
00135         timeout->user_data = user_data;
00136         timeout->handler = handler;
00137         timeout->next = NULL;
00138 
00139         if (eloop.timeout == NULL) {
00140                 eloop.timeout = timeout;
00141                 return 0;
00142         }
00143 
00144         prev = NULL;
00145         tmp = eloop.timeout;
00146         while (tmp != NULL) {
00147                 if (os_time_before(&timeout->time, &tmp->time))
00148                         break;
00149                 prev = tmp;
00150                 tmp = tmp->next;
00151         }
00152 
00153         if (prev == NULL) {
00154                 timeout->next = eloop.timeout;
00155                 eloop.timeout = timeout;
00156         } else {
00157                 timeout->next = prev->next;
00158                 prev->next = timeout;
00159         }
00160 
00161         return 0;
00162 }
00163 
00164 
00165 int eloop_cancel_timeout(void (*handler)(void *eloop_ctx, void *sock_ctx),
00166                          void *eloop_data, void *user_data)
00167 {
00168         struct eloop_timeout *timeout, *prev, *next;
00169         int removed = 0;
00170 
00171         prev = NULL;
00172         timeout = eloop.timeout;
00173         while (timeout != NULL) {
00174                 next = timeout->next;
00175 
00176                 if (timeout->handler == handler &&
00177                     (timeout->eloop_data == eloop_data ||
00178                      eloop_data == ELOOP_ALL_CTX) &&
00179                     (timeout->user_data == user_data ||
00180                      user_data == ELOOP_ALL_CTX)) {
00181                         if (prev == NULL)
00182                                 eloop.timeout = next;
00183                         else
00184                                 prev->next = next;
00185                         free(timeout);
00186                         removed++;
00187                 } else
00188                         prev = timeout;
00189 
00190                 timeout = next;
00191         }
00192 
00193         return removed;
00194 }
00195 
00196 
00197 int eloop_is_timeout_registered(void (*handler)(void *eloop_ctx,
00198                                                 void *timeout_ctx),
00199                                 void *eloop_data, void *user_data)
00200 {
00201         struct eloop_timeout *tmp;
00202 
00203         tmp = eloop.timeout;
00204         while (tmp != NULL) {
00205                 if (tmp->handler == handler &&
00206                     tmp->eloop_data == eloop_data &&
00207                     tmp->user_data == user_data)
00208                         return 1;
00209 
00210                 tmp = tmp->next;
00211         }
00212 
00213         return 0;
00214 }
00215 
00216 
00217 /* TODO: replace with suitable signal handler */
00218 #if 0
00219 static void eloop_handle_signal(int sig)
00220 {
00221         int i;
00222 
00223         eloop.signaled++;
00224         for (i = 0; i < eloop.signal_count; i++) {
00225                 if (eloop.signals[i].sig == sig) {
00226                         eloop.signals[i].signaled++;
00227                         break;
00228                 }
00229         }
00230 }
00231 #endif
00232 
00233 
00234 static void eloop_process_pending_signals(void)
00235 {
00236         int i;
00237 
00238         if (eloop.signaled == 0)
00239                 return;
00240         eloop.signaled = 0;
00241 
00242         if (eloop.pending_terminate) {
00243                 eloop.pending_terminate = 0;
00244         }
00245 
00246         for (i = 0; i < eloop.signal_count; i++) {
00247                 if (eloop.signals[i].signaled) {
00248                         eloop.signals[i].signaled = 0;
00249                         eloop.signals[i].handler(eloop.signals[i].sig,
00250                                                  eloop.user_data,
00251                                                  eloop.signals[i].user_data);
00252                 }
00253         }
00254 }
00255 
00256 
00257 int eloop_register_signal(int sig,
00258                           void (*handler)(int sig, void *eloop_ctx,
00259                                           void *signal_ctx),
00260                           void *user_data)
00261 {
00262         struct eloop_signal *tmp;
00263 
00264         tmp = (struct eloop_signal *)
00265                 realloc(eloop.signals,
00266                         (eloop.signal_count + 1) *
00267                         sizeof(struct eloop_signal));
00268         if (tmp == NULL)
00269                 return -1;
00270 
00271         tmp[eloop.signal_count].sig = sig;
00272         tmp[eloop.signal_count].user_data = user_data;
00273         tmp[eloop.signal_count].handler = handler;
00274         tmp[eloop.signal_count].signaled = 0;
00275         eloop.signal_count++;
00276         eloop.signals = tmp;
00277 
00278         /* TODO: register signal handler */
00279 
00280         return 0;
00281 }
00282 
00283 
00284 int eloop_register_signal_terminate(void (*handler)(int sig, void *eloop_ctx,
00285                                                     void *signal_ctx),
00286                                     void *user_data)
00287 {
00288 #if 0
00289         /* TODO: for example */
00290         int ret = eloop_register_signal(SIGINT, handler, user_data);
00291         if (ret == 0)
00292                 ret = eloop_register_signal(SIGTERM, handler, user_data);
00293         return ret;
00294 #endif
00295         return 0;
00296 }
00297 
00298 
00299 int eloop_register_signal_reconfig(void (*handler)(int sig, void *eloop_ctx,
00300                                                    void *signal_ctx),
00301                                    void *user_data)
00302 {
00303 #if 0
00304         /* TODO: for example */
00305         return eloop_register_signal(SIGHUP, handler, user_data);
00306 #endif
00307         return 0;
00308 }
00309 
00310 
00311 void eloop_run(void)
00312 {
00313         int i;
00314         struct os_time tv, now;
00315 
00316         while (!eloop.terminate &&
00317                 (eloop.timeout || eloop.reader_count > 0)) {
00318                 if (eloop.timeout) {
00319                         os_get_time(&now);
00320                         if (os_time_before(&now, &eloop.timeout->time))
00321                                 os_time_sub(&eloop.timeout->time, &now, &tv);
00322                         else
00323                                 tv.sec = tv.usec = 0;
00324                 }
00325 
00326                 /*
00327                  * TODO: wait for any event (read socket ready, timeout (tv),
00328                  * signal
00329                  */
00330                 os_sleep(1, 0); /* just a dummy wait for testing */
00331 
00332                 eloop_process_pending_signals();
00333 
00334                 /* check if some registered timeouts have occurred */
00335                 if (eloop.timeout) {
00336                         struct eloop_timeout *tmp;
00337 
00338                         os_get_time(&now);
00339                         if (!os_time_before(&now, &eloop.timeout->time)) {
00340                                 tmp = eloop.timeout;
00341                                 eloop.timeout = eloop.timeout->next;
00342                                 tmp->handler(tmp->eloop_data,
00343                                              tmp->user_data);
00344                                 free(tmp);
00345                         }
00346 
00347                 }
00348 
00349                 eloop.reader_table_changed = 0;
00350                 for (i = 0; i < eloop.reader_count; i++) {
00351                         /*
00352                          * TODO: call each handler that has pending data to
00353                          * read
00354                          */
00355                         if (0 /* TODO: eloop.readers[i].sock ready */) {
00356                                 eloop.readers[i].handler(
00357                                         eloop.readers[i].sock,
00358                                         eloop.readers[i].eloop_data,
00359                                         eloop.readers[i].user_data);
00360                                 if (eloop.reader_table_changed)
00361                                         break;
00362                         }
00363                 }
00364         }
00365 }
00366 
00367 
00368 void eloop_terminate(void)
00369 {
00370         eloop.terminate = 1;
00371 }
00372 
00373 
00374 void eloop_destroy(void)
00375 {
00376         struct eloop_timeout *timeout, *prev;
00377 
00378         timeout = eloop.timeout;
00379         while (timeout != NULL) {
00380                 prev = timeout;
00381                 timeout = timeout->next;
00382                 free(prev);
00383         }
00384         free(eloop.readers);
00385         free(eloop.signals);
00386 }
00387 
00388 
00389 int eloop_terminated(void)
00390 {
00391         return eloop.terminate;
00392 }
00393 
00394 
00395 void eloop_wait_for_read_sock(int sock)
00396 {
00397         /*
00398          * TODO: wait for the file descriptor to have something available for
00399          * reading
00400          */
00401 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:35