[BACK] Return to HTTimer.c CVS log [TXT] [DIR] Up to [Public] / libwww / Library / src

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

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.23 ! frystyk 6: **   @(#) $Id: HTTimer.c,v 2.22 1998年05月31日 18:55: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 */
2.20 frystyk 20: #include "wwwsys.h"
2.1 frystyk 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;
2.21 frystyk 30:   BOOL    repetitive;
2.1 frystyk 31:   void *   param;     /* Client supplied context */
 32:   HTTimerCallback * cbf;
 33: };
 34: 
2.3 eric 35: PRIVATE HTList * Timers = NULL;              /* List of timers */
2.1 frystyk 36: 
2.9 frystyk 37: PRIVATE HTTimerSetCallback * SetPlatformTimer = NULL;
 38: PRIVATE HTTimerSetCallback * DeletePlatformTimer = NULL;
 39: 
2.17 frystyk 40: #if 0 /* WATCH_RECURSION */
2.7 eric 41: 
 42: PRIVATE HTTimer * InTimer = NULL;
2.19 frystyk 43: #define CHECKME(timer) if (InTimer != NULL) HTDebugBreak(__FILE__, __LINE__, "\n"); InTimer = timer;
 44: #define CLEARME(timer) if (InTimer != timer) HTDebugBreak(__FILE, __LINE__, "\n"); InTimer = NULL;
2.7 eric 45: #define SETME(timer) InTimer = timer;
 46: 
 47: #else /* WATCH_RECURSION */
 48: 
 49: #define CHECKME(timer)
 50: #define CLEARME(timer)
 51: #define SETME(timer)
 52: 
 53: #endif /* !WATCH_RECURSION */
2.1 frystyk 54: /* ------------------------------------------------------------------------- */
 55: 
2.23 ! frystyk 56: /*
 ! 57: ** When a timer has expired, we dispatch the event handler and re-register the
 ! 58: ** timer with the next expiration time if repetitive. Otherwise we just leave
 ! 59: ** it
 ! 60: */
 ! 61: PRIVATE int Timer_dispatch (HTList * cur, HTList * last)
 ! 62: {
 ! 63:   HTTimer * timer;
 ! 64:   int ret = HT_ERROR;
 ! 65: 
 ! 66:   timer = (HTTimer *)HTList_objectOf(cur);
 ! 67:   if (timer == NULL) {
 ! 68: #if 0
 ! 69:     HTDebugBreak(__FILE__, __LINE__, "Timer dispatch couldn't find a timer\n");
 ! 70: #endif
 ! 71:     CLEARME(timer);
 ! 72:    return HT_ERROR;
 ! 73:   }
 ! 74:   if (timer->repetitive)
 ! 75:    HTTimer_new(timer, timer->cbf, timer->param, timer->millis, YES, YES);
 ! 76:   else
 ! 77:    HTList_quickRemoveElement(cur, last);
 ! 78:   if (THD_TRACE) HTTrace("Timer....... Dispatch timer %p\n", timer);
 ! 79:   ret = (*timer->cbf) (timer, timer->param, HTEvent_TIMEOUT);
 ! 80:   return ret;
 ! 81: }
 ! 82: 
2.9 frystyk 83: PUBLIC BOOL HTTimer_registerSetTimerCallback (HTTimerSetCallback * cbf)
2.4 eric 84: {
2.9 frystyk 85:   if (CORE_TRACE) HTTrace("Timer....... registering %p as timer set cbf\n", cbf);
 86:   if (cbf) {
 87:    SetPlatformTimer = cbf;
 88:    return YES;
 89:   }
 90:   return NO;
2.4 eric 91: }
 92: 
2.9 frystyk 93: PUBLIC BOOL HTTimer_registerDeleteTimerCallback (HTTimerSetCallback * cbf)
2.4 eric 94: {
2.9 frystyk 95:   if (CORE_TRACE) HTTrace("Timer....... registering %p as timer delete cbf\n", cbf);
 96:   if (cbf) {
 97:    DeletePlatformTimer = cbf;
 98:    return YES;
 99:   }
 100:   return NO;
2.10 eric 101: }
 102: 
 103: PUBLIC ms_t HTTimer_getTime(HTTimer * timer)
 104: {
 105:   if (timer)
 106:    return timer->millis;
 107:   return 0;
2.4 eric 108: }
 109: 
2.1 frystyk 110: PUBLIC BOOL HTTimer_delete (HTTimer * timer)
 111: {
2.3 eric 112:   HTList * last;
 113:   HTList * cur;
2.7 eric 114:   CHECKME(timer);
2.23 ! frystyk 115:   if ((cur = HTList_elementOf(Timers, (void *)timer, &last)) == NULL) CLEARME(timer);
2.18 frystyk 116:   if (HTList_quickRemoveElement(cur, last)) {
2.23 ! frystyk 117:    if (THD_TRACE) HTTrace("Timer....... Deleted active timer %p\n", timer);
2.18 frystyk 118:   } else { 
2.23 ! frystyk 119:    if (THD_TRACE) HTTrace("Timer....... Deleted expired timer %p\n", timer);
2.18 frystyk 120:   }
2.9 frystyk 121: 
 122:   /*
 123:   ** Call any platform specific timer handler
 124:   */
 125:   if (DeletePlatformTimer) DeletePlatformTimer(timer);
 126: 
2.7 eric 127:   CLEARME(timer);
2.3 eric 128:   HT_FREE(timer);
 129:   return YES;
2.1 frystyk 130: }
 131: 
 132: PUBLIC HTTimer * HTTimer_new (HTTimer * timer, HTTimerCallback * cbf,
2.21 frystyk 133:               void * param, ms_t millis, BOOL relative,
 134:               BOOL repetitive)
2.1 frystyk 135: {
2.7 eric 136:   HTList * last;
 137:   HTList * cur;
2.2 frystyk 138:   ms_t now = HTGetTimeInMillis();
2.3 eric 139:   ms_t expires;
2.7 eric 140:   HTTimer * pres;
2.3 eric 141: 
2.7 eric 142:   CHECKME(timer);
2.3 eric 143:   expires = millis;
2.17 frystyk 144:   if (relative)
 145:    expires += now;
 146:   else
 147:    millis = expires-now;
2.3 eric 148: 
 149:   if (Timers == NULL)
 150:    Timers = HTList_new();
 151: 
 152:   if (timer) {
 153: 
 154:    /*   if a timer is specified, it should already exist
 155:     */
2.7 eric 156:    if ((cur = HTList_elementOf(Timers, (void *)timer, &last)) == NULL) {
2.19 frystyk 157:      HTDebugBreak(__FILE__, __LINE__, "Timer %p not found\n", timer);
2.7 eric 158:      CLEARME(timer);
2.3 eric 159:      return NULL;
2.7 eric 160:    }
 161:    HTList_quickRemoveElement(cur, last);
2.11 frystyk 162:    if (THD_TRACE)
 163:      HTTrace("Timer....... Found timer %p with callback %p, context %p, and %s timeout %d\n",
 164:          timer, cbf, param, relative ? "relative" : "absolute", millis);
2.7 eric 165:    /* could optimize by sorting from last when ((HTList *)(last->object))->expires < expires (most common case) */
2.3 eric 166:   } else {
 167: 
 168:    /*   create a new timer
 169:     */
2.1 frystyk 170:    if ((timer = (HTTimer *) HT_CALLOC(1, sizeof(HTTimer))) == NULL)
2.2 frystyk 171:      HT_OUTOFMEM("HTTimer_new");
2.7 eric 172:    last = Timers;
2.11 frystyk 173:    if (THD_TRACE)
2.21 frystyk 174:      HTTrace("Timer....... Created %s timer %p with callback %p, context %p, and %s timeout %d\n",
 175:          repetitive ? "repetitive" : "one shot",
 176:          timer, cbf, param,
 177:          relative ? "relative" : "absolute", millis);
2.1 frystyk 178:   }
2.16 frystyk 179: 
 180:   /*
 181:   ** Sort new element into list
 182:   */
2.7 eric 183:   for (cur = last; 
 184:     (pres = (HTTimer *) HTList_nextObject(cur)) != NULL && pres->expires < expires; 
 185:     last = cur);
2.16 frystyk 186: 
 187:   /*
 188:   ** If the expiration is 0 then we still register it but dispatch it immediately.
 189:   */
 190:   if (!millis) if (THD_TRACE) HTTrace("Timer....... Timeout is 0 - expires NOW\n");
 191: 
2.3 eric 192:   timer->expires = expires;
2.1 frystyk 193:   timer->cbf = cbf;
 194:   timer->param = param;
 195:   timer->millis = millis;
 196:   timer->relative = relative;
2.21 frystyk 197:   timer->repetitive = repetitive;
2.7 eric 198:   SETME(timer);
2.3 eric 199: 
 200:   /*
 201:   ** add to list if timer is new
 202:   */
2.7 eric 203:   HTList_addObject(last, (void *)timer);
2.9 frystyk 204: 
 205:   /*
 206:   ** Call any platform specific timer handler
 207:   */
 208:   if (SetPlatformTimer) SetPlatformTimer(timer);
 209: 
2.23 ! frystyk 210:   /* Check if the timer object has already expired. If so then dispatch */
 ! 211:   if (timer->expires <= now) Timer_dispatch(cur, last);
2.16 frystyk 212: 
2.7 eric 213:   CLEARME(timer);
2.1 frystyk 214:   return timer;
 215: }
 216: 
 217: 
2.7 eric 218: PUBLIC BOOL HTTimer_refresh (HTTimer * timer, ms_t now)
 219: {
2.21 frystyk 220:   if (timer == NULL || timer->repetitive == NO)
2.7 eric 221:    return NO;
2.21 frystyk 222:   if (HTTimer_new(timer, timer->cbf, timer->param, timer->millis, YES, YES) == NULL)
2.7 eric 223:    return NO;
 224:   return YES;
 225: }
 226: 
2.1 frystyk 227: PUBLIC BOOL HTTimer_deleteAll (void)
 228: {
2.3 eric 229:   HTList * cur = Timers;
 230:   HTTimer * pres;
 231:   if (Timers) {
 232:    while ((pres = (HTTimer *) HTList_nextObject(cur))) {
2.9 frystyk 233: 
 234:      /*
 235:      ** Call any platform specific timer handler
 236:      */
 237:      if (DeletePlatformTimer) DeletePlatformTimer(pres);
2.3 eric 238:      HT_FREE(pres);
2.1 frystyk 239:    }
2.3 eric 240:    HTList_delete(Timers);
 241:    Timers = NULL;
2.1 frystyk 242:    return YES;
 243:   }
 244:   return NO;
 245: }
 246: 
2.3 eric 247: PUBLIC int HTTimer_dispatch (HTTimer * timer)
 248: {
 249:   HTList * cur;
 250:   HTList * last = Timers;
 251:   cur = HTList_elementOf(Timers, (void *)timer, &last);
2.23 ! frystyk 252:   return Timer_dispatch(cur, last);
2.21 frystyk 253: }
 254: 
 255: /*
 256: ** Check if the timer object has already expired
 257: */
 258: PUBLIC BOOL HTTimer_hasTimerExpired (HTTimer * timer)
 259: {
 260:   return (timer && timer->expires <= HTGetTimeInMillis());
2.1 frystyk 261: }
 262: 
2.7 eric 263: PUBLIC int HTTimer_next (ms_t * pSoonest)
2.1 frystyk 264: {
2.17 frystyk 265:   HTList * cur = Timers;
 266:   HTList * last = Timers;
2.7 eric 267:   HTTimer * pres;
2.3 eric 268:   ms_t now = HTGetTimeInMillis();
2.7 eric 269:   int ret = HT_OK;
2.3 eric 270: 
2.17 frystyk 271:   /*
 272:   ** Dispatch all timers that have expired
 273:   */
 274:   while (Timers && (pres = (HTTimer *) HTList_nextObject(cur))) {
 275:    if (pres->expires <= now) {
2.23 ! frystyk 276:      if ((ret = Timer_dispatch(cur, last)) != HT_OK) break;
2.17 frystyk 277:      cur = last = Timers;
 278:    } else {
 279:      last = cur;
 280:    }    
 281:   }
2.3 eric 282: 
2.7 eric 283:   if (pSoonest) {
 284:    /*
 285:    **   First element in Timers is the next to expire.
2.3 eric 286:    */
2.8 frystyk 287:    HTList * cur = Timers; /* for now */
 288:    pres = (HTTimer *) HTList_nextObject(cur);
2.7 eric 289:    *pSoonest = pres ? pres->expires - now : 0;
2.1 frystyk 290:   }
2.7 eric 291:   return ret;
2.1 frystyk 292: }
2.12 eric 293: 
2.13 frystyk 294: #ifdef WATCH_RECURSION
2.12 eric 295: extern void CheckSockEvent(HTTimer * timer, HTTimerCallback * cbf, void * param);
2.13 frystyk 296: PRIVATE void CheckTimers(void)
2.12 eric 297: {
 298:   HTList * cur = Timers;
 299:   HTTimer * pres;
 300:   while ((pres = (HTTimer *) HTList_nextObject(cur))) {
 301:    CheckSockEvent(pres, pres->cbf, pres->param);
 302:   }
 303: }
2.13 frystyk 304: #endif

Webmaster

AltStyle によって変換されたページ (->オリジナル) /