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💯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>
This commit is contained in:
Philip Withnall 2020-06-29 10:42:00 +01:00
parent 7cb5cd8d98
commit da948f7218

View File

@ -452,13 +452,22 @@ static GMainContext *glib_worker_context;
* Both variables must be accessed using atomic primitives, unless those atomic * Both variables must be accessed using atomic primitives, unless those atomic
* primitives are implemented using fallback mutexes (as those arent safe in * primitives are implemented using fallback mutexes (as those arent safe in
* an interrupt context). * an interrupt context).
*
* If using atomic primitives, the variables must be of type `int` (so theyre
* the right size for the atomic primitives). Otherwise, use `sig_atomic_t` if
* its available, which is guaranteed to be async-signal-safe (but its *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 thats not the case on
* FreeBSD, so we cant use it unconditionally if its defined.
*/ */
#ifdef HAVE_SIG_ATOMIC_T #if (defined(G_ATOMIC_LOCK_FREE) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) || !defined(HAVE_SIG_ATOMIC_T)
static volatile sig_atomic_t unix_signal_pending[NSIG];
static volatile sig_atomic_t any_unix_signal_pending;
#else
static volatile int unix_signal_pending[NSIG]; static volatile int unix_signal_pending[NSIG];
static volatile int any_unix_signal_pending; 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 #endif
/* Guards all the data below */ /* Guards all the data below */