freebsd-dev/lib/libatm/timer.c
2003-03-25 04:29:26 +00:00

259 lines
4.7 KiB
C

/*
*
* ===================================
* HARP | Host ATM Research Platform
* ===================================
*
*
* This Host ATM Research Platform ("HARP") file (the "Software") is
* made available by Network Computing Services, Inc. ("NetworkCS")
* "AS IS". NetworkCS does not provide maintenance, improvements or
* support of any kind.
*
* NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
* INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
* SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
* In no event shall NetworkCS be responsible for any damages, including
* but not limited to consequential damages, arising from or relating to
* any use of the Software or related support.
*
* Copyright 1994-1998 Network Computing Services, Inc.
*
* Copies of this Software may be made, however, the above copyright
* notice must be reproduced on all copies.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* User Space Library Functions
* ----------------------------
*
* Timer functions
*
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netatm/port.h>
#include <netatm/queue.h>
#include <netatm/atm.h>
#include <netatm/atm_if.h>
#include <netatm/atm_sap.h>
#include <netatm/atm_sys.h>
#include <netatm/atm_ioctl.h>
#include <errno.h>
#include <signal.h>
#include "libatm.h"
Harp_timer *harp_timer_head;
int harp_timer_exec;
/*
* Process a HARP timer tick
*
* This function is called via the SIGALRM signal. It increments
* harp_timer_exec. The user should check this flag frequently and
* call timer_proc when it is set.
*
* Arguments:
* None
*
* Returns:
* None
*
*/
static void
timer_tick(void)
{
/*
* Bump the timer flag
*/
harp_timer_exec++;
}
/*
* Process HARP timers
*
* This function is called after a SIGALRM signal is posted. It runs
* down the list of timer entries, calling the specified functions
* for any timers that have expired.
*
* Arguments:
* None
*
* Returns:
* None
*
*/
void
timer_proc(void)
{
Harp_timer *htp;
void (*f)(Harp_timer *);
/*
* Reset marks in all timers on the queue
*/
for (htp = harp_timer_head; htp; htp = htp->ht_next) {
htp->ht_mark = -1;
}
/*
* Run through timer chain decrementing each timer.
* If an expired timer is found, take the timer block
* off the chain and call the specified function. A
* timer's action can result in other timers being
* cancelled (taken off the queue), so every time we
* call a user function, we start over from the top of
* the list.
*/
timer_cont:
for (htp = harp_timer_head; htp; htp = htp->ht_next) {
/*
* Make sure we only process each entry once and
* don't process entries that are put on the queue
* by user functions we call for this tick
*/
if (htp->ht_mark == -1) {
/*
* Decrement the timer and mark that we've
* processed the entry
*/
htp->ht_ticks -= harp_timer_exec;
htp->ht_mark = 1;
/*
* Check whether the timer is expired
*/
if (htp->ht_ticks <= 0) {
/*
* Unlink the timer block and call
* the user function
*/
f = htp->ht_func;
UNLINK(htp, Harp_timer, harp_timer_head,
ht_next);
f(htp);
/*
* Start over
*/
goto timer_cont;
}
}
}
/*
* Reset the timer exec flag
*/
harp_timer_exec = 0;
}
/*
* Start the timer
*
* Set up the SIGALRM signal handler and set up the real-time
* timer to tick once per second.
*
* Arguments:
* None
*
* Returns:
* 0 success
* errno reason for failure
*
*/
int
init_timer()
{
int rc = 0;
struct itimerval timeval;
/*
* Clear the timer flag
*/
harp_timer_exec = 0;
/*
* Set up signal handler
*/
if (signal(SIGALRM, (sig_t)timer_tick) == SIG_ERR) {
return(errno);
}
/*
* Start timer
*/
timeval.it_value.tv_sec = 1;
timeval.it_value.tv_usec = 0;
timeval.it_interval.tv_sec = 1;
timeval.it_interval.tv_usec = 0;
if (setitimer(ITIMER_REAL, &timeval,
(struct itimerval *)0) == -1) {
rc = errno;
(void)signal(SIGALRM, SIG_DFL);
}
return(rc);
}
/*
* Block timers from firing
*
* Block the SIGALRM signal.
*
* Arguments:
* None
*
* Returns:
* mask the previous blocked signal mask
*
*/
int
block_timer()
{
/*
* Block the SIGALRM signal
*/
return(sigblock(sigmask(SIGALRM)));
}
/*
* Re-enable timers
*
* Restore the signal mask (presumably one that was returned by
* block_timer).
*
* Arguments:
* mask the signal mask to be restored
*
* Returns:
* mask the previous blocked signal mask
*
*/
void
enable_timer(mask)
int mask;
{
/*
* Set the signal mask
*/
sigsetmask(mask);
return;
}