/****************************************************************************
* Copyright (C) 1998 WIDE Project. All rights reserved.
* Copyright (C) 1999,2000,2001,2002 University of Tromso. All rights reserved.
* Copyright (C) 2002 Invenia Innovation AS. All rights reserved.
*
* Author: Feike W. Dillema, feico@pasta.cs.uit.no.
* based on newbie code by Yusuke DOI, Keio Univ. Murai Lab.
****************************************************************************/
/*
* <$Id: ev_timeout.c,v 3.27 2002/12/11 16:39:49 dillema Exp $>
*/
#include "totd.h"
static Q_Set *ev_to_queue;
int ev_to_init (void) {
if (ev_to_queue)
return -1;
ev_to_queue = queue_create ();
if (!ev_to_queue)
return -1;
return 0;
}
int ev_to_register (Ev_TO_Data *td) {
char *fn = "ev_to_register()";
G_Queue *gq_new, *gq_tmp, *gq_prev;
gq_new = malloc (sizeof (G_Queue));
if (!gq_new)
syslog (LOG_ERR, "%s: Cannot allocate memory", fn);
else {
gq_prev = NULL;
/* find place insertion sort style */
for (gq_tmp = ev_to_queue->head; gq_tmp->next &&
((Ev_TO_Data *) (gq_tmp->p))->at < td->at;
gq_tmp = gq_tmp->next)
gq_prev = gq_tmp; /* just skip */
if (!gq_prev) {
if (T.debug > 3)
syslog (LOG_DEBUG, "%s: add event to head", fn);
gq_new->p = (void *) td;
gq_new->next = ev_to_queue->head;
ev_to_queue->head = gq_new;
} else {
while (gq_tmp->p &&
(((Ev_TO_Data *) (gq_tmp->p))->at == td->at)) {
gq_prev = gq_tmp;
gq_tmp = gq_tmp->next;
}
if (!gq_tmp->p) {
if (T.debug > 3)
syslog (LOG_DEBUG, "%s: add to tail",
fn);
ev_to_queue->tail->p = (void *) td;
ev_to_queue->tail->next = gq_new;
gq_new->p = NULL;
gq_new->next = NULL;
ev_to_queue->tail = gq_new;
} else {
if (T.debug > 3)
syslog (LOG_DEBUG, "%s: add to middle",
fn);
gq_new->p = (void *) td;
gq_prev->next = gq_new;
gq_new->next = gq_tmp;
}
}
/* SUCCESS */
return 0;
}
/* FAILURE */
return -1;
}
time_t ev_timeout_process (void) {
char *fn = "ev_timeout_process()";
Ev_TO_Data *td_tmp;
while ((td_tmp = (Ev_TO_Data *) queue_peek (ev_to_queue))
&& (td_tmp->at <= time (NULL))) {
/* process the event */
td_tmp = dequeue (ev_to_queue);
/* call timeout handler, if any */
if (td_tmp->handler) {
if (T.debug > 3)
syslog (LOG_DEBUG, "%s: call timeout handler",
fn);
(td_tmp->handler) (td_tmp);
} else
if (T.debug > 3)
syslog (LOG_DEBUG, "%s: cancel timeout event",
fn);
ev_to_data_free (td_tmp);
}
td_tmp = (Ev_TO_Data *) queue_peek (ev_to_queue);
if (td_tmp)
return td_tmp->at; /* next event scheduled time */
else
return 0; /* no event scheduled */
}
void ev_to_data_free (Ev_TO_Data *td) {
char *fn = "ev_to_data_free()";
switch (td->type) {
case EV_TIMEOUT_NULL:
if (td->data.p)
free (td->data.p);
break;
case EV_TIMEOUT_CONTEXT:
/*
* don't free td->data.cont because transaction itself will
* free its context
*/
break;
default:
syslog (LOG_CRIT, "%s: unknown type for timeout event", fn);
break;
}
free (td);
}
void ev_to_data_free_v (void *td_v) {
ev_to_data_free ((Ev_TO_Data *) td_v);
}
void ev_to_finish (void) {
queue_destroy (ev_to_queue, ev_to_data_free_v);
}
void ev_to_flush (int type) {
G_Queue *gqp;
Ev_TO_Data *etdp;
/* check one by one */
for (gqp = ev_to_queue->head; gqp->next; gqp = gqp->next) {
if (gqp->p) {
etdp = (Ev_TO_Data *) (gqp->p);
if (etdp->type == type) {
if (etdp->handler)
(etdp->handler) (etdp);
etdp->handler = NULL; /* disable the queue */
}
}
}
return;
}
int ev_to_register_ifcheck (void) {
char *fn = "ev_to_register_ifcheck()";
Ev_TO_Data *td_new;
if (T.debug > 2)
syslog (LOG_DEBUG, "%s: start", fn);
if (!ev_to_queue)
return -1;
td_new = malloc (sizeof (Ev_TO_Data));
if (!td_new) {
syslog (LOG_ERR, "%s: can't allocate new event", fn);
return -1;
}
td_new->at = time (NULL) + IF_CHECK_INTERVAL;
td_new->handler = ev_to_handler_ifcheck;
td_new->type = EV_TIMEOUT_NULL;
td_new->data.p = NULL;
ev_to_register (td_new);
return 0;
}
int ev_to_handler_ifcheck (Ev_TO_Data *td) {
char *fn = "ev_to_handler_ifcheck()";
if (T.debug > 2)
syslog (LOG_DEBUG, "%s: start", fn);
if (td) {
switch (net_reinit_socketlist (T.port, 0)) {
case 0:
/* no change */
syslog (LOG_DEBUG, "%s: Socket List still the same", fn);
break;
case 1:
/* change, bound new sockets */
syslog (LOG_DEBUG, "%s: Socket List updated", fn);
break;
default:
syslog (LOG_ERR, "%s: Can't get new socket list!", fn);
}
}
/* (re-) register my event */
return (ev_to_register_ifcheck());
}
syntax highlighted by Code2HTML, v. 0.9.1