Skip to content

Commit

Permalink
flush internal buffers before auto-saving control file
Browse files Browse the repository at this point in the history
Otherwise, some pieces may be marked as finished in the control file
though they have not yet been written to the storage file.

This should prevent data loss and corruption when resuming downloads
after an app crash.

Signed-off-by: Ali MJ Al-Nasrawy <[email protected]>
  • Loading branch information
aliemjay committed Jun 17, 2020
1 parent 9d0a48a commit 870e2a6
Show file tree
Hide file tree
Showing 6 changed files with 14 additions and 8 deletions.
6 changes: 4 additions & 2 deletions src/DefaultPieceStorage.cc
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ std::shared_ptr<DiskAdaptor> DefaultPieceStorage::getDiskAdaptor()

WrDiskCache* DefaultPieceStorage::getWrDiskCache() { return wrDiskCache_; }

void DefaultPieceStorage::flushWrDiskCacheEntry()
void DefaultPieceStorage::flushWrDiskCacheEntry(bool releaseEntries)
{
if (!wrDiskCache_) {
return;
Expand All @@ -697,7 +697,9 @@ void DefaultPieceStorage::flushWrDiskCacheEntry()
auto ce = piece->getWrDiskCacheEntry();
if (ce) {
piece->flushWrCache(wrDiskCache_);
piece->releaseWrCache(wrDiskCache_);
if (releaseEntries) {
piece->releaseWrCache(wrDiskCache_);
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/DefaultPieceStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ class DefaultPieceStorage : public PieceStorage {

virtual WrDiskCache* getWrDiskCache() CXX11_OVERRIDE;

virtual void flushWrDiskCacheEntry() CXX11_OVERRIDE;
virtual void flushWrDiskCacheEntry(bool releaseEntries) CXX11_OVERRIDE;

virtual int32_t getPieceLength(size_t index) CXX11_OVERRIDE;

Expand Down
5 changes: 3 additions & 2 deletions src/PieceStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,9 @@ class PieceStorage {

virtual WrDiskCache* getWrDiskCache() = 0;

// Flushes write disk cache for in-flight piece and evicts them.
virtual void flushWrDiskCacheEntry() = 0;
// Flushes write disk cache for in-flight piece
// and optionally releases the associated cache entries.
virtual void flushWrDiskCacheEntry(bool releaseEntries) = 0;

virtual int32_t getPieceLength(size_t index) = 0;

Expand Down
5 changes: 4 additions & 1 deletion src/RequestGroup.cc
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ std::pair<error_code::Value, std::string> RequestGroup::downloadResult() const
void RequestGroup::closeFile()
{
if (pieceStorage_) {
pieceStorage_->flushWrDiskCacheEntry();
pieceStorage_->flushWrDiskCacheEntry(true);
pieceStorage_->getDiskAdaptor()->closeFile();
}
}
Expand Down Expand Up @@ -1290,6 +1290,9 @@ bool RequestGroup::doesUploadSpeedExceed()
void RequestGroup::saveControlFile() const
{
if (saveControlFile_) {
if (pieceStorage_) {
pieceStorage_->flushWrDiskCacheEntry(false);
}
progressInfoFile_->save();
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/UnknownLengthPieceStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ class UnknownLengthPieceStorage : public PieceStorage {

virtual WrDiskCache* getWrDiskCache() CXX11_OVERRIDE { return nullptr; }

virtual void flushWrDiskCacheEntry() CXX11_OVERRIDE {}
virtual void flushWrDiskCacheEntry(bool releaseEntries) CXX11_OVERRIDE {}

virtual int32_t getPieceLength(size_t index) CXX11_OVERRIDE;

Expand Down
2 changes: 1 addition & 1 deletion test/MockPieceStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ class MockPieceStorage : public PieceStorage {

virtual WrDiskCache* getWrDiskCache() CXX11_OVERRIDE { return 0; }

virtual void flushWrDiskCacheEntry() CXX11_OVERRIDE {}
virtual void flushWrDiskCacheEntry(bool releaseEntries) CXX11_OVERRIDE {}

void setDiskAdaptor(const std::shared_ptr<DiskAdaptor>& adaptor)
{
Expand Down

0 comments on commit 870e2a6

Please sign in to comment.