Annotation of 43BSDReno/usr.sbin/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 provided
        !             7:  * that: (1) source distributions retain this entire copyright notice and
        !             8:  * comment, and (2) distributions including binaries display the following
        !             9:  * acknowledgement:  ``This product includes software developed by the
        !            10:  * University of California, Berkeley and its contributors'' in the
        !            11:  * documentation or other materials provided with the distribution and in
        !            12:  * all advertising materials mentioning features or use of this software.
        !            13:  * Neither the name of the University nor the names of its contributors may
        !            14:  * be used to endorse or promote products derived from this software without
        !            15:  * specific prior written permission.
        !            16:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            17:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            18:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            19:  */
        !            20: 
        !            21: #ifndef lint
        !            22: static char sccsid[] = "@(#)clock.c    5.8 (Berkeley) 6/1/90";
        !            23: #endif /* not lint */
        !            24: 
        !            25: # include "sendmail.h"
        !            26: # include <signal.h>
        !            27: 
        !            28: /*
        !            29: **  SETEVENT -- set an event to happen at a specific time.
        !            30: **
        !            31: **     Events are stored in a sorted list for fast processing.
        !            32: **     An event only applies to the process that set it.
        !            33: **
        !            34: **     Parameters:
        !            35: **             intvl -- intvl until next event occurs.
        !            36: **             func -- function to call on event.
        !            37: **             arg -- argument to func on event.
        !            38: **
        !            39: **     Returns:
        !            40: **             none.
        !            41: **
        !            42: **     Side Effects:
        !            43: **             none.
        !            44: */
        !            45: 
        !            46: EVENT *
        !            47: setevent(intvl, func, arg)
        !            48:        time_t intvl;
        !            49:        int (*func)();
        !            50:        int arg;
        !            51: {
        !            52:        register EVENT **evp;
        !            53:        register EVENT *ev;
        !            54:        auto time_t now;
        !            55:        extern tick();
        !            56: 
        !            57:        if (intvl <= 0)
        !            58:        {
        !            59:                syserr("setevent: intvl=%ld\n", intvl);
        !            60:                return (NULL);
        !            61:        }
        !            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:        if (tTd(5, 5))
        !            82:                printf("setevent: intvl=%ld, for=%ld, func=%x, arg=%d, ev=%x\n",
        !            83:                        intvl, now + intvl, func, arg, ev);
        !            84: 
        !            85:        tick();
        !            86:        return (ev);
        !            87: }
        !            88: /*
        !            89: **  CLREVENT -- remove an event from the event queue.
        !            90: **
        !            91: **     Parameters:
        !            92: **             ev -- pointer to event to remove.
        !            93: **
        !            94: **     Returns:
        !            95: **             none.
        !            96: **
        !            97: **     Side Effects:
        !            98: **             arranges for event ev to not happen.
        !            99: */
        !           100: 
        !           101: clrevent(ev)
        !           102:        register EVENT *ev;
        !           103: {
        !           104:        register EVENT **evp;
        !           105: 
        !           106:        if (tTd(5, 5))
        !           107:                printf("clrevent: ev=%x\n", ev);
        !           108:        if (ev == NULL)
        !           109:                return;
        !           110: 
        !           111:        /* find the parent event */
        !           112:        (void) signal(SIGALRM, SIG_IGN);
        !           113:        for (evp = &EventQueue; *evp != NULL; evp = &(*evp)->ev_link)
        !           114:        {
        !           115:                if (*evp == ev)
        !           116:                        break;
        !           117:        }
        !           118: 
        !           119:        /* now remove it */
        !           120:        if (*evp != NULL)
        !           121:        {
        !           122:                *evp = ev->ev_link;
        !           123:                free((char *) ev);
        !           124:        }
        !           125: 
        !           126:        /* restore clocks and pick up anything spare */
        !           127:        tick();
        !           128: }
        !           129: /*
        !           130: **  TICK -- take a clock tick
        !           131: **
        !           132: **     Called by the alarm clock.  This routine runs events as needed.
        !           133: **
        !           134: **     Parameters:
        !           135: **             none.
        !           136: **
        !           137: **     Returns:
        !           138: **             none.
        !           139: **
        !           140: **     Side Effects:
        !           141: **             calls the next function in EventQueue.
        !           142: */
        !           143: 
        !           144: tick()
        !           145: {
        !           146:        register time_t now;
        !           147:        register EVENT *ev;
        !           148:        int mypid = getpid();
        !           149: 
        !           150:        (void) signal(SIGALRM, SIG_IGN);
        !           151:        (void) alarm(0);
        !           152:        now = curtime();
        !           153: 
        !           154:        if (tTd(5, 4))
        !           155:                printf("tick: now=%ld\n", now);
        !           156: 
        !           157:        while ((ev = EventQueue) != NULL &&
        !           158:               (ev->ev_time <= now || ev->ev_pid != mypid))
        !           159:        {
        !           160:                int (*f)();
        !           161:                int arg;
        !           162:                int pid;
        !           163: 
        !           164:                /* process the event on the top of the queue */
        !           165:                ev = EventQueue;
        !           166:                EventQueue = EventQueue->ev_link;
        !           167:                if (tTd(5, 6))
        !           168:                        printf("tick: ev=%x, func=%x, arg=%d, pid=%d\n", ev,
        !           169:                                ev->ev_func, ev->ev_arg, ev->ev_pid);
        !           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.