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.
pull/364/head
Tatsuhiro Tsujikawa 2015-03-22 01:32:38 +09:00
parent c248d456d1
commit 7f9bb0e2da
2 changed files with 27 additions and 5 deletions

View File

@ -41,6 +41,7 @@
# include "FallocFileAllocationIterator.h" # include "FallocFileAllocationIterator.h"
#endif // HAVE_SOME_FALLOCATE #endif // HAVE_SOME_FALLOCATE
#include "DiskWriter.h" #include "DiskWriter.h"
#include "DefaultDiskWriterFactory.h"
namespace aria2 { namespace aria2 {
@ -50,37 +51,57 @@ MultiFileAllocationIterator::MultiFileAllocationIterator
entryItr_{std::begin(diskAdaptor_->getDiskWriterEntries())} entryItr_{std::begin(diskAdaptor_->getDiskWriterEntries())}
{} {}
MultiFileAllocationIterator::~MultiFileAllocationIterator() {} MultiFileAllocationIterator::~MultiFileAllocationIterator() {
if(diskWriter_) {
diskWriter_->closeFile();
}
}
void MultiFileAllocationIterator::allocateChunk() void MultiFileAllocationIterator::allocateChunk()
{ {
while((!fileAllocationIterator_ || while((!fileAllocationIterator_ ||
fileAllocationIterator_->finished()) && fileAllocationIterator_->finished()) &&
entryItr_ != std::end(diskAdaptor_->getDiskWriterEntries())) { entryItr_ != std::end(diskAdaptor_->getDiskWriterEntries())) {
if (diskWriter_) {
diskWriter_->closeFile();
diskWriter_.reset();
}
fileAllocationIterator_.reset();
if(!(*entryItr_)->getDiskWriter()) {
++entryItr_;
continue;
}
auto& fileEntry = (*entryItr_)->getFileEntry(); 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 // Open file before calling DiskWriterEntry::size(). Calling
// private function of MultiDiskAdaptor. // private function of MultiDiskAdaptor.
diskAdaptor_->openIfNot((*entryItr_).get(), &DiskWriterEntry::openFile); diskWriter_->openFile(fileEntry->getLength());
if((*entryItr_)->needsFileAllocation() && if((*entryItr_)->needsFileAllocation() &&
(*entryItr_)->size() < fileEntry->getLength()) { (*entryItr_)->size() < fileEntry->getLength()) {
switch(diskAdaptor_->getFileAllocationMethod()) { switch(diskAdaptor_->getFileAllocationMethod()) {
#ifdef HAVE_SOME_FALLOCATE #ifdef HAVE_SOME_FALLOCATE
case(DiskAdaptor::FILE_ALLOC_FALLOC): case(DiskAdaptor::FILE_ALLOC_FALLOC):
fileAllocationIterator_ = make_unique<FallocFileAllocationIterator> fileAllocationIterator_ = make_unique<FallocFileAllocationIterator>
((*entryItr_)->getDiskWriter().get(), (diskWriter_.get(),
(*entryItr_)->size(), (*entryItr_)->size(),
fileEntry->getLength()); fileEntry->getLength());
break; break;
#endif // HAVE_SOME_FALLOCATE #endif // HAVE_SOME_FALLOCATE
case(DiskAdaptor::FILE_ALLOC_TRUNC): case(DiskAdaptor::FILE_ALLOC_TRUNC):
fileAllocationIterator_ = make_unique<TruncFileAllocationIterator> fileAllocationIterator_ = make_unique<TruncFileAllocationIterator>
((*entryItr_)->getDiskWriter().get(), (diskWriter_.get(),
(*entryItr_)->size(), (*entryItr_)->size(),
fileEntry->getLength()); fileEntry->getLength());
break; break;
default: default:
fileAllocationIterator_ = make_unique<AdaptiveFileAllocationIterator> fileAllocationIterator_ = make_unique<AdaptiveFileAllocationIterator>
((*entryItr_)->getDiskWriter().get(), (diskWriter_.get(),
(*entryItr_)->size(), (*entryItr_)->size(),
fileEntry->getLength()); fileEntry->getLength());
break; break;

View File

@ -51,6 +51,7 @@ class MultiFileAllocationIterator:public FileAllocationIterator
private: private:
MultiDiskAdaptor* diskAdaptor_; MultiDiskAdaptor* diskAdaptor_;
DiskWriterEntries::const_iterator entryItr_; DiskWriterEntries::const_iterator entryItr_;
std::shared_ptr<DiskWriter> diskWriter_;
std::unique_ptr<FileAllocationIterator> fileAllocationIterator_; std::unique_ptr<FileAllocationIterator> fileAllocationIterator_;
public: public:
MultiFileAllocationIterator(MultiDiskAdaptor* diskAdaptor); MultiFileAllocationIterator(MultiDiskAdaptor* diskAdaptor);