gmain: Make GUnixSignalWatchSource pending field atomic

Ensure synchronization between prepare / check /dispatch of
GUnixSignalWatchSource and UNIX signal dispatcher by making operations
on `pending` field atomic.

Issue #1312.
This commit is contained in:
Tomasz Miąsko 2018-11-01 00:00:00 +00:00
parent d2fd53df03
commit 9e652f94d2

View File

@ -5138,14 +5138,10 @@ dispatch_unix_signals_unlocked (void)
{
GUnixSignalWatchSource *source = node->data;
if (!source->pending)
if (pending[source->signum] &&
g_atomic_int_compare_and_exchange (&source->pending, FALSE, TRUE))
{
if (pending[source->signum])
{
source->pending = TRUE;
wake_source ((GSource *) source);
}
wake_source ((GSource *) source);
}
}
@ -5188,7 +5184,7 @@ g_unix_signal_watch_prepare (GSource *source,
unix_signal_source = (GUnixSignalWatchSource *) source;
return unix_signal_source->pending;
return g_atomic_int_get (&unix_signal_source->pending);
}
static gboolean
@ -5198,7 +5194,7 @@ g_unix_signal_watch_check (GSource *source)
unix_signal_source = (GUnixSignalWatchSource *) source;
return unix_signal_source->pending;
return g_atomic_int_get (&unix_signal_source->pending);
}
static gboolean
@ -5220,7 +5216,7 @@ g_unix_signal_watch_dispatch (GSource *source,
again = (callback) (user_data);
unix_signal_source->pending = FALSE;
g_atomic_int_set (&unix_signal_source->pending, FALSE);
return again;
}