From 208e8e87d338e8956f4dbb7243a7cc5ec6553f13 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Wed, 26 Jan 2011 14:27:35 +0200 Subject: QComboBox popup incorrectly opened in Sym^3 QCombobox popup opens into incorrect position in Sym^3. This is due to that there is a new layout in use, where softkeys are positioned at the bottom. The current implementation just checks if native stacon component is in use and if not, puts the popup to left/right border of the application area (depending on UI direction). Task-number: QTBUG-16886 Reviewed-by: Miikka Heikkinen --- src/gui/widgets/qcombobox.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index 3e5f1b3..dbbf49a 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -2476,10 +2476,18 @@ void QComboBox::showPopup() listRect.setWidth(listRect.height()); //by default popup is centered on screen in landscape listRect.moveCenter(screen.center()); - if (staConTopRect.IsEmpty() && AknLayoutUtils::CbaLocation() != AknLayoutUtils::EAknCbaLocationBottom) { - // landscape without stacon, menu should be at the right - (opt.direction == Qt::LeftToRight) ? listRect.setRight(screen.right()) : - listRect.setLeft(screen.left()); + if (staConTopRect.IsEmpty()) { + TRect cbaRect = TRect(); + AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EControlPane, cbaRect); + AknLayoutUtils::TAknCbaLocation cbaLocation = AknLayoutUtils::CbaLocation(); + switch (cbaLocation) { + case AknLayoutUtils::EAknCbaLocationRight: + listRect.setRight(screen.right()); + break; + case AknLayoutUtils::EAknCbaLocationLeft: + listRect.setLeft(screen.left()); + break; + } } } #endif -- cgit v0.12 From 121e2b39043a4ffc6583f250aebb9a3a746076c1 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 13 Dec 2010 15:38:47 +0100 Subject: Improve timer ID safety by using a serial counter per ID. The high bits of the counter are not used, so we store a serial counter there. This has nothing to do with the serial counter used in nextFreeTimerId, which is there for ABA protection. Reviewed-by: Bradley T. Hughes --- src/corelib/kernel/qabstracteventdispatcher.cpp | 30 ++++++++++++++++++++----- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index e79f87a..cc08f092 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -137,6 +137,12 @@ void QAbstractEventDispatcherPrivate::init() // free list). As an added protection, we use the cell to store an invalid // (negative) value that we can later check for integrity. // +// ABA prevention simply adds a value to 7 of the top 8 bits when resetting +// nextFreeTimerId. +// +// The extra code is the bucket allocation which allows us to start with a +// very small bucket size and grow as needed. +// // (continues below). int QAbstractEventDispatcherPrivate::allocateTimerId() { @@ -164,6 +170,8 @@ int QAbstractEventDispatcherPrivate::allocateTimerId() newTimerId = prepareNewValueWithSerialNumber(timerId, b[at]); } while (!nextFreeTimerId.testAndSetRelaxed(timerId, newTimerId)); + timerId &= TimerIdMask; + timerId |= b[at] & TimerSerialMask; b[at] = -timerId; return timerId; @@ -174,12 +182,13 @@ int QAbstractEventDispatcherPrivate::allocateTimerId() // X[timerId] = nextFreeTimerId; // then we update nextFreeTimerId to the timer we've just released // -// The extra code in allocateTimerId and releaseTimerId are ABA prevention -// and bucket memory. The buckets are simply to make sure we allocate only -// the necessary number of timers. See above. -// // ABA prevention simply adds a value to 7 of the top 8 bits when resetting // nextFreeTimerId. +// +// In addition to that, we update the same 7 bits in each entry in the bucket +// as a counter. That way, a timer ID allocated and released will always be +// returned with a different ID. This reduces the chances of timers being released +// erroneously by application code. void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId) { int which = timerId & TimerIdMask; @@ -187,12 +196,21 @@ void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId) int at = bucketIndex(bucket, which); int *b = timerIds[bucket]; - Q_ASSERT(b[at] == -timerId); +#ifndef QT_NO_DEBUG + // debug code + Q_ASSERT_X(timerId == -b[at], "QAbstractEventDispatcher::releaseTimerId", "Timer ID was not found, fix application"); +#else + if (timerId != -b[at]) { + // release code + qWarning("Timer ID %d was not found, fix application", timerId); + return; + } +#endif int freeId, newTimerId; do { freeId = nextFreeTimerId;//.loadAcquire(); // ### FIXME Proper memory ordering semantics - b[at] = freeId & TimerIdMask; + b[at] = prepareNewValueWithSerialNumber(-b[at], freeId); newTimerId = prepareNewValueWithSerialNumber(freeId, timerId); } while (!nextFreeTimerId.testAndSetRelease(freeId, newTimerId)); -- cgit v0.12 From 861333040c252fa0f53894b604f7cb768c085281 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 26 Jan 2011 14:06:11 +0100 Subject: Check if the interpolators have already been deleted. During application destruction, the order in which static destructors is run is undetermined. So avoid a null-pointer dereference. Task-number: QTBUG-16855 Reviewed-by: Robin Burchell Patch by task reporter --- src/corelib/animation/qvariantanimation.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index 212e85d..c76cb89 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -431,12 +431,17 @@ void QVariantAnimation::registerInterpolator(QVariantAnimation::Interpolator fun { // will override any existing interpolators QInterpolatorVector *interpolators = registeredInterpolators(); + // When built on solaris with GCC, the destructors can be called + // in such an order that we get here with interpolators == NULL, + // to continue causes the app to crash on exit with a SEGV + if (interpolators) { #ifndef QT_NO_THREAD - QMutexLocker locker(QMutexPool::globalInstanceGet(interpolators)); + QMutexLocker locker(QMutexPool::globalInstanceGet(interpolators)); #endif - if (int(interpolationType) >= interpolators->count()) - interpolators->resize(int(interpolationType) + 1); - interpolators->replace(interpolationType, func); + if (int(interpolationType) >= interpolators->count()) + interpolators->resize(int(interpolationType) + 1); + interpolators->replace(interpolationType, func); + } } -- cgit v0.12 From db3d9b67ac543ddfdac649bec2c1287982d50a4e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 20 Dec 2010 19:38:11 +0100 Subject: Change the D-Bus signal filter to return NOT_YET_HANDLED for signals --- src/dbus/qdbusintegrator.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index adc3408..2e7b052 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -558,8 +558,9 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg) switch (amsg.type()) { case QDBusMessage::SignalMessage: handleSignal(amsg); - return true; - break; + // if there are any other filters in this DBusConnection, + // let them see the signal too + return false; case QDBusMessage::MethodCallMessage: handleObjectCall(amsg); return true; -- cgit v0.12 From 7012b6697df8472df5d772394edb0fbf7219da42 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 14 Jan 2011 20:15:37 +0100 Subject: QNAM FTP: switch to binary mode before sending a SIZE command With some servers, SIZE is not allowed in ASCII mode or it may return different sizes. Since we transfer in binary anyway, better get the size in binary too. Reviewed-by: Peter Hartmann --- src/network/access/qnetworkaccessftpbackend.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp index 42d2955..b0303aa 100644 --- a/src/network/access/qnetworkaccessftpbackend.cpp +++ b/src/network/access/qnetworkaccessftpbackend.cpp @@ -307,8 +307,10 @@ void QNetworkAccessFtpBackend::ftpDone() // logged in successfully, send the stat requests (if supported) QString command = url().path(); command.prepend(QLatin1String("%1 ")); - if (supportsSize) + if (supportsSize) { + ftp->rawCommand(QLatin1String("TYPE I")); sizeId = ftp->rawCommand(command.arg(QLatin1String("SIZE"))); // get size + } if (supportsMdtm) mdtmId = ftp->rawCommand(command.arg(QLatin1String("MDTM"))); // get modified time if (!supportsSize && !supportsMdtm) -- cgit v0.12 From b7de076b698a1e0a61c6b1597db860c88dd3ee86 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 21 Jan 2011 23:04:33 +0100 Subject: Fix warning in ODBC driver: passing NULL to non-pointer. Warning was: passing NULL to non-pointer argument 7 of 'SQLRETURN SQLGetDiagRecW(SQLSMALLINT, void*, SQLSMALLINT, SQLWCHAR*, SQLINTEGER*, SQLWCHAR*, SQLSMALLINT, SQLSMALLINT*)' --- src/sql/drivers/odbc/qsql_odbc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index c91aa54..8cff61b 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -223,7 +223,7 @@ static QString qWarnODBCHandle(int handleType, SQLHANDLE handle, int *nativeCode state_, &nativeCode_, 0, - NULL, + 0, &msgLen); if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && msgLen > 0) description_.resize(msgLen+1); @@ -400,7 +400,7 @@ static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool uni // colSize-1: remove 0 termination when there is more data to fetch int rSize = (r == SQL_SUCCESS_WITH_INFO) ? colSize : lengthIndicator/sizeof(SQLTCHAR); fieldVal += fromSQLTCHAR(buf, rSize); - if (lengthIndicator < (unsigned int)colSize*sizeof(SQLTCHAR)) { + if ((unsigned)lengthIndicator < colSize*sizeof(SQLTCHAR)) { // workaround for Drivermanagers that don't return SQL_NO_DATA break; } -- cgit v0.12 From f34e2b62b03e35015b0eaa6b96dc982caf0f230d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 21 Jan 2011 23:05:37 +0100 Subject: Fix warnings in PSQL driver: handle VersionUnknown in switch --- src/sql/drivers/psql/qsql_psql.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index 0a7d5bf..a044c7f 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -1021,6 +1021,9 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from " "pg_namespace where pg_namespace.nspname = '%1') AND ").arg(schema)); break; + case QPSQLDriver::VersionUnknown: + qFatal("PSQL version is unknown"); + break; } i.exec(stmt.arg(tbl)); @@ -1110,6 +1113,9 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from " "pg_namespace where pg_namespace.nspname = '%1')").arg(schema)); break; + case QPSQLDriver::VersionUnknown: + qFatal("PSQL version is unknown"); + break; } QSqlQuery query(createResult()); -- cgit v0.12 From 1d85e1ce92e6df1af97bde7542467f40f7003975 Mon Sep 17 00:00:00 2001 From: Zeno Albisser Date: Thu, 20 Jan 2011 14:54:06 +0100 Subject: Fix: define hotSpot for Gestures on Mac If there is no hotSpot defined for a gesture it cannot be propagated propperly within GraphicsView. Task-number: QTBUG-16618 Reviewed-by: Denis Dzyubenko --- examples/gestures/imagegestures/imagewidget.cpp | 1 + src/gui/kernel/qmacgesturerecognizer_mac.mm | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/examples/gestures/imagegestures/imagewidget.cpp b/examples/gestures/imagegestures/imagewidget.cpp index 12e6216..8bbb965 100644 --- a/examples/gestures/imagegestures/imagewidget.cpp +++ b/examples/gestures/imagegestures/imagewidget.cpp @@ -1,3 +1,4 @@ + /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). diff --git a/src/gui/kernel/qmacgesturerecognizer_mac.mm b/src/gui/kernel/qmacgesturerecognizer_mac.mm index 0e432f3..6a4f0bb 100644 --- a/src/gui/kernel/qmacgesturerecognizer_mac.mm +++ b/src/gui/kernel/qmacgesturerecognizer_mac.mm @@ -69,6 +69,7 @@ QMacSwipeGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *e case QNativeGestureEvent::Swipe: { QSwipeGesture *g = static_cast(gesture); g->setSwipeAngle(ev->angle); + g->setHotSpot(ev->position); return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint; break; } default: @@ -110,6 +111,7 @@ QMacPinchGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *e g->setCenterPoint(g->startCenterPoint()); g->setChangeFlags(QPinchGesture::CenterPointChanged); g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags()); + g->setHotSpot(ev->position); return QGestureRecognizer::MayBeGesture | QGestureRecognizer::ConsumeEventHint; case QNativeGestureEvent::Rotate: { g->setLastScaleFactor(g->scaleFactor()); @@ -117,6 +119,7 @@ QMacPinchGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *e g->setRotationAngle(g->rotationAngle() + ev->percentage); g->setChangeFlags(QPinchGesture::RotationAngleChanged); g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags()); + g->setHotSpot(ev->position); return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint; } case QNativeGestureEvent::Zoom: @@ -125,6 +128,7 @@ QMacPinchGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *e g->setScaleFactor(g->scaleFactor() * (1 + ev->percentage)); g->setChangeFlags(QPinchGesture::ScaleFactorChanged); g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags()); + g->setHotSpot(ev->position); return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint; case QNativeGestureEvent::GestureEnd: return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint; @@ -221,6 +225,7 @@ QMacPanGestureRecognizer::recognize(QGesture *gesture, QObject *target, QEvent * const QPointF posOffset = p - _startPos; g->setLastOffset(g->offset()); g->setOffset(QPointF(posOffset.x(), posOffset.y())); + g->setHotSpot(_startPos); return QGestureRecognizer::TriggerGesture; } } else if (_panTimer.isActive()) { @@ -239,6 +244,7 @@ QMacPanGestureRecognizer::recognize(QGesture *gesture, QObject *target, QEvent * break; // Begin new pan session! _startPos = QCursor::pos(); + g->setHotSpot(_startPos); return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint; } break; } -- cgit v0.12 From bd6c9225328b6042ff14dfddb28e2e1279ba0e46 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 27 Jan 2011 10:01:48 +0100 Subject: Make syncqt not complain about missing header macros. qsharedpointer_impl.h contains class definitions that are also mirrored in qsharedpointer.h (which is there for qdoc3), so we have a macro to stop processing. Task-number: QTBUG-16912 Reviewed-by: Olivier Goffart --- src/corelib/tools/qsharedpointer_impl.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 2404d2a..0337c1f 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -44,7 +44,17 @@ #ifndef QSHAREDPOINTER_H #error Do not include qsharedpointer_impl.h directly #endif + #if 0 +// These macros are duplicated here to make syncqt not complain a about +// this header, as we have a "qt_sync_stop_processing" below, which in turn +// is here because this file contains a template mess and duplicates the +// classes found in qsharedpointer.h +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE +QT_MODULE(Core) +QT_END_NAMESPACE +QT_END_HEADER #pragma qt_sync_stop_processing #endif -- cgit v0.12 From 4ec245a3e75470186557d00b2383af3872a720b0 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 27 Jan 2011 12:40:33 +0200 Subject: No longer replace dash and dot in TARGET with underscore in Symbian There is no fundamental reason to not have dash or dot in binary names in Symbian, so do not replace them with underscore. One thing that doesn't work with a dot in the filename is launching an application via resources, so automatic resource generation is suppressed for applications that have a dot in filename portion of the TARGET value. Task-number: QTBUG-16888 Reviewed-by: axis --- mkspecs/common/symbian/symbian.conf | 9 +-- mkspecs/features/symbian/application_icon.prf | 106 ++++++++++++++------------ qmake/generators/symbian/symbiancommon.cpp | 23 ++---- qmake/generators/symbian/symbiancommon.h | 1 - qmake/generators/symbian/symmake.cpp | 31 ++++++-- 5 files changed, 89 insertions(+), 81 deletions(-) diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index 5619d4f..0bb3a29 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -215,19 +215,14 @@ default_deployment.pkg_prerules += pkg_depends_webkit pkg_depends_qt pkg_platfor DEPLOYMENT += default_deployment default_bin_deployment default_resource_deployment default_reg_deployment defineReplace(symbianRemoveSpecialCharacters) { - # Produce identical string to what SymbianCommonGenerator::removeSpecialCharacters and - # SymbianCommonGenerator::removeEpocSpecialCharacters produce + # Produce identical string to what SymbianCommonGenerator::removeSpecialCharacters fixedStr = $$1 fixedStr = $$replace(fixedStr, /,_) fixedStr = $$replace(fixedStr, \\\\,_) fixedStr = $$replace(fixedStr, " ",_) - symbian-abld|symbian-sbsv2 { - fixedStr = $$replace(fixedStr, -,_) - fixedStr = $$replace(fixedStr, \\.,_) - fixedStr = $$replace(fixedStr, :,_) - } + fixedStr = $$replace(fixedStr, :,_) return ($$fixedStr) } diff --git a/mkspecs/features/symbian/application_icon.prf b/mkspecs/features/symbian/application_icon.prf index 6e1aa8e..b6be89b 100644 --- a/mkspecs/features/symbian/application_icon.prf +++ b/mkspecs/features/symbian/application_icon.prf @@ -11,68 +11,74 @@ contains(CONFIG, no_icon) { !contains(CONFIG, no_icon) { baseTarget = $$symbianRemoveSpecialCharacters($$basename(TARGET)) - symbian-abld|symbian-sbsv2 { - resourceZDir = $$EPOCROOT$$HW_ZDIR$$APP_RESOURCE_DIR - regZDir = $$EPOCROOT$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR + contains(baseTarget, "^.*\\..*$") { + CONFIG += no_icon + ICON = + warning("Symbian resources do not support '.' character in TARGET, skipping resource generation.") } else { - contains(DESTDIR, "/.*") { - resourceZDir = $$DESTDIR - } else:isEmpty(DESTDIR) { - resourceZDir = $$OUT_PWD + symbian-abld|symbian-sbsv2 { + resourceZDir = $$EPOCROOT$$HW_ZDIR$$APP_RESOURCE_DIR + regZDir = $$EPOCROOT$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR } else { - resourceZDir = $$OUT_PWD/$$DESTDIR + contains(DESTDIR, "/.*") { + resourceZDir = $$DESTDIR + } else:isEmpty(DESTDIR) { + resourceZDir = $$OUT_PWD + } else { + resourceZDir = $$OUT_PWD/$$DESTDIR + } + regZDir = $$resourceZDir } - regZDir = $$resourceZDir - } - default_resource_deployment.sources += $$resourceZDir/$${baseTarget}.rsc - default_resource_deployment.path = $$APP_RESOURCE_DIR - default_reg_deployment.sources += $$regZDir/$${baseTarget}_reg.rsc - default_reg_deployment.path = $$REG_RESOURCE_IMPORT_DIR + default_resource_deployment.sources += $$resourceZDir/$${baseTarget}.rsc + default_resource_deployment.path = $$APP_RESOURCE_DIR + default_reg_deployment.sources += $$regZDir/$${baseTarget}_reg.rsc + default_reg_deployment.path = $$REG_RESOURCE_IMPORT_DIR - !isEmpty(ICON) { - !count(ICON, 1) { - ICON = $$first(ICON) - warning("Only first icon specified in ICON variable is used: $$ICON") - } + !isEmpty(ICON) { + !count(ICON, 1) { + ICON = $$first(ICON) + warning("Only first icon specified in ICON variable is used: $$ICON") + } - # Note: symbian-sbsv2 builds can't utilize extra compiler for mifconv, so ICON handling is done in code - !symbian-sbsv2 { - # Absolute path required for shadow builds. - # However, in older Symbian environments abld toolchain can't handle even moderately long - # paths, so don't force absolute there. - !symbian-abld:!contains(ICON, "^(/|\\\\|.:).*"):ICON = $$_PRO_FILE_PWD_/$$ICON + # Note: symbian-sbsv2 builds can't utilize extra compiler for mifconv, so ICON handling is done in code + !symbian-sbsv2 { + # Absolute path required for shadow builds. + # However, in older Symbian environments abld toolchain can't handle even moderately long + # paths, so don't force absolute there. + !symbian-abld:!contains(ICON, "^(/|\\\\|.:).*"):ICON = $$_PRO_FILE_PWD_/$$ICON - #Makefile: requires paths with backslash - ICON_backslashed = $$ICON + #Makefile: requires paths with backslash + ICON_backslashed = $$ICON - symbian-abld { - # ${ZDIR} is defined in Makefile - mifIconZDir = ${ZDIR}$$APP_RESOURCE_DIR - } else { - mifIconZDir = $$resourceZDir - } + symbian-abld { + # ${ZDIR} is defined in Makefile + mifIconZDir = ${ZDIR}$$APP_RESOURCE_DIR + } else { + mifIconZDir = $$resourceZDir + } - # Extra compiler rules for mifconv - mifconv.target = $$mifIconZDir/$${baseTarget}.mif - contains(QMAKE_HOST.os, "Windows") { - ICON_backslashed = $$replace(ICON_backslashed, /, \\) - mifconv.target = $$replace(mifconv.target, /, \\) + # Extra compiler rules for mifconv + mifconv.target = $$mifIconZDir/$${baseTarget}.mif + contains(QMAKE_HOST.os, "Windows") { + ICON_backslashed = $$replace(ICON_backslashed, /, \\) + mifconv.target = $$replace(mifconv.target, /, \\) + } + # Based on: http://www.forum.nokia.com/document/Cpp_Developers_Library + # svg-t icons should always use /c32 depth + mifconv.commands = mifconv $$mifconv.target /c32 $$ICON_backslashed + + mifconv.depends = $$ICON + PRE_TARGETDEPS += $$mifconv.target + QMAKE_EXTRA_TARGETS += mifconv + QMAKE_DISTCLEAN += $$mifconv.target } - # Based on: http://www.forum.nokia.com/document/Cpp_Developers_Library - # svg-t icons should always use /c32 depth - mifconv.commands = mifconv $$mifconv.target /c32 $$ICON_backslashed + # Rules to use generated MIF file from symbian resources + RSS_RULES.number_of_icons = $$size(ICON_backslashed) + RSS_RULES.icon_file = $$APP_RESOURCE_DIR/$${baseTarget}.mif - mifconv.depends = $$ICON - PRE_TARGETDEPS += $$mifconv.target - QMAKE_EXTRA_TARGETS += mifconv - QMAKE_DISTCLEAN += $$mifconv.target + default_resource_deployment.sources += $$resourceZDir/$${baseTarget}.mif } - # Rules to use generated MIF file from symbian resources - RSS_RULES.number_of_icons = $$size(ICON_backslashed) - RSS_RULES.icon_file = $$APP_RESOURCE_DIR/$${baseTarget}.mif - - default_resource_deployment.sources += $$resourceZDir/$${baseTarget}.mif } } diff --git a/qmake/generators/symbian/symbiancommon.cpp b/qmake/generators/symbian/symbiancommon.cpp index 2270c2e..96d7725 100644 --- a/qmake/generators/symbian/symbiancommon.cpp +++ b/qmake/generators/symbian/symbiancommon.cpp @@ -79,11 +79,7 @@ void SymbianCommonGenerator::init() fixedTarget = project->first("TARGET"); fixedTarget = generator->unescapeFilePath(fixedTarget); fixedTarget = removePathSeparators(fixedTarget); - if (project->first("MAKEFILE_GENERATOR") == "SYMBIAN_ABLD" - || project->first("MAKEFILE_GENERATOR") == "SYMBIAN_SBSV2") - removeEpocSpecialCharacters(fixedTarget); - else - removeSpecialCharacters(fixedTarget); + removeSpecialCharacters(fixedTarget); // This should not be empty since the mkspecs are supposed to set it if missing. uid3 = project->first("TARGET.UID3").trimmed(); @@ -131,18 +127,11 @@ bool SymbianCommonGenerator::containsStartWithItem(const QChar &c, const QString void SymbianCommonGenerator::removeSpecialCharacters(QString& str) { // When modifying this method check also symbianRemoveSpecialCharacters in symbian.conf - str.replace(QString("/"), QString("_")); - str.replace(QString("\\"), QString("_")); - str.replace(QString(" "), QString("_")); -} - -void SymbianCommonGenerator::removeEpocSpecialCharacters(QString& str) -{ - // When modifying this method check also symbianRemoveSpecialCharacters in symbian.conf - str.replace(QString("-"), QString("_")); - str.replace(QString(":"), QString("_")); - str.replace(QString("."), QString("_")); - removeSpecialCharacters(str); + QString underscore = QLatin1String("_"); + str.replace(QLatin1String("/"), underscore); + str.replace(QLatin1String("\\"), underscore); + str.replace(QLatin1String(" "), underscore); + str.replace(QLatin1String(":"), underscore); } QString romPath(const QString& path) diff --git a/qmake/generators/symbian/symbiancommon.h b/qmake/generators/symbian/symbiancommon.h index 0b5f53d..5182021 100644 --- a/qmake/generators/symbian/symbiancommon.h +++ b/qmake/generators/symbian/symbiancommon.h @@ -82,7 +82,6 @@ protected: QString removePathSeparators(QString &file); void removeSpecialCharacters(QString& str); - void removeEpocSpecialCharacters(QString& str); void generatePkgFile(const QString &iconFile, bool epocBuild, const SymbianLocalizationList &symbianLocalizationList); diff --git a/qmake/generators/symbian/symmake.cpp b/qmake/generators/symbian/symmake.cpp index a2b567d..4f9f22d 100644 --- a/qmake/generators/symbian/symmake.cpp +++ b/qmake/generators/symbian/symmake.cpp @@ -83,6 +83,8 @@ #define VAR_CFLAGS "QMAKE_CFLAGS" #define VAR_LFLAGS "QMAKE_LFLAGS" +#define DEFINE_REPLACE_REGEXP "[^A-Z0-9_]" + QString SymbianMakefileGenerator::fixPathForMmp(const QString& origPath, const QDir& parentDir) { static QString epocRootStr; @@ -165,11 +167,15 @@ void SymbianMakefileGenerator::writeHeader(QTextStream &t) QString bldinfDefine = shortProFilename; bldinfDefine.append("_"); bldinfDefine.append(generate_uid(project->projectFile())); + bldinfDefine = bldinfDefine.toUpper(); + + // replace anything not alphanumeric with underscore + QRegExp replacementMask(DEFINE_REPLACE_REGEXP); + bldinfDefine.replace(replacementMask, QLatin1String("_")); bldinfDefine.prepend("BLD_INF_"); - removeEpocSpecialCharacters(bldinfDefine); - t << "#define " << bldinfDefine.toUpper() << endl << endl; + t << "#define " << bldinfDefine << endl << endl; } bool SymbianMakefileGenerator::writeMakefile(QTextStream &t) @@ -902,13 +908,17 @@ void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploy const QStringList &subdirs = project->values("SUBDIRS"); foreach(QString item, subdirs) { + bool fromFile = false; QString fixedItem; if (!project->isEmpty(item + ".file")) { fixedItem = project->first(item + ".file"); + fromFile = true; } else if (!project->isEmpty(item + ".subdir")) { fixedItem = project->first(item + ".subdir"); + fromFile = false; } else { fixedItem = item; + fromFile = item.endsWith(Option::pro_ext); } QString condition; @@ -917,9 +927,15 @@ void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploy QFileInfo subdir(fileInfo(fixedItem)); QString relativePath = directory.relativeFilePath(fixedItem); - QString subdirFileName = subdir.completeBaseName(); - QString fullProName = subdir.absoluteFilePath();; + QString fullProName = subdir.absoluteFilePath(); QString bldinfFilename; + QString subdirFileName; + + if (fromFile) { + subdirFileName = subdir.completeBaseName(); + } else { + subdirFileName = subdir.fileName(); + } if (subdir.isDir()) { // Subdir is a regular project @@ -941,7 +957,10 @@ void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploy QString uid = generate_uid(fullProName); QString bldinfDefine = QString("BLD_INF_") + subdirFileName + QString("_") + uid; bldinfDefine = bldinfDefine.toUpper(); - removeEpocSpecialCharacters(bldinfDefine); + + // replace anything not alphanumeric with underscore + QRegExp replacementMask(DEFINE_REPLACE_REGEXP); + bldinfDefine.replace(replacementMask, QLatin1String("_")); if (!condition.isEmpty()) t << "#if defined(" << condition << ")" << endl; @@ -1124,4 +1143,4 @@ QString SymbianMakefileGenerator::generateLocFileTarget(QTextStream& t, const QS } return locFile; -} \ No newline at end of file +} -- cgit v0.12 From 2e72a8b19ea6c674fb4777860dac50faa5d387e6 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 27 Jan 2011 11:49:49 +0100 Subject: Restore Qt 4.6 behaviour: exec() always enters the event loop. In Qt 4.6 as well as 4.7's QCoreApplication and QEventLoop, calling exec() always enters the event loop, even if you had tried to quit()/exit() it before entering, with one exception (noted in the unit tests; this difference has been in Qt since at least Qt 4.2). Add unit tests to ensure all of the three classes have the same behaviour. Decide if we want to match the behaviours in Qt 4.8. Reviewed-by: Bradley T. Hughes --- src/corelib/thread/qthread.cpp | 5 +- .../auto/qcoreapplication/tst_qcoreapplication.cpp | 45 +++++ tests/auto/qeventloop/tst_qeventloop.cpp | 41 ++++- tests/auto/qthread/tst_qthread.cpp | 191 +++++++++++++++------ 4 files changed, 221 insertions(+), 61 deletions(-) diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index f368192..f4bfa5d 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -482,10 +482,7 @@ int QThread::exec() Q_D(QThread); QMutexLocker locker(&d->mutex); d->data->quitNow = false; - if (d->exited) { - d->exited = false; - return d->returnCode; - } + d->exited = false; locker.unlock(); QEventLoop eventLoop; diff --git a/tests/auto/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/qcoreapplication/tst_qcoreapplication.cpp index 95055d1..bc69461 100644 --- a/tests/auto/qcoreapplication/tst_qcoreapplication.cpp +++ b/tests/auto/qcoreapplication/tst_qcoreapplication.cpp @@ -59,6 +59,9 @@ private slots: void applicationPid(); void globalPostedEventsCount(); void processEventsAlwaysSendsPostedEvents(); + void reexec(); + void execAfterExit(); + void eventLoopExecAfterExit(); }; class EventSpy : public QObject @@ -524,5 +527,47 @@ void tst_QCoreApplication::processEventsAlwaysSendsPostedEvents() } while (t.elapsed() < 3000); } +void tst_QCoreApplication::reexec() +{ + int argc = 1; + char *argv[] = { "tst_qcoreapplication" }; + QCoreApplication app(argc, argv); + + // exec once + QMetaObject::invokeMethod(&app, "quit", Qt::QueuedConnection); + QCOMPARE(app.exec(), 0); + + // and again + QMetaObject::invokeMethod(&app, "quit", Qt::QueuedConnection); + QCOMPARE(app.exec(), 0); +} + +void tst_QCoreApplication::execAfterExit() +{ + int argc = 1; + char *argv[] = { "tst_qcoreapplication" }; + QCoreApplication app(argc, argv); + + app.exit(1); + QMetaObject::invokeMethod(&app, "quit", Qt::QueuedConnection); + QCOMPARE(app.exec(), 0); +} + +void tst_QCoreApplication::eventLoopExecAfterExit() +{ + int argc = 1; + char *argv[] = { "tst_qcoreapplication" }; + QCoreApplication app(argc, argv); + + // exec once and exit + QMetaObject::invokeMethod(&app, "quit", Qt::QueuedConnection); + QCOMPARE(app.exec(), 0); + + // and again, but this time using a QEventLoop + QEventLoop loop; + QMetaObject::invokeMethod(&loop, "quit", Qt::QueuedConnection); + QCOMPARE(loop.exec(), 0); +} + QTEST_APPLESS_MAIN(tst_QCoreApplication) #include "tst_qcoreapplication.moc" diff --git a/tests/auto/qeventloop/tst_qeventloop.cpp b/tests/auto/qeventloop/tst_qeventloop.cpp index 7af722f..6860f19 100644 --- a/tests/auto/qeventloop/tst_qeventloop.cpp +++ b/tests/auto/qeventloop/tst_qeventloop.cpp @@ -112,6 +112,10 @@ signals: public: QMutex mutex; QWaitCondition cond; + volatile int result1; + volatile int result2; + MultipleExecThread() : result1(0xdead), result2(0xbeef) {} + void run() { QMutexLocker locker(&mutex); @@ -124,13 +128,13 @@ public: connect(&timer, SIGNAL(timeout()), SLOT(quit()), Qt::DirectConnection); timer.setInterval(1000); timer.start(); - (void) exec(); + result1 = exec(); // this should return immediately, since exit() has been called cond.wakeOne(); cond.wait(&mutex); QEventLoop eventLoop; - (void) eventLoop.exec(); + result2 = eventLoop.exec(); } }; @@ -197,7 +201,9 @@ private slots: void symbianNestedActiveSchedulerLoop(); void processEvents(); void exec(); + void reexec(); void exit(); + void execAfterExit(); void wakeUp(); void quit(); void processEventsExcludeSocket(); @@ -398,7 +404,9 @@ void tst_QEventLoop::exec() } { - // calling exec() after exit()/quit() should return immediately + // calling QEventLoop::exec() after a thread loop has exit()ed should return immediately + // Note: this behaviour differs from QCoreApplication and QEventLoop + // see tst_QCoreApplication::eventLoopExecAfterExit, tst_QEventLoop::reexec MultipleExecThread thread; // start thread and wait for checkpoint @@ -411,6 +419,8 @@ void tst_QEventLoop::exec() thread.cond.wakeOne(); thread.cond.wait(&thread.mutex); QVERIFY(spy.count() > 0); + int v = thread.result1; + QCOMPARE(v, 0); // exec should return immediately spy.clear(); @@ -418,6 +428,8 @@ void tst_QEventLoop::exec() thread.mutex.unlock(); thread.wait(); QCOMPARE(spy.count(), 0); + v = thread.result2; + QCOMPARE(v, -1); } { @@ -462,9 +474,32 @@ void tst_QEventLoop::exec() #endif } +void tst_QEventLoop::reexec() +{ + QEventLoop loop; + + // exec once + QMetaObject::invokeMethod(&loop, "quit", Qt::QueuedConnection); + QCOMPARE(loop.exec(), 0); + + // and again + QMetaObject::invokeMethod(&loop, "quit", Qt::QueuedConnection); + QCOMPARE(loop.exec(), 0); +} + void tst_QEventLoop::exit() { DEPENDS_ON(exec()); } +void tst_QEventLoop::execAfterExit() +{ + QEventLoop loop; + EventLoopExiter obj(&loop); + + QMetaObject::invokeMethod(&obj, "exit", Qt::QueuedConnection); + loop.exit(1); + QCOMPARE(loop.exec(), 0); +} + void tst_QEventLoop::wakeUp() { EventLoopThread thread; diff --git a/tests/auto/qthread/tst_qthread.cpp b/tests/auto/qthread/tst_qthread.cpp index e6bf9ce..c7036e4 100644 --- a/tests/auto/qthread/tst_qthread.cpp +++ b/tests/auto/qthread/tst_qthread.cpp @@ -86,6 +86,7 @@ private slots: void start(); void terminate(); void quit(); + void execAfterQuit(); void wait(); void started(); void finished(); @@ -265,6 +266,34 @@ public: } }; +class ExecAfterQuitThreadHelper: public QObject +{ + Q_OBJECT + QThread *thr; +public: + ExecAfterQuitThreadHelper(QThread *thr) : thr(thr) {} +public slots: + void doIt() { thr->exit(0); } +}; + +class ExecAfterQuitThread: public QThread +{ +public: + int returnValue; + void run() + { + ExecAfterQuitThreadHelper obj(this); + + QMetaObject::invokeMethod(&obj, "doIt", Qt::QueuedConnection); + exit(1); + + // returnValue will be either 0 or 1, depending on which of the two + // above take effect. The correct value is 0, since exit(1) before + // exec() should have no effect + returnValue = exec(); + } +}; + tst_QThread::tst_QThread() { @@ -424,34 +453,52 @@ void tst_QThread::stackSize() void tst_QThread::exit() { - Exit_Thread thread; - thread.object = new Exit_Object; - thread.object->moveToThread(&thread); - thread.code = 42; - thread.result = 0; - QVERIFY(!thread.isFinished()); - QVERIFY(!thread.isRunning()); - QMutexLocker locker(&thread.mutex); - thread.start(); - QVERIFY(thread.isRunning()); - QVERIFY(!thread.isFinished()); - thread.cond.wait(locker.mutex()); - QVERIFY(thread.wait(five_minutes)); - QVERIFY(thread.isFinished()); - QVERIFY(!thread.isRunning()); - QCOMPARE(thread.result, thread.code); - delete thread.object; + { + Exit_Thread thread; + thread.object = new Exit_Object; + thread.object->moveToThread(&thread); + thread.code = 42; + thread.result = 0; + QVERIFY(!thread.isFinished()); + QVERIFY(!thread.isRunning()); - Exit_Thread thread2; - thread2.object = 0; - thread2.code = 53; - thread2.result = 0; - QMutexLocker locker2(&thread2.mutex); - thread2.start(); - thread2.exit(thread2.code); - thread2.cond.wait(locker2.mutex()); - QVERIFY(thread2.wait(five_minutes)); - QCOMPARE(thread2.result, thread2.code); + QMutexLocker locker(&thread.mutex); + thread.start(); + QVERIFY(thread.isRunning()); + QVERIFY(!thread.isFinished()); + // but the thread is not running the event loop yet (the mutex is locked) + + // start the event loop + thread.cond.wait(locker.mutex()); + + // the Exit_Object above will cause the thread to exit + QVERIFY(thread.wait(five_minutes)); + QVERIFY(thread.isFinished()); + QVERIFY(!thread.isRunning()); + QCOMPARE(thread.result, thread.code); + delete thread.object; + } + + { + Exit_Thread thread2; + thread2.object = 0; + thread2.code = 53; + thread2.result = 0; + QMutexLocker locker2(&thread2.mutex); + thread2.start(); + + // the mutex is locked, so the thread has *not* started running the event loop yet + // this will do nothing: + thread2.exit(thread2.code); + + // the thread will now start running + thread2.cond.wait(locker2.mutex()); + + // this will cause it to exit now + thread2.exit(++thread2.code); + QVERIFY(thread2.wait(five_minutes)); + QCOMPARE(thread2.result, thread2.code); + } } void tst_QThread::start() @@ -498,32 +545,59 @@ void tst_QThread::terminate() void tst_QThread::quit() { - Quit_Thread thread; - thread.object = new Quit_Object; - thread.object->moveToThread(&thread); - thread.result = -1; - QVERIFY(!thread.isFinished()); - QVERIFY(!thread.isRunning()); - QMutexLocker locker(&thread.mutex); - thread.start(); - QVERIFY(thread.isRunning()); - QVERIFY(!thread.isFinished()); - thread.cond.wait(locker.mutex()); - QVERIFY(thread.wait(five_minutes)); - QVERIFY(thread.isFinished()); - QVERIFY(!thread.isRunning()); - QCOMPARE(thread.result, 0); - delete thread.object; + // very similar to exit() above + { + Quit_Thread thread; + thread.object = new Quit_Object; + thread.object->moveToThread(&thread); + thread.result = -1; + QVERIFY(!thread.isFinished()); + QVERIFY(!thread.isRunning()); - Quit_Thread thread2; - thread2.object = 0; - thread2.result = -1; - QMutexLocker locker2(&thread2.mutex); - thread2.start(); - thread2.quit(); - thread2.cond.wait(locker2.mutex()); - QVERIFY(thread2.wait(five_minutes)); - QCOMPARE(thread2.result, 0); + // start the thread, but keep the event loop from starting + // (while the mutex is locked) + QMutexLocker locker(&thread.mutex); + thread.start(); + QVERIFY(thread.isRunning()); + QVERIFY(!thread.isFinished()); + + // unlock the mutex and let the event loop run + // the Quit_Object above will cause the thread to quit + thread.cond.wait(locker.mutex()); + QVERIFY(thread.wait(five_minutes)); + QVERIFY(thread.isFinished()); + QVERIFY(!thread.isRunning()); + QCOMPARE(thread.result, 0); + delete thread.object; + } + + { + Quit_Thread thread2; + thread2.object = 0; + thread2.result = -1; + + // start the thread, but keep the event loop from starting + // (while the mutex is locked) + QMutexLocker locker2(&thread2.mutex); + thread2.start(); + thread2.quit(); // does nothing, the event loop is not running! + + // unlock the mutex and let the event loop run + thread2.cond.wait(locker2.mutex()); + + // there's no Quit_Object so it won't quit on its own + thread2.quit(); + QVERIFY(thread2.wait(five_minutes)); + QCOMPARE(thread2.result, 0); + } +} + +void tst_QThread::execAfterQuit() +{ + ExecAfterQuitThread thread; + thread.start(); + QVERIFY(thread.wait()); + QCOMPARE(thread.returnValue, 0); } void tst_QThread::wait() @@ -994,8 +1068,17 @@ void tst_QThread::QTBUG15378_exitAndExec() Thread thread; thread.value = 0; thread.start(); - thread.exit(556); - thread.sem1.release(); //should exit the first loop + thread.exit(42); // will do nothing, this value should not appear + thread.sem1.release(); //should enter the first loop + + Exit_Object *exit_object = new Exit_Object; + exit_object->code = 556; + exit_object->thread = &thread; + QMetaObject::invokeMethod(exit_object, "slot", Qt::QueuedConnection); + exit_object->deleteLater(); + exit_object->moveToThread(&thread); // should exit the first loop + exit_object = 0; + thread.sem2.acquire(); int v = thread.value; QCOMPARE(v, 556); -- cgit v0.12 From e0489b905d6a31c7a904ca2b62a1e60cd12dba4f Mon Sep 17 00:00:00 2001 From: mread Date: Tue, 25 Jan 2011 14:29:41 +0000 Subject: Orientation control implementation for Symbian This used the orientation control QWidget attributes API from maemo5, and provides a simple implementation for Symbian. The essense of the implementation is that the latest setting of one of these QWidget orientation attributes will set the orientation for the whole app. Testing the attributes will return only the last attribute set, it will not return the app orientation state. A new task, QTBUG-16972, has been created to provide a more comprehensive implementation in the future. This may provide a more effective emulation of the maemo5 behaviour, or may incorporate further reaching concepts for QML rotations. Task-number: QTBUG-11785 Reviewed-by: Shane Kearns --- src/corelib/global/qnamespace.h | 13 ++++++++++--- src/gui/kernel/qt_s60_p.h | 2 ++ src/gui/kernel/qwidget.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 4f3a742..e492345 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -511,9 +511,16 @@ public: #if 0 // these values are reserved for Maemo5 - do not re-use them WA_Maemo5NonComposited = 126, WA_Maemo5StackedWindow = 127, - WA_Maemo5PortraitOrientation = 128, - WA_Maemo5LandscapeOrientation = 129, - WA_Maemo5AutoOrientation = 130, +#endif + + WA_LockPortraitOrientation = 128, + WA_LockLandscapeOrientation = 129, + WA_AutoOrientation = 130, + +#if 0 // these values are reserved for Maemo5 - do not re-use them + WA_Maemo5PortraitOrientation = WA_LockPortraitOrientation, + WA_Maemo5LandscapeOrientation = WA_LockLandscapeOrientation, + WA_Maemo5AutoOrientation = WA_AutoOrientation, WA_Maemo5ShowProgressIndicator = 131, #endif diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index fdb35d5..40697bf 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -141,6 +141,7 @@ public: int supportsPremultipliedAlpha : 1; int avkonComponentsSupportTransparency : 1; int menuBeingConstructed : 1; + int orientationSet : 1; QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type static CEikButtonGroupContainer *cba; @@ -295,6 +296,7 @@ inline QS60Data::QS60Data() supportsPremultipliedAlpha(0), avkonComponentsSupportTransparency(0), menuBeingConstructed(0), + orientationSet(0), s60ApplicationFactory(0) #ifdef Q_OS_SYMBIAN ,s60InstalledTrapHandler(0) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 9a76b0a..e542a59 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -124,6 +124,10 @@ #include "qtabwidget.h" // Needed in inTabWidget() #endif // QT_KEYPAD_NAVIGATION +#ifdef Q_WS_S60 +#include +#endif + // widget/widget data creation count //#define QWIDGET_EXTRA_DEBUG //#define ALIEN_DEBUG @@ -10810,6 +10814,42 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) d->registerTouchWindow(); #endif break; + case Qt::WA_LockPortraitOrientation: + case Qt::WA_LockLandscapeOrientation: + case Qt::WA_AutoOrientation: { + const Qt::WidgetAttribute orientations[3] = { + Qt::WA_LockPortraitOrientation, + Qt::WA_LockLandscapeOrientation, + Qt::WA_AutoOrientation + }; + + if (on) { + // We can only have one of these set at a time + for (int i = 0; i < 3; ++i) { + if (orientations[i] != attribute) + setAttribute_internal(orientations[i], false, data, d); + } + } + +#ifdef Q_WS_S60 + CAknAppUiBase* appUi = static_cast(CEikonEnv::Static()->EikAppUi()); + const CAknAppUiBase::TAppUiOrientation s60orientations[] = { + CAknAppUiBase::EAppUiOrientationPortrait, + CAknAppUiBase::EAppUiOrientationLandscape, + CAknAppUiBase::EAppUiOrientationAutomatic + }; + CAknAppUiBase::TAppUiOrientation s60orientation = CAknAppUiBase::EAppUiOrientationUnspecified; + for (int i = 0; i < 3; ++i) { + if (testAttribute(orientations[i])) { + s60orientation = s60orientations[i]; + break; + } + } + QT_TRAP_THROWING(appUi->SetOrientationL(s60orientation)); + S60->orientationSet = true; +#endif + break; + } default: break; } -- cgit v0.12 From ead20f4c1edc2e1c5c39f47bf7c9e56600d6362b Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 27 Jan 2011 16:29:52 +0100 Subject: Fix alignment issue causing crash in QtScript/JavaScriptCore When creating a substring, JSC::UStringImpl required that the base string pointer was 8-byte aligned. However, on platforms where FastMalloc isn't enabled (such as Symbian), it's possible that the system malloc() returns a pointer that is only 4-byte aligned. (On Symbian, this can happen if the argument to malloc() itself isn't a multiple of 8.) Cherry-picked http://trac.webkit.org/changeset/54743 from WebKit trunk, which fixes this issue. (The commit happened shortly after we rebased QtScript/JSC for 4.7, so it applies cleanly to our copy.) Task-number: QTBUG-16828 Reviewed-by: Simon Hausmann --- .../javascriptcore/JavaScriptCore/ChangeLog | 25 +++++ .../JavaScriptCore/runtime/UStringImpl.cpp | 14 +-- .../JavaScriptCore/runtime/UStringImpl.h | 117 ++++++++------------- src/3rdparty/javascriptcore/VERSION | 4 +- 4 files changed, 76 insertions(+), 84 deletions(-) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog b/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog index c2b1155..9cbf0c1 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog +++ b/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog @@ -358,6 +358,31 @@ * wtf/AlwaysInline.h: +2010-02-12 Gavin Barraclough + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=33731 + Many false leaks in release builds due to PtrAndFlags + + Remove UntypedPtrAndBitfield (similar to PtrAndFlags) in UStringImpl, + and steal bits from the refCount instead. + + * runtime/UStringImpl.cpp: + (JSC::UStringImpl::baseSharedBuffer): + (JSC::UStringImpl::~UStringImpl): + * runtime/UStringImpl.h: + (JSC::UStringImpl::cost): + (JSC::UStringImpl::isIdentifier): + (JSC::UStringImpl::setIsIdentifier): + (JSC::UStringImpl::ref): + (JSC::UStringImpl::deref): + (JSC::UStringImpl::UStringImpl): + (JSC::UStringImpl::bufferOwnerString): + (JSC::UStringImpl::bufferOwnership): + (JSC::UStringImpl::isStatic): + (JSC::UStringImpl::): + 2010-02-12 Kwang Yul Seo Reviewed by Adam Barth. diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UStringImpl.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UStringImpl.cpp index 4b0d1c9..4fde49e 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UStringImpl.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UStringImpl.cpp @@ -38,12 +38,14 @@ namespace JSC { SharedUChar* UStringImpl::baseSharedBuffer() { ASSERT((bufferOwnership() == BufferShared) - || ((bufferOwnership() == BufferOwned) && !m_dataBuffer.asPtr())); + || ((bufferOwnership() == BufferOwned) && !m_buffer)); - if (bufferOwnership() != BufferShared) - m_dataBuffer = UntypedPtrAndBitfield(SharedUChar::create(new OwnFastMallocPtr(m_data)).releaseRef(), BufferShared); + if (bufferOwnership() != BufferShared) { + m_refCountAndFlags = (m_refCountAndFlags & ~s_refCountMaskBufferOwnership) | BufferShared; + m_bufferShared = SharedUChar::create(new OwnFastMallocPtr(m_data)).releaseRef(); + } - return m_dataBuffer.asPtr(); + return m_bufferShared; } SharedUChar* UStringImpl::sharedBuffer() @@ -71,10 +73,10 @@ UStringImpl::~UStringImpl() if (bufferOwnership() == BufferOwned) fastFree(m_data); else if (bufferOwnership() == BufferSubstring) - m_dataBuffer.asPtr()->deref(); + m_bufferSubstring->deref(); else { ASSERT(bufferOwnership() == BufferShared); - m_dataBuffer.asPtr()->deref(); + m_bufferShared->deref(); } } } diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UStringImpl.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UStringImpl.h index 4e1ddc7..e6d1a8a 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UStringImpl.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UStringImpl.h @@ -40,48 +40,6 @@ class IdentifierTable; typedef CrossThreadRefCounted > SharedUChar; -class UntypedPtrAndBitfield { -public: - UntypedPtrAndBitfield() {} - - UntypedPtrAndBitfield(void* ptrValue, uintptr_t bitValue) - : m_value(reinterpret_cast(ptrValue) | bitValue) -#ifndef NDEBUG - , m_leaksPtr(ptrValue) -#endif - { - ASSERT(ptrValue == asPtr()); - ASSERT((*this & ~s_alignmentMask) == bitValue); - } - - template - T asPtr() const { return reinterpret_cast(m_value & s_alignmentMask); } - - UntypedPtrAndBitfield& operator&=(uintptr_t bits) - { - m_value &= bits | s_alignmentMask; - return *this; - } - - UntypedPtrAndBitfield& operator|=(uintptr_t bits) - { - m_value |= bits & ~s_alignmentMask; - return *this; - } - - uintptr_t operator&(uintptr_t mask) const - { - return m_value & mask & ~s_alignmentMask; - } - -private: - static const uintptr_t s_alignmentMask = ~static_cast(0x7); - uintptr_t m_value; -#ifndef NDEBUG - void* m_leaksPtr; // Only used to allow tools like leaks on OSX to detect that the memory is referenced. -#endif -}; - class UStringImpl : Noncopyable { public: template @@ -151,21 +109,27 @@ public: { // For substrings, return the cost of the base string. if (bufferOwnership() == BufferSubstring) - return m_dataBuffer.asPtr()->cost(); + return m_bufferSubstring->cost(); - if (m_dataBuffer & s_reportedCostBit) + if (m_refCountAndFlags & s_refCountFlagHasReportedCost) return 0; - m_dataBuffer |= s_reportedCostBit; + m_refCountAndFlags |= s_refCountFlagHasReportedCost; return m_length; } unsigned hash() const { if (!m_hash) m_hash = computeHash(data(), m_length); return m_hash; } unsigned existingHash() const { ASSERT(m_hash); return m_hash; } // fast path for Identifiers void setHash(unsigned hash) { ASSERT(hash == computeHash(data(), m_length)); m_hash = hash; } // fast path for Identifiers - bool isIdentifier() const { return m_isIdentifier; } - void setIsIdentifier(bool isIdentifier) { m_isIdentifier = isIdentifier; } + bool isIdentifier() const { return m_refCountAndFlags & s_refCountFlagIsIdentifier; } + void setIsIdentifier(bool isIdentifier) + { + if (isIdentifier) + m_refCountAndFlags |= s_refCountFlagIsIdentifier; + else + m_refCountAndFlags &= ~s_refCountFlagIsIdentifier; + } - UStringImpl* ref() { m_refCount += s_refCountIncrement; return this; } - ALWAYS_INLINE void deref() { if (!(m_refCount -= s_refCountIncrement)) delete this; } + UStringImpl* ref() { m_refCountAndFlags += s_refCountIncrement; return this; } + ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & s_refCountMask)) delete this; } static void copyChars(UChar* destination, const UChar* source, unsigned numCharacters) { @@ -205,11 +169,10 @@ private: // Used to construct normal strings with an internal or external buffer. UStringImpl(UChar* data, int length, BufferOwnership ownership) : m_data(data) + , m_buffer(0) , m_length(length) - , m_refCount(s_refCountIncrement) + , m_refCountAndFlags(s_refCountIncrement | ownership) , m_hash(0) - , m_isIdentifier(false) - , m_dataBuffer(0, ownership) { ASSERT((ownership == BufferInternal) || (ownership == BufferOwned)); checkConsistency(); @@ -221,11 +184,10 @@ private: enum StaticStringConstructType { ConstructStaticString }; UStringImpl(UChar* data, int length, StaticStringConstructType) : m_data(data) + , m_buffer(0) , m_length(length) - , m_refCount(s_staticRefCountInitialValue) + , m_refCountAndFlags(s_refCountFlagStatic | BufferOwned) , m_hash(0) - , m_isIdentifier(false) - , m_dataBuffer(0, BufferOwned) { checkConsistency(); } @@ -233,28 +195,26 @@ private: // Used to create new strings that are a substring of an existing string. UStringImpl(UChar* data, int length, PassRefPtr base) : m_data(data) + , m_bufferSubstring(base.releaseRef()) , m_length(length) - , m_refCount(s_refCountIncrement) + , m_refCountAndFlags(s_refCountIncrement | BufferSubstring) , m_hash(0) - , m_isIdentifier(false) - , m_dataBuffer(base.releaseRef(), BufferSubstring) { // Do use static strings as a base for substrings; UntypedPtrAndBitfield assumes // that all pointers will be at least 8-byte aligned, we cannot guarantee that of // UStringImpls that are not heap allocated. - ASSERT(m_dataBuffer.asPtr()->size()); - ASSERT(!m_dataBuffer.asPtr()->isStatic()); + ASSERT(m_bufferSubstring->size()); + ASSERT(!m_bufferSubstring->isStatic()); checkConsistency(); } // Used to construct new strings sharing an existing shared buffer. UStringImpl(UChar* data, int length, PassRefPtr sharedBuffer) : m_data(data) + , m_bufferShared(sharedBuffer.releaseRef()) , m_length(length) - , m_refCount(s_refCountIncrement) + , m_refCountAndFlags(s_refCountIncrement | BufferShared) , m_hash(0) - , m_isIdentifier(false) - , m_dataBuffer(sharedBuffer.releaseRef(), BufferShared) { checkConsistency(); } @@ -277,26 +237,31 @@ private: // This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings. static const int s_minLengthToShare = 10; static const unsigned s_copyCharsInlineCutOff = 20; - static const uintptr_t s_bufferOwnershipMask = 3; - static const uintptr_t s_reportedCostBit = 4; // We initialize and increment/decrement the refCount for all normal (non-static) strings by the value 2. // We initialize static strings with an odd number (specifically, 1), such that the refCount cannot reach zero. - static const int s_refCountIncrement = 2; - static const int s_staticRefCountInitialValue = 1; - - UStringImpl* bufferOwnerString() { return (bufferOwnership() == BufferSubstring) ? m_dataBuffer.asPtr() : this; } - const UStringImpl* bufferOwnerString() const { return (bufferOwnership() == BufferSubstring) ? m_dataBuffer.asPtr() : this; } + static const unsigned s_refCountMask = 0xFFFFFFF0; + static const int s_refCountIncrement = 0x20; + static const int s_refCountFlagStatic = 0x10; + static const unsigned s_refCountFlagHasReportedCost = 0x8; + static const unsigned s_refCountFlagIsIdentifier = 0x4; + static const unsigned s_refCountMaskBufferOwnership = 0x3; + + UStringImpl* bufferOwnerString() { return (bufferOwnership() == BufferSubstring) ? m_bufferSubstring : this; } + const UStringImpl* bufferOwnerString() const { return (bufferOwnership() == BufferSubstring) ? m_bufferSubstring : this; } SharedUChar* baseSharedBuffer(); - unsigned bufferOwnership() const { return m_dataBuffer & s_bufferOwnershipMask; } - bool isStatic() const { return m_refCount & 1; } + unsigned bufferOwnership() const { return m_refCountAndFlags & s_refCountMaskBufferOwnership; } + bool isStatic() const { return m_refCountAndFlags & s_refCountFlagStatic; } // unshared data UChar* m_data; + union { + void* m_buffer; + UStringImpl* m_bufferSubstring; + SharedUChar* m_bufferShared; + }; int m_length; - unsigned m_refCount; - mutable unsigned m_hash : 31; - mutable unsigned m_isIdentifier : 1; - UntypedPtrAndBitfield m_dataBuffer; + unsigned m_refCountAndFlags; + mutable unsigned m_hash; JS_EXPORTDATA static UStringImpl* s_null; JS_EXPORTDATA static UStringImpl* s_empty; diff --git a/src/3rdparty/javascriptcore/VERSION b/src/3rdparty/javascriptcore/VERSION index b4744b7..13943b2 100644 --- a/src/3rdparty/javascriptcore/VERSION +++ b/src/3rdparty/javascriptcore/VERSION @@ -4,8 +4,8 @@ This is a snapshot of JavaScriptCore from The commit imported was from the - javascriptcore-snapshot-24012011 branch/tag + javascriptcore-snapshot-27012011 branch/tag and has the sha1 checksum - d143bde5ae8cff229aebd43487a2fce5e713e990 + 3ab0f621048fbeb480b687a28ed31d92d8506150 -- cgit v0.12 From b127b1036ec75c625920a6c029b64a95e3702bf9 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 28 Jan 2011 10:10:31 +0100 Subject: Invalidate QScriptPrograms when engine is destroyed If the engine is destroyed before the program, the program must be invalidated; otherwise the program destructor will access a stale engine pointer, which can cause a crash (it crashes on Symbian, but "only" gives a Valgrind warning on Linux for our autotests). We need to keep track of all associated programs, just like we already do for values and strings. This fix follows the exact same pattern, but uses a QSet to keep the patch minimal. No new tests, but the evaluateProgram() test runs successfully on Symbian now, and there are no more Valgrind warnings. Task-number: QTBUG-16987 Reviewed-by: Olivier Goffart --- src/script/api/qscriptengine.cpp | 9 +++++++++ src/script/api/qscriptengine_p.h | 18 ++++++++++++++++++ src/script/api/qscriptprogram.cpp | 21 ++++++++++++++------- src/script/api/qscriptprogram_p.h | 1 + 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 9e338d4..54039c0 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -1022,6 +1022,7 @@ QScriptEnginePrivate::~QScriptEnginePrivate() while (!ownedAgents.isEmpty()) delete ownedAgents.takeFirst(); + detachAllRegisteredScriptPrograms(); detachAllRegisteredScriptValues(); detachAllRegisteredScriptStrings(); qDeleteAll(m_qobjectData); @@ -1576,6 +1577,14 @@ bool QScriptEnginePrivate::scriptDisconnect(JSC::JSValue signal, JSC::JSValue re #endif +void QScriptEnginePrivate::detachAllRegisteredScriptPrograms() +{ + QSet::const_iterator it; + for (it = registeredScriptPrograms.constBegin(); it != registeredScriptPrograms.constEnd(); ++it) + (*it)->detachFromEngine(); + registeredScriptPrograms.clear(); +} + void QScriptEnginePrivate::detachAllRegisteredScriptValues() { QScriptValuePrivate *it; diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 05a8901..f8144e9 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -87,6 +87,7 @@ class QScriptEngineAgent; class QScriptEnginePrivate; class QScriptSyntaxCheckResult; class QScriptEngine; +class QScriptProgramPrivate; namespace QScript { @@ -273,6 +274,10 @@ public: static QScriptSyntaxCheckResult checkSyntax(const QString &program); static bool canEvaluate(const QString &program); + inline void registerScriptProgram(QScriptProgramPrivate *program); + inline void unregisterScriptProgram(QScriptProgramPrivate *program); + void detachAllRegisteredScriptPrograms(); + inline QScriptValuePrivate *allocateScriptValuePrivate(size_t); inline void freeScriptValuePrivate(QScriptValuePrivate *p); @@ -368,6 +373,7 @@ public: static const int maxFreeScriptValues = 256; int freeScriptValuesCount; QScriptStringPrivate *registeredScriptStrings; + QSet registeredScriptPrograms; QHash m_typeInfos; int processEventsInterval; QScriptValue abortResult; @@ -566,6 +572,18 @@ inline QByteArray convertToLatin1(const JSC::UString &str) } // namespace QScript +inline void QScriptEnginePrivate::registerScriptProgram(QScriptProgramPrivate *program) +{ + Q_ASSERT(!registeredScriptPrograms.contains(program)); + registeredScriptPrograms.insert(program); +} + +inline void QScriptEnginePrivate::unregisterScriptProgram(QScriptProgramPrivate *program) +{ + Q_ASSERT(registeredScriptPrograms.contains(program)); + registeredScriptPrograms.remove(program); +} + inline QScriptValuePrivate *QScriptEnginePrivate::allocateScriptValuePrivate(size_t size) { if (freeScriptValues) { diff --git a/src/script/api/qscriptprogram.cpp b/src/script/api/qscriptprogram.cpp index da103bb..31af9a0 100644 --- a/src/script/api/qscriptprogram.cpp +++ b/src/script/api/qscriptprogram.cpp @@ -64,6 +64,7 @@ QScriptProgramPrivate::~QScriptProgramPrivate() if (engine) { QScript::APIShim shim(engine); _executable.clear(); + engine->unregisterScriptProgram(this); } } @@ -78,7 +79,10 @@ JSC::EvalExecutable *QScriptProgramPrivate::executable(JSC::ExecState *exec, if (_executable) { if (eng == engine) return _executable.get(); - _executable = 0; + // "Migrating" to another engine; clean up old state + QScript::APIShim shim(engine); + _executable.clear(); + engine->unregisterScriptProgram(this); } WTF::PassRefPtr provider = QScript::UStringSourceProviderWithFeedback::create(sourceCode, fileName, firstLineNumber, eng); @@ -86,10 +90,19 @@ JSC::EvalExecutable *QScriptProgramPrivate::executable(JSC::ExecState *exec, JSC::SourceCode source(provider, firstLineNumber); //after construction of SourceCode provider variable will be null. _executable = JSC::EvalExecutable::create(exec, source); engine = eng; + engine->registerScriptProgram(this); isCompiled = false; return _executable.get(); } +void QScriptProgramPrivate::detachFromEngine() +{ + _executable.clear(); + sourceId = -1; + isCompiled = false; + engine = 0; +} + /*! Constructs a null QScriptProgram. */ @@ -122,9 +135,6 @@ QScriptProgram::QScriptProgram(const QScriptProgram &other) */ QScriptProgram::~QScriptProgram() { - // Q_D(QScriptProgram); - // if (d->engine && (d->ref == 1)) - // d->engine->unregisterScriptProgram(d); } /*! @@ -132,9 +142,6 @@ QScriptProgram::~QScriptProgram() */ QScriptProgram &QScriptProgram::operator=(const QScriptProgram &other) { - // if (d_func() && d_func()->engine && (d_func()->ref == 1)) - // d_func()->engine->unregisterScriptProgram(d_func()); - // } d_ptr = other.d_ptr; return *this; } diff --git a/src/script/api/qscriptprogram_p.h b/src/script/api/qscriptprogram_p.h index d2fd234..e7809ab 100644 --- a/src/script/api/qscriptprogram_p.h +++ b/src/script/api/qscriptprogram_p.h @@ -61,6 +61,7 @@ public: JSC::EvalExecutable *executable(JSC::ExecState *exec, QScriptEnginePrivate *engine); + void detachFromEngine(); QBasicAtomicInt ref; -- cgit v0.12 From 298b54b4fa99db47d62ec37eacefb4f419b79a69 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 28 Jan 2011 11:12:50 +0100 Subject: Revert "Improve timer ID safety by using a serial counter per ID." This reverts commit 121e2b39043a4ffc6583f250aebb9a3a746076c1. It was considered too dangerous for 4.7. --- src/corelib/kernel/qabstracteventdispatcher.cpp | 30 +++++-------------------- 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index cc08f092..e79f87a 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -137,12 +137,6 @@ void QAbstractEventDispatcherPrivate::init() // free list). As an added protection, we use the cell to store an invalid // (negative) value that we can later check for integrity. // -// ABA prevention simply adds a value to 7 of the top 8 bits when resetting -// nextFreeTimerId. -// -// The extra code is the bucket allocation which allows us to start with a -// very small bucket size and grow as needed. -// // (continues below). int QAbstractEventDispatcherPrivate::allocateTimerId() { @@ -170,8 +164,6 @@ int QAbstractEventDispatcherPrivate::allocateTimerId() newTimerId = prepareNewValueWithSerialNumber(timerId, b[at]); } while (!nextFreeTimerId.testAndSetRelaxed(timerId, newTimerId)); - timerId &= TimerIdMask; - timerId |= b[at] & TimerSerialMask; b[at] = -timerId; return timerId; @@ -182,13 +174,12 @@ int QAbstractEventDispatcherPrivate::allocateTimerId() // X[timerId] = nextFreeTimerId; // then we update nextFreeTimerId to the timer we've just released // +// The extra code in allocateTimerId and releaseTimerId are ABA prevention +// and bucket memory. The buckets are simply to make sure we allocate only +// the necessary number of timers. See above. +// // ABA prevention simply adds a value to 7 of the top 8 bits when resetting // nextFreeTimerId. -// -// In addition to that, we update the same 7 bits in each entry in the bucket -// as a counter. That way, a timer ID allocated and released will always be -// returned with a different ID. This reduces the chances of timers being released -// erroneously by application code. void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId) { int which = timerId & TimerIdMask; @@ -196,21 +187,12 @@ void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId) int at = bucketIndex(bucket, which); int *b = timerIds[bucket]; -#ifndef QT_NO_DEBUG - // debug code - Q_ASSERT_X(timerId == -b[at], "QAbstractEventDispatcher::releaseTimerId", "Timer ID was not found, fix application"); -#else - if (timerId != -b[at]) { - // release code - qWarning("Timer ID %d was not found, fix application", timerId); - return; - } -#endif + Q_ASSERT(b[at] == -timerId); int freeId, newTimerId; do { freeId = nextFreeTimerId;//.loadAcquire(); // ### FIXME Proper memory ordering semantics - b[at] = prepareNewValueWithSerialNumber(-b[at], freeId); + b[at] = freeId & TimerIdMask; newTimerId = prepareNewValueWithSerialNumber(freeId, timerId); } while (!nextFreeTimerId.testAndSetRelease(freeId, newTimerId)); -- cgit v0.12 From 97503dfd7fad9c8023b2f9632e6ef865ccd0cad8 Mon Sep 17 00:00:00 2001 From: Jani Hautakangas Date: Fri, 28 Jan 2011 13:12:47 +0200 Subject: Fix typo in qglthreads auto test. Reviewed-by: TRUSTME --- tests/auto/qglthreads/tst_qglthreads.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qglthreads/tst_qglthreads.cpp b/tests/auto/qglthreads/tst_qglthreads.cpp index 0bcc4f6..65bebb0 100644 --- a/tests/auto/qglthreads/tst_qglthreads.cpp +++ b/tests/auto/qglthreads/tst_qglthreads.cpp @@ -216,7 +216,7 @@ public: // That's why we create only small textures. width = 50; height = 20; -#else +#endif QImage image(width, height, QImage::Format_RGB32); QPainter p(&image); p.fillRect(image.rect(), QColor(rand() % 256, rand() % 256, rand() % 256)); -- cgit v0.12 From bdf3782b40b0fc2ebfda960be08c90b549cfd970 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 28 Jan 2011 12:23:08 +0100 Subject: Fix potential networking crash due to null-pointer dereference An internal bug report suggests that we unconditionally dereference the backend pointer in QNetworkReplyImpl when checking for the synchronity of the originating request. The dereferencing code was introduced in commit ad1e82323225e996720136e8b2d669166b8d8441. Unfortunately the report does not detail where/how the crash happened, but it appears plausible that the backend pointer became null, and the surrounding code that has extra checks suggests this, too. In an attempt of defensive programming this patch introduces the missing check in the reported line 112 as well as in other places where it seems appropriate. Reviewed-by: Peter Hartmann --- src/network/access/qnetworkreplyimpl.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 9d7082c..343f344 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -109,7 +109,7 @@ void QNetworkReplyImplPrivate::_q_startOperation() } #endif - if (backend->isSynchronous()) { + if (backend && backend->isSynchronous()) { state = Finished; } else { if (state != Finished) { @@ -296,7 +296,7 @@ void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const // in QtWebKit. QVariant synchronousHttpAttribute = req.attribute( static_cast(QNetworkRequest::DownloadBufferAttribute + 1)); - if (synchronousHttpAttribute.toBool()) { + if (backend && synchronousHttpAttribute.toBool()) { backend->setSynchronous(true); if (outgoingData && outgoingData->isSequential()) { outgoingDataBuffer = new QRingBuffer(); @@ -351,7 +351,7 @@ void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); } #else - if (backend->isSynchronous()) + if (backend && backend->isSynchronous()) _q_startOperation(); else QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); -- cgit v0.12 From be4d3182e48dcae70837f26d76dd449d914e8cb3 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 28 Jan 2011 16:32:33 +0200 Subject: Fix generated mif file cleaning in symbian-abld Mif file cleaning was incorrectly done at distclean phase. Task-number: QTBUG-16893 Reviewed-by: axis --- mkspecs/features/symbian/application_icon.prf | 2 +- qmake/generators/symbian/symmake_abld.cpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/symbian/application_icon.prf b/mkspecs/features/symbian/application_icon.prf index b6be89b..06f5b31 100644 --- a/mkspecs/features/symbian/application_icon.prf +++ b/mkspecs/features/symbian/application_icon.prf @@ -71,7 +71,7 @@ contains(CONFIG, no_icon) { mifconv.depends = $$ICON PRE_TARGETDEPS += $$mifconv.target QMAKE_EXTRA_TARGETS += mifconv - QMAKE_DISTCLEAN += $$mifconv.target + QMAKE_CLEAN += $$mifconv.target } # Rules to use generated MIF file from symbian resources RSS_RULES.number_of_icons = $$size(ICON_backslashed) diff --git a/qmake/generators/symbian/symmake_abld.cpp b/qmake/generators/symbian/symmake_abld.cpp index 5729e26..b582257 100644 --- a/qmake/generators/symbian/symmake_abld.cpp +++ b/qmake/generators/symbian/symmake_abld.cpp @@ -190,6 +190,7 @@ void SymbianAbldMakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, bool t << "QMAKE = " << var("QMAKE_QMAKE") << endl; t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl; + t << "DEL_TREE = " << var("QMAKE_DEL_TREE") << endl; t << "MOVE = " << var("QMAKE_MOVE") << endl; t << "CHK_DIR_EXISTS = " << var("QMAKE_CHK_DIR_EXISTS") << endl; t << "MKDIR = " << var("QMAKE_MKDIR") << endl; @@ -329,7 +330,8 @@ void SymbianAbldMakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, bool // Note: EXTENSION_CLEAN will get called many times when doing reallyclean // This is why the "2> NUL" gets appended to generated clean targets in makefile.cpp. t << EXTENSION_CLEAN ": " COMPILER_CLEAN_TARGET << endl; - generateCleanCommands(t, dirsToClean, var("QMAKE_DEL_TREE"), "", "", ""); + generateCleanCommands(t, dirsToClean, "$(DEL_TREE)", "", "", ""); + generateCleanCommands(t, project->values("QMAKE_CLEAN"), "$(DEL_FILE)", "", "", ""); t << endl; t << PRE_TARGETDEPS_TARGET ":" -- cgit v0.12