Annotation of 43BSD/usr.lib/sendmail/src/clock.c, revision 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.