[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 760107639b: Protect windows from garbage collection when a Client
From: |
Po Lu |
Subject: |
master 760107639b: Protect windows from garbage collection when a ClientMessage is pending |
Date: |
Sat, 16 Apr 2022 04:50:12 -0400 (EDT) |
branch: master
commit 760107639be7657c4a209c9c04b17c79fc19f2c6
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Protect windows from garbage collection when a ClientMessage is pending
* src/xterm.c (x_protect_window_for_callback)
(x_unprotect_window_for_callback): New functions.
(x_send_scroll_bar_event): Protect windows from garbage
collection before sending event containing pointer to window.
(handle_one_xevent): Unprotect after such a ClientMessage is
received and the window put in the keyboard buffer.
(x_term_init): Initialize protected windows list.
(x_delete_display): Free that list.
(mark_xterm): Mark the windows in that list.
* src/xterm.h (struct x_display_info): New fields for recording
a list of protected windows.
---
src/xterm.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
src/xterm.h | 6 ++++++
2 files changed, 63 insertions(+), 4 deletions(-)
diff --git a/src/xterm.c b/src/xterm.c
index c5b31553ae..ae3f2d7517 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -10846,6 +10846,35 @@ xt_horizontal_action_hook (Widget widget, XtPointer
client_data, String action_n
}
#endif /* not USE_GTK */
+/* Protect WINDOW from garbage collection until a matching scroll bar
+ message is received. Return whether or not protection
+ succeeded. */
+static bool
+x_protect_window_for_callback (struct x_display_info *dpyinfo,
+ Lisp_Object window)
+{
+ if (dpyinfo->n_protected_windows + 1
+ >= dpyinfo->protected_windows_max)
+ return false;
+
+ dpyinfo->protected_windows[dpyinfo->n_protected_windows++]
+ = window;
+ return true;
+}
+
+static void
+x_unprotect_window_for_callback (struct x_display_info *dpyinfo)
+{
+ if (!dpyinfo->n_protected_windows)
+ emacs_abort ();
+
+ dpyinfo->n_protected_windows--;
+
+ if (dpyinfo->n_protected_windows)
+ memmove (dpyinfo->protected_windows, &dpyinfo->protected_windows[1],
+ sizeof (Lisp_Object) * dpyinfo->n_protected_windows);
+}
+
/* Send a client message with message type Xatom_Scrollbar for a
scroll action to the frame of WINDOW. PART is a value identifying
the part of the scroll bar that was clicked on. PORTION is the
@@ -10863,8 +10892,12 @@ x_send_scroll_bar_event (Lisp_Object window, enum
scroll_bar_part part,
verify (INTPTR_WIDTH <= 64);
int sign_shift = INTPTR_WIDTH - 32;
- block_input ();
+ /* Don't do anything if too many scroll bar events have been
+ sent but not received. */
+ if (!x_protect_window_for_callback (FRAME_DISPLAY_INFO (f), window))
+ return;
+ block_input ();
/* Construct a ClientMessage event to send to the frame. */
ev->type = ClientMessage;
ev->message_type = (horizontal
@@ -18854,6 +18887,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
count++;
}
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ if (event->xany.type == ClientMessage
+ && inev.ie.kind == SCROLL_BAR_CLICK_EVENT)
+ x_unprotect_window_for_callback (dpyinfo);
+#endif
+
if (do_help
&& !(hold_quit && hold_quit->kind != NO_EVENT))
{
@@ -23415,6 +23454,12 @@ x_term_init (Lisp_Object display_name, char
*xrm_option, char *resource_name)
x_extension_initialize (dpyinfo);
#endif
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ dpyinfo->protected_windows = xmalloc (sizeof (Lisp_Object) * 256);
+ dpyinfo->n_protected_windows = 0;
+ dpyinfo->protected_windows_max = 256;
+#endif
+
unblock_input ();
return dpyinfo;
@@ -23469,12 +23514,14 @@ x_delete_display (struct x_display_info *dpyinfo)
xfree (dpyinfo->x_id_name);
xfree (dpyinfo->x_dnd_atoms);
xfree (dpyinfo->color_cells);
- xfree (dpyinfo);
-
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ xfree (dpyinfo->protected_windows);
+#endif
#ifdef HAVE_XINPUT2
if (dpyinfo->supports_xi2)
x_free_xi_devices (dpyinfo);
#endif
+ xfree (dpyinfo);
}
#ifdef USE_X_TOOLKIT
@@ -23817,11 +23864,17 @@ mark_xterm (void)
mark_object (val);
}
-#ifdef HAVE_XINPUT2
+#if defined HAVE_XINPUT2 || defined USE_TOOLKIT_SCROLL_BARS
for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
{
+#ifdef HAVE_XINPUT2
for (i = 0; i < dpyinfo->num_devices; ++i)
mark_object (dpyinfo->devices[i].name);
+#endif
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ for (i = 0; i < dpyinfo->n_protected_windows; ++i)
+ mark_object (dpyinfo->protected_windows[i]);
+#endif
}
#endif
}
diff --git a/src/xterm.h b/src/xterm.h
index a04596cdb1..5d2b397874 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -672,6 +672,12 @@ struct x_display_info
int xshape_event_base;
int xshape_error_base;
#endif
+
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ Lisp_Object *protected_windows;
+ int n_protected_windows;
+ int protected_windows_max;
+#endif
};
#ifdef HAVE_X_I18N
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 760107639b: Protect windows from garbage collection when a ClientMessage is pending,
Po Lu <=