]> git.ipfire.org Git - thirdparty/dbus.git/commitdiff
On Windows make access to member 'refcount' of struct DBusBabysitter thread safe.
authorRalf Habacker <ralf.habacker@freenet.de>
Tue, 10 May 2016 14:53:57 +0000 (16:53 +0200)
committerRalf Habacker <ralf.habacker@freenet.de>
Fri, 13 May 2016 11:39:30 +0000 (13:39 +0200)
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=95191
Reviewed-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
dbus/dbus-internals.h
dbus/dbus-spawn-win.c
dbus/dbus-sysdeps.h

index df8e9643dd9673ac2eff7b17a2c658eb838bb06e..5e6efd81f76e6d2161759fb17ab94cf8b49d1cf9 100644 (file)
@@ -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,
index fa2906386f702e820d5cfa0a04abaf35a64ec7d6..cbd26f1848e66d5d497d686755924049d470c33a 100644 (file)
@@ -60,7 +60,7 @@
  */
 struct DBusBabysitter
   {
-    int refcount;
+    DBusAtomic refcount;
 
     HANDLE start_sync_event;
 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
@@ -91,16 +91,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)
@@ -148,11 +165,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;
 }
@@ -187,14 +206,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);
 
index 2f493b09986edc7fc0c6016121dad09b26a53853..2d152b8c44c9a5903fcd81cd2b8890603da4d469 100644 (file)
@@ -295,8 +295,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