aboutsummaryrefslogtreecommitdiffstats
path: root/src/blockinput.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/blockinput.h')
-rw-r--r--src/blockinput.h126
1 files changed, 37 insertions, 89 deletions
diff --git a/src/blockinput.h b/src/blockinput.h
index dc02919cf4f..6dc22c6f5dd 100644
--- a/src/blockinput.h
+++ b/src/blockinput.h
@@ -1,5 +1,5 @@
1/* blockinput.h - interface to blocking complicated interrupt-driven input. 1/* blockinput.h - interface to blocking complicated interrupt-driven input.
2 Copyright (C) 1989, 1993, 2001-2012 Free Software Foundation, Inc. 2 Copyright (C) 1989, 1993, 2001-2013 Free Software Foundation, Inc.
3 3
4This file is part of GNU Emacs. 4This file is part of GNU Emacs.
5 5
@@ -19,109 +19,57 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19#ifndef EMACS_BLOCKINPUT_H 19#ifndef EMACS_BLOCKINPUT_H
20#define EMACS_BLOCKINPUT_H 20#define EMACS_BLOCKINPUT_H
21 21
22#include "atimer.h" 22INLINE_HEADER_BEGIN
23#ifndef BLOCKINPUT_INLINE
24# define BLOCKINPUT_INLINE INLINE
25#endif
23 26
24/* When Emacs is using signal-driven input, the processing of those 27/* Emacs should avoid doing anything hairy in a signal handler, because
25 input signals can get pretty hairy. For example, when Emacs is 28 so many system functions are non-reentrant. For example, malloc
26 running under X windows, handling an input signal can entail 29 and the Xlib functions aren't usually re-entrant, so if they were
27 retrieving events from the X event queue, or making other X calls. 30 used by the SIGIO handler, we'd lose.
28
29 If an input signal occurs while Emacs is in the midst of some
30 non-reentrant code, and the signal processing invokes that same
31 code, we lose. For example, malloc and the Xlib functions aren't
32 usually re-entrant, and both are used by the X input signal handler
33 - if we try to process an input signal in the midst of executing
34 any of these functions, we'll lose.
35 31
36 To avoid this, we make the following requirements: 32 To avoid this, we make the following requirements:
37 33
38 * Everyone must evaluate BLOCK_INPUT before entering these functions, 34 * Everyone must evaluate BLOCK_INPUT before performing actions that
39 and then call UNBLOCK_INPUT after performing them. Calls 35 might conflict with a signal handler, and then call UNBLOCK_INPUT
40 BLOCK_INPUT and UNBLOCK_INPUT may be nested. 36 after performing them. Calls BLOCK_INPUT and UNBLOCK_INPUT may be
37 nested.
41 38
42 * Any complicated interrupt handling code should test 39 * Any complicated interrupt handling code should test
43 interrupt_input_blocked, and put off its work until later. 40 INPUT_BLOCKED_P, and put off its work until later.
44 41
45 * If the interrupt handling code wishes, it may set 42 * If the interrupt handling code wishes, it may set
46 interrupt_input_pending to a non-zero value. If that flag is set 43 pending_signals to a non-zero value. If that flag is set
47 when input becomes unblocked, UNBLOCK_INPUT will send a new SIGIO. */ 44 when input becomes unblocked, UNBLOCK_INPUT will then read
48 45 input and process timers.
49extern volatile int interrupt_input_blocked;
50 46
51/* Nonzero means an input interrupt has arrived 47 Historically, Emacs signal handlers did much more than they do now,
52 during the current critical section. */ 48 and this caused many BLOCK_INPUT calls to be sprinkled around the code.
53extern int interrupt_input_pending; 49 FIXME: Remove calls that aren't needed now. */
54 50
51extern volatile int interrupt_input_blocked;
55 52
56/* Non-zero means asynchronous timers should be run when input is 53/* Begin critical section. */
57 unblocked. */
58
59extern int pending_atimers;
60 54
55BLOCKINPUT_INLINE void
56block_input (void)
57{
58 interrupt_input_blocked++;
59}
61 60
62/* Begin critical section. */ 61extern void unblock_input (void);
63#define BLOCK_INPUT (interrupt_input_blocked++) 62extern void totally_unblock_input (void);
64 63extern void unblock_input_to (int);
65/* End critical section.
66
67 If doing signal-driven input, and a signal came in when input was
68 blocked, reinvoke the signal handler now to deal with it.
69
70 We used to have two possible definitions of this macro - one for
71 when SIGIO was #defined, and one for when it wasn't; when SIGIO
72 wasn't #defined, we wouldn't bother to check if we should re-invoke
73 the signal handler. But that doesn't work very well; some of the
74 files which use this macro don't #include the right files to get
75 SIGIO.
76
77 So, we always test interrupt_input_pending now; that's not too
78 expensive, and it'll never get set if we don't need to resignal. */
79
80#define UNBLOCK_INPUT \
81 do \
82 { \
83 --interrupt_input_blocked; \
84 if (interrupt_input_blocked == 0) \
85 { \
86 if (interrupt_input_pending) \
87 reinvoke_input_signal (); \
88 if (pending_atimers) \
89 do_pending_atimers (); \
90 } \
91 else if (interrupt_input_blocked < 0) \
92 abort (); \
93 } \
94 while (0)
95
96/* Undo any number of BLOCK_INPUT calls,
97 and also reinvoke any pending signal. */
98
99#define TOTALLY_UNBLOCK_INPUT \
100 do if (interrupt_input_blocked != 0) \
101 { \
102 interrupt_input_blocked = 1; \
103 UNBLOCK_INPUT; \
104 } \
105 while (0)
106
107/* Undo any number of BLOCK_INPUT calls down to level LEVEL,
108 and also (if the level is now 0) reinvoke any pending signal. */
109
110#define UNBLOCK_INPUT_TO(LEVEL) \
111 do \
112 { \
113 interrupt_input_blocked = (LEVEL) + 1; \
114 UNBLOCK_INPUT; \
115 } \
116 while (0)
117
118#define UNBLOCK_INPUT_RESIGNAL UNBLOCK_INPUT
119 64
120/* In critical section ? */ 65/* In critical section ? */
121#define INPUT_BLOCKED_P (interrupt_input_blocked > 0)
122 66
123/* Defined in keyboard.c */ 67BLOCKINPUT_INLINE bool
124extern void reinvoke_input_signal (void); 68input_blocked_p (void)
69{
70 return interrupt_input_blocked > 0;
71}
125 72
126#endif /* EMACS_BLOCKINPUT_H */ 73INLINE_HEADER_END
127 74
75#endif /* EMACS_BLOCKINPUT_H */