[glib] gmain: Fix use of atomic primitives with sig_atomic_t



commit da948f7218749487adbe18983a1795913a827803
Author: Philip Withnall <withnall endlessm com>
Date:   Mon Jun 29 10:42:00 2020 +0100

    gmain: Fix use of atomic primitives with sig_atomic_t
    
    It seems that `sig_atomic_t` is not the same width as `int` on FreeBSD,
    which is causing CI failures:
    ```
     ../glib/gmain.c:5206:3: error: '_GStaticAssertCompileTimeAssertion_73' declared as an array with a 
negative size
      g_atomic_int_set (&any_unix_signal_pending, 0);
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ../glib/gatomic.h:100:5: note: expanded from macro 'g_atomic_int_set'
        G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint));                     \
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ```
    
    Fix that by only using `sig_atomic_t` if the code is *not* using atomic
    primitives (i.e. in the fallback case). `sig_atomic_t` is only a typedef
    around an integer type and is not magic. Its typedef is chosen by the
    platform to be async-signal-safe (i.e. read or written in one instruction),
    but not necessarily thread-safe.
    
    Signed-off-by: Philip Withnall <withnall endlessm com>

 glib/gmain.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
---
diff --git a/glib/gmain.c b/glib/gmain.c
index 88140c865..c18d29079 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -452,13 +452,22 @@ static GMainContext *glib_worker_context;
  * Both variables must be accessed using atomic primitives, unless those atomic
  * primitives are implemented using fallback mutexes (as those aren’t safe in
  * an interrupt context).
+ *
+ * If using atomic primitives, the variables must be of type `int` (so they’re
+ * the right size for the atomic primitives). Otherwise, use `sig_atomic_t` if
+ * it’s available, which is guaranteed to be async-signal-safe (but it’s *not*
+ * guaranteed to be thread-safe, which is why we use atomic primitives if
+ * possible).
+ *
+ * Typically, `sig_atomic_t` is a typedef to `int`, but that’s not the case on
+ * FreeBSD, so we can’t use it unconditionally if it’s defined.
  */
-#ifdef HAVE_SIG_ATOMIC_T
-static volatile sig_atomic_t unix_signal_pending[NSIG];
-static volatile sig_atomic_t any_unix_signal_pending;
-#else
+#if (defined(G_ATOMIC_LOCK_FREE) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) || 
!defined(HAVE_SIG_ATOMIC_T)
 static volatile int unix_signal_pending[NSIG];
 static volatile int any_unix_signal_pending;
+#else
+static volatile sig_atomic_t unix_signal_pending[NSIG];
+static volatile sig_atomic_t any_unix_signal_pending;
 #endif
 
 /* Guards all the data below */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]