From ff983ee8257b79143911ca58ebedc49b1660a0c4 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 30 Mar 2010 16:03:29 +1000 Subject: Make qmlpixmapcache thread shutdown cleaner Change to Thiago's method: QThread::quit() is *not* thread-safe, so we mustn't call it from outside the QThread that the QThread holds. Unlike other QObjects, this method and some others must not be called from the thread they have affinity to. So add a hack to call it in the auxiliary thread. Do that by connecting a dummy QObject's destroyed() signal to the quit() slot in a DirectConnection, then move the object to the thread. When we call deleteLater(), this will cause the thread's event loop to delete the object, which in turn calls quit() in the actual thread. Reviewed-by: Thiago Macieira --- src/declarative/util/qdeclarativepixmapcache.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp index a9c30f8..1da929e 100644 --- a/src/declarative/util/qdeclarativepixmapcache.cpp +++ b/src/declarative/util/qdeclarativepixmapcache.cpp @@ -114,7 +114,7 @@ private: QList cancelled; QDeclarativeEngine *engine; QDeclarativeImageRequestHandler *handler; - QWaitCondition started; + QObject *eventLoopQuitHack; QMutex mutex; static QHash readers; @@ -370,6 +370,9 @@ void QDeclarativeImageRequestHandler::networkRequestDone() QDeclarativeImageReader::QDeclarativeImageReader(QDeclarativeEngine *eng) : QThread(eng), engine(eng), handler(0) { + eventLoopQuitHack = new QObject; + eventLoopQuitHack->moveToThread(this); + connect(eventLoopQuitHack, SIGNAL(destroyed(QObject*)), SLOT(quit()), Qt::DirectConnection); start(QThread::IdlePriority); } @@ -379,15 +382,8 @@ QDeclarativeImageReader::~QDeclarativeImageReader() readers.remove(engine); readerMutex.unlock(); - if (isRunning()) { - quit(); - while (!wait(100)) { - // It is possible to for the quit to happen before exec() - // Need to wait until the event loop starts so that we - // can stop it. Particularly likely with an idle thread. - quit(); - } - } + eventLoopQuitHack->deleteLater(); + wait(); } QDeclarativeImageReader *QDeclarativeImageReader::instance(QDeclarativeEngine *engine) @@ -396,7 +392,6 @@ QDeclarativeImageReader *QDeclarativeImageReader::instance(QDeclarativeEngine *e QDeclarativeImageReader *reader = readers.value(engine); if (!reader) { reader = new QDeclarativeImageReader(engine); - reader->started.wait(&readerMutex); readers.insert(engine, reader); } readerMutex.unlock(); @@ -433,7 +428,6 @@ void QDeclarativeImageReader::run() { readerMutex.lock(); handler = new QDeclarativeImageRequestHandler(this, engine); - started.wakeAll(); readerMutex.unlock(); exec(); -- cgit v0.12