summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2022-11-24 20:10:14 +0800
committerPo Lu <luangruo@yahoo.com>2022-11-24 20:10:32 +0800
commit9fcff114b8fe2d538699172fe756606441e67b92 (patch)
treed63b70006730686c73b44db2f5caf6566fb40dff /src
parent867e962cf5318399dfc17cc53c661db4bbd3c3d1 (diff)
downloademacs-9fcff114b8fe2d538699172fe756606441e67b92.tar.gz
Fix reentrancy problem/crash in xterm.c
* src/xterm.c (x_ignore_errors_for_next_request) (x_stop_ignoring_errors): Be paranoid and block input inside the protected section. (x_focus_frame): Block input around critical section.
Diffstat (limited to 'src')
-rw-r--r--src/xterm.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/src/xterm.c b/src/xterm.c
index cfd8c385d1d..7d855c92ccb 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -25461,6 +25461,17 @@ x_clean_failable_requests (struct x_display_info *dpyinfo)
+ (last - first));
}
+/* Protect a section of X requests: ignore errors generated by X
+ requests made from now until `x_stop_ignoring_errors'. Each call
+ must be paired with a call to `x_stop_ignoring_errors', and
+ recursive calls inside the protected section are not allowed.
+
+ The advantage over x_catch_errors followed by
+ x_uncatch_errors_after_check is that this function does not sync to
+ catch errors if requests were made. It should be used instead of
+ those two functions for catching errors around requests that do not
+ require a reply. */
+
void
x_ignore_errors_for_next_request (struct x_display_info *dpyinfo)
{
@@ -25468,7 +25479,13 @@ x_ignore_errors_for_next_request (struct x_display_info *dpyinfo)
unsigned long next_request;
#ifdef HAVE_GTK3
GdkDisplay *gdpy;
+#endif
+ /* This code is not reentrant, so be sure nothing calls it
+ recursively in response to input. */
+ block_input ();
+
+#ifdef HAVE_GTK3
/* GTK 3 tends to override our own error handler inside certain
callbacks, which this can be called from. Instead of trying to
restore our own, add a trap for the following requests with
@@ -25537,6 +25554,8 @@ x_stop_ignoring_errors (struct x_display_info *dpyinfo)
if (gdpy)
gdk_x11_display_error_trap_pop_ignored (gdpy);
#endif
+
+ unblock_input ();
}
/* Undo the last x_catch_errors call.
@@ -27836,6 +27855,10 @@ x_focus_frame (struct frame *f, bool noactivate)
struct x_display_info *dpyinfo;
Time time;
+ /* The code below is not reentrant wrt to dpyinfo->x_focus_frame and
+ friends being set. */
+ block_input ();
+
dpyinfo = FRAME_DISPLAY_INFO (f);
if (FRAME_X_EMBEDDED_P (f))
@@ -27866,7 +27889,7 @@ x_focus_frame (struct frame *f, bool noactivate)
the current workspace, and mapping it, etc, before moving
input focus to the frame. */
x_ewmh_activate_frame (f);
- return;
+ goto out;
}
if (NILP (Vx_no_window_manager))
@@ -27900,6 +27923,9 @@ x_focus_frame (struct frame *f, bool noactivate)
matter. */
CurrentTime);
}
+
+ out:
+ unblock_input ();
}