diff --git a/src/file-io/collection.h b/src/file-io/collection.h --- a/src/file-io/collection.h +++ b/src/file-io/collection.h @@ -20,6 +20,8 @@ #define PALAPELI_COLLECTION_H #include +#include + class KConfig; class KConfigGroup; @@ -56,6 +58,7 @@ KConfig* m_config; KConfigGroup* m_group; + QMutex m_configMutex; }; } diff --git a/src/file-io/collection.cpp b/src/file-io/collection.cpp --- a/src/file-io/collection.cpp +++ b/src/file-io/collection.cpp @@ -129,7 +129,7 @@ //construct puzzle with CollectionStorageComponent if (!path.isEmpty() && (desktopPath.isEmpty() || QFileInfo(path).lastModified() >= QFileInfo(desktopPath).lastModified())) { - Palapeli::Puzzle* puzzle = new Palapeli::Puzzle(new Palapeli::CollectionStorageComponent(puzzleGroup), path, puzzleId); + Palapeli::Puzzle* puzzle = new Palapeli::Puzzle(new Palapeli::CollectionStorageComponent(puzzleGroup, &m_configMutex), path, puzzleId); appendRow(new Item(puzzle)); continue; } @@ -176,9 +176,11 @@ puzzle->get(Palapeli::PuzzleComponent::ArchiveStorage).waitForFinished(); //create the config group for this puzzle (use pseudo-URL to avoid problems //when the configuration directory is moved) + m_configMutex.lock(); KConfigGroup puzzleGroup(m_group, id); puzzleGroup.writeEntry("Location", palapeliUrl); m_config->sync(); + m_configMutex.unlock(); //add to the model appendRow(new Item(puzzle)); } @@ -217,8 +219,10 @@ if (!QFile(puzzle->location()).remove()) return false; //remove puzzle from config + m_configMutex.lock(); KConfigGroup(m_group, puzzle->identifier()).deleteGroup(); m_config->sync(); + m_configMutex.unlock(); //remove puzzle from model and delete it const int count = rowCount(); for (int row = 0; row < count; ++row) diff --git a/src/file-io/components-collectionstorage.cpp b/src/file-io/components-collectionstorage.cpp --- a/src/file-io/components-collectionstorage.cpp +++ b/src/file-io/components-collectionstorage.cpp @@ -21,9 +21,10 @@ #include #include #include +#include -Palapeli::CollectionStorageComponent::CollectionStorageComponent(KConfigGroup* group) - : m_group(group) +Palapeli::CollectionStorageComponent::CollectionStorageComponent(KConfigGroup* group, QMutex *groupMutex) + : m_group(group), m_groupMutex(groupMutex) { } @@ -45,6 +46,7 @@ } //try to serve metadata from cache const QDateTime mtime = QFileInfo(file).lastModified(); + m_groupMutex->lock(); if (m_group->readEntry("ModifyDateTime", QDateTime()) == mtime) { //cache is up-to-date @@ -55,10 +57,12 @@ metadata.pieceCount = m_group->readEntry("PieceCount", 0); metadata.modifyProtection = m_group->readEntry("ModifyProtection", false); metadata.thumbnail.loadFromData(m_group->readEntry("Thumbnail", QByteArray())); + m_groupMutex->unlock(); return new Palapeli::MetadataComponent(metadata); } else { + m_groupMutex->unlock(); //read metadata from archive... const Palapeli::PuzzleComponent* arStorage = puzzle()->get(ArchiveStorage); if (!arStorage) @@ -69,16 +73,18 @@ //...and populate cache (image is written via a buffer //because KConfig does not support QImage directly) const Palapeli::PuzzleMetadata metadata = dynamic_cast(cMetadata)->metadata; + QBuffer buffer; + metadata.thumbnail.save(&buffer, "PNG"); + m_groupMutex->lock(); m_group->writeEntry("Name", metadata.name); m_group->writeEntry("Comment", metadata.comment); m_group->writeEntry("Author", metadata.author); m_group->writeEntry("PieceCount", metadata.pieceCount); m_group->writeEntry("ModifyProtection", metadata.modifyProtection); m_group->writeEntry("ModifyDateTime", mtime); - QBuffer buffer; - metadata.thumbnail.save(&buffer, "PNG"); m_group->writeEntry("Thumbnail", buffer.data()); m_group->sync(); + m_groupMutex->unlock(); return cMetadata; } } diff --git a/src/file-io/components.h b/src/file-io/components.h --- a/src/file-io/components.h +++ b/src/file-io/components.h @@ -106,12 +106,13 @@ COMPONENT_SUBCLASS(CollectionStorage) public: ///Takes ownership of @a group. - CollectionStorageComponent(KConfigGroup* group); + CollectionStorageComponent(KConfigGroup* group, QMutex *groupMutex); virtual ~CollectionStorageComponent(); Palapeli::PuzzleComponent* cast(Type type) const Q_DECL_OVERRIDE; private: KConfigGroup* m_group; + QMutex *m_groupMutex; }; ///This is used by the collection if, instead of an actual puzzle archive,