From 79878da0d8b759aea52558ef12a87de2a556f164 Mon Sep 17 00:00:00 2001 From: Ralf Habacker Date: Tue, 10 May 2016 16:53:57 +0200 Subject: [PATCH 3/4] On Windows make access to member 'refcount' of struct DBusBabysitter thread save. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=95191 --- dbus/dbus-internals.h | 1 + dbus/dbus-spawn-win.c | 35 ++++++++++++++++++++++++++++------- dbus/dbus-sysdeps.h | 3 +++ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/dbus/dbus-internals.h b/dbus/dbus-internals.h index 82950a0..7ec77e5 100644 --- a/dbus/dbus-internals.h +++ b/dbus/dbus-internals.h @@ -124,6 +124,7 @@ static void _dbus_verbose(const char * x,...) {;} # define _dbus_is_verbose() FALSE #endif /* !DBUS_ENABLE_VERBOSE_MODE */ +DBUS_PRIVATE_EXPORT void _dbus_trace_ref (const char *obj_name, void *obj, int old_refcount, diff --git a/dbus/dbus-spawn-win.c b/dbus/dbus-spawn-win.c index 964888f..7a9d454 100644 --- a/dbus/dbus-spawn-win.c +++ b/dbus/dbus-spawn-win.c @@ -60,7 +60,7 @@ */ struct DBusBabysitter { - int refcount; + DBusAtomic refcount; HANDLE start_sync_event; #ifdef DBUS_ENABLE_EMBEDDED_TESTS @@ -89,16 +89,33 @@ struct DBusBabysitter int child_status; }; +static void +_dbus_babysitter_trace_ref (DBusBabysitter *sitter, + int old_refcount, + int new_refcount, + const char *why) +{ +#ifdef DBUS_ENABLE_VERBOSE_MODE + static int enabled = -1; + + _dbus_trace_ref ("DBusBabysitter", sitter, old_refcount, new_refcount, why, + "DBUS_BABYSITTER_TRACE", &enabled); +#endif +} + static DBusBabysitter* _dbus_babysitter_new (void) { DBusBabysitter *sitter; + dbus_int32_t old_refcount; sitter = dbus_new0 (DBusBabysitter, 1); if (sitter == NULL) return NULL; - sitter->refcount = 1; + old_refcount = _dbus_atomic_inc (&sitter->refcount); + + _dbus_babysitter_trace_ref (sitter, old_refcount, old_refcount+1, __FUNCTION__); sitter->start_sync_event = CreateEvent (NULL, FALSE, FALSE, NULL); if (sitter->start_sync_event == NULL) @@ -146,11 +163,13 @@ _dbus_babysitter_new (void) DBusBabysitter * _dbus_babysitter_ref (DBusBabysitter *sitter) { + dbus_int32_t old_refcount; PING(); _dbus_assert (sitter != NULL); - _dbus_assert (sitter->refcount > 0); - sitter->refcount += 1; + old_refcount = _dbus_atomic_inc (&sitter->refcount); + _dbus_assert (old_refcount > 0); + _dbus_babysitter_trace_ref (sitter, old_refcount, old_refcount+1, __FUNCTION__); return sitter; } @@ -185,14 +204,16 @@ void _dbus_babysitter_unref (DBusBabysitter *sitter) { int i; + dbus_int32_t old_refcount; PING(); _dbus_assert (sitter != NULL); - _dbus_assert (sitter->refcount > 0); - sitter->refcount -= 1; + old_refcount = _dbus_atomic_dec (&sitter->refcount); + _dbus_assert (old_refcount > 0); + _dbus_babysitter_trace_ref (sitter, old_refcount, old_refcount-1, __FUNCTION__); - if (sitter->refcount == 0) + if (old_refcount == 1) { close_socket_to_babysitter (sitter); diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index a6bc978..3659dd4 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -296,8 +296,11 @@ struct DBusAtomic # undef DBUS_HAVE_ATOMIC_INT #endif +DBUS_PRIVATE_EXPORT dbus_int32_t _dbus_atomic_inc (DBusAtomic *atomic); +DBUS_PRIVATE_EXPORT dbus_int32_t _dbus_atomic_dec (DBusAtomic *atomic); +DBUS_PRIVATE_EXPORT dbus_int32_t _dbus_atomic_get (DBusAtomic *atomic); #ifdef DBUS_WIN -- 2.6.6