17358Seric # include "sendmail.h"
27358Seric 
3*7684Seric SCCSID(@(#)clock.c	3.3		08/08/82);
47358Seric 
57358Seric /*
6*7684Seric **  SETEVENT -- set an event to happen at a specific time.
7*7684Seric **
8*7684Seric **	Parameters:
9*7684Seric **		intvl -- intvl until next event occurs.
10*7684Seric **		func -- function to call on event.
11*7684Seric **		arg -- argument to func on event.
12*7684Seric **
13*7684Seric **	Returns:
14*7684Seric **		none.
15*7684Seric **
16*7684Seric **	Side Effects:
17*7684Seric **		none.
18*7684Seric */
19*7684Seric 
20*7684Seric EVENT *
21*7684Seric setevent(intvl, func, arg)
22*7684Seric 	time_t intvl;
23*7684Seric 	int (*func)();
24*7684Seric 	int arg;
25*7684Seric {
26*7684Seric 	register EVENT **evp;
27*7684Seric 	register EVENT *ev;
28*7684Seric 	auto time_t now;
29*7684Seric 	extern tick();
30*7684Seric 
31*7684Seric 	(void) time(&now);
32*7684Seric 
33*7684Seric 	/* search event queue for correct position */
34*7684Seric 	for (evp = &EventQueue; (ev = *evp) != NULL; evp = &ev->ev_link)
35*7684Seric 	{
36*7684Seric 		if (ev->ev_time >= now + intvl)
37*7684Seric 			break;
38*7684Seric 	}
39*7684Seric 
40*7684Seric 	/* insert new event */
41*7684Seric 	ev = (EVENT *) xalloc(sizeof *ev);
42*7684Seric 	ev->ev_time = now + intvl;
43*7684Seric 	ev->ev_func = func;
44*7684Seric 	ev->ev_arg = arg;
45*7684Seric 	ev->ev_link = *evp;
46*7684Seric 	*evp = ev;
47*7684Seric 
48*7684Seric 	/* reschedule next clock tick if appropriate */
49*7684Seric 	if (ev == EventQueue)
50*7684Seric 	{
51*7684Seric 		/* we have a new event */
52*7684Seric 		(void) signal(SIGALRM, tick);
53*7684Seric 		(void) alarm(intvl);
54*7684Seric 	}
55*7684Seric 
56*7684Seric # ifdef DEBUG
57*7684Seric 	if (tTd(5, 2))
58*7684Seric 		printf("setevent: intvl=%ld, for=%ld, func=%x, arg=%d, ev=%x\n",
59*7684Seric 			intvl, now + intvl, func, arg, ev);
60*7684Seric # endif DEBUG
61*7684Seric 
62*7684Seric 	return (ev);
63*7684Seric }
64*7684Seric /*
65*7684Seric **  CLREVENT -- remove an event from the event queue.
66*7684Seric **
67*7684Seric **	Parameters:
68*7684Seric **		ev -- pointer to event to remove.
69*7684Seric **
70*7684Seric **	Returns:
71*7684Seric **		none.
72*7684Seric **
73*7684Seric **	Side Effects:
74*7684Seric **		arranges for event ev to not happen.
75*7684Seric */
76*7684Seric 
77*7684Seric clrevent(ev)
78*7684Seric 	register EVENT *ev;
79*7684Seric {
80*7684Seric 	register EVENT **evp;
81*7684Seric 
82*7684Seric # ifdef DEBUG
83*7684Seric 	if (tTd(5, 2))
84*7684Seric 		printf("clrevent: ev=%x\n", ev);
85*7684Seric # endif DEBUG
86*7684Seric 
87*7684Seric 	/* find the parent event */
88*7684Seric 	for (evp = &EventQueue; *evp != NULL; evp = &(*evp)->ev_link)
89*7684Seric 	{
90*7684Seric 		if (*evp == ev)
91*7684Seric 			break;
92*7684Seric 	}
93*7684Seric 
94*7684Seric 	/* now remove it */
95*7684Seric 	if (*evp == NULL)
96*7684Seric 	{
97*7684Seric 		/* hmmmmm.... must have happened. */
98*7684Seric 		return;
99*7684Seric 	}
100*7684Seric 
101*7684Seric 	*evp = ev->ev_link;
102*7684Seric 	free(ev);
103*7684Seric }
104*7684Seric /*
1057358Seric **  TICK -- take a clock tick
1067358Seric **
107*7684Seric **	Called by the alarm clock.  This routine runs events as needed.
1087358Seric **
1097358Seric **	Parameters:
1107358Seric **		none.
1117358Seric **
1127358Seric **	Returns:
113*7684Seric **		none.
1147358Seric **
1157358Seric **	Side Effects:
116*7684Seric **		calls the next function in EventQueue.
1177358Seric */
1187358Seric 
1197358Seric tick()
1207358Seric {
121*7684Seric 	auto time_t now;
122*7684Seric 	register EVENT *ev;
123*7684Seric 
124*7684Seric 	(void) time(&now);
125*7684Seric 
1267358Seric # ifdef DEBUG
1277674Seric 	if (tTd(5, 1))
128*7684Seric 		printf("tick: now=%ld\n", now);
1297358Seric # endif DEBUG
130*7684Seric 
131*7684Seric 	while (EventQueue != NULL && EventQueue->ev_time <= now)
132*7684Seric 	{
133*7684Seric 		/* process the event on the top of the queue */
134*7684Seric 		ev = EventQueue;
135*7684Seric 		EventQueue = EventQueue->ev_link;
136*7684Seric # ifdef DEBUG
137*7684Seric 		if (tTd(5, 3))
138*7684Seric 			printf("tick: ev=%x, func=%x, arg=%d\n", ev,
139*7684Seric 				ev->ev_func, ev->ev_arg);
140*7684Seric # endif DEBUG
141*7684Seric 		(*ev->ev_func)(ev->ev_arg);
142*7684Seric 		free(ev);
143*7684Seric 		(void) time(&now);
144*7684Seric 	}
145*7684Seric 
146*7684Seric 	/* schedule the next clock tick */
147*7684Seric 	signal(SIGALRM, tick);
148*7684Seric 	if (EventQueue != NULL)
149*7684Seric 		(void) alarm(EventQueue->ev_time - now);
1507358Seric }
151