mirror of https://github.com/aria2/aria2
2007-12-06 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Rewritten direct I/O support routine * src/SingleFileAllocationIterator.cc * src/MultiDiskAdaptor.{h, cc} * src/ByteArrayDiskWriter.h * src/AbstractSingleDiskAdaptor.h * src/AbstractDiskWriter.cc * src/DefaultPieceStorage.cc * src/DiskWriter.h * src/BinaryStream.h * src/IteratableChunkChecksumValidator.cc * src/IteratableChecksumValidator.cc * src/CheckIntegrityEntry.cc * src/FileAllocationEntry.ccpull/1/head
parent
84e896eb09
commit
2850c16f8a
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
|||
2007-12-06 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
Rewritten direct I/O support routine
|
||||
* src/SingleFileAllocationIterator.cc
|
||||
* src/MultiDiskAdaptor.{h, cc}
|
||||
* src/ByteArrayDiskWriter.h
|
||||
* src/AbstractSingleDiskAdaptor.h
|
||||
* src/AbstractDiskWriter.cc
|
||||
* src/DefaultPieceStorage.cc
|
||||
* src/DiskWriter.h
|
||||
* src/BinaryStream.h
|
||||
* src/IteratableChunkChecksumValidator.cc
|
||||
* src/IteratableChecksumValidator.cc
|
||||
* src/CheckIntegrityEntry.cc
|
||||
* src/FileAllocationEntry.cc
|
||||
|
||||
2007-12-06 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
Fixed typo
|
||||
|
|
|
@ -47,8 +47,7 @@
|
|||
|
||||
AbstractDiskWriter::AbstractDiskWriter():
|
||||
fd(-1),
|
||||
logger(LogFactory::getInstance())
|
||||
{}
|
||||
logger(LogFactory::getInstance()) {}
|
||||
|
||||
AbstractDiskWriter::~AbstractDiskWriter()
|
||||
{
|
||||
|
@ -167,9 +166,11 @@ int64_t AbstractDiskWriter::size() const
|
|||
void AbstractDiskWriter::enableDirectIO()
|
||||
{
|
||||
#ifdef ENABLE_DIRECT_IO
|
||||
int32_t flg;
|
||||
while((flg = fcntl(fd, F_GETFL)) == -1 && errno == EINTR);
|
||||
while(fcntl(fd, F_SETFL, flg|O_DIRECT) == -1 && errno == EINTR);
|
||||
if(_directIOAllowed) {
|
||||
int32_t flg;
|
||||
while((flg = fcntl(fd, F_GETFL)) == -1 && errno == EINTR);
|
||||
while(fcntl(fd, F_SETFL, flg|O_DIRECT) == -1 && errno == EINTR);
|
||||
}
|
||||
#endif // ENABLE_DIRECT_IO
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,12 @@ public:
|
|||
virtual void enableDirectIO();
|
||||
|
||||
virtual void disableDirectIO();
|
||||
|
||||
|
||||
virtual bool directIOAllowed() const
|
||||
{
|
||||
return diskWriter->directIOAllowed();
|
||||
}
|
||||
|
||||
void setDiskWriter(const DiskWriterHandle diskWriter) {
|
||||
this->diskWriter = diskWriter;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,12 @@ public:
|
|||
virtual int32_t readData(unsigned char* data, int32_t len, int64_t offset) = 0;
|
||||
|
||||
virtual void truncate(int64_t length) = 0;
|
||||
|
||||
virtual void enableDirectIO() = 0;
|
||||
|
||||
virtual void disableDirectIO() = 0;
|
||||
|
||||
virtual bool directIOAllowed() const = 0;
|
||||
};
|
||||
|
||||
typedef SharedHandle<BinaryStream> BinaryStreamHandle;
|
||||
|
|
|
@ -66,7 +66,5 @@ Commands BtCheckIntegrityEntry::onDownloadFinished(DownloadEngine* e)
|
|||
// are valid, then aira2 goes to seeding mode. Sometimes it is better
|
||||
// to exit rather than doing seeding. So, it would be good to toggle this
|
||||
// behavior.
|
||||
// TODO If FileAllocationEntry is not going to be used, call
|
||||
// DiskAdaptor::disableDirectIO() manually here.
|
||||
return onDownloadIncomplete(e);
|
||||
}
|
||||
|
|
|
@ -70,6 +70,11 @@ public:
|
|||
|
||||
virtual void disableDirectIO() {}
|
||||
|
||||
virtual bool directIOAllowed() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void setString(const string& s)
|
||||
{
|
||||
buf.str(s);
|
||||
|
|
|
@ -36,27 +36,14 @@
|
|||
#include "Command.h"
|
||||
#include "RequestGroup.h"
|
||||
#include "IteratableValidator.h"
|
||||
#include "prefs.h"
|
||||
#include "PieceStorage.h"
|
||||
#include "DownloadContext.h"
|
||||
#include "DiskAdaptor.h"
|
||||
#include "Option.h"
|
||||
|
||||
CheckIntegrityEntry::CheckIntegrityEntry(RequestGroup* requestGroup,
|
||||
Command* nextCommand):
|
||||
RequestGroupEntry(requestGroup, nextCommand),
|
||||
_validator(0)
|
||||
{
|
||||
if(_requestGroup->getOption()->getAsBool(PREF_ENABLE_DIRECT_IO) &&
|
||||
_requestGroup->getDownloadContext()->getFileEntries().size() == 1) {
|
||||
_requestGroup->getPieceStorage()->getDiskAdaptor()->enableDirectIO();
|
||||
}
|
||||
}
|
||||
{}
|
||||
|
||||
CheckIntegrityEntry::~CheckIntegrityEntry()
|
||||
{
|
||||
// TODO DiskAdaptor::disableIO() will be called from ~FileAllocationEntry
|
||||
}
|
||||
CheckIntegrityEntry::~CheckIntegrityEntry() {}
|
||||
|
||||
void CheckIntegrityEntry::validateChunk()
|
||||
{
|
||||
|
|
|
@ -434,6 +434,7 @@ void DefaultPieceStorage::initStorage()
|
|||
if(downloadContext->getFileMode() == DownloadContext::SINGLE) {
|
||||
logger->debug("Instantiating DirectDiskAdaptor");
|
||||
DiskWriterHandle writer = _diskWriterFactory->newDiskWriter();
|
||||
writer->setDirectIOAllowed(option->getAsBool(PREF_ENABLE_DIRECT_IO));
|
||||
DirectDiskAdaptorHandle directDiskAdaptor = new DirectDiskAdaptor();
|
||||
directDiskAdaptor->setDiskWriter(writer);
|
||||
directDiskAdaptor->setTotalLength(downloadContext->getTotalLength());
|
||||
|
@ -443,12 +444,14 @@ void DefaultPieceStorage::initStorage()
|
|||
if(option->get(PREF_DIRECT_FILE_MAPPING) == V_TRUE) {
|
||||
logger->debug("Instantiating MultiDiskAdaptor");
|
||||
MultiDiskAdaptorHandle multiDiskAdaptor = new MultiDiskAdaptor();
|
||||
multiDiskAdaptor->setDirectIOAllowed(option->getAsBool(PREF_ENABLE_DIRECT_IO));
|
||||
multiDiskAdaptor->setPieceLength(downloadContext->getPieceLength());
|
||||
multiDiskAdaptor->setTopDir(downloadContext->getName());
|
||||
this->diskAdaptor = multiDiskAdaptor;
|
||||
} else {
|
||||
logger->debug("Instantiating CopyDiskAdaptor");
|
||||
DiskWriterHandle writer = _diskWriterFactory->newDiskWriter();
|
||||
writer->setDirectIOAllowed(option->getAsBool(PREF_ENABLE_DIRECT_IO));
|
||||
CopyDiskAdaptorHandle copyDiskAdaptor = new CopyDiskAdaptor();
|
||||
copyDiskAdaptor->setDiskWriter(writer);
|
||||
copyDiskAdaptor->setTempFilename(downloadContext->getName()+".a2tmp");
|
||||
|
|
|
@ -90,9 +90,9 @@ public:
|
|||
|
||||
virtual FileAllocationIteratorHandle fileAllocationIterator() = 0;
|
||||
|
||||
virtual void enableDirectIO() {};
|
||||
virtual void enableDirectIO() {}
|
||||
|
||||
virtual void disableDirectIO() {};
|
||||
virtual void disableDirectIO() {}
|
||||
};
|
||||
|
||||
typedef SharedHandle<DiskAdaptor> DiskAdaptorHandle;
|
||||
|
|
|
@ -42,7 +42,12 @@
|
|||
*
|
||||
*/
|
||||
class DiskWriter:public BinaryStream {
|
||||
protected:
|
||||
bool _directIOAllowed;
|
||||
|
||||
public:
|
||||
DiskWriter():_directIOAllowed(false) {}
|
||||
|
||||
virtual ~DiskWriter() {}
|
||||
/**
|
||||
* Creates a file output stream to write to the file with the specified name.
|
||||
|
@ -75,6 +80,16 @@ public:
|
|||
virtual void enableDirectIO() = 0;
|
||||
|
||||
virtual void disableDirectIO() = 0;
|
||||
|
||||
virtual bool directIOAllowed() const
|
||||
{
|
||||
return _directIOAllowed;
|
||||
}
|
||||
|
||||
void setDirectIOAllowed(bool f)
|
||||
{
|
||||
_directIOAllowed = f;
|
||||
}
|
||||
};
|
||||
|
||||
typedef SharedHandle<DiskWriter> DiskWriterHandle;
|
||||
|
|
|
@ -38,24 +38,14 @@
|
|||
#include "RequestGroup.h"
|
||||
#include "PieceStorage.h"
|
||||
#include "DiskAdaptor.h"
|
||||
#include "prefs.h"
|
||||
#include "Option.h"
|
||||
|
||||
FileAllocationEntry::FileAllocationEntry(RequestGroup* requestGroup, Command* nextCommand):
|
||||
RequestGroupEntry(requestGroup, nextCommand),
|
||||
_fileAllocationIterator(requestGroup->getPieceStorage()->getDiskAdaptor()->fileAllocationIterator())
|
||||
{
|
||||
if(_requestGroup->getOption()->getAsBool(PREF_ENABLE_DIRECT_IO)) {
|
||||
_requestGroup->getPieceStorage()->getDiskAdaptor()->enableDirectIO();
|
||||
}
|
||||
}
|
||||
{}
|
||||
|
||||
FileAllocationEntry:: ~FileAllocationEntry()
|
||||
{
|
||||
if(_requestGroup->getOption()->getAsBool(PREF_ENABLE_DIRECT_IO)) {
|
||||
_requestGroup->getPieceStorage()->getDiskAdaptor()->disableDirectIO();
|
||||
}
|
||||
}
|
||||
{}
|
||||
|
||||
int64_t FileAllocationEntry::getCurrentLength()
|
||||
{
|
||||
|
|
|
@ -82,7 +82,12 @@ void IteratableChecksumValidator::validateChunk()
|
|||
|
||||
bool IteratableChecksumValidator::finished() const
|
||||
{
|
||||
return _currentOffset >= _dctx->getTotalLength();
|
||||
if(_currentOffset >= _dctx->getTotalLength()) {
|
||||
_pieceStorage->getDiskAdaptor()->disableDirectIO();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t IteratableChecksumValidator::getTotalLength() const
|
||||
|
@ -97,6 +102,7 @@ void IteratableChecksumValidator::init()
|
|||
#else
|
||||
_buffer = new unsigned char[BUFSIZE];
|
||||
#endif // HAVE_POSIX_MEMALIGN
|
||||
_pieceStorage->getDiskAdaptor()->enableDirectIO();
|
||||
_currentOffset = 0;
|
||||
_ctx = new MessageDigestContext();
|
||||
_ctx->trySetAlgo(_dctx->getChecksumHashAlgo());
|
||||
|
|
|
@ -116,6 +116,9 @@ void IteratableChunkChecksumValidator::init()
|
|||
#else
|
||||
_buffer = new unsigned char[BUFSIZE];
|
||||
#endif // HAVE_POSIX_MEMALIGN
|
||||
if(_dctx->getFileEntries().size() == 1) {
|
||||
_pieceStorage->getDiskAdaptor()->enableDirectIO();
|
||||
}
|
||||
_ctx = new MessageDigestContext();
|
||||
_ctx->trySetAlgo(_dctx->getPieceHashAlgo());
|
||||
_ctx->digestInit();
|
||||
|
@ -157,7 +160,12 @@ string IteratableChunkChecksumValidator::digest(int64_t offset, int32_t length)
|
|||
|
||||
bool IteratableChunkChecksumValidator::finished() const
|
||||
{
|
||||
return _currentIndex >= (uint32_t)_dctx->getNumPieces();
|
||||
if(_currentIndex >= (uint32_t)_dctx->getNumPieces()) {
|
||||
_pieceStorage->getDiskAdaptor()->disableDirectIO();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t IteratableChunkChecksumValidator::getCurrentOffset() const
|
||||
|
|
|
@ -51,6 +51,7 @@ void MultiDiskAdaptor::resetDiskWriterEntries()
|
|||
} else {
|
||||
entry->setDiskWriter(new DefaultDiskWriter());
|
||||
}
|
||||
entry->getDiskWriter()->setDirectIOAllowed(_directIOAllowed);
|
||||
diskWriterEntries.push_back(entry);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,6 +116,8 @@ private:
|
|||
int32_t pieceLength;
|
||||
DiskWriterEntries diskWriterEntries;
|
||||
|
||||
bool _directIOAllowed;
|
||||
|
||||
void resetDiskWriterEntries();
|
||||
|
||||
void mkdir() const;
|
||||
|
@ -178,6 +180,16 @@ public:
|
|||
int32_t getPieceLength() const {
|
||||
return pieceLength;
|
||||
}
|
||||
|
||||
virtual bool directIOAllowed() const
|
||||
{
|
||||
return _directIOAllowed;
|
||||
}
|
||||
|
||||
void setDirectIOAllowed(bool b)
|
||||
{
|
||||
_directIOAllowed = b;
|
||||
}
|
||||
};
|
||||
|
||||
typedef SharedHandle<MultiDiskAdaptor> MultiDiskAdaptorHandle;
|
||||
|
|
|
@ -40,11 +40,16 @@
|
|||
#define BUFSIZE (256*1024)
|
||||
|
||||
SingleFileAllocationIterator::SingleFileAllocationIterator(BinaryStream* stream, int64_t offset, int64_t totalLength):_stream(stream), _offset(offset), _totalLength(totalLength), _buffer(0)
|
||||
{}
|
||||
{
|
||||
if(_offset%512 == 0) {
|
||||
_stream->enableDirectIO();
|
||||
}
|
||||
}
|
||||
|
||||
SingleFileAllocationIterator::~SingleFileAllocationIterator()
|
||||
{
|
||||
delete [] _buffer;
|
||||
_stream->disableDirectIO();
|
||||
}
|
||||
|
||||
void SingleFileAllocationIterator::init()
|
||||
|
|
Loading…
Reference in New Issue