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