GDBusWorker: as a precaution, access 'stopped' boolean atomically

This member is written in _g_dbus_worker_stop from arbitrary threads, and
read by the worker thread, so it should be accessed atomically.

Bug: https://bugzilla.gnome.org/show_bug.cgi?id=651268
Bug-NB: NB#271520
Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Signed-off-by: David Zeuthen <davidz@redhat.com>
This commit is contained in:
Simon McVittie
2011-09-12 18:26:45 +01:00
committed by David Zeuthen
parent 20497f7af9
commit 698eeb3ef6

View File

@@ -340,7 +340,8 @@ struct GDBusWorker
SharedThreadData *shared_thread_data; SharedThreadData *shared_thread_data;
gboolean stopped; /* really a boolean, but GLib 2.28 lacks atomic boolean ops */
volatile gint stopped;
/* TODO: frozen (e.g. G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING) currently /* TODO: frozen (e.g. G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING) currently
* only affects messages received from the other peer (since GDBusServer is the * only affects messages received from the other peer (since GDBusServer is the
@@ -472,7 +473,7 @@ _g_dbus_worker_emit_disconnected (GDBusWorker *worker,
gboolean remote_peer_vanished, gboolean remote_peer_vanished,
GError *error) GError *error)
{ {
if (!worker->stopped) if (!g_atomic_int_get (&worker->stopped))
worker->disconnected_callback (worker, remote_peer_vanished, error, worker->user_data); worker->disconnected_callback (worker, remote_peer_vanished, error, worker->user_data);
} }
@@ -480,7 +481,7 @@ static void
_g_dbus_worker_emit_message_received (GDBusWorker *worker, _g_dbus_worker_emit_message_received (GDBusWorker *worker,
GDBusMessage *message) GDBusMessage *message)
{ {
if (!worker->stopped) if (!g_atomic_int_get (&worker->stopped))
worker->message_received_callback (worker, message, worker->user_data); worker->message_received_callback (worker, message, worker->user_data);
} }
@@ -489,7 +490,7 @@ _g_dbus_worker_emit_message_about_to_be_sent (GDBusWorker *worker,
GDBusMessage *message) GDBusMessage *message)
{ {
GDBusMessage *ret; GDBusMessage *ret;
if (!worker->stopped) if (!g_atomic_int_get (&worker->stopped))
ret = worker->message_about_to_be_sent_callback (worker, message, worker->user_data); ret = worker->message_about_to_be_sent_callback (worker, message, worker->user_data);
else else
ret = message; ret = message;
@@ -571,7 +572,7 @@ _g_dbus_worker_do_read_cb (GInputStream *input_stream,
g_mutex_lock (worker->read_lock); g_mutex_lock (worker->read_lock);
/* If already stopped, don't even process the reply */ /* If already stopped, don't even process the reply */
if (worker->stopped) if (g_atomic_int_get (&worker->stopped))
goto out; goto out;
error = NULL; error = NULL;
@@ -1631,7 +1632,7 @@ _g_dbus_worker_close (GDBusWorker *worker,
void void
_g_dbus_worker_stop (GDBusWorker *worker) _g_dbus_worker_stop (GDBusWorker *worker)
{ {
worker->stopped = TRUE; g_atomic_int_set (&worker->stopped, TRUE);
/* Cancel any pending operations and schedule a close of the underlying I/O /* Cancel any pending operations and schedule a close of the underlying I/O
* stream in the worker thread * stream in the worker thread