Skip to content
  • Philip Withnall's avatar
    gmain: Access Unix signal handler state atomically · 253f5cda
    Philip Withnall authored
    
    
    There are two variables which are used to pass state from the Unix
    signal handler interrupt function to the rest of `gmain.c`. They are
    currently defined as `sig_atomic_t`, which means that they are
    guaranteed to be interrupt safe. However, it does not guarantee they are
    thread-safe, and GLib attaches its signal handler interrupt function to
    a worker thread.
    
    Make them thread-safe using atomics. It’s not possible to use locks, as
    pthread mutex functions are not signal-handler-safe. In particular, this
    means we have to be careful not to end up using GLib’s fallback atomics
    implementation, as that secretly uses a mutex. Better to be unsafe than
    have a re-entrant call into `pthread_mutex_lock()` from a nested signal
    handler.
    
    This commit solves two problems:
     1. Writes to `any_unix_signal_pending` and `unix_signal_pending` could
        be delivered out of order to the worker thread which calls
        `dispatch_unix_signals()`, resulting in signals not being handled
        until the next iteration of that worker thread. This is a
        performance problem but not a correctness problem.
     2. Setting an element of `unix_signal_pending` from
        `g_unix_signal_handler()` and clearing it from
        `dispatch_unix_signals_unlocked()` (in the worker thread) could
        race, resulting in a signal emission being cleared without being
        handled. That’s a correctness problem.
    
    Signed-off-by: default avatarPhilip Withnall <withnall@endlessm.com>
    
    Fixes: #1670
    253f5cda