PUBLIC HTList * HTList_appendList (HTList * me, void *newObject) { if (me) { while (me->next) me = me->next; return HTList_addList(me, newObject); } return (HTList *) NULL; }
PUBLIC HTTimer * HTTimer_new (HTTimer * timer, HTTimerCallback * cbf, void * param, ms_t millis, BOOL relative, BOOL repetitive) { HTList * last; HTList * cur; ms_t now = HTGetTimeInMillis(); ms_t expires; HTTimer * pres; CHECKME(timer); expires = millis; if (relative) expires += now; else millis = expires-now; if (Timers == NULL) Timers = HTList_new(); if (timer) { /* if a timer is specified, it should already exist */ if ((cur = HTList_elementOf(Timers, (void *)timer, &last)) == NULL) { HTDEBUGBREAK("Timer %p not found\n" _ timer); CLEARME(timer); return NULL; } HTList_quickRemoveElement(cur, last); HTTRACE(THD_TRACE, "Timer....... Found timer %p with callback %p, context %p, and %s timeout %d\n" _ timer _ cbf _ param _ relative ? "relative" : "absolute" _ millis); /* could optimize by sorting from last when ((HTList *)(last->object))->expires < expires (most common case) */ } else { /* create a new timer */ if ((timer = (HTTimer *) HT_CALLOC(1, sizeof(HTTimer))) == NULL) HT_OUTOFMEM("HTTimer_new"); last = Timers; HTTRACE(THD_TRACE, "Timer....... Created %s timer %p with callback %p, context %p, and %s timeout %d\n" _ repetitive ? "repetitive" : "one shot" _ timer _ cbf _ param _ relative ? "relative" : "absolute" _ millis); } /* ** Sort new element into list */ for (cur = last; (pres = (HTTimer *) HTList_nextObject(cur)) != NULL && pres->expires < expires; last = cur); /* ** If the expiration is 0 then we still register it but dispatch it immediately. */ if (!millis) HTTRACE(THD_TRACE, "Timer....... Timeout is 0 - expires NOW\n"); timer->expires = expires; timer->cbf = cbf; timer->param = param; timer->millis = millis; timer->relative = relative; timer->repetitive = repetitive; SETME(timer); /* ** add to list if timer is new */ cur = HTList_addList(last, (void *)timer); /* ** Call any platform specific timer handler */ if (SetPlatformTimer) SetPlatformTimer(timer); /* Check if the timer object has already expired. If so then dispatch */ if (timer->expires <= now) Timer_dispatch(cur, last); CLEARME(timer); return timer; }