From 51f095e655ce8b4b1d73d0d11817bb839a91c1df Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 17 May 2017 13:07:14 +0200 Subject: Revert "Merge the QDBusMetaType's custom information to QDBusConnectionManager" This reverts commit daeb334039e9dcc01485995f53552749131a06b7. The commit was causing race conditions, and random failures in CI. Task-number: QTBUG-60792 Change-Id: I6e49b733965632a1a268f0e88809794098465ec0 Reviewed-by: Simon Hausmann Reviewed-by: Lars Knoll --- src/dbus/qdbusconnection.cpp | 1 - src/dbus/qdbusconnectionmanager_p.h | 3 +- src/dbus/qdbusintegrator.cpp | 1 + src/dbus/qdbusmetatype.cpp | 185 +++++++++++++++++------------------- src/dbus/qdbusmetatype_p.h | 27 +----- src/dbus/qdbusmisc.cpp | 3 +- 6 files changed, 93 insertions(+), 127 deletions(-) diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index 8fae11c8cd..75c1e92f96 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -190,7 +190,6 @@ void QDBusConnectionManager::run() } } connectionHash.clear(); - customTypes.clear(); // allow deletion from any thread without warning moveToThread(Q_NULLPTR); diff --git a/src/dbus/qdbusconnectionmanager_p.h b/src/dbus/qdbusconnectionmanager_p.h index fd6cd84677..1c7dea811d 100644 --- a/src/dbus/qdbusconnectionmanager_p.h +++ b/src/dbus/qdbusconnectionmanager_p.h @@ -55,14 +55,13 @@ #include #include "qdbusconnection_p.h" -#include "qdbusmetatype_p.h" #include "private/qthread_p.h" #ifndef QT_NO_DBUS QT_BEGIN_NAMESPACE -class QDBusConnectionManager : public QDaemonThread, public QDBusMetaTypeId +class QDBusConnectionManager : public QDaemonThread { Q_OBJECT struct ConnectionRequestData; diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index e1e588b850..16cd021d0d 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1039,6 +1039,7 @@ QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p) qdbusThreadDebug = qdbusDefaultThreadDebug; #endif + QDBusMetaTypeId::init(); connect(this, &QDBusConnectionPrivate::dispatchStatusChanged, this, &QDBusConnectionPrivate::doDispatch, Qt::QueuedConnection); connect(this, &QDBusConnectionPrivate::spyHooksFinished, diff --git a/src/dbus/qdbusmetatype.cpp b/src/dbus/qdbusmetatype.cpp index 9ab3c345bb..fb2b407997 100644 --- a/src/dbus/qdbusmetatype.cpp +++ b/src/dbus/qdbusmetatype.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtDBus module of the Qt Toolkit. @@ -40,15 +39,19 @@ #include "qdbusmetatype.h" #include "qdbusmetatype_p.h" -#include "qdbus_symbols_p.h" #include +#include "qdbus_symbols_p.h" + +#include +#include +#include +#include #include "qdbusargument_p.h" #include "qdbusutil_p.h" #include "qdbusunixfiledescriptor.h" #ifndef QT_BOOTSTRAPPED -#include "qdbusconnectionmanager_p.h" #include "qdbusmessage.h" #endif @@ -61,72 +64,82 @@ QT_BEGIN_NAMESPACE -static void registerMarshallOperatorsNoLock(QVector &ct, int id, - QDBusMetaType::MarshallFunction mf, - QDBusMetaType::DemarshallFunction df); +class QDBusCustomTypeInfo +{ +public: + QDBusCustomTypeInfo() : signature(), marshall(0), demarshall(0) + { } + + // Suggestion: + // change 'signature' to char* and make QDBusCustomTypeInfo a Movable type + QByteArray signature; + QDBusMetaType::MarshallFunction marshall; + QDBusMetaType::DemarshallFunction demarshall; +}; template -inline static void registerHelper(QVector &ct) +inline static void registerHelper(T * = 0) { void (*mf)(QDBusArgument &, const T *) = qDBusMarshallHelper; void (*df)(const QDBusArgument &, T *) = qDBusDemarshallHelper; - registerMarshallOperatorsNoLock(ct, qMetaTypeId(), + QDBusMetaType::registerMarshallOperators(qMetaTypeId(), reinterpret_cast(mf), reinterpret_cast(df)); } -QDBusMetaTypeId *QDBusMetaTypeId::instance() +void QDBusMetaTypeId::init() { -#ifdef QT_BOOTSTRAPPED - static QDBusMetaTypeId self; - return &self; -#else - return QDBusConnectionManager::instance(); -#endif -} - -QDBusMetaTypeId::QDBusMetaTypeId() -{ - // register our types with Qt Core (calling qMetaTypeId() does this implicitly) - (void)message(); - (void)argument(); - (void)variant(); - (void)objectpath(); - (void)signature(); - (void)error(); - (void)unixfd(); + static QBasicAtomicInt initialized = Q_BASIC_ATOMIC_INITIALIZER(false); + + // reentrancy is not a problem since everything else is locked on their own + // set the guard variable at the end + if (!initialized.load()) { + // register our types with Qt Core (calling qMetaTypeId() does this implicitly) + (void)message(); + (void)argument(); + (void)variant(); + (void)objectpath(); + (void)signature(); + (void)error(); + (void)unixfd(); #ifndef QDBUS_NO_SPECIALTYPES - // and register Qt Core's with us - registerHelper(customTypes); - registerHelper(customTypes); - registerHelper(customTypes); - registerHelper(customTypes); - registerHelper(customTypes); - registerHelper(customTypes); - registerHelper(customTypes); - registerHelper(customTypes); - registerHelper(customTypes); - registerHelper(customTypes); - registerHelper(customTypes); - registerHelper(customTypes); - registerHelper(customTypes); - registerHelper(customTypes); - - registerHelper >(customTypes); - registerHelper >(customTypes); - registerHelper >(customTypes); - registerHelper >(customTypes); - registerHelper >(customTypes); - registerHelper >(customTypes); - registerHelper >(customTypes); - registerHelper >(customTypes); - registerHelper >(customTypes); - registerHelper >(customTypes); - registerHelper >(customTypes); + // and register Qt Core's with us + registerHelper(); + registerHelper(); + registerHelper(); + registerHelper(); + registerHelper(); + registerHelper(); + registerHelper(); + registerHelper(); + registerHelper(); + registerHelper(); + registerHelper(); + registerHelper(); + registerHelper(); + registerHelper(); + + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); + qDBusRegisterMetaType >(); #endif + + initialized.store(true); + } } +Q_GLOBAL_STATIC(QVector, customTypes) +Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock) + /*! \class QDBusMetaType \inmodule QtDBus @@ -204,22 +217,14 @@ void QDBusMetaType::registerMarshallOperators(int id, MarshallFunction mf, DemarshallFunction df) { QByteArray var; - QDBusMetaTypeId *mgr = QDBusMetaTypeId::instance(); - if (id < 0 || !mf || !df || !mgr) + QVector *ct = customTypes(); + if (id < 0 || !mf || !df || !ct) return; // error! - QWriteLocker locker(&mgr->customTypesLock); - QVector &ct = mgr->customTypes; - registerMarshallOperatorsNoLock(ct, id, mf, df); -} - -static void registerMarshallOperatorsNoLock(QVector &ct, int id, - QDBusMetaType::MarshallFunction mf, - QDBusMetaType::DemarshallFunction df) -{ - if (id >= ct.size()) - ct.resize(id + 1); - QDBusCustomTypeInfo &info = ct[id]; + QWriteLocker locker(customTypesLock()); + if (id >= ct->size()) + ct->resize(id + 1); + QDBusCustomTypeInfo &info = (*ct)[id]; info.marshall = mf; info.demarshall = df; } @@ -236,16 +241,12 @@ bool QDBusMetaType::marshall(QDBusArgument &arg, int id, const void *data) MarshallFunction mf; { - const QDBusMetaTypeId *mgr = QDBusMetaTypeId::instance(); - if (!mgr) - return false; // shutting down - - QReadLocker locker(&mgr->customTypesLock); - const QVector &ct = mgr->customTypes; - if (id >= ct.size()) + QReadLocker locker(customTypesLock()); + QVector *ct = customTypes(); + if (id >= ct->size()) return false; // non-existent - const QDBusCustomTypeInfo &info = ct.at(id); + const QDBusCustomTypeInfo &info = (*ct).at(id); if (!info.marshall) { mf = 0; // make gcc happy return false; @@ -269,16 +270,12 @@ bool QDBusMetaType::demarshall(const QDBusArgument &arg, int id, void *data) DemarshallFunction df; { - const QDBusMetaTypeId *mgr = QDBusMetaTypeId::instance(); - if (!mgr) - return false; // shutting down - - QReadLocker locker(&mgr->customTypesLock); - const QVector &ct = mgr->customTypes; - if (id >= ct.size()) + QReadLocker locker(customTypesLock()); + QVector *ct = customTypes(); + if (id >= ct->size()) return false; // non-existent - const QDBusCustomTypeInfo &info = ct.at(id); + const QDBusCustomTypeInfo &info = (*ct).at(id); if (!info.demarshall) { df = 0; // make gcc happy return false; @@ -437,11 +434,7 @@ const char *QDBusMetaType::typeToSignature(int type) DBUS_TYPE_BYTE_AS_STRING; // ay } - // try the database - QDBusMetaTypeId *mgr = QDBusMetaTypeId::instance(); - if (!mgr) - return Q_NULLPTR; // shutting down - + QDBusMetaTypeId::init(); if (type == QDBusMetaTypeId::variant()) return DBUS_TYPE_VARIANT_AS_STRING; else if (type == QDBusMetaTypeId::objectpath()) @@ -451,13 +444,14 @@ const char *QDBusMetaType::typeToSignature(int type) else if (type == QDBusMetaTypeId::unixfd()) return DBUS_TYPE_UNIX_FD_AS_STRING; + // try the database + QVector *ct = customTypes(); { - QReadLocker locker(&mgr->customTypesLock); - const QVector &ct = mgr->customTypes; - if (type >= ct.size()) + QReadLocker locker(customTypesLock()); + if (type >= ct->size()) return 0; // type not registered with us - const QDBusCustomTypeInfo &info = ct.at(type); + const QDBusCustomTypeInfo &info = (*ct).at(type); if (!info.signature.isNull()) return info.signature; @@ -474,9 +468,8 @@ const char *QDBusMetaType::typeToSignature(int type) QByteArray signature = QDBusArgumentPrivate::createSignature(type); // re-acquire lock - QWriteLocker locker(&mgr->customTypesLock); - QVector &ct = mgr->customTypes; - info = &ct[type]; + QWriteLocker locker(customTypesLock()); + info = &(*ct)[type]; info->signature = signature; } return info->signature; diff --git a/src/dbus/qdbusmetatype_p.h b/src/dbus/qdbusmetatype_p.h index 1f7e61318a..1aa11552df 100644 --- a/src/dbus/qdbusmetatype_p.h +++ b/src/dbus/qdbusmetatype_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtDBus module of the Qt Toolkit. @@ -61,27 +60,10 @@ #include #include -#include -#include -#include - #ifndef QT_NO_DBUS QT_BEGIN_NAMESPACE -class QDBusCustomTypeInfo -{ -public: - QDBusCustomTypeInfo() : signature(), marshall(0), demarshall(0) - { } - - // Suggestion: - // change 'signature' to char* and make QDBusCustomTypeInfo a Movable type - QByteArray signature; - QDBusMetaType::MarshallFunction marshall; - QDBusMetaType::DemarshallFunction demarshall; -}; - struct QDBusMetaTypeId { static int message(); // QDBusMessage @@ -92,14 +74,7 @@ struct QDBusMetaTypeId static int error(); // QDBusError static int unixfd(); // QDBusUnixFileDescriptor - static void init() { instance(); } - static QDBusMetaTypeId *instance(); - - mutable QReadWriteLock customTypesLock; - QVector customTypes; - -protected: - QDBusMetaTypeId(); + static void init(); }; inline int QDBusMetaTypeId::message() diff --git a/src/dbus/qdbusmisc.cpp b/src/dbus/qdbusmisc.cpp index 01436da481..930c3bd2da 100644 --- a/src/dbus/qdbusmisc.cpp +++ b/src/dbus/qdbusmisc.cpp @@ -144,9 +144,8 @@ int qDBusParametersForMethod(const QMetaMethod &mm, QVector &metaTypes, QSt int qDBusParametersForMethod(const QList ¶meterTypes, QVector& metaTypes, QString &errorMsg) { + QDBusMetaTypeId::init(); metaTypes.clear(); - if (!QDBusMetaTypeId::instance()) - return -1; metaTypes.append(0); // return type int inputCount = 0; -- cgit v1.2.3