Commit | Line | Data |
---|---|---|
9ac0d9e0 | 1 | /* blockinput.h - interface to blocking complicated interrupt-driven input. |
73b0cd50 | 2 | Copyright (C) 1989, 1993, 2001-2011 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 | ||
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. */ | |
95d9dd00 GM |
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) | |
33f9662a | 95 | |
835ee136 RS |
96 | /* Undo any number of BLOCK_INPUT calls, |
97 | and also reinvoke any pending signal. */ | |
98 | ||
99 | #define TOTALLY_UNBLOCK_INPUT \ | |
6bf40bf0 | 100 | do if (interrupt_input_blocked != 0) \ |
835ee136 RS |
101 | { \ |
102 | interrupt_input_blocked = 1; \ | |
103 | UNBLOCK_INPUT; \ | |
104 | } \ | |
6bf40bf0 | 105 | while (0) |
835ee136 RS |
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 | { \ | |
835ee136 | 113 | interrupt_input_blocked = (LEVEL) + 1; \ |
c71fd7b7 | 114 | UNBLOCK_INPUT; \ |
835ee136 RS |
115 | } \ |
116 | while (0) | |
117 | ||
33f9662a | 118 | #define UNBLOCK_INPUT_RESIGNAL UNBLOCK_INPUT |
ec5d8db7 | 119 | |
c2de28ef KS |
120 | /* In critical section ? */ |
121 | #define INPUT_BLOCKED_P (interrupt_input_blocked > 0) | |
122 | ||
ec5d8db7 | 123 | /* Defined in keyboard.c */ |
c532d349 | 124 | extern void reinvoke_input_signal (void); |
b6df5543 DL |
125 | |
126 | #endif /* EMACS_BLOCKINPUT_H */ | |
ab5796a9 | 127 |