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