Updated through tag hostap_2_5 from git://w1.fi/hostap.git
[mech_eap.git] / libeap / src / utils / eloop.c
1 /*
2  * Event loop based on select() loop
3  * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8
9 #include "includes.h"
10 #include <assert.h>
11
12 #include "common.h"
13 #include "trace.h"
14 #include "list.h"
15 #include "eloop.h"
16
17 #if defined(CONFIG_ELOOP_POLL) && defined(CONFIG_ELOOP_EPOLL)
18 #error Do not define both of poll and epoll
19 #endif
20
21 #if !defined(CONFIG_ELOOP_POLL) && !defined(CONFIG_ELOOP_EPOLL)
22 #define CONFIG_ELOOP_SELECT
23 #endif
24
25 #ifdef CONFIG_ELOOP_POLL
26 #include <poll.h>
27 #endif /* CONFIG_ELOOP_POLL */
28
29 #ifdef CONFIG_ELOOP_EPOLL
30 #include <sys/epoll.h>
31 #endif /* CONFIG_ELOOP_EPOLL */
32
33 struct eloop_sock {
34         int sock;
35         void *eloop_data;
36         void *user_data;
37         eloop_sock_handler handler;
38         WPA_TRACE_REF(eloop);
39         WPA_TRACE_REF(user);
40         WPA_TRACE_INFO
41 };
42
43 struct eloop_timeout {
44         struct dl_list list;
45         struct os_reltime time;
46         void *eloop_data;
47         void *user_data;
48         eloop_timeout_handler handler;
49         WPA_TRACE_REF(eloop);
50         WPA_TRACE_REF(user);
51         WPA_TRACE_INFO
52 };
53
54 struct eloop_signal {
55         int sig;
56         void *user_data;
57         eloop_signal_handler handler;
58         int signaled;
59 };
60
61 struct eloop_sock_table {
62         int count;
63         struct eloop_sock *table;
64         eloop_event_type type;
65         int changed;
66 };
67
68 struct eloop_data {
69         int max_sock;
70
71         int count; /* sum of all table counts */
72 #ifdef CONFIG_ELOOP_POLL
73         int max_pollfd_map; /* number of pollfds_map currently allocated */
74         int max_poll_fds; /* number of pollfds currently allocated */
75         struct pollfd *pollfds;
76         struct pollfd **pollfds_map;
77 #endif /* CONFIG_ELOOP_POLL */
78 #ifdef CONFIG_ELOOP_EPOLL
79         int epollfd;
80         int epoll_max_event_num;
81         int epoll_max_fd;
82         struct eloop_sock *epoll_table;
83         struct epoll_event *epoll_events;
84 #endif /* CONFIG_ELOOP_EPOLL */
85         struct eloop_sock_table readers;
86         struct eloop_sock_table writers;
87         struct eloop_sock_table exceptions;
88
89         struct dl_list timeout;
90
91         int signal_count;
92         struct eloop_signal *signals;
93         int signaled;
94         int pending_terminate;
95
96         int terminate;
97 };
98
99 static struct eloop_data eloop;
100
101
102 #ifdef WPA_TRACE
103
104 static void eloop_sigsegv_handler(int sig)
105 {
106         wpa_trace_show("eloop SIGSEGV");
107         abort();
108 }
109
110 static void eloop_trace_sock_add_ref(struct eloop_sock_table *table)
111 {
112         int i;
113         if (table == NULL || table->table == NULL)
114                 return;
115         for (i = 0; i < table->count; i++) {
116                 wpa_trace_add_ref(&table->table[i], eloop,
117                                   table->table[i].eloop_data);
118                 wpa_trace_add_ref(&table->table[i], user,
119                                   table->table[i].user_data);
120         }
121 }
122
123
124 static void eloop_trace_sock_remove_ref(struct eloop_sock_table *table)
125 {
126         int i;
127         if (table == NULL || table->table == NULL)
128                 return;
129         for (i = 0; i < table->count; i++) {
130                 wpa_trace_remove_ref(&table->table[i], eloop,
131                                      table->table[i].eloop_data);
132                 wpa_trace_remove_ref(&table->table[i], user,
133                                      table->table[i].user_data);
134         }
135 }
136
137 #else /* WPA_TRACE */
138
139 #define eloop_trace_sock_add_ref(table) do { } while (0)
140 #define eloop_trace_sock_remove_ref(table) do { } while (0)
141
142 #endif /* WPA_TRACE */
143
144
145 int eloop_init(void)
146 {
147         os_memset(&eloop, 0, sizeof(eloop));
148         dl_list_init(&eloop.timeout);
149 #ifdef CONFIG_ELOOP_EPOLL
150         eloop.epollfd = epoll_create1(0);
151         if (eloop.epollfd < 0) {
152                 wpa_printf(MSG_ERROR, "%s: epoll_create1 failed. %s\n",
153                            __func__, strerror(errno));
154                 return -1;
155         }
156         eloop.readers.type = EVENT_TYPE_READ;
157         eloop.writers.type = EVENT_TYPE_WRITE;
158         eloop.exceptions.type = EVENT_TYPE_EXCEPTION;
159 #endif /* CONFIG_ELOOP_EPOLL */
160 #ifdef WPA_TRACE
161         signal(SIGSEGV, eloop_sigsegv_handler);
162 #endif /* WPA_TRACE */
163         return 0;
164 }
165
166
167 static int eloop_sock_table_add_sock(struct eloop_sock_table *table,
168                                      int sock, eloop_sock_handler handler,
169                                      void *eloop_data, void *user_data)
170 {
171 #ifdef CONFIG_ELOOP_EPOLL
172         struct eloop_sock *temp_table;
173         struct epoll_event ev, *temp_events;
174         int next;
175 #endif /* CONFIG_ELOOP_EPOLL */
176         struct eloop_sock *tmp;
177         int new_max_sock;
178
179         if (sock > eloop.max_sock)
180                 new_max_sock = sock;
181         else
182                 new_max_sock = eloop.max_sock;
183
184         if (table == NULL)
185                 return -1;
186
187 #ifdef CONFIG_ELOOP_POLL
188         if (new_max_sock >= eloop.max_pollfd_map) {
189                 struct pollfd **nmap;
190                 nmap = os_realloc_array(eloop.pollfds_map, new_max_sock + 50,
191                                         sizeof(struct pollfd *));
192                 if (nmap == NULL)
193                         return -1;
194
195                 eloop.max_pollfd_map = new_max_sock + 50;
196                 eloop.pollfds_map = nmap;
197         }
198
199         if (eloop.count + 1 > eloop.max_poll_fds) {
200                 struct pollfd *n;
201                 int nmax = eloop.count + 1 + 50;
202                 n = os_realloc_array(eloop.pollfds, nmax,
203                                      sizeof(struct pollfd));
204                 if (n == NULL)
205                         return -1;
206
207                 eloop.max_poll_fds = nmax;
208                 eloop.pollfds = n;
209         }
210 #endif /* CONFIG_ELOOP_POLL */
211 #ifdef CONFIG_ELOOP_EPOLL
212         if (new_max_sock >= eloop.epoll_max_fd) {
213                 next = eloop.epoll_max_fd == 0 ? 16 : eloop.epoll_max_fd * 2;
214                 temp_table = os_realloc_array(eloop.epoll_table, next,
215                                               sizeof(struct eloop_sock));
216                 if (temp_table == NULL)
217                         return -1;
218
219                 eloop.epoll_max_fd = next;
220                 eloop.epoll_table = temp_table;
221         }
222
223         if (eloop.count + 1 > eloop.epoll_max_event_num) {
224                 next = eloop.epoll_max_event_num == 0 ? 8 :
225                         eloop.epoll_max_event_num * 2;
226                 temp_events = os_realloc_array(eloop.epoll_events, next,
227                                                sizeof(struct epoll_event));
228                 if (temp_events == NULL) {
229                         wpa_printf(MSG_ERROR, "%s: malloc for epoll failed. "
230                                    "%s\n", __func__, strerror(errno));
231                         return -1;
232                 }
233
234                 eloop.epoll_max_event_num = next;
235                 eloop.epoll_events = temp_events;
236         }
237 #endif /* CONFIG_ELOOP_EPOLL */
238
239         eloop_trace_sock_remove_ref(table);
240         tmp = os_realloc_array(table->table, table->count + 1,
241                                sizeof(struct eloop_sock));
242         if (tmp == NULL) {
243                 eloop_trace_sock_add_ref(table);
244                 return -1;
245         }
246
247         tmp[table->count].sock = sock;
248         tmp[table->count].eloop_data = eloop_data;
249         tmp[table->count].user_data = user_data;
250         tmp[table->count].handler = handler;
251         wpa_trace_record(&tmp[table->count]);
252         table->count++;
253         table->table = tmp;
254         eloop.max_sock = new_max_sock;
255         eloop.count++;
256         table->changed = 1;
257         eloop_trace_sock_add_ref(table);
258
259 #ifdef CONFIG_ELOOP_EPOLL
260         os_memset(&ev, 0, sizeof(ev));
261         switch (table->type) {
262         case EVENT_TYPE_READ:
263                 ev.events = EPOLLIN;
264                 break;
265         case EVENT_TYPE_WRITE:
266                 ev.events = EPOLLOUT;
267                 break;
268         /*
269          * Exceptions are always checked when using epoll, but I suppose it's
270          * possible that someone registered a socket *only* for exception
271          * handling.
272          */
273         case EVENT_TYPE_EXCEPTION:
274                 ev.events = EPOLLERR | EPOLLHUP;
275                 break;
276         }
277         ev.data.fd = sock;
278         if (epoll_ctl(eloop.epollfd, EPOLL_CTL_ADD, sock, &ev) < 0) {
279                 wpa_printf(MSG_ERROR, "%s: epoll_ctl(ADD) for fd=%d "
280                            "failed. %s\n", __func__, sock, strerror(errno));
281                 return -1;
282         }
283         os_memcpy(&eloop.epoll_table[sock], &table->table[table->count - 1],
284                   sizeof(struct eloop_sock));
285 #endif /* CONFIG_ELOOP_EPOLL */
286         return 0;
287 }
288
289
290 static void eloop_sock_table_remove_sock(struct eloop_sock_table *table,
291                                          int sock)
292 {
293         int i;
294
295         if (table == NULL || table->table == NULL || table->count == 0)
296                 return;
297
298         for (i = 0; i < table->count; i++) {
299                 if (table->table[i].sock == sock)
300                         break;
301         }
302         if (i == table->count)
303                 return;
304         eloop_trace_sock_remove_ref(table);
305         if (i != table->count - 1) {
306                 os_memmove(&table->table[i], &table->table[i + 1],
307                            (table->count - i - 1) *
308                            sizeof(struct eloop_sock));
309         }
310         table->count--;
311         eloop.count--;
312         table->changed = 1;
313         eloop_trace_sock_add_ref(table);
314 #ifdef CONFIG_ELOOP_EPOLL
315         if (epoll_ctl(eloop.epollfd, EPOLL_CTL_DEL, sock, NULL) < 0) {
316                 wpa_printf(MSG_ERROR, "%s: epoll_ctl(DEL) for fd=%d "
317                            "failed. %s\n", __func__, sock, strerror(errno));
318                 return;
319         }
320         os_memset(&eloop.epoll_table[sock], 0, sizeof(struct eloop_sock));
321 #endif /* CONFIG_ELOOP_EPOLL */
322 }
323
324
325 #ifdef CONFIG_ELOOP_POLL
326
327 static struct pollfd * find_pollfd(struct pollfd **pollfds_map, int fd, int mx)
328 {
329         if (fd < mx && fd >= 0)
330                 return pollfds_map[fd];
331         return NULL;
332 }
333
334
335 static int eloop_sock_table_set_fds(struct eloop_sock_table *readers,
336                                     struct eloop_sock_table *writers,
337                                     struct eloop_sock_table *exceptions,
338                                     struct pollfd *pollfds,
339                                     struct pollfd **pollfds_map,
340                                     int max_pollfd_map)
341 {
342         int i;
343         int nxt = 0;
344         int fd;
345         struct pollfd *pfd;
346
347         /* Clear pollfd lookup map. It will be re-populated below. */
348         os_memset(pollfds_map, 0, sizeof(struct pollfd *) * max_pollfd_map);
349
350         if (readers && readers->table) {
351                 for (i = 0; i < readers->count; i++) {
352                         fd = readers->table[i].sock;
353                         assert(fd >= 0 && fd < max_pollfd_map);
354                         pollfds[nxt].fd = fd;
355                         pollfds[nxt].events = POLLIN;
356                         pollfds[nxt].revents = 0;
357                         pollfds_map[fd] = &(pollfds[nxt]);
358                         nxt++;
359                 }
360         }
361
362         if (writers && writers->table) {
363                 for (i = 0; i < writers->count; i++) {
364                         /*
365                          * See if we already added this descriptor, update it
366                          * if so.
367                          */
368                         fd = writers->table[i].sock;
369                         assert(fd >= 0 && fd < max_pollfd_map);
370                         pfd = pollfds_map[fd];
371                         if (!pfd) {
372                                 pfd = &(pollfds[nxt]);
373                                 pfd->events = 0;
374                                 pfd->fd = fd;
375                                 pollfds[i].revents = 0;
376                                 pollfds_map[fd] = pfd;
377                                 nxt++;
378                         }
379                         pfd->events |= POLLOUT;
380                 }
381         }
382
383         /*
384          * Exceptions are always checked when using poll, but I suppose it's
385          * possible that someone registered a socket *only* for exception
386          * handling. Set the POLLIN bit in this case.
387          */
388         if (exceptions && exceptions->table) {
389                 for (i = 0; i < exceptions->count; i++) {
390                         /*
391                          * See if we already added this descriptor, just use it
392                          * if so.
393                          */
394                         fd = exceptions->table[i].sock;
395                         assert(fd >= 0 && fd < max_pollfd_map);
396                         pfd = pollfds_map[fd];
397                         if (!pfd) {
398                                 pfd = &(pollfds[nxt]);
399                                 pfd->events = POLLIN;
400                                 pfd->fd = fd;
401                                 pollfds[i].revents = 0;
402                                 pollfds_map[fd] = pfd;
403                                 nxt++;
404                         }
405                 }
406         }
407
408         return nxt;
409 }
410
411
412 static int eloop_sock_table_dispatch_table(struct eloop_sock_table *table,
413                                            struct pollfd **pollfds_map,
414                                            int max_pollfd_map,
415                                            short int revents)
416 {
417         int i;
418         struct pollfd *pfd;
419
420         if (!table || !table->table)
421                 return 0;
422
423         table->changed = 0;
424         for (i = 0; i < table->count; i++) {
425                 pfd = find_pollfd(pollfds_map, table->table[i].sock,
426                                   max_pollfd_map);
427                 if (!pfd)
428                         continue;
429
430                 if (!(pfd->revents & revents))
431                         continue;
432
433                 table->table[i].handler(table->table[i].sock,
434                                         table->table[i].eloop_data,
435                                         table->table[i].user_data);
436                 if (table->changed)
437                         return 1;
438         }
439
440         return 0;
441 }
442
443
444 static void eloop_sock_table_dispatch(struct eloop_sock_table *readers,
445                                       struct eloop_sock_table *writers,
446                                       struct eloop_sock_table *exceptions,
447                                       struct pollfd **pollfds_map,
448                                       int max_pollfd_map)
449 {
450         if (eloop_sock_table_dispatch_table(readers, pollfds_map,
451                                             max_pollfd_map, POLLIN | POLLERR |
452                                             POLLHUP))
453                 return; /* pollfds may be invalid at this point */
454
455         if (eloop_sock_table_dispatch_table(writers, pollfds_map,
456                                             max_pollfd_map, POLLOUT))
457                 return; /* pollfds may be invalid at this point */
458
459         eloop_sock_table_dispatch_table(exceptions, pollfds_map,
460                                         max_pollfd_map, POLLERR | POLLHUP);
461 }
462
463 #endif /* CONFIG_ELOOP_POLL */
464
465 #ifdef CONFIG_ELOOP_SELECT
466
467 static void eloop_sock_table_set_fds(struct eloop_sock_table *table,
468                                      fd_set *fds)
469 {
470         int i;
471
472         FD_ZERO(fds);
473
474         if (table->table == NULL)
475                 return;
476
477         for (i = 0; i < table->count; i++) {
478                 assert(table->table[i].sock >= 0);
479                 FD_SET(table->table[i].sock, fds);
480         }
481 }
482
483
484 static void eloop_sock_table_dispatch(struct eloop_sock_table *table,
485                                       fd_set *fds)
486 {
487         int i;
488
489         if (table == NULL || table->table == NULL)
490                 return;
491
492         table->changed = 0;
493         for (i = 0; i < table->count; i++) {
494                 if (FD_ISSET(table->table[i].sock, fds)) {
495                         table->table[i].handler(table->table[i].sock,
496                                                 table->table[i].eloop_data,
497                                                 table->table[i].user_data);
498                         if (table->changed)
499                                 break;
500                 }
501         }
502 }
503
504 #endif /* CONFIG_ELOOP_SELECT */
505
506
507 #ifdef CONFIG_ELOOP_EPOLL
508 static void eloop_sock_table_dispatch(struct epoll_event *events, int nfds)
509 {
510         struct eloop_sock *table;
511         int i;
512
513         for (i = 0; i < nfds; i++) {
514                 table = &eloop.epoll_table[events[i].data.fd];
515                 if (table->handler == NULL)
516                         continue;
517                 table->handler(table->sock, table->eloop_data,
518                                table->user_data);
519                 if (eloop.readers.changed ||
520                     eloop.writers.changed ||
521                     eloop.exceptions.changed)
522                         break;
523         }
524 }
525 #endif /* CONFIG_ELOOP_EPOLL */
526
527
528 static void eloop_sock_table_destroy(struct eloop_sock_table *table)
529 {
530         if (table) {
531                 int i;
532                 for (i = 0; i < table->count && table->table; i++) {
533                         wpa_printf(MSG_INFO, "ELOOP: remaining socket: "
534                                    "sock=%d eloop_data=%p user_data=%p "
535                                    "handler=%p",
536                                    table->table[i].sock,
537                                    table->table[i].eloop_data,
538                                    table->table[i].user_data,
539                                    table->table[i].handler);
540                         wpa_trace_dump_funcname("eloop unregistered socket "
541                                                 "handler",
542                                                 table->table[i].handler);
543                         wpa_trace_dump("eloop sock", &table->table[i]);
544                 }
545                 os_free(table->table);
546         }
547 }
548
549
550 int eloop_register_read_sock(int sock, eloop_sock_handler handler,
551                              void *eloop_data, void *user_data)
552 {
553         return eloop_register_sock(sock, EVENT_TYPE_READ, handler,
554                                    eloop_data, user_data);
555 }
556
557
558 void eloop_unregister_read_sock(int sock)
559 {
560         eloop_unregister_sock(sock, EVENT_TYPE_READ);
561 }
562
563
564 static struct eloop_sock_table *eloop_get_sock_table(eloop_event_type type)
565 {
566         switch (type) {
567         case EVENT_TYPE_READ:
568                 return &eloop.readers;
569         case EVENT_TYPE_WRITE:
570                 return &eloop.writers;
571         case EVENT_TYPE_EXCEPTION:
572                 return &eloop.exceptions;
573         }
574
575         return NULL;
576 }
577
578
579 int eloop_register_sock(int sock, eloop_event_type type,
580                         eloop_sock_handler handler,
581                         void *eloop_data, void *user_data)
582 {
583         struct eloop_sock_table *table;
584
585         assert(sock >= 0);
586         table = eloop_get_sock_table(type);
587         return eloop_sock_table_add_sock(table, sock, handler,
588                                          eloop_data, user_data);
589 }
590
591
592 void eloop_unregister_sock(int sock, eloop_event_type type)
593 {
594         struct eloop_sock_table *table;
595
596         table = eloop_get_sock_table(type);
597         eloop_sock_table_remove_sock(table, sock);
598 }
599
600
601 int eloop_register_timeout(unsigned int secs, unsigned int usecs,
602                            eloop_timeout_handler handler,
603                            void *eloop_data, void *user_data)
604 {
605         struct eloop_timeout *timeout, *tmp;
606         os_time_t now_sec;
607
608         timeout = os_zalloc(sizeof(*timeout));
609         if (timeout == NULL)
610                 return -1;
611         if (os_get_reltime(&timeout->time) < 0) {
612                 os_free(timeout);
613                 return -1;
614         }
615         now_sec = timeout->time.sec;
616         timeout->time.sec += secs;
617         if (timeout->time.sec < now_sec) {
618                 /*
619                  * Integer overflow - assume long enough timeout to be assumed
620                  * to be infinite, i.e., the timeout would never happen.
621                  */
622                 wpa_printf(MSG_DEBUG, "ELOOP: Too long timeout (secs=%u) to "
623                            "ever happen - ignore it", secs);
624                 os_free(timeout);
625                 return 0;
626         }
627         timeout->time.usec += usecs;
628         while (timeout->time.usec >= 1000000) {
629                 timeout->time.sec++;
630                 timeout->time.usec -= 1000000;
631         }
632         timeout->eloop_data = eloop_data;
633         timeout->user_data = user_data;
634         timeout->handler = handler;
635         wpa_trace_add_ref(timeout, eloop, eloop_data);
636         wpa_trace_add_ref(timeout, user, user_data);
637         wpa_trace_record(timeout);
638
639         /* Maintain timeouts in order of increasing time */
640         dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
641                 if (os_reltime_before(&timeout->time, &tmp->time)) {
642                         dl_list_add(tmp->list.prev, &timeout->list);
643                         return 0;
644                 }
645         }
646         dl_list_add_tail(&eloop.timeout, &timeout->list);
647
648         return 0;
649 }
650
651
652 static void eloop_remove_timeout(struct eloop_timeout *timeout)
653 {
654         dl_list_del(&timeout->list);
655         wpa_trace_remove_ref(timeout, eloop, timeout->eloop_data);
656         wpa_trace_remove_ref(timeout, user, timeout->user_data);
657         os_free(timeout);
658 }
659
660
661 int eloop_cancel_timeout(eloop_timeout_handler handler,
662                          void *eloop_data, void *user_data)
663 {
664         struct eloop_timeout *timeout, *prev;
665         int removed = 0;
666
667         dl_list_for_each_safe(timeout, prev, &eloop.timeout,
668                               struct eloop_timeout, list) {
669                 if (timeout->handler == handler &&
670                     (timeout->eloop_data == eloop_data ||
671                      eloop_data == ELOOP_ALL_CTX) &&
672                     (timeout->user_data == user_data ||
673                      user_data == ELOOP_ALL_CTX)) {
674                         eloop_remove_timeout(timeout);
675                         removed++;
676                 }
677         }
678
679         return removed;
680 }
681
682
683 int eloop_cancel_timeout_one(eloop_timeout_handler handler,
684                              void *eloop_data, void *user_data,
685                              struct os_reltime *remaining)
686 {
687         struct eloop_timeout *timeout, *prev;
688         int removed = 0;
689         struct os_reltime now;
690
691         os_get_reltime(&now);
692         remaining->sec = remaining->usec = 0;
693
694         dl_list_for_each_safe(timeout, prev, &eloop.timeout,
695                               struct eloop_timeout, list) {
696                 if (timeout->handler == handler &&
697                     (timeout->eloop_data == eloop_data) &&
698                     (timeout->user_data == user_data)) {
699                         removed = 1;
700                         if (os_reltime_before(&now, &timeout->time))
701                                 os_reltime_sub(&timeout->time, &now, remaining);
702                         eloop_remove_timeout(timeout);
703                         break;
704                 }
705         }
706         return removed;
707 }
708
709
710 int eloop_is_timeout_registered(eloop_timeout_handler handler,
711                                 void *eloop_data, void *user_data)
712 {
713         struct eloop_timeout *tmp;
714
715         dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
716                 if (tmp->handler == handler &&
717                     tmp->eloop_data == eloop_data &&
718                     tmp->user_data == user_data)
719                         return 1;
720         }
721
722         return 0;
723 }
724
725
726 int eloop_deplete_timeout(unsigned int req_secs, unsigned int req_usecs,
727                           eloop_timeout_handler handler, void *eloop_data,
728                           void *user_data)
729 {
730         struct os_reltime now, requested, remaining;
731         struct eloop_timeout *tmp;
732
733         dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
734                 if (tmp->handler == handler &&
735                     tmp->eloop_data == eloop_data &&
736                     tmp->user_data == user_data) {
737                         requested.sec = req_secs;
738                         requested.usec = req_usecs;
739                         os_get_reltime(&now);
740                         os_reltime_sub(&tmp->time, &now, &remaining);
741                         if (os_reltime_before(&requested, &remaining)) {
742                                 eloop_cancel_timeout(handler, eloop_data,
743                                                      user_data);
744                                 eloop_register_timeout(requested.sec,
745                                                        requested.usec,
746                                                        handler, eloop_data,
747                                                        user_data);
748                                 return 1;
749                         }
750                         return 0;
751                 }
752         }
753
754         return -1;
755 }
756
757
758 int eloop_replenish_timeout(unsigned int req_secs, unsigned int req_usecs,
759                             eloop_timeout_handler handler, void *eloop_data,
760                             void *user_data)
761 {
762         struct os_reltime now, requested, remaining;
763         struct eloop_timeout *tmp;
764
765         dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) {
766                 if (tmp->handler == handler &&
767                     tmp->eloop_data == eloop_data &&
768                     tmp->user_data == user_data) {
769                         requested.sec = req_secs;
770                         requested.usec = req_usecs;
771                         os_get_reltime(&now);
772                         os_reltime_sub(&tmp->time, &now, &remaining);
773                         if (os_reltime_before(&remaining, &requested)) {
774                                 eloop_cancel_timeout(handler, eloop_data,
775                                                      user_data);
776                                 eloop_register_timeout(requested.sec,
777                                                        requested.usec,
778                                                        handler, eloop_data,
779                                                        user_data);
780                                 return 1;
781                         }
782                         return 0;
783                 }
784         }
785
786         return -1;
787 }
788
789
790 #ifndef CONFIG_NATIVE_WINDOWS
791 static void eloop_handle_alarm(int sig)
792 {
793         wpa_printf(MSG_ERROR, "eloop: could not process SIGINT or SIGTERM in "
794                    "two seconds. Looks like there\n"
795                    "is a bug that ends up in a busy loop that "
796                    "prevents clean shutdown.\n"
797                    "Killing program forcefully.\n");
798         exit(1);
799 }
800 #endif /* CONFIG_NATIVE_WINDOWS */
801
802
803 static void eloop_handle_signal(int sig)
804 {
805         int i;
806
807 #ifndef CONFIG_NATIVE_WINDOWS
808         if ((sig == SIGINT || sig == SIGTERM) && !eloop.pending_terminate) {
809                 /* Use SIGALRM to break out from potential busy loops that
810                  * would not allow the program to be killed. */
811                 eloop.pending_terminate = 1;
812                 signal(SIGALRM, eloop_handle_alarm);
813                 alarm(2);
814         }
815 #endif /* CONFIG_NATIVE_WINDOWS */
816
817         eloop.signaled++;
818         for (i = 0; i < eloop.signal_count; i++) {
819                 if (eloop.signals[i].sig == sig) {
820                         eloop.signals[i].signaled++;
821                         break;
822                 }
823         }
824 }
825
826
827 static void eloop_process_pending_signals(void)
828 {
829         int i;
830
831         if (eloop.signaled == 0)
832                 return;
833         eloop.signaled = 0;
834
835         if (eloop.pending_terminate) {
836 #ifndef CONFIG_NATIVE_WINDOWS
837                 alarm(0);
838 #endif /* CONFIG_NATIVE_WINDOWS */
839                 eloop.pending_terminate = 0;
840         }
841
842         for (i = 0; i < eloop.signal_count; i++) {
843                 if (eloop.signals[i].signaled) {
844                         eloop.signals[i].signaled = 0;
845                         eloop.signals[i].handler(eloop.signals[i].sig,
846                                                  eloop.signals[i].user_data);
847                 }
848         }
849 }
850
851
852 int eloop_register_signal(int sig, eloop_signal_handler handler,
853                           void *user_data)
854 {
855         struct eloop_signal *tmp;
856
857         tmp = os_realloc_array(eloop.signals, eloop.signal_count + 1,
858                                sizeof(struct eloop_signal));
859         if (tmp == NULL)
860                 return -1;
861
862         tmp[eloop.signal_count].sig = sig;
863         tmp[eloop.signal_count].user_data = user_data;
864         tmp[eloop.signal_count].handler = handler;
865         tmp[eloop.signal_count].signaled = 0;
866         eloop.signal_count++;
867         eloop.signals = tmp;
868         signal(sig, eloop_handle_signal);
869
870         return 0;
871 }
872
873
874 int eloop_register_signal_terminate(eloop_signal_handler handler,
875                                     void *user_data)
876 {
877         int ret = eloop_register_signal(SIGINT, handler, user_data);
878         if (ret == 0)
879                 ret = eloop_register_signal(SIGTERM, handler, user_data);
880         return ret;
881 }
882
883
884 int eloop_register_signal_reconfig(eloop_signal_handler handler,
885                                    void *user_data)
886 {
887 #ifdef CONFIG_NATIVE_WINDOWS
888         return 0;
889 #else /* CONFIG_NATIVE_WINDOWS */
890         return eloop_register_signal(SIGHUP, handler, user_data);
891 #endif /* CONFIG_NATIVE_WINDOWS */
892 }
893
894
895 void eloop_run(void)
896 {
897 #ifdef CONFIG_ELOOP_POLL
898         int num_poll_fds;
899         int timeout_ms = 0;
900 #endif /* CONFIG_ELOOP_POLL */
901 #ifdef CONFIG_ELOOP_SELECT
902         fd_set *rfds, *wfds, *efds;
903         struct timeval _tv;
904 #endif /* CONFIG_ELOOP_SELECT */
905 #ifdef CONFIG_ELOOP_EPOLL
906         int timeout_ms = -1;
907 #endif /* CONFIG_ELOOP_EPOLL */
908         int res;
909         struct os_reltime tv, now;
910
911 #ifdef CONFIG_ELOOP_SELECT
912         rfds = os_malloc(sizeof(*rfds));
913         wfds = os_malloc(sizeof(*wfds));
914         efds = os_malloc(sizeof(*efds));
915         if (rfds == NULL || wfds == NULL || efds == NULL)
916                 goto out;
917 #endif /* CONFIG_ELOOP_SELECT */
918
919         while (!eloop.terminate &&
920                (!dl_list_empty(&eloop.timeout) || eloop.readers.count > 0 ||
921                 eloop.writers.count > 0 || eloop.exceptions.count > 0)) {
922                 struct eloop_timeout *timeout;
923
924                 if (eloop.pending_terminate) {
925                         /*
926                          * This may happen in some corner cases where a signal
927                          * is received during a blocking operation. We need to
928                          * process the pending signals and exit if requested to
929                          * avoid hitting the SIGALRM limit if the blocking
930                          * operation took more than two seconds.
931                          */
932                         eloop_process_pending_signals();
933                         if (eloop.terminate)
934                                 break;
935                 }
936
937                 timeout = dl_list_first(&eloop.timeout, struct eloop_timeout,
938                                         list);
939                 if (timeout) {
940                         os_get_reltime(&now);
941                         if (os_reltime_before(&now, &timeout->time))
942                                 os_reltime_sub(&timeout->time, &now, &tv);
943                         else
944                                 tv.sec = tv.usec = 0;
945 #if defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL)
946                         timeout_ms = tv.sec * 1000 + tv.usec / 1000;
947 #endif /* defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) */
948 #ifdef CONFIG_ELOOP_SELECT
949                         _tv.tv_sec = tv.sec;
950                         _tv.tv_usec = tv.usec;
951 #endif /* CONFIG_ELOOP_SELECT */
952                 }
953
954 #ifdef CONFIG_ELOOP_POLL
955                 num_poll_fds = eloop_sock_table_set_fds(
956                         &eloop.readers, &eloop.writers, &eloop.exceptions,
957                         eloop.pollfds, eloop.pollfds_map,
958                         eloop.max_pollfd_map);
959                 res = poll(eloop.pollfds, num_poll_fds,
960                            timeout ? timeout_ms : -1);
961 #endif /* CONFIG_ELOOP_POLL */
962 #ifdef CONFIG_ELOOP_SELECT
963                 eloop_sock_table_set_fds(&eloop.readers, rfds);
964                 eloop_sock_table_set_fds(&eloop.writers, wfds);
965                 eloop_sock_table_set_fds(&eloop.exceptions, efds);
966                 res = select(eloop.max_sock + 1, rfds, wfds, efds,
967                              timeout ? &_tv : NULL);
968 #endif /* CONFIG_ELOOP_SELECT */
969 #ifdef CONFIG_ELOOP_EPOLL
970                 if (eloop.count == 0) {
971                         res = 0;
972                 } else {
973                         res = epoll_wait(eloop.epollfd, eloop.epoll_events,
974                                          eloop.count, timeout_ms);
975                 }
976 #endif /* CONFIG_ELOOP_EPOLL */
977                 if (res < 0 && errno != EINTR && errno != 0) {
978                         wpa_printf(MSG_ERROR, "eloop: %s: %s",
979 #ifdef CONFIG_ELOOP_POLL
980                                    "poll"
981 #endif /* CONFIG_ELOOP_POLL */
982 #ifdef CONFIG_ELOOP_SELECT
983                                    "select"
984 #endif /* CONFIG_ELOOP_SELECT */
985 #ifdef CONFIG_ELOOP_EPOLL
986                                    "epoll"
987 #endif /* CONFIG_ELOOP_EPOLL */
988                                    , strerror(errno));
989                         goto out;
990                 }
991
992                 eloop.readers.changed = 0;
993                 eloop.writers.changed = 0;
994                 eloop.exceptions.changed = 0;
995
996                 eloop_process_pending_signals();
997
998                 /* check if some registered timeouts have occurred */
999                 timeout = dl_list_first(&eloop.timeout, struct eloop_timeout,
1000                                         list);
1001                 if (timeout) {
1002                         os_get_reltime(&now);
1003                         if (!os_reltime_before(&now, &timeout->time)) {
1004                                 void *eloop_data = timeout->eloop_data;
1005                                 void *user_data = timeout->user_data;
1006                                 eloop_timeout_handler handler =
1007                                         timeout->handler;
1008                                 eloop_remove_timeout(timeout);
1009                                 handler(eloop_data, user_data);
1010                         }
1011
1012                 }
1013
1014                 if (res <= 0)
1015                         continue;
1016
1017                 if (eloop.readers.changed ||
1018                     eloop.writers.changed ||
1019                     eloop.exceptions.changed) {
1020                          /*
1021                           * Sockets may have been closed and reopened with the
1022                           * same FD in the signal or timeout handlers, so we
1023                           * must skip the previous results and check again
1024                           * whether any of the currently registered sockets have
1025                           * events.
1026                           */
1027                         continue;
1028                 }
1029
1030 #ifdef CONFIG_ELOOP_POLL
1031                 eloop_sock_table_dispatch(&eloop.readers, &eloop.writers,
1032                                           &eloop.exceptions, eloop.pollfds_map,
1033                                           eloop.max_pollfd_map);
1034 #endif /* CONFIG_ELOOP_POLL */
1035 #ifdef CONFIG_ELOOP_SELECT
1036                 eloop_sock_table_dispatch(&eloop.readers, rfds);
1037                 eloop_sock_table_dispatch(&eloop.writers, wfds);
1038                 eloop_sock_table_dispatch(&eloop.exceptions, efds);
1039 #endif /* CONFIG_ELOOP_SELECT */
1040 #ifdef CONFIG_ELOOP_EPOLL
1041                 eloop_sock_table_dispatch(eloop.epoll_events, res);
1042 #endif /* CONFIG_ELOOP_EPOLL */
1043         }
1044
1045         eloop.terminate = 0;
1046 out:
1047 #ifdef CONFIG_ELOOP_SELECT
1048         os_free(rfds);
1049         os_free(wfds);
1050         os_free(efds);
1051 #endif /* CONFIG_ELOOP_SELECT */
1052         return;
1053 }
1054
1055
1056 void eloop_terminate(void)
1057 {
1058         eloop.terminate = 1;
1059 }
1060
1061
1062 void eloop_destroy(void)
1063 {
1064         struct eloop_timeout *timeout, *prev;
1065         struct os_reltime now;
1066
1067         os_get_reltime(&now);
1068         dl_list_for_each_safe(timeout, prev, &eloop.timeout,
1069                               struct eloop_timeout, list) {
1070                 int sec, usec;
1071                 sec = timeout->time.sec - now.sec;
1072                 usec = timeout->time.usec - now.usec;
1073                 if (timeout->time.usec < now.usec) {
1074                         sec--;
1075                         usec += 1000000;
1076                 }
1077                 wpa_printf(MSG_INFO, "ELOOP: remaining timeout: %d.%06d "
1078                            "eloop_data=%p user_data=%p handler=%p",
1079                            sec, usec, timeout->eloop_data, timeout->user_data,
1080                            timeout->handler);
1081                 wpa_trace_dump_funcname("eloop unregistered timeout handler",
1082                                         timeout->handler);
1083                 wpa_trace_dump("eloop timeout", timeout);
1084                 eloop_remove_timeout(timeout);
1085         }
1086         eloop_sock_table_destroy(&eloop.readers);
1087         eloop_sock_table_destroy(&eloop.writers);
1088         eloop_sock_table_destroy(&eloop.exceptions);
1089         os_free(eloop.signals);
1090
1091 #ifdef CONFIG_ELOOP_POLL
1092         os_free(eloop.pollfds);
1093         os_free(eloop.pollfds_map);
1094 #endif /* CONFIG_ELOOP_POLL */
1095 #ifdef CONFIG_ELOOP_EPOLL
1096         os_free(eloop.epoll_table);
1097         os_free(eloop.epoll_events);
1098         close(eloop.epollfd);
1099 #endif /* CONFIG_ELOOP_EPOLL */
1100 }
1101
1102
1103 int eloop_terminated(void)
1104 {
1105         return eloop.terminate || eloop.pending_terminate;
1106 }
1107
1108
1109 void eloop_wait_for_read_sock(int sock)
1110 {
1111 #ifdef CONFIG_ELOOP_POLL
1112         struct pollfd pfd;
1113
1114         if (sock < 0)
1115                 return;
1116
1117         os_memset(&pfd, 0, sizeof(pfd));
1118         pfd.fd = sock;
1119         pfd.events = POLLIN;
1120
1121         poll(&pfd, 1, -1);
1122 #endif /* CONFIG_ELOOP_POLL */
1123 #if defined(CONFIG_ELOOP_SELECT) || defined(CONFIG_ELOOP_EPOLL)
1124         /*
1125          * We can use epoll() here. But epoll() requres 4 system calls.
1126          * epoll_create1(), epoll_ctl() for ADD, epoll_wait, and close() for
1127          * epoll fd. So select() is better for performance here.
1128          */
1129         fd_set rfds;
1130
1131         if (sock < 0)
1132                 return;
1133
1134         FD_ZERO(&rfds);
1135         FD_SET(sock, &rfds);
1136         select(sock + 1, &rfds, NULL, NULL, NULL);
1137 #endif /* defined(CONFIG_ELOOP_SELECT) || defined(CONFIG_ELOOP_EPOLL) */
1138 }
1139
1140 #ifdef CONFIG_ELOOP_SELECT
1141 #undef CONFIG_ELOOP_SELECT
1142 #endif /* CONFIG_ELOOP_SELECT */