1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22: #include <config.h>
23: #include <signal.h>
24: #include <stdio.h>
25: #include <lisp.h>
26: #include <syssignal.h>
27: #include <systime.h>
28: #include <blockinput.h>
29: #include <atimer.h>
30:
31: #ifdef HAVE_UNISTD_H
32: #include <unistd.h>
33: #endif
34:
35: #ifdef HAVE_SYS_TIME_H
36: #include <sys/time.h>
37: #endif
38:
39:
40:
41: static struct atimer *free_atimers;
42:
43:
44:
45:
46: static struct atimer *stopped_atimers;
47:
48:
49:
50:
51: static struct atimer *atimers;
52:
53:
54:
55:
56:
57:
58:
59: int pending_atimers;
60:
61:
62:
63: #define BLOCK_ATIMERS sigblock (sigmask (SIGALRM))
64: #define UNBLOCK_ATIMERS sigunblock (sigmask (SIGALRM))
65:
66:
67:
68: static void set_alarm P_ ((void));
69: static void schedule_atimer P_ ((struct atimer *));
70: static struct atimer *append_atimer_lists P_ ((struct atimer *,
71: struct atimer *));
72: SIGTYPE alarm_signal_handler ();
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93: struct atimer *
94: start_atimer (type, time, fn, client_data)
95: enum atimer_type type;
96: EMACS_TIME time;
97: atimer_callback fn;
98: void *client_data;
99: {
100: struct atimer *t;
101:
102:
103:
104: #ifndef HAVE_SETITIMER
105: if (EMACS_USECS (time) != 0)
106: {
107: EMACS_SET_USECS (time, 0);
108: EMACS_SET_SECS (time, EMACS_SECS (time) + 1);
109: }
110: #endif
111:
112:
113:
114: if (free_atimers)
115: {
116: t = free_atimers;
117: free_atimers = t->next;
118: }
119: else
120: t = (struct atimer *) xmalloc (sizeof *t);
121:
122:
123: bzero (t, sizeof *t);
124: t->type = type;
125: t->fn = fn;
126: t->client_data = client_data;
127:
128: BLOCK_ATIMERS;
129:
130:
131: switch (type)
132: {
133: case ATIMER_ABSOLUTE:
134: t->expiration = time;
135: break;
136:
137: case ATIMER_RELATIVE:
138: EMACS_GET_TIME (t->expiration);
139: EMACS_ADD_TIME (t->expiration, t->expiration, time);
140: break;
141:
142: case ATIMER_CONTINUOUS:
143: EMACS_GET_TIME (t->expiration);
144: EMACS_ADD_TIME (t->expiration, t->expiration, time);
145: t->interval = time;
146: break;
147: }
148:
149:
150: schedule_atimer (t);
151: UNBLOCK_ATIMERS;
152:
153:
154: set_alarm ();
155:
156: return t;
157: }
158:
159:
160:
161:
162: void
163: cancel_atimer (timer)
164: struct atimer *timer;
165: {
166: int i;
167:
168: BLOCK_ATIMERS;
169:
170: for (i = 0; i < 2; ++i)
171: {
172: struct atimer *t, *prev;
173: struct atimer **list = i ? &stopped_atimers : &atimers;
174:
175:
176: for (t = *list, prev = NULL; t && t != timer; prev = t, t = t->next)
177: ;
178:
179:
180:
181:
182: if (t)
183: {
184: if (prev)
185: prev->next = t->next;
186: else
187: *list = t->next;
188:
189: t->next = free_atimers;
190: free_atimers = t;
191: break;
192: }
193: }
194:
195: UNBLOCK_ATIMERS;
196: }
197:
198:
199:
200:
201:
202: static struct atimer *
203: append_atimer_lists (list1, list2)
204: struct atimer *list1, *list2;
205: {
206: if (list1 == NULL)
207: return list2;
208: else if (list2 == NULL)
209: return list1;
210: else
211: {
212: struct atimer *p;
213:
214: for (p = list1; p->next; p = p->next)
215: ;
216: p->next = list2;
217: return list1;
218: }
219: }
220:
221:
222:
223:
224: void
225: stop_other_atimers (t)
226: struct atimer *t;
227: {
228: BLOCK_ATIMERS;
229:
230: if (t)
231: {
232: struct atimer *p, *prev;
233:
234:
235: for (p = atimers, prev = NULL; p && p != t; prev = p, p = p->next)
236: ;
237:
238: if (p == t)
239: {
240: if (prev)
241: prev->next = t->next;
242: else
243: atimers = t->next;
244: t->next = NULL;
245: }
246: else
247:
248: t = NULL;
249: }
250:
251: stopped_atimers = append_atimer_lists (atimers, stopped_atimers);
252: atimers = t;
253: UNBLOCK_ATIMERS;
254: }
255:
256:
257:
258:
259:
260: void
261: run_all_atimers ()
262: {
263: if (stopped_atimers)
264: {
265: struct atimer *t = atimers;
266: struct atimer *next;
267:
268: BLOCK_ATIMERS;
269: atimers = stopped_atimers;
270: stopped_atimers = NULL;
271:
272: while (t)
273: {
274: next = t->next;
275: schedule_atimer (t);
276: t = next;
277: }
278:
279: UNBLOCK_ATIMERS;
280: }
281: }
282:
283:
284:
285:
286: Lisp_Object
287: unwind_stop_other_atimers (dummy)
288: Lisp_Object dummy;
289: {
290: run_all_atimers ();
291: return Qnil;
292: }
293:
294:
295:
296:
297: static void
298: set_alarm ()
299: {
300: #if defined (USG) && !defined (POSIX_SIGNALS)
301:
302:
303: signal (SIGALRM, alarm_signal_handler);
304: #endif
305:
306: if (atimers)
307: {
308: EMACS_TIME now, time;
309: #ifdef HAVE_SETITIMER
310: struct itimerval it;
311: #endif
312:
313:
314: EMACS_GET_TIME (now);
315: EMACS_SUB_TIME (time, atimers->expiration, now);
316:
317: #ifdef HAVE_SETITIMER
318:
319: if (EMACS_TIME_LE (atimers->expiration, now))
320: {
321: EMACS_SET_SECS (time, 0);
322: EMACS_SET_USECS (time, 1000);
323: }
324:
325: bzero (&it, sizeof it);
326: it.it_value = time;
327: setitimer (ITIMER_REAL, &it, 0);
328: #else
329: alarm (max (EMACS_SECS (time), 1));
330: #endif
331: }
332: }
333:
334:
335:
336:
337:
338:
339: static void
340: schedule_atimer (t)
341: struct atimer *t;
342: {
343: struct atimer *a = atimers, *prev = NULL;
344:
345:
346: while (a && EMACS_TIME_GT (t->expiration, a->expiration))
347: prev = a, a = a->next;
348:
349:
350: if (prev)
351: prev->next = t;
352: else
353: atimers = t;
354:
355: t->next = a;
356: }
357:
358:
359:
360:
361:
362: SIGTYPE
363: alarm_signal_handler (signo)
364: int signo;
365: {
366: EMACS_TIME now;
367:
368: SIGNAL_THREAD_CHECK (signo);
369:
370: EMACS_GET_TIME (now);
371: pending_atimers = 0;
372:
373: while (atimers
374: && (pending_atimers = interrupt_input_blocked) == 0
375: && EMACS_TIME_LE (atimers->expiration, now))
376: {
377: struct atimer *t;
378:
379: t = atimers;
380: atimers = atimers->next;
381: #ifndef MAC_OSX
382: t->fn (t);
383: #endif
384:
385: if (t->type == ATIMER_CONTINUOUS)
386: {
387: EMACS_ADD_TIME (t->expiration, now, t->interval);
388: schedule_atimer (t);
389: }
390: else
391: {
392: t->next = free_atimers;
393: free_atimers = t;
394: }
395: #ifdef MAC_OSX
396:
397: t->fn (t);
398: #endif
399:
400: EMACS_GET_TIME (now);
401: }
402:
403: if (! pending_atimers)
404: set_alarm ();
405: }
406:
407:
408:
409:
410: void
411: do_pending_atimers ()
412: {
413: if (pending_atimers)
414: {
415: BLOCK_ATIMERS;
416: alarm_signal_handler (SIGALRM);
417: UNBLOCK_ATIMERS;
418: }
419: }
420:
421:
422:
423:
424:
425: void
426: turn_on_atimers (on)
427: int on;
428: {
429: if (on)
430: {
431: signal (SIGALRM, alarm_signal_handler);
432: set_alarm ();
433: }
434: else
435: alarm (0);
436: }
437:
438:
439: void
440: init_atimer ()
441: {
442: free_atimers = atimers = NULL;
443: pending_atimers = 0;
444: signal (SIGALRM, alarm_signal_handler);
445: }
446:
447:
448: