Don't copy Option in RequestGroup ctor.

Copy on receive is not a practice in aria2 source code.
This commit is contained in:
Tatsuhiro Tsujikawa 2011-10-25 21:44:04 +09:00
parent 62a07fff5f
commit 12659c74a8
9 changed files with 53 additions and 39 deletions

View file

@ -147,23 +147,23 @@ void
Metalink2RequestGroup::createRequestGroup Metalink2RequestGroup::createRequestGroup
(std::vector<SharedHandle<RequestGroup> >& groups, (std::vector<SharedHandle<RequestGroup> >& groups,
const std::vector<SharedHandle<MetalinkEntry> >& entries, const std::vector<SharedHandle<MetalinkEntry> >& entries,
const SharedHandle<Option>& option) const SharedHandle<Option>& optionTemplate)
{ {
if(entries.empty()) { if(entries.empty()) {
A2_LOG_NOTICE(EX_NO_RESULT_WITH_YOUR_PREFS); A2_LOG_NOTICE(EX_NO_RESULT_WITH_YOUR_PREFS);
return; return;
} }
std::vector<int32_t> selectIndexes = std::vector<int32_t> selectIndexes =
util::parseIntRange(option->get(PREF_SELECT_FILE)).flush(); util::parseIntRange(optionTemplate->get(PREF_SELECT_FILE)).flush();
std::sort(selectIndexes.begin(), selectIndexes.end()); std::sort(selectIndexes.begin(), selectIndexes.end());
std::vector<std::string> locations; std::vector<std::string> locations;
if(option->defined(PREF_METALINK_LOCATION)) { if(optionTemplate->defined(PREF_METALINK_LOCATION)) {
util::split(util::toLower(option->get(PREF_METALINK_LOCATION)), util::split(util::toLower(optionTemplate->get(PREF_METALINK_LOCATION)),
std::back_inserter(locations), ",", true); std::back_inserter(locations), ",", true);
} }
std::string preferredProtocol; std::string preferredProtocol;
if(option->get(PREF_METALINK_PREFERRED_PROTOCOL) != V_NONE) { if(optionTemplate->get(PREF_METALINK_PREFERRED_PROTOCOL) != V_NONE) {
preferredProtocol = option->get(PREF_METALINK_PREFERRED_PROTOCOL); preferredProtocol = optionTemplate->get(PREF_METALINK_PREFERRED_PROTOCOL);
} }
std::vector<SharedHandle<MetalinkEntry> > selectedEntries; std::vector<SharedHandle<MetalinkEntry> > selectedEntries;
selectedEntries.reserve(entries.size()); selectedEntries.reserve(entries.size());
@ -205,7 +205,7 @@ Metalink2RequestGroup::createRequestGroup
uris.push_back(metaurl); uris.push_back(metaurl);
{ {
std::vector<SharedHandle<RequestGroup> > result; std::vector<SharedHandle<RequestGroup> > result;
createRequestGroupForUri(result, option, uris, createRequestGroupForUri(result, optionTemplate, uris,
/* ignoreForceSequential = */true, /* ignoreForceSequential = */true,
/* ignoreLocalPath = */true); /* ignoreLocalPath = */true);
if(!uris.empty()) { if(!uris.empty()) {
@ -229,6 +229,7 @@ Metalink2RequestGroup::createRequestGroup
} }
} }
#endif // ENABLE_BITTORRENT #endif // ENABLE_BITTORRENT
SharedHandle<Option> option = util::copy(optionTemplate);
SharedHandle<RequestGroup> rg(new RequestGroup(option)); SharedHandle<RequestGroup> rg(new RequestGroup(option));
SharedHandle<DownloadContext> dctx; SharedHandle<DownloadContext> dctx;
if(mes.size() == 1) { if(mes.size() == 1) {
@ -311,7 +312,7 @@ Metalink2RequestGroup::createRequestGroup
} }
rg->setDownloadContext(dctx); rg->setDownloadContext(dctx);
rg->setPauseRequested(option->getAsBool(PREF_PAUSE)); rg->setPauseRequested(option->getAsBool(PREF_PAUSE));
removeOneshotOption(rg->getOption()); removeOneshotOption(option);
// remove "metalink" from Accept Type list to avoid loop in // remove "metalink" from Accept Type list to avoid loop in
// tranparent metalink // tranparent metalink
util::removeMetalinkContentTypes(rg); util::removeMetalinkContentTypes(rg);

View file

@ -124,7 +124,7 @@ a2_gid_t RequestGroup::gidCounter_ = 0;
RequestGroup::RequestGroup(const SharedHandle<Option>& option) RequestGroup::RequestGroup(const SharedHandle<Option>& option)
: gid_(newGID()), : gid_(newGID()),
option_(new Option(*option.get())), option_(option),
numConcurrentCommand_(option->getAsInt(PREF_SPLIT)), numConcurrentCommand_(option->getAsInt(PREF_SPLIT)),
numStreamConnection_(0), numStreamConnection_(0),
numStreamCommand_(0), numStreamCommand_(0),

View file

@ -196,7 +196,6 @@ private:
bool isCheckIntegrityReady() const; bool isCheckIntegrityReady() const;
public: public:
// The copy of option is stored in RequestGroup object.
RequestGroup(const SharedHandle<Option>& option); RequestGroup(const SharedHandle<Option>& option);
~RequestGroup(); ~RequestGroup();

View file

@ -215,7 +215,8 @@ TrackerWatcherCommand::createRequestGroup(const std::string& uri)
{ {
std::vector<std::string> uris; std::vector<std::string> uris;
uris.push_back(uri); uris.push_back(uri);
SharedHandle<RequestGroup> rg(new RequestGroup(getOption())); SharedHandle<Option> option = util::copy(getOption());
SharedHandle<RequestGroup> rg(new RequestGroup(option));
if(backupTrackerIsAvailable(requestGroup_->getDownloadContext())) { if(backupTrackerIsAvailable(requestGroup_->getDownloadContext())) {
A2_LOG_DEBUG("This is multi-tracker announce."); A2_LOG_DEBUG("This is multi-tracker announce.");
} else { } else {
@ -224,19 +225,19 @@ TrackerWatcherCommand::createRequestGroup(const std::string& uri)
rg->setNumConcurrentCommand(1); rg->setNumConcurrentCommand(1);
// If backup tracker is available, try 2 times for each tracker // If backup tracker is available, try 2 times for each tracker
// and if they all fails, then try next one. // and if they all fails, then try next one.
rg->getOption()->put(PREF_MAX_TRIES, "2"); option->put(PREF_MAX_TRIES, "2");
// TODO When dry-run mode becomes available in BitTorrent, set // TODO When dry-run mode becomes available in BitTorrent, set
// PREF_DRY_RUN=false too. // PREF_DRY_RUN=false too.
rg->getOption()->put(PREF_USE_HEAD, A2_V_FALSE); option->put(PREF_USE_HEAD, A2_V_FALSE);
// Setting tracker timeouts // Setting tracker timeouts
rg->setTimeout(rg->getOption()->getAsInt(PREF_BT_TRACKER_TIMEOUT)); rg->setTimeout(option->getAsInt(PREF_BT_TRACKER_TIMEOUT));
rg->getOption()->put(PREF_CONNECT_TIMEOUT, option->put(PREF_CONNECT_TIMEOUT,
rg->getOption()->get(PREF_BT_TRACKER_CONNECT_TIMEOUT)); option->get(PREF_BT_TRACKER_CONNECT_TIMEOUT));
rg->getOption()->put(PREF_REUSE_URI, A2_V_FALSE); option->put(PREF_REUSE_URI, A2_V_FALSE);
rg->getOption()->put(PREF_SELECT_LEAST_USED_HOST, A2_V_FALSE); option->put(PREF_SELECT_LEAST_USED_HOST, A2_V_FALSE);
static const std::string TRACKER_ANNOUNCE_FILE("[tracker.announce]"); static const std::string TRACKER_ANNOUNCE_FILE("[tracker.announce]");
SharedHandle<DownloadContext> dctx SharedHandle<DownloadContext> dctx
(new DownloadContext(getOption()->getAsInt(PREF_PIECE_LENGTH), (new DownloadContext(option->getAsInt(PREF_PIECE_LENGTH),
0, 0,
TRACKER_ANNOUNCE_FILE)); TRACKER_ANNOUNCE_FILE));
dctx->getFileEntries().front()->setUris(uris); dctx->getFileEntries().front()->setUris(uris);

View file

@ -110,9 +110,11 @@ void splitURI(std::vector<std::string>& result,
namespace { namespace {
SharedHandle<RequestGroup> createRequestGroup SharedHandle<RequestGroup> createRequestGroup
(const SharedHandle<Option>& option, const std::vector<std::string>& uris, (const SharedHandle<Option>& optionTemplate,
const std::vector<std::string>& uris,
bool useOutOption = false) bool useOutOption = false)
{ {
SharedHandle<Option> option = util::copy(optionTemplate);
SharedHandle<RequestGroup> rg(new RequestGroup(option)); SharedHandle<RequestGroup> rg(new RequestGroup(option));
SharedHandle<DownloadContext> dctx SharedHandle<DownloadContext> dctx
(new DownloadContext (new DownloadContext
@ -135,7 +137,7 @@ SharedHandle<RequestGroup> createRequestGroup
#endif // ENABLE_MESSAGE_DIGEST #endif // ENABLE_MESSAGE_DIGEST
rg->setDownloadContext(dctx); rg->setDownloadContext(dctx);
rg->setPauseRequested(option->getAsBool(PREF_PAUSE)); rg->setPauseRequested(option->getAsBool(PREF_PAUSE));
removeOneshotOption(rg->getOption()); removeOneshotOption(option);
return rg; return rg;
} }
} // namespace } // namespace
@ -161,11 +163,12 @@ SharedHandle<MetadataInfo> createMetadataInfoDataOnly()
namespace { namespace {
SharedHandle<RequestGroup> SharedHandle<RequestGroup>
createBtRequestGroup(const std::string& torrentFilePath, createBtRequestGroup(const std::string& torrentFilePath,
const SharedHandle<Option>& option, const SharedHandle<Option>& optionTemplate,
const std::vector<std::string>& auxUris, const std::vector<std::string>& auxUris,
const std::string& torrentData = "", const std::string& torrentData = "",
bool adjustAnnounceUri = true) bool adjustAnnounceUri = true)
{ {
SharedHandle<Option> option = util::copy(optionTemplate);
SharedHandle<RequestGroup> rg(new RequestGroup(option)); SharedHandle<RequestGroup> rg(new RequestGroup(option));
SharedHandle<DownloadContext> dctx(new DownloadContext()); SharedHandle<DownloadContext> dctx(new DownloadContext());
if(torrentData.empty()) { if(torrentData.empty()) {
@ -194,16 +197,18 @@ createBtRequestGroup(const std::string& torrentFilePath,
// Remove "metalink" from Accept Type list to avoid server from // Remove "metalink" from Accept Type list to avoid server from
// responding Metalink file for web-seeding URIs. // responding Metalink file for web-seeding URIs.
util::removeMetalinkContentTypes(rg); util::removeMetalinkContentTypes(rg);
removeOneshotOption(rg->getOption()); removeOneshotOption(option);
return rg; return rg;
} }
} // namespace } // namespace
namespace { namespace {
SharedHandle<RequestGroup> SharedHandle<RequestGroup>
createBtMagnetRequestGroup(const std::string& magnetLink, createBtMagnetRequestGroup
const SharedHandle<Option>& option) (const std::string& magnetLink,
const SharedHandle<Option>& optionTemplate)
{ {
SharedHandle<Option> option = util::copy(optionTemplate);
SharedHandle<RequestGroup> rg(new RequestGroup(option)); SharedHandle<RequestGroup> rg(new RequestGroup(option));
SharedHandle<DownloadContext> dctx SharedHandle<DownloadContext> dctx
(new DownloadContext(METADATA_PIECE_SIZE, 0, (new DownloadContext(METADATA_PIECE_SIZE, 0,
@ -215,7 +220,7 @@ createBtMagnetRequestGroup(const std::string& magnetLink,
bittorrent::loadMagnet(magnetLink, dctx); bittorrent::loadMagnet(magnetLink, dctx);
SharedHandle<TorrentAttribute> torrentAttrs = SharedHandle<TorrentAttribute> torrentAttrs =
bittorrent::getTorrentAttrs(dctx); bittorrent::getTorrentAttrs(dctx);
bittorrent::adjustAnnounceUri(torrentAttrs, rg->getOption()); bittorrent::adjustAnnounceUri(torrentAttrs, option);
dctx->getFirstFileEntry()->setPath(torrentAttrs->name); dctx->getFirstFileEntry()->setPath(torrentAttrs->name);
rg->setDownloadContext(dctx); rg->setDownloadContext(dctx);
rg->clearPostDownloadHandler(); rg->clearPostDownloadHandler();
@ -227,7 +232,7 @@ createBtMagnetRequestGroup(const std::string& magnetLink,
rg->setMetadataInfo(createMetadataInfo(magnetLink)); rg->setMetadataInfo(createMetadataInfo(magnetLink));
rg->markInMemoryDownload(); rg->markInMemoryDownload();
rg->setPauseRequested(option->getAsBool(PREF_PAUSE)); rg->setPauseRequested(option->getAsBool(PREF_PAUSE));
removeOneshotOption(rg->getOption()); removeOneshotOption(option);
return rg; return rg;
} }
} // namespace } // namespace

View file

@ -514,6 +514,12 @@ nextParam
return std::make_pair(end, false); return std::make_pair(end, false);
} }
template<typename T>
SharedHandle<T> copy(const SharedHandle<T>& a)
{
return SharedHandle<T>(new T(*a.get()));
}
} // namespace util } // namespace util
} // namespace aria2 } // namespace aria2

View file

@ -18,6 +18,7 @@
#include "ByteArrayDiskWriter.h" #include "ByteArrayDiskWriter.h"
#include "MockPieceStorage.h" #include "MockPieceStorage.h"
#include "prefs.h" #include "prefs.h"
#include "util.h"
namespace aria2 { namespace aria2 {
@ -37,7 +38,7 @@ class BtDependencyTest:public CppUnit::TestFixture {
SharedHandle<RequestGroup> createDependant(const SharedHandle<Option>& option) SharedHandle<RequestGroup> createDependant(const SharedHandle<Option>& option)
{ {
SharedHandle<RequestGroup> dependant(new RequestGroup(option)); SharedHandle<RequestGroup> dependant(new RequestGroup(util::copy(option)));
SharedHandle<DownloadContext> dctx SharedHandle<DownloadContext> dctx
(new DownloadContext(0, 0, "/tmp/outfile.path")); (new DownloadContext(0, 0, "/tmp/outfile.path"));
std::vector<std::string> uris; std::vector<std::string> uris;
@ -55,7 +56,7 @@ class BtDependencyTest:public CppUnit::TestFixture {
const std::string& torrentFile, const std::string& torrentFile,
int64_t length) int64_t length)
{ {
SharedHandle<RequestGroup> dependee(new RequestGroup(option)); SharedHandle<RequestGroup> dependee(new RequestGroup(util::copy(option)));
SharedHandle<DownloadContext> dctx SharedHandle<DownloadContext> dctx
(new DownloadContext(1024*1024, length, torrentFile)); (new DownloadContext(1024*1024, length, torrentFile));
dependee->setDownloadContext(dctx); dependee->setDownloadContext(dctx);

View file

@ -15,6 +15,7 @@
#include "File.h" #include "File.h"
#include "array_fun.h" #include "array_fun.h"
#include "RecoverableException.h" #include "RecoverableException.h"
#include "util.h"
namespace aria2 { namespace aria2 {
@ -48,8 +49,8 @@ CPPUNIT_TEST_SUITE_REGISTRATION( RequestGroupManTest );
void RequestGroupManTest::testIsSameFileBeingDownloaded() void RequestGroupManTest::testIsSameFileBeingDownloaded()
{ {
SharedHandle<RequestGroup> rg1(new RequestGroup(option_)); SharedHandle<RequestGroup> rg1(new RequestGroup(util::copy(option_)));
SharedHandle<RequestGroup> rg2(new RequestGroup(option_)); SharedHandle<RequestGroup> rg2(new RequestGroup(util::copy(option_)));
SharedHandle<DownloadContext> dctx1 SharedHandle<DownloadContext> dctx1
(new DownloadContext(0, 0, "aria2.tar.bz2")); (new DownloadContext(0, 0, "aria2.tar.bz2"));
@ -117,10 +118,10 @@ void RequestGroupManTest::testLoadServerStat()
void RequestGroupManTest::testChangeReservedGroupPosition() void RequestGroupManTest::testChangeReservedGroupPosition()
{ {
SharedHandle<RequestGroup> gs[] = { SharedHandle<RequestGroup> gs[] = {
SharedHandle<RequestGroup>(new RequestGroup(option_)), SharedHandle<RequestGroup>(new RequestGroup(util::copy(option_))),
SharedHandle<RequestGroup>(new RequestGroup(option_)), SharedHandle<RequestGroup>(new RequestGroup(util::copy(option_))),
SharedHandle<RequestGroup>(new RequestGroup(option_)), SharedHandle<RequestGroup>(new RequestGroup(util::copy(option_))),
SharedHandle<RequestGroup>(new RequestGroup(option_)) SharedHandle<RequestGroup>(new RequestGroup(util::copy(option_)))
}; };
std::vector<SharedHandle<RequestGroup> > groups(vbegin(gs), vend(gs)); std::vector<SharedHandle<RequestGroup> > groups(vbegin(gs), vend(gs));
RequestGroupMan rm(groups, 0, option_.get()); RequestGroupMan rm(groups, 0, option_.get());

View file

@ -752,11 +752,11 @@ void RpcMethodTest::testGatherProgressCommon()
SharedHandle<DownloadContext> dctx(new DownloadContext(0, 0,"aria2.tar.bz2")); SharedHandle<DownloadContext> dctx(new DownloadContext(0, 0,"aria2.tar.bz2"));
std::string uris[] = { "http://localhost/aria2.tar.bz2" }; std::string uris[] = { "http://localhost/aria2.tar.bz2" };
dctx->getFirstFileEntry()->addUris(vbegin(uris), vend(uris)); dctx->getFirstFileEntry()->addUris(vbegin(uris), vend(uris));
SharedHandle<RequestGroup> group(new RequestGroup(option_)); SharedHandle<RequestGroup> group(new RequestGroup(util::copy(option_)));
group->setDownloadContext(dctx); group->setDownloadContext(dctx);
std::vector<SharedHandle<RequestGroup> > followedBy; std::vector<SharedHandle<RequestGroup> > followedBy;
for(int i = 0; i < 2; ++i) { for(int i = 0; i < 2; ++i) {
followedBy.push_back(SharedHandle<RequestGroup>(new RequestGroup(option_))); followedBy.push_back(SharedHandle<RequestGroup>(new RequestGroup(util::copy(option_))));
} }
group->followedBy(followedBy.begin(), followedBy.end()); group->followedBy(followedBy.begin(), followedBy.end());
@ -844,9 +844,9 @@ void RpcMethodTest::testGatherBitTorrentMetadata()
void RpcMethodTest::testChangePosition() void RpcMethodTest::testChangePosition()
{ {
e_->getRequestGroupMan()->addReservedGroup e_->getRequestGroupMan()->addReservedGroup
(SharedHandle<RequestGroup>(new RequestGroup(option_))); (SharedHandle<RequestGroup>(new RequestGroup(util::copy(option_))));
e_->getRequestGroupMan()->addReservedGroup e_->getRequestGroupMan()->addReservedGroup
(SharedHandle<RequestGroup>(new RequestGroup(option_))); (SharedHandle<RequestGroup>(new RequestGroup(util::copy(option_))));
ChangePositionRpcMethod m; ChangePositionRpcMethod m;
RpcRequest req(ChangePositionRpcMethod::getMethodName(), List::g()); RpcRequest req(ChangePositionRpcMethod::getMethodName(), List::g());