diff options
author | Simon McVittie <smcv@collabora.com> | 2019-12-06 02:54:18 +0100 |
---|---|---|
committer | Ralf Habacker <ralf.habacker@freenet.de> | 2019-12-12 09:36:32 +0100 |
commit | bf20f7387381d1bba0a261f6f0a849c0df5d7e1a (patch) | |
tree | 22897bc8aa632c6ea9139f8db81035fb1fd8306b | |
parent | 4e3d6bffe26039d694e44a12d31d9db35e5183c0 (diff) |
_dbus_modify_sigpipe: be thread-safe
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.
-rw-r--r-- | dbus/dbus-connection.c | 13 | ||||
-rw-r--r-- | dbus/dbus-sysdeps-unix.c | 36 | ||||
-rw-r--r-- | dbus/dbus-sysdeps-win.c | 22 | ||||
-rw-r--r-- | dbus/dbus-sysdeps.h | 4 |
4 files changed, 70 insertions, 5 deletions
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 0b6a0c6d..159dbe1b 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -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); } /** diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index 1eb54bd4..c91c05ef 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -3072,6 +3072,42 @@ _dbus_atomic_get (DBusAtomic *atomic) } /** + * 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(). * * @param fds the file descriptors to poll diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c index 46cbfe35..c5a9d016 100644 --- a/dbus/dbus-sysdeps-win.c +++ b/dbus/dbus-sysdeps-win.c @@ -3299,6 +3299,28 @@ _dbus_atomic_get (DBusAtomic *atomic) } /** + * 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 * are probably broken, but c'est la vie. diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index 7c420426..60091026 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -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 |