]> git.ipfire.org Git - thirdparty/dbus.git/commitdiff
_dbus_modify_sigpipe: be thread-safe
authorSimon McVittie <smcv@collabora.com>
Fri, 6 Dec 2019 01:54:18 +0000 (02:54 +0100)
committerRalf Habacker <ralf.habacker@freenet.de>
Thu, 12 Dec 2019 08:36:32 +0000 (09:36 +0100)
This needs new atomic primitives: we don't have "set to a value",
and in fact that's a bit annoying to implement in terms of gcc
intrinsics. "Set to 0" and "set to nonzero" are easy, though.

dbus/dbus-connection.c
dbus/dbus-sysdeps-unix.c
dbus/dbus-sysdeps-win.c
dbus/dbus-sysdeps.h

index 0b6a0c6d5dc7914d59781b64f16f9f615419d1e7..159dbe1b6a6a562e9ee86ee7281ed9b4b7cbc3af 100644 (file)
@@ -245,9 +245,9 @@ struct DBusPreallocatedSend
 };
 
 #if HAVE_DECL_MSG_NOSIGNAL
-static dbus_bool_t _dbus_modify_sigpipe = FALSE;
+static DBusAtomic _dbus_modify_sigpipe = { FALSE };
 #else
-static dbus_bool_t _dbus_modify_sigpipe = TRUE;
+static DBusAtomic _dbus_modify_sigpipe = { TRUE };
 #endif
 
 /**
@@ -1328,7 +1328,7 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
   if (objects == NULL)
     goto error;
   
-  if (_dbus_modify_sigpipe)
+  if (_dbus_atomic_get (&_dbus_modify_sigpipe) != 0)
     _dbus_disable_sigpipe ();
 
   /* initialized to 0: use atomic op to avoid mixing atomic and non-atomic */
@@ -6115,8 +6115,11 @@ dbus_connection_get_data (DBusConnection   *connection,
  */
 void
 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
-{  
-  _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
+{
+  if (will_modify_sigpipe)
+    _dbus_atomic_set_nonzero (&_dbus_modify_sigpipe);
+  else
+    _dbus_atomic_set_zero (&_dbus_modify_sigpipe);
 }
 
 /**
index 1eb54bd4930516bac6dac012b212604b9fdcdfbe..c91c05ef4933025a3255b1dc88480f7a94022824 100644 (file)
@@ -3071,6 +3071,42 @@ _dbus_atomic_get (DBusAtomic *atomic)
 #endif
 }
 
+/**
+ * Atomically set the value of an integer to 0.
+ *
+ * @param atomic pointer to the integer to set
+ */
+void
+_dbus_atomic_set_zero (DBusAtomic *atomic)
+{
+#if DBUS_USE_SYNC
+  /* Atomic version of "*atomic &= 0; return *atomic" */
+  __sync_and_and_fetch (&atomic->value, 0);
+#else
+  pthread_mutex_lock (&atomic_mutex);
+  atomic->value = 0;
+  pthread_mutex_unlock (&atomic_mutex);
+#endif
+}
+
+/**
+ * Atomically set the value of an integer to something nonzero.
+ *
+ * @param atomic pointer to the integer to set
+ */
+void
+_dbus_atomic_set_nonzero (DBusAtomic *atomic)
+{
+#if DBUS_USE_SYNC
+  /* Atomic version of "*atomic |= 1; return *atomic" */
+  __sync_or_and_fetch (&atomic->value, 1);
+#else
+  pthread_mutex_lock (&atomic_mutex);
+  atomic->value = 1;
+  pthread_mutex_unlock (&atomic_mutex);
+#endif
+}
+
 /**
  * Wrapper for poll().
  *
index 46cbfe355773971e3ac08105f7c39a5426911bcf..c5a9d0168a5c003365799423196e1d08a6402c79 100644 (file)
@@ -3298,6 +3298,28 @@ _dbus_atomic_get (DBusAtomic *atomic)
   return atomic->value;
 }
 
+/**
+ * Atomically set the value of an integer to 0.
+ *
+ * @param atomic pointer to the integer to set
+ */
+void
+_dbus_atomic_set_zero (DBusAtomic *atomic)
+{
+  InterlockedExchange (&atomic->value, 0);
+}
+
+/**
+ * Atomically set the value of an integer to something nonzero.
+ *
+ * @param atomic pointer to the integer to set
+ */
+void
+_dbus_atomic_set_nonzero (DBusAtomic *atomic)
+{
+  InterlockedExchange (&atomic->value, 1);
+}
+
 /**
  * Called when the bus daemon is signaled to reload its configuration; any
  * caches should be nuked. Of course any caches that need explicit reload
index 7c4204264a3b3604f31392730181e0658af784ce..60091026a7f6cca4ed69fafccaf6e65479f96613 100644 (file)
@@ -335,6 +335,10 @@ DBUS_PRIVATE_EXPORT
 dbus_int32_t _dbus_atomic_dec (DBusAtomic *atomic);
 DBUS_PRIVATE_EXPORT
 dbus_int32_t _dbus_atomic_get (DBusAtomic *atomic);
+DBUS_PRIVATE_EXPORT
+void         _dbus_atomic_set_zero    (DBusAtomic *atomic);
+DBUS_PRIVATE_EXPORT
+void         _dbus_atomic_set_nonzero (DBusAtomic *atomic);
 
 #ifdef DBUS_WIN