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