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

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

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