a399b7655a1d835aa8606c2b29e4e777baac8635zf/*
39de7e401c4775b362a283e4714b49f6859eecabdanmcd * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
a399b7655a1d835aa8606c2b29e4e777baac8635zf * Use is subject to license terms.
a399b7655a1d835aa8606c2b29e4e777baac8635zf */
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf/*
a399b7655a1d835aa8606c2b29e4e777baac8635zf * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
a399b7655a1d835aa8606c2b29e4e777baac8635zf * Sun elects to license this software under the BSD license.
a399b7655a1d835aa8606c2b29e4e777baac8635zf * See README for more details.
a399b7655a1d835aa8606c2b29e4e777baac8635zf */
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf#pragma ident "%Z%%M% %I% %E% SMI"
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf#include <stdio.h>
a399b7655a1d835aa8606c2b29e4e777baac8635zf#include <stdlib.h>
a399b7655a1d835aa8606c2b29e4e777baac8635zf#include <string.h>
a399b7655a1d835aa8606c2b29e4e777baac8635zf#include <sys/time.h>
a399b7655a1d835aa8606c2b29e4e777baac8635zf#include <unistd.h>
a399b7655a1d835aa8606c2b29e4e777baac8635zf#include <errno.h>
a399b7655a1d835aa8606c2b29e4e777baac8635zf#include <signal.h>
a399b7655a1d835aa8606c2b29e4e777baac8635zf#include <poll.h>
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf#include "eloop.h"
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zfstatic struct eloop_data eloop;
a399b7655a1d835aa8606c2b29e4e777baac8635zf/*
a399b7655a1d835aa8606c2b29e4e777baac8635zf * Initialize global event loop data - must be called before any other eloop_*
a399b7655a1d835aa8606c2b29e4e777baac8635zf * function. user_data is a pointer to global data structure and will be passed
a399b7655a1d835aa8606c2b29e4e777baac8635zf * as eloop_ctx to signal handlers.
a399b7655a1d835aa8606c2b29e4e777baac8635zf */
a399b7655a1d835aa8606c2b29e4e777baac8635zfvoid
a399b7655a1d835aa8606c2b29e4e777baac8635zfeloop_init(void *user_data)
a399b7655a1d835aa8606c2b29e4e777baac8635zf{
a399b7655a1d835aa8606c2b29e4e777baac8635zf (void) memset(&eloop, 0, sizeof (eloop));
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.user_data = user_data;
a399b7655a1d835aa8606c2b29e4e777baac8635zf}
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf/*
a399b7655a1d835aa8606c2b29e4e777baac8635zf * Register handler for read event
a399b7655a1d835aa8606c2b29e4e777baac8635zf */
a399b7655a1d835aa8606c2b29e4e777baac8635zfint
a399b7655a1d835aa8606c2b29e4e777baac8635zfeloop_register_read_sock(int sock,
a399b7655a1d835aa8606c2b29e4e777baac8635zf void (*handler)(int sock, void *eloop_ctx,
a399b7655a1d835aa8606c2b29e4e777baac8635zf void *sock_ctx), void *eloop_data, void *user_data)
a399b7655a1d835aa8606c2b29e4e777baac8635zf{
a399b7655a1d835aa8606c2b29e4e777baac8635zf struct eloop_sock *tmp;
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf tmp = (struct eloop_sock *)realloc(eloop.readers,
a399b7655a1d835aa8606c2b29e4e777baac8635zf (eloop.reader_count + 1) * sizeof (struct eloop_sock));
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (tmp == NULL)
a399b7655a1d835aa8606c2b29e4e777baac8635zf return (-1);
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf tmp[eloop.reader_count].sock = sock;
a399b7655a1d835aa8606c2b29e4e777baac8635zf tmp[eloop.reader_count].eloop_data = eloop_data;
a399b7655a1d835aa8606c2b29e4e777baac8635zf tmp[eloop.reader_count].user_data = user_data;
a399b7655a1d835aa8606c2b29e4e777baac8635zf tmp[eloop.reader_count].handler = handler;
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.reader_count++;
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.readers = tmp;
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (sock > eloop.max_sock)
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.max_sock = sock;
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf return (0);
a399b7655a1d835aa8606c2b29e4e777baac8635zf}
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zfvoid
a399b7655a1d835aa8606c2b29e4e777baac8635zfeloop_unregister_read_sock(int sock)
a399b7655a1d835aa8606c2b29e4e777baac8635zf{
a399b7655a1d835aa8606c2b29e4e777baac8635zf int i;
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (eloop.readers == NULL || eloop.reader_count == 0)
a399b7655a1d835aa8606c2b29e4e777baac8635zf return;
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf for (i = 0; i < eloop.reader_count; i++) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (eloop.readers[i].sock == sock)
a399b7655a1d835aa8606c2b29e4e777baac8635zf break;
a399b7655a1d835aa8606c2b29e4e777baac8635zf }
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (i == eloop.reader_count)
a399b7655a1d835aa8606c2b29e4e777baac8635zf return;
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (i != eloop.reader_count - 1) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf (void) memmove(&eloop.readers[i], &eloop.readers[i + 1],
a399b7655a1d835aa8606c2b29e4e777baac8635zf (eloop.reader_count - i - 1) *
a399b7655a1d835aa8606c2b29e4e777baac8635zf sizeof (struct eloop_sock));
a399b7655a1d835aa8606c2b29e4e777baac8635zf }
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.reader_count--;
a399b7655a1d835aa8606c2b29e4e777baac8635zf}
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf/*
a399b7655a1d835aa8606c2b29e4e777baac8635zf * Register timeout routines
a399b7655a1d835aa8606c2b29e4e777baac8635zf */
a399b7655a1d835aa8606c2b29e4e777baac8635zfint
a399b7655a1d835aa8606c2b29e4e777baac8635zfeloop_register_timeout(unsigned int secs, unsigned int usecs,
a399b7655a1d835aa8606c2b29e4e777baac8635zf void (*handler)(void *eloop_ctx, void *timeout_ctx),
a399b7655a1d835aa8606c2b29e4e777baac8635zf void *eloop_data, void *user_data)
a399b7655a1d835aa8606c2b29e4e777baac8635zf{
a399b7655a1d835aa8606c2b29e4e777baac8635zf struct eloop_timeout *timeout, *tmp, *prev;
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf timeout = (struct eloop_timeout *)malloc(sizeof (*timeout));
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (timeout == NULL)
a399b7655a1d835aa8606c2b29e4e777baac8635zf return (-1);
a399b7655a1d835aa8606c2b29e4e777baac8635zf (void) gettimeofday(&timeout->time, NULL);
a399b7655a1d835aa8606c2b29e4e777baac8635zf timeout->time.tv_sec += secs;
a399b7655a1d835aa8606c2b29e4e777baac8635zf timeout->time.tv_usec += usecs;
a399b7655a1d835aa8606c2b29e4e777baac8635zf while (timeout->time.tv_usec >= 1000000) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf timeout->time.tv_sec++;
a399b7655a1d835aa8606c2b29e4e777baac8635zf timeout->time.tv_usec -= 1000000;
a399b7655a1d835aa8606c2b29e4e777baac8635zf }
a399b7655a1d835aa8606c2b29e4e777baac8635zf timeout->eloop_data = eloop_data;
a399b7655a1d835aa8606c2b29e4e777baac8635zf timeout->user_data = user_data;
a399b7655a1d835aa8606c2b29e4e777baac8635zf timeout->handler = handler;
a399b7655a1d835aa8606c2b29e4e777baac8635zf timeout->next = NULL;
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (eloop.timeout == NULL) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.timeout = timeout;
a399b7655a1d835aa8606c2b29e4e777baac8635zf return (0);
a399b7655a1d835aa8606c2b29e4e777baac8635zf }
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf prev = NULL;
a399b7655a1d835aa8606c2b29e4e777baac8635zf tmp = eloop.timeout;
a399b7655a1d835aa8606c2b29e4e777baac8635zf while (tmp != NULL) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (timercmp(&timeout->time, &tmp->time, < /* */))
a399b7655a1d835aa8606c2b29e4e777baac8635zf break;
a399b7655a1d835aa8606c2b29e4e777baac8635zf prev = tmp;
a399b7655a1d835aa8606c2b29e4e777baac8635zf tmp = tmp->next;
a399b7655a1d835aa8606c2b29e4e777baac8635zf }
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (prev == NULL) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf timeout->next = eloop.timeout;
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.timeout = timeout;
a399b7655a1d835aa8606c2b29e4e777baac8635zf } else {
a399b7655a1d835aa8606c2b29e4e777baac8635zf timeout->next = prev->next;
a399b7655a1d835aa8606c2b29e4e777baac8635zf prev->next = timeout;
a399b7655a1d835aa8606c2b29e4e777baac8635zf }
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf return (0);
a399b7655a1d835aa8606c2b29e4e777baac8635zf}
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf/*
a399b7655a1d835aa8606c2b29e4e777baac8635zf * Cancel timeouts matching <handler,eloop_data,user_data>.
a399b7655a1d835aa8606c2b29e4e777baac8635zf * ELOOP_ALL_CTX can be used as a wildcard for cancelling all timeouts
a399b7655a1d835aa8606c2b29e4e777baac8635zf * regardless of eloop_data/user_data.
a399b7655a1d835aa8606c2b29e4e777baac8635zf */
a399b7655a1d835aa8606c2b29e4e777baac8635zfvoid
a399b7655a1d835aa8606c2b29e4e777baac8635zfeloop_cancel_timeout(void (*handler)(void *eloop_ctx, void *sock_ctx),
a399b7655a1d835aa8606c2b29e4e777baac8635zf void *eloop_data, void *user_data)
a399b7655a1d835aa8606c2b29e4e777baac8635zf{
a399b7655a1d835aa8606c2b29e4e777baac8635zf struct eloop_timeout *timeout, *prev, *next;
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf prev = NULL;
a399b7655a1d835aa8606c2b29e4e777baac8635zf timeout = eloop.timeout;
a399b7655a1d835aa8606c2b29e4e777baac8635zf while (timeout != NULL) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf next = timeout->next;
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (timeout->handler == handler &&
a399b7655a1d835aa8606c2b29e4e777baac8635zf (timeout->eloop_data == eloop_data ||
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop_data == ELOOP_ALL_CTX) &&
a399b7655a1d835aa8606c2b29e4e777baac8635zf (timeout->user_data == user_data ||
a399b7655a1d835aa8606c2b29e4e777baac8635zf user_data == ELOOP_ALL_CTX)) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (prev == NULL)
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.timeout = next;
a399b7655a1d835aa8606c2b29e4e777baac8635zf else
a399b7655a1d835aa8606c2b29e4e777baac8635zf prev->next = next;
a399b7655a1d835aa8606c2b29e4e777baac8635zf free(timeout);
a399b7655a1d835aa8606c2b29e4e777baac8635zf } else
a399b7655a1d835aa8606c2b29e4e777baac8635zf prev = timeout;
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf timeout = next;
a399b7655a1d835aa8606c2b29e4e777baac8635zf }
a399b7655a1d835aa8606c2b29e4e777baac8635zf}
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zfstatic void eloop_handle_signal(int sig)
a399b7655a1d835aa8606c2b29e4e777baac8635zf{
a399b7655a1d835aa8606c2b29e4e777baac8635zf int i;
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.signaled++;
a399b7655a1d835aa8606c2b29e4e777baac8635zf for (i = 0; i < eloop.signal_count; i++) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (eloop.signals[i].sig == sig) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.signals[i].signaled++;
a399b7655a1d835aa8606c2b29e4e777baac8635zf break;
a399b7655a1d835aa8606c2b29e4e777baac8635zf }
a399b7655a1d835aa8606c2b29e4e777baac8635zf }
a399b7655a1d835aa8606c2b29e4e777baac8635zf}
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zfstatic void eloop_process_pending_signals(void)
a399b7655a1d835aa8606c2b29e4e777baac8635zf{
a399b7655a1d835aa8606c2b29e4e777baac8635zf int i;
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (eloop.signaled == 0)
a399b7655a1d835aa8606c2b29e4e777baac8635zf return;
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.signaled = 0;
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf for (i = 0; i < eloop.signal_count; i++) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (eloop.signals[i].signaled) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.signals[i].signaled = 0;
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.signals[i].handler(eloop.signals[i].sig,
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.user_data, eloop.signals[i].user_data);
a399b7655a1d835aa8606c2b29e4e777baac8635zf }
a399b7655a1d835aa8606c2b29e4e777baac8635zf }
a399b7655a1d835aa8606c2b29e4e777baac8635zf}
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf/*
a399b7655a1d835aa8606c2b29e4e777baac8635zf * Register handler for signal.
a399b7655a1d835aa8606c2b29e4e777baac8635zf * Note: signals are 'global' events and there is no local eloop_data pointer
a399b7655a1d835aa8606c2b29e4e777baac8635zf * like with other handlers. The (global) pointer given to eloop_init() will be
a399b7655a1d835aa8606c2b29e4e777baac8635zf * used as eloop_ctx for signal handlers.
a399b7655a1d835aa8606c2b29e4e777baac8635zf */
a399b7655a1d835aa8606c2b29e4e777baac8635zfint
a399b7655a1d835aa8606c2b29e4e777baac8635zfeloop_register_signal(int sig,
a399b7655a1d835aa8606c2b29e4e777baac8635zf void (*handler)(int sig, void *eloop_ctx, void *signal_ctx),
a399b7655a1d835aa8606c2b29e4e777baac8635zf void *user_data)
a399b7655a1d835aa8606c2b29e4e777baac8635zf{
a399b7655a1d835aa8606c2b29e4e777baac8635zf struct eloop_signal *tmp;
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf tmp = (struct eloop_signal *)
a399b7655a1d835aa8606c2b29e4e777baac8635zf realloc(eloop.signals,
a399b7655a1d835aa8606c2b29e4e777baac8635zf (eloop.signal_count + 1) *
a399b7655a1d835aa8606c2b29e4e777baac8635zf sizeof (struct eloop_signal));
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (tmp == NULL)
a399b7655a1d835aa8606c2b29e4e777baac8635zf return (-1);
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf tmp[eloop.signal_count].sig = sig;
a399b7655a1d835aa8606c2b29e4e777baac8635zf tmp[eloop.signal_count].user_data = user_data;
a399b7655a1d835aa8606c2b29e4e777baac8635zf tmp[eloop.signal_count].handler = handler;
a399b7655a1d835aa8606c2b29e4e777baac8635zf tmp[eloop.signal_count].signaled = 0;
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.signal_count++;
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.signals = tmp;
a399b7655a1d835aa8606c2b29e4e777baac8635zf (void) signal(sig, eloop_handle_signal);
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf return (0);
a399b7655a1d835aa8606c2b29e4e777baac8635zf}
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf/*
a399b7655a1d835aa8606c2b29e4e777baac8635zf * Start event loop and continue running as long as there are any registered
a399b7655a1d835aa8606c2b29e4e777baac8635zf * event handlers.
a399b7655a1d835aa8606c2b29e4e777baac8635zf */
a399b7655a1d835aa8606c2b29e4e777baac8635zfvoid
a399b7655a1d835aa8606c2b29e4e777baac8635zfeloop_run(void)
a399b7655a1d835aa8606c2b29e4e777baac8635zf{
a399b7655a1d835aa8606c2b29e4e777baac8635zf struct pollfd pfds[MAX_POLLFDS]; /* array of polled fd */
a399b7655a1d835aa8606c2b29e4e777baac8635zf int i, res;
a399b7655a1d835aa8606c2b29e4e777baac8635zf int default_t, t;
a399b7655a1d835aa8606c2b29e4e777baac8635zf struct timeval tv, now;
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf default_t = 5 * 1000; /* 5 seconds */
a399b7655a1d835aa8606c2b29e4e777baac8635zf while (!eloop.terminate &&
39de7e401c4775b362a283e4714b49f6859eecabdanmcd (eloop.timeout || eloop.reader_count > 0)) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (eloop.timeout) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf (void) gettimeofday(&now, NULL);
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (timercmp(&now, &eloop.timeout->time, < /* */))
a399b7655a1d835aa8606c2b29e4e777baac8635zf timersub(&eloop.timeout->time, &now, &tv);
a399b7655a1d835aa8606c2b29e4e777baac8635zf else
a399b7655a1d835aa8606c2b29e4e777baac8635zf tv.tv_sec = tv.tv_usec = 0;
a399b7655a1d835aa8606c2b29e4e777baac8635zf }
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf t = (eloop.timeout == NULL ?
a399b7655a1d835aa8606c2b29e4e777baac8635zf default_t : (tv.tv_sec * 1000 + tv.tv_usec / 1000));
a399b7655a1d835aa8606c2b29e4e777baac8635zf for (i = 0; i < eloop.reader_count; i++) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf pfds[i].fd = eloop.readers[i].sock;
a399b7655a1d835aa8606c2b29e4e777baac8635zf pfds[i].events = POLLIN | POLLPRI;
a399b7655a1d835aa8606c2b29e4e777baac8635zf }
a399b7655a1d835aa8606c2b29e4e777baac8635zf res = poll(pfds, eloop.reader_count, t);
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (res < 0 && errno != EINTR)
a399b7655a1d835aa8606c2b29e4e777baac8635zf return;
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop_process_pending_signals();
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf /* check if some registered timeouts have occurred */
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (eloop.timeout) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf struct eloop_timeout *tmp;
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf (void) gettimeofday(&now, NULL);
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (!timercmp(&now, &eloop.timeout->time, < /* */)) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf tmp = eloop.timeout;
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.timeout = eloop.timeout->next;
a399b7655a1d835aa8606c2b29e4e777baac8635zf tmp->handler(tmp->eloop_data, tmp->user_data);
a399b7655a1d835aa8606c2b29e4e777baac8635zf free(tmp);
a399b7655a1d835aa8606c2b29e4e777baac8635zf }
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf }
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (res <= 0)
a399b7655a1d835aa8606c2b29e4e777baac8635zf continue;
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf for (i = 0; i < eloop.reader_count; i++) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf if (pfds[i].revents) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.readers[i].handler(
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.readers[i].sock,
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.readers[i].eloop_data,
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.readers[i].user_data);
a399b7655a1d835aa8606c2b29e4e777baac8635zf }
a399b7655a1d835aa8606c2b29e4e777baac8635zf }
a399b7655a1d835aa8606c2b29e4e777baac8635zf }
a399b7655a1d835aa8606c2b29e4e777baac8635zf}
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf/*
a399b7655a1d835aa8606c2b29e4e777baac8635zf * Terminate event loop even if there are registered events.
a399b7655a1d835aa8606c2b29e4e777baac8635zf */
a399b7655a1d835aa8606c2b29e4e777baac8635zfvoid
a399b7655a1d835aa8606c2b29e4e777baac8635zfeloop_terminate(void)
a399b7655a1d835aa8606c2b29e4e777baac8635zf{
a399b7655a1d835aa8606c2b29e4e777baac8635zf eloop.terminate = 1;
a399b7655a1d835aa8606c2b29e4e777baac8635zf}
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf/*
a399b7655a1d835aa8606c2b29e4e777baac8635zf * Free any reserved resources. After calling eloop_destoy(), other eloop_*
a399b7655a1d835aa8606c2b29e4e777baac8635zf * functions must not be called before re-running eloop_init().
a399b7655a1d835aa8606c2b29e4e777baac8635zf */
a399b7655a1d835aa8606c2b29e4e777baac8635zfvoid
a399b7655a1d835aa8606c2b29e4e777baac8635zfeloop_destroy(void)
a399b7655a1d835aa8606c2b29e4e777baac8635zf{
a399b7655a1d835aa8606c2b29e4e777baac8635zf struct eloop_timeout *timeout, *prev;
a399b7655a1d835aa8606c2b29e4e777baac8635zf
a399b7655a1d835aa8606c2b29e4e777baac8635zf timeout = eloop.timeout;
a399b7655a1d835aa8606c2b29e4e777baac8635zf while (timeout != NULL) {
a399b7655a1d835aa8606c2b29e4e777baac8635zf prev = timeout;
a399b7655a1d835aa8606c2b29e4e777baac8635zf timeout = timeout->next;
a399b7655a1d835aa8606c2b29e4e777baac8635zf free(prev);
a399b7655a1d835aa8606c2b29e4e777baac8635zf }
a399b7655a1d835aa8606c2b29e4e777baac8635zf free(eloop.readers);
a399b7655a1d835aa8606c2b29e4e777baac8635zf free(eloop.signals);
a399b7655a1d835aa8606c2b29e4e777baac8635zf}