|
|
1.1 ! root 1: # include "sendmail.h" ! 2: # include <signal.h> ! 3: ! 4: SCCSID(@(#)clock.c 4.1 7/25/83); ! 5: ! 6: /* ! 7: ** SETEVENT -- set an event to happen at a specific time. ! 8: ** ! 9: ** Events are stored in a sorted list for fast processing. ! 10: ** An event only applies to the process that set it. ! 11: ** ! 12: ** Parameters: ! 13: ** intvl -- intvl until next event occurs. ! 14: ** func -- function to call on event. ! 15: ** arg -- argument to func on event. ! 16: ** ! 17: ** Returns: ! 18: ** none. ! 19: ** ! 20: ** Side Effects: ! 21: ** none. ! 22: */ ! 23: ! 24: EVENT * ! 25: setevent(intvl, func, arg) ! 26: time_t intvl; ! 27: int (*func)(); ! 28: int arg; ! 29: { ! 30: register EVENT **evp; ! 31: register EVENT *ev; ! 32: auto time_t now; ! 33: extern tick(); ! 34: ! 35: # ifdef DEBUG ! 36: if (intvl <= 0) ! 37: { ! 38: syserr("setevent: intvl=%ld\n", intvl); ! 39: return (NULL); ! 40: } ! 41: # endif DEBUG ! 42: ! 43: (void) time(&now); ! 44: ! 45: /* search event queue for correct position */ ! 46: for (evp = &EventQueue; (ev = *evp) != NULL; evp = &ev->ev_link) ! 47: { ! 48: if (ev->ev_time >= now + intvl) ! 49: break; ! 50: } ! 51: ! 52: /* insert new event */ ! 53: ev = (EVENT *) xalloc(sizeof *ev); ! 54: ev->ev_time = now + intvl; ! 55: ev->ev_func = func; ! 56: ev->ev_arg = arg; ! 57: ev->ev_pid = getpid(); ! 58: ev->ev_link = *evp; ! 59: *evp = ev; ! 60: ! 61: # ifdef DEBUG ! 62: if (tTd(5, 5)) ! 63: printf("setevent: intvl=%ld, for=%ld, func=%x, arg=%d, ev=%x\n", ! 64: intvl, now + intvl, func, arg, ev); ! 65: # endif DEBUG ! 66: ! 67: tick(); ! 68: return (ev); ! 69: } ! 70: /* ! 71: ** CLREVENT -- remove an event from the event queue. ! 72: ** ! 73: ** Parameters: ! 74: ** ev -- pointer to event to remove. ! 75: ** ! 76: ** Returns: ! 77: ** none. ! 78: ** ! 79: ** Side Effects: ! 80: ** arranges for event ev to not happen. ! 81: */ ! 82: ! 83: clrevent(ev) ! 84: register EVENT *ev; ! 85: { ! 86: register EVENT **evp; ! 87: ! 88: # ifdef DEBUG ! 89: if (tTd(5, 5)) ! 90: printf("clrevent: ev=%x\n", ev); ! 91: # endif DEBUG ! 92: if (ev == NULL) ! 93: return; ! 94: ! 95: /* find the parent event */ ! 96: (void) signal(SIGALRM, SIG_IGN); ! 97: for (evp = &EventQueue; *evp != NULL; evp = &(*evp)->ev_link) ! 98: { ! 99: if (*evp == ev) ! 100: break; ! 101: } ! 102: ! 103: /* now remove it */ ! 104: if (*evp != NULL) ! 105: { ! 106: *evp = ev->ev_link; ! 107: free((char *) ev); ! 108: } ! 109: ! 110: /* restore clocks and pick up anything spare */ ! 111: tick(); ! 112: } ! 113: /* ! 114: ** TICK -- take a clock tick ! 115: ** ! 116: ** Called by the alarm clock. This routine runs events as needed. ! 117: ** ! 118: ** Parameters: ! 119: ** none. ! 120: ** ! 121: ** Returns: ! 122: ** none. ! 123: ** ! 124: ** Side Effects: ! 125: ** calls the next function in EventQueue. ! 126: */ ! 127: ! 128: tick() ! 129: { ! 130: register time_t now; ! 131: register EVENT *ev; ! 132: ! 133: (void) signal(SIGALRM, SIG_IGN); ! 134: (void) alarm(0); ! 135: now = curtime(); ! 136: ! 137: # ifdef DEBUG ! 138: if (tTd(5, 4)) ! 139: printf("tick: now=%ld\n", now); ! 140: # endif DEBUG ! 141: ! 142: while ((ev = EventQueue) != NULL && ! 143: (ev->ev_time <= now || ev->ev_pid != getpid())) ! 144: { ! 145: int (*f)(), a; ! 146: ! 147: /* process the event on the top of the queue */ ! 148: ev = EventQueue; ! 149: EventQueue = EventQueue->ev_link; ! 150: # ifdef DEBUG ! 151: if (tTd(5, 6)) ! 152: printf("tick: ev=%x, func=%x, arg=%d, pid=%d\n", ev, ! 153: ev->ev_func, ev->ev_arg, ev->ev_pid); ! 154: # endif DEBUG ! 155: ! 156: /* we must be careful in here because ev_func may not return */ ! 157: (void) signal(SIGALRM, tick); ! 158: f = ev->ev_func; ! 159: a = ev->ev_arg; ! 160: free((char *) ev); ! 161: if (ev->ev_pid != getpid()) ! 162: continue; ! 163: if (EventQueue != NULL) ! 164: { ! 165: if (EventQueue->ev_time > now) ! 166: (void) alarm((unsigned) (EventQueue->ev_time - now)); ! 167: else ! 168: (void) alarm(3); ! 169: } ! 170: (*f)(a); ! 171: (void) alarm(0); ! 172: now = curtime(); ! 173: } ! 174: (void) signal(SIGALRM, tick); ! 175: if (EventQueue != NULL) ! 176: (void) alarm((unsigned) (EventQueue->ev_time - now)); ! 177: } ! 178: /* ! 179: ** SLEEP -- a version of sleep that works with this stuff ! 180: ** ! 181: ** Because sleep uses the alarm facility, I must reimplement ! 182: ** it here. ! 183: ** ! 184: ** Parameters: ! 185: ** intvl -- time to sleep. ! 186: ** ! 187: ** Returns: ! 188: ** none. ! 189: ** ! 190: ** Side Effects: ! 191: ** waits for intvl time. However, other events can ! 192: ** be run during that interval. ! 193: */ ! 194: ! 195: static bool SleepDone; ! 196: ! 197: sleep(intvl) ! 198: int intvl; ! 199: { ! 200: extern endsleep(); ! 201: ! 202: if (intvl == 0) ! 203: return; ! 204: SleepDone = FALSE; ! 205: (void) setevent((time_t) intvl, endsleep, 0); ! 206: while (!SleepDone) ! 207: pause(); ! 208: } ! 209: ! 210: static ! 211: endsleep() ! 212: { ! 213: SleepDone = TRUE; ! 214: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.