diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2013-04-16 16:28:44 +0100 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2013-06-17 17:00:00 +0100 |
commit | 2b3272c75ae48c93911bd6f656965cf77d6de3e8 (patch) | |
tree | c612839ca6bf80883028d7e39c7c894d8c56b900 /dbus/dbus-message.c | |
parent | c80c20af46c5f43dcbe672f2c6d8aec0e7f2bbd6 (diff) | |
download | dbus-2b3272c75ae48c93911bd6f656965cf77d6de3e8.tar.gz |
Make taking a global lock automatically initialize locking if needed
This lets them be thread-safe by default, at the cost that they can
now fail.
init_uninitialized_locks() and init_global_locks() must now both
reimplement the equivalent of _dbus_register_shutdown_func(), by using
_dbus_platform_rmutex_lock() on the same underlying mutex around a call
to _dbus_register_shutdown_func_unlocked().
This is because if they used the usual _DBUS_LOCK() API (as
_dbus_register_shutdown_func() does), it would automatically try to
initialize global locking, leading to infinite recursion.
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=54972
Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Reviewed-by: Alban Crequy <alban.crequy@collabora.co.uk>
Reviewed-by: Anas Nashif <anas.nashif@intel.com>
Diffstat (limited to 'dbus/dbus-message.c')
-rw-r--r-- | dbus/dbus-message.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index bc2380f8..696991f6 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -516,7 +516,9 @@ dbus_message_cache_shutdown (void *data) { int i; - _DBUS_LOCK (message_cache); + if (!_DBUS_LOCK (message_cache)) + _dbus_assert_not_reached ("we would have initialized global locks " + "before registering a shutdown function"); i = 0; while (i < MAX_MESSAGE_CACHE_SIZE) @@ -548,7 +550,12 @@ dbus_message_get_cached (void) message = NULL; - _DBUS_LOCK (message_cache); + if (!_DBUS_LOCK (message_cache)) + { + /* we'd have initialized global locks before caching anything, + * so there can't be anything in the cache */ + return NULL; + } _dbus_assert (message_cache_count >= 0); @@ -660,7 +667,13 @@ dbus_message_cache_or_finalize (DBusMessage *message) was_cached = FALSE; - _DBUS_LOCK (message_cache); + if (!_DBUS_LOCK (message_cache)) + { + /* The only way to get a non-null message goes through + * dbus_message_get_cached() which takes the lock. */ + _dbus_assert_not_reached ("we would have initialized global locks " + "the first time we constructed a message"); + } if (!message_cache_shutdown_registered) { |