Annotation of 43BSDReno/usr.sbin/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 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.