GDBusConnection: check for initialization where needed for thread-safety
authorSimon McVittie <simon.mcvittie@collabora.co.uk>
Thu, 20 Oct 2011 12:12:26 +0000 (13:12 +0100)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>
Fri, 21 Oct 2011 15:02:27 +0000 (16:02 +0100)
commita7ea94929420cafe5189b477f24da4903bec9e49
tree67c5bd4c0e145fae5d0b6dce126ad6dbcfd8b4d7
parent245d68be6ff0104783ce0b2d4bc0a139f09e0c34
GDBusConnection: check for initialization where needed for thread-safety

Also document which fields require such a check in order to have correct
threading semantics.

This usage doesn't matches the GInitable documentation, which suggests
use of a GError - but using an uninitialized GDBusConnection is
programming error, and not usefully recoverable. (The GInitable
documentation may have been a mistake - GNOME#662208.) Also, not all of
the places where we need it can raise a GError.

The check serves a dual purpose: it turns a non-deterministic crash into
a deterministic critical warning, and is also a memory barrier for
thread-safety. All of these functions dereference or return fields that
are meant to be protected by FLAG_INITIALIZED, so they could crash or
return an undefined value to their caller without this, if called from a
thread that isn't the one that called initable_init() (although I can't
think of any way to do that without encountering a memory barrier,
undefined behaviour, or a race condition that leads to undefined
behaviour if the non-initializing thread wins the race).

One exception is that initable_init() itself makes a synchronous call.
We deal with that by passing new internal flags up the call stack, to
reassure g_dbus_connection_send_message_unlocked() that it can go ahead.

Bug: https://bugzilla.gnome.org/show_bug.cgi?id=661689
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=661992
Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Reviewed-by: David Zeuthen <davidz@redhat.com>
gio/gdbusconnection.c
gio/gioenums.h