Commit | Line | Data |
---|---|---|
9ac0d9e0 | 1 | /* blockinput.h - interface to blocking complicated interrupt-driven input. |
429ab54e | 2 | Copyright (C) 1989, 1993, 2001, 2002, 2003, 2004, |
114f9c96 | 3 | 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. |
33f9662a JB |
4 | |
5 | This file is part of GNU Emacs. | |
6 | ||
b9b1cc14 | 7 | GNU Emacs is free software: you can redistribute it and/or modify |
33f9662a | 8 | it under the terms of the GNU General Public License as published by |
b9b1cc14 GM |
9 | the Free Software Foundation, either version 3 of the License, or |
10 | (at your option) any later version. | |
33f9662a JB |
11 | |
12 | GNU Emacs is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
b9b1cc14 | 18 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ |
33f9662a | 19 | |
b6df5543 DL |
20 | #ifndef EMACS_BLOCKINPUT_H |
21 | #define EMACS_BLOCKINPUT_H | |
22 | ||
23 | #include "atimer.h" | |
33f9662a JB |
24 | |
25 | /* When Emacs is using signal-driven input, the processing of those | |
26 | input signals can get pretty hairy. For example, when Emacs is | |
27 | running under X windows, handling an input signal can entail | |
28 | retrieving events from the X event queue, or making other X calls. | |
29 | ||
30 | If an input signal occurs while Emacs is in the midst of some | |
31 | non-reentrant code, and the signal processing invokes that same | |
32 | code, we lose. For example, malloc and the Xlib functions aren't | |
33 | usually re-entrant, and both are used by the X input signal handler | |
34 | - if we try to process an input signal in the midst of executing | |
35 | any of these functions, we'll lose. | |
36 | ||
37 | To avoid this, we make the following requirements: | |
38 | ||
39 | * Everyone must evaluate BLOCK_INPUT before entering these functions, | |
40 | and then call UNBLOCK_INPUT after performing them. Calls | |
41 | BLOCK_INPUT and UNBLOCK_INPUT may be nested. | |
42 | ||
43 | * Any complicated interrupt handling code should test | |
177c0ea7 | 44 | interrupt_input_blocked, and put off its work until later. |
33f9662a JB |
45 | |
46 | * If the interrupt handling code wishes, it may set | |
47 | interrupt_input_pending to a non-zero value. If that flag is set | |
48 | when input becomes unblocked, UNBLOCK_INPUT will send a new SIGIO. */ | |
49 | ||
cf2db145 | 50 | extern volatile int interrupt_input_blocked; |
33f9662a JB |
51 | |
52 | /* Nonzero means an input interrupt has arrived | |
53 | during the current critical section. */ | |
54 | extern int interrupt_input_pending; | |
55 | ||
95d9dd00 GM |
56 | |
57 | /* Non-zero means asynchronous timers should be run when input is | |
58 | unblocked. */ | |
59 | ||
60 | extern int pending_atimers; | |
61 | ||
edfda783 | 62 | |
33f9662a JB |
63 | /* Begin critical section. */ |
64 | #define BLOCK_INPUT (interrupt_input_blocked++) | |
65 | ||
40a4095a JB |
66 | /* End critical section. |
67 | ||
68 | If doing signal-driven input, and a signal came in when input was | |
69 | blocked, reinvoke the signal handler now to deal with it. | |
70 | ||
71 | We used to have two possible definitions of this macro - one for | |
72 | when SIGIO was #defined, and one for when it wasn't; when SIGIO | |
73 | wasn't #defined, we wouldn't bother to check if we should re-invoke | |
74 | the signal handler. But that doesn't work very well; some of the | |
75 | files which use this macro don't #include the right files to get | |
76 | SIGIO. | |
77 | ||
78 | So, we always test interrupt_input_pending now; that's not too | |
79 | expensive, and it'll never get set if we don't need to resignal. */ | |
95d9dd00 GM |
80 | |
81 | #define UNBLOCK_INPUT \ | |
82 | do \ | |
83 | { \ | |
84 | --interrupt_input_blocked; \ | |
85 | if (interrupt_input_blocked == 0) \ | |
86 | { \ | |
87 | if (interrupt_input_pending) \ | |
88 | reinvoke_input_signal (); \ | |
89 | if (pending_atimers) \ | |
90 | do_pending_atimers (); \ | |
91 | } \ | |
92 | else if (interrupt_input_blocked < 0) \ | |
93 | abort (); \ | |
94 | } \ | |
95 | while (0) | |
33f9662a | 96 | |
835ee136 RS |
97 | /* Undo any number of BLOCK_INPUT calls, |
98 | and also reinvoke any pending signal. */ | |
99 | ||
100 | #define TOTALLY_UNBLOCK_INPUT \ | |
6bf40bf0 | 101 | do if (interrupt_input_blocked != 0) \ |
835ee136 RS |
102 | { \ |
103 | interrupt_input_blocked = 1; \ | |
104 | UNBLOCK_INPUT; \ | |
105 | } \ | |
6bf40bf0 | 106 | while (0) |
835ee136 RS |
107 | |
108 | /* Undo any number of BLOCK_INPUT calls down to level LEVEL, | |
109 | and also (if the level is now 0) reinvoke any pending signal. */ | |
110 | ||
111 | #define UNBLOCK_INPUT_TO(LEVEL) \ | |
112 | do \ | |
113 | { \ | |
835ee136 | 114 | interrupt_input_blocked = (LEVEL) + 1; \ |
c71fd7b7 | 115 | UNBLOCK_INPUT; \ |
835ee136 RS |
116 | } \ |
117 | while (0) | |
118 | ||
33f9662a | 119 | #define UNBLOCK_INPUT_RESIGNAL UNBLOCK_INPUT |
ec5d8db7 | 120 | |
c2de28ef KS |
121 | /* In critical section ? */ |
122 | #define INPUT_BLOCKED_P (interrupt_input_blocked > 0) | |
123 | ||
ec5d8db7 | 124 | /* Defined in keyboard.c */ |
de4df76b | 125 | /* Don't use a prototype here; it causes trouble in some files. */ |
c532d349 | 126 | extern void reinvoke_input_signal (void); |
b6df5543 DL |
127 | |
128 | #endif /* EMACS_BLOCKINPUT_H */ | |
ab5796a9 MB |
129 | |
130 | /* arch-tag: 51a9ec86-945a-4966-8f04-2d1341250e03 | |
131 | (do not change this comment) */ |