Fix Bug#24432
[emacs.git] / src / atimer.c
blob64c9e8ab6cb4a98ebbb233998ee2f3e7c2fc2365
1 /* Asynchronous timers.
2 Copyright (C) 2000-2016 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 3 of the License, or (at
9 your option) any later version.
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. If not, see <http://www.gnu.org/licenses/>. */
19 #include <config.h>
20 #include <stdio.h>
22 #include "lisp.h"
23 #include "syssignal.h"
24 #include "systime.h"
25 #include "atimer.h"
26 #include <unistd.h>
28 #ifdef HAVE_TIMERFD
29 #include <errno.h>
30 # include <sys/timerfd.h>
31 #endif
33 #ifdef MSDOS
34 #include "msdos.h"
35 #endif
37 /* Free-list of atimer structures. */
39 static struct atimer *free_atimers;
41 /* List of currently not running timers due to a call to
42 lock_atimer. */
44 static struct atimer *stopped_atimers;
46 /* List of active atimers, sorted by expiration time. The timer that
47 will become ripe next is always at the front of this list. */
49 static struct atimer *atimers;
51 #ifdef HAVE_ITIMERSPEC
52 /* The alarm timer and whether it was properly initialized, if
53 POSIX timers are available. */
54 static timer_t alarm_timer;
55 static bool alarm_timer_ok;
57 # ifdef HAVE_TIMERFD
58 /* File descriptor for timer, or -1 if it could not be created. */
59 static int timerfd;
60 # else
61 enum { timerfd = -1 };
62 # endif
63 #endif
65 /* Block/unblock SIGALRM. */
67 static void
68 block_atimers (sigset_t *oldset)
70 sigset_t blocked;
71 sigemptyset (&blocked);
72 sigaddset (&blocked, SIGALRM);
73 sigaddset (&blocked, SIGINT);
74 pthread_sigmask (SIG_BLOCK, &blocked, oldset);
76 static void
77 unblock_atimers (sigset_t const *oldset)
79 pthread_sigmask (SIG_SETMASK, oldset, 0);
82 /* Function prototypes. */
84 static void set_alarm (void);
85 static void schedule_atimer (struct atimer *);
86 static struct atimer *append_atimer_lists (struct atimer *,
87 struct atimer *);
89 /* Start a new atimer of type TYPE. TIMESTAMP specifies when the timer is
90 ripe. FN is the function to call when the timer fires.
91 CLIENT_DATA is stored in the client_data member of the atimer
92 structure returned and so made available to FN when it is called.
94 If TYPE is ATIMER_ABSOLUTE, TIMESTAMP is the absolute time at which the
95 timer fires.
97 If TYPE is ATIMER_RELATIVE, the timer is ripe TIMESTAMP seconds in the
98 future.
100 In both cases, the timer is automatically freed after it has fired.
102 If TYPE is ATIMER_CONTINUOUS, the timer fires every TIMESTAMP seconds.
104 Value is a pointer to the atimer started. It can be used in calls
105 to cancel_atimer; don't free it yourself. */
107 struct atimer *
108 start_atimer (enum atimer_type type, struct timespec timestamp,
109 atimer_callback fn, void *client_data)
111 struct atimer *t;
112 sigset_t oldset;
114 /* Round TIMESTAMP up to the next full second if we don't have itimers. */
115 #ifndef HAVE_SETITIMER
116 if (timestamp.tv_nsec != 0 && timestamp.tv_sec < TYPE_MAXIMUM (time_t))
117 timestamp = make_timespec (timestamp.tv_sec + 1, 0);
118 #endif /* not HAVE_SETITIMER */
120 /* Get an atimer structure from the free-list, or allocate
121 a new one. */
122 if (free_atimers)
124 t = free_atimers;
125 free_atimers = t->next;
127 else
128 t = xmalloc (sizeof *t);
130 /* Fill the atimer structure. */
131 memset (t, 0, sizeof *t);
132 t->type = type;
133 t->fn = fn;
134 t->client_data = client_data;
136 block_atimers (&oldset);
138 /* Compute the timer's expiration time. */
139 switch (type)
141 case ATIMER_ABSOLUTE:
142 t->expiration = timestamp;
143 break;
145 case ATIMER_RELATIVE:
146 t->expiration = timespec_add (current_timespec (), timestamp);
147 break;
149 case ATIMER_CONTINUOUS:
150 t->expiration = timespec_add (current_timespec (), timestamp);
151 t->interval = timestamp;
152 break;
155 /* Insert the timer in the list of active atimers. */
156 schedule_atimer (t);
157 unblock_atimers (&oldset);
159 /* Arrange for a SIGALRM at the time the next atimer is ripe. */
160 set_alarm ();
162 return t;
166 /* Cancel and free atimer TIMER. */
168 void
169 cancel_atimer (struct atimer *timer)
171 int i;
172 sigset_t oldset;
174 block_atimers (&oldset);
176 for (i = 0; i < 2; ++i)
178 struct atimer *t, *prev;
179 struct atimer **list = i ? &stopped_atimers : &atimers;
181 /* See if TIMER is active or stopped. */
182 for (t = *list, prev = NULL; t && t != timer; prev = t, t = t->next)
185 /* If it is, take it off its list, and put in on the free-list.
186 We don't bother to arrange for setting a different alarm time,
187 since a too early one doesn't hurt. */
188 if (t)
190 if (prev)
191 prev->next = t->next;
192 else
193 *list = t->next;
195 t->next = free_atimers;
196 free_atimers = t;
197 break;
201 unblock_atimers (&oldset);
205 /* Append two lists of atimers LIST_1 and LIST_2 and return the
206 result list. */
208 static struct atimer *
209 append_atimer_lists (struct atimer *list_1, struct atimer *list_2)
211 if (list_1 == NULL)
212 return list_2;
213 else if (list_2 == NULL)
214 return list_1;
215 else
217 struct atimer *p;
219 for (p = list_1; p->next; p = p->next)
221 p->next = list_2;
222 return list_1;
227 /* Stop all timers except timer T. T null means stop all timers. */
229 void
230 stop_other_atimers (struct atimer *t)
232 sigset_t oldset;
233 block_atimers (&oldset);
235 if (t)
237 struct atimer *p, *prev;
239 /* See if T is active. */
240 for (p = atimers, prev = NULL; p && p != t; prev = p, p = p->next)
243 if (p == t)
245 if (prev)
246 prev->next = t->next;
247 else
248 atimers = t->next;
249 t->next = NULL;
251 else
252 /* T is not active. Let's handle this like T == 0. */
253 t = NULL;
256 stopped_atimers = append_atimer_lists (atimers, stopped_atimers);
257 atimers = t;
258 unblock_atimers (&oldset);
262 /* Run all timers again, if some have been stopped with a call to
263 stop_other_atimers. */
265 void
266 run_all_atimers (void)
268 if (stopped_atimers)
270 struct atimer *t = atimers;
271 struct atimer *next;
272 sigset_t oldset;
274 block_atimers (&oldset);
275 atimers = stopped_atimers;
276 stopped_atimers = NULL;
278 while (t)
280 next = t->next;
281 schedule_atimer (t);
282 t = next;
285 unblock_atimers (&oldset);
290 /* Arrange for a SIGALRM to arrive when the next timer is ripe. */
292 static void
293 set_alarm (void)
295 if (atimers)
297 #ifdef HAVE_SETITIMER
298 struct itimerval it;
299 #endif
300 struct timespec now, interval;
302 #ifdef HAVE_ITIMERSPEC
303 if (0 <= timerfd || alarm_timer_ok)
305 struct itimerspec ispec;
306 ispec.it_value = atimers->expiration;
307 ispec.it_interval.tv_sec = ispec.it_interval.tv_nsec = 0;
308 # ifdef HAVE_TIMERFD
309 if (timerfd_settime (timerfd, TFD_TIMER_ABSTIME, &ispec, 0) == 0)
311 add_timer_wait_descriptor (timerfd);
312 return;
314 # endif
315 if (alarm_timer_ok
316 && timer_settime (alarm_timer, TIMER_ABSTIME, &ispec, 0) == 0)
317 return;
319 #endif
321 /* Determine interval till the next timer is ripe.
322 Don't set the interval to 0; this disables the timer. */
323 now = current_timespec ();
324 interval = (timespec_cmp (atimers->expiration, now) <= 0
325 ? make_timespec (0, 1000 * 1000)
326 : timespec_sub (atimers->expiration, now));
328 #ifdef HAVE_SETITIMER
330 memset (&it, 0, sizeof it);
331 it.it_value = make_timeval (interval);
332 setitimer (ITIMER_REAL, &it, 0);
333 #else /* not HAVE_SETITIMER */
334 alarm (max (interval.tv_sec, 1));
335 #endif /* not HAVE_SETITIMER */
340 /* Insert timer T into the list of active atimers `atimers', keeping
341 the list sorted by expiration time. T must not be in this list
342 already. */
344 static void
345 schedule_atimer (struct atimer *t)
347 struct atimer *a = atimers, *prev = NULL;
349 /* Look for the first atimer that is ripe after T. */
350 while (a && timespec_cmp (a->expiration, t->expiration) < 0)
351 prev = a, a = a->next;
353 /* Insert T in front of the atimer found, if any. */
354 if (prev)
355 prev->next = t;
356 else
357 atimers = t;
359 t->next = a;
362 static void
363 run_timers (void)
365 struct timespec now = current_timespec ();
367 while (atimers && timespec_cmp (atimers->expiration, now) <= 0)
369 struct atimer *t = atimers;
370 atimers = atimers->next;
371 t->fn (t);
373 if (t->type == ATIMER_CONTINUOUS)
375 t->expiration = timespec_add (now, t->interval);
376 schedule_atimer (t);
378 else
380 t->next = free_atimers;
381 free_atimers = t;
385 set_alarm ();
389 /* Signal handler for SIGALRM. SIGNO is the signal number, i.e.
390 SIGALRM. */
392 static void
393 handle_alarm_signal (int sig)
395 pending_signals = 1;
398 #ifdef HAVE_TIMERFD
400 /* Called from wait_reading_process_output when FD, which
401 should be equal to TIMERFD, is available for reading. */
403 void
404 timerfd_callback (int fd, void *arg)
406 ptrdiff_t nbytes;
407 uint64_t expirations;
409 eassert (fd == timerfd);
410 nbytes = emacs_read (fd, &expirations, sizeof (expirations));
412 if (nbytes == sizeof (expirations))
414 /* Timer should expire just once. */
415 eassert (expirations == 1);
416 do_pending_atimers ();
418 else if (nbytes < 0)
419 /* For some not yet known reason, we may get weird event and no
420 data on timer descriptor. This can break Gnus at least, see:
421 http://lists.gnu.org/archive/html/emacs-devel/2014-07/msg00503.html. */
422 eassert (errno == EAGAIN);
423 else
424 /* I don't know what else can happen with this descriptor. */
425 emacs_abort ();
428 #endif /* HAVE_TIMERFD */
430 /* Do pending timers. */
432 void
433 do_pending_atimers (void)
435 if (atimers)
437 sigset_t oldset;
438 block_atimers (&oldset);
439 run_timers ();
440 unblock_atimers (&oldset);
445 /* Turn alarms on/off. This seems to be temporarily necessary on
446 some systems like HPUX (see process.c). */
448 void
449 turn_on_atimers (bool on)
451 if (on)
452 set_alarm ();
453 else
455 #ifdef HAVE_ITIMERSPEC
456 struct itimerspec ispec;
457 memset (&ispec, 0, sizeof ispec);
458 if (alarm_timer_ok)
459 timer_settime (alarm_timer, TIMER_ABSTIME, &ispec, 0);
460 # ifdef HAVE_TIMERFD
461 timerfd_settime (timerfd, TFD_TIMER_ABSTIME, &ispec, 0);
462 # endif
463 #endif
464 alarm (0);
468 /* This is intended to use from automated tests. */
470 #ifdef ENABLE_CHECKING
472 #define MAXTIMERS 10
474 struct atimer_result
476 /* Time when we expect this timer to trigger. */
477 struct timespec expected;
479 /* Timer status: -1 if not triggered, 0 if triggered
480 too early or too late, 1 if triggered timely. */
481 int intime;
484 static void
485 debug_timer_callback (struct atimer *t)
487 struct timespec now = current_timespec ();
488 struct atimer_result *r = (struct atimer_result *) t->client_data;
489 int result = timespec_cmp (now, r->expected);
491 if (result < 0)
492 /* Too early. */
493 r->intime = 0;
494 else if (result >= 0)
496 #ifdef HAVE_SETITIMER
497 struct timespec delta = timespec_sub (now, r->expected);
498 /* Too late if later than expected + 0.02s. FIXME:
499 this should depend from system clock resolution. */
500 if (timespec_cmp (delta, make_timespec (0, 20000000)) > 0)
501 r->intime = 0;
502 else
503 #endif /* HAVE_SETITIMER */
504 r->intime = 1;
508 DEFUN ("debug-timer-check", Fdebug_timer_check, Sdebug_timer_check, 0, 0, 0,
509 doc: /* Run internal self-tests to check timers subsystem.
510 Return t if all self-tests are passed, nil otherwise. */)
511 (void)
513 int i, ok;
514 struct atimer *timer;
515 struct atimer_result *results[MAXTIMERS];
516 struct timespec t = make_timespec (0, 0);
518 /* Arm MAXTIMERS relative timers to trigger with 0.1s intervals. */
519 for (i = 0; i < MAXTIMERS; i++)
521 results[i] = xmalloc (sizeof (struct atimer_result));
522 t = timespec_add (t, make_timespec (0, 100000000));
523 results[i]->expected = timespec_add (current_timespec (), t);
524 results[i]->intime = -1;
525 timer = start_atimer (ATIMER_RELATIVE, t,
526 debug_timer_callback, results[i]);
529 #ifdef HAVE_TIMERFD
530 /* Wait for 1s but process timers. */
531 wait_reading_process_output (1, 0, 0, false, Qnil, NULL, 0);
532 #else
533 /* If timerfd is not supported, wait_reading_process_output won't
534 pay attention to timers that expired, and the callbacks won't be
535 called. So we need to run the expired timers' callbacks by
536 hand. */
537 /* Wait 1.2 sec for the timers to expire. */
538 struct timespec tend =
539 timespec_add (current_timespec (), make_timespec (1, 200000000));
541 while (timespec_cmp (current_timespec (), tend) < 0)
543 /* Wait for 5 msec between iterations. */
544 wait_reading_process_output (0, 5000000, 0, false, Qnil, NULL, 0);
545 if (pending_signals)
546 do_pending_atimers ();
548 #endif
549 /* Shut up the compiler by "using" this variable. */
550 (void) timer;
552 for (i = 0, ok = 0; i < MAXTIMERS; i++)
553 ok += results[i]->intime, xfree (results[i]);
555 return ok == MAXTIMERS ? Qt : Qnil;
558 #endif /* ENABLE_CHECKING */
560 void
561 init_atimer (void)
563 #ifdef HAVE_ITIMERSPEC
564 # ifdef HAVE_TIMERFD
565 /* Until this feature is considered stable, you can ask to not use it. */
566 timerfd = (egetenv ("EMACS_IGNORE_TIMERFD") ? -1 :
567 timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC));
568 # endif
569 if (timerfd < 0)
571 struct sigevent sigev;
572 sigev.sigev_notify = SIGEV_SIGNAL;
573 sigev.sigev_signo = SIGALRM;
574 sigev.sigev_value.sival_ptr = &alarm_timer;
575 alarm_timer_ok
576 = timer_create (CLOCK_REALTIME, &sigev, &alarm_timer) == 0;
578 #endif
579 free_atimers = stopped_atimers = atimers = NULL;
581 /* pending_signals is initialized in init_keyboard. */
582 struct sigaction action;
583 emacs_sigaction_init (&action, handle_alarm_signal);
584 sigaction (SIGALRM, &action, 0);
586 #ifdef ENABLE_CHECKING
587 defsubr (&Sdebug_timer_check);
588 #endif