aboutsummaryrefslogtreecommitdiffstats
path: root/src/blockinput.h
diff options
context:
space:
mode:
authorDaniel Colascione2012-10-07 14:31:58 -0800
committerDaniel Colascione2012-10-07 14:31:58 -0800
commit36a305a723c63fd345be65c536c52fe9765c14be (patch)
treefb89d9e103552863214c60297a65320917109357 /src/blockinput.h
parent2ab329f3b5d52a39f0a45c3d9c129f1c19560142 (diff)
parent795b1482a9e314cda32d62ac2988f573d359366e (diff)
downloademacs-36a305a723c63fd345be65c536c52fe9765c14be.tar.gz
emacs-36a305a723c63fd345be65c536c52fe9765c14be.zip
Merge from trunk
Diffstat (limited to 'src/blockinput.h')
-rw-r--r--src/blockinput.h118
1 files changed, 36 insertions, 82 deletions
diff --git a/src/blockinput.h b/src/blockinput.h
index 7501bfc91a0..70822e29be7 100644
--- a/src/blockinput.h
+++ b/src/blockinput.h
@@ -19,103 +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
51/* Nonzero means an input interrupt has arrived
52 during the current critical section. */
53extern int interrupt_input_pending;
54 46
47 Historically, Emacs signal handlers did much more than they do now,
48 and this caused many BLOCK_INPUT calls to be sprinkled around the code.
49 FIXME: Remove calls that aren't needed now. */
55 50
56/* Non-zero means asynchronous timers should be run when input is 51extern volatile int interrupt_input_blocked;
57 unblocked. */
58 52
59extern int pending_atimers; 53/* Begin critical section. */
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 Always test interrupt_input_pending; that's not too expensive, and
71 it'll never get set if we don't need to resignal. This is simpler
72 than dealing here with every configuration option that might affect
73 whether interrupt_input_pending can be nonzero. */
74
75#define UNBLOCK_INPUT \
76 do \
77 { \
78 --interrupt_input_blocked; \
79 if (interrupt_input_blocked == 0) \
80 { \
81 if (interrupt_input_pending) \
82 reinvoke_input_signal (); \
83 if (pending_atimers) \
84 do_pending_atimers (); \
85 } \
86 else if (interrupt_input_blocked < 0) \
87 emacs_abort (); \
88 } \
89 while (0)
90
91/* Undo any number of BLOCK_INPUT calls,
92 and also reinvoke any pending signal. */
93
94#define TOTALLY_UNBLOCK_INPUT \
95 do if (interrupt_input_blocked != 0) \
96 { \
97 interrupt_input_blocked = 1; \
98 UNBLOCK_INPUT; \
99 } \
100 while (0)
101
102/* Undo any number of BLOCK_INPUT calls down to level LEVEL,
103 and also (if the level is now 0) reinvoke any pending signal. */
104
105#define UNBLOCK_INPUT_TO(LEVEL) \
106 do \
107 { \
108 interrupt_input_blocked = (LEVEL) + 1; \
109 UNBLOCK_INPUT; \
110 } \
111 while (0)
112
113#define UNBLOCK_INPUT_RESIGNAL UNBLOCK_INPUT
114 64
115/* In critical section ? */ 65/* In critical section ? */
116#define INPUT_BLOCKED_P (interrupt_input_blocked > 0)
117 66
118/* Defined in keyboard.c */ 67BLOCKINPUT_INLINE bool
119extern void reinvoke_input_signal (void); 68input_blocked_p (void)
69{
70 return 0 < interrupt_input_blocked;
71}
72
73INLINE_HEADER_END
120 74
121#endif /* EMACS_BLOCKINPUT_H */ 75#endif /* EMACS_BLOCKINPUT_H */