Annotation of 43BSDTahoe/usr.lib/sendmail/src/clock.c, revision 1.1

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

unix.superglobalmegacorp.com

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