1

I need to evaluate a lot of prepared xqueries against a stream of XMLs, since QXmlQuery instances created at startup, copying or moving them to the thread causes an assertion failure. At this point i solve this by creating an instance of QXmlQuery at each iteration, which leads to an overhead that I would like to avoid with code like:

#include <QFile>
#include <QtXml>
#include <QtXmlPatterns>
#include <QtConcurrent>
 
QString  async_eval(QString doc, QXmlQuery query)
{
    QString result;
    QXmlQuery second_query(query); // This line will fail with ASSERT (see below)
    second_query.setFocus(doc);
    second_query.evaluateTo(&result);
    return result;
}
 
int main(int argc, char* argv[])
{
    QCoreApplication a(argc, argv);
    QFile f("input.xml");
    f.open(QIODevice::ReadOnly);
    QTextStream stream(&f);
    QTextCodec* codec = QTextCodec::codecForName("utf-8");
    stream.setCodec(codec);
    QString doc = stream.readAll();
 
    QString first_xpath("//price");
    QXmlQuery first_q;
    first_q.setFocus(doc);
    first_q.setQuery(first_xpath);
    QString first_res;
 
    std::cout << "First query will be evaluated without warnings" << '\n';
    first_q.evaluateTo(&first_res);
    std::cout << "first_res = " << first_res.toUtf8().data() << '\n';
 
    std::cout << "Second query will be evaluated with warnings or with debug assert" << '\n';
    auto future = QtConcurrent::run(QThreadPool::globalInstance(), async_eval, doc, first_q);
    future.waitForFinished();
 
    QString second_res = future.result();
    std::cout << "second_res= " << second_res.toUtf8().data() << '\n';
    return 0;
}

This code fails with:

ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 0x0x38cb97f930. Receiver '' (of type 'QObject') was created in thread 0x0x17d03fcf5b0", file kernel\qcoreapplication.cpp, line 558 QObject: Cannot create children for a parent that is in a different thread.

tomato
  • 13
  • 2

0 Answers0