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

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.6     ! frystyk     6: **     @(#) $Id: HTTimer.c,v 2.5 1996/12/07 00:06:31 eric 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: 
2.4       eric       38: #ifdef WWW_WIN_ASYNC
                     39: 
                     40: #define SET_PLATFORM_TIMER(timer)      Timer_setWindowsTimer(timer)
                     41: #define DELETE_PLATFORM_TIMER(timer)   Timer_deleteWindowsTimer(timer)
                     42: 
                     43: PRIVATE int Timer_setWindowsTimer(HTTimer * timer)
                     44: {
                     45:     HWND hwnd;
                     46:     UINT id;
2.5       eric       47:     hwnd = HTEventList_getWinHandle(&id);
2.4       eric       48:     return SetTimer(hwnd, (UINT)timer, (UINT)timer->millis, NULL) != 0;
                     49: }
                     50: 
                     51: PRIVATE int Timer_deleteWindowsTimer(HTTimer * timer)
                     52: {
                     53:     HWND hwnd;
                     54:     UINT id;
2.5       eric       55:     hwnd = HTEventList_getWinHandle(&id);
2.4       eric       56:     return KillTimer(hwnd, (UINT)timer) != 0;
                     57: }
                     58: 
                     59: #else /* WWW_WIN_ASYNC */
                     60: 
                     61: #define SET_PLATFORM_TIMER(timer)
                     62: #define DELETE_PLATFORM_TIMER(timer)
                     63: 
                     64: #endif /* !WWW_WIN_ASYNC */
                     65: 
2.1       frystyk    66: PUBLIC BOOL HTTimer_delete (HTTimer * timer)
                     67: {
2.3       eric       68:     HTList * last;
                     69:     HTList * cur;
                     70:     if ((cur = HTList_elementOf(Timers, (void *)timer, &last)) == NULL)
                     71:        return NO;
                     72:     HTList_quickRemoveElement(cur, last);
2.4       eric       73:     DELETE_PLATFORM_TIMER(timer);
2.3       eric       74:     if (THD_TRACE) HTTrace("Timer....... Deleted timer %p\n", timer);
                     75:     HT_FREE(timer);
                     76:     return YES;
2.1       frystyk    77: }
                     78: 
                     79: PUBLIC HTTimer * HTTimer_new (HTTimer * timer, HTTimerCallback * cbf,
2.2       frystyk    80:                              void * param, ms_t millis, BOOL relative)
2.1       frystyk    81: {
2.3       eric       82:     HTList * last = Timers;
                     83:     HTList * cur = NULL;       /* will serve to flag newly created timers */
2.2       frystyk    84:     ms_t now = HTGetTimeInMillis();
2.3       eric       85:     ms_t expires;
                     86: 
                     87:     expires = millis;
                     88:     if (relative) expires += now;
                     89: 
                     90:     if (Timers == NULL)
                     91:        Timers = HTList_new();
                     92: 
                     93:     if (timer) {
                     94: 
                     95:        /*      if a timer is specified, it should already exist
                     96:         */
                     97:        if ((cur = HTList_elementOf(Timers, (void *)timer, &last)) == NULL)
                     98:            return NULL;
                     99:     } else {
                    100: 
                    101:        /*      create a new timer
                    102:         */
                    103:        HTTimer * pres;
2.1       frystyk   104:        if ((timer = (HTTimer *) HT_CALLOC(1, sizeof(HTTimer))) == NULL)
2.2       frystyk   105:            HT_OUTOFMEM("HTTimer_new");
2.3       eric      106: 
                    107:        /*      sort new element into list
                    108:         */
2.5       eric      109:        for (last = cur = Timers; 
2.3       eric      110:             (pres = (HTTimer *) HTList_nextObject(cur)) != NULL && pres->expires < expires; 
                    111:             last = cur);
2.2       frystyk   112:        if (THD_TRACE)
                    113:            HTTrace("Timer....... Created timer %p with callback %p, context %p, and %s timeout %d\n",
                    114:                    timer, cbf, param, relative ? "relative" : "absolute", millis);
2.1       frystyk   115:     }
                    116:     if (!millis) return timer;
2.3       eric      117:     timer->expires = expires;
2.1       frystyk   118:     timer->cbf = cbf;
                    119:     timer->param = param;
                    120:     timer->millis = millis;
                    121:     timer->relative = relative;
2.3       eric      122: 
                    123:     /* may already be obsolete
                    124:      */
2.1       frystyk   125:     if (timer->expires <= now) {
                    126:        int status;
                    127:        if ((status = (*timer->cbf)(timer, timer->param)) != HT_OK) {
2.3       eric      128:            if (cur)
                    129:                HTList_quickRemoveElement(cur, last);
                    130:            HT_FREE(timer);
2.1       frystyk   131:            return NULL;
                    132:        }
                    133:     }
2.3       eric      134: 
2.5       eric      135: #if 0
                    136:     for (prev = &timers;
                    137:         *prev && millis > (*prev)->millis;
                    138:         prev = &(*prev)->next);
                    139:     timer->next = *prev;
                    140:     *prev = timer;
                    141: #endif
                    142: 
2.3       eric      143:     /*
                    144:     ** add to list if timer is new
                    145:     */
2.5       eric      146:     if (cur == NULL) HTList_addObject(last, (void *)timer);
2.4       eric      147:     SET_PLATFORM_TIMER(timer);
2.1       frystyk   148:     return timer;
                    149: }
                    150: 
                    151: 
                    152: PUBLIC BOOL HTTimer_deleteAll (void)
                    153: {
2.3       eric      154:     HTList * cur = Timers;
                    155:     HTTimer * pres;
                    156:     if (Timers) {
                    157:        while ((pres = (HTTimer *) HTList_nextObject(cur))) {
2.4       eric      158:            DELETE_PLATFORM_TIMER(pres);
2.3       eric      159:            HT_FREE(pres);
2.1       frystyk   160:        }
2.3       eric      161:        HTList_delete(Timers);
                    162:        Timers = NULL;
2.1       frystyk   163:        return YES;
                    164:     }
                    165:     return NO;
                    166: }
                    167: 
                    168: /*
                    169: **  When a timer has expired, we dispatch the event handler and re-register the
                    170: **  timer with the next expiration time.
                    171: */
2.3       eric      172: PRIVATE int Timer_dispatch (HTList * cur, HTList * last, int now)
2.1       frystyk   173: {
2.3       eric      174:     HTTimer * timer;
                    175:     int ret;
                    176: 
                    177:     timer = (HTTimer *)HTList_objectOf(cur);
                    178:     if (timer == NULL)
                    179:        return HT_ERROR;
2.1       frystyk   180:     if (timer->relative)
                    181:        HTTimer_new(timer, timer->cbf, timer->param, timer->millis, YES);
2.3       eric      182:     else
                    183:        HTList_quickRemoveElement(cur, last);
2.1       frystyk   184:     if (THD_TRACE) HTTrace("Timer....... Dispatch timer %p\n", timer);
2.6     ! frystyk   185:     ret = (*timer->cbf) (timer, timer->param);
2.3       eric      186:     if (!timer->relative)
                    187:        HT_FREE(timer);
                    188:     return ret;
                    189: }
                    190: 
                    191: PUBLIC int HTTimer_dispatch (HTTimer * timer)
                    192: {
                    193:     HTList * cur;
                    194:     HTList * last = Timers;
                    195:     HTTimer * pres;
                    196:     ms_t now = HTGetTimeInMillis();
                    197: 
                    198:     cur = HTList_elementOf(Timers, (void *)timer, &last);
                    199:     return Timer_dispatch(cur, last, now);
2.1       frystyk   200: }
                    201: 
2.2       frystyk   202: PUBLIC ms_t HTTimer_soonest (void)
2.1       frystyk   203: {
2.3       eric      204:     HTList * cur = Timers;
                    205:     HTList * last = Timers;
                    206:     HTTimer * pres = NULL;
                    207:     ms_t now = HTGetTimeInMillis();
                    208:     int ret;
                    209: 
                    210:     if (Timers == NULL)
                    211:        return 0;
                    212: 
                    213:     while ((pres = (HTTimer *) HTList_nextObject(cur)) && pres->expires <= now) {
                    214:        if ((ret = Timer_dispatch(cur, last, now)) != HT_OK)
                    215:            return ret;
                    216:        last = cur;
2.2       frystyk   217:     }
2.3       eric      218: 
                    219:     return pres ? pres->expires - now : 0;
2.1       frystyk   220: }
                    221: 
                    222: PUBLIC int HTTimer_dispatchAll (void)
                    223: {
2.3       eric      224:     HTList * cur = Timers;
                    225:     HTList * last = Timers;
                    226:     HTTimer * pres;
                    227:     ms_t now = HTGetTimeInMillis();
                    228:     int ret;
                    229: 
                    230:     if (Timers) {
                    231:        /*      The Timers list may be modified during a dispatch
                    232:        **      so we have to build an intermediate list
                    233:        */
                    234:        HTList * head = HTList_new();
                    235:        while ((pres = (HTTimer *) HTList_nextObject(cur)))
                    236:            HTList_appendObject(head, (void *)pres);
                    237:        cur = last = head;
                    238:        while ((pres = (HTTimer *) HTList_nextObject(cur))) {
                    239:            if ((ret = Timer_dispatch(cur, last, now)) != HT_OK)
                    240:                return ret;
                    241:            last = cur;
                    242:        }
                    243:        return HT_OK;
2.1       frystyk   244:     }
2.3       eric      245:     return HT_ERROR;
2.1       frystyk   246: }

Webmaster