summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-02-16 21:46:20 +0100
committerLiang Qi <liang.qi@qt.io>2017-02-16 21:51:11 +0100
commitc577f6edafef7c40a5f78092ec4fcd78bb820b2c (patch)
tree9ca3819e5cca9b7e61f305a874b682e5a2085e83 /src/corelib/kernel
parent99ce1d3d97c0423c3ee63ccf58deed964db0770e (diff)
parentde225ccdf95efb57866d62bc80872c1a2ab99703 (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.cpp49
-rw-r--r--src/corelib/kernel/qmetatype.cpp39
-rw-r--r--src/corelib/kernel/qobject.cpp2
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