[glibmm/glibmm-2-62] Gio::DBus::Connection: Make the wrap() function thread-safe
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glibmm/glibmm-2-62] Gio::DBus::Connection: Make the wrap() function thread-safe
- Date: Tue, 22 Oct 2019 11:12:20 +0000 (UTC)
commit 786f01b59a7a13060d958b426dcaf52e17a273e9
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date: Tue Oct 22 13:10:03 2019 +0200
Gio::DBus::Connection: Make the wrap() function thread-safe
Add a std::mutex that guarantees that two threads don't create C++
wrappers for the same GDBusConnection instance.
Fixes #56
gio/src/dbusconnection.ccg | 34 +++++++++++++++++++++++++++++++++-
gio/src/dbusconnection.hg | 1 +
2 files changed, 34 insertions(+), 1 deletion(-)
---
diff --git a/gio/src/dbusconnection.ccg b/gio/src/dbusconnection.ccg
index 6199e855..de813fa0 100644
--- a/gio/src/dbusconnection.ccg
+++ b/gio/src/dbusconnection.ccg
@@ -24,6 +24,7 @@
#include <giomm/menumodel.h>
#include <giomm/unixfdlist.h>
#include "slot_async.h"
+#include <mutex>
namespace
{
@@ -84,7 +85,16 @@ DBusConnection_Message_Filter_giomm_callback_destroy(void* data)
}
} // extern "C"
-}
+
+// Glib::wrap(GDBusConnection* object, bool take_copy) must be protected by a
+// mutex while a C++ wrapper is being constructed. The same GDBusConnection
+// instance can be used in more than one thread. The wrap() function can be
+// called simultaneously in different threads for the same GDBusConnection
+// instance before it has been given a C++ wrapper.
+// https://gitlab.gnome.org/GNOME/glibmm/issues/56
+std::mutex wrap_mutex;
+
+} // anonymous namespace
namespace Gio
{
@@ -722,3 +732,25 @@ Connection::register_subtree(
} // namespace DBus
} // namespace Gio
+
+namespace Glib
+{
+
+Glib::RefPtr<Gio::DBus::Connection> wrap(GDBusConnection* object, bool take_copy)
+{
+ Glib::ObjectBase* pCppObject = nullptr;
+ if (!ObjectBase::_get_current_wrapper((GObject*)object))
+ {
+ // 'object' does not yet have a C++ wrapper. Construction of the C++ wrapper
+ // must be thread-safe. See comments at the definition of wrap_mutex.
+ std::lock_guard<std::mutex> lock(wrap_mutex);
+ pCppObject = Glib::wrap_auto((GObject*)object, take_copy);
+ }
+ else
+ pCppObject = Glib::wrap_auto((GObject*)object, take_copy);
+
+ return Glib::RefPtr<Gio::DBus::Connection>(dynamic_cast<Gio::DBus::Connection*>(pCppObject));
+ //We use dynamic_cast<> in case of multiple inheritance.
+}
+
+} // namespace Glib
diff --git a/gio/src/dbusconnection.hg b/gio/src/dbusconnection.hg
index 9233e8d9..0986f934 100644
--- a/gio/src/dbusconnection.hg
+++ b/gio/src/dbusconnection.hg
@@ -78,6 +78,7 @@ protected:
_CLASS_GOBJECT(Connection, GDBusConnection, G_DBUS_CONNECTION, Glib::Object, GObject)
_IMPLEMENTS_INTERFACE(Initable)
_IMPLEMENTS_INTERFACE(AsyncInitable)
+ _CUSTOM_WRAP_FUNCTION
protected:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]