17358Seric # include "sendmail.h" 27358Seric 3*7690Seric SCCSID(@(#)clock.c 3.4 08/08/82); 47358Seric 57358Seric /* 67684Seric ** SETEVENT -- set an event to happen at a specific time. 77684Seric ** 87684Seric ** Parameters: 97684Seric ** intvl -- intvl until next event occurs. 107684Seric ** func -- function to call on event. 117684Seric ** arg -- argument to func on event. 127684Seric ** 137684Seric ** Returns: 147684Seric ** none. 157684Seric ** 167684Seric ** Side Effects: 177684Seric ** none. 187684Seric */ 197684Seric 207684Seric EVENT * 217684Seric setevent(intvl, func, arg) 227684Seric time_t intvl; 237684Seric int (*func)(); 247684Seric int arg; 257684Seric { 267684Seric register EVENT **evp; 277684Seric register EVENT *ev; 287684Seric auto time_t now; 297684Seric extern tick(); 307684Seric 317684Seric (void) time(&now); 327684Seric 337684Seric /* search event queue for correct position */ 347684Seric for (evp = &EventQueue; (ev = *evp) != NULL; evp = &ev->ev_link) 357684Seric { 367684Seric if (ev->ev_time >= now + intvl) 377684Seric break; 387684Seric } 397684Seric 407684Seric /* insert new event */ 417684Seric ev = (EVENT *) xalloc(sizeof *ev); 427684Seric ev->ev_time = now + intvl; 437684Seric ev->ev_func = func; 447684Seric ev->ev_arg = arg; 457684Seric ev->ev_link = *evp; 467684Seric *evp = ev; 477684Seric 487684Seric /* reschedule next clock tick if appropriate */ 497684Seric if (ev == EventQueue) 507684Seric { 517684Seric /* we have a new event */ 527684Seric (void) signal(SIGALRM, tick); 537684Seric (void) alarm(intvl); 547684Seric } 557684Seric 567684Seric # ifdef DEBUG 577684Seric if (tTd(5, 2)) 587684Seric printf("setevent: intvl=%ld, for=%ld, func=%x, arg=%d, ev=%x\n", 597684Seric intvl, now + intvl, func, arg, ev); 607684Seric # endif DEBUG 617684Seric 627684Seric return (ev); 637684Seric } 647684Seric /* 657684Seric ** CLREVENT -- remove an event from the event queue. 667684Seric ** 677684Seric ** Parameters: 687684Seric ** ev -- pointer to event to remove. 697684Seric ** 707684Seric ** Returns: 717684Seric ** none. 727684Seric ** 737684Seric ** Side Effects: 747684Seric ** arranges for event ev to not happen. 757684Seric */ 767684Seric 777684Seric clrevent(ev) 787684Seric register EVENT *ev; 797684Seric { 807684Seric register EVENT **evp; 817684Seric 827684Seric # ifdef DEBUG 837684Seric if (tTd(5, 2)) 847684Seric printf("clrevent: ev=%x\n", ev); 857684Seric # endif DEBUG 867684Seric 877684Seric /* find the parent event */ 887684Seric for (evp = &EventQueue; *evp != NULL; evp = &(*evp)->ev_link) 897684Seric { 907684Seric if (*evp == ev) 917684Seric break; 927684Seric } 937684Seric 947684Seric /* now remove it */ 957684Seric if (*evp == NULL) 967684Seric { 977684Seric /* hmmmmm.... must have happened. */ 987684Seric return; 997684Seric } 1007684Seric 1017684Seric *evp = ev->ev_link; 1027684Seric free(ev); 1037684Seric } 1047684Seric /* 1057358Seric ** TICK -- take a clock tick 1067358Seric ** 1077684Seric ** Called by the alarm clock. This routine runs events as needed. 1087358Seric ** 1097358Seric ** Parameters: 1107358Seric ** none. 1117358Seric ** 1127358Seric ** Returns: 1137684Seric ** none. 1147358Seric ** 1157358Seric ** Side Effects: 1167684Seric ** calls the next function in EventQueue. 1177358Seric */ 1187358Seric 1197358Seric tick() 1207358Seric { 1217684Seric auto time_t now; 1227684Seric register EVENT *ev; 1237684Seric 124*7690Seric signal(SIGALRM, SIG_IGN); 1257684Seric (void) time(&now); 1267684Seric 1277358Seric # ifdef DEBUG 1287674Seric if (tTd(5, 1)) 1297684Seric printf("tick: now=%ld\n", now); 1307358Seric # endif DEBUG 1317684Seric 1327684Seric while (EventQueue != NULL && EventQueue->ev_time <= now) 1337684Seric { 1347684Seric /* process the event on the top of the queue */ 1357684Seric ev = EventQueue; 1367684Seric EventQueue = EventQueue->ev_link; 1377684Seric # ifdef DEBUG 1387684Seric if (tTd(5, 3)) 1397684Seric printf("tick: ev=%x, func=%x, arg=%d\n", ev, 1407684Seric ev->ev_func, ev->ev_arg); 1417684Seric # endif DEBUG 1427684Seric (*ev->ev_func)(ev->ev_arg); 1437684Seric free(ev); 1447684Seric (void) time(&now); 1457684Seric } 1467684Seric 1477684Seric /* schedule the next clock tick */ 1487684Seric signal(SIGALRM, tick); 1497684Seric if (EventQueue != NULL) 1507684Seric (void) alarm(EventQueue->ev_time - now); 1517358Seric } 152*7690Seric /* 153*7690Seric ** SLEEP -- a version of sleep that works with this stuff 154*7690Seric ** 155*7690Seric ** Because sleep uses the alarm facility, I must reimplement 156*7690Seric ** it here. 157*7690Seric ** 158*7690Seric ** Parameters: 159*7690Seric ** intvl -- time to sleep. 160*7690Seric ** 161*7690Seric ** Returns: 162*7690Seric ** none. 163*7690Seric ** 164*7690Seric ** Side Effects: 165*7690Seric ** waits for intvl time. However, other events can 166*7690Seric ** be run during that interval. 167*7690Seric */ 168*7690Seric 169*7690Seric static bool SleepDone; 170*7690Seric 171*7690Seric sleep(intvl) 172*7690Seric int intvl; 173*7690Seric { 174*7690Seric extern endsleep(); 175*7690Seric 176*7690Seric SleepDone = FALSE; 177*7690Seric setevent(intvl, endsleep, 0); 178*7690Seric while (!SleepDone) 179*7690Seric pause(); 180*7690Seric } 181*7690Seric 182*7690Seric static 183*7690Seric endsleep() 184*7690Seric { 185*7690Seric SleepDone = TRUE; 186*7690Seric } 187