summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/gestures/imagegestures/imagewidget.cpp1
-rw-r--r--mkspecs/common/symbian/symbian.conf9
-rw-r--r--mkspecs/features/symbian/application_icon.prf108
-rw-r--r--qmake/generators/symbian/symbiancommon.cpp23
-rw-r--r--qmake/generators/symbian/symbiancommon.h1
-rw-r--r--qmake/generators/symbian/symmake.cpp29
-rw-r--r--qmake/generators/symbian/symmake_abld.cpp4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog25
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/UStringImpl.cpp14
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/UStringImpl.h117
-rw-r--r--src/3rdparty/javascriptcore/VERSION4
-rw-r--r--src/corelib/animation/qvariantanimation.cpp13
-rw-r--r--src/corelib/global/qnamespace.h13
-rw-r--r--src/corelib/thread/qthread.cpp5
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h10
-rw-r--r--src/dbus/qdbusintegrator.cpp5
-rw-r--r--src/gui/kernel/qmacgesturerecognizer_mac.mm6
-rw-r--r--src/gui/kernel/qt_s60_p.h2
-rw-r--r--src/gui/kernel/qwidget.cpp40
-rw-r--r--src/gui/widgets/qcombobox.cpp16
-rw-r--r--src/network/access/qnetworkaccessftpbackend.cpp4
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp6
-rw-r--r--src/script/api/qscriptengine.cpp9
-rw-r--r--src/script/api/qscriptengine_p.h18
-rw-r--r--src/script/api/qscriptprogram.cpp21
-rw-r--r--src/script/api/qscriptprogram_p.h1
-rw-r--r--src/sql/drivers/odbc/qsql_odbc.cpp2
-rw-r--r--src/sql/drivers/psql/qsql_psql.cpp6
-rw-r--r--tests/auto/qcoreapplication/tst_qcoreapplication.cpp45
-rw-r--r--tests/auto/qeventloop/tst_qeventloop.cpp41
-rw-r--r--tests/auto/qglthreads/tst_qglthreads.cpp2
-rw-r--r--tests/auto/qthread/tst_qthread.cpp193
32 files changed, 539 insertions, 254 deletions
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/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf
index 37bbb82..006a2da 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 f50e944..d9918bf 100644
--- a/mkspecs/features/symbian/application_icon.prf
+++ b/mkspecs/features/symbian/application_icon.prf
@@ -12,69 +12,75 @@ 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.files += $$resourceZDir/$${baseTarget}.rsc
- default_resource_deployment.path = $$APP_RESOURCE_DIR
- default_reg_deployment.files += $$regZDir/$${baseTarget}_reg.rsc
- default_reg_deployment.path = $$REG_RESOURCE_IMPORT_DIR
+ default_resource_deployment.files += $$resourceZDir/$${baseTarget}.rsc
+ default_resource_deployment.path = $$APP_RESOURCE_DIR
+ default_reg_deployment.files += $$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, /, \\)
- }
- # 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
+ # 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
- }
- # Rules to use generated MIF file from symbian resources
- RSS_RULES.number_of_icons = $$size(ICON_backslashed)
+ mifconv.depends = $$ICON
+ PRE_TARGETDEPS += $$mifconv.target
+ QMAKE_EXTRA_TARGETS += mifconv
+ QMAKE_CLEAN += $$mifconv.target
+ }
+ # 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
+ RSS_RULES.icon_file = $$APP_RESOURCE_DIR/$${baseTarget}.mif
- default_resource_deployment.files += $$resourceZDir/$${baseTarget}.mif
+ default_resource_deployment.files += $$resourceZDir/$${baseTarget}.mif
+ }
}
}
diff --git a/qmake/generators/symbian/symbiancommon.cpp b/qmake/generators/symbian/symbiancommon.cpp
index c54fac7..46b8cf5 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 e6c9666..08d3370 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)
@@ -892,13 +898,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;
@@ -907,9 +917,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
@@ -931,7 +947,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;
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 ":"
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 <barraclough@apple.com>
+
+ 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 <skyul@company100.net>
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<void*>()));
+ || ((bufferOwnership() == BufferOwned) && !m_buffer));
- if (bufferOwnership() != BufferShared)
- m_dataBuffer = UntypedPtrAndBitfield(SharedUChar::create(new OwnFastMallocPtr<UChar>(m_data)).releaseRef(), BufferShared);
+ if (bufferOwnership() != BufferShared) {
+ m_refCountAndFlags = (m_refCountAndFlags & ~s_refCountMaskBufferOwnership) | BufferShared;
+ m_bufferShared = SharedUChar::create(new OwnFastMallocPtr<UChar>(m_data)).releaseRef();
+ }
- return m_dataBuffer.asPtr<SharedUChar*>();
+ 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<UStringImpl*>()->deref();
+ m_bufferSubstring->deref();
else {
ASSERT(bufferOwnership() == BufferShared);
- m_dataBuffer.asPtr<SharedUChar*>()->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<OwnFastMallocPtr<UChar> > SharedUChar;
-class UntypedPtrAndBitfield {
-public:
- UntypedPtrAndBitfield() {}
-
- UntypedPtrAndBitfield(void* ptrValue, uintptr_t bitValue)
- : m_value(reinterpret_cast<uintptr_t>(ptrValue) | bitValue)
-#ifndef NDEBUG
- , m_leaksPtr(ptrValue)
-#endif
- {
- ASSERT(ptrValue == asPtr<void*>());
- ASSERT((*this & ~s_alignmentMask) == bitValue);
- }
-
- template<typename T>
- T asPtr() const { return reinterpret_cast<T>(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<uintptr_t>(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<size_t inlineCapacity>
@@ -151,21 +109,27 @@ public:
{
// For substrings, return the cost of the base string.
if (bufferOwnership() == BufferSubstring)
- return m_dataBuffer.asPtr<UStringImpl*>()->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<UStringImpl> 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<UStringImpl*>()->size());
- ASSERT(!m_dataBuffer.asPtr<UStringImpl*>()->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<SharedUChar> 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<UStringImpl*>() : this; }
- const UStringImpl* bufferOwnerString() const { return (bufferOwnership() == BufferSubstring) ? m_dataBuffer.asPtr<UStringImpl*>() : 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
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);
+ }
}
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 7a6ab36..1b22c77 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/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index 1494745..b8f891c 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -488,10 +488,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/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
index 273c5bd..b29e5b6 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
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index 3c0cb6e..1358524 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;
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<QSwipeGesture *>(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; }
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 547da11..475d4da 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -127,6 +127,10 @@
#include "qtabwidget.h" // Needed in inTabWidget()
#endif // QT_KEYPAD_NAVIGATION
+#ifdef Q_WS_S60
+#include <aknappui.h>
+#endif
+
// widget/widget data creation count
//#define QWIDGET_EXTRA_DEBUG
//#define ALIEN_DEBUG
@@ -10871,6 +10875,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<CAknAppUiBase*>(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;
}
diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp
index 7946137..b5dda5a 100644
--- a/src/gui/widgets/qcombobox.cpp
+++ b/src/gui/widgets/qcombobox.cpp
@@ -2486,10 +2486,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
diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp
index bad010f..e34e6bb 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)
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index 9069b14..41a6c62 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -115,7 +115,7 @@ void QNetworkReplyImplPrivate::_q_startOperation()
}
#endif
- if (backend->isSynchronous()) {
+ if (backend && backend->isSynchronous()) {
state = Finished;
q_func()->setFinished(true);
} else {
@@ -307,7 +307,7 @@ void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const
// in QtWebKit.
QVariant synchronousHttpAttribute = req.attribute(
static_cast<QNetworkRequest::Attribute>(QNetworkRequest::DownloadBufferAttribute + 1));
- if (synchronousHttpAttribute.toBool()) {
+ if (backend && synchronousHttpAttribute.toBool()) {
backend->setSynchronous(true);
if (outgoingData && outgoingData->isSequential()) {
outgoingDataBuffer = new QRingBuffer();
@@ -362,7 +362,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);
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
index 004e3a5..e3291e0 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<QScriptProgramPrivate*>::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<QScriptProgramPrivate*> registeredScriptPrograms;
QHash<int, QScriptTypeInfo*> 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<QScript::UStringSourceProviderWithFeedback> 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;
diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp
index 1573d02..0b534d9 100644
--- a/src/sql/drivers/odbc/qsql_odbc.cpp
+++ b/src/sql/drivers/odbc/qsql_odbc.cpp
@@ -214,7 +214,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);
diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp
index 5a32d1a..34277b3 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());
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/qglthreads/tst_qglthreads.cpp b/tests/auto/qglthreads/tst_qglthreads.cpp
index 434fd9d..45c8cbc 100644
--- a/tests/auto/qglthreads/tst_qglthreads.cpp
+++ b/tests/auto/qglthreads/tst_qglthreads.cpp
@@ -210,7 +210,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));
diff --git a/tests/auto/qthread/tst_qthread.cpp b/tests/auto/qthread/tst_qthread.cpp
index 19c6c16..6b5504d 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();
@@ -271,6 +272,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()
{
@@ -430,34 +459,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 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);
+ {
+ 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());
+ // 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()
@@ -504,32 +551,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);
+ // 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());
+
+ // 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.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;
-
- 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);
+ QVERIFY(thread.wait());
+ QCOMPARE(thread.returnValue, 0);
}
void tst_QThread::wait()
@@ -999,8 +1073,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);