diff options
author | Martin Jones <martin.jones@nokia.com> | 2010-03-30 06:03:29 (GMT) |
---|---|---|
committer | Martin Jones <martin.jones@nokia.com> | 2010-03-30 06:03:29 (GMT) |
commit | ff983ee8257b79143911ca58ebedc49b1660a0c4 (patch) | |
tree | c09ee8766332604a63874b7ac4ce1816afda1b9a | |
parent | 8368e041e35ab2a79c79f651a56e6ee53a46549f (diff) | |
download | Qt-ff983ee8257b79143911ca58ebedc49b1660a0c4.zip Qt-ff983ee8257b79143911ca58ebedc49b1660a0c4.tar.gz Qt-ff983ee8257b79143911ca58ebedc49b1660a0c4.tar.bz2 |
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
-rw-r--r-- | src/declarative/util/qdeclarativepixmapcache.cpp | 18 |
1 files 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<QDeclarativePixmapReply*> cancelled; QDeclarativeEngine *engine; QDeclarativeImageRequestHandler *handler; - QWaitCondition started; + QObject *eventLoopQuitHack; QMutex mutex; static QHash<QDeclarativeEngine *,QDeclarativeImageReader*> 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(); |