Commit | Line | Data |
---|---|---|
9ac0d9e0 | 1 | /* blockinput.h - interface to blocking complicated interrupt-driven input. |
acaf905b | 2 | Copyright (C) 1989, 1993, 2001-2012 Free Software Foundation, Inc. |
33f9662a JB |
3 | |
4 | This file is part of GNU Emacs. | |
5 | ||
b9b1cc14 | 6 | GNU Emacs is free software: you can redistribute it and/or modify |
33f9662a | 7 | it under the terms of the GNU General Public License as published by |
b9b1cc14 GM |
8 | the Free Software Foundation, either version 3 of the License, or |
9 | (at your option) any later version. | |
33f9662a JB |
10 | |
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. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
b9b1cc14 | 17 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ |
33f9662a | 18 | |
b6df5543 DL |
19 | #ifndef EMACS_BLOCKINPUT_H |
20 | #define EMACS_BLOCKINPUT_H | |
21 | ||
22 | #include "atimer.h" | |
33f9662a JB |
23 | |
24 | /* When Emacs is using signal-driven input, the processing of those | |
25 | input signals can get pretty hairy. For example, when Emacs is | |
26 | running under X windows, handling an input signal can entail | |
27 | retrieving events from the X event queue, or making other X calls. | |
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 | ||
36 | To avoid this, we make the following requirements: | |
37 | ||
38 | * Everyone must evaluate BLOCK_INPUT before entering these functions, | |
39 | and then call UNBLOCK_INPUT after performing them. Calls | |
40 | BLOCK_INPUT and UNBLOCK_INPUT may be nested. | |
41 | ||
42 | * Any complicated interrupt handling code should test | |
177c0ea7 | 43 | interrupt_input_blocked, and put off its work until later. |
33f9662a JB |
44 | |
45 | * If the interrupt handling code wishes, it may set | |
46 | interrupt_input_pending to a non-zero value. If that flag is set | |
47 | when input becomes unblocked, UNBLOCK_INPUT will send a new SIGIO. */ | |
48 | ||
cf2db145 | 49 | extern volatile int interrupt_input_blocked; |
33f9662a JB |
50 | |
51 | /* Nonzero means an input interrupt has arrived | |
52 | during the current critical section. */ | |
53 | extern int interrupt_input_pending; | |
54 | ||
95d9dd00 GM |
55 | |
56 | /* Non-zero means asynchronous timers should be run when input is | |
57 | unblocked. */ | |
58 | ||
59 | extern int pending_atimers; | |
60 | ||
edfda783 | 61 | |
33f9662a JB |
62 | /* Begin critical section. */ |
63 | #define BLOCK_INPUT (interrupt_input_blocked++) | |
64 | ||
40a4095a JB |
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 | ||
4a4bbad2 PE |
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. */ | |
95d9dd00 GM |
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) \ | |
1088b922 | 87 | emacs_abort (); \ |
95d9dd00 GM |
88 | } \ |
89 | while (0) | |
33f9662a | 90 | |
835ee136 RS |
91 | /* Undo any number of BLOCK_INPUT calls, |
92 | and also reinvoke any pending signal. */ | |
93 | ||
94 | #define TOTALLY_UNBLOCK_INPUT \ | |
6bf40bf0 | 95 | do if (interrupt_input_blocked != 0) \ |
835ee136 RS |
96 | { \ |
97 | interrupt_input_blocked = 1; \ | |
98 | UNBLOCK_INPUT; \ | |
99 | } \ | |
6bf40bf0 | 100 | while (0) |
835ee136 RS |
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 | { \ | |
835ee136 | 108 | interrupt_input_blocked = (LEVEL) + 1; \ |
c71fd7b7 | 109 | UNBLOCK_INPUT; \ |
835ee136 RS |
110 | } \ |
111 | while (0) | |
112 | ||
33f9662a | 113 | #define UNBLOCK_INPUT_RESIGNAL UNBLOCK_INPUT |
ec5d8db7 | 114 | |
c2de28ef KS |
115 | /* In critical section ? */ |
116 | #define INPUT_BLOCKED_P (interrupt_input_blocked > 0) | |
117 | ||
ec5d8db7 | 118 | /* Defined in keyboard.c */ |
c532d349 | 119 | extern void reinvoke_input_signal (void); |
b6df5543 DL |
120 | |
121 | #endif /* EMACS_BLOCKINPUT_H */ |