]>
code.delx.au - gnu-emacs/blob - src/atimer.c
1 /* Asynchronous timers.
2 Copyright (C) 2000 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
24 #include <syssignal.h>
26 #include <blockinput.h>
34 #ifdef HAVE_SYS_TIME_H
38 /* The ubiquitous min/max macros. */
40 #define max(X, Y) ((X) > (Y) ? (X) : (Y))
41 #define min(X, Y) ((X) < (Y) ? (X) : (Y))
43 /* Free-list of atimer structures. */
45 static struct atimer
*free_atimers
;
47 /* List of currently not running timers due to a call to
50 static struct atimer
*stopped_atimers
;
52 /* List of active atimers, sorted by expiration time. The timer that
53 will become ripe next is always at the front of this list. */
55 static struct atimer
*atimers
;
57 /* Non-zero means alarm_signal_handler has found ripe timers but
58 interrupt_input_blocked was non-zero. In this case, timer
59 functions are not called until the next UNBLOCK_INPUT because timer
60 functions are expected to call X, and X cannot be assumed to be
65 /* Block/unblock SIGALRM.. */
67 #define BLOCK_ATIMERS sigblock (sigmask (SIGALRM))
68 #define UNBLOCK_ATIMERS sigunblock (sigmask (SIGALRM))
70 /* Function prototypes. */
72 static void set_alarm
P_ ((void));
73 static void schedule_atimer
P_ ((struct atimer
*));
76 /* Start a new atimer of type TYPE. TIME specifies when the timer is
77 ripe. FN is the function to call when the timer fires.
78 CLIENT_DATA is stored in the client_data member of the atimer
79 structure returned and so made available to FN when it is called.
81 If TYPE is ATIMER_ABSOLUTE, TIME is the absolute time at which the
84 If TYPE is ATIMER_RELATIVE, the timer is ripe TIME s/us in the
87 In both cases, the timer is automatically freed after it has fired.
89 If TYPE is ATIMER_CONTINUOUS, the timer fires every TIME s/us.
91 Value is a pointer to the atimer started. It can be used in calls
92 to cancel_atimer; don't free it yourself. */
95 start_atimer (type
, time
, fn
, client_data
)
96 enum atimer_type type
;
103 /* May not be called when some timers are stopped. */
107 /* Round TIME up to the next full second if we don't have
109 #ifndef HAVE_SETITIMER
110 if (EMACS_USECS (time
) != 0)
112 EMACS_SET_USECS (time
, 0);
113 EMACS_SET_SECS (time
, EMACS_SECS (time
) + 1);
115 #endif /* not HAVE_SETITIMER */
117 /* Get an atimer structure from the free-list, or allocate
122 free_atimers
= t
->next
;
125 t
= (struct atimer
*) xmalloc (sizeof *t
);
127 /* Fill the atimer structure. */
128 bzero (t
, sizeof *t
);
131 t
->client_data
= client_data
;
135 /* Compute the timer's expiration time. */
138 case ATIMER_ABSOLUTE
:
139 t
->expiration
= time
;
142 case ATIMER_RELATIVE
:
143 EMACS_GET_TIME (t
->expiration
);
144 EMACS_ADD_TIME (t
->expiration
, t
->expiration
, time
);
147 case ATIMER_CONTINUOUS
:
148 EMACS_GET_TIME (t
->expiration
);
149 EMACS_ADD_TIME (t
->expiration
, t
->expiration
, time
);
154 /* Insert the timer in the list of active atimers. */
158 /* Arrange for a SIGALRM at the time the next atimer is ripe. */
165 /* Cancel and free atimer TIMER. */
168 cancel_atimer (timer
)
169 struct atimer
*timer
;
171 struct atimer
*t
, *prev
;
173 /* May not be called when some timers are stopped. */
179 /* See if TIMER is active. */
180 for (t
= atimers
, prev
= 0; t
&& t
!= timer
; t
= t
->next
)
183 /* If it is, take it off the list of active timers, put in on the
184 free-list. We don't bother to arrange for setting a different
185 alarm time, since a too early one doesn't hurt. */
189 prev
->next
= t
->next
;
193 t
->next
= free_atimers
;
201 /* Stop all timers except timer T. T null means stop all timers.
202 This function may only be called when all timers are running. Two
203 calls of this function in a row will lead to an abort. You may not
204 call cancel_atimer or start_atimer while timers are stopped. */
207 stop_other_atimers (t
)
217 struct atimer
*p
, *prev
;
219 /* See if T is active. */
220 for (p
= atimers
, prev
= 0; p
&& p
!= t
; p
= p
->next
)
226 prev
->next
= t
->next
;
232 /* T is not active. Let's handle this like T == 0. */
236 stopped_atimers
= atimers
;
242 /* Run all timers again, if some have been stopped with a call to
243 stop_other_atimers. */
250 struct atimer
*t
= atimers
;
252 atimers
= stopped_atimers
;
253 stopped_atimers
= NULL
;
261 /* A version of run_all_timers suitable for a record_unwind_protect. */
264 unwind_stop_other_atimers (dummy
)
272 /* Arrange for a SIGALRM to arrive when the next timer is ripe. */
277 #if defined (USG) && !defined (POSIX_SIGNALS)
278 /* USG systems forget handlers when they are used;
279 must reestablish each time. */
280 signal (SIGALRM
, alarm_signal_handler
);
285 EMACS_TIME now
, time
;
286 #ifdef HAVE_SETITIMER
290 /* Determine s/us till the next timer is ripe. */
291 EMACS_GET_TIME (now
);
292 EMACS_SUB_TIME (time
, atimers
->expiration
, now
);
294 #ifdef HAVE_SETITIMER
295 /* Don't set the interval to 0; this disables the timer. */
296 if (EMACS_TIME_LE (atimers
->expiration
, now
))
298 EMACS_SET_SECS (time
, 0);
299 EMACS_SET_USECS (time
, 1000);
302 bzero (&it
, sizeof it
);
304 setitimer (ITIMER_REAL
, &it
, 0);
305 #else /* not HAVE_SETITIMER */
306 alarm (max (EMACS_SECS (time
), 1));
307 #endif /* not HAVE_SETITIMER */
312 /* Insert timer T into the list of active atimers `atimers', keeping
313 the list sorted by expiration time. T must not be in this list
320 struct atimer
*a
= atimers
, *prev
= NULL
;
322 /* Look for the first atimer that is ripe after T. */
323 while (a
&& EMACS_TIME_GT (t
->expiration
, a
->expiration
))
324 prev
= a
, a
= a
->next
;
326 /* Insert T in front of the atimer found, if any. */
336 /* Signal handler for SIGALRM. SIGNO is the signal number, i.e.
340 alarm_signal_handler (signo
)
345 EMACS_GET_TIME (now
);
349 && (pending_atimers
= interrupt_input_blocked
) == 0
350 && EMACS_TIME_LE (atimers
->expiration
, now
))
355 atimers
= atimers
->next
;
358 if (t
->type
== ATIMER_CONTINUOUS
)
360 EMACS_ADD_TIME (t
->expiration
, now
, t
->interval
);
365 t
->next
= free_atimers
;
369 EMACS_GET_TIME (now
);
372 #if defined (USG) && !defined (POSIX_SIGNALS)
373 /* USG systems forget handlers when they are used;
374 must reestablish each time. */
375 signal (SIGALRM
, alarm_signal_handler
);
382 /* Call alarm_signal_handler for pending timers. */
385 do_pending_atimers ()
390 alarm_signal_handler (SIGALRM
);
396 /* Turn alarms on/off. This seems to be temporarily necessary on
397 some systems like HPUX (see process.c). */
405 signal (SIGALRM
, alarm_signal_handler
);
416 free_atimers
= atimers
= NULL
;
418 signal (SIGALRM
, alarm_signal_handler
);