From: Eli Zaretskii Date: Fri, 25 Jun 2021 13:52:48 +0000 (+0300) Subject: Fix race conditions between Lisp threads in GTK builds X-Git-Tag: emacs-28.0.90~2032 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=6e0bff0296b08fe96b7060f8d10eaa393fcb7bd4;p=emacs.git Fix race conditions between Lisp threads in GTK builds * src/xgselect.c (release_select_lock, acquire_select_lock) [GCC >= 4.7.0]: Use '__atomic' builtins to prevent races between threads in accessing 'threads_holding_glib_lock'. Reported by . (Bug#36609) --- diff --git a/src/xgselect.c b/src/xgselect.c index 0d91d55bad6..92b118b9559 100644 --- a/src/xgselect.c +++ b/src/xgselect.c @@ -34,12 +34,27 @@ static GMainContext *glib_main_context; void release_select_lock (void) { +#if GNUC_PREREQ (4, 7, 0) + if (__atomic_sub_fetch (&threads_holding_glib_lock, 1, __ATOMIC_ACQ_REL) == 0) + g_main_context_release (glib_main_context); +#else if (--threads_holding_glib_lock == 0) g_main_context_release (glib_main_context); +#endif } 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) + { + glib_main_context = context; + while (!g_main_context_acquire (context)) + { + /* Spin. */ + } + } +#else if (threads_holding_glib_lock++ == 0) { glib_main_context = context; @@ -48,6 +63,7 @@ static void acquire_select_lock (GMainContext *context) /* Spin. */ } } +#endif } /* `xg_select' is a `pselect' replacement. Why do we need a separate function?