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