]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix xwidgets setting their own signal handlers
authorPo Lu <luangruo@yahoo.com>
Wed, 5 Jan 2022 02:36:40 +0000 (10:36 +0800)
committerPo Lu <luangruo@yahoo.com>
Wed, 5 Jan 2022 02:36:40 +0000 (10:36 +0800)
* src/xgselect.c (release_select_lock):
(acquire_select_lock): Fix coding style.
(xg_select): Call `catch_child_signal' if xwidgets are enabled.

* src/xwidget.c (kill_xwidget):
(kill_buffer_xwidgets): Call `catch_child_signal'.  (bug#53013)

src/xgselect.c
src/xwidget.c

index 8afd3f238f0e05a41f0a1a5bc1f9c591699cb1ef..674c259db762e13e3beec32cefbb47c77488c0a9 100644 (file)
@@ -28,11 +28,13 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 #include "lisp.h"
 #include "blockinput.h"
 #include "systime.h"
+#include "process.h"
 
 static ptrdiff_t threads_holding_glib_lock;
 static GMainContext *glib_main_context;
 
-void release_select_lock (void)
+void
+release_select_lock (void)
 {
 #if GNUC_PREREQ (4, 7, 0)
   if (__atomic_sub_fetch (&threads_holding_glib_lock, 1, __ATOMIC_ACQ_REL) == 0)
@@ -43,7 +45,8 @@ void release_select_lock (void)
 #endif
 }
 
-static void acquire_select_lock (GMainContext *context)
+static void
+acquire_select_lock (GMainContext *context)
 {
 #if GNUC_PREREQ (4, 7, 0)
   if (__atomic_fetch_add (&threads_holding_glib_lock, 1, __ATOMIC_ACQ_REL) == 0)
@@ -181,6 +184,21 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds,
 #else
   need_to_dispatch = true;
 #endif
+
+  /* xwidgets make heavy use of GLib subprocesses, which add their own
+     SIGCHLD handler at arbitrary locations.  That doesn't play well
+     with Emacs's own handler, so once GLib does its thing with its
+     subprocesses we restore our own SIGCHLD handler (which chains the
+     GLib handler) here.
+
+     There is an obvious race condition, but we can't really do
+     anything about that, except hope a SIGCHLD arrives soon to clear
+     up the situation.  */
+
+#ifdef HAVE_XWIDGETS
+  catch_child_signal ();
+#endif
+
   if (need_to_dispatch)
     {
       acquire_select_lock (context);
index 24dafa7d3c6dfc5ad01c2edc0ed69010a60f1e4f..7d6d256a191e5f504d5f184717c71233c2a47ca1 100644 (file)
@@ -3610,6 +3610,8 @@ kill_xwidget (struct xwidget *xw)
   xw->widget_osr = NULL;
   xw->widgetwindow_osr = NULL;
   xw->find_text = NULL;
+
+  catch_child_signal ();
 #elif defined NS_IMPL_COCOA
   nsxwidget_kill (xw);
 #endif
@@ -3630,4 +3632,6 @@ kill_buffer_xwidgets (Lisp_Object buffer)
        kill_xwidget (xw);
       }
     }
+
+  catch_child_signal ();
 }