1526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* 2526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Event loop - empty template (basic structure, but no OS specific operations) 3526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi> 4526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 5526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This program is free software; you can redistribute it and/or modify 6526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * it under the terms of the GNU General Public License version 2 as 7526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * published by the Free Software Foundation. 8526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 9526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 10526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * license. 11526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 12526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * See README and COPYING for more details. 13526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 14526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 15526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "includes.h" 16526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 17526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "common.h" 18526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "eloop.h" 19526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 20526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 21526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct eloop_sock { 22526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int sock; 23526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *eloop_data; 24526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *user_data; 25526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void (*handler)(int sock, void *eloop_ctx, void *sock_ctx); 26526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 27526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 28526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct eloop_timeout { 29526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct os_time time; 30526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *eloop_data; 31526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *user_data; 32526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void (*handler)(void *eloop_ctx, void *sock_ctx); 33526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eloop_timeout *next; 34526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 35526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 36526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct eloop_signal { 37526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int sig; 38526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *user_data; 39526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void (*handler)(int sig, void *eloop_ctx, void *signal_ctx); 40526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int signaled; 41526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 42526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 43526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct eloop_data { 44526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *user_data; 45526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 46526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int max_sock, reader_count; 47526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eloop_sock *readers; 48526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 49526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eloop_timeout *timeout; 50526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 51526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int signal_count; 52526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eloop_signal *signals; 53526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int signaled; 54526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int pending_terminate; 55526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 56526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int terminate; 57526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int reader_table_changed; 58526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 59526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 60526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct eloop_data eloop; 61526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 62526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 63526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint eloop_init(void *user_data) 64526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 65526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt memset(&eloop, 0, sizeof(eloop)); 66526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.user_data = user_data; 67526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 68526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 69526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 70526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 71526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint eloop_register_read_sock(int sock, 72526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void (*handler)(int sock, void *eloop_ctx, 73526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *sock_ctx), 74526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *eloop_data, void *user_data) 75526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 76526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eloop_sock *tmp; 77526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 78526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp = (struct eloop_sock *) 79526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt realloc(eloop.readers, 80526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (eloop.reader_count + 1) * sizeof(struct eloop_sock)); 81526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (tmp == NULL) 82526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 83526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 84526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp[eloop.reader_count].sock = sock; 85526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp[eloop.reader_count].eloop_data = eloop_data; 86526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp[eloop.reader_count].user_data = user_data; 87526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp[eloop.reader_count].handler = handler; 88526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.reader_count++; 89526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.readers = tmp; 90526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sock > eloop.max_sock) 91526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.max_sock = sock; 92526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.reader_table_changed = 1; 93526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 94526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 95526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 96526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 97526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 98526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid eloop_unregister_read_sock(int sock) 99526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int i; 101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eloop.readers == NULL || eloop.reader_count == 0) 103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < eloop.reader_count; i++) { 106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eloop.readers[i].sock == sock) 107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (i == eloop.reader_count) 110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (i != eloop.reader_count - 1) { 112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt memmove(&eloop.readers[i], &eloop.readers[i + 1], 113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (eloop.reader_count - i - 1) * 114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sizeof(struct eloop_sock)); 115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.reader_count--; 117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.reader_table_changed = 1; 118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint eloop_register_timeout(unsigned int secs, unsigned int usecs, 122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void (*handler)(void *eloop_ctx, void *timeout_ctx), 123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *eloop_data, void *user_data) 124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eloop_timeout *timeout, *tmp, *prev; 126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt timeout = (struct eloop_timeout *) malloc(sizeof(*timeout)); 128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (timeout == NULL) 129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_get_time(&timeout->time); 131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt timeout->time.sec += secs; 132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt timeout->time.usec += usecs; 133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (timeout->time.usec >= 1000000) { 134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt timeout->time.sec++; 135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt timeout->time.usec -= 1000000; 136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt timeout->eloop_data = eloop_data; 138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt timeout->user_data = user_data; 139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt timeout->handler = handler; 140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt timeout->next = NULL; 141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eloop.timeout == NULL) { 143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.timeout = timeout; 144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt prev = NULL; 148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp = eloop.timeout; 149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (tmp != NULL) { 150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (os_time_before(&timeout->time, &tmp->time)) 151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt prev = tmp; 153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp = tmp->next; 154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (prev == NULL) { 157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt timeout->next = eloop.timeout; 158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.timeout = timeout; 159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt timeout->next = prev->next; 161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt prev->next = timeout; 162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint eloop_cancel_timeout(void (*handler)(void *eloop_ctx, void *sock_ctx), 169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *eloop_data, void *user_data) 170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eloop_timeout *timeout, *prev, *next; 172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int removed = 0; 173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt prev = NULL; 175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt timeout = eloop.timeout; 176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (timeout != NULL) { 177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt next = timeout->next; 178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (timeout->handler == handler && 180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (timeout->eloop_data == eloop_data || 181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_data == ELOOP_ALL_CTX) && 182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (timeout->user_data == user_data || 183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt user_data == ELOOP_ALL_CTX)) { 184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (prev == NULL) 185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.timeout = next; 186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt prev->next = next; 188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt free(timeout); 189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt removed++; 190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else 191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt prev = timeout; 192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt timeout = next; 194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return removed; 197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint eloop_is_timeout_registered(void (*handler)(void *eloop_ctx, 201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *timeout_ctx), 202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *eloop_data, void *user_data) 203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eloop_timeout *tmp; 205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp = eloop.timeout; 207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (tmp != NULL) { 208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (tmp->handler == handler && 209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp->eloop_data == eloop_data && 210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp->user_data == user_data) 211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 1; 212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp = tmp->next; 214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 219526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 220526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* TODO: replace with suitable signal handler */ 221526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#if 0 222526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void eloop_handle_signal(int sig) 223526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 224526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int i; 225526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 226526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.signaled++; 227526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < eloop.signal_count; i++) { 228526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eloop.signals[i].sig == sig) { 229526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.signals[i].signaled++; 230526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 231526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 232526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 233526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 234526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 235526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 236526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 237526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void eloop_process_pending_signals(void) 238526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 239526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int i; 240526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eloop.signaled == 0) 242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.signaled = 0; 244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eloop.pending_terminate) { 246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.pending_terminate = 0; 247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < eloop.signal_count; i++) { 250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eloop.signals[i].signaled) { 251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.signals[i].signaled = 0; 252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.signals[i].handler(eloop.signals[i].sig, 253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.user_data, 254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.signals[i].user_data); 255526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 256526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 257526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 258526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 259526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 260526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint eloop_register_signal(int sig, 261526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void (*handler)(int sig, void *eloop_ctx, 262526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *signal_ctx), 263526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *user_data) 264526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 265526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eloop_signal *tmp; 266526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 267526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp = (struct eloop_signal *) 268526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt realloc(eloop.signals, 269526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (eloop.signal_count + 1) * 270526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sizeof(struct eloop_signal)); 271526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (tmp == NULL) 272526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 273526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 274526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp[eloop.signal_count].sig = sig; 275526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp[eloop.signal_count].user_data = user_data; 276526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp[eloop.signal_count].handler = handler; 277526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp[eloop.signal_count].signaled = 0; 278526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.signal_count++; 279526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.signals = tmp; 280526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 281526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* TODO: register signal handler */ 282526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 283526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 284526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 285526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 286526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 287526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint eloop_register_signal_terminate(void (*handler)(int sig, void *eloop_ctx, 288526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *signal_ctx), 289526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *user_data) 290526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 291526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#if 0 292526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* TODO: for example */ 293526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int ret = eloop_register_signal(SIGINT, handler, user_data); 294526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret == 0) 295526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = eloop_register_signal(SIGTERM, handler, user_data); 296526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ret; 297526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 298526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 299526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 300526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 301526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 302526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint eloop_register_signal_reconfig(void (*handler)(int sig, void *eloop_ctx, 303526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *signal_ctx), 304526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *user_data) 305526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 306526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#if 0 307526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* TODO: for example */ 308526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eloop_register_signal(SIGHUP, handler, user_data); 309526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 310526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 311526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 312526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 313526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 314526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid eloop_run(void) 315526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 316526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int i; 317526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct os_time tv, now; 318526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 319526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (!eloop.terminate && 320526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (eloop.timeout || eloop.reader_count > 0)) { 321526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eloop.timeout) { 322526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_get_time(&now); 323526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (os_time_before(&now, &eloop.timeout->time)) 324526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_time_sub(&eloop.timeout->time, &now, &tv); 325526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 326526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tv.sec = tv.usec = 0; 327526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 328526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 329526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 330526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * TODO: wait for any event (read socket ready, timeout (tv), 331526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * signal 332526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 333526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_sleep(1, 0); /* just a dummy wait for testing */ 334526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 335526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_process_pending_signals(); 336526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 337526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* check if some registered timeouts have occurred */ 338526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eloop.timeout) { 339526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eloop_timeout *tmp; 340526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 341526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_get_time(&now); 342526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!os_time_before(&now, &eloop.timeout->time)) { 343526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp = eloop.timeout; 344526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.timeout = eloop.timeout->next; 345526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp->handler(tmp->eloop_data, 346526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp->user_data); 347526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt free(tmp); 348526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 349526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 350526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 351526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 352526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.reader_table_changed = 0; 353526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < eloop.reader_count; i++) { 354526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 355526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * TODO: call each handler that has pending data to 356526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * read 357526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 358526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (0 /* TODO: eloop.readers[i].sock ready */) { 359526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.readers[i].handler( 360526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.readers[i].sock, 361526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.readers[i].eloop_data, 362526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.readers[i].user_data); 363526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eloop.reader_table_changed) 364526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 365526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 366526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 367526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 368526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 369526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 370526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 371526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid eloop_terminate(void) 372526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 373526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop.terminate = 1; 374526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 375526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 376526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 377526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid eloop_destroy(void) 378526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 379526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct eloop_timeout *timeout, *prev; 380526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 381526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt timeout = eloop.timeout; 382526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (timeout != NULL) { 383526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt prev = timeout; 384526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt timeout = timeout->next; 385526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt free(prev); 386526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 387526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt free(eloop.readers); 388526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt free(eloop.signals); 389526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 390526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 391526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 392526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint eloop_terminated(void) 393526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 394526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eloop.terminate; 395526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 396526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 397526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 398526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid eloop_wait_for_read_sock(int sock) 399526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 400526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 401526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * TODO: wait for the file descriptor to have something available for 402526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * reading 403526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 404526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 405526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 406526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 407526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid * eloop_get_user_data(void) 408526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 409526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return eloop.user_data; 410526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 411