From c7d8462bf8919fa887d264adcccdf1e38eb6422c Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Mon, 26 Sep 2011 15:07:12 +0200 Subject: [PATCH] QmlJS: Fix threading issue in QmlObjectValue. Still need to get rid of the lock in ValueOwner::registerValue. Change-Id: If9bbc548de54edf52805906aaaf730f5c66573dd Reviewed-on: http://codereview.qt-project.org/5542 Reviewed-by: Fawzi Mohamed --- src/libs/qmljs/qmljsinterpreter.cpp | 26 ++++++++++++++------------ src/libs/qmljs/qmljsinterpreter.h | 4 +--- src/libs/qmljs/qmljsvalueowner.cpp | 1 + 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp index 94518dbde99..3c57475f67d 100644 --- a/src/libs/qmljs/qmljsinterpreter.cpp +++ b/src/libs/qmljs/qmljsinterpreter.cpp @@ -182,17 +182,6 @@ QmlObjectValue::QmlObjectValue(FakeMetaObject::ConstPtr metaObject, const QStrin QmlObjectValue::~QmlObjectValue() {} -const Value *QmlObjectValue::findOrCreateSignature(int index, const FakeMetaMethod &method, QString *methodName) const -{ - *methodName = method.methodName(); - const Value *value = _metaSignature.value(index); - if (! value) { - value = new MetaFunction(method, valueOwner()); - _metaSignature.insert(index, value); - } - return value; -} - void QmlObjectValue::processMembers(MemberProcessor *processor) const { // process the meta enums @@ -207,6 +196,19 @@ void QmlObjectValue::processMembers(MemberProcessor *processor) const // all explicitly defined signal names QSet explicitSignals; + // make MetaFunction instances lazily when first needed + QList *signatures = _metaSignatures; + if (!signatures) { + signatures = new QList; + signatures->reserve(_metaObject->methodCount()); + for (int index = 0; index < _metaObject->methodCount(); ++index) + signatures->append(new MetaFunction(_metaObject->method(index), valueOwner())); + if (!_metaSignatures.testAndSetOrdered(0, signatures)) { + delete signatures; + signatures = _metaSignatures; + } + } + // process the meta methods for (int index = 0; index < _metaObject->methodCount(); ++index) { const FakeMetaMethod method = _metaObject->method(index); @@ -214,7 +216,7 @@ void QmlObjectValue::processMembers(MemberProcessor *processor) const continue; QString methodName; - const Value *signature = findOrCreateSignature(index, method, &methodName); + const Value *signature = signatures->at(index); if (method.methodType() == FakeMetaMethod::Slot && method.access() == FakeMetaMethod::Public) { processor->processSlot(methodName, signature); diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h index 804e52b03e3..92d1978e9fe 100644 --- a/src/libs/qmljs/qmljsinterpreter.h +++ b/src/libs/qmljs/qmljsinterpreter.h @@ -449,8 +449,6 @@ public: LanguageUtils::FakeMetaEnum getEnum(const QString &typeName, const QmlObjectValue **foundInScope = 0) const; const QmlEnumValue *getEnumValue(const QString &typeName, const QmlObjectValue **foundInScope = 0) const; protected: - const Value *findOrCreateSignature(int index, const LanguageUtils::FakeMetaMethod &method, - QString *methodName) const; bool isDerivedFrom(LanguageUtils::FakeMetaObject::ConstPtr base) const; private: @@ -462,7 +460,7 @@ private: // needed in cases when B 1.0 has A 1.1 as prototype when imported as 1.1 const LanguageUtils::ComponentVersion _componentVersion; const LanguageUtils::ComponentVersion _importVersion; - mutable QHash _metaSignature; + mutable QAtomicPointer< QList > _metaSignatures; QHash _enums; int _metaObjectRevision; }; diff --git a/src/libs/qmljs/qmljsvalueowner.cpp b/src/libs/qmljs/qmljsvalueowner.cpp index c6ef8fd52c2..aaa9f4d28b4 100644 --- a/src/libs/qmljs/qmljsvalueowner.cpp +++ b/src/libs/qmljs/qmljsvalueowner.cpp @@ -453,6 +453,7 @@ const ObjectValue *ValueOwner::qtObject() const void ValueOwner::registerValue(Value *value) { + // ### get rid of this lock QMutexLocker locker(&_mutex); _registeredValues.append(value); }