diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2013-10-14 17:46:57 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2013-10-14 18:00:54 +0200 |
commit | 0f1357200ee710e84389e927859eac75d24323d3 (patch) | |
tree | 56727d0464b52ad9e31c6831964ae772c32bc12f /sd | |
parent | e202ea3ab830f64b1305b6a6031a807a2c12ebdc (diff) |
D-Bus is not thread safe
...so it could happen that both the main thread at
> internal_bus_get
> dbus_bus_get_private
> avahi_dbus_bus_get
> avahi_client_new
> sd::AvahiNetworkService::setup
> sd::DiscoveryService::DiscoveryService
> sd::DiscoveryService::setup
> SdDLL::RegisterRemotes
[...]
as well as the thread
> internal_bus_get
> dbus_bus_get
> dbusConnectToNameOnBus
> sd::BluetoothServer::run
> threadFunc
> osl_thread_start_Impl
> start_thread
spawned from the main thread at
> sd::BluetoothServer::setup
> sd::RemoteServer::setup
> SdDLL::RegisterRemotes
[...]
are in D-Bus's internal_bus_get simultaneously (with disastrous consequences,
like SEGV) despite the _DBUS_LOCK(bus) there, unless you previously called
dbus_threads_init_default. (Which the D-Bus documentation makes you believe can
be called from multiple threads, though a look at the implemenation makes it
clear that it really should be called from the main thread before any other
threads are created---which we still don't do; oh my.)
Other places that (indirectly) use D-Bus (tubes/source/file-transfer-helper.c,
vcl/generic/fontmanager/fontconfig.cxx, vcl/unx/gtk/window/gtksalframe.cxx might
need this, too.
Change-Id: I912829c615b46b05a89c07bd044b04f1e5f5e7ba
Diffstat (limited to 'sd')
-rw-r--r-- | sd/source/ui/remotecontrol/AvahiNetworkService.cxx | 10 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/BluetoothServer.cxx | 8 |
2 files changed, 18 insertions, 0 deletions
diff --git a/sd/source/ui/remotecontrol/AvahiNetworkService.cxx b/sd/source/ui/remotecontrol/AvahiNetworkService.cxx index 8fc4eb7216bb..34b94a364c0e 100644 --- a/sd/source/ui/remotecontrol/AvahiNetworkService.cxx +++ b/sd/source/ui/remotecontrol/AvahiNetworkService.cxx @@ -8,6 +8,7 @@ */ #include <time.h> #include <iostream> +#include <new> #include <stdlib.h> #include <assert.h> @@ -20,6 +21,8 @@ #include <avahi-common/timeval.h> #include <avahi-common/thread-watch.h> +#include <dbus/dbus.h> + #include <sal/log.hxx> #include "AvahiNetworkService.hxx" @@ -149,6 +152,13 @@ static void client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UN } void AvahiNetworkService::setup() { + // Avahi internally uses D-Bus, which requires the following in order to be + // thread-safe (and we potentially access D-Bus from different threads in + // different places of the code base): + if (!dbus_threads_init_default()) { + throw std::bad_alloc(); + } + int error = 0; avahiService = this; if (!(threaded_poll = avahi_threaded_poll_new())) { diff --git a/sd/source/ui/remotecontrol/BluetoothServer.cxx b/sd/source/ui/remotecontrol/BluetoothServer.cxx index ccdf03f31ac5..1deab3c6668b 100644 --- a/sd/source/ui/remotecontrol/BluetoothServer.cxx +++ b/sd/source/ui/remotecontrol/BluetoothServer.cxx @@ -11,6 +11,7 @@ #include <iostream> #include <iomanip> +#include <new> #include <sal/log.hxx> @@ -586,6 +587,13 @@ BluetoothServer::BluetoothServer( std::vector<Communicator*>* pCommunicators ) mpCommunicators( pCommunicators ) { #ifdef LINUX_BLUETOOTH + // D-Bus requires the following in order to be thread-safe (and we + // potentially access D-Bus from different threads in different places of + // the code base): + if (!dbus_threads_init_default()) { + throw std::bad_alloc(); + } + mpImpl.reset(new BluetoothServer::Impl()); #endif } |