QDBusMetaType: Check that Q_GLOBAL_STATIC is not destroyed before using it

Combine the lock and the custom types list into one struct
so that the check code does not have to be duplicated.

Task-number: QTBUG-58732
Change-Id: Ib61d5be3a3cb6465acc5834e5dcbc735fb8b4d8e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
(cherry picked from commit df485fff264265aaaa280d8039aff35a5e9af6fb)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Ievgenii Meshcheriakov 2023-08-08 15:04:20 +02:00 committed by Qt Cherry-pick Bot
parent e03c895be6
commit 7ae5b002dc

View File

@ -97,9 +97,13 @@ void QDBusMetaTypeId::init()
} }
} }
using QDBusCustomTypeHash = QHash<int, QDBusCustomTypeInfo>; struct QDBusCustomTypes
Q_GLOBAL_STATIC(QDBusCustomTypeHash, customTypes) {
Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock) QReadWriteLock lock;
QHash<int, QDBusCustomTypeInfo> hash;
};
Q_GLOBAL_STATIC(QDBusCustomTypes, customTypes)
/*! /*!
\class QDBusMetaType \class QDBusMetaType
@ -180,12 +184,15 @@ void QDBusMetaType::registerMarshallOperators(QMetaType metaType, MarshallFuncti
DemarshallFunction df) DemarshallFunction df)
{ {
int id = metaType.id(); int id = metaType.id();
auto *ct = customTypes(); if (id < 0 || !mf || !df)
if (id < 0 || !mf || !df || !ct)
return; // error! return; // error!
QWriteLocker locker(customTypesLock()); auto *ct = customTypes();
QDBusCustomTypeInfo &info = (*ct)[id]; if (!ct)
return;
QWriteLocker locker(&ct->lock);
QDBusCustomTypeInfo &info = ct->hash[id];
info.marshall = mf; info.marshall = mf;
info.demarshall = df; info.demarshall = df;
} }
@ -198,15 +205,19 @@ void QDBusMetaType::registerMarshallOperators(QMetaType metaType, MarshallFuncti
*/ */
bool QDBusMetaType::marshall(QDBusArgument &arg, QMetaType metaType, const void *data) bool QDBusMetaType::marshall(QDBusArgument &arg, QMetaType metaType, const void *data)
{ {
auto *ct = customTypes();
if (!ct)
return false;
int id = metaType.id(); int id = metaType.id();
QDBusMetaTypeId::init(); QDBusMetaTypeId::init();
MarshallFunction mf; MarshallFunction mf;
{ {
QReadLocker locker(customTypesLock()); QReadLocker locker(&ct->lock);
auto *ct = customTypes();
auto it = ct->constFind(id); auto it = ct->hash.constFind(id);
if (it == ct->cend()) if (it == ct->hash.cend())
return false; // non-existent return false; // non-existent
const QDBusCustomTypeInfo &info = *it; const QDBusCustomTypeInfo &info = *it;
@ -229,15 +240,19 @@ bool QDBusMetaType::marshall(QDBusArgument &arg, QMetaType metaType, const void
*/ */
bool QDBusMetaType::demarshall(const QDBusArgument &arg, QMetaType metaType, void *data) bool QDBusMetaType::demarshall(const QDBusArgument &arg, QMetaType metaType, void *data)
{ {
auto *ct = customTypes();
if (!ct)
return false;
int id = metaType.id(); int id = metaType.id();
QDBusMetaTypeId::init(); QDBusMetaTypeId::init();
DemarshallFunction df; DemarshallFunction df;
{ {
QReadLocker locker(customTypesLock()); QReadLocker locker(&ct->lock);
auto *ct = customTypes();
auto it = ct->constFind(id); auto it = ct->hash.constFind(id);
if (it == ct->cend()) if (it == ct->hash.cend())
return false; // non-existent return false; // non-existent
const QDBusCustomTypeInfo &info = *it; const QDBusCustomTypeInfo &info = *it;
@ -355,8 +370,11 @@ QMetaType QDBusMetaType::signatureToMetaType(const char *signature)
void QDBusMetaType::registerCustomType(QMetaType type, const QByteArray &signature) void QDBusMetaType::registerCustomType(QMetaType type, const QByteArray &signature)
{ {
auto *ct = customTypes(); auto *ct = customTypes();
QWriteLocker locker(customTypesLock()); if (!ct)
auto &info = (*ct)[type.id()]; return;
QWriteLocker locker(&ct->lock);
auto &info = ct->hash[type.id()];
info.signature = signature; info.signature = signature;
// note how marshall/demarshall are not set, the type is never used at runtime // note how marshall/demarshall are not set, the type is never used at runtime
} }
@ -428,10 +446,13 @@ const char *QDBusMetaType::typeToSignature(QMetaType type)
// try the database // try the database
auto *ct = customTypes(); auto *ct = customTypes();
if (!ct)
return nullptr;
{ {
QReadLocker locker(customTypesLock()); QReadLocker locker(&ct->lock);
auto it = ct->constFind(type.id()); auto it = ct->hash.constFind(type.id());
if (it == ct->end()) if (it == ct->hash.end())
return nullptr; return nullptr;
const QDBusCustomTypeInfo &info = *it; const QDBusCustomTypeInfo &info = *it;
@ -451,8 +472,8 @@ const char *QDBusMetaType::typeToSignature(QMetaType type)
QByteArray signature = QDBusArgumentPrivate::createSignature(type.id()); QByteArray signature = QDBusArgumentPrivate::createSignature(type.id());
// re-acquire lock // re-acquire lock
QWriteLocker locker(customTypesLock()); QWriteLocker locker(&ct->lock);
info = &(*ct)[type.id()]; info = &ct->hash[type.id()];
info->signature = signature; info->signature = signature;
} }
return info->signature; return info->signature;