eloop.c revision 8d520ff1dc2da35cdca849e982051b86468016d8
172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse/* 272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * Event loop based on select() loop 372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> 472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * 572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * This program is free software; you can redistribute it and/or modify 672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * it under the terms of the GNU General Public License version 2 as 772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * published by the Free Software Foundation. 872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * 972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * Alternatively, this software may be distributed under the terms of BSD 1072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * license. 1172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * 1272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse * See README and COPYING for more details. 1372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse */ 1472128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse 1572128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse#include "includes.h" 1672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse 1772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse#include "common.h" 1872128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse#include "trace.h" 1972128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse#include "list.h" 2072128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse#include "eloop.h" 2172128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse 2272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse 23de553d906b4a205d811a9e1651f14212ec284e29Jerome Glissestruct eloop_sock { 24ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard int sock; 25077c448d184799e0d9ec962013ec784c6a5c1807Henri Verbeet void *eloop_data; 26a3a94554f5a12f0626d9712ddcdc81b1e21d36c2Dave Airlie void *user_data; 2772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse eloop_sock_handler handler; 28330b6c85c961b32f704ce8ec7dbf8cb7fc0b80a8Marek Olšák WPA_TRACE_REF(eloop); 29ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard WPA_TRACE_REF(user); 30330b6c85c961b32f704ce8ec7dbf8cb7fc0b80a8Marek Olšák WPA_TRACE_INFO 31330b6c85c961b32f704ce8ec7dbf8cb7fc0b80a8Marek Olšák}; 32330b6c85c961b32f704ce8ec7dbf8cb7fc0b80a8Marek Olšák 33330b6c85c961b32f704ce8ec7dbf8cb7fc0b80a8Marek Olšákstruct eloop_timeout { 34ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard struct dl_list list; 35ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard struct os_time time; 36de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse void *eloop_data; 37843dfe3206c4f397c7911b748373dde5540392a4Cédric Cano void *user_data; 38843dfe3206c4f397c7911b748373dde5540392a4Cédric Cano eloop_timeout_handler handler; 397779f6d1dffde2c0501e44adc342e52803de08d4Dave Airlie WPA_TRACE_REF(eloop); 407779f6d1dffde2c0501e44adc342e52803de08d4Dave Airlie WPA_TRACE_REF(user); 417779f6d1dffde2c0501e44adc342e52803de08d4Dave Airlie WPA_TRACE_INFO 427779f6d1dffde2c0501e44adc342e52803de08d4Dave Airlie}; 437779f6d1dffde2c0501e44adc342e52803de08d4Dave Airlie 447779f6d1dffde2c0501e44adc342e52803de08d4Dave Airliestruct eloop_signal { 457779f6d1dffde2c0501e44adc342e52803de08d4Dave Airlie int sig; 467779f6d1dffde2c0501e44adc342e52803de08d4Dave Airlie void *user_data; 477779f6d1dffde2c0501e44adc342e52803de08d4Dave Airlie eloop_signal_handler handler; 487779f6d1dffde2c0501e44adc342e52803de08d4Dave Airlie int signaled; 497779f6d1dffde2c0501e44adc342e52803de08d4Dave Airlie}; 507779f6d1dffde2c0501e44adc342e52803de08d4Dave Airlie 517779f6d1dffde2c0501e44adc342e52803de08d4Dave Airliestruct eloop_sock_table { 527779f6d1dffde2c0501e44adc342e52803de08d4Dave Airlie int count; 537779f6d1dffde2c0501e44adc342e52803de08d4Dave Airlie struct eloop_sock *table; 547779f6d1dffde2c0501e44adc342e52803de08d4Dave Airlie int changed; 557779f6d1dffde2c0501e44adc342e52803de08d4Dave Airlie}; 567779f6d1dffde2c0501e44adc342e52803de08d4Dave Airlie 577779f6d1dffde2c0501e44adc342e52803de08d4Dave Airliestruct eloop_data { 587779f6d1dffde2c0501e44adc342e52803de08d4Dave Airlie int max_sock; 597779f6d1dffde2c0501e44adc342e52803de08d4Dave Airlie 60a6a710cbe7425819e1cd5ad5f2085311c092f2e7Henri Verbeet struct eloop_sock_table readers; 611235becaa1cf7e29f580900592563c3329d326deJerome Glisse struct eloop_sock_table writers; 62e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák struct eloop_sock_table exceptions; 631235becaa1cf7e29f580900592563c3329d326deJerome Glisse 64843dfe3206c4f397c7911b748373dde5540392a4Cédric Cano struct dl_list timeout; 65843dfe3206c4f397c7911b748373dde5540392a4Cédric Cano 661235becaa1cf7e29f580900592563c3329d326deJerome Glisse int signal_count; 671235becaa1cf7e29f580900592563c3329d326deJerome Glisse struct eloop_signal *signals; 681235becaa1cf7e29f580900592563c3329d326deJerome Glisse int signaled; 696101b6d442b06a347c001fe85848d636ab7df260Marek Olšák int pending_terminate; 706101b6d442b06a347c001fe85848d636ab7df260Marek Olšák 711235becaa1cf7e29f580900592563c3329d326deJerome Glisse int terminate; 721235becaa1cf7e29f580900592563c3329d326deJerome Glisse int reader_table_changed; 731235becaa1cf7e29f580900592563c3329d326deJerome Glisse}; 740a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák 75d7577ae3a6d6e174ab36d244f6bd4dedd63c3d1dHenri Verbeetstatic struct eloop_data eloop; 76d7577ae3a6d6e174ab36d244f6bd4dedd63c3d1dHenri Verbeet 77d7577ae3a6d6e174ab36d244f6bd4dedd63c3d1dHenri Verbeet 78d7577ae3a6d6e174ab36d244f6bd4dedd63c3d1dHenri Verbeet#ifdef WPA_TRACE 79d7577ae3a6d6e174ab36d244f6bd4dedd63c3d1dHenri Verbeet 80d7577ae3a6d6e174ab36d244f6bd4dedd63c3d1dHenri Verbeetstatic void eloop_sigsegv_handler(int sig) 81843dfe3206c4f397c7911b748373dde5540392a4Cédric Cano{ 820a6120244e66494db070ce875c0a464fbc5b15a1Marek Olšák wpa_trace_show("eloop SIGSEGV"); 831235becaa1cf7e29f580900592563c3329d326deJerome Glisse abort(); 841235becaa1cf7e29f580900592563c3329d326deJerome Glisse} 851235becaa1cf7e29f580900592563c3329d326deJerome Glisse 861235becaa1cf7e29f580900592563c3329d326deJerome Glissestatic void eloop_trace_sock_add_ref(struct eloop_sock_table *table) 874f7dfd8ad3185f006e7ae8ed86bafd4d66ebc903Henri Verbeet{ 881235becaa1cf7e29f580900592563c3329d326deJerome Glisse int i; 891235becaa1cf7e29f580900592563c3329d326deJerome Glisse if (table == NULL || table->table == NULL) 901235becaa1cf7e29f580900592563c3329d326deJerome Glisse return; 911235becaa1cf7e29f580900592563c3329d326deJerome Glisse for (i = 0; i < table->count; i++) { 921235becaa1cf7e29f580900592563c3329d326deJerome Glisse wpa_trace_add_ref(&table->table[i], eloop, 931235becaa1cf7e29f580900592563c3329d326deJerome Glisse table->table[i].eloop_data); 944f7dfd8ad3185f006e7ae8ed86bafd4d66ebc903Henri Verbeet wpa_trace_add_ref(&table->table[i], user, 951235becaa1cf7e29f580900592563c3329d326deJerome Glisse table->table[i].user_data); 961235becaa1cf7e29f580900592563c3329d326deJerome Glisse } 971235becaa1cf7e29f580900592563c3329d326deJerome Glisse} 981235becaa1cf7e29f580900592563c3329d326deJerome Glisse 991235becaa1cf7e29f580900592563c3329d326deJerome Glisse 1001235becaa1cf7e29f580900592563c3329d326deJerome Glissestatic void eloop_trace_sock_remove_ref(struct eloop_sock_table *table) 1011235becaa1cf7e29f580900592563c3329d326deJerome Glisse{ 1021235becaa1cf7e29f580900592563c3329d326deJerome Glisse int i; 1031235becaa1cf7e29f580900592563c3329d326deJerome Glisse if (table == NULL || table->table == NULL) 1041235becaa1cf7e29f580900592563c3329d326deJerome Glisse return; 1051235becaa1cf7e29f580900592563c3329d326deJerome Glisse for (i = 0; i < table->count; i++) { 106e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák wpa_trace_remove_ref(&table->table[i], eloop, 1073b1c1f02537544a11772b94a8f2e8c3d4c886ca8Henri Verbeet table->table[i].eloop_data); 108eafd331cf3b024001abd3f64861f41cd33a9acb2Vadim Girlin wpa_trace_remove_ref(&table->table[i], user, 1091235becaa1cf7e29f580900592563c3329d326deJerome Glisse table->table[i].user_data); 110052b9e8fab2e7deddf7f287d63c45aa938e5ec67Christian König } 111e4340c1908a6a3b09e1a15d5195f6da7d00494d0Marek Olšák} 1124acf71f01ea1edb253cd38cc059d4af1a2a40bf4Vadim Girlin 1131235becaa1cf7e29f580900592563c3329d326deJerome Glisse#else /* WPA_TRACE */ 1141235becaa1cf7e29f580900592563c3329d326deJerome Glisse 115c33e091d17b90df61f7b3873a2f124c4f26adf06Jerome Glisse#define eloop_trace_sock_add_ref(table) do { } while (0) 116c33e091d17b90df61f7b3873a2f124c4f26adf06Jerome Glisse#define eloop_trace_sock_remove_ref(table) do { } while (0) 117c33e091d17b90df61f7b3873a2f124c4f26adf06Jerome Glisse 118c33e091d17b90df61f7b3873a2f124c4f26adf06Jerome Glisse#endif /* WPA_TRACE */ 119052b9e8fab2e7deddf7f287d63c45aa938e5ec67Christian König 120052b9e8fab2e7deddf7f287d63c45aa938e5ec67Christian König 121052b9e8fab2e7deddf7f287d63c45aa938e5ec67Christian Königint eloop_init(void) 1224acf71f01ea1edb253cd38cc059d4af1a2a40bf4Vadim Girlin{ 123543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák os_memset(&eloop, 0, sizeof(eloop)); 1244acf71f01ea1edb253cd38cc059d4af1a2a40bf4Vadim Girlin dl_list_init(&eloop.timeout); 125543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák#ifdef WPA_TRACE 126543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák signal(SIGSEGV, eloop_sigsegv_handler); 1274acf71f01ea1edb253cd38cc059d4af1a2a40bf4Vadim Girlin#endif /* WPA_TRACE */ 1284acf71f01ea1edb253cd38cc059d4af1a2a40bf4Vadim Girlin return 0; 1294acf71f01ea1edb253cd38cc059d4af1a2a40bf4Vadim Girlin} 130543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák 1314acf71f01ea1edb253cd38cc059d4af1a2a40bf4Vadim Girlin 1322449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšákstatic int eloop_sock_table_add_sock(struct eloop_sock_table *table, 1332449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák int sock, eloop_sock_handler handler, 1342449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák void *eloop_data, void *user_data) 1352449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák{ 136543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák struct eloop_sock *tmp; 137543b2331d7b45a29ccd3530daa2389e87e65d89bMarek Olšák 138052b9e8fab2e7deddf7f287d63c45aa938e5ec67Christian König if (table == NULL) 139eafd331cf3b024001abd3f64861f41cd33a9acb2Vadim Girlin return -1; 1401235becaa1cf7e29f580900592563c3329d326deJerome Glisse 1411235becaa1cf7e29f580900592563c3329d326deJerome Glisse eloop_trace_sock_remove_ref(table); 1421235becaa1cf7e29f580900592563c3329d326deJerome Glisse tmp = (struct eloop_sock *) 1431235becaa1cf7e29f580900592563c3329d326deJerome Glisse os_realloc(table->table, 1444a47662beaa2092447939db7880531fb706afeddMarek Olšák (table->count + 1) * sizeof(struct eloop_sock)); 1451235becaa1cf7e29f580900592563c3329d326deJerome Glisse if (tmp == NULL) 1461235becaa1cf7e29f580900592563c3329d326deJerome Glisse return -1; 1471235becaa1cf7e29f580900592563c3329d326deJerome Glisse 1481235becaa1cf7e29f580900592563c3329d326deJerome Glisse tmp[table->count].sock = sock; 149052b9e8fab2e7deddf7f287d63c45aa938e5ec67Christian König tmp[table->count].eloop_data = eloop_data; 1504a47662beaa2092447939db7880531fb706afeddMarek Olšák tmp[table->count].user_data = user_data; 151052b9e8fab2e7deddf7f287d63c45aa938e5ec67Christian König tmp[table->count].handler = handler; 152052b9e8fab2e7deddf7f287d63c45aa938e5ec67Christian König wpa_trace_record(&tmp[table->count]); 153afc56b1861c1dae4137493af4c0e6dacc6ee41f9Jerome Glisse table->count++; 1541235becaa1cf7e29f580900592563c3329d326deJerome Glisse table->table = tmp; 1551235becaa1cf7e29f580900592563c3329d326deJerome Glisse if (sock > eloop.max_sock) 15669251fc4cd5f71be403e08398bc43d19052a640dJerome Glisse eloop.max_sock = sock; 157ccb9be105602edaaff196046e324c8cb4a12fe0aTilman Sauerbeck table->changed = 1; 1586101b6d442b06a347c001fe85848d636ab7df260Marek Olšák eloop_trace_sock_add_ref(table); 1594a47662beaa2092447939db7880531fb706afeddMarek Olšák 160ccb9be105602edaaff196046e324c8cb4a12fe0aTilman Sauerbeck return 0; 161ccb9be105602edaaff196046e324c8cb4a12fe0aTilman Sauerbeck} 1621235becaa1cf7e29f580900592563c3329d326deJerome Glisse 1631235becaa1cf7e29f580900592563c3329d326deJerome Glisse 1641235becaa1cf7e29f580900592563c3329d326deJerome Glissestatic void eloop_sock_table_remove_sock(struct eloop_sock_table *table, 1652b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glisse int sock) 1662b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glisse{ 167a77e813de32643ae2dfffd7ad12abed596172cabHenri Verbeet int i; 168a77e813de32643ae2dfffd7ad12abed596172cabHenri Verbeet 169a77e813de32643ae2dfffd7ad12abed596172cabHenri Verbeet if (table == NULL || table->table == NULL || table->count == 0) 170a77e813de32643ae2dfffd7ad12abed596172cabHenri Verbeet return; 171a77e813de32643ae2dfffd7ad12abed596172cabHenri Verbeet 172a77e813de32643ae2dfffd7ad12abed596172cabHenri Verbeet for (i = 0; i < table->count; i++) { 173a77e813de32643ae2dfffd7ad12abed596172cabHenri Verbeet if (table->table[i].sock == sock) 174a77e813de32643ae2dfffd7ad12abed596172cabHenri Verbeet break; 175a77e813de32643ae2dfffd7ad12abed596172cabHenri Verbeet } 1762b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glisse if (i == table->count) 1772b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glisse return; 1782b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glisse eloop_trace_sock_remove_ref(table); 1792b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glisse if (i != table->count - 1) { 1802b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glisse os_memmove(&table->table[i], &table->table[i + 1], 1812b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glisse (table->count - i - 1) * 1822b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glisse sizeof(struct eloop_sock)); 1832b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glisse } 18478293b99b23268e6698f1267aaf40647c17d95a5Marek Olšák table->count--; 1852b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glisse table->changed = 1; 18640aec11b7569fcdd2d884629b172af3db3fbaf1dMike Kaplinskiy eloop_trace_sock_add_ref(table); 18778293b99b23268e6698f1267aaf40647c17d95a5Marek Olšák} 18878293b99b23268e6698f1267aaf40647c17d95a5Marek Olšák 18978293b99b23268e6698f1267aaf40647c17d95a5Marek Olšák 190fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airliestatic void eloop_sock_table_set_fds(struct eloop_sock_table *table, 191fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie fd_set *fds) 192fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie{ 193fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie int i; 194fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie 195725a820b926575265e6790601a0defd9c30947dcVadim Girlin FD_ZERO(fds); 196725a820b926575265e6790601a0defd9c30947dcVadim Girlin 19754e8dcaad65cbe3603730414fd8d76ac53f89a86Vadim Girlin if (table->table == NULL) 19854e8dcaad65cbe3603730414fd8d76ac53f89a86Vadim Girlin return; 199c4d644bac1e738af7e2a3f1bef7eea09df8bb81cVadim Girlin 200951b888be45539e5d5b535a5a393df719fae4172Vadim Girlin for (i = 0; i < table->count; i++) 2012b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glisse FD_SET(table->table[i].sock, fds); 2022b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glisse} 2032b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glisse 2042b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glisse 2052b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glissestatic void eloop_sock_table_dispatch(struct eloop_sock_table *table, 2062b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glisse fd_set *fds) 2072b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glisse{ 2082b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glisse int i; 2092b3b76a4a0e21eb4bd4f1a4da5ff6ed26ccbabd1Jerome Glisse 2107779f6d1dffde2c0501e44adc342e52803de08d4Dave Airlie if (table == NULL || table->table == NULL) 21142c966bc496d4049d98eb1d45dd7bb0b55fa41bdTilman Sauerbeck return; 212ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 213ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard table->changed = 0; 214ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard for (i = 0; i < table->count; i++) { 215ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard if (FD_ISSET(table->table[i].sock, fds)) { 216ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard table->table[i].handler(table->table[i].sock, 217ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard table->table[i].eloop_data, 218ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard table->table[i].user_data); 219ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard if (table->changed) 220ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard break; 221ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard } 222ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard } 223ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard} 224ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 225ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 226ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellardstatic void eloop_sock_table_destroy(struct eloop_sock_table *table) 2276a829a1b724ca0d960decee217d260b4de8a5463Adam Rak{ 2286a829a1b724ca0d960decee217d260b4de8a5463Adam Rak if (table) { 2296a829a1b724ca0d960decee217d260b4de8a5463Adam Rak int i; 2306a829a1b724ca0d960decee217d260b4de8a5463Adam Rak for (i = 0; i < table->count && table->table; i++) { 2316a829a1b724ca0d960decee217d260b4de8a5463Adam Rak wpa_printf(MSG_INFO, "ELOOP: remaining socket: " 2326a829a1b724ca0d960decee217d260b4de8a5463Adam Rak "sock=%d eloop_data=%p user_data=%p " 2336a829a1b724ca0d960decee217d260b4de8a5463Adam Rak "handler=%p", 2346a829a1b724ca0d960decee217d260b4de8a5463Adam Rak table->table[i].sock, 2356a829a1b724ca0d960decee217d260b4de8a5463Adam Rak table->table[i].eloop_data, 2366a829a1b724ca0d960decee217d260b4de8a5463Adam Rak table->table[i].user_data, 2376a829a1b724ca0d960decee217d260b4de8a5463Adam Rak table->table[i].handler); 2386a829a1b724ca0d960decee217d260b4de8a5463Adam Rak wpa_trace_dump_funcname("eloop unregistered socket " 2396a829a1b724ca0d960decee217d260b4de8a5463Adam Rak "handler", 2406a829a1b724ca0d960decee217d260b4de8a5463Adam Rak table->table[i].handler); 2416a829a1b724ca0d960decee217d260b4de8a5463Adam Rak wpa_trace_dump("eloop sock", &table->table[i]); 2426a829a1b724ca0d960decee217d260b4de8a5463Adam Rak } 2436a829a1b724ca0d960decee217d260b4de8a5463Adam Rak os_free(table->table); 2446a829a1b724ca0d960decee217d260b4de8a5463Adam Rak } 2456a829a1b724ca0d960decee217d260b4de8a5463Adam Rak} 2466a829a1b724ca0d960decee217d260b4de8a5463Adam Rak 2476a829a1b724ca0d960decee217d260b4de8a5463Adam Rak 2486a829a1b724ca0d960decee217d260b4de8a5463Adam Rakint eloop_register_read_sock(int sock, eloop_sock_handler handler, 2490c4b19ac63efa41242c515824301e6161aceeea5Tom Stellard void *eloop_data, void *user_data) 2500c4b19ac63efa41242c515824301e6161aceeea5Tom Stellard{ 2510c4b19ac63efa41242c515824301e6161aceeea5Tom Stellard return eloop_register_sock(sock, EVENT_TYPE_READ, handler, 2526a829a1b724ca0d960decee217d260b4de8a5463Adam Rak eloop_data, user_data); 2536a829a1b724ca0d960decee217d260b4de8a5463Adam Rak} 2546a829a1b724ca0d960decee217d260b4de8a5463Adam Rak 2556a829a1b724ca0d960decee217d260b4de8a5463Adam Rak 2566a829a1b724ca0d960decee217d260b4de8a5463Adam Rakvoid eloop_unregister_read_sock(int sock) 2576a829a1b724ca0d960decee217d260b4de8a5463Adam Rak{ 2586a829a1b724ca0d960decee217d260b4de8a5463Adam Rak eloop_unregister_sock(sock, EVENT_TYPE_READ); 2596a829a1b724ca0d960decee217d260b4de8a5463Adam Rak} 2606a829a1b724ca0d960decee217d260b4de8a5463Adam Rak 2612c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard 2622c485cda2062ca2b9af89ea62618515d960c7904Tom Stellardstatic struct eloop_sock_table *eloop_get_sock_table(eloop_event_type type) 2632c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard{ 2642c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard switch (type) { 2652c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard case EVENT_TYPE_READ: 2662c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard return &eloop.readers; 2672c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard case EVENT_TYPE_WRITE: 2682c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard return &eloop.writers; 2692c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard case EVENT_TYPE_EXCEPTION: 2702c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard return &eloop.exceptions; 2712c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard } 272ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 273ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard return NULL; 274ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard} 275ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 276ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 277ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellardint eloop_register_sock(int sock, eloop_event_type type, 278ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard eloop_sock_handler handler, 279ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard void *eloop_data, void *user_data) 280ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard{ 281ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard struct eloop_sock_table *table; 282ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 283ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard table = eloop_get_sock_table(type); 284ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard return eloop_sock_table_add_sock(table, sock, handler, 285ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard eloop_data, user_data); 286ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard} 287ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 288ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 289ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellardvoid eloop_unregister_sock(int sock, eloop_event_type type) 290ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard{ 291ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard struct eloop_sock_table *table; 292ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 293ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard table = eloop_get_sock_table(type); 294ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard eloop_sock_table_remove_sock(table, sock); 295ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard} 2968f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune 297ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 298ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellardint eloop_register_timeout(unsigned int secs, unsigned int usecs, 299ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard eloop_timeout_handler handler, 300ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard void *eloop_data, void *user_data) 301ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard{ 302ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard struct eloop_timeout *timeout, *tmp; 303ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard os_time_t now_sec; 304ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 305ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard timeout = os_zalloc(sizeof(*timeout)); 306ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard if (timeout == NULL) 307ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard return -1; 308ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard if (os_get_time(&timeout->time) < 0) { 309ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard os_free(timeout); 310ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard return -1; 311ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard } 312ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard now_sec = timeout->time.sec; 313ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard timeout->time.sec += secs; 3148f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune if (timeout->time.sec < now_sec) { 315da676eab93e7dad30b574b4eb4cffd4df952e819Vincent Lejeune /* 316ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard * Integer overflow - assume long enough timeout to be assumed 317ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard * to be infinite, i.e., the timeout would never happen. 318ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard */ 319ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard wpa_printf(MSG_DEBUG, "ELOOP: Too long timeout (secs=%u) to " 3208f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune "ever happen - ignore it", secs); 3218f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune os_free(timeout); 3228f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune return 0; 3238f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune } 3248f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune timeout->time.usec += usecs; 3258f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune while (timeout->time.usec >= 1000000) { 3268f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune timeout->time.sec++; 3278f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune timeout->time.usec -= 1000000; 3288f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune } 3298f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune timeout->eloop_data = eloop_data; 3308f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune timeout->user_data = user_data; 3318f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune timeout->handler = handler; 3328f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune wpa_trace_add_ref(timeout, eloop, eloop_data); 3338f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune wpa_trace_add_ref(timeout, user, user_data); 3348f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune wpa_trace_record(timeout); 3358f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune 3368f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune /* Maintain timeouts in order of increasing time */ 3378f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { 3388f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune if (os_time_before(&timeout->time, &tmp->time)) { 3398f597d57e959830040473b548e0e04cfc63866c2Vincent Lejeune dl_list_add(tmp->list.prev, &timeout->list); 340ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard return 0; 341ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard } 342ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard } 343ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard dl_list_add_tail(&eloop.timeout, &timeout->list); 344ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 345ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard return 0; 346ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard} 347ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 348ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 349ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellardstatic void eloop_remove_timeout(struct eloop_timeout *timeout) 350ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard{ 351ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard dl_list_del(&timeout->list); 352ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard wpa_trace_remove_ref(timeout, eloop, timeout->eloop_data); 353ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard wpa_trace_remove_ref(timeout, user, timeout->user_data); 354ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard os_free(timeout); 355ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard} 356ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 357ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 358ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellardint eloop_cancel_timeout(eloop_timeout_handler handler, 359ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard void *eloop_data, void *user_data) 360ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard{ 361ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard struct eloop_timeout *timeout, *prev; 362ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard int removed = 0; 363ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 364ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard dl_list_for_each_safe(timeout, prev, &eloop.timeout, 365ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard struct eloop_timeout, list) { 366ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard if (timeout->handler == handler && 367ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard (timeout->eloop_data == eloop_data || 368ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard eloop_data == ELOOP_ALL_CTX) && 369ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard (timeout->user_data == user_data || 370ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard user_data == ELOOP_ALL_CTX)) { 371ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard eloop_remove_timeout(timeout); 372ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard removed++; 373ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard } 374ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard } 375ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 376ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard return removed; 377ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard} 378ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 379ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 380ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellardint eloop_is_timeout_registered(eloop_timeout_handler handler, 381ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard void *eloop_data, void *user_data) 3822fae8227ad906a6d6290134368b62f5dd3a1858eTom Stellard{ 383ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard struct eloop_timeout *tmp; 384ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 385ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { 3862fae8227ad906a6d6290134368b62f5dd3a1858eTom Stellard if (tmp->handler == handler && 387bc4b4c605cc04138e5209782fa5939bfd71930bdVincent Lejeune tmp->eloop_data == eloop_data && 388bc4b4c605cc04138e5209782fa5939bfd71930bdVincent Lejeune tmp->user_data == user_data) 389ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard return 1; 3902fae8227ad906a6d6290134368b62f5dd3a1858eTom Stellard } 391bc4b4c605cc04138e5209782fa5939bfd71930bdVincent Lejeune 392ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard return 0; 3932fae8227ad906a6d6290134368b62f5dd3a1858eTom Stellard} 394bc4b4c605cc04138e5209782fa5939bfd71930bdVincent Lejeune 395ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 3962fae8227ad906a6d6290134368b62f5dd3a1858eTom Stellard#ifndef CONFIG_NATIVE_WINDOWS 397bc4b4c605cc04138e5209782fa5939bfd71930bdVincent Lejeunestatic void eloop_handle_alarm(int sig) 398ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard{ 3992fae8227ad906a6d6290134368b62f5dd3a1858eTom Stellard wpa_printf(MSG_ERROR, "eloop: could not process SIGINT or SIGTERM in " 400bc4b4c605cc04138e5209782fa5939bfd71930bdVincent Lejeune "two seconds. Looks like there\n" 401ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard "is a bug that ends up in a busy loop that " 4022fae8227ad906a6d6290134368b62f5dd3a1858eTom Stellard "prevents clean shutdown.\n" 403ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard "Killing program forcefully.\n"); 404bc4b4c605cc04138e5209782fa5939bfd71930bdVincent Lejeune exit(1); 405ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard} 4062fae8227ad906a6d6290134368b62f5dd3a1858eTom Stellard#endif /* CONFIG_NATIVE_WINDOWS */ 407bc4b4c605cc04138e5209782fa5939bfd71930bdVincent Lejeune 4082fae8227ad906a6d6290134368b62f5dd3a1858eTom Stellard 409bc4b4c605cc04138e5209782fa5939bfd71930bdVincent Lejeunestatic void eloop_handle_signal(int sig) 4102fae8227ad906a6d6290134368b62f5dd3a1858eTom Stellard{ 411ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard int i; 412ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 413ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard#ifndef CONFIG_NATIVE_WINDOWS 414ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard if ((sig == SIGINT || sig == SIGTERM) && !eloop.pending_terminate) { 415ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard /* Use SIGALRM to break out from potential busy loops that 416ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard * would not allow the program to be killed. */ 417ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard eloop.pending_terminate = 1; 418ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard signal(SIGALRM, eloop_handle_alarm); 419ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard alarm(2); 420ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard } 421ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard#endif /* CONFIG_NATIVE_WINDOWS */ 422ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 423ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard eloop.signaled++; 424ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard for (i = 0; i < eloop.signal_count; i++) { 425ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard if (eloop.signals[i].sig == sig) { 4262fae8227ad906a6d6290134368b62f5dd3a1858eTom Stellard eloop.signals[i].signaled++; 42718617d7423b2c12aac9adbb8354fbf5d0c8ddfeaTom Stellard break; 42818617d7423b2c12aac9adbb8354fbf5d0c8ddfeaTom Stellard } 42918617d7423b2c12aac9adbb8354fbf5d0c8ddfeaTom Stellard } 4302fae8227ad906a6d6290134368b62f5dd3a1858eTom Stellard} 4312fae8227ad906a6d6290134368b62f5dd3a1858eTom Stellard 4322fae8227ad906a6d6290134368b62f5dd3a1858eTom Stellard 4332fae8227ad906a6d6290134368b62f5dd3a1858eTom Stellardstatic void eloop_process_pending_signals(void) 434ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard{ 435ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard int i; 436ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 437ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard if (eloop.signaled == 0) 438ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard return; 439ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard eloop.signaled = 0; 440ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 441ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard if (eloop.pending_terminate) { 442ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard#ifndef CONFIG_NATIVE_WINDOWS 443ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard alarm(0); 444ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard#endif /* CONFIG_NATIVE_WINDOWS */ 445ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard eloop.pending_terminate = 0; 446ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard } 447ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 448ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard for (i = 0; i < eloop.signal_count; i++) { 449ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard if (eloop.signals[i].signaled) { 450ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard eloop.signals[i].signaled = 0; 451ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard eloop.signals[i].handler(eloop.signals[i].sig, 452ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard eloop.signals[i].user_data); 453ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard } 454ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard } 455ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard} 456ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 457ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 458ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellardint eloop_register_signal(int sig, eloop_signal_handler handler, 459ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard void *user_data) 460ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard{ 461ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard struct eloop_signal *tmp; 462ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 463ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard tmp = (struct eloop_signal *) 464ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard os_realloc(eloop.signals, 465ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard (eloop.signal_count + 1) * 466ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard sizeof(struct eloop_signal)); 467ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard if (tmp == NULL) 468ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard return -1; 469ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 470ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard tmp[eloop.signal_count].sig = sig; 471ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard tmp[eloop.signal_count].user_data = user_data; 472ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard tmp[eloop.signal_count].handler = handler; 473e42df8e10a83e76565474f82330d34403da71b49Tom Stellard tmp[eloop.signal_count].signaled = 0; 474e42df8e10a83e76565474f82330d34403da71b49Tom Stellard eloop.signal_count++; 475e42df8e10a83e76565474f82330d34403da71b49Tom Stellard eloop.signals = tmp; 476e42df8e10a83e76565474f82330d34403da71b49Tom Stellard signal(sig, eloop_handle_signal); 4772c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard 4782c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard return 0; 4792c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard} 4802c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard 4812c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard 482e42df8e10a83e76565474f82330d34403da71b49Tom Stellardint eloop_register_signal_terminate(eloop_signal_handler handler, 4832c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard void *user_data) 4842c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard{ 4852c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard int ret = eloop_register_signal(SIGINT, handler, user_data); 4862c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard if (ret == 0) 4872c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard ret = eloop_register_signal(SIGTERM, handler, user_data); 4882c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard return ret; 4892c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard} 4902c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard 4912c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard 4922c485cda2062ca2b9af89ea62618515d960c7904Tom Stellardint eloop_register_signal_reconfig(eloop_signal_handler handler, 4932c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard void *user_data) 4942c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard{ 4952c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard#ifdef CONFIG_NATIVE_WINDOWS 4962c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard return 0; 4972c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard#else /* CONFIG_NATIVE_WINDOWS */ 4982c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard return eloop_register_signal(SIGHUP, handler, user_data); 4992c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard#endif /* CONFIG_NATIVE_WINDOWS */ 5002c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard} 5012c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard 5022c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard 5032c485cda2062ca2b9af89ea62618515d960c7904Tom Stellardvoid eloop_run(void) 5042c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard{ 5052c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard fd_set *rfds, *wfds, *efds; 5062c485cda2062ca2b9af89ea62618515d960c7904Tom Stellard int res; 507e42df8e10a83e76565474f82330d34403da71b49Tom Stellard struct timeval _tv; 508e42df8e10a83e76565474f82330d34403da71b49Tom Stellard struct os_time tv, now; 509e42df8e10a83e76565474f82330d34403da71b49Tom Stellard 510e42df8e10a83e76565474f82330d34403da71b49Tom Stellard rfds = os_malloc(sizeof(*rfds)); 511e42df8e10a83e76565474f82330d34403da71b49Tom Stellard wfds = os_malloc(sizeof(*wfds)); 512e42df8e10a83e76565474f82330d34403da71b49Tom Stellard efds = os_malloc(sizeof(*efds)); 513e42df8e10a83e76565474f82330d34403da71b49Tom Stellard if (rfds == NULL || wfds == NULL || efds == NULL) 514e42df8e10a83e76565474f82330d34403da71b49Tom Stellard goto out; 515e42df8e10a83e76565474f82330d34403da71b49Tom Stellard 516ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard while (!eloop.terminate && 517ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard (!dl_list_empty(&eloop.timeout) || eloop.readers.count > 0 || 518ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard eloop.writers.count > 0 || eloop.exceptions.count > 0)) { 519ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard struct eloop_timeout *timeout; 5206f50f939ef85bb058c1401b5dad8340aa4f96aecTom Stellard timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, 521ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard list); 522ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard if (timeout) { 523ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard os_get_time(&now); 524ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard if (os_time_before(&now, &timeout->time)) 525ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard os_time_sub(&timeout->time, &now, &tv); 526ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard else 527ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard tv.sec = tv.usec = 0; 528ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard _tv.tv_sec = tv.sec; 529ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard _tv.tv_usec = tv.usec; 530ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard } 531ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 532ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard eloop_sock_table_set_fds(&eloop.readers, rfds); 533ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard eloop_sock_table_set_fds(&eloop.writers, wfds); 534ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard eloop_sock_table_set_fds(&eloop.exceptions, efds); 535ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard res = select(eloop.max_sock + 1, rfds, wfds, efds, 5366f50f939ef85bb058c1401b5dad8340aa4f96aecTom Stellard timeout ? &_tv : NULL); 5376f50f939ef85bb058c1401b5dad8340aa4f96aecTom Stellard if (res < 0 && errno != EINTR && errno != 0) { 5386f50f939ef85bb058c1401b5dad8340aa4f96aecTom Stellard perror("select"); 5396f50f939ef85bb058c1401b5dad8340aa4f96aecTom Stellard goto out; 5406f50f939ef85bb058c1401b5dad8340aa4f96aecTom Stellard } 5416f50f939ef85bb058c1401b5dad8340aa4f96aecTom Stellard eloop_process_pending_signals(); 5426f50f939ef85bb058c1401b5dad8340aa4f96aecTom Stellard 5436f50f939ef85bb058c1401b5dad8340aa4f96aecTom Stellard /* check if some registered timeouts have occurred */ 5446f50f939ef85bb058c1401b5dad8340aa4f96aecTom Stellard timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, 545e42df8e10a83e76565474f82330d34403da71b49Tom Stellard list); 546e42df8e10a83e76565474f82330d34403da71b49Tom Stellard if (timeout) { 547e42df8e10a83e76565474f82330d34403da71b49Tom Stellard os_get_time(&now); 548e42df8e10a83e76565474f82330d34403da71b49Tom Stellard if (!os_time_before(&now, &timeout->time)) { 549e42df8e10a83e76565474f82330d34403da71b49Tom Stellard void *eloop_data = timeout->eloop_data; 550ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard void *user_data = timeout->user_data; 551ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard eloop_timeout_handler handler = 552ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard timeout->handler; 553ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard eloop_remove_timeout(timeout); 554ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard handler(eloop_data, user_data); 555ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard } 556ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard 557ced73ea5df306156e5383b438d6858e58b1479e5Tom Stellard } 558de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse 559de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse if (res <= 0) 560de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse continue; 561de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse 562de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse eloop_sock_table_dispatch(&eloop.readers, rfds); 563de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse eloop_sock_table_dispatch(&eloop.writers, wfds); 564de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse eloop_sock_table_dispatch(&eloop.exceptions, efds); 565de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse } 566de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse 56772128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisseout: 568de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse os_free(rfds); 569de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse os_free(wfds); 570de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse os_free(efds); 571c6131879eb7dfdf26cd068109f6680608d608ab4Jerome Glisse} 572a03d456f5a41926e39194de70b2d50776e64b8a2Dave Airlie 573de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse 574de553d906b4a205d811a9e1651f14212ec284e29Jerome Glissevoid eloop_terminate(void) 575de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse{ 57672128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse eloop.terminate = 1; 577a03d456f5a41926e39194de70b2d50776e64b8a2Dave Airlie} 578de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse 5798260ab93461eca3e18f9c17a9ca1961a11372071Keith Whitwell 5808260ab93461eca3e18f9c17a9ca1961a11372071Keith Whitwellvoid eloop_destroy(void) 5818260ab93461eca3e18f9c17a9ca1961a11372071Keith Whitwell{ 582de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse struct eloop_timeout *timeout, *prev; 583de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse struct os_time now; 584de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse 585de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse os_get_time(&now); 58647d5a19df1e7760c4f5f0e340bfc56355c2e428bDave Airlie dl_list_for_each_safe(timeout, prev, &eloop.timeout, 58747d5a19df1e7760c4f5f0e340bfc56355c2e428bDave Airlie struct eloop_timeout, list) { 588de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse int sec, usec; 589de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse sec = timeout->time.sec - now.sec; 590de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse usec = timeout->time.usec - now.usec; 591de553d906b4a205d811a9e1651f14212ec284e29Jerome Glisse if (timeout->time.usec < now.usec) { 59272128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse sec--; 59372128962d640846472c1b0dc22cf4ac6ce875dc9Jerome Glisse usec += 1000000; 594fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie } 59550526e094f4c66957c7f74c190c35903bc82fb62Dave Airlie wpa_printf(MSG_INFO, "ELOOP: remaining timeout: %d.%06d " 59650526e094f4c66957c7f74c190c35903bc82fb62Dave Airlie "eloop_data=%p user_data=%p handler=%p", 5974a47662beaa2092447939db7880531fb706afeddMarek Olšák sec, usec, timeout->eloop_data, timeout->user_data, 598fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie timeout->handler); 599fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie wpa_trace_dump_funcname("eloop unregistered timeout handler", 600fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie timeout->handler); 601fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie wpa_trace_dump("eloop timeout", timeout); 602fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie eloop_remove_timeout(timeout); 603fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie } 604fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie eloop_sock_table_destroy(&eloop.readers); 605fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie eloop_sock_table_destroy(&eloop.writers); 606fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie eloop_sock_table_destroy(&eloop.exceptions); 607fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie os_free(eloop.signals); 608fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie} 609fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie 610fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie 611fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlieint eloop_terminated(void) 612fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie{ 613fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie return eloop.terminate; 614fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie} 615fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie 616fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie 6177ffd4e976fd11b8c083c2927effd25a2f79ac841Jerome Glissevoid eloop_wait_for_read_sock(int sock) 618fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie{ 619fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie fd_set rfds; 620fc6caef4cb67fb13642c5ebccee53019d1764df6Dave Airlie 62150526e094f4c66957c7f74c190c35903bc82fb62Dave Airlie if (sock < 0) 62250526e094f4c66957c7f74c190c35903bc82fb62Dave Airlie return; 6234a47662beaa2092447939db7880531fb706afeddMarek Olšák 62450526e094f4c66957c7f74c190c35903bc82fb62Dave Airlie FD_ZERO(&rfds); 62550526e094f4c66957c7f74c190c35903bc82fb62Dave Airlie FD_SET(sock, &rfds); 626738334e80cf8a7b9fbf573f3a77cbf767ce81095Vadim Girlin select(sock + 1, &rfds, NULL, NULL, NULL); 62750526e094f4c66957c7f74c190c35903bc82fb62Dave Airlie} 628738334e80cf8a7b9fbf573f3a77cbf767ce81095Vadim Girlin