diff options
author | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2014-12-10 07:58:06 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2014-12-10 07:58:06 +0100 |
commit | 015002fec9abff6a4c1bb3fa4b9de87279a079c3 (patch) | |
tree | ad93af535a503d0a49d6c6367e990a8fbca163d3 /src/corelib/kernel | |
parent | f1e00262321cc8daa3c7506153653453e2779886 (diff) | |
parent | b9547af45ea2bbbc634722c1ef41afdb54216ce2 (diff) |
Merge remote-tracking branch 'origin/5.4' into dev
Conflicts:
doc/global/template/style/online.css
mkspecs/android-g++/qmake.conf
Change-Id: Ib39ea7bd42f5ae12e82a3bc59a66787a16bdfc61
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r-- | src/corelib/kernel/qfunctions_winrt.cpp | 4 | ||||
-rw-r--r-- | src/corelib/kernel/qfunctions_winrt.h | 61 | ||||
-rw-r--r-- | src/corelib/kernel/qjni.cpp | 83 | ||||
-rw-r--r-- | src/corelib/kernel/qtranslator.cpp | 20 |
4 files changed, 105 insertions, 63 deletions
diff --git a/src/corelib/kernel/qfunctions_winrt.cpp b/src/corelib/kernel/qfunctions_winrt.cpp index 84e7b5688f..60faead122 100644 --- a/src/corelib/kernel/qfunctions_winrt.cpp +++ b/src/corelib/kernel/qfunctions_winrt.cpp @@ -37,7 +37,7 @@ #include "qbytearray.h" #include "qhash.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE // Environment ------------------------------------------------------ inline QHash<QByteArray, QByteArray> &qt_app_environment() @@ -94,4 +94,6 @@ void qt_winrt__tzset() { } +QT_END_NAMESPACE + #endif // Q_OS_WINRT diff --git a/src/corelib/kernel/qfunctions_winrt.h b/src/corelib/kernel/qfunctions_winrt.h index 04ebda5cfe..2bec1fc2ff 100644 --- a/src/corelib/kernel/qfunctions_winrt.h +++ b/src/corelib/kernel/qfunctions_winrt.h @@ -42,21 +42,36 @@ #include <QtCore/QAbstractEventDispatcher> #include <QtCore/qt_windows.h> -QT_BEGIN_NAMESPACE +// Convenience macros for handling HRESULT values +#define RETURN_IF_FAILED(msg, ret) \ + if (FAILED(hr)) { \ + qErrnoWarning(hr, msg); \ + ret; \ + } -#ifdef QT_BUILD_CORE_LIB -#endif +#define RETURN_HR_IF_FAILED(msg) RETURN_IF_FAILED(msg, return hr) +#define RETURN_OK_IF_FAILED(msg) RETURN_IF_FAILED(msg, return S_OK) +#define RETURN_FALSE_IF_FAILED(msg) RETURN_IF_FAILED(msg, return false) +#define RETURN_VOID_IF_FAILED(msg) RETURN_IF_FAILED(msg, return) -QT_END_NAMESPACE +#define Q_ASSERT_SUCCEEDED(hr) \ + Q_ASSERT_X(SUCCEEDED(hr), Q_FUNC_INFO, qPrintable(qt_error_string(hr))); #ifdef Q_OS_WINRT +QT_BEGIN_NAMESPACE + +#ifdef QT_BUILD_CORE_LIB +#endif + // Environment ------------------------------------------------------ errno_t qt_winrt_getenv_s(size_t*, char*, size_t, const char*); errno_t qt_winrt__putenv_s(const char*, const char*); void qt_winrt_tzset(); void qt_winrt__tzset(); +QT_END_NAMESPACE + // As Windows Runtime lacks some standard functions used in Qt, these got // reimplemented. Other projects do this as well. Inline functions are used // that there is a central place to disable functions for newer versions if @@ -69,42 +84,42 @@ void qt_winrt__tzset(); #define generate_inline_return_func0(funcname, returntype) \ inline returntype funcname() \ { \ - return qt_winrt_##funcname(); \ + return QT_PREPEND_NAMESPACE(qt_winrt_##funcname)(); \ } #define generate_inline_return_func1(funcname, returntype, param1) \ inline returntype funcname(param1 p1) \ { \ - return qt_winrt_##funcname(p1); \ + return QT_PREPEND_NAMESPACE(qt_winrt_##funcname)(p1); \ } #define generate_inline_return_func2(funcname, returntype, param1, param2) \ inline returntype funcname(param1 p1, param2 p2) \ { \ - return qt_winrt_##funcname(p1, p2); \ + return QT_PREPEND_NAMESPACE(qt_winrt_##funcname)(p1, p2); \ } #define generate_inline_return_func3(funcname, returntype, param1, param2, param3) \ inline returntype funcname(param1 p1, param2 p2, param3 p3) \ { \ - return qt_winrt_##funcname(p1, p2, p3); \ + return QT_PREPEND_NAMESPACE(qt_winrt_##funcname)(p1, p2, p3); \ } #define generate_inline_return_func4(funcname, returntype, param1, param2, param3, param4) \ inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4) \ { \ - return qt_winrt_##funcname(p1, p2, p3, p4); \ + return QT_PREPEND_NAMESPACE(qt_winrt_##funcname)(p1, p2, p3, p4); \ } #define generate_inline_return_func5(funcname, returntype, param1, param2, param3, param4, param5) \ inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ { \ - return qt_winrt_##funcname(p1, p2, p3, p4, p5); \ + return QT_PREPEND_NAMESPACE(qt_winrt_##funcname)(p1, p2, p3, p4, p5); \ } #define generate_inline_return_func6(funcname, returntype, param1, param2, param3, param4, param5, param6) \ inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ { \ - return qt_winrt_##funcname(p1, p2, p3, p4, p5, p6); \ + return QT_PREPEND_NAMESPACE(qt_winrt_##funcname)(p1, p2, p3, p4, p5, p6); \ } #define generate_inline_return_func7(funcname, returntype, param1, param2, param3, param4, param5, param6, param7) \ inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7) \ { \ - return qt_winrt_##funcname(p1, p2, p3, p4, p5, p6, p7); \ + return QT_PREPEND_NAMESPACE(qt_winrt_##funcname)(p1, p2, p3, p4, p5, p6, p7); \ } typedef unsigned (__stdcall *StartAdressExFunc)(void *); @@ -116,23 +131,7 @@ generate_inline_return_func2(_putenv_s, errno_t, const char *, const char *) generate_inline_return_func0(tzset, void) generate_inline_return_func0(_tzset, void) -#endif // Q_OS_WINRT - -// Convenience macros for handling HRESULT values -#define RETURN_IF_FAILED(msg, ret) \ - if (FAILED(hr)) { \ - qErrnoWarning(hr, msg); \ - ret; \ - } - -#define RETURN_HR_IF_FAILED(msg) RETURN_IF_FAILED(msg, return hr) -#define RETURN_OK_IF_FAILED(msg) RETURN_IF_FAILED(msg, return S_OK) -#define RETURN_FALSE_IF_FAILED(msg) RETURN_IF_FAILED(msg, return false) -#define RETURN_VOID_IF_FAILED(msg) RETURN_IF_FAILED(msg, return) - -#define Q_ASSERT_SUCCEEDED(hr) \ - Q_ASSERT_X(SUCCEEDED(hr), Q_FUNC_INFO, qPrintable(qt_error_string(hr))); - +QT_BEGIN_NAMESPACE namespace Microsoft { namespace WRL { template <typename T> class ComPtr; } } @@ -207,6 +206,10 @@ static inline HRESULT await(const Microsoft::WRL::ComPtr<T> &asyncOp, U *results } // QWinRTFunctions +QT_END_NAMESPACE + +#endif // Q_OS_WINRT + #endif // Q_OS_WIN #endif // QFUNCTIONS_WINRT_H diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp index b179323fdc..9d74fd69de 100644 --- a/src/corelib/kernel/qjni.cpp +++ b/src/corelib/kernel/qjni.cpp @@ -37,6 +37,7 @@ #include <QtCore/qhash.h> #include <QtCore/qstring.h> #include <QtCore/QThread> +#include <QtCore/QReadWriteLock> QT_BEGIN_NAMESPACE @@ -45,11 +46,6 @@ static inline QString keyBase() return QStringLiteral("%1%2%3"); } -static inline QByteArray threadBaseName() -{ - return QByteArrayLiteral("QtThread-"); -} - static QString qt_convertJString(jstring string) { QJNIEnvironmentPrivate env; @@ -74,6 +70,7 @@ static inline bool exceptionCheckAndClear(JNIEnv *env) typedef QHash<QString, jclass> JClassHash; Q_GLOBAL_STATIC(JClassHash, cachedClasses) +Q_GLOBAL_STATIC(QReadWriteLock, cachedClassesLock) static QString toDotEncodedClassName(const char *className) { @@ -82,8 +79,9 @@ static QString toDotEncodedClassName(const char *className) static jclass getCachedClass(const QString &classDotEnc, bool *isCached = 0) { - QHash<QString, jclass>::iterator it = cachedClasses->find(classDotEnc); - const bool found = (it != cachedClasses->end()); + QReadLocker locker(cachedClassesLock); + const QHash<QString, jclass>::const_iterator &it = cachedClasses->constFind(classDotEnc); + const bool found = (it != cachedClasses->constEnd()); if (isCached != 0) *isCached = found; @@ -102,6 +100,12 @@ static jclass loadClassDotEnc(const QString &classDotEnc, JNIEnv *env) if (!classLoader.isValid()) return 0; + QWriteLocker locker(cachedClassesLock); + // did we lose the race? + const QHash<QString, jclass>::const_iterator &it = cachedClasses->constFind(classDotEnc); + if (it != cachedClasses->constEnd()) + return it.value(); + QJNIObjectPrivate stringName = QJNIObjectPrivate::fromString(classDotEnc); QJNIObjectPrivate classObject = classLoader.callObjectMethod("loadClass", "(Ljava/lang/String;)Ljava/lang/Class;", @@ -121,6 +125,7 @@ inline static jclass loadClass(const char *className, JNIEnv *env) typedef QHash<QString, jmethodID> JMethodIDHash; Q_GLOBAL_STATIC(JMethodIDHash, cachedMethodID) +Q_GLOBAL_STATIC(QReadWriteLock, cachedMethodIDLock) static jmethodID getCachedMethodID(JNIEnv *env, jclass clazz, @@ -128,11 +133,24 @@ static jmethodID getCachedMethodID(JNIEnv *env, const char *sig, bool isStatic = false) { - jmethodID id = 0; // TODO: We need to use something else then the ref. from clazz to avoid collisions. - QString key = keyBase().arg(size_t(clazz)).arg(QLatin1String(name)).arg(QLatin1String(sig)); - QHash<QString, jmethodID>::iterator it = cachedMethodID->find(key); - if (it == cachedMethodID->end()) { + const QString key = keyBase().arg(size_t(clazz)).arg(QLatin1String(name)).arg(QLatin1String(sig)); + QHash<QString, jmethodID>::const_iterator it; + + { + QReadLocker locker(cachedMethodIDLock); + it = cachedMethodID->constFind(key); + if (it != cachedMethodID->constEnd()) + return it.value(); + } + + { + QWriteLocker locker(cachedMethodIDLock); + it = cachedMethodID->constFind(key); + if (it != cachedMethodID->constEnd()) + return it.value(); + + jmethodID id = 0; if (isStatic) id = env->GetStaticMethodID(clazz, name, sig); else @@ -142,14 +160,13 @@ static jmethodID getCachedMethodID(JNIEnv *env, id = 0; cachedMethodID->insert(key, id); - } else { - id = it.value(); + return id; } - return id; } typedef QHash<QString, jfieldID> JFieldIDHash; Q_GLOBAL_STATIC(JFieldIDHash, cachedFieldID) +Q_GLOBAL_STATIC(QReadWriteLock, cachedFieldIDLock) static jfieldID getCachedFieldID(JNIEnv *env, jclass clazz, @@ -157,10 +174,23 @@ static jfieldID getCachedFieldID(JNIEnv *env, const char *sig, bool isStatic = false) { - jfieldID id = 0; - QString key = keyBase().arg(size_t(clazz)).arg(QLatin1String(name)).arg(QLatin1String(sig)); - QHash<QString, jfieldID>::iterator it = cachedFieldID->find(key); - if (it == cachedFieldID->end()) { + const QString key = keyBase().arg(size_t(clazz)).arg(QLatin1String(name)).arg(QLatin1String(sig)); + QHash<QString, jfieldID>::const_iterator it; + + { + QReadLocker locker(cachedFieldIDLock); + it = cachedFieldID->constFind(key); + if (it != cachedFieldID->constEnd()) + return it.value(); + } + + { + QWriteLocker locker(cachedFieldIDLock); + it = cachedFieldID->constFind(key); + if (it != cachedFieldID->constEnd()) + return it.value(); + + jfieldID id = 0; if (isStatic) id = env->GetStaticFieldID(clazz, name, sig); else @@ -170,10 +200,8 @@ static jfieldID getCachedFieldID(JNIEnv *env, id = 0; cachedFieldID->insert(key, id); - } else { - id = it.value(); + return id; } - return id; } class QJNIEnvironmentPrivateTLS @@ -187,14 +215,14 @@ public: Q_GLOBAL_STATIC(QThreadStorage<QJNIEnvironmentPrivateTLS *>, jniEnvTLS) +static const char qJniThreadName[] = "QtThread"; + QJNIEnvironmentPrivate::QJNIEnvironmentPrivate() : jniEnv(0) { JavaVM *vm = QtAndroidPrivate::javaVM(); if (vm->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) == JNI_EDETACHED) { - const qulonglong id = reinterpret_cast<qulonglong>(QThread::currentThreadId()); - const QByteArray threadName = threadBaseName() + QByteArray::number(id); - JavaVMAttachArgs args = { JNI_VERSION_1_6, threadName, Q_NULLPTR }; + JavaVMAttachArgs args = { JNI_VERSION_1_6, qJniThreadName, Q_NULLPTR }; if (vm->AttachCurrentThread(&jniEnv, &args) != JNI_OK) return; } @@ -223,6 +251,12 @@ jclass QJNIEnvironmentPrivate::findClass(const char *className, JNIEnv *env) return clazz; if (env != 0) { // We got an env. pointer (We expect this to be the right env. and call FindClass()) + QWriteLocker locker(cachedClassesLock); + const QHash<QString, jclass>::const_iterator &it = cachedClasses->constFind(classDotEnc); + // Did we lose the race? + if (it != cachedClasses->constEnd()) + return it.value(); + jclass fclazz = env->FindClass(className); if (!exceptionCheckAndClear(env)) { clazz = static_cast<jclass>(env->NewGlobalRef(fclazz)); @@ -400,7 +434,6 @@ QJNIObjectPrivate::QJNIObjectPrivate(jobject obj) d->m_jclass = static_cast<jclass>(env->NewGlobalRef(objectClass)); env->DeleteLocalRef(objectClass); } - template <> void QJNIObjectPrivate::callMethodV<void>(const char *methodName, const char *sig, va_list args) const { diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index a2cf4a7813..a9c608384a 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -86,13 +86,13 @@ static const uchar magic[MagicLength] = { 0xcd, 0x21, 0x1c, 0xbf, 0x60, 0xa1, 0xbd, 0xdd }; -static bool match(const uchar* found, const char* target, uint len) +static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen) { // catch the case if \a found has a zero-terminating symbol and \a len includes it. // (normalize it to be without the zero-terminating symbol) - if (len > 0 && found[len-1] == '\0') - --len; - return (memcmp(found, target, len) == 0 && target[len] == '\0'); + if (foundLen > 0 && found[foundLen-1] == '\0') + --foundLen; + return ((targetLen == foundLen) && memcmp(found, target, foundLen) == 0); } static void elfHash_continue(const char *name, uint &h) @@ -878,6 +878,9 @@ static QString getMessage(const uchar *m, const uchar *end, const char *context, { const uchar *tn = 0; uint tn_length = 0; + const uint sourceTextLen = uint(strlen(sourceText)); + const uint contextLen = uint(strlen(context)); + const uint commentLen = uint(strlen(comment)); for (;;) { uchar tag = 0; @@ -904,7 +907,7 @@ static QString getMessage(const uchar *m, const uchar *end, const char *context, case Tag_SourceText: { quint32 len = read32(m); m += 4; - if (!match(m, sourceText, len)) + if (!match(m, len, sourceText, sourceTextLen)) return QString(); m += len; } @@ -912,7 +915,7 @@ static QString getMessage(const uchar *m, const uchar *end, const char *context, case Tag_Context: { quint32 len = read32(m); m += 4; - if (!match(m, context, len)) + if (!match(m, len, context, contextLen)) return QString(); m += len; } @@ -920,7 +923,7 @@ static QString getMessage(const uchar *m, const uchar *end, const char *context, case Tag_Comment: { quint32 len = read32(m); m += 4; - if (*m && !match(m, comment, len)) + if (*m && !match(m, len, comment, commentLen)) return QString(); m += len; } @@ -970,11 +973,12 @@ QString QTranslatorPrivate::do_translate(const char *context, const char *source return QString(); c = contextArray + (2 + (hTableSize << 1) + (off << 1)); + const uint contextLen = uint(strlen(context)); for (;;) { quint8 len = read8(c++); if (len == 0) return QString(); - if (match(c, context, len)) + if (match(c, len, context, contextLen)) break; c += len; } |