summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2014-10-14 00:13:29 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2014-10-14 00:13:29 +0900
commitf72a303b8deb702a2ea4f63280302f88741da581 (patch)
tree9df1a81101fe93b1eb9b545559f0148dde504591
parent09d79565376c03b3e735793703c1dc185d413c31 (diff)
Add --bt-detach-seed-only option
This option excludes seed only downloads when counting concurrent active downloads (-j option). This means that if -j3 is given and this option is turned on and 3 downloads are active and one of those enters seed mode, then it is excluded from active download count (thus it becomes 2), and the next download waiting in queue gets started. But be aware that seeding item is still recognized as active download in RPC method.
-rw-r--r--doc/manual-src/en/aria2c.rst10
-rw-r--r--src/BtFileAllocationEntry.cc1
-rw-r--r--src/DefaultPieceStorage.cc11
-rw-r--r--src/OptionHandlerFactory.cc9
-rw-r--r--src/RequestGroup.cc17
-rw-r--r--src/RequestGroup.h8
-rw-r--r--src/RequestGroupMan.cc18
-rw-r--r--src/RequestGroupMan.h9
-rw-r--r--src/prefs.cc1
-rw-r--r--src/prefs.h2
-rw-r--r--src/usage_text.h11
11 files changed, 90 insertions, 7 deletions
diff --git a/doc/manual-src/en/aria2c.rst b/doc/manual-src/en/aria2c.rst
index 2a9f3ccf..e065695e 100644
--- a/doc/manual-src/en/aria2c.rst
+++ b/doc/manual-src/en/aria2c.rst
@@ -595,6 +595,16 @@ BitTorrent/Metalink Options
BitTorrent Specific Options
~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. option:: --bt-detach-seed-only[=true|false]
+
+ Exclude seed only downloads when counting concurrent active
+ downloads (See :option:`-j` option). This means that if ``-j3`` is
+ given and this option is turned on and 3 downloads are active and
+ one of those enters seed mode, then it is excluded from active
+ download count (thus it becomes 2), and the next download waiting in
+ queue gets started. But be aware that seeding item is still
+ recognized as active download in RPC method. Default: ``false``
+
.. option:: --bt-enable-lpd[=true|false]
Enable Local Peer Discovery. If a private flag is set in a torrent,
diff --git a/src/BtFileAllocationEntry.cc b/src/BtFileAllocationEntry.cc
index 4b1f4147..5063f989 100644
--- a/src/BtFileAllocationEntry.cc
+++ b/src/BtFileAllocationEntry.cc
@@ -89,6 +89,7 @@ void BtFileAllocationEntry::prepareForNextAction
diskAdaptor->openFile();
}
#endif // __MINGW32__
+ getRequestGroup()->enableSeedOnly();
}
}
diff --git a/src/DefaultPieceStorage.cc b/src/DefaultPieceStorage.cc
index 1191a5a0..713e8365 100644
--- a/src/DefaultPieceStorage.cc
+++ b/src/DefaultPieceStorage.cc
@@ -490,11 +490,14 @@ void DefaultPieceStorage::completePiece(const std::shared_ptr<Piece>& piece)
diskAdaptor_->enableReadOnly();
diskAdaptor_->openFile();
#endif // __MINGW32__
- util::executeHookByOptName(downloadContext_->getOwnerRequestGroup(),
- option_, PREF_ON_BT_DOWNLOAD_COMPLETE);
+ auto group = downloadContext_->getOwnerRequestGroup();
+
+ util::executeHookByOptName(group, option_,
+ PREF_ON_BT_DOWNLOAD_COMPLETE);
SingletonHolder<Notifier>::instance()->
- notifyDownloadEvent(EVENT_ON_BT_DOWNLOAD_COMPLETE,
- downloadContext_->getOwnerRequestGroup());
+ notifyDownloadEvent(EVENT_ON_BT_DOWNLOAD_COMPLETE, group);
+
+ group->enableSeedOnly();
}
}
#endif // ENABLE_BITTORRENT
diff --git a/src/OptionHandlerFactory.cc b/src/OptionHandlerFactory.cc
index f89a1c44..dec0624a 100644
--- a/src/OptionHandlerFactory.cc
+++ b/src/OptionHandlerFactory.cc
@@ -1702,6 +1702,15 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
#ifdef ENABLE_BITTORRENT
{
OptionHandler* op(new BooleanOptionHandler
+ (PREF_BT_DETACH_SEED_ONLY,
+ TEXT_BT_DETACH_SEED_ONLY,
+ A2_V_FALSE,
+ OptionHandler::OPT_ARG));
+ op->addTag(TAG_BITTORRENT);
+ handlers.push_back(op);
+ }
+ {
+ OptionHandler* op(new BooleanOptionHandler
(PREF_BT_ENABLE_LPD,
TEXT_BT_ENABLE_LPD,
A2_V_FALSE,
diff --git a/src/RequestGroup.cc b/src/RequestGroup.cc
index e06decdc..d839286e 100644
--- a/src/RequestGroup.cc
+++ b/src/RequestGroup.cc
@@ -149,7 +149,8 @@ RequestGroup::RequestGroup(const std::shared_ptr<GroupId>& gid,
haltRequested_(false),
forceHaltRequested_(false),
pauseRequested_(false),
- inMemoryDownload_(false)
+ inMemoryDownload_(false),
+ seedOnly_(false)
{
fileAllocationEnabled_ = option_->get(PREF_FILE_ALLOCATION) != V_NONE;
if(!option_->getAsBool(PREF_DRY_RUN)) {
@@ -1265,4 +1266,18 @@ bool RequestGroup::p2pInvolved() const
#endif // !ENABLE_BITTORRENT
}
+void RequestGroup::enableSeedOnly()
+{
+ if(seedOnly_ || !option_->getAsBool(PREF_BT_DETACH_SEED_ONLY)) {
+ return;
+ }
+
+ if(requestGroupMan_) {
+ seedOnly_ = true;
+
+ requestGroupMan_->decreaseNumActive();
+ requestGroupMan_->requestQueueCheck();
+ }
+}
+
} // namespace aria2
diff --git a/src/RequestGroup.h b/src/RequestGroup.h
index b04cfafc..00966748 100644
--- a/src/RequestGroup.h
+++ b/src/RequestGroup.h
@@ -179,6 +179,7 @@ private:
// just sits in memory.
bool inMemoryDownload_;
+ bool seedOnly_;
void validateFilename(const std::string& expectedFilename,
const std::string& actualFilename) const;
@@ -563,6 +564,13 @@ public:
{
state_ = state;
}
+
+ bool isSeedOnlyEnabled()
+ {
+ return seedOnly_;
+ }
+
+ void enableSeedOnly();
};
} // namespace aria2
diff --git a/src/RequestGroupMan.cc b/src/RequestGroupMan.cc
index 8921bfe1..b33e79e0 100644
--- a/src/RequestGroupMan.cc
+++ b/src/RequestGroupMan.cc
@@ -105,6 +105,7 @@ RequestGroupMan::RequestGroupMan
int maxSimultaneousDownloads,
const Option* option)
: maxSimultaneousDownloads_(maxSimultaneousDownloads),
+ numActive_(0),
option_(option),
serverStatMan_(std::make_shared<ServerStatMan>()),
maxOverallDownloadSpeedLimit_
@@ -140,6 +141,7 @@ bool RequestGroupMan::downloadFinished()
void RequestGroupMan::addRequestGroup
(const std::shared_ptr<RequestGroup>& group)
{
+ ++numActive_;
requestGroups_.push_back(group->getGID(), group);
}
@@ -320,6 +322,11 @@ public:
if(group->getNumCommand() == 0) {
collectStat(group);
const std::shared_ptr<DownloadContext>& dctx = group->getDownloadContext();
+
+ if(!group->isSeedOnlyEnabled()) {
+ e_->getRequestGroupMan()->decreaseNumActive();
+ }
+
// DownloadContext::resetDownloadStopTime() is only called when
// download completed. If
// DownloadContext::getDownloadStopTime().isZero() is true, then
@@ -453,11 +460,11 @@ std::vector<std::unique_ptr<Command>> createInitialCommand
void RequestGroupMan::fillRequestGroupFromReserver(DownloadEngine* e)
{
removeStoppedGroup(e);
- if(static_cast<size_t>(maxSimultaneousDownloads_) <= requestGroups_.size()) {
+ if(static_cast<size_t>(maxSimultaneousDownloads_) <= numActive_) {
return;
}
int count = 0;
- int num = maxSimultaneousDownloads_-requestGroups_.size();
+ int num = maxSimultaneousDownloads_ - numActive_;
std::vector<std::shared_ptr<RequestGroup> > pending;
while(count < num && (uriListParser_ || !reservedGroups_.empty())) {
@@ -488,6 +495,7 @@ void RequestGroupMan::fillRequestGroupFromReserver(DownloadEngine* e)
configureRequestGroup(groupToAdd);
groupToAdd->setRequestGroupMan(this);
groupToAdd->setState(RequestGroup::STATE_ACTIVE);
+ ++numActive_;
requestGroups_.push_back(groupToAdd->getGID(), groupToAdd);
try {
auto res = createInitialCommand(groupToAdd, e);
@@ -965,4 +973,10 @@ void RequestGroupMan::initWrDiskCache()
}
}
+void RequestGroupMan::decreaseNumActive()
+{
+ assert(numActive_ > 0);
+ --numActive_;
+}
+
} // namespace aria2
diff --git a/src/RequestGroupMan.h b/src/RequestGroupMan.h
index a9b8c4ec..fa08f182 100644
--- a/src/RequestGroupMan.h
+++ b/src/RequestGroupMan.h
@@ -75,6 +75,13 @@ private:
int maxSimultaneousDownloads_;
+ // The number of simultaneous active downloads, excluding seed only
+ // item if PREF_BT_DETACH_SEED_ONLY is true. We rely on this
+ // variable to maintain the number of concurrent downloads. If
+ // PREF_BT_DETACH_SEED_ONLY is false, this variable is equal to
+ // requestGroups_.size().
+ size_t numActive_;
+
const Option* option_;
std::shared_ptr<ServerStatMan> serverStatMan_;
@@ -376,6 +383,8 @@ public:
{
return openedFileCounter_;
}
+
+ void decreaseNumActive();
};
} // namespace aria2
diff --git a/src/prefs.cc b/src/prefs.cc
index 4ceea78a..a6de66ef 100644
--- a/src/prefs.cc
+++ b/src/prefs.cc
@@ -542,6 +542,7 @@ PrefPtr PREF_BT_EXCLUDE_TRACKER = makePref("bt-exclude-tracker");
// values: true | false
PrefPtr PREF_BT_REMOVE_UNSELECTED_FILE =
makePref("bt-remove-unselected-file");
+PrefPtr PREF_BT_DETACH_SEED_ONLY = makePref("bt-detach-seed-only");
/**
* Metalink related preferences
diff --git a/src/prefs.h b/src/prefs.h
index 071e1651..33ab67ac 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -478,6 +478,8 @@ extern PrefPtr PREF_BT_TRACKER;
extern PrefPtr PREF_BT_EXCLUDE_TRACKER;
// values: true | false
extern PrefPtr PREF_BT_REMOVE_UNSELECTED_FILE;
+// values: true |false
+extern PrefPtr PREF_BT_DETACH_SEED_ONLY;
/**
* Metalink related preferences
diff --git a/src/usage_text.h b/src/usage_text.h
index d8d60b31..2831b48e 100644
--- a/src/usage_text.h
+++ b/src/usage_text.h
@@ -1000,3 +1000,14 @@
" using their metadata. This option pauses these\n" \
" subsequent downloads. This option is effective\n" \
" only when --enable-rpc=true is given.")
+#define TEXT_BT_DETACH_SEED_ONLY \
+ _(" --bt-detach-seed-only[=true|false]\n" \
+ " Exclude seed only downloads when counting\n" \
+ " concurrent active downloads (See -j option).\n" \
+ " This means that if -j3 is given and this option\n" \
+ " is turned on and 3 downloads are active and one\n" \
+ " of those enters seed mode, then it is excluded\n" \
+ " from active download count (thus it becomes 2),\n" \
+ " and the next download waiting in queue gets\n" \
+ " started. But be aware that seeding item is still\n" \
+ " recognized as active download in RPC method.")