summaryrefslogtreecommitdiffstats
path: root/src/declarative/util/qdeclarativexmllistmodel.cpp
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2010-06-17 06:36:00 (GMT)
committerMartin Jones <martin.jones@nokia.com>2010-06-17 06:36:00 (GMT)
commitf8080432e1307c099aee65153870af7c1677ccba (patch)
tree4a09e84da73dfe09170f534999fd90ea02f52dc9 /src/declarative/util/qdeclarativexmllistmodel.cpp
parenta6b0458c5ab5bc8ad6c868425820e0bf0e932336 (diff)
downloadQt-f8080432e1307c099aee65153870af7c1677ccba.zip
Qt-f8080432e1307c099aee65153870af7c1677ccba.tar.gz
Qt-f8080432e1307c099aee65153870af7c1677ccba.tar.bz2
XmlListModel: Don't lock while doing the slow bit.
Diffstat (limited to 'src/declarative/util/qdeclarativexmllistmodel.cpp')
-rw-r--r--src/declarative/util/qdeclarativexmllistmodel.cpp71
1 files changed, 41 insertions, 30 deletions
diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp
index 4adef25..bfd25be 100644
--- a/src/declarative/util/qdeclarativexmllistmodel.cpp
+++ b/src/declarative/util/qdeclarativexmllistmodel.cpp
@@ -148,6 +148,7 @@ public:
QDeclarativeXmlQuery(QObject *parent=0)
: QThread(parent), m_quit(false), m_abortQueryId(-1), m_queryIds(XMLLISTMODEL_CLEAR_ID + 1) {
qRegisterMetaType<QDeclarativeXmlQueryResult>("QDeclarativeXmlQueryResult");
+ m_currentJob.queryId = -1;
}
~QDeclarativeXmlQuery() {
@@ -161,6 +162,13 @@ public:
void abort(int id) {
QMutexLocker locker(&m_mutex);
+ QQueue<XmlQueryJob>::iterator it;
+ for (it = m_jobs.begin(); it != m_jobs.end(); ++it) {
+ if ((*it).queryId == id) {
+ m_jobs.erase(it);
+ return;
+ }
+ }
m_abortQueryId = id;
}
@@ -188,7 +196,7 @@ public:
m_queryIds++;
if (!isRunning())
- start();
+ start(QThread::IdlePriority);
else
m_condition.wakeOne();
return job.queryId;
@@ -202,24 +210,28 @@ protected:
void run() {
while (!m_quit) {
m_mutex.lock();
- doQueryJob();
- doSubQueryJob();
+ if (!m_jobs.isEmpty())
+ m_currentJob = m_jobs.dequeue();
m_mutex.unlock();
- m_mutex.lock();
- const XmlQueryJob &job = m_jobs.dequeue();
- if (m_abortQueryId != job.queryId) {
- QDeclarativeXmlQueryResult r;
- r.queryId = job.queryId;
+ QDeclarativeXmlQueryResult r;
+ if (m_currentJob.queryId != -1) {
+ doQueryJob();
+ doSubQueryJob();
+ r.queryId = m_currentJob.queryId;
r.size = m_size;
r.data = m_modelData;
r.inserted = m_insertedItemRanges;
r.removed = m_removedItemRanges;
- r.keyRoleResultsCache = job.keyRoleResultsCache;
- emit queryCompleted(r);
+ r.keyRoleResultsCache = m_currentJob.keyRoleResultsCache;
}
+
+ m_mutex.lock();
+ if (m_currentJob.queryId != -1 && m_abortQueryId != m_currentJob.queryId)
+ emit queryCompleted(r);
if (m_jobs.isEmpty())
m_condition.wait(&m_mutex);
+ m_currentJob.queryId = -1;
m_abortQueryId = -1;
m_mutex.unlock();
}
@@ -235,6 +247,7 @@ private:
QMutex m_mutex;
QWaitCondition m_condition;
QQueue<XmlQueryJob> m_jobs;
+ XmlQueryJob m_currentJob;
bool m_quit;
int m_abortQueryId;
QString m_prefix;
@@ -249,15 +262,14 @@ Q_GLOBAL_STATIC(QDeclarativeXmlQuery, globalXmlQuery)
void QDeclarativeXmlQuery::doQueryJob()
{
- Q_ASSERT(!m_jobs.isEmpty());
- XmlQueryJob &job = m_jobs.head();
+ Q_ASSERT(m_currentJob.queryId != -1);
QString r;
QXmlQuery query;
- QBuffer buffer(&job.data);
+ QBuffer buffer(&m_currentJob.data);
buffer.open(QIODevice::ReadOnly);
query.bindVariable(QLatin1String("src"), &buffer);
- query.setQuery(job.namespaces + job.query);
+ query.setQuery(m_currentJob.namespaces + m_currentJob.query);
query.evaluateTo(&r);
//always need a single root element
@@ -265,9 +277,9 @@ void QDeclarativeXmlQuery::doQueryJob()
QBuffer b(&xml);
b.open(QIODevice::ReadOnly);
- QString namespaces = QLatin1String("declare namespace dummy=\"http://qtsotware.com/dummy\";\n") + job.namespaces;
+ QString namespaces = QLatin1String("declare namespace dummy=\"http://qtsotware.com/dummy\";\n") + m_currentJob.namespaces;
QString prefix = QLatin1String("doc($inputDocument)/dummy:items") +
- job.query.mid(job.query.lastIndexOf(QLatin1Char('/')));
+ m_currentJob.query.mid(m_currentJob.query.lastIndexOf(QLatin1Char('/')));
//figure out how many items we are dealing with
int count = -1;
@@ -282,7 +294,7 @@ void QDeclarativeXmlQuery::doQueryJob()
count = item.toAtomicValue().toInt();
}
- job.data = xml;
+ m_currentJob.data = xml;
m_prefix = namespaces + prefix + QLatin1Char('/');
m_size = 0;
if (count > 0)
@@ -291,9 +303,9 @@ void QDeclarativeXmlQuery::doQueryJob()
void QDeclarativeXmlQuery::getValuesOfKeyRoles(QStringList *values, QXmlQuery *query) const
{
- Q_ASSERT(!m_jobs.isEmpty());
+ Q_ASSERT(m_currentJob.queryId != -1);
- const QStringList &keysQueries = m_jobs.head().keyRoleQueries;
+ const QStringList &keysQueries = m_currentJob.keyRoleQueries;
QString keysQuery;
if (keysQueries.count() == 1)
keysQuery = m_prefix + keysQueries[0];
@@ -323,11 +335,10 @@ void QDeclarativeXmlQuery::addIndexToRangeList(QList<QDeclarativeXmlListRange> *
void QDeclarativeXmlQuery::doSubQueryJob()
{
- Q_ASSERT(!m_jobs.isEmpty());
- XmlQueryJob &job = m_jobs.head();
+ Q_ASSERT(m_currentJob.queryId != -1);
m_modelData.clear();
- QBuffer b(&job.data);
+ QBuffer b(&m_currentJob.data);
b.open(QIODevice::ReadOnly);
QXmlQuery subquery;
@@ -340,16 +351,16 @@ void QDeclarativeXmlQuery::doSubQueryJob()
m_insertedItemRanges.clear();
m_removedItemRanges.clear();
- if (job.keyRoleResultsCache.isEmpty()) {
+ if (m_currentJob.keyRoleResultsCache.isEmpty()) {
m_insertedItemRanges << qMakePair(0, m_size);
} else {
- if (keyRoleResults != job.keyRoleResultsCache) {
+ if (keyRoleResults != m_currentJob.keyRoleResultsCache) {
QStringList temp;
- for (int i=0; i<job.keyRoleResultsCache.count(); i++) {
- if (!keyRoleResults.contains(job.keyRoleResultsCache[i]))
+ for (int i=0; i<m_currentJob.keyRoleResultsCache.count(); i++) {
+ if (!keyRoleResults.contains(m_currentJob.keyRoleResultsCache[i]))
addIndexToRangeList(&m_removedItemRanges, i);
else
- temp << job.keyRoleResultsCache[i];
+ temp << m_currentJob.keyRoleResultsCache[i];
}
for (int i=0; i<keyRoleResults.count(); i++) {
@@ -360,11 +371,11 @@ void QDeclarativeXmlQuery::doSubQueryJob()
}
}
}
- job.keyRoleResultsCache = keyRoleResults;
+ m_currentJob.keyRoleResultsCache = keyRoleResults;
// Get the new values for each role.
//### we might be able to condense even further (query for everything in one go)
- const QStringList &queries = job.roleQueries;
+ const QStringList &queries = m_currentJob.roleQueries;
for (int i = 0; i < queries.size(); ++i) {
QList<QVariant> resultList;
if (!queries[i].isEmpty()) {
@@ -378,7 +389,7 @@ void QDeclarativeXmlQuery::doSubQueryJob()
item = resultItems.next();
}
} else {
- emit error(job.roleQueryErrorId.at(i), queries[i]);
+ emit error(m_currentJob.roleQueryErrorId.at(i), queries[i]);
}
}
//### should warn here if things have gone wrong.