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; 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]) wake_source ((GSource *) source);
{
source->pending = TRUE;
wake_source ((GSource *) source);
}
} }
} }
@ -5188,7 +5184,7 @@ g_unix_signal_watch_prepare (GSource *source,
unix_signal_source = (GUnixSignalWatchSource *) source; unix_signal_source = (GUnixSignalWatchSource *) source;
return unix_signal_source->pending; return g_atomic_int_get (&unix_signal_source->pending);
} }
static gboolean static gboolean
@ -5198,7 +5194,7 @@ g_unix_signal_watch_check (GSource *source)
unix_signal_source = (GUnixSignalWatchSource *) source; unix_signal_source = (GUnixSignalWatchSource *) source;
return unix_signal_source->pending; return g_atomic_int_get (&unix_signal_source->pending);
} }
static gboolean static gboolean
@ -5220,7 +5216,7 @@ g_unix_signal_watch_dispatch (GSource *source,
again = (callback) (user_data); again = (callback) (user_data);
unix_signal_source->pending = FALSE; g_atomic_int_set (&unix_signal_source->pending, FALSE);
return again; return again;
} }