From 9333dd84757086c93b95a60e66f891883c36974e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Sep 2010 10:49:59 +0200 Subject: Update the ICC mkspec: keep the stack aligned to 16-byte After discussing with Intel, turns out that ICC defaults to aligning the stack when it needs to (e.g., when issuing aligned operations), but doesn't care otherwise. GCC, on the other hand, expects the stack to always be aligned and will issue instructions without checking. We'll probably add __attribute__((force_align_arg_pointer)) to some functions in our code, but we won't be able to catch everything. Reviewed-By: Bradley T. Hughes --- mkspecs/linux-icc/qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/linux-icc/qmake.conf b/mkspecs/linux-icc/qmake.conf index 3b26f7d..af56a9a 100644 --- a/mkspecs/linux-icc/qmake.conf +++ b/mkspecs/linux-icc/qmake.conf @@ -21,7 +21,7 @@ QMAKE_LEX = flex QMAKE_LEXFLAGS = QMAKE_YACC = yacc QMAKE_YACCFLAGS = -d -QMAKE_CFLAGS = +QMAKE_CFLAGS = -falign-stack=maintain-16-byte QMAKE_CFLAGS_DEPS = -M QMAKE_CFLAGS_WARN_ON = -w1 -Wcheck -wd654,1572,411,873,1125 QMAKE_CFLAGS_WARN_OFF = -w -- cgit v0.12 From a9af4502e50bcbe80ff93fabb2da7f07a1dcf53b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Sep 2010 10:55:52 +0200 Subject: Make the de-inlined isRightToLeft not get called from updateProperties Before Qt 4.7, QString::isRightToLeft was an inline function that called QString::updateProperties(). In Qt 4.7, QString::isRightToLeft was de-inlined and is now called from QString::updateProperties(). According to the Binary Compatibility Guidelines, it's ok to de-inline a function provided that it's ok the old method is called. Under some rare circumstances nowadays, the old method could be called from updateProperties(), which would result in an infinite loop (updateProperties -> isRightToLeft -> updateProperties -> ...) This is usually prevented by -fvisibility-inlines-hidden in GCC (automatic in Qt) and also by -Wl,-Bsymbolic-functions (not automatic, must pass -reduced-relocations to configure). Reviewed-by: Bradley T. Hughes --- src/corelib/tools/qstring.cpp | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 3521b31..5be885b 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -6941,6 +6941,27 @@ QString QString::multiArg(int numArgs, const QString **args) const return result; } +static bool isStringRightToLeft(const ushort *p, const ushort *end) +{ + bool righttoleft = false; + while (p < end) { + switch(QChar::direction(*p)) + { + case QChar::DirL: + goto end; + case QChar::DirR: + case QChar::DirAL: + righttoleft = true; + goto end; + default: + break; + } + ++p; + } + end: + return righttoleft; +} + /*! \internal */ void QString::updateProperties() const @@ -6957,31 +6978,13 @@ void QString::updateProperties() const p++; } - d->righttoleft = isRightToLeft(); + d->righttoleft = isStringRightToLeft(d->data, d->data + d->size); d->clean = true; } bool QString::isRightToLeft() const { - ushort *p = d->data; - const ushort * const end = p + d->size; - bool righttoleft = false; - while (p < end) { - switch(QChar::direction(*p)) - { - case QChar::DirL: - goto end; - case QChar::DirR: - case QChar::DirAL: - righttoleft = true; - goto end; - default: - break; - } - ++p; - } - end: - return righttoleft; + return isStringRightToLeft(d->data, d->data + d->size); } /*! \fn bool QString::isSimpleText() const -- cgit v0.12 From 5120dfec47475dd37f51df4dda9a4ef8494036ab Mon Sep 17 00:00:00 2001 From: Misha Tyutyunik Date: Wed, 22 Sep 2010 10:06:01 +0200 Subject: QNAM: Use QFileNetworkReply for qrc:/ URL schema Resources do not need network access and can be quicker loaded with QFileNetworkReply. Reviewed-by: Markus Goetz --- src/network/access/qfilenetworkreply.cpp | 5 ++++- src/network/access/qnetworkaccessmanager.cpp | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/network/access/qfilenetworkreply.cpp b/src/network/access/qfilenetworkreply.cpp index 4ac9a8c..00bd29e 100644 --- a/src/network/access/qfilenetworkreply.cpp +++ b/src/network/access/qfilenetworkreply.cpp @@ -97,7 +97,10 @@ QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req QString fileName = url.toLocalFile(); if (fileName.isEmpty()) { - fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery); + if (url.scheme() == QLatin1String("qrc")) + fileName = QLatin1Char(':') + url.path(); + else + fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery); } QFileInfo fi(fileName); diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index b35c318..a637474 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -946,10 +946,10 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera // fast path for GET on file:// URLs // Also if the scheme is empty we consider it a file. - // The QNetworkAccessFileBackend will right now only be used - // for PUT or qrc:// + // The QNetworkAccessFileBackend will right now only be used for PUT if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation) && (req.url().scheme() == QLatin1String("file") + || req.url().scheme() == QLatin1String("qrc") || req.url().scheme().isEmpty())) { return new QFileNetworkReply(this, req, op); } -- cgit v0.12 From af50ff6fccf5b8828738d4cd13edb7949100b67b Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 22 Sep 2010 10:31:27 +0200 Subject: XML schema internals: fix memory leak MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch-by: Tobias König Task-number: QTBUG-8948 --- src/xmlpatterns/schema/qxsdtypechecker.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/xmlpatterns/schema/qxsdtypechecker.cpp b/src/xmlpatterns/schema/qxsdtypechecker.cpp index 4bb03f5..217932e 100644 --- a/src/xmlpatterns/schema/qxsdtypechecker.cpp +++ b/src/xmlpatterns/schema/qxsdtypechecker.cpp @@ -171,6 +171,7 @@ XsdTypeChecker::XsdTypeChecker(const XsdSchemaContext::Ptr &context, const QVect XsdTypeChecker::~XsdTypeChecker() { + delete m_reflection; } QString XsdTypeChecker::normalizedValue(const QString &value, const XsdFacet::Hash &facets) -- cgit v0.12 From 56bb732f1628fb23b98a2554348b309f634ca55f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 10 Sep 2010 17:05:05 +0200 Subject: Quick performance optimisation: cache a QString with "org.freedesktop.DBus" Reviewed-By: Robin Burchell Reviewed-By: Ritt Konstantin --- src/dbus/qdbusintegrator.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 3833874..cf6ca28 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -71,6 +71,17 @@ QT_BEGIN_NAMESPACE static bool isDebugging; #define qDBusDebug if (!::isDebugging); else qDebug +Q_GLOBAL_STATIC_WITH_ARGS(const QString, orgFreedesktopDBusString, (QLatin1String(DBUS_SERVICE_DBUS))) + +static inline QString dbusServiceString() +{ return *orgFreedesktopDBusString(); } +static inline QString dbusInterfaceString() +{ + // it's the same string, but just be sure + Q_ASSERT(*orgFreedesktopDBusString() == QLatin1String(DBUS_INTERFACE_DBUS)); + return *orgFreedesktopDBusString(); +} + static inline QDebug operator<<(QDebug dbg, const QThread *th) { dbg.nospace() << "QThread(ptr=" << (void*)th; @@ -1675,10 +1686,9 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError qWarning("QDBusConnectionPrivate::setConnection: Unable to get base service"); } - QString busService = QLatin1String(DBUS_SERVICE_DBUS); - connectSignal(busService, QString(), QString(), QLatin1String("NameAcquired"), QStringList(), QString(), + connectSignal(dbusServiceString(), QString(), QString(), QLatin1String("NameAcquired"), QStringList(), QString(), this, SLOT(registerService(QString))); - connectSignal(busService, QString(), QString(), QLatin1String("NameLost"), QStringList(), QString(), + connectSignal(dbusServiceString(), QString(), QString(), QLatin1String("NameLost"), QStringList(), QString(), this, SLOT(unregisterService(QString))); @@ -2069,8 +2079,7 @@ void QDBusConnectionPrivate::connectSignal(const QString &key, const SignalHook WatchedServicesHash::mapped_type &data = watchedServices[hook.service]; if (++data.refcount == 1) { // we need to watch for this service changing - QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS); - connectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS), + connectSignal(dbusServiceString(), QString(), dbusInterfaceString(), QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(), this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); data.owner = getNameOwnerNoCache(hook.service); @@ -2149,8 +2158,7 @@ QDBusConnectionPrivate::disconnectSignal(SignalHookHash::Iterator &it) if (sit != watchedServices.end()) { if (--sit.value().refcount == 0) { watchedServices.erase(sit); - QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS); - disconnectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS), + disconnectSignal(dbusServiceString(), QString(), dbusInterfaceString(), QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(), this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); } @@ -2272,8 +2280,8 @@ QString QDBusConnectionPrivate::getNameOwner(const QString& serviceName) QString QDBusConnectionPrivate::getNameOwnerNoCache(const QString &serviceName) { - QDBusMessage msg = QDBusMessage::createMethodCall(QLatin1String(DBUS_SERVICE_DBUS), - QLatin1String(DBUS_PATH_DBUS), QLatin1String(DBUS_INTERFACE_DBUS), + QDBusMessage msg = QDBusMessage::createMethodCall(dbusServiceString(), + QLatin1String(DBUS_PATH_DBUS), dbusInterfaceString(), QLatin1String("GetNameOwner")); QDBusMessagePrivate::setParametersValidated(msg, true); msg << serviceName; -- cgit v0.12 From ad1fe7574f36dc54a1a0050308c52fc15e757842 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 10 Sep 2010 17:07:29 +0200 Subject: Pre-populate the watched services hash with org.freedesktop.DBus The D-Bus specification doesn't require GetNameOwner("org.freedesktop.DBus") to return anything in specific, but the reference implementation always returns "org.freedesktop.DBus". The Python D-Bus bindings even require it. So add the same assumption to QtDBus, which saves a round-trip at the application start to ask the server what its own owner is Reviewed-By: Robin Burchell Reviewed-By: Ritt Konstantin --- src/dbus/qdbusconnection_p.h | 3 +++ src/dbus/qdbusintegrator.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 81af2c7..1bd00da 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -160,6 +160,9 @@ public: struct WatchedServiceData { WatchedServiceData() : refcount(0) {} + WatchedServiceData(const QString &owner, int refcount = 0) + : owner(owner), refcount(refcount) + {} QString owner; int refcount; }; diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index cf6ca28..c7b531e 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -973,6 +973,10 @@ QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p) QDBusMetaTypeId::init(); rootNode.flags = 0; + + // prepopulate watchedServices: + // we know that the owner of org.freedesktop.DBus is itself + watchedServices.insert(dbusServiceString(), WatchedServiceData(dbusServiceString(), 1)); } QDBusConnectionPrivate::~QDBusConnectionPrivate() -- cgit v0.12 From 2d3836c44ac0e97b1f7301668f0241a57aff9c4a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 10 Sep 2010 17:12:53 +0200 Subject: Save the D-Bus's base service earlier. It's impossible for it not to be present, so there's no need to test for it. Reviewed-By: Robin Burchell Reviewed-By: Ritt Konstantin --- src/dbus/qdbusintegrator.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index c7b531e..3deb738 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1661,6 +1661,10 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError connection = dbc; mode = ClientMode; + const char *service = q_dbus_bus_get_unique_name(connection); + Q_ASSERT(service); + baseService = QString::fromUtf8(service); + q_dbus_connection_set_exit_on_disconnect(connection, false); q_dbus_connection_set_watch_functions(connection, qDBusAddWatch, qDBusRemoveWatch, qDBusToggleWatch, this, 0); @@ -1671,7 +1675,6 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError // Initialize the match rules // We want all messages that have us as destination // signals don't have destinations, but connectSignal() takes care of them - const char *service = q_dbus_bus_get_unique_name(connection); if (service) { QVarLengthArray filter; filter.append("destination='", 13); @@ -1685,7 +1688,6 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError return; } - baseService = QString::fromUtf8(service); } else { qWarning("QDBusConnectionPrivate::setConnection: Unable to get base service"); } -- cgit v0.12 From e824d627a8702926e81d4d5605f1a372044fbc2c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Sep 2010 15:01:59 +0200 Subject: We don't need to add a match rule to receive messages targetted at us. This wasn't explicit in the D-Bus specification until recently. The reference implementation of the daemon already does it. Task-number: QT-3881 Reviewed-By: Robin Burchell Reviewed-By: Ritt Konstantin --- src/dbus/qdbusintegrator.cpp | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 3deb738..98d6a32 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1673,24 +1673,6 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError q_dbus_connection_set_dispatch_status_function(connection, qDBusUpdateDispatchStatus, this, 0); // Initialize the match rules - // We want all messages that have us as destination - // signals don't have destinations, but connectSignal() takes care of them - if (service) { - QVarLengthArray filter; - filter.append("destination='", 13); - filter.append(service, qstrlen(service)); - filter.append("\'\0", 2); - - QDBusErrorInternal error; - q_dbus_bus_add_match(connection, filter.constData(), error); - if (handleError(error)) { - closeConnection(); - return; - } - - } else { - qWarning("QDBusConnectionPrivate::setConnection: Unable to get base service"); - } connectSignal(dbusServiceString(), QString(), QString(), QLatin1String("NameAcquired"), QStringList(), QString(), this, SLOT(registerService(QString))); -- cgit v0.12 From ef2fcad61a316e36383e8b1e437699837f0baeda Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 10 Sep 2010 19:40:32 +0200 Subject: Avoid adding match rules for NameAcquired and NameLost These two signals from org.freedesktop.DBus are delivered no matter what, because they are directed signals. So we don't need to add match rules for it. QDBusConnectionPrivate::connectSignal builds a match rule and adds it, so we shouldn't use it. Task-number: QT-3881 Reviewed-By: Robin Burchell Reviewed-By: Ritt Konstantin --- src/dbus/qdbusintegrator.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 98d6a32..4efea75 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1671,17 +1671,25 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError q_dbus_connection_set_timeout_functions(connection, qDBusAddTimeout, qDBusRemoveTimeout, qDBusToggleTimeout, this, 0); q_dbus_connection_set_dispatch_status_function(connection, qDBusUpdateDispatchStatus, this, 0); - - // Initialize the match rules - - connectSignal(dbusServiceString(), QString(), QString(), QLatin1String("NameAcquired"), QStringList(), QString(), - this, SLOT(registerService(QString))); - connectSignal(dbusServiceString(), QString(), QString(), QLatin1String("NameLost"), QStringList(), QString(), - this, SLOT(unregisterService(QString))); - - q_dbus_connection_add_filter(connection, qDBusSignalFilter, this, 0); + // Initialize the hooks for the NameAcquired and NameLost signals + // we don't use connectSignal here because we don't need the rules to be sent to the bus + // the bus will always send us these two signals + SignalHook hook; + hook.service = dbusServiceString(); + hook.path.clear(); // no matching + hook.obj = this; + hook.params << QMetaType::Void << QVariant::String; // both functions take a QString as parameter and return void + + hook.midx = staticMetaObject.indexOfSlot("registerService(QString)"); + Q_ASSERT(hook.midx != -1); + signalHooks.insert(QLatin1String("NameAcquired:" DBUS_INTERFACE_DBUS), hook); + + hook.midx = staticMetaObject.indexOfSlot("unregisterService(QString)"); + Q_ASSERT(hook.midx != -1); + signalHooks.insert(QLatin1String("NameLost:" DBUS_INTERFACE_DBUS), hook); + qDBusDebug() << this << ": connected successfully"; // schedule a dispatch: -- cgit v0.12 From 42f7c123e95c6d9f1d0ece648f61defa79627ab8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 10 Sep 2010 19:48:45 +0200 Subject: We also don't need to watch for org.freedesktop.DBus changing owners It never does. Task-number: QT-3881 Reviewed-By: Robin Burchell Reviewed-By: Ritt Konstantin --- src/dbus/qdbusintegrator.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 4efea75..31588e7 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -977,6 +977,10 @@ QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p) // prepopulate watchedServices: // we know that the owner of org.freedesktop.DBus is itself watchedServices.insert(dbusServiceString(), WatchedServiceData(dbusServiceString(), 1)); + + // prepopulate matchRefCounts: + // we know that org.freedesktop.DBus will never change owners + matchRefCounts.insert("type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',arg0='org.freedesktop.DBus'", 1); } QDBusConnectionPrivate::~QDBusConnectionPrivate() -- cgit v0.12