/* timer.c -- Subroutines for (system-) timed events */
#include "autoconf.h"
#include "copyright.h"
#ifndef lint
static char *RCSid = "$Id: timer.c,v 1.7 1995/03/21 00:01:16 ambar Exp $";
USE(RCSid);
#endif
#include <signal.h>
#include "interface.h"
#include "match.h"
#include "command.h"
#include "rwho_clilib.h"
extern void NDECL(pool_reset);
extern void NDECL(do_second);
extern void FDECL(fork_and_dump, (int key));
extern unsigned int FDECL(alarm, (unsigned int seconds));
extern void NDECL(pcache_trim);
int
NDECL(next_timer)
{
#ifdef NEVER
/*
* This code is hosed. Due to an ancient bug, this never returned anything
* other than 1. When this bug was fixed, certain operating systems
* decided to return pretty wild values, more or less thoroughly
* breaking the wait queue stuff.
* As far as I can tell, this _needs_ to return 1 in order for do_second()
* to function properly.
*/
int result;
result = mudstate.dump_counter;
if (mudstate.check_counter < result)
result = mudstate.check_counter;
if (mudstate.idle_counter < result)
result = mudstate.idle_counter;
if (mudstate.rwho_counter < result)
result = mudstate.rwho_counter;
result -= mudstate.now;
if (result <= 0)
result = 1;
return result;
#else
return 1;
#endif /* NEVER */
}
void
NDECL(init_timer)
{
mudstate.now = time(NULL);
mudstate.dump_counter = ((mudconf.dump_offset == 0) ?
mudconf.dump_interval : mudconf.dump_offset) + mudstate.now;
mudstate.check_counter = ((mudconf.check_offset == 0) ?
mudconf.check_interval : mudconf.check_offset) + mudstate.now;
mudstate.idle_counter = mudconf.idle_interval + mudstate.now;
mudstate.rwho_counter = mudconf.rwho_interval + mudstate.now;
alarm(next_timer());
}
void
NDECL(dispatch)
{
char *cmdsave;
cmdsave = mudstate.debug_cmd;
mudstate.debug_cmd = (char *) "< dispatch >";
/* this routine can be used to poll from interface.c */
if (!mudstate.alarm_triggered)
return;
mudstate.alarm_triggered = 0;
mudstate.now = time(NULL);
do_second();
/* Free list reconstruction */
if ((mudconf.control_flags & CF_DBCHECK) &&
(mudstate.check_counter <= mudstate.now)) {
mudstate.check_counter = mudconf.check_interval + mudstate.now;
mudstate.debug_cmd = (char *) "< dbck >";
cache_reset(0);
do_dbck(NOTHING, NOTHING, 0);
cache_reset(0);
pcache_trim();
}
/* Database dump routines */
if ((mudconf.control_flags & CF_CHECKPOINT) &&
(mudstate.dump_counter <= mudstate.now)) {
pool_reset(); /* Clear extra buffer pools */
mudstate.dump_counter = mudconf.dump_interval + mudstate.now;
mudstate.debug_cmd = (char *) "< dump >";
fork_and_dump(0);
}
/* Idle user check */
if ((mudconf.control_flags & CF_IDLECHECK) &&
(mudstate.idle_counter <= mudstate.now)) {
mudstate.idle_counter = mudconf.idle_interval + mudstate.now;
mudstate.debug_cmd = (char *) "< idlecheck >";
cache_reset(0);
check_idle();
}
#ifdef RWHO_IN_USE
if ((mudconf.control_flags & CF_RWHO_XMIT) &&
(mudstate.rwho_counter <= mudstate.now)) {
mudstate.rwho_counter = mudconf.rwho_interval + mudstate.now;
mudstate.debug_cmd = (char *) "< rwho update >";
rwho_update();
}
#endif
/* reset alarm */
alarm(1);
mudstate.debug_cmd = cmdsave;
}
/* ---------------------------------------------------------------------------
* do_timewarp: Adjust various internal timers.
*/
void
do_timewarp(player, cause, key, arg)
dbref player, cause;
int key;
char *arg;
{
int secs;
secs = atoi(arg);
if ((key == 0) || (key & TWARP_QUEUE)) /* Sem/Wait queues */
do_queue(player, cause, QUEUE_WARP, arg);
if (key & TWARP_DUMP)
mudstate.dump_counter -= secs;
if (key & TWARP_CLEAN)
mudstate.check_counter -= secs;
if (key & TWARP_IDLE)
mudstate.idle_counter -= secs;
if (key & TWARP_RWHO)
mudstate.rwho_counter -= secs;
}