Annotation of 43BSD/usr.lib/sendmail/src/clock.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.