Annotation of libwww/Library/src/HTTimer.c, revision 2.3

2.1       frystyk     1: /*                                                                  HTEvntrg.c
                      2: **     EVENT MANAGER
                      3: **
                      4: **     (c) COPYRIGHT MIT 1995.
                      5: **     Please first read the full copyright statement in the file COPYRIGH.
2.3     ! eric        6: **     @(#) $Id: HTTimer.c,v 2.2 1996/12/02 20:19:48 frystyk Exp $
2.1       frystyk     7: **
                      8: **     Updated HTEvent module 
                      9: **     This new module combines the functions of the old HTEvent module and 
                     10: **     the HTThread module. We retain the old HTThread module, but it
                     11: **     consists of calls to the HTEvent interfaces
                     12: **
                     13: ** Authors:
                     14: **     EGP     Eric Prud'hommeaux (eric@w3.org)
                     15: ** Bugs
                     16: **
                     17: */
                     18: 
                     19: /* Implementation dependent include files */
                     20: #include "sysdep.h"
                     21: #include "WWWUtil.h"
                     22: #include "WWWCore.h"
                     23: #include "HTReqMan.h"
                     24: #include "HTTimer.h"                                    /* Implemented here */
                     25: 
                     26: struct _HTTimer {
2.2       frystyk    27:     ms_t       millis;         /* Relative value in millis */
                     28:     ms_t       expires;        /* Absolute value in millis */
2.1       frystyk    29:     BOOL       relative;
                     30:     void *     param;          /* Client supplied context */
                     31:     HTTimerCallback * cbf;
                     32: };
                     33: 
2.3     ! eric       34: PRIVATE HTList * Timers = NULL;                           /* List of timers */
2.1       frystyk    35: 
                     36: /* ------------------------------------------------------------------------- */
                     37: 
                     38: PUBLIC BOOL HTTimer_delete (HTTimer * timer)
                     39: {
2.3     ! eric       40:     HTList * last;
        !            41:     HTList * cur;
        !            42:     if ((cur = HTList_elementOf(Timers, (void *)timer, &last)) == NULL)
        !            43:        return NO;
        !            44:     HTList_quickRemoveElement(cur, last);
        !            45:     if (THD_TRACE) HTTrace("Timer....... Deleted timer %p\n", timer);
        !            46:     HT_FREE(timer);
        !            47:     return YES;
2.1       frystyk    48: }
                     49: 
                     50: PUBLIC HTTimer * HTTimer_new (HTTimer * timer, HTTimerCallback * cbf,
2.2       frystyk    51:                              void * param, ms_t millis, BOOL relative)
2.1       frystyk    52: {
2.3     ! eric       53:     HTList * last = Timers;
        !            54:     HTList * cur = NULL;       /* will serve to flag newly created timers */
2.2       frystyk    55:     ms_t now = HTGetTimeInMillis();
2.3     ! eric       56:     ms_t expires;
        !            57: 
        !            58:     expires = millis;
        !            59:     if (relative) expires += now;
        !            60: 
        !            61:     if (Timers == NULL)
        !            62:        Timers = HTList_new();
        !            63: 
        !            64:     if (timer) {
        !            65: 
        !            66:        /*      if a timer is specified, it should already exist
        !            67:         */
        !            68:        if ((cur = HTList_elementOf(Timers, (void *)timer, &last)) == NULL)
        !            69:            return NULL;
        !            70:     } else {
        !            71: 
        !            72:        /*      create a new timer
        !            73:         */
        !            74:        HTTimer * pres;
2.1       frystyk    75:        if ((timer = (HTTimer *) HT_CALLOC(1, sizeof(HTTimer))) == NULL)
2.2       frystyk    76:            HT_OUTOFMEM("HTTimer_new");
2.3     ! eric       77: 
        !            78:        /*      sort new element into list
        !            79:         */
        !            80:        for (cur = Timers; 
        !            81:             (pres = (HTTimer *) HTList_nextObject(cur)) != NULL && pres->expires < expires; 
        !            82:             last = cur);
2.2       frystyk    83:        if (THD_TRACE)
                     84:            HTTrace("Timer....... Created timer %p with callback %p, context %p, and %s timeout %d\n",
                     85:                    timer, cbf, param, relative ? "relative" : "absolute", millis);
2.1       frystyk    86:     }
                     87:     if (!millis) return timer;
2.3     ! eric       88:     timer->expires = expires;
2.1       frystyk    89:     timer->cbf = cbf;
                     90:     timer->param = param;
                     91:     timer->millis = millis;
                     92:     timer->relative = relative;
2.3     ! eric       93: 
        !            94:     /* may already be obsolete
        !            95:      */
2.1       frystyk    96:     if (timer->expires <= now) {
                     97:        int status;
                     98:        if ((status = (*timer->cbf)(timer, timer->param)) != HT_OK) {
2.3     ! eric       99:            if (cur)
        !           100:                HTList_quickRemoveElement(cur, last);
        !           101:            HT_FREE(timer);
2.1       frystyk   102:            return NULL;
                    103:        }
                    104:     }
2.3     ! eric      105: 
        !           106:     /*
        !           107:     ** add to list if timer is new
        !           108:     */
        !           109:     if (cur == NULL)
        !           110:        HTList_appendObject(Timers, (void *)timer);
2.1       frystyk   111:     return timer;
                    112: }
                    113: 
                    114: 
                    115: PUBLIC BOOL HTTimer_deleteAll (void)
                    116: {
2.3     ! eric      117:     HTList * cur = Timers;
        !           118:     HTTimer * pres;
        !           119:     if (Timers) {
        !           120:        while ((pres = (HTTimer *) HTList_nextObject(cur))) {
        !           121:            HT_FREE(pres);
2.1       frystyk   122:        }
2.3     ! eric      123:        HTList_delete(Timers);
        !           124:        Timers = NULL;
2.1       frystyk   125:        return YES;
                    126:     }
                    127:     return NO;
                    128: }
                    129: 
                    130: /*
                    131: **  When a timer has expired, we dispatch the event handler and re-register the
                    132: **  timer with the next expiration time.
                    133: */
2.3     ! eric      134: PRIVATE int Timer_dispatch (HTList * cur, HTList * last, int now)
2.1       frystyk   135: {
2.3     ! eric      136:     HTTimer * timer;
        !           137:     int ret;
        !           138: 
        !           139:     timer = (HTTimer *)HTList_objectOf(cur);
        !           140:     if (timer == NULL)
        !           141:        return HT_ERROR;
2.1       frystyk   142:     if (timer->relative)
                    143:        HTTimer_new(timer, timer->cbf, timer->param, timer->millis, YES);
2.3     ! eric      144:     else
        !           145:        HTList_quickRemoveElement(cur, last);
2.1       frystyk   146:     if (THD_TRACE) HTTrace("Timer....... Dispatch timer %p\n", timer);
2.3     ! eric      147:     ret = (*timer->cbf) (timer, timer->param);
        !           148:     if (!timer->relative)
        !           149:        HT_FREE(timer);
        !           150:     return ret;
        !           151: }
        !           152: 
        !           153: PUBLIC int HTTimer_dispatch (HTTimer * timer)
        !           154: {
        !           155:     HTList * cur;
        !           156:     HTList * last = Timers;
        !           157:     HTTimer * pres;
        !           158:     ms_t now = HTGetTimeInMillis();
        !           159: 
        !           160:     cur = HTList_elementOf(Timers, (void *)timer, &last);
        !           161:     return Timer_dispatch(cur, last, now);
2.1       frystyk   162: }
                    163: 
2.2       frystyk   164: PUBLIC ms_t HTTimer_soonest (void)
2.1       frystyk   165: {
2.3     ! eric      166:     HTList * cur = Timers;
        !           167:     HTList * last = Timers;
        !           168:     HTTimer * pres = NULL;
        !           169:     ms_t now = HTGetTimeInMillis();
        !           170:     int ret;
        !           171: 
        !           172:     if (Timers == NULL)
        !           173:        return 0;
        !           174: 
        !           175:     while ((pres = (HTTimer *) HTList_nextObject(cur)) && pres->expires <= now) {
        !           176:        if ((ret = Timer_dispatch(cur, last, now)) != HT_OK)
        !           177:            return ret;
        !           178:        last = cur;
2.2       frystyk   179:     }
2.3     ! eric      180: 
        !           181:     return pres ? pres->expires - now : 0;
2.1       frystyk   182: }
                    183: 
                    184: PUBLIC int HTTimer_dispatchAll (void)
                    185: {
2.3     ! eric      186:     HTList * cur = Timers;
        !           187:     HTList * last = Timers;
        !           188:     HTTimer * pres;
        !           189:     ms_t now = HTGetTimeInMillis();
        !           190:     int ret;
        !           191: 
        !           192:     if (Timers) {
        !           193:        /*      The Timers list may be modified during a dispatch
        !           194:        **      so we have to build an intermediate list
        !           195:        */
        !           196:        HTList * head = HTList_new();
        !           197:        while ((pres = (HTTimer *) HTList_nextObject(cur)))
        !           198:            HTList_appendObject(head, (void *)pres);
        !           199:        cur = last = head;
        !           200:        while ((pres = (HTTimer *) HTList_nextObject(cur))) {
        !           201:            if ((ret = Timer_dispatch(cur, last, now)) != HT_OK)
        !           202:                return ret;
        !           203:            last = cur;
        !           204:        }
        !           205:        return HT_OK;
2.1       frystyk   206:     }
2.3     ! eric      207:     return HT_ERROR;
2.1       frystyk   208: }

Webmaster