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