Annotation of libwww/Library/src/HTTimer.c, revision 2.4
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.4 ! eric 6: ** @(#) $Id: HTTimer.c,v 2.3 1996年12月05日 23:20:10 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;
! 47: hwnd HTEventList_getWinHAndle(&id);
! 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;
! 55: hwnd HTEventList_getWinHAndle(&id);
! 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: */
109: for (cur = Timers;
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:
135: /*
136: ** add to list if timer is new
137: */
138: if (cur == NULL)
139: HTList_appendObject(Timers, (void *)timer);
2.4 ! eric 140: SET_PLATFORM_TIMER(timer);
2.1 frystyk 141: return timer;
142: }
143:
144:
145: PUBLIC BOOL HTTimer_deleteAll (void)
146: {
2.3 eric 147: HTList * cur = Timers;
148: HTTimer * pres;
149: if (Timers) {
150: while ((pres = (HTTimer *) HTList_nextObject(cur))) {
2.4 ! eric 151: DELETE_PLATFORM_TIMER(pres);
2.3 eric 152: HT_FREE(pres);
2.1 frystyk 153: }
2.3 eric 154: HTList_delete(Timers);
155: Timers = NULL;
2.1 frystyk 156: return YES;
157: }
158: return NO;
159: }
160:
161: /*
162: ** When a timer has expired, we dispatch the event handler and re-register the
163: ** timer with the next expiration time.
164: */
2.3 eric 165: PRIVATE int Timer_dispatch (HTList * cur, HTList * last, int now)
2.1 frystyk 166: {
2.3 eric 167: HTTimer * timer;
168: int ret;
169:
170: timer = (HTTimer *)HTList_objectOf(cur);
171: if (timer == NULL)
172: return HT_ERROR;
2.1 frystyk 173: if (timer->relative)
174: HTTimer_new(timer, timer->cbf, timer->param, timer->millis, YES);
2.3 eric 175: else
176: HTList_quickRemoveElement(cur, last);
2.1 frystyk 177: if (THD_TRACE) HTTrace("Timer....... Dispatch timer %p\n", timer);
2.3 eric 178: ret = (*timer->cbf) (timer, timer->param);
179: if (!timer->relative)
180: HT_FREE(timer);
181: return ret;
182: }
183:
184: PUBLIC int HTTimer_dispatch (HTTimer * timer)
185: {
186: HTList * cur;
187: HTList * last = Timers;
188: HTTimer * pres;
189: ms_t now = HTGetTimeInMillis();
190:
191: cur = HTList_elementOf(Timers, (void *)timer, &last);
192: return Timer_dispatch(cur, last, now);
2.1 frystyk 193: }
194:
2.2 frystyk 195: PUBLIC ms_t HTTimer_soonest (void)
2.1 frystyk 196: {
2.3 eric 197: HTList * cur = Timers;
198: HTList * last = Timers;
199: HTTimer * pres = NULL;
200: ms_t now = HTGetTimeInMillis();
201: int ret;
202:
203: if (Timers == NULL)
204: return 0;
205:
206: while ((pres = (HTTimer *) HTList_nextObject(cur)) && pres->expires <= now) {
207: if ((ret = Timer_dispatch(cur, last, now)) != HT_OK)
208: return ret;
209: last = cur;
2.2 frystyk 210: }
2.3 eric 211:
212: return pres ? pres->expires - now : 0;
2.1 frystyk 213: }
214:
215: PUBLIC int HTTimer_dispatchAll (void)
216: {
2.3 eric 217: HTList * cur = Timers;
218: HTList * last = Timers;
219: HTTimer * pres;
220: ms_t now = HTGetTimeInMillis();
221: int ret;
222:
223: if (Timers) {
224: /* The Timers list may be modified during a dispatch
225: ** so we have to build an intermediate list
226: */
227: HTList * head = HTList_new();
228: while ((pres = (HTTimer *) HTList_nextObject(cur)))
229: HTList_appendObject(head, (void *)pres);
230: cur = last = head;
231: while ((pres = (HTTimer *) HTList_nextObject(cur))) {
232: if ((ret = Timer_dispatch(cur, last, now)) != HT_OK)
233: return ret;
234: last = cur;
235: }
236: return HT_OK;
2.1 frystyk 237: }
2.3 eric 238: return HT_ERROR;
2.1 frystyk 239: }
Webmaster