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