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

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.4     ! eric        6: **     @(#) $Id: HTTimer.c,v 2.3 1996/12/05 23:20:10 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;
        !            47:     hwnd HTEventList_getWinHAndle(&id);
        !            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;
        !            55:     hwnd HTEventList_getWinHAndle(&id);
        !            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:         */
                    109:        for (cur = Timers; 
                    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: 
                    135:     /*
                    136:     ** add to list if timer is new
                    137:     */
                    138:     if (cur == NULL)
                    139:        HTList_appendObject(Timers, (void *)timer);
2.4     ! eric      140:     SET_PLATFORM_TIMER(timer);
2.1       frystyk   141:     return timer;
                    142: }
                    143: 
                    144: 
                    145: PUBLIC BOOL HTTimer_deleteAll (void)
                    146: {
2.3       eric      147:     HTList * cur = Timers;
                    148:     HTTimer * pres;
                    149:     if (Timers) {
                    150:        while ((pres = (HTTimer *) HTList_nextObject(cur))) {
2.4     ! eric      151:            DELETE_PLATFORM_TIMER(pres);
2.3       eric      152:            HT_FREE(pres);
2.1       frystyk   153:        }
2.3       eric      154:        HTList_delete(Timers);
                    155:        Timers = NULL;
2.1       frystyk   156:        return YES;
                    157:     }
                    158:     return NO;
                    159: }
                    160: 
                    161: /*
                    162: **  When a timer has expired, we dispatch the event handler and re-register the
                    163: **  timer with the next expiration time.
                    164: */
2.3       eric      165: PRIVATE int Timer_dispatch (HTList * cur, HTList * last, int now)
2.1       frystyk   166: {
2.3       eric      167:     HTTimer * timer;
                    168:     int ret;
                    169: 
                    170:     timer = (HTTimer *)HTList_objectOf(cur);
                    171:     if (timer == NULL)
                    172:        return HT_ERROR;
2.1       frystyk   173:     if (timer->relative)
                    174:        HTTimer_new(timer, timer->cbf, timer->param, timer->millis, YES);
2.3       eric      175:     else
                    176:        HTList_quickRemoveElement(cur, last);
2.1       frystyk   177:     if (THD_TRACE) HTTrace("Timer....... Dispatch timer %p\n", timer);
2.3       eric      178:     ret = (*timer->cbf) (timer, timer->param);
                    179:     if (!timer->relative)
                    180:        HT_FREE(timer);
                    181:     return ret;
                    182: }
                    183: 
                    184: PUBLIC int HTTimer_dispatch (HTTimer * timer)
                    185: {
                    186:     HTList * cur;
                    187:     HTList * last = Timers;
                    188:     HTTimer * pres;
                    189:     ms_t now = HTGetTimeInMillis();
                    190: 
                    191:     cur = HTList_elementOf(Timers, (void *)timer, &last);
                    192:     return Timer_dispatch(cur, last, now);
2.1       frystyk   193: }
                    194: 
2.2       frystyk   195: PUBLIC ms_t HTTimer_soonest (void)
2.1       frystyk   196: {
2.3       eric      197:     HTList * cur = Timers;
                    198:     HTList * last = Timers;
                    199:     HTTimer * pres = NULL;
                    200:     ms_t now = HTGetTimeInMillis();
                    201:     int ret;
                    202: 
                    203:     if (Timers == NULL)
                    204:        return 0;
                    205: 
                    206:     while ((pres = (HTTimer *) HTList_nextObject(cur)) && pres->expires <= now) {
                    207:        if ((ret = Timer_dispatch(cur, last, now)) != HT_OK)
                    208:            return ret;
                    209:        last = cur;
2.2       frystyk   210:     }
2.3       eric      211: 
                    212:     return pres ? pres->expires - now : 0;
2.1       frystyk   213: }
                    214: 
                    215: PUBLIC int HTTimer_dispatchAll (void)
                    216: {
2.3       eric      217:     HTList * cur = Timers;
                    218:     HTList * last = Timers;
                    219:     HTTimer * pres;
                    220:     ms_t now = HTGetTimeInMillis();
                    221:     int ret;
                    222: 
                    223:     if (Timers) {
                    224:        /*      The Timers list may be modified during a dispatch
                    225:        **      so we have to build an intermediate list
                    226:        */
                    227:        HTList * head = HTList_new();
                    228:        while ((pres = (HTTimer *) HTList_nextObject(cur)))
                    229:            HTList_appendObject(head, (void *)pres);
                    230:        cur = last = head;
                    231:        while ((pres = (HTTimer *) HTList_nextObject(cur))) {
                    232:            if ((ret = Timer_dispatch(cur, last, now)) != HT_OK)
                    233:                return ret;
                    234:            last = cur;
                    235:        }
                    236:        return HT_OK;
2.1       frystyk   237:     }
2.3       eric      238:     return HT_ERROR;
2.1       frystyk   239: }

Webmaster