QDBusMetaTypeId: don't cache the result of qMetaTypeId<>() in static ints
authorMarc Mutz <marc.mutz@kdab.com>
Fri, 24 Aug 2012 10:06:03 +0000 (12:06 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Sat, 22 Sep 2012 17:19:37 +0000 (19:19 +0200)
There's not much point in caching the result of qMetaTypeId<>,
because it's already internally memoised.

In addition, the code that initialised the static int caches wasn't
protected against concurrent access under the assumption that the
operations performed were thread-safe.

That is true for most of them, but not for the stores to the static ints,
which race against each other:

   // Thread A               // Thread B
   r1 = initialized /*=false*/
                             r1 = initialized /*=false*/
   r2 = qMetaTypeId<...>();
                             r2 = qMetaTypeId<...>();
   message = r2;             message = r2; // race, ditto for all other ints

To fix, turn the ints into inline functions that just call the respective
qMetaTypeId<>() function.

Change-Id: I5aa80c624872c3867232abc26ffdcde70cd54022
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
12 files changed:
src/dbus/qdbusabstractadaptor.cpp
src/dbus/qdbusintegrator.cpp
src/dbus/qdbusinterface.cpp
src/dbus/qdbusinternalfilters.cpp
src/dbus/qdbusmarshaller.cpp
src/dbus/qdbusmetatype.cpp
src/dbus/qdbusmetatype_p.h
src/dbus/qdbusmisc.cpp
src/dbus/qdbuspendingcall.cpp
src/dbus/qdbusreply.cpp
src/dbus/qdbusxmlgenerator.cpp
src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp

index e8236dd..d17f10f 100644 (file)
@@ -304,7 +304,7 @@ void QDBusAdaptorConnector::relay(QObject *senderObj, int lastSignalIdx, void **
         // qDBusParametersForMethod has already complained
         return;
     if (inputCount + 1 != types.count() ||
-        types.at(inputCount) == QDBusMetaTypeId::message) {
+        types.at(inputCount) == QDBusMetaTypeId::message()) {
         // invalid signal signature
         // qDBusParametersForMethod has not yet complained about this one
         qWarning("QDBusAbstractAdaptor: Cannot relay signal %s::%s",
index ff6927c..aa794d6 100644 (file)
@@ -667,7 +667,7 @@ static int findSlot(const QMetaObject *mo, const QByteArray &name, int flags,
         metaTypes[0] = returnType;
         bool hasMessage = false;
         if (inputCount > 0 &&
-            metaTypes.at(inputCount) == QDBusMetaTypeId::message) {
+            metaTypes.at(inputCount) == QDBusMetaTypeId::message()) {
             // "no input parameters" is allowed as long as the message meta type is there
             hasMessage = true;
             --inputCount;
@@ -738,7 +738,7 @@ QDBusCallDeliveryEvent* QDBusConnectionPrivate::prepareReply(QDBusConnectionPriv
     Q_UNUSED(object);
 
     int n = metaTypes.count() - 1;
-    if (metaTypes[n] == QDBusMetaTypeId::message)
+    if (metaTypes[n] == QDBusMetaTypeId::message())
         --n;
 
     if (msg.arguments().count() < n)
@@ -838,7 +838,7 @@ bool QDBusConnectionPrivate::activateCall(QObject* object, int flags, const QDBu
             // try with no parameters, but with a QDBusMessage
             slotData.slotIdx = ::findSlot(mo, memberName, flags, QString(), slotData.metaTypes);
             if (slotData.metaTypes.count() != 2 ||
-                slotData.metaTypes.at(1) != QDBusMetaTypeId::message) {
+                slotData.metaTypes.at(1) != QDBusMetaTypeId::message()) {
                 // not found
                 // save the negative lookup
                 slotData.slotIdx = -1;
@@ -889,7 +889,7 @@ void QDBusConnectionPrivate::deliverCall(QObject *object, int /*flags*/, const Q
     int pCount = qMin(msg.arguments().count(), metaTypes.count() - 1);
     for (i = 1; i <= pCount; ++i) {
         int id = metaTypes[i];
-        if (id == QDBusMetaTypeId::message)
+        if (id == QDBusMetaTypeId::message())
             break;
 
         const QVariant &arg = msg.arguments().at(i - 1);
@@ -918,7 +918,7 @@ void QDBusConnectionPrivate::deliverCall(QObject *object, int /*flags*/, const Q
         }
     }
 
-    if (metaTypes.count() > i && metaTypes[i] == QDBusMetaTypeId::message) {
+    if (metaTypes.count() > i && metaTypes[i] == QDBusMetaTypeId::message()) {
         params.append(const_cast<void*>(static_cast<const void*>(&msg)));
         ++i;
     }
@@ -1298,7 +1298,7 @@ bool QDBusConnectionPrivate::prepareHook(QDBusConnectionPrivate::SignalHook &hoo
     if (buildSignature) {
         hook.signature.clear();
         for (int i = 1; i < hook.params.count(); ++i)
-            if (hook.params.at(i) != QDBusMetaTypeId::message)
+            if (hook.params.at(i) != QDBusMetaTypeId::message())
                 hook.signature += QLatin1String( QDBusMetaType::typeToSignature( hook.params.at(i) ) );
     }
 
index 47b5b7b..29d0007 100644 (file)
@@ -106,13 +106,13 @@ static void copyArgument(void *to, int id, const QVariant &arg)
             return;
         }
 
-        if (id == QDBusMetaTypeId::variant) {
+        if (id == QDBusMetaTypeId::variant()) {
             *reinterpret_cast<QDBusVariant *>(to) = arg.value<QDBusVariant>();
             return;
-        } else if (id == QDBusMetaTypeId::objectpath) {
+        } else if (id == QDBusMetaTypeId::objectpath()) {
             *reinterpret_cast<QDBusObjectPath *>(to) = arg.value<QDBusObjectPath>();
             return;
-        } else if (id == QDBusMetaTypeId::signature) {
+        } else if (id == QDBusMetaTypeId::signature()) {
             *reinterpret_cast<QDBusSignature *>(to) = arg.value<QDBusSignature>();
             return;
         }
@@ -123,7 +123,7 @@ static void copyArgument(void *to, int id, const QVariant &arg)
     }
 
     // if we got here, it's either an un-dermarshalled type or a mismatch
-    if (arg.userType() != QDBusMetaTypeId::argument) {
+    if (arg.userType() != QDBusMetaTypeId::argument()) {
         // it's a mismatch
         //qWarning?
         return;
index 6b38218..ac6cc08 100644 (file)
@@ -354,7 +354,7 @@ static int writeProperty(QObject *obj, const QByteArray &property_name, QVariant
         return PropertyWriteFailed;
     }
 
-    if (id != QMetaType::QVariant && value.userType() == QDBusMetaTypeId::argument) {
+    if (id != QMetaType::QVariant && value.userType() == QDBusMetaTypeId::argument()) {
         // we have to demarshall before writing
         void *null = 0;
         QVariant other(id, null);
index 00ef7fd..0a91a7c 100644 (file)
@@ -185,7 +185,7 @@ inline bool QDBusMarshaller::append(const QDBusVariant &arg)
 
     QByteArray tmpSignature;
     const char *signature = 0;
-    if (id == QDBusMetaTypeId::argument) {
+    if (id == QDBusMetaTypeId::argument()) {
         // take the signature from the QDBusArgument object we're marshalling
         tmpSignature =
             qvariant_cast<QDBusArgument>(value).currentSignature().toLatin1();
@@ -372,7 +372,7 @@ bool QDBusMarshaller::appendVariantInternal(const QVariant &arg)
     }
 
     // intercept QDBusArgument parameters here
-    if (id == QDBusMetaTypeId::argument) {
+    if (id == QDBusMetaTypeId::argument()) {
         QDBusArgument dbusargument = qvariant_cast<QDBusArgument>(arg);
         QDBusArgumentPrivate *d = QDBusArgumentPrivate::d(dbusargument);
         if (!d->message)
index dade978..d8ee0b3 100644 (file)
@@ -89,14 +89,6 @@ inline static void registerHelper(T * = 0)
         reinterpret_cast<QDBusMetaType::DemarshallFunction>(df));
 }
 
-int QDBusMetaTypeId::message;
-int QDBusMetaTypeId::argument;
-int QDBusMetaTypeId::variant;
-int QDBusMetaTypeId::objectpath;
-int QDBusMetaTypeId::signature;
-int QDBusMetaTypeId::error;
-int QDBusMetaTypeId::unixfd;
-
 void QDBusMetaTypeId::init()
 {
     static volatile bool initialized = false;
@@ -104,16 +96,14 @@ void QDBusMetaTypeId::init()
     // reentrancy is not a problem since everything else is locked on their own
     // set the guard variable at the end
     if (!initialized) {
-#ifndef QT_BOOTSTRAPPED
         // register our types with QtCore (calling qMetaTypeId<T>() does this implicitly)
-        message = qMetaTypeId<QDBusMessage>();
-        error = qMetaTypeId<QDBusError>();
-#endif
-        argument = qMetaTypeId<QDBusArgument>();
-        variant = qMetaTypeId<QDBusVariant>();
-        objectpath = qMetaTypeId<QDBusObjectPath>();
-        signature = qMetaTypeId<QDBusSignature>();
-        unixfd = qMetaTypeId<QDBusUnixFileDescriptor>();
+        (void)message();
+        (void)argument();
+        (void)variant();
+        (void)objectpath();
+        (void)signature();
+        (void)error();
+        (void)unixfd();
 
 #ifndef QDBUS_NO_SPECIALTYPES
         // and register QtCore's with us
@@ -145,11 +135,6 @@ void QDBusMetaTypeId::init()
         qDBusRegisterMetaType<QList<QDBusUnixFileDescriptor> >();
 #endif
 
-#ifdef QT_BOOTSTRAPPED
-        const int lastId = qDBusRegisterMetaType<QList<QDBusUnixFileDescriptor> >();
-        message = lastId + 1;
-        error = lastId + 2;
-#endif
         initialized = true;
     }
 }
@@ -353,16 +338,16 @@ int QDBusMetaType::signatureToType(const char *signature)
         return QVariant::String;
 
     case DBUS_TYPE_OBJECT_PATH:
-        return QDBusMetaTypeId::objectpath;
+        return QDBusMetaTypeId::objectpath();
 
     case DBUS_TYPE_SIGNATURE:
-        return QDBusMetaTypeId::signature;
+        return QDBusMetaTypeId::signature();
 
     case DBUS_TYPE_UNIX_FD:
-        return QDBusMetaTypeId::unixfd;
+        return QDBusMetaTypeId::unixfd();
 
     case DBUS_TYPE_VARIANT:
-        return QDBusMetaTypeId::variant;
+        return QDBusMetaTypeId::variant();
 
     case DBUS_TYPE_ARRAY:       // special case
         switch (signature[1]) {
@@ -444,13 +429,13 @@ const char *QDBusMetaType::typeToSignature(int type)
     }
 
     QDBusMetaTypeId::init();
-    if (type == QDBusMetaTypeId::variant)
+    if (type == QDBusMetaTypeId::variant())
         return DBUS_TYPE_VARIANT_AS_STRING;
-    else if (type == QDBusMetaTypeId::objectpath)
+    else if (type == QDBusMetaTypeId::objectpath())
         return DBUS_TYPE_OBJECT_PATH_AS_STRING;
-    else if (type == QDBusMetaTypeId::signature)
+    else if (type == QDBusMetaTypeId::signature())
         return DBUS_TYPE_SIGNATURE_AS_STRING;
-    else if (type == QDBusMetaTypeId::unixfd)
+    else if (type == QDBusMetaTypeId::unixfd())
         return DBUS_TYPE_UNIX_FD_AS_STRING;
 
     // try the database
index 8239657..8814408 100644 (file)
 
 #include <qdbusmetatype.h>
 
+#include <qdbusmessage.h>
+#include <qdbusargument.h>
+#include <qdbusextratypes.h>
+#include <qdbuserror.h>
+#include <qdbusunixfiledescriptor.h>
+
 QT_BEGIN_NAMESPACE
 
 struct QDBusMetaTypeId
 {
-    static int message;         // QDBusMessage
-    static int argument;        // QDBusArgument
-    static int variant;         // QDBusVariant
-    static int objectpath;      // QDBusObjectPath
-    static int signature;       // QDBusSignature
-    static int error;           // QDBusError
-    static int unixfd;          // QDBusUnixFileDescriptor
+    static int message();         // QDBusMessage
+    static int argument();        // QDBusArgument
+    static int variant();         // QDBusVariant
+    static int objectpath();      // QDBusObjectPath
+    static int signature();       // QDBusSignature
+    static int error();           // QDBusError
+    static int unixfd();          // QDBusUnixFileDescriptor
 
     static void init();
 };
 
+inline int QDBusMetaTypeId::message()
+#ifdef QT_BOOTSTRAPPED
+{ return qDBusRegisterMetaType<QList<QDBusUnixFileDescriptor> >() + 1; }
+#else
+{ return qMetaTypeId<QDBusMessage>(); }
+#endif
+
+inline int QDBusMetaTypeId::argument()
+{ return qMetaTypeId<QDBusArgument>(); }
+
+inline int QDBusMetaTypeId::variant()
+{ return qMetaTypeId<QDBusVariant>(); }
+
+inline int QDBusMetaTypeId::objectpath()
+{ return qMetaTypeId<QDBusObjectPath>(); }
+
+inline int QDBusMetaTypeId::signature()
+{ return qMetaTypeId<QDBusSignature>(); }
+
+inline int QDBusMetaTypeId::error()
+#ifdef QT_BOOTSTRAPPED
+{ return qDBusRegisterMetaType<QList<QDBusUnixFileDescriptor> >() + 2; }
+#else
+{ return qMetaTypeId<QDBusError>(); }
+#endif
+
+inline int QDBusMetaTypeId::unixfd()
+{ return qMetaTypeId<QDBusUnixFileDescriptor>(); }
+
 QT_END_NAMESPACE
 
 #endif
index d92349b..3c8e906 100644 (file)
@@ -186,7 +186,7 @@ int qDBusParametersForMethod(const QList<QByteArray> &parameterTypes, QVector<in
             return -1;
         }
 
-        if (id == QDBusMetaTypeId::message)
+        if (id == QDBusMetaTypeId::message())
             seenMessage = true;
         else if (QDBusMetaType::typeToSignature(id) == 0)
             return -1;
index 9ae68c7..6d318d9 100644 (file)
@@ -172,12 +172,12 @@ bool QDBusPendingCallPrivate::setReplyCallback(QObject *target, const char *memb
     // success
     // construct the expected signature
     int count = metaTypes.count() - 1;
-    if (count == 1 && metaTypes.at(1) == QDBusMetaTypeId::message) {
+    if (count == 1 && metaTypes.at(1) == QDBusMetaTypeId::message()) {
         // wildcard slot, can receive anything, so don't set the signature
         return true;
     }
 
-    if (metaTypes.at(count) == QDBusMetaTypeId::message)
+    if (metaTypes.at(count) == QDBusMetaTypeId::message())
         --count;
 
     setMetaTypes(count, count ? metaTypes.constData() + 1 : 0);
index 9e3c28a..c044a1f 100644 (file)
@@ -203,7 +203,7 @@ void qDBusReplyFill(const QDBusMessage &reply, QDBusError &error, QVariant &data
     QByteArray receivedSignature;
 
     if (reply.arguments().count() >= 1) {
-        if (reply.arguments().at(0).userType() == QDBusMetaTypeId::argument) {
+        if (reply.arguments().at(0).userType() == QDBusMetaTypeId::argument()) {
             // compare signatures instead
             QDBusArgument arg = qvariant_cast<QDBusArgument>(reply.arguments().at(0));
             receivedSignature = arg.currentSignature().toLatin1();
index 9b888f3..e342d5c 100644 (file)
@@ -172,7 +172,7 @@ static QString generateInterfaceXml(const QMetaObject *mo, int flags, int method
             continue;           // invalid form
         if (isSignal && inputCount + 1 != types.count())
             continue;           // signal with output arguments?
-        if (isSignal && types.at(inputCount) == QDBusMetaTypeId::message)
+        if (isSignal && types.at(inputCount) == QDBusMetaTypeId::message())
             continue;           // signal with QDBusMessage argument?
         if (isSignal && mm.attributes() & QMetaMethod::Cloned)
             continue;           // cloned signal?
@@ -181,7 +181,7 @@ static QString generateInterfaceXml(const QMetaObject *mo, int flags, int method
         bool isScriptable = mm.attributes() & QMetaMethod::Scriptable;
         for (j = 1; j < types.count(); ++j) {
             // input parameter for a slot or output for a signal
-            if (types.at(j) == QDBusMetaTypeId::message) {
+            if (types.at(j) == QDBusMetaTypeId::message()) {
                 isScriptable = true;
                 continue;
             }
index 7383362..370cabe 100644 (file)
@@ -145,13 +145,13 @@ static QString addFunction(const FunctionDef &mm, bool isSignal = false) {
         return QString();           // invalid form
     if (isSignal && inputCount + 1 != types.count())
         return QString();           // signal with output arguments?
-    if (isSignal && types.at(inputCount) == QDBusMetaTypeId::message)
+    if (isSignal && types.at(inputCount) == QDBusMetaTypeId::message())
         return QString();           // signal with QDBusMessage argument?
 
     bool isScriptable = mm.isScriptable;
     for (int j = 1; j < types.count(); ++j) {
         // input parameter for a slot or output for a signal
-        if (types.at(j) == QDBusMetaTypeId::message) {
+        if (types.at(j) == QDBusMetaTypeId::message()) {
             isScriptable = true;
             continue;
         }