1
0
This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
Files
2024-07-22 01:58:46 -03:00

235 lines
4.8 KiB
C

/*
* Timers and signals wrapper
*
* $Id: timers.c,v 1.1.1.1 2007/04/12 09:42:38 ian Exp $
*
*/
/* System includes */
#define _POSIX_SOURCE 1
#include <unistd.h>
#include <signal.h>
#include <assert.h>
#include <limits.h>
/* Local includes */
#include "timers.h"
#include "load.h"
#include "dump.h"
#include "mem.h"
/* Type definitions */
typedef struct _TimerList_t {
Timer_t *timer;
struct _TimerList_t *next;
} TimerList_t;
/* Local function prototypes */
static void timer_init0(void);
static void timer_init1(void);
static void timer_dump(void);
static void timer_release(void);
static void hup_handler(int nsig);
static void usr1_handler(int nsig);
static void usr2_handler(int nsig);
static void alarm_handler(int nsig);
/* Data */
#define TIMER_MAX 65535
static const char *rcsid="$Id: timers.c,v 1.1.1.1 2007/04/12 09:42:38 ian Exp $";
const Unit_t timer_unit = {
"timer",
&timer_init0,
&timer_init1,
&timer_dump,
&timer_release
};
static TimerList_t *timerlist;
volatile int sig_hup, sig_usr1, sig_usr2, sig_alarm;
/* Functions */
/* Initialize local data */
static void
timer_init0(void)
{
struct sigaction sig;
sig_hup = sig_usr1 = sig_usr2 = sig_alarm = 0;
sig.sa_handler = hup_handler;
sigemptyset(&sig.sa_mask);
sig.sa_flags = 0;
sigaction(SIGHUP, &sig, NULL);
sig.sa_handler = usr1_handler;
sigemptyset(&sig.sa_mask);
sig.sa_flags = 0;
sigaction(SIGUSR1, &sig, NULL);
sig.sa_handler = usr2_handler;
sigemptyset(&sig.sa_mask);
sig.sa_flags = 0;
sigaction(SIGUSR2, &sig, NULL);
sig.sa_handler = alarm_handler;
sigemptyset(&sig.sa_mask);
sig.sa_flags = 0;
sigaction(SIGALRM, &sig, NULL);
timerlist = NULL;
}
/* Initialization for data that needs other units */
static void
timer_init1(void)
{
set_var_str(&timer_unit, "version", rcsid);
Debug_unit(&timer_unit, "Initialized.");
}
/* Dump status, local data etc. */
static void
timer_dump(void)
{
TimerList_t *tmp;
for (tmp = timerlist; tmp != NULL; tmp = tmp->next) {
assert(tmp->timer != NULL);
assert(tmp->timer->unit != NULL);
assert(tmp->timer->unit->name != NULL);
Debug_unit(&timer_unit, "unit %s alarm %d data 0x%x", tmp->timer->unit->name, tmp->timer->alarm_time, tmp->timer->data);
}
}
/* Release allocated memory, close files etc. */
static void
timer_release(void)
{
TimerList_t *tmp;
alarm(0);
for (tmp = timerlist; tmp != NULL; ) {
assert(tmp->timer != NULL);
assert(tmp->timer->unit != NULL);
assert(tmp->timer->unit->name != NULL);
Debug_unit(&timer_unit, "discarding timer, unit %s alarm %d data 0x%x", tmp->timer->unit->name, tmp->timer->alarm_time, tmp->timer->data);
tmp = timerlist->next;
mem_free(&timer_unit, timerlist->timer);
mem_free(&timer_unit, timerlist);
timerlist = tmp;
}
}
Timer_t *
timer_new(const Unit_t *unit)
{
Timer_t *timer;
TimerList_t *tmp;
timer = (Timer_t *)mem_alloc(&timer_unit, sizeof(Timer_t));
timer->alarm_time = INT_MAX;
timer->unit = unit;
tmp = (TimerList_t *)mem_alloc(&timer_unit, sizeof(TimerList_t *));
tmp->timer = timer;
tmp->next = timerlist;
timerlist = tmp;
timer_dump();
return (Timer_t *)timer;
}
void
timer_free(const Unit_t *unit, Timer_t *timer)
{
TimerList_t *tmp, *prev = NULL;
for (tmp = timerlist; tmp != NULL; tmp = tmp->next) {
assert(tmp->timer != NULL);
if (tmp->timer == timer) {
mem_free(&timer_unit, tmp->timer);
if (prev != NULL) {
prev->next = tmp->next;
}
else {
timerlist = tmp->next;
}
mem_free(&timer_unit, tmp);
return;
}
prev = tmp;
}
}
/* Delay for the specified period */
void
timer_alarm(const Unit_t *unit, Timer_t *timer, unsigned int nsecs, void *data)
{
assert (timer != NULL);
timer->data = data;
timer->alarm_time = time(NULL) + nsecs;
}
/* Acknowledge alarm */
void
timer_ack(const Unit_t *unit, Timer_t *timer)
{
assert (timer != NULL);
timer->alarm_time = INT_MAX;
}
/* Find soonest timer expiration */
Timer_t *
timer_find_soonest(const Unit_t *unit)
{
TimerList_t *tmp;
Timer_t *lowest = NULL;
for (tmp = timerlist; tmp != NULL; tmp = tmp->next ) {
assert(tmp->timer != NULL);
if (lowest == NULL || tmp->timer->alarm_time < lowest->alarm_time) {
lowest = tmp->timer;
}
}
if (lowest == NULL) {
return NULL;
}
Debug_unit(&timer_unit, "lowest: %d", lowest->alarm_time);
return lowest;
}
/* Handler for signal HUP, restart */
static void
hup_handler(int nsig)
{
Debug_unit(&timer_unit, "Hup");
sig_hup = 1;
}
/* Handler for signal USR1, status dump */
static void
usr1_handler(int nsig)
{
Debug_unit(&timer_unit, "Usr1");
sig_usr1 = 1;
}
/* Handler for signal INT, exit */
static void
usr2_handler(int nsig)
{
Debug_unit(&timer_unit, "Int");
sig_usr2 = 1;
}
/* Handler for signal ALARM, timer expiration */
static void
alarm_handler(int nsig)
{
Debug_unit(&timer_unit, "Alarm");
sig_alarm = 1;
}