18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Event loop - empty template (basic structure, but no OS specific operations) 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eloop_sock { 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int sock; 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *eloop_data; 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *user_data; 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*handler)(int sock, void *eloop_ctx, void *sock_ctx); 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eloop_timeout { 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_time time; 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *eloop_data; 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *user_data; 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*handler)(void *eloop_ctx, void *sock_ctx); 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eloop_timeout *next; 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eloop_signal { 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int sig; 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *user_data; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*handler)(int sig, void *eloop_ctx, void *signal_ctx); 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int signaled; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eloop_data { 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int max_sock, reader_count; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eloop_sock *readers; 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eloop_timeout *timeout; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int signal_count; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eloop_signal *signals; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int signaled; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int pending_terminate; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int terminate; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reader_table_changed; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct eloop_data eloop; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eloop_init(void) 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memset(&eloop, 0, sizeof(eloop)); 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eloop_register_read_sock(int sock, 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*handler)(int sock, void *eloop_ctx, 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *sock_ctx), 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *eloop_data, void *user_data) 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eloop_sock *tmp; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = (struct eloop_sock *) 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt realloc(eloop.readers, 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (eloop.reader_count + 1) * sizeof(struct eloop_sock)); 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp[eloop.reader_count].sock = sock; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp[eloop.reader_count].eloop_data = eloop_data; 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp[eloop.reader_count].user_data = user_data; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp[eloop.reader_count].handler = handler; 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.reader_count++; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.readers = tmp; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sock > eloop.max_sock) 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.max_sock = sock; 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.reader_table_changed = 1; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eloop_unregister_read_sock(int sock) 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eloop.readers == NULL || eloop.reader_count == 0) 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < eloop.reader_count; i++) { 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eloop.readers[i].sock == sock) 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i == eloop.reader_count) 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i != eloop.reader_count - 1) { 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memmove(&eloop.readers[i], &eloop.readers[i + 1], 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (eloop.reader_count - i - 1) * 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(struct eloop_sock)); 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.reader_count--; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.reader_table_changed = 1; 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eloop_register_timeout(unsigned int secs, unsigned int usecs, 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*handler)(void *eloop_ctx, void *timeout_ctx), 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *eloop_data, void *user_data) 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eloop_timeout *timeout, *tmp, *prev; 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout = (struct eloop_timeout *) malloc(sizeof(*timeout)); 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (timeout == NULL) 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&timeout->time); 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout->time.sec += secs; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout->time.usec += usecs; 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (timeout->time.usec >= 1000000) { 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout->time.sec++; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout->time.usec -= 1000000; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout->eloop_data = eloop_data; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout->user_data = user_data; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout->handler = handler; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout->next = NULL; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eloop.timeout == NULL) { 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.timeout = timeout; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = NULL; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = eloop.timeout; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (tmp != NULL) { 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_time_before(&timeout->time, &tmp->time)) 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = tmp; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = tmp->next; 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev == NULL) { 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout->next = eloop.timeout; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.timeout = timeout; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout->next = prev->next; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = timeout; 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eloop_cancel_timeout(void (*handler)(void *eloop_ctx, void *sock_ctx), 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *eloop_data, void *user_data) 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eloop_timeout *timeout, *prev, *next; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int removed = 0; 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = NULL; 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout = eloop.timeout; 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (timeout != NULL) { 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt next = timeout->next; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (timeout->handler == handler && 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (timeout->eloop_data == eloop_data || 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_data == ELOOP_ALL_CTX) && 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (timeout->user_data == user_data || 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt user_data == ELOOP_ALL_CTX)) { 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev == NULL) 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.timeout = next; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = next; 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt free(timeout); 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt removed++; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = timeout; 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout = next; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return removed; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eloop_is_timeout_registered(void (*handler)(void *eloop_ctx, 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *timeout_ctx), 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *eloop_data, void *user_data) 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eloop_timeout *tmp; 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = eloop.timeout; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (tmp != NULL) { 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp->handler == handler && 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp->eloop_data == eloop_data && 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp->user_data == user_data) 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = tmp->next; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* TODO: replace with suitable signal handler */ 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if 0 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eloop_handle_signal(int sig) 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.signaled++; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < eloop.signal_count; i++) { 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eloop.signals[i].sig == sig) { 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.signals[i].signaled++; 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eloop_process_pending_signals(void) 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eloop.signaled == 0) 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.signaled = 0; 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eloop.pending_terminate) { 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.pending_terminate = 0; 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < eloop.signal_count; i++) { 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eloop.signals[i].signaled) { 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.signals[i].signaled = 0; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.signals[i].handler(eloop.signals[i].sig, 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.user_data, 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.signals[i].user_data); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eloop_register_signal(int sig, 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*handler)(int sig, void *eloop_ctx, 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *signal_ctx), 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *user_data) 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eloop_signal *tmp; 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = (struct eloop_signal *) 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt realloc(eloop.signals, 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (eloop.signal_count + 1) * 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(struct eloop_signal)); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp[eloop.signal_count].sig = sig; 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp[eloop.signal_count].user_data = user_data; 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp[eloop.signal_count].handler = handler; 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp[eloop.signal_count].signaled = 0; 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.signal_count++; 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.signals = tmp; 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: register signal handler */ 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eloop_register_signal_terminate(void (*handler)(int sig, void *eloop_ctx, 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *signal_ctx), 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *user_data) 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if 0 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: for example */ 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = eloop_register_signal(SIGINT, handler, user_data); 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret == 0) 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = eloop_register_signal(SIGTERM, handler, user_data); 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eloop_register_signal_reconfig(void (*handler)(int sig, void *eloop_ctx, 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *signal_ctx), 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *user_data) 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if 0 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: for example */ 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eloop_register_signal(SIGHUP, handler, user_data); 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eloop_run(void) 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_time tv, now; 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (!eloop.terminate && 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (eloop.timeout || eloop.reader_count > 0)) { 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eloop.timeout) { 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&now); 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_time_before(&now, &eloop.timeout->time)) 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_time_sub(&eloop.timeout->time, &now, &tv); 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tv.sec = tv.usec = 0; 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TODO: wait for any event (read socket ready, timeout (tv), 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * signal 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_sleep(1, 0); /* just a dummy wait for testing */ 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_process_pending_signals(); 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* check if some registered timeouts have occurred */ 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eloop.timeout) { 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eloop_timeout *tmp; 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&now); 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!os_time_before(&now, &eloop.timeout->time)) { 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = eloop.timeout; 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.timeout = eloop.timeout->next; 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp->handler(tmp->eloop_data, 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp->user_data); 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt free(tmp); 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.reader_table_changed = 0; 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < eloop.reader_count; i++) { 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TODO: call each handler that has pending data to 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * read 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (0 /* TODO: eloop.readers[i].sock ready */) { 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.readers[i].handler( 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.readers[i].sock, 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.readers[i].eloop_data, 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.readers[i].user_data); 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eloop.reader_table_changed) 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eloop_terminate(void) 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop.terminate = 1; 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eloop_destroy(void) 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eloop_timeout *timeout, *prev; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout = eloop.timeout; 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (timeout != NULL) { 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = timeout; 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout = timeout->next; 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt free(prev); 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt free(eloop.readers); 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt free(eloop.signals); 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eloop_terminated(void) 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eloop.terminate; 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eloop_wait_for_read_sock(int sock) 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TODO: wait for the file descriptor to have something available for 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * reading 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 396