aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/ApiExtractor/typesystem.cpp
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2018-07-25 11:42:39 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2018-07-25 12:16:31 +0000
commitbe202bd1baf600c7b422c96cc6b47a327e7a9d23 (patch)
tree187183f6636901b36c1e0c87708040c653b7d0fd /sources/shiboken2/ApiExtractor/typesystem.cpp
parentfdae2fce386cb4d72c4528b7e868c61860c43069 (diff)
shiboken: Fix the allow-thread attribute to actually have an effect
Previously, calls to BEGIN_ALLOW_THREADS/END_ALLOW_THREADS were always generated since the value of XML attribute was not used. Fix it to actually use the value. Since having it default to "no" caused a number of deadlocks (related to thread functions or functions calling a virtual function (potentially reimplemented in Python), introduce "auto" as default value. "auto" turns off BEGIN_ALLOW_THREADS/END_ALLOW_THREADS for simple getter functions. Task-number: PYSIDE-743 Change-Id: I4833afef14f2552c75b3424417c2702ce25cb379 Reviewed-by: Christian Tismer <tismer@stackless.com> Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources/shiboken2/ApiExtractor/typesystem.cpp')
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.cpp39
1 files changed, 34 insertions, 5 deletions
diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp
index 70563286c..1eab95248 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystem.cpp
@@ -171,6 +171,17 @@ static EnumType functionName(QStringView needle, EnumType defaultValue = default
return lb != end && *lb == needleEntry ? lb->value : defaultValue; \
}
+ENUM_LOOKUP_BEGIN(TypeSystem::AllowThread, Qt::CaseInsensitive,
+ allowThreadFromAttribute, TypeSystem::AllowThread::Unspecified)
+ {
+ {QStringViewLiteral("yes"), TypeSystem::AllowThread::Allow},
+ {QStringViewLiteral("true"), TypeSystem::AllowThread::Allow},
+ {QStringViewLiteral("auto"), TypeSystem::AllowThread::Auto},
+ {QStringViewLiteral("no"), TypeSystem::AllowThread::Disallow},
+ {QStringViewLiteral("false"), TypeSystem::AllowThread::Disallow},
+ };
+ENUM_LOOKUP_LINEAR_SEARCH()
+
ENUM_LOOKUP_BEGIN(TypeSystem::Language, Qt::CaseInsensitive,
languageFromAttribute, TypeSystem::NoLanguage)
{
@@ -363,6 +374,19 @@ static QString msgMissingAttribute(const QString &a)
+ QLatin1String("' missing.");
}
+QTextStream &operator<<(QTextStream &str, const QXmlStreamAttribute &attribute)
+{
+ str << attribute.qualifiedName() << "=\"" << attribute.value() << '"';
+ return str;
+}
+
+static QString msgInvalidAttributeValue(const QXmlStreamAttribute &attribute)
+{
+ QString result;
+ QTextStream(&result) << "Invalid attribute value:" << attribute;
+ return result;
+}
+
static QString msgUnusedAttributes(const QStringRef &tag, const QXmlStreamAttributes &attributes)
{
QString result;
@@ -371,7 +395,7 @@ static QString msgUnusedAttributes(const QStringRef &tag, const QXmlStreamAttrib
for (int i = 0, size = attributes.size(); i < size; ++i) {
if (i)
str << ", ";
- str << attributes.at(i).qualifiedName() << "=\"" << attributes.at(i).value() << '"';
+ str << attributes.at(i);
}
return result;
}
@@ -1853,7 +1877,7 @@ bool Handler::parseModifyFunction(const QXmlStreamReader &,
QString association;
bool deprecated = false;
bool isThread = false;
- bool allowThread = false;
+ TypeSystem::AllowThread allowThread = TypeSystem::AllowThread::Unspecified;
bool virtualSlot = false;
for (int i = attributes->size() - 1; i >= 0; --i) {
const QStringRef name = attributes->at(i).qualifiedName();
@@ -1874,8 +1898,12 @@ bool Handler::parseModifyFunction(const QXmlStreamReader &,
isThread = convertBoolean(attributes->takeAt(i).value(),
threadAttribute(), false);
} else if (name == allowThreadAttribute()) {
- allowThread = convertBoolean(attributes->takeAt(i).value(),
- allowThreadAttribute(), false);
+ const QXmlStreamAttribute attribute = attributes->takeAt(i);
+ allowThread = allowThreadFromAttribute(attribute.value());
+ if (allowThread == TypeSystem::AllowThread::Unspecified) {
+ m_error = msgInvalidAttributeValue(attribute);
+ return false;
+ }
} else if (name == virtualSlotAttribute()) {
virtualSlot = convertBoolean(attributes->takeAt(i).value(),
virtualSlotAttribute(), false);
@@ -1924,7 +1952,8 @@ bool Handler::parseModifyFunction(const QXmlStreamReader &,
mod.association = association;
mod.setIsThread(isThread);
- mod.setAllowThread(allowThread);
+ if (allowThread != TypeSystem::AllowThread::Unspecified)
+ mod.setAllowThread(allowThread);
if (virtualSlot)
mod.modifiers |= Modification::VirtualSlot;