diff options
author | Liang Qi <liang.qi@qt.io> | 2017-02-16 21:46:20 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-02-16 21:51:11 +0100 |
commit | c577f6edafef7c40a5f78092ec4fcd78bb820b2c (patch) | |
tree | 9ca3819e5cca9b7e61f305a874b682e5a2085e83 /src/corelib/kernel | |
parent | 99ce1d3d97c0423c3ee63ccf58deed964db0770e (diff) | |
parent | de225ccdf95efb57866d62bc80872c1a2ab99703 (diff) |
Merge remote-tracking branch 'origin/5.8' into 5.9
Conflicts:
src/corelib/plugin/qlibrary_unix.cpp
src/plugins/platforms/xcb/qxcbconnection.cpp
tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
Change-Id: I632c400d909f8c204f55743aadc7886af2f15dfb
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r-- | src/corelib/kernel/qjnihelpers.cpp | 49 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype.cpp | 39 | ||||
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 2 |
3 files changed, 40 insertions, 50 deletions
diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp index 091280400e..93bc477e7d 100644 --- a/src/corelib/kernel/qjnihelpers.cpp +++ b/src/corelib/kernel/qjnihelpers.cpp @@ -73,7 +73,7 @@ static jclass g_jNativeClass = Q_NULLPTR; static jmethodID g_runPendingCppRunnablesMethodID = Q_NULLPTR; static jmethodID g_hideSplashScreenMethodID = Q_NULLPTR; Q_GLOBAL_STATIC(std::deque<QtAndroidPrivate::Runnable>, g_pendingRunnables); -Q_GLOBAL_STATIC(QMutex, g_pendingRunnablesMutex); +static QBasicMutex g_pendingRunnablesMutex; class PermissionsResultClass : public QObject { @@ -88,21 +88,24 @@ private: typedef QHash<int, QSharedPointer<PermissionsResultClass>> PendingPermissionRequestsHash; Q_GLOBAL_STATIC(PendingPermissionRequestsHash, g_pendingPermissionRequests); -Q_GLOBAL_STATIC(QMutex, g_pendingPermissionRequestsMutex); -Q_GLOBAL_STATIC(QAtomicInt, g_requestPermissionsRequestCode); +static QBasicMutex g_pendingPermissionRequestsMutex; +static int nextRequestCode() +{ + static QBasicAtomicInt counter = Q_BASIC_ATOMIC_INITIALIZER(0); + return counter.fetchAndAddRelaxed(1); +} // function called from Java from Android UI thread static void runPendingCppRunnables(JNIEnv */*env*/, jobject /*obj*/) { for (;;) { // run all posted runnables - g_pendingRunnablesMutex->lock(); + QMutexLocker locker(&g_pendingRunnablesMutex); if (g_pendingRunnables->empty()) { - g_pendingRunnablesMutex->unlock(); break; } QtAndroidPrivate::Runnable runnable(std::move(g_pendingRunnables->front())); g_pendingRunnables->pop_front(); - g_pendingRunnablesMutex->unlock(); + locker.unlock(); runnable(); // run it outside the sync block! } } @@ -122,16 +125,17 @@ Q_GLOBAL_STATIC(GenericMotionEventListeners, g_genericMotionEventListeners) static void sendRequestPermissionsResult(JNIEnv *env, jobject /*obj*/, jint requestCode, jobjectArray permissions, jintArray grantResults) { - g_pendingPermissionRequestsMutex->lock(); + QMutexLocker locker(&g_pendingPermissionRequestsMutex); auto it = g_pendingPermissionRequests->find(requestCode); if (it == g_pendingPermissionRequests->end()) { - g_pendingPermissionRequestsMutex->unlock(); // show an error or something ? return; } - g_pendingPermissionRequestsMutex->unlock(); + auto request = std::move(*it); + g_pendingPermissionRequests->erase(it); + locker.unlock(); - Qt::ConnectionType connection = QThread::currentThread() == it.value()->thread() ? Qt::DirectConnection : Qt::BlockingQueuedConnection; + Qt::ConnectionType connection = QThread::currentThread() == request->thread() ? Qt::DirectConnection : Qt::BlockingQueuedConnection; QtAndroidPrivate::PermissionsHash hash; const int size = env->GetArrayLength(permissions); std::unique_ptr<jint[]> results(new jint[size]); @@ -143,10 +147,7 @@ static void sendRequestPermissionsResult(JNIEnv *env, jobject /*obj*/, jint requ QtAndroidPrivate::PermissionsResult::Denied; hash[permission] = value; } - QMetaObject::invokeMethod(it.value().data(), "sendResult", connection, Q_ARG(QtAndroidPrivate::PermissionsHash, hash)); - g_pendingPermissionRequestsMutex->lock(); - g_pendingPermissionRequests->erase(it); - g_pendingPermissionRequestsMutex->unlock(); + QMetaObject::invokeMethod(request.data(), "sendResult", connection, Q_ARG(QtAndroidPrivate::PermissionsHash, hash)); } static jboolean dispatchGenericMotionEvent(JNIEnv *, jclass, jobject event) @@ -403,7 +404,7 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env) return JNI_ERR; g_runPendingCppRunnablesMethodID = env->GetStaticMethodID(jQtNative, - "runPendingCppRunnablesOnUiThread", + "runPendingCppRunnablesOnAndroidThread", "()V"); g_hideSplashScreenMethodID = env->GetStaticMethodID(jQtNative, "hideSplashScreen", "()V"); g_jNativeClass = static_cast<jclass>(env->NewGlobalRef(jQtNative)); @@ -459,10 +460,10 @@ void QtAndroidPrivate::runOnUiThread(QRunnable *runnable, JNIEnv *env) void QtAndroidPrivate::runOnAndroidThread(const QtAndroidPrivate::Runnable &runnable, JNIEnv *env) { - g_pendingRunnablesMutex->lock(); + QMutexLocker locker(&g_pendingRunnablesMutex); const bool triggerRun = g_pendingRunnables->empty(); g_pendingRunnables->push_back(runnable); - g_pendingRunnablesMutex->unlock(); + locker.unlock(); if (triggerRun) env->CallStaticVoidMethod(g_jNativeClass, g_runPendingCppRunnablesMethodID); } @@ -487,18 +488,16 @@ void QtAndroidPrivate::requestPermissions(JNIEnv *env, const QStringList &permis return; } // Check API 23+ permissions - const int requestCode = (*g_requestPermissionsRequestCode)++; + const int requestCode = nextRequestCode(); if (!directCall) { - g_pendingPermissionRequestsMutex->lock(); + QMutexLocker locker(&g_pendingPermissionRequestsMutex); (*g_pendingPermissionRequests)[requestCode] = QSharedPointer<PermissionsResultClass>::create(callbackFunc); - g_pendingPermissionRequestsMutex->unlock(); } runOnAndroidThread([permissions, callbackFunc, requestCode, directCall] { if (directCall) { - g_pendingPermissionRequestsMutex->lock(); + QMutexLocker locker(&g_pendingPermissionRequestsMutex); (*g_pendingPermissionRequests)[requestCode] = QSharedPointer<PermissionsResultClass>::create(callbackFunc); - g_pendingPermissionRequestsMutex->unlock(); } QJNIEnvironmentPrivate env; @@ -519,8 +518,10 @@ QHash<QString, QtAndroidPrivate::PermissionsResult> QtAndroidPrivate::requestPer *res = result; sem->release(); }, true); - sem->tryAcquire(1, timeoutMs); - return *res; + if (sem->tryAcquire(1, timeoutMs)) + return std::move(*res); + else // mustn't touch *res + return QHash<QString, QtAndroidPrivate::PermissionsResult>(); } QtAndroidPrivate::PermissionsResult QtAndroidPrivate::checkPermission(const QString &permission) diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 5623b085b8..1764c8116e 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -834,38 +834,27 @@ void QMetaType::registerStreamOperators(int idx, SaveOperator saveOp, const char *QMetaType::typeName(int typeId) { const uint type = typeId; - // In theory it can be filled during compilation time, but for some reason template code - // that is able to do it causes GCC 4.6 to generate additional 3K of executable code. Probably - // it is not worth of it. - static const char *namesCache[QMetaType::HighestInternalId + 1]; - - const char *result; - if (type <= QMetaType::HighestInternalId && ((result = namesCache[type]))) - return result; - #define QT_METATYPE_TYPEID_TYPENAME_CONVERTER(MetaTypeName, TypeId, RealName) \ - case QMetaType::MetaTypeName: result = #RealName; break; + case QMetaType::MetaTypeName: return #RealName; break; switch (QMetaType::Type(type)) { QT_FOR_EACH_STATIC_TYPE(QT_METATYPE_TYPEID_TYPENAME_CONVERTER) - - default: { - if (Q_UNLIKELY(type < QMetaType::User)) { - return 0; // It can happen when someone cast int to QVariant::Type, we should not crash... - } else { - const QVector<QCustomTypeInfo> * const ct = customTypes(); - QReadLocker locker(customTypesLock()); - return ct && uint(ct->count()) > type - QMetaType::User && !ct->at(type - QMetaType::User).typeName.isEmpty() - ? ct->at(type - QMetaType::User).typeName.constData() - : 0; - } + case QMetaType::UnknownType: + case QMetaType::User: + break; } + + if (Q_UNLIKELY(type < QMetaType::User)) { + return nullptr; // It can happen when someone cast int to QVariant::Type, we should not crash... } -#undef QT_METATYPE_TYPEID_TYPENAME_CONVERTER - Q_ASSERT(type <= QMetaType::HighestInternalId); - namesCache[type] = result; - return result; + const QVector<QCustomTypeInfo> * const ct = customTypes(); + QReadLocker locker(customTypesLock()); + return ct && uint(ct->count()) > type - QMetaType::User && !ct->at(type - QMetaType::User).typeName.isEmpty() + ? ct->at(type - QMetaType::User).typeName.constData() + : nullptr; + +#undef QT_METATYPE_TYPEID_TYPENAME_CONVERTER } /* diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 8088b18ef4..8e906b278d 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -3708,7 +3708,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i continue; QObject * const receiver = c->receiver; - const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId; + const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId.load(); // determine if this connection should be sent immediately or // put into the event queue |