mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
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 <helling@atdotde.de> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
cae99471ad
commit
2e6588dc0e
2 changed files with 21 additions and 1 deletions
|
@ -77,6 +77,8 @@ void ImageDownloader::saveImage(QNetworkReply *reply)
|
||||||
|
|
||||||
void loadPicture(struct picture *picture, bool fromHash)
|
void loadPicture(struct picture *picture, bool fromHash)
|
||||||
{
|
{
|
||||||
|
if (!picture)
|
||||||
|
return;
|
||||||
ImageDownloader download(picture);
|
ImageDownloader download(picture);
|
||||||
download.load(fromHash);
|
download.load(fromHash);
|
||||||
}
|
}
|
||||||
|
|
|
@ -996,6 +996,7 @@ QHash <QString, QImage > thumbnailCache;
|
||||||
|
|
||||||
extern "C" char * hashstring(char * filename)
|
extern "C" char * hashstring(char * filename)
|
||||||
{
|
{
|
||||||
|
QMutexLocker locker(&hashOfMutex);
|
||||||
return hashOf[QString(filename)].toHex().data();
|
return hashOf[QString(filename)].toHex().data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1012,6 +1013,7 @@ extern "C" char *hashfile_name_string()
|
||||||
void read_hashes()
|
void read_hashes()
|
||||||
{
|
{
|
||||||
QFile hashfile(hashfile_name());
|
QFile hashfile(hashfile_name());
|
||||||
|
QMutexLocker locker(&hashOfMutex);
|
||||||
if (hashfile.open(QIODevice::ReadOnly)) {
|
if (hashfile.open(QIODevice::ReadOnly)) {
|
||||||
QDataStream stream(&hashfile);
|
QDataStream stream(&hashfile);
|
||||||
stream >> localFilenameOf;
|
stream >> localFilenameOf;
|
||||||
|
@ -1024,6 +1026,8 @@ void read_hashes()
|
||||||
void write_hashes()
|
void write_hashes()
|
||||||
{
|
{
|
||||||
QSaveFile hashfile(hashfile_name());
|
QSaveFile hashfile(hashfile_name());
|
||||||
|
QMutexLocker locker(&hashOfMutex);
|
||||||
|
|
||||||
if (hashfile.open(QIODevice::WriteOnly)) {
|
if (hashfile.open(QIODevice::WriteOnly)) {
|
||||||
QDataStream stream(&hashfile);
|
QDataStream stream(&hashfile);
|
||||||
stream << localFilenameOf;
|
stream << localFilenameOf;
|
||||||
|
@ -1064,8 +1068,16 @@ void learnHash(struct picture *picture, QByteArray hash)
|
||||||
picture->hash = strdup(hash.toHex());
|
picture->hash = strdup(hash.toHex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool haveHash(QString &filename)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&hashOfMutex);
|
||||||
|
return hashOf.contains(filename);
|
||||||
|
}
|
||||||
|
|
||||||
QString localFilePath(const QString originalFilename)
|
QString localFilePath(const QString originalFilename)
|
||||||
{
|
{
|
||||||
|
QMutexLocker locker(&hashOfMutex);
|
||||||
|
|
||||||
if (hashOf.contains(originalFilename) && localFilenameOf.contains(hashOf[originalFilename]))
|
if (hashOf.contains(originalFilename) && localFilenameOf.contains(hashOf[originalFilename]))
|
||||||
return localFilenameOf[hashOf[originalFilename]];
|
return localFilenameOf[hashOf[originalFilename]];
|
||||||
else
|
else
|
||||||
|
@ -1074,11 +1086,15 @@ QString localFilePath(const QString originalFilename)
|
||||||
|
|
||||||
QString fileFromHash(char *hash)
|
QString fileFromHash(char *hash)
|
||||||
{
|
{
|
||||||
|
QMutexLocker locker(&hashOfMutex);
|
||||||
|
|
||||||
return localFilenameOf[QByteArray::fromHex(hash)];
|
return localFilenameOf[QByteArray::fromHex(hash)];
|
||||||
}
|
}
|
||||||
|
|
||||||
// This needs to operate on a copy of picture as it frees it after finishing!
|
// This needs to operate on a copy of picture as it frees it after finishing!
|
||||||
void updateHash(struct picture *picture) {
|
void updateHash(struct picture *picture) {
|
||||||
|
if (!picture)
|
||||||
|
return;
|
||||||
QByteArray hash = hashFile(fileFromHash(picture->hash));
|
QByteArray hash = hashFile(fileFromHash(picture->hash));
|
||||||
learnHash(picture, hash);
|
learnHash(picture, hash);
|
||||||
picture_free(picture);
|
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!
|
// This needs to operate on a copy of picture as it frees it after finishing!
|
||||||
void hashPicture(struct picture *picture)
|
void hashPicture(struct picture *picture)
|
||||||
{
|
{
|
||||||
|
if (!picture)
|
||||||
|
return;
|
||||||
char *oldHash = copy_string(picture->hash);
|
char *oldHash = copy_string(picture->hash);
|
||||||
learnHash(picture, hashFile(QString(picture->filename)));
|
learnHash(picture, hashFile(QString(picture->filename)));
|
||||||
if (!same_string(picture->hash, "") && !same_string(picture->hash, oldHash))
|
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)
|
extern "C" void cache_picture(struct picture *picture)
|
||||||
{
|
{
|
||||||
QString filename = picture->filename;
|
QString filename = picture->filename;
|
||||||
if (!hashOf.contains(filename))
|
if (!haveHash(filename))
|
||||||
QtConcurrent::run(hashPicture, clone_picture(picture));
|
QtConcurrent::run(hashPicture, clone_picture(picture));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue