From 7f9bb0e2da6365863f7c144117e5dbfa5f9aa3cf Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 22 Mar 2015 01:32:38 +0900 Subject: [PATCH] Use dedicated DiskWriter in MultiDiskFileAllocationIterator We have to use dedicated DiskWriter instead of (*entryItr_)->getDiskWriter(). This is because SingleFileAllocationIterator cannot reopen file if file is closed by OpenedFileCounter. --- src/MultiFileAllocationIterator.cc | 31 +++++++++++++++++++++++++----- src/MultiFileAllocationIterator.h | 1 + 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/MultiFileAllocationIterator.cc b/src/MultiFileAllocationIterator.cc index 1b234c0a..225d8a00 100644 --- a/src/MultiFileAllocationIterator.cc +++ b/src/MultiFileAllocationIterator.cc @@ -41,6 +41,7 @@ # include "FallocFileAllocationIterator.h" #endif // HAVE_SOME_FALLOCATE #include "DiskWriter.h" +#include "DefaultDiskWriterFactory.h" namespace aria2 { @@ -50,37 +51,57 @@ MultiFileAllocationIterator::MultiFileAllocationIterator entryItr_{std::begin(diskAdaptor_->getDiskWriterEntries())} {} -MultiFileAllocationIterator::~MultiFileAllocationIterator() {} +MultiFileAllocationIterator::~MultiFileAllocationIterator() { + if(diskWriter_) { + diskWriter_->closeFile(); + } +} void MultiFileAllocationIterator::allocateChunk() { while((!fileAllocationIterator_ || fileAllocationIterator_->finished()) && entryItr_ != std::end(diskAdaptor_->getDiskWriterEntries())) { + if (diskWriter_) { + diskWriter_->closeFile(); + diskWriter_.reset(); + } + fileAllocationIterator_.reset(); + if(!(*entryItr_)->getDiskWriter()) { + ++entryItr_; + continue; + } auto& fileEntry = (*entryItr_)->getFileEntry(); + // we use dedicated DiskWriter instead of + // (*entryItr_)->getDiskWriter(). This is because + // SingleFileAllocationIterator cannot reopen file if file is + // closed by OpenedFileCounter. + diskWriter_ = + DefaultDiskWriterFactory().newDiskWriter((*entryItr_)->getFilePath()); // Open file before calling DiskWriterEntry::size(). Calling // private function of MultiDiskAdaptor. - diskAdaptor_->openIfNot((*entryItr_).get(), &DiskWriterEntry::openFile); + diskWriter_->openFile(fileEntry->getLength()); + if((*entryItr_)->needsFileAllocation() && (*entryItr_)->size() < fileEntry->getLength()) { switch(diskAdaptor_->getFileAllocationMethod()) { #ifdef HAVE_SOME_FALLOCATE case(DiskAdaptor::FILE_ALLOC_FALLOC): fileAllocationIterator_ = make_unique - ((*entryItr_)->getDiskWriter().get(), + (diskWriter_.get(), (*entryItr_)->size(), fileEntry->getLength()); break; #endif // HAVE_SOME_FALLOCATE case(DiskAdaptor::FILE_ALLOC_TRUNC): fileAllocationIterator_ = make_unique - ((*entryItr_)->getDiskWriter().get(), + (diskWriter_.get(), (*entryItr_)->size(), fileEntry->getLength()); break; default: fileAllocationIterator_ = make_unique - ((*entryItr_)->getDiskWriter().get(), + (diskWriter_.get(), (*entryItr_)->size(), fileEntry->getLength()); break; diff --git a/src/MultiFileAllocationIterator.h b/src/MultiFileAllocationIterator.h index ea3181a8..6f07ef6e 100644 --- a/src/MultiFileAllocationIterator.h +++ b/src/MultiFileAllocationIterator.h @@ -51,6 +51,7 @@ class MultiFileAllocationIterator:public FileAllocationIterator private: MultiDiskAdaptor* diskAdaptor_; DiskWriterEntries::const_iterator entryItr_; + std::shared_ptr diskWriter_; std::unique_ptr fileAllocationIterator_; public: MultiFileAllocationIterator(MultiDiskAdaptor* diskAdaptor);