/* timer.c */
/* Subroutines for timed events */
#include "copyright.h"
#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>
#ifdef WANT_ANSI
#ifdef __STDC__
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#endif /* __STDC__ */
#endif /* WANT_ANSI */
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#ifdef XENIX
#include <sys/signal.h>
#else
#include <signal.h>
#endif /* xenix */
#include "mudconf.h"
#include "config.h"
#include "db.h"
#include "interface.h"
#include "match.h"
#include "externs.h"
#include "command.h"
#include "rwho_clilib.h"
extern void atr_collect ();
extern void do_second (int nsecs);
extern void fork_and_dump (int key);
static int alarm_triggered = 0;
static
#ifndef VMS
void
#endif
alarm_handler ()
{
alarm_triggered = 1;
#ifdef XENIX
signal (SIGALRM, alarm_handler);
#endif
#ifdef VMS
signal (SIGALRM, alarm_handler);
return 1;
#endif
}
void init_timer ()
{
signal (SIGALRM, alarm_handler);
signal (SIGHUP, alarm_handler);
mudstate.dump_counter = (mudconf.dump_offset == 0) ?
mudconf.dump_interval : mudconf.dump_offset;
mudstate.check_counter = (mudconf.check_offset == 0) ?
mudconf.check_interval : mudconf.check_offset;
mudstate.idle_counter = mudconf.idle_interval;
mudstate.rwho_counter = mudconf.rwho_interval;
mudstate.mstats_counter = 15;
alarm (1);
}
void dispatch ()
{
char *cmdsave;
int now, curr;
struct rusage usage;
cmdsave = mudstate.debug_cmd;
mudstate.debug_cmd = (char *)"< dispatch >";
/* this routine can be used to poll from interface.c */
if (!alarm_triggered) return;
alarm_triggered = 0;
do_second(1);
/* Free list reconstruction */
if ((mudconf.control_flags & CF_DBCHECK) &&
(mudstate.check_counter-- <= 0)) {
mudstate.check_counter = mudconf.check_interval;
mudstate.debug_cmd = (char *)"< dbck >";
tmp_sync();
cache_reset();
do_dbck (NOTHING, NOTHING, 0);
tmp_sync();
cache_reset();
}
/* Database dump routines */
if ((mudconf.control_flags & CF_CHECKPOINT) &&
(mudstate.dump_counter-- <= 0)) {
mudstate.dump_counter = mudconf.dump_interval;
mudstate.debug_cmd = (char *)"< dump >";
tmp_sync();
cache_reset();
fork_and_dump(0);
}
/* Idle user check */
if ((mudconf.control_flags & CF_IDLECHECK) &&
(mudstate.idle_counter-- <= 0)) {
mudstate.idle_counter = mudconf.idle_interval;
mudstate.debug_cmd = (char *)"< idlecheck >";
tmp_sync();
cache_reset();
check_idle();
}
/* Memory use stats */
if (mudstate.mstats_counter-- <= 0) {
mudstate.mstats_counter = 15;
now = time(0);
curr = mudstate.mstat_curr;
if (now > mudstate.mstat_secs[curr]) {
curr = 1-curr;
getrusage(RUSAGE_SELF, &usage);
mudstate.mstat_ixrss[curr] = usage.ru_ixrss;
mudstate.mstat_idrss[curr] = usage.ru_idrss;
mudstate.mstat_isrss[curr] = usage.ru_isrss;
mudstate.mstat_secs[curr] = now;
mudstate.mstat_curr = curr;
}
}
#ifdef RWHO_IN_USE
if ((mudconf.control_flags & CF_RWHO_XMIT) &&
(mudstate.rwho_counter-- <= 0)) {
mudstate.rwho_counter = mudconf.rwho_interval;
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 (dbref player, dbref cause, int key, char *arg)
{
int secs;
secs = atol(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;
}