Update xdisp.c commentary

* src/xdisp.c: Update commentary regarding "asynchronous" entry
into redisplay.  (Bug#30182)
This commit is contained in:
Eli Zaretskii 2018-02-03 12:19:41 +02:00
parent e23de39e22
commit 1ed408995a

View file

@ -34,26 +34,41 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
in xdisp.c is the only entry into the inner redisplay code. in xdisp.c is the only entry into the inner redisplay code.
The following diagram shows how redisplay code is invoked. As you The following diagram shows how redisplay code is invoked. As you
can see, Lisp calls redisplay and vice versa. Under window systems can see, Lisp calls redisplay and vice versa.
like X, some portions of the redisplay code are also called
asynchronously during mouse movement or expose events. It is very Under window systems like X, some portions of the redisplay code
important that these code parts do NOT use the C library (malloc, are also called asynchronously, due to mouse movement or expose
free) because many C libraries under Unix are not reentrant. They events. "Asynchronously" in this context means that any C function
may also NOT call functions of the Lisp interpreter which could which calls maybe_quit or process_pending_signals could enter
change the interpreter's state. If you don't follow these rules, redisplay via expose_frame and/or note_mouse_highlight, if X events
you will encounter bugs which are very hard to explain. were recently reported to Emacs about mouse movements or frame(s)
that were exposed. And such redisplay could invoke the Lisp
interpreter, e.g. via the :eval forms in mode-line-format, and as
result the global state could change. It is therefore very
important that C functions which might cause such "asynchronous"
redisplay, but cannot tolerate the results, use
block_input/unblock_input around code fragments which assume that
global Lisp state doesn't change. If you don't follow this rule,
you will encounter bugs which are very hard to explain. One place
that needs to take such precautions is timer_check, some of whose
code cannot tolerate changes in timer alists while it processes
timers.
+--------------+ redisplay +----------------+ +--------------+ redisplay +----------------+
| Lisp machine |---------------->| Redisplay code |<--+ | Lisp machine |---------------->| Redisplay code |<--+
+--------------+ (xdisp.c) +----------------+ | +--------------+ (xdisp.c) +----------------+ |
^ | | ^ | |
+----------------------------------+ | +----------------------------------+ |
Don't use this path when called | Block input to prevent this when |
asynchronously! | called asynchronously! |
| |
expose_window (asynchronous) | note_mouse_highlight (asynchronous) |
| |
X expose events -----+ X mouse events -----+
|
expose_frame (asynchronous) |
|
X expose events -----+
What does redisplay do? Obviously, it has to figure out somehow what What does redisplay do? Obviously, it has to figure out somehow what
has been changed since the last time the display has been updated, has been changed since the last time the display has been updated,