* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* @file
+/** @file
* @brief Implementation of event loop mid-layer.
* @version $Id$
*/
#include "ircd_snprintf.h"
#include "s_debug.h"
-#include <assert.h>
+/* #include <assert.h> -- Now using assert in ircd_log.h */
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
static void
timer_enqueue(struct Timer* timer)
{
- struct Timer** ptr_p;
+ struct GenHeader** ptr_p;
assert(0 != timer);
assert(0 == timer->t_header.gh_prev_p); /* not already on queue */
/* Find a slot to insert timer */
for (ptr_p = &evInfo.gens.g_timer; ;
- ptr_p = (struct Timer**) &(*ptr_p)->t_header.gh_next)
- if (!*ptr_p || timer->t_expire < (*ptr_p)->t_expire)
+ ptr_p = &(*ptr_p)->gh_next)
+ if (!*ptr_p || timer->t_expire < ((struct Timer*)*ptr_p)->t_expire)
break;
/* link it in the right place */
- timer->t_header.gh_next = (struct GenHeader*) *ptr_p;
- timer->t_header.gh_prev_p = (struct GenHeader**) ptr_p;
+ timer->t_header.gh_next = *ptr_p;
+ timer->t_header.gh_prev_p = ptr_p;
if (*ptr_p)
- (*ptr_p)->t_header.gh_prev_p = &timer->t_header.gh_next;
- *ptr_p = timer;
+ (*ptr_p)->gh_prev_p = &timer->t_header.gh_next;
+ *ptr_p = &timer->t_header;
}
/** &Signal handler for writing signal notification to pipe.
{
unsigned char sigstr[SIGS_PER_SOCK];
int sig, n_sigs, i;
- struct Signal* ptr;
+ struct GenHeader* ptr;
assert(event->ev_type == ET_READ); /* readable events only */
sig = (int) sigstr[i]; /* get signal */
for (ptr = evInfo.gens.g_signal; ptr;
- ptr = (struct Signal*) ptr->sig_header.gh_next)
- if (ptr->sig_signal == sig) /* find its descriptor... */
+ ptr = ptr->gh_next)
+ if (((struct Signal*)ptr)->sig_signal == sig) /* find its descriptor... */
break;
if (ptr)
struct Timer*
timer_init(struct Timer* timer)
{
- gen_init((struct GenHeader*) timer, 0, 0, 0, 0);
+ gen_init(&timer->t_header, 0, 0, 0, 0);
timer->t_header.gh_flags = 0; /* turn off active flag */
"timeout %Tu", timer, timer_to_name(timer->t_type), timer->t_value,
timer_to_name(type), value));
- gen_dequeue(timer); /* remove the timer from the queue */
-
timer->t_type = type; /* Set the new type and value */
timer->t_value = value;
timer->t_expire = 0;
+ /* If the timer expiration callback tries to change the timer
+ * expiration, flag the timer but do not dequeue it yet.
+ */
+ if (timer->t_header.gh_flags & GEN_MARKED)
+ {
+ timer->t_header.gh_flags |= GEN_READD;
+ return;
+ }
+ gen_dequeue(timer); /* remove the timer from the queue */
timer_enqueue(timer); /* re-queue the timer */
}
struct Timer* ptr;
/* go through queue... */
- while ((ptr = evInfo.gens.g_timer)) {
+ while ((ptr = (struct Timer*)evInfo.gens.g_timer)) {
if (CurrentTime < ptr->t_expire)
break; /* processed all pending timers */
assert(0 != evInfo.engine);
/* set up struct */
- gen_init((struct GenHeader*) signal, call, data,
- (struct GenHeader*) evInfo.gens.g_signal,
- (struct GenHeader**) &evInfo.gens.g_signal);
+ gen_init(&signal->sig_header, call, data,
+ evInfo.gens.g_signal,
+ &evInfo.gens.g_signal);
signal->sig_signal = sig;
assert(0 != evInfo.engine->eng_add);
/* set up struct */
- gen_init((struct GenHeader*) sock, call, data,
- (struct GenHeader*) evInfo.gens.g_socket,
- (struct GenHeader**) &evInfo.gens.g_socket);
+ gen_init(&sock->s_header, call, data,
+ evInfo.gens.g_socket,
+ &evInfo.gens.g_socket);
sock->s_state = state;
sock->s_events = events & SOCK_EVENT_MASK;