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