aboutsummaryrefslogtreecommitdiffstats
path: root/src/atimer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/atimer.c')
-rw-r--r--src/atimer.c69
1 files changed, 44 insertions, 25 deletions
diff --git a/src/atimer.c b/src/atimer.c
index eb3136ae55d..34731920af5 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -17,7 +17,6 @@ You should have received a copy of the GNU General Public License
17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ 17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
18 18
19#include <config.h> 19#include <config.h>
20#include <signal.h>
21#include <stdio.h> 20#include <stdio.h>
22#include <setjmp.h> 21#include <setjmp.h>
23#include "lisp.h" 22#include "lisp.h"
@@ -41,7 +40,7 @@ static struct atimer *stopped_atimers;
41 40
42static struct atimer *atimers; 41static struct atimer *atimers;
43 42
44/* Non-zero means alarm_signal_handler has found ripe timers but 43/* Non-zero means alarm signal handler has found ripe timers but
45 interrupt_input_blocked was non-zero. In this case, timer 44 interrupt_input_blocked was non-zero. In this case, timer
46 functions are not called until the next UNBLOCK_INPUT because timer 45 functions are not called until the next UNBLOCK_INPUT because timer
47 functions are expected to call X, and X cannot be assumed to be 46 functions are expected to call X, and X cannot be assumed to be
@@ -51,8 +50,24 @@ int pending_atimers;
51 50
52/* Block/unblock SIGALRM. */ 51/* Block/unblock SIGALRM. */
53 52
54#define BLOCK_ATIMERS sigblock (sigmask (SIGALRM)) 53static void
55#define UNBLOCK_ATIMERS sigunblock (sigmask (SIGALRM)) 54sigmask_atimers (int how)
55{
56 sigset_t blocked;
57 sigemptyset (&blocked);
58 sigaddset (&blocked, SIGALRM);
59 pthread_sigmask (how, &blocked, 0);
60}
61static void
62block_atimers (void)
63{
64 sigmask_atimers (SIG_BLOCK);
65}
66static void
67unblock_atimers (void)
68{
69 sigmask_atimers (SIG_UNBLOCK);
70}
56 71
57/* Function prototypes. */ 72/* Function prototypes. */
58 73
@@ -60,8 +75,6 @@ static void set_alarm (void);
60static void schedule_atimer (struct atimer *); 75static void schedule_atimer (struct atimer *);
61static struct atimer *append_atimer_lists (struct atimer *, 76static struct atimer *append_atimer_lists (struct atimer *,
62 struct atimer *); 77 struct atimer *);
63static void alarm_signal_handler (int signo);
64
65 78
66/* Start a new atimer of type TYPE. TIME specifies when the timer is 79/* Start a new atimer of type TYPE. TIME specifies when the timer is
67 ripe. FN is the function to call when the timer fires. 80 ripe. FN is the function to call when the timer fires.
@@ -111,7 +124,7 @@ start_atimer (enum atimer_type type, EMACS_TIME timestamp, atimer_callback fn,
111 t->fn = fn; 124 t->fn = fn;
112 t->client_data = client_data; 125 t->client_data = client_data;
113 126
114 BLOCK_ATIMERS; 127 block_atimers ();
115 128
116 /* Compute the timer's expiration time. */ 129 /* Compute the timer's expiration time. */
117 switch (type) 130 switch (type)
@@ -132,7 +145,7 @@ start_atimer (enum atimer_type type, EMACS_TIME timestamp, atimer_callback fn,
132 145
133 /* Insert the timer in the list of active atimers. */ 146 /* Insert the timer in the list of active atimers. */
134 schedule_atimer (t); 147 schedule_atimer (t);
135 UNBLOCK_ATIMERS; 148 unblock_atimers ();
136 149
137 /* Arrange for a SIGALRM at the time the next atimer is ripe. */ 150 /* Arrange for a SIGALRM at the time the next atimer is ripe. */
138 set_alarm (); 151 set_alarm ();
@@ -148,7 +161,7 @@ cancel_atimer (struct atimer *timer)
148{ 161{
149 int i; 162 int i;
150 163
151 BLOCK_ATIMERS; 164 block_atimers ();
152 165
153 for (i = 0; i < 2; ++i) 166 for (i = 0; i < 2; ++i)
154 { 167 {
@@ -175,7 +188,7 @@ cancel_atimer (struct atimer *timer)
175 } 188 }
176 } 189 }
177 190
178 UNBLOCK_ATIMERS; 191 unblock_atimers ();
179} 192}
180 193
181 194
@@ -206,7 +219,7 @@ append_atimer_lists (struct atimer *list_1, struct atimer *list_2)
206void 219void
207stop_other_atimers (struct atimer *t) 220stop_other_atimers (struct atimer *t)
208{ 221{
209 BLOCK_ATIMERS; 222 block_atimers ();
210 223
211 if (t) 224 if (t)
212 { 225 {
@@ -231,7 +244,7 @@ stop_other_atimers (struct atimer *t)
231 244
232 stopped_atimers = append_atimer_lists (atimers, stopped_atimers); 245 stopped_atimers = append_atimer_lists (atimers, stopped_atimers);
233 atimers = t; 246 atimers = t;
234 UNBLOCK_ATIMERS; 247 unblock_atimers ();
235} 248}
236 249
237 250
@@ -246,7 +259,7 @@ run_all_atimers (void)
246 struct atimer *t = atimers; 259 struct atimer *t = atimers;
247 struct atimer *next; 260 struct atimer *next;
248 261
249 BLOCK_ATIMERS; 262 block_atimers ();
250 atimers = stopped_atimers; 263 atimers = stopped_atimers;
251 stopped_atimers = NULL; 264 stopped_atimers = NULL;
252 265
@@ -257,7 +270,7 @@ run_all_atimers (void)
257 t = next; 270 t = next;
258 } 271 }
259 272
260 UNBLOCK_ATIMERS; 273 unblock_atimers ();
261 } 274 }
262} 275}
263 276
@@ -374,13 +387,9 @@ run_timers (void)
374/* Signal handler for SIGALRM. SIGNO is the signal number, i.e. 387/* Signal handler for SIGALRM. SIGNO is the signal number, i.e.
375 SIGALRM. */ 388 SIGALRM. */
376 389
377void 390static void
378alarm_signal_handler (int signo) 391handle_alarm_signal (int sig)
379{ 392{
380#ifndef SYNC_INPUT
381 SIGNAL_THREAD_CHECK (signo);
382#endif
383
384 pending_atimers = 1; 393 pending_atimers = 1;
385#ifdef SYNC_INPUT 394#ifdef SYNC_INPUT
386 pending_signals = 1; 395 pending_signals = 1;
@@ -389,17 +398,23 @@ alarm_signal_handler (int signo)
389#endif 398#endif
390} 399}
391 400
401static void
402deliver_alarm_signal (int sig)
403{
404 handle_on_main_thread (sig, handle_alarm_signal);
405}
406
392 407
393/* Call alarm_signal_handler for pending timers. */ 408/* Call alarm signal handler for pending timers. */
394 409
395void 410void
396do_pending_atimers (void) 411do_pending_atimers (void)
397{ 412{
398 if (pending_atimers) 413 if (pending_atimers)
399 { 414 {
400 BLOCK_ATIMERS; 415 block_atimers ();
401 run_timers (); 416 run_timers ();
402 UNBLOCK_ATIMERS; 417 unblock_atimers ();
403 } 418 }
404} 419}
405 420
@@ -412,7 +427,9 @@ turn_on_atimers (bool on)
412{ 427{
413 if (on) 428 if (on)
414 { 429 {
415 signal (SIGALRM, alarm_signal_handler); 430 struct sigaction action;
431 emacs_sigaction_init (&action, deliver_alarm_signal);
432 sigaction (SIGALRM, &action, 0);
416 set_alarm (); 433 set_alarm ();
417 } 434 }
418 else 435 else
@@ -423,8 +440,10 @@ turn_on_atimers (bool on)
423void 440void
424init_atimer (void) 441init_atimer (void)
425{ 442{
443 struct sigaction action;
426 free_atimers = stopped_atimers = atimers = NULL; 444 free_atimers = stopped_atimers = atimers = NULL;
427 pending_atimers = 0; 445 pending_atimers = 0;
428 /* pending_signals is initialized in init_keyboard.*/ 446 /* pending_signals is initialized in init_keyboard.*/
429 signal (SIGALRM, alarm_signal_handler); 447 emacs_sigaction_init (&action, deliver_alarm_signal);
448 sigaction (SIGALRM, &action, 0);
430} 449}