cache: fixed double write corruption

This commit is contained in:
itsmattkc
2022-05-16 16:10:54 -07:00
parent a7c466bd6b
commit 9ba3f24f3b
4 changed files with 40 additions and 36 deletions
+32 -27
View File
@@ -36,8 +36,6 @@
namespace olive {
QMutex FrameHashCache::currently_saving_frames_mutex_;
QMap<QString, FramePtr> FrameHashCache::currently_saving_frames_;
const QString FrameHashCache::kCacheFormatExtension = QStringLiteral(".exr");
#define super PlaybackCache
@@ -81,23 +79,30 @@ bool FrameHashCache::SaveCacheFrame(const QString &cache_path, const QUuid &uuid
QString fn = CachePathName(cache_path, uuid, time);
QMutexLocker locker(&currently_saving_frames_mutex_);
currently_saving_frames_.insert(fn, frame);
locker.unlock();
bool ret = SaveCacheFrame(fn, frame);
locker.relock();
currently_saving_frames_.remove(fn);
locker.unlock();
// Register frame with the disk manager
if (ret) {
QMetaObject::invokeMethod(DiskManager::instance(),
"CreatedFile",
Qt::QueuedConnection,
Q_ARG(QString, cache_path),
Q_ARG(QString, fn));
DiskManager::instance()->CreatedFile(cache_path, fn);
}
return ret;
}
bool FrameHashCache::SaveCacheFrame(const QString &cache_path, const QUuid &uuid, const rational &time, const rational &tb, FramePtr frame)
{
if (cache_path.isEmpty()) {
qWarning() << "Failed to save cache frame with empty path";
return false;
}
QString fn = CachePathName(cache_path, uuid, time, tb);
bool ret = SaveCacheFrame(fn, frame);
// Register frame with the disk manager
if (ret) {
DiskManager::instance()->CreatedFile(cache_path, fn);
}
return ret;
@@ -110,12 +115,6 @@ FramePtr FrameHashCache::LoadCacheFrame(const QString &cache_path, const QUuid &
// we try to load a frame that's half way through being saved.
QString filename = CachePathName(cache_path, uuid, time);
QMutexLocker locker(&currently_saving_frames_mutex_);
if (currently_saving_frames_.contains(filename)) {
return currently_saving_frames_.value(filename);
}
locker.unlock();
if (cache_path.isEmpty()) {
qWarning() << "Failed to load cache frame with empty path";
return nullptr;
@@ -187,7 +186,7 @@ FramePtr FrameHashCache::LoadCacheFrame(const QString &fn)
frame = nullptr;
// Assume this frame is corrupt in some way and delete it
QMetaObject::invokeMethod(DiskManager::instance(), "DeleteSpecificFile", Qt::QueuedConnection, Q_ARG(QString, fn));
DiskManager::instance()->DeleteSpecificFile(fn);
}
}
@@ -233,20 +232,26 @@ QString FrameHashCache::CachePathName(const int64_t &time) const
return CachePathName(GetCacheDirectory(), uuid_, time);
}
QString FrameHashCache::CachePathName(const rational &time) const
{
return CachePathName(GetCacheDirectory(), uuid_, time, timebase_);
}
QString FrameHashCache::CachePathName(const QString &cache_path, const QUuid &cache_id, const int64_t &time)
{
QString filename = QDir(QDir(cache_path).filePath(cache_id.toString())).filePath(QString::number(time));
// Register that in some way this hash has been accessed
QMetaObject::invokeMethod(DiskManager::instance(),
"Accessed",
Qt::QueuedConnection,
Q_ARG(QString, cache_path),
Q_ARG(QString, filename));
DiskManager::instance()->Accessed(cache_path, filename);
return filename;
}
QString FrameHashCache::CachePathName(const QString &cache_path, const QUuid &cache_id, const rational &time, const rational &tb)
{
return CachePathName(cache_path, cache_id, Timecode::time_to_timestamp(time, tb, Timecode::kRound));
}
bool FrameHashCache::SaveCacheFrame(const QString &filename, const FramePtr frame)
{
if (!VideoParams::FormatIsFloat(frame->format())) {
+3 -6
View File
@@ -66,6 +66,7 @@ public:
static bool SaveCacheFrame(const QString& filename, FramePtr frame);
bool SaveCacheFrame(const int64_t &time, FramePtr frame) const;
static bool SaveCacheFrame(const QString& cache_path, const QUuid &uuid, const int64_t &time, FramePtr frame);
static bool SaveCacheFrame(const QString& cache_path, const QUuid &uuid, const rational &time, const rational &tb, FramePtr frame);
static FramePtr LoadCacheFrame(const QString& cache_path, const QUuid &uuid, const int64_t &time);
FramePtr LoadCacheFrame(const int64_t &time) const;
static FramePtr LoadCacheFrame(const QString& fn);
@@ -78,19 +79,15 @@ private:
* @brief Return the path of the cached image at this time
*/
QString CachePathName(const int64_t &time) const;
QString CachePathName(const rational &time) const
{
return CachePathName(ToTimestamp(time, Timecode::kRound));
}
QString CachePathName(const rational &time) const;
static QString CachePathName(const QString& cache_path, const QUuid &cache_id, const int64_t &time);
static QString CachePathName(const QString& cache_path, const QUuid &cache_id, const rational &time, const rational &tb);
rational timebase_;
QUuid uuid_;
static QMutex currently_saving_frames_mutex_;
static QMap<QString, FramePtr> currently_saving_frames_;
static const QString kCacheFormatExtension;
private slots:
+2 -1
View File
@@ -157,7 +157,8 @@ RenderTicketPtr RenderManager::SaveFrameToCache(FrameHashCache *cache, FramePtr
ticket->setProperty("cache", cache->GetCacheDirectory());
ticket->setProperty("frame", QVariant::fromValue(frame));
ticket->setProperty("time", QVariant::fromValue(Timecode::time_to_timestamp(time, cache->GetTimebase(), Timecode::kFloor)));
ticket->setProperty("time", QVariant::fromValue(time));
ticket->setProperty("timebase", QVariant::fromValue(cache->GetTimebase()));
ticket->setProperty("uuid", QVariant::fromValue(cache->GetUuid()));
ticket->setProperty("type", kTypeVideoDownload);
+3 -2
View File
@@ -219,10 +219,11 @@ void RenderProcessor::Run()
{
QString cache = ticket_->property("cache").toString();
FramePtr frame = ticket_->property("frame").value<FramePtr>();
int64_t time = ticket_->property("time").value<int64_t>();
rational time = ticket_->property("time").value<rational>();
rational timebase = ticket_->property("timebase").value<rational>();
QUuid uuid = ticket_->property("uuid").value<QUuid>();
ticket_->Finish(FrameHashCache::SaveCacheFrame(cache, uuid, time, frame));
ticket_->Finish(FrameHashCache::SaveCacheFrame(cache, uuid, time, timebase, frame));
break;
}
default: