From 7139f6ed6e49c7ddcd3e90940ac703487de95c92 Mon Sep 17 00:00:00 2001 From: "Robert C. Helling" Date: Fri, 29 Apr 2016 16:18:06 +0200 Subject: [PATCH] Protect access to image hash dictionaries with lock Otherwise we step on our own feet when downloading several images, like after import from divelogs.de with many linked images. Signed-off-by: Robert C. Helling --- core/imagedownloader.cpp | 2 ++ core/qthelper.cpp | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/core/imagedownloader.cpp b/core/imagedownloader.cpp index f406ee4..dc74a1e 100644 --- a/core/imagedownloader.cpp +++ b/core/imagedownloader.cpp @@ -77,6 +77,8 @@ void ImageDownloader::saveImage(QNetworkReply *reply) void loadPicture(struct picture *picture, bool fromHash) { + if (!picture) + return; ImageDownloader download(picture); download.load(fromHash); } diff --git a/core/qthelper.cpp b/core/qthelper.cpp index a261cca..4bc3c5b 100644 --- a/core/qthelper.cpp +++ b/core/qthelper.cpp @@ -996,6 +996,7 @@ QHash thumbnailCache; extern "C" char * hashstring(char * filename) { + QMutexLocker locker(&hashOfMutex); return hashOf[QString(filename)].toHex().data(); } @@ -1012,6 +1013,7 @@ extern "C" char *hashfile_name_string() void read_hashes() { QFile hashfile(hashfile_name()); + QMutexLocker locker(&hashOfMutex); if (hashfile.open(QIODevice::ReadOnly)) { QDataStream stream(&hashfile); stream >> localFilenameOf; @@ -1024,6 +1026,8 @@ void read_hashes() void write_hashes() { QSaveFile hashfile(hashfile_name()); + QMutexLocker locker(&hashOfMutex); + if (hashfile.open(QIODevice::WriteOnly)) { QDataStream stream(&hashfile); stream << localFilenameOf; @@ -1064,8 +1068,16 @@ void learnHash(struct picture *picture, QByteArray hash) picture->hash = strdup(hash.toHex()); } +bool haveHash(QString &filename) +{ + QMutexLocker locker(&hashOfMutex); + return hashOf.contains(filename); +} + QString localFilePath(const QString originalFilename) { + QMutexLocker locker(&hashOfMutex); + if (hashOf.contains(originalFilename) && localFilenameOf.contains(hashOf[originalFilename])) return localFilenameOf[hashOf[originalFilename]]; else @@ -1074,11 +1086,15 @@ QString localFilePath(const QString originalFilename) QString fileFromHash(char *hash) { + QMutexLocker locker(&hashOfMutex); + return localFilenameOf[QByteArray::fromHex(hash)]; } // This needs to operate on a copy of picture as it frees it after finishing! void updateHash(struct picture *picture) { + if (!picture) + return; QByteArray hash = hashFile(fileFromHash(picture->hash)); learnHash(picture, hash); picture_free(picture); @@ -1087,6 +1103,8 @@ void updateHash(struct picture *picture) { // This needs to operate on a copy of picture as it frees it after finishing! void hashPicture(struct picture *picture) { + if (!picture) + return; char *oldHash = copy_string(picture->hash); learnHash(picture, hashFile(QString(picture->filename))); if (!same_string(picture->hash, "") && !same_string(picture->hash, oldHash)) @@ -1098,7 +1116,7 @@ void hashPicture(struct picture *picture) extern "C" void cache_picture(struct picture *picture) { QString filename = picture->filename; - if (!hashOf.contains(filename)) + if (!haveHash(filename)) QtConcurrent::run(hashPicture, clone_picture(picture)); } -- 2.6.4 (Apple Git-63)