FreeBSD-5.3/lib/libatm/timer.c

Compare this file to the similar file:
Show the results in this format:

/*
 *
 * ===================================
 * 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: src/lib/libatm/timer.c,v 1.8 2003/03/25 04:29:26 mdodd Exp $");

/*
 * 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;
}