Fix a crash with newest library

This is basically a replica of
4c0020385a
for Spectral.
This commit is contained in:
Kitsune Ral
2019-02-28 10:34:24 +00:00
parent b71359e92a
commit c2f66dcc70
2 changed files with 38 additions and 32 deletions

View File

@@ -4,39 +4,38 @@
#include <jobs/mediathumbnailjob.h>
#include <QtCore/QDebug>
#include <QtCore/QThread>
#include <QtCore/QReadWriteLock>
using QMatrixClient::BaseJob;
using QMatrixClient::Connection;
ThumbnailResponse::ThumbnailResponse(Connection* c, QString mediaId,
const QSize& requestedSize)
: c(c),
mediaId(std::move(mediaId)),
requestedSize(requestedSize),
errorStr("Image request hasn't started") {
moveToThread(c->thread());
ThumbnailResponse::ThumbnailResponse(QMatrixClient::Connection* c,
QString mediaId, const QSize& requestedSize)
: c(c),
mediaId(std::move(mediaId)),
requestedSize(requestedSize),
errorStr("Image request hasn't started") {
if (requestedSize.isEmpty()) {
errorStr.clear();
emit finished();
return;
}
if (mediaId.count('/') != 1) {
errorStr =
tr("Media id '%1' doesn't follow server/mediaId pattern")
.arg(mediaId);
emit finished();
return;
}
// Execute a request on the main thread asynchronously
moveToThread(c->thread());
QMetaObject::invokeMethod(this, &ThumbnailResponse::startRequest,
Qt::QueuedConnection);
}
void ThumbnailResponse::startRequest() {
// Runs in the main thread, not QML thread
if (mediaId.count('/') != 1) {
errorStr =
QStringLiteral("Media id '%1' doesn't follow server/mediaId pattern")
.arg(mediaId);
emit finished();
return;
}
QWriteLocker _(&lock);
Q_ASSERT(QThread::currentThread() == c->thread());
job = c->getThumbnail(mediaId, requestedSize);
// Connect to any possible outcome including abandonment
// to make sure the QML thread is not left stuck forever.
@@ -44,13 +43,16 @@ void ThumbnailResponse::startRequest() {
}
void ThumbnailResponse::prepareResult() {
Q_ASSERT(QThread::currentThread() == job->thread());
Q_ASSERT(job->error() != BaseJob::Pending);
{
QWriteLocker _(&lock);
Q_ASSERT(job->error() != BaseJob::Pending);
if (job->error() == BaseJob::Success) {
image = job->thumbnail();
errorStr.clear();
} else if (job->error() == BaseJob::Abandoned) {
errorStr = tr("Image request has been cancelled");
qDebug() << "ThumbnailResponse: cancelled for" << mediaId;
} else {
errorStr = job->errorString();
qWarning() << "ThumbnailResponse: no valid image for" << mediaId << "-"
@@ -61,6 +63,13 @@ void ThumbnailResponse::prepareResult() {
emit finished();
}
void ThumbnailResponse::doCancel() {
// Runs in the main thread, not QML thread
Q_ASSERT(QThread::currentThread() == job->thread());
if (job)
job->abandon();
}
QQuickTextureFactory* ThumbnailResponse::textureFactory() const {
QReadLocker _(&lock);
return QQuickTextureFactory::textureFactoryForImage(image);
@@ -72,12 +81,8 @@ QString ThumbnailResponse::errorString() const {
}
void ThumbnailResponse::cancel() {
QWriteLocker _(&lock);
if (job) {
job->abandon();
job = nullptr;
}
errorStr = "Image request has been cancelled";
QMetaObject::invokeMethod(this, &ThumbnailResponse::doCancel,
Qt::QueuedConnection);
}
QQuickImageResponse* ImageProvider::requestImageResponse(