summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2009-02-23 13:27:08 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2009-02-23 13:27:08 +0000
commit2dfee3dc49463286854aa3e20ab0398b3c8adb57 (patch)
treee7e2624664ad717a62776136e80bc858d93e309c /src
parent120e2de09646b200a78e971d24b061a1d9e47b67 (diff)
2009-02-23 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
In BitTorrent, Open files in read-only mode for hash check. After that, re-open file in read/write mode only when the download is not finished. * src/AbstractDiskWriter.cc * src/AbstractDiskWriter.h * src/AbstractSingleDiskAdaptor.cc * src/AbstractSingleDiskAdaptor.h * src/BtCheckIntegrityEntry.cc * src/DiskAdaptor.h * src/DiskWriter.h * src/MultiDiskAdaptor.cc * src/MultiDiskAdaptor.h * src/RequestGroup.cc
Diffstat (limited to 'src')
-rw-r--r--src/AbstractDiskWriter.cc20
-rw-r--r--src/AbstractDiskWriter.h8
-rw-r--r--src/AbstractSingleDiskAdaptor.cc10
-rw-r--r--src/AbstractSingleDiskAdaptor.h8
-rw-r--r--src/BtCheckIntegrityEntry.cc22
-rw-r--r--src/DiskAdaptor.h4
-rw-r--r--src/DiskWriter.h10
-rw-r--r--src/MultiDiskAdaptor.cc16
-rw-r--r--src/MultiDiskAdaptor.h6
-rw-r--r--src/RequestGroup.cc3
10 files changed, 98 insertions, 9 deletions
diff --git a/src/AbstractDiskWriter.cc b/src/AbstractDiskWriter.cc
index d3a31f5a..cec3bdaf 100644
--- a/src/AbstractDiskWriter.cc
+++ b/src/AbstractDiskWriter.cc
@@ -58,6 +58,7 @@ namespace aria2 {
AbstractDiskWriter::AbstractDiskWriter():
fd(-1),
+ _readOnly(false),
logger(LogFactory::getInstance()) {}
AbstractDiskWriter::~AbstractDiskWriter()
@@ -93,7 +94,14 @@ void AbstractDiskWriter::openExistingFile(const std::string& filename,
(StringFormat(EX_FILE_OPEN, filename.c_str(), MSG_FILE_NOT_FOUND).str());
}
- if((fd = open(filename.c_str(), O_RDWR|O_BINARY, OPEN_MODE)) < 0) {
+ int flags = O_BINARY;
+ if(_readOnly) {
+ flags |= O_RDONLY;
+ } else {
+ flags |= O_RDWR;
+ }
+
+ if((fd = open(filename.c_str(), flags, OPEN_MODE)) < 0) {
throw DlAbortEx
(StringFormat(EX_FILE_OPEN, filename.c_str(), strerror(errno)).str());
}
@@ -217,4 +225,14 @@ void AbstractDiskWriter::disableDirectIO()
#endif // ENABLE_DIRECT_IO
}
+void AbstractDiskWriter::enableReadOnly()
+{
+ _readOnly = true;
+}
+
+void AbstractDiskWriter::disableReadOnly()
+{
+ _readOnly = false;
+}
+
} // namespace aria2
diff --git a/src/AbstractDiskWriter.h b/src/AbstractDiskWriter.h
index d459ee48..ef967687 100644
--- a/src/AbstractDiskWriter.h
+++ b/src/AbstractDiskWriter.h
@@ -46,6 +46,9 @@ class AbstractDiskWriter : public DiskWriter {
protected:
std::string filename;
int fd;
+
+ bool _readOnly;
+
Logger* logger;
void createFile(const std::string& filename, int addFlags = 0);
@@ -55,7 +58,6 @@ private:
ssize_t readDataInternal(unsigned char* data, size_t len);
void seek(off_t offset);
-
public:
AbstractDiskWriter();
virtual ~AbstractDiskWriter();
@@ -77,6 +79,10 @@ public:
virtual void enableDirectIO();
virtual void disableDirectIO();
+
+ virtual void enableReadOnly();
+
+ virtual void disableReadOnly();
};
} // namespace aria2
diff --git a/src/AbstractSingleDiskAdaptor.cc b/src/AbstractSingleDiskAdaptor.cc
index ca21b1c6..d1c4d8a5 100644
--- a/src/AbstractSingleDiskAdaptor.cc
+++ b/src/AbstractSingleDiskAdaptor.cc
@@ -111,6 +111,16 @@ bool AbstractSingleDiskAdaptor::directIOAllowed() const
return diskWriter->directIOAllowed();
}
+void AbstractSingleDiskAdaptor::enableReadOnly()
+{
+ diskWriter->enableReadOnly();
+}
+
+void AbstractSingleDiskAdaptor::disableReadOnly()
+{
+ diskWriter->disableReadOnly();
+}
+
void AbstractSingleDiskAdaptor::cutTrailingGarbage()
{
if(File(getFilePath()).size() > totalLength) {
diff --git a/src/AbstractSingleDiskAdaptor.h b/src/AbstractSingleDiskAdaptor.h
index 36a2ede9..fd16d585 100644
--- a/src/AbstractSingleDiskAdaptor.h
+++ b/src/AbstractSingleDiskAdaptor.h
@@ -77,7 +77,13 @@ public:
virtual void disableDirectIO();
virtual bool directIOAllowed() const;
-
+
+ // Make sure that DiskWriter is set before calling this function.
+ virtual void enableReadOnly();
+
+ // Make sure that DiskWriter is set before calling this function.
+ virtual void disableReadOnly();
+
virtual void cutTrailingGarbage();
void setDiskWriter(const SharedHandle<DiskWriter>& diskWriter);
diff --git a/src/BtCheckIntegrityEntry.cc b/src/BtCheckIntegrityEntry.cc
index feeb924e..bed582c5 100644
--- a/src/BtCheckIntegrityEntry.cc
+++ b/src/BtCheckIntegrityEntry.cc
@@ -49,17 +49,28 @@ BtCheckIntegrityEntry::BtCheckIntegrityEntry(RequestGroup* requestGroup):
BtCheckIntegrityEntry::~BtCheckIntegrityEntry() {}
-void BtCheckIntegrityEntry::onDownloadIncomplete(std::deque<Command*>& commands,
- DownloadEngine* e)
+static void proceedFileAllocation
+(std::deque<Command*>& commands, DownloadEngine* e, RequestGroup* requestGroup)
{
- FileAllocationEntryHandle entry(new BtFileAllocationEntry(_requestGroup));
- if(_requestGroup->needsFileAllocation()) {
+ FileAllocationEntryHandle entry(new BtFileAllocationEntry(requestGroup));
+ if(requestGroup->needsFileAllocation()) {
e->_fileAllocationMan->pushEntry(entry);
} else {
entry->prepareForNextAction(commands, e);
}
}
+void BtCheckIntegrityEntry::onDownloadIncomplete(std::deque<Command*>& commands,
+ DownloadEngine* e)
+{
+ // Now reopen DiskAdaptor with read only disabled.
+ _requestGroup->getPieceStorage()->getDiskAdaptor()->closeFile();
+ _requestGroup->getPieceStorage()->getDiskAdaptor()->disableReadOnly();
+ _requestGroup->getPieceStorage()->getDiskAdaptor()->openFile();
+
+ proceedFileAllocation(commands, e, _requestGroup);
+}
+
void BtCheckIntegrityEntry::onDownloadFinished(std::deque<Command*>& commands,
DownloadEngine* e)
{
@@ -69,8 +80,9 @@ void BtCheckIntegrityEntry::onDownloadFinished(std::deque<Command*>& commands,
// to exit rather than doing seeding. So, it would be good to toggle this
// behavior.
if(e->option->getAsBool(PREF_BT_HASH_CHECK_SEED)) {
- onDownloadIncomplete(commands, e);
+ proceedFileAllocation(commands, e, _requestGroup);
}
}
+
} // namespace aria2
diff --git a/src/DiskAdaptor.h b/src/DiskAdaptor.h
index 012eb48b..9b4fb1a7 100644
--- a/src/DiskAdaptor.h
+++ b/src/DiskAdaptor.h
@@ -98,6 +98,10 @@ public:
virtual void disableDirectIO() {}
+ virtual void enableReadOnly() {}
+
+ virtual void disableReadOnly() {}
+
// Assumed each file length is stored in fileEntries or DiskAdaptor knows it.
// If each actual file's length is larger than that, truncate file to that
// length.
diff --git a/src/DiskWriter.h b/src/DiskWriter.h
index 2084826e..dfd9fd97 100644
--- a/src/DiskWriter.h
+++ b/src/DiskWriter.h
@@ -92,6 +92,16 @@ public:
{
_directIOAllowed = f;
}
+
+ // Enables read-only mode. After this call, openExistingFile() opens
+ // file in read-only mode. This is an optional functionality. The
+ // default implementation is do nothing.
+ virtual void enableReadOnly() {}
+
+ // Disables read-only mode. After this call, openExistingFile()
+ // opens file in read/write mode. This is an optional
+ // functionality. The default implementation is do noting.
+ virtual void disableReadOnly() {}
};
typedef SharedHandle<DiskWriter> DiskWriterHandle;
diff --git a/src/MultiDiskAdaptor.cc b/src/MultiDiskAdaptor.cc
index 1b1ebb53..bf586345 100644
--- a/src/MultiDiskAdaptor.cc
+++ b/src/MultiDiskAdaptor.cc
@@ -169,7 +169,8 @@ void DiskWriterEntry::needsFileAllocation(bool f)
MultiDiskAdaptor::MultiDiskAdaptor():
pieceLength(0),
_maxOpenFiles(DEFAULT_MAX_OPEN_FILES),
- _directIOAllowed(false) {}
+ _directIOAllowed(false),
+ _readOnly(false) {}
MultiDiskAdaptor::~MultiDiskAdaptor() {}
@@ -273,6 +274,9 @@ void MultiDiskAdaptor::resetDiskWriterEntries()
(*i)->getFilePath(getTopDirPath()).c_str());
(*i)->setDiskWriter(dwFactory.newDiskWriter());
(*i)->getDiskWriter()->setDirectIOAllowed(_directIOAllowed);
+ if(_readOnly) {
+ (*i)->getDiskWriter()->enableReadOnly();
+ }
}
}
}
@@ -518,6 +522,16 @@ void MultiDiskAdaptor::disableDirectIO()
}
}
+void MultiDiskAdaptor::enableReadOnly()
+{
+ _readOnly = true;
+}
+
+void MultiDiskAdaptor::disableReadOnly()
+{
+ _readOnly = false;
+}
+
void MultiDiskAdaptor::cutTrailingGarbage()
{
for(std::deque<SharedHandle<DiskWriterEntry> >::const_iterator i =
diff --git a/src/MultiDiskAdaptor.h b/src/MultiDiskAdaptor.h
index 51ea1094..a52e8b1e 100644
--- a/src/MultiDiskAdaptor.h
+++ b/src/MultiDiskAdaptor.h
@@ -113,6 +113,8 @@ private:
bool _directIOAllowed;
+ bool _readOnly;
+
void resetDiskWriterEntries();
void mkdir(const std::string& topDirPath) const;
@@ -160,6 +162,10 @@ public:
virtual void disableDirectIO();
+ virtual void enableReadOnly();
+
+ virtual void disableReadOnly();
+
void setTopDir(const std::string& topDir) {
this->topDir = topDir;
}
diff --git a/src/RequestGroup.cc b/src/RequestGroup.cc
index c0252032..a82ae865 100644
--- a/src/RequestGroup.cc
+++ b/src/RequestGroup.cc
@@ -266,6 +266,9 @@ void RequestGroup::createInitialCommand(std::deque<Command*>& commands,
progressInfoFile->getFilename().c_str(),
_pieceStorage->getDiskAdaptor()->getFilePath().c_str());
}
+ // First, make DiskAdaptor read-only mode.
+ _pieceStorage->getDiskAdaptor()->enableReadOnly();
+
// Call Load, Save and file allocation command here
if(progressInfoFile->exists()) {
// load .aria2 file if it exists.