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

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

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

Webmaster

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