/* * event.C: Event subsystem. * * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team * Rights to this code are as documented in COPYING. * * * Portions of this file were derived from sources bearing the following license: * Rights to this code are documented in doc/pod/license.pod. * Copyright © 2005-2007 Atheme Project (http://www.atheme.org) */ static char const rcsid[] = "$Id: event.C,v 1.6 2007/09/22 14:27:30 pippijn Exp $"; #include "atheme.h" #include #include #include "internal.h" char const *last_event_ran = NULL; struct ev_entry event_table[MAX_EVENTS]; static time_t event_time_min = -1; /* add an event to the table to be continually ran */ unsigned int event_add (char const * const name, EVH * func, void *arg, time_t when) { unsigned int i; /* find the first inactive index */ for (i = 0; i < MAX_EVENTS; i++) { if (!event_table[i].active) { event_table[i].func = func; event_table[i].name = name; event_table[i].arg = arg; event_table[i].when = NOW + when; event_table[i].frequency = when; event_table[i].active = true; if ((event_table[i].when < event_time_min) || (event_time_min == -1)) event_time_min = event_table[i].when; slog (LG_DEBUG, "event_add(): \"%s\"", name); system_state.event++; return i; } } /* failed to add it... */ slog (LG_DEBUG, "event_add(): failed to add \"%s\" to event table", name); return UINT_MAX; } /* adds an event to the table to be ran only once */ unsigned int event_add_once (char const * const name, EVH * func, void *arg, time_t when) { unsigned int i; /* find the first inactive index */ for (i = 0; i < MAX_EVENTS; i++) { if (!event_table[i].active) { event_table[i].func = func; event_table[i].name = name; event_table[i].arg = arg; event_table[i].when = NOW + when; event_table[i].frequency = 0; event_table[i].active = true; if ((event_table[i].when < event_time_min) || (event_time_min == -1)) event_time_min = event_table[i].when; slog (LG_DEBUG, "event_add_once(): \"%s\"", name); system_state.event++; return i; } } /* failed to add it... */ slog (LG_DEBUG, "event_add(): failed to add \"%s\" to event table", name); return UINT_MAX; } /* delete an event from the table */ void event_delete (EVH * func, void *arg) { int i = event_find (func, arg); if (i == -1) return; slog (LG_DEBUG, "event_delete(): removing \"%s\"", event_table[i].name); event_table[i].name = NULL; event_table[i].func = NULL; event_table[i].arg = NULL; event_table[i].active = false; system_state.event--; } /* checks all pending events */ void event_run (void) { unsigned int i; for (i = 0; i < MAX_EVENTS; i++) { if (event_table[i].active && (event_table[i].when <= NOW)) { /* now we call it */ last_event_ran = event_table[i].name; event_table[i].func (event_table[i].arg); event_time_min = -1; /* event is scheduled more than once */ if (event_table[i].frequency) event_table[i].when = NOW + event_table[i].frequency; else { event_table[i].name = NULL; event_table[i].func = NULL; event_table[i].arg = NULL; event_table[i].active = false; system_state.event--; } } } } /* returns the time the next event_run() should happen */ time_t event_next_time (void) { unsigned int i; if (event_time_min == -1) { for (i = 0; i < MAX_EVENTS; i++) { if (event_table[i].active && ((event_table[i].when < event_time_min) || event_time_min == -1)) event_time_min = event_table[i].when; } } return event_time_min; } /* initializes event system */ void event_init (void) { last_event_ran = NULL; memset ((void *) event_table, 0, sizeof (event_table)); } /* finds an event in the table */ unsigned int event_find (EVH * func, void *arg) { unsigned int i; for (i = 0; i < MAX_EVENTS; i++) { if ((event_table[i].func == func) && (event_table[i].arg == arg)) return i; } return UINT_MAX; }