Wrap Command object in std::unique_ptr

pull/103/head
Tatsuhiro Tsujikawa 2013-06-23 21:55:52 +09:00
parent bb5b7eeedb
commit fa9f3fb5a3
103 changed files with 555 additions and 713 deletions

View File

@ -48,7 +48,6 @@
#include "DownloadFailureException.h" #include "DownloadFailureException.h"
#include "CreateRequestCommand.h" #include "CreateRequestCommand.h"
#include "InitiateConnectionCommandFactory.h" #include "InitiateConnectionCommandFactory.h"
#include "SleepCommand.h"
#include "StreamCheckIntegrityEntry.h" #include "StreamCheckIntegrityEntry.h"
#include "PieceStorage.h" #include "PieceStorage.h"
#include "SocketCore.h" #include "SocketCore.h"
@ -133,11 +132,10 @@ void AbstractCommand::useFasterRequest
fasterRequest->getPort())); fasterRequest->getPort()));
// Cancel current Request object and use faster one. // Cancel current Request object and use faster one.
fileEntry_->removeRequest(req_); fileEntry_->removeRequest(req_);
Command* command =
InitiateConnectionCommandFactory::createInitiateConnectionCommand
(getCuid(), fasterRequest, fileEntry_, requestGroup_, e_);
e_->setNoWait(true); e_->setNoWait(true);
e_->addCommand(command); e_->addCommand(InitiateConnectionCommandFactory::
createInitiateConnectionCommand
(getCuid(), fasterRequest, fileEntry_, requestGroup_, e_));
} }
bool AbstractCommand::execute() { bool AbstractCommand::execute() {
@ -301,7 +299,7 @@ bool AbstractCommand::execute() {
} }
throw DL_RETRY_EX2(EX_TIME_OUT, error_code::TIME_OUT); throw DL_RETRY_EX2(EX_TIME_OUT, error_code::TIME_OUT);
} }
e_->addCommand(this); addCommandSelf();
return false; return false;
} }
} catch(DlAbortEx& err) { } catch(DlAbortEx& err) {
@ -390,10 +388,10 @@ void AbstractCommand::tryReserved() {
} }
A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Trying reserved/pooled request.", A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Trying reserved/pooled request.",
getCuid())); getCuid()));
std::vector<Command*> commands; std::vector<std::unique_ptr<Command>> commands;
requestGroup_->createNextCommand(commands, e_, 1); requestGroup_->createNextCommand(commands, e_, 1);
e_->setNoWait(true); e_->setNoWait(true);
e_->addCommand(commands); e_->addCommand(std::move(commands));
} }
bool AbstractCommand::prepareForRetry(time_t wait) { bool AbstractCommand::prepareForRetry(time_t wait) {
@ -415,16 +413,16 @@ bool AbstractCommand::prepareForRetry(time_t wait) {
} }
} }
Command* command = new CreateRequestCommand(getCuid(), requestGroup_, e_); auto command = make_unique<CreateRequestCommand>(getCuid(),
requestGroup_, e_);
if(wait == 0) { if(wait == 0) {
e_->setNoWait(true); e_->setNoWait(true);
e_->addCommand(command);
} else { } else {
// We don't use wait so that Command can be executed by // We don't use wait so that Command can be executed by
// DownloadEngine::setRefreshInterval(0). // DownloadEngine::setRefreshInterval(0).
command->setStatus(Command::STATUS_INACTIVE); command->setStatus(Command::STATUS_INACTIVE);
e_->addCommand(command);
} }
e_->addCommand(std::move(command));
return true; return true;
} }
@ -774,11 +772,9 @@ std::string AbstractCommand::resolveHostname
void AbstractCommand::prepareForNextAction void AbstractCommand::prepareForNextAction
(const std::shared_ptr<CheckIntegrityEntry>& checkEntry) (const std::shared_ptr<CheckIntegrityEntry>& checkEntry)
{ {
std::vector<Command*>* commands = new std::vector<Command*>(); std::vector<std::unique_ptr<Command>> commands;
auto_delete_container<std::vector<Command*> > commandsDel(commands); requestGroup_->processCheckIntegrityEntry(commands, checkEntry, e_);
requestGroup_->processCheckIntegrityEntry(*commands, checkEntry, e_); e_->addCommand(std::move(commands));
e_->addCommand(*commands);
commands->clear();
e_->setNoWait(true); e_->setNoWait(true);
} }
@ -796,11 +792,10 @@ bool AbstractCommand::checkIfConnectionEstablished
A2_LOG_INFO(fmt(MSG_CONNECT_FAILED_AND_RETRY, A2_LOG_INFO(fmt(MSG_CONNECT_FAILED_AND_RETRY,
getCuid(), getCuid(),
connectedAddr.c_str(), connectedPort)); connectedAddr.c_str(), connectedPort));
Command* command =
InitiateConnectionCommandFactory::createInitiateConnectionCommand
(getCuid(), req_, fileEntry_, requestGroup_, e_);
e_->setNoWait(true); e_->setNoWait(true);
e_->addCommand(command); e_->addCommand(InitiateConnectionCommandFactory::
createInitiateConnectionCommand
(getCuid(), req_, fileEntry_, requestGroup_, e_));
return false; return false;
} }
e_->removeCachedIPAddress(connectedHostname, connectedPort); e_->removeCachedIPAddress(connectedHostname, connectedPort);
@ -889,4 +884,9 @@ void AbstractCommand::checkSocketRecvBuffer()
} }
} }
void AbstractCommand::addCommandSelf()
{
e_->addCommand(std::unique_ptr<Command>(this));
}
} // namespace aria2 } // namespace aria2

View File

@ -222,6 +222,7 @@ public:
void checkSocketRecvBuffer(); void checkSocketRecvBuffer();
void addCommandSelf();
protected: protected:
virtual bool prepareForRetry(time_t wait); virtual bool prepareForRetry(time_t wait);
virtual void onAbort(); virtual void onAbort();

View File

@ -126,7 +126,7 @@ bool AbstractHttpServerResponseCommand::execute()
return true; return true;
} else { } else {
updateReadWriteCheck(); updateReadWriteCheck();
e_->addCommand(this); e_->addCommand(std::unique_ptr<Command>(this));
return false; return false;
} }
} }

View File

@ -88,7 +88,7 @@ bool AbstractProxyRequestCommand::executeInternal() {
return true; return true;
} else { } else {
setWriteCheckSocket(getSocket()); setWriteCheckSocket(getSocket());
getDownloadEngine()->addCommand(this); addCommandSelf();
return false; return false;
} }
} }

View File

@ -70,7 +70,7 @@ public:
virtual ~AbstractProxyRequestCommand(); virtual ~AbstractProxyRequestCommand();
virtual Command* getNextCommand() = 0; virtual std::unique_ptr<Command> getNextCommand() = 0;
}; };
} // namespace aria2 } // namespace aria2

View File

@ -67,7 +67,7 @@ bool AbstractProxyResponseCommand::executeInternal() {
std::shared_ptr<HttpResponse> httpResponse = httpConnection_->receiveResponse(); std::shared_ptr<HttpResponse> httpResponse = httpConnection_->receiveResponse();
if(!httpResponse) { if(!httpResponse) {
// the server has not responded our request yet. // the server has not responded our request yet.
getDownloadEngine()->addCommand(this); addCommandSelf();
return false; return false;
} }
if(httpResponse->getStatusCode() != 200) { if(httpResponse->getStatusCode() != 200) {

View File

@ -64,7 +64,7 @@ public:
virtual ~AbstractProxyResponseCommand(); virtual ~AbstractProxyResponseCommand();
virtual Command* getNextCommand() = 0; virtual std::unique_ptr<Command> getNextCommand() = 0;
}; };
} // namespace aria2 } // namespace aria2

View File

@ -123,7 +123,7 @@ bool ActivePeerConnectionCommand::execute() {
} }
} }
} }
e_->addCommand(this); e_->addCommand(std::unique_ptr<Command>(this));
return false; return false;
} }
@ -136,12 +136,11 @@ void ActivePeerConnectionCommand::makeNewConnections(int num)
if(!peer) { if(!peer) {
break; break;
} }
PeerInitiateConnectionCommand* command; auto command = make_unique<PeerInitiateConnectionCommand>
command = new PeerInitiateConnectionCommand(ncuid, requestGroup_, peer, e_, (ncuid, requestGroup_, peer, e_, btRuntime_);
btRuntime_);
command->setPeerStorage(peerStorage_); command->setPeerStorage(peerStorage_);
command->setPieceStorage(pieceStorage_); command->setPieceStorage(pieceStorage_);
e_->addCommand(command); e_->addCommand(std::move(command));
A2_LOG_INFO(fmt(MSG_CONNECTING_TO_PEER, getCuid(), A2_LOG_INFO(fmt(MSG_CONNECTING_TO_PEER, getCuid(),
peer->getIPAddress().c_str())); peer->getIPAddress().c_str()));
} }

View File

@ -133,7 +133,7 @@ bool BackupIPv4ConnectCommand::execute()
retval = true; retval = true;
} }
if(!retval) { if(!retval) {
e_->addCommand(this); e_->addCommand(std::unique_ptr<Command>(this));
} }
return retval; return retval;
} }

View File

@ -49,7 +49,7 @@ BtCheckIntegrityEntry::BtCheckIntegrityEntry(RequestGroup* requestGroup):
BtCheckIntegrityEntry::~BtCheckIntegrityEntry() {} BtCheckIntegrityEntry::~BtCheckIntegrityEntry() {}
void BtCheckIntegrityEntry::onDownloadIncomplete void BtCheckIntegrityEntry::onDownloadIncomplete
(std::vector<Command*>& commands, DownloadEngine* e) (std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
{ {
const std::shared_ptr<PieceStorage>& ps = getRequestGroup()->getPieceStorage(); const std::shared_ptr<PieceStorage>& ps = getRequestGroup()->getPieceStorage();
ps->onDownloadIncomplete(); ps->onDownloadIncomplete();
@ -69,7 +69,7 @@ void BtCheckIntegrityEntry::onDownloadIncomplete
} }
void BtCheckIntegrityEntry::onDownloadFinished void BtCheckIntegrityEntry::onDownloadFinished
(std::vector<Command*>& commands, DownloadEngine* e) (std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
{ {
// TODO Currently,when all the checksums // TODO Currently,when all the checksums
// are valid, then aira2 goes to seeding mode. Sometimes it is better // are valid, then aira2 goes to seeding mode. Sometimes it is better

View File

@ -45,11 +45,11 @@ public:
virtual ~BtCheckIntegrityEntry(); virtual ~BtCheckIntegrityEntry();
virtual void onDownloadFinished(std::vector<Command*>& commands, virtual void onDownloadFinished
DownloadEngine* e); (std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e);
virtual void onDownloadIncomplete(std::vector<Command*>& commands, virtual void onDownloadIncomplete
DownloadEngine* e); (std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e);
}; };
} // namespace aria2 } // namespace aria2

View File

@ -56,7 +56,7 @@ BtFileAllocationEntry::BtFileAllocationEntry(RequestGroup* requestGroup):
BtFileAllocationEntry::~BtFileAllocationEntry() {} BtFileAllocationEntry::~BtFileAllocationEntry() {}
void BtFileAllocationEntry::prepareForNextAction void BtFileAllocationEntry::prepareForNextAction
(std::vector<Command*>& commands, DownloadEngine* e) (std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
{ {
BtSetup().setup(commands, getRequestGroup(), e, BtSetup().setup(commands, getRequestGroup(), e,
getRequestGroup()->getOption().get()); getRequestGroup()->getOption().get());

View File

@ -45,8 +45,8 @@ public:
virtual ~BtFileAllocationEntry(); virtual ~BtFileAllocationEntry();
virtual void prepareForNextAction(std::vector<Command*>& commands, virtual void prepareForNextAction
DownloadEngine* e); (std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e);
}; };
} // namespace aria2 } // namespace aria2

View File

@ -90,7 +90,7 @@ namespace aria2 {
BtSetup::BtSetup() {} BtSetup::BtSetup() {}
void BtSetup::setup(std::vector<Command*>& commands, void BtSetup::setup(std::vector<std::unique_ptr<Command>>& commands,
RequestGroup* requestGroup, RequestGroup* requestGroup,
DownloadEngine* e, DownloadEngine* e,
const Option* option) const Option* option)
@ -109,53 +109,50 @@ void BtSetup::setup(std::vector<Command*>& commands,
const std::shared_ptr<BtAnnounce>& btAnnounce = btObject->btAnnounce; const std::shared_ptr<BtAnnounce>& btAnnounce = btObject->btAnnounce;
// commands // commands
{ {
TrackerWatcherCommand* c = auto c = make_unique<TrackerWatcherCommand>(e->newCUID(), requestGroup, e);
new TrackerWatcherCommand(e->newCUID(), requestGroup, e);
c->setPeerStorage(peerStorage); c->setPeerStorage(peerStorage);
c->setPieceStorage(pieceStorage); c->setPieceStorage(pieceStorage);
c->setBtRuntime(btRuntime); c->setBtRuntime(btRuntime);
c->setBtAnnounce(btAnnounce); c->setBtAnnounce(btAnnounce);
commands.push_back(c); commands.push_back(std::move(c));
} }
if(!metadataGetMode) { if(!metadataGetMode) {
PeerChokeCommand* c = auto c = make_unique<PeerChokeCommand>(e->newCUID(), e);
new PeerChokeCommand(e->newCUID(), e);
c->setPeerStorage(peerStorage); c->setPeerStorage(peerStorage);
c->setBtRuntime(btRuntime); c->setBtRuntime(btRuntime);
commands.push_back(c); commands.push_back(std::move(c));
} }
{ {
ActivePeerConnectionCommand* c = auto c = make_unique<ActivePeerConnectionCommand>
new ActivePeerConnectionCommand(e->newCUID(), requestGroup, e, (e->newCUID(), requestGroup, e, metadataGetMode?2:10);
metadataGetMode?2:10);
c->setBtRuntime(btRuntime); c->setBtRuntime(btRuntime);
c->setPieceStorage(pieceStorage); c->setPieceStorage(pieceStorage);
c->setPeerStorage(peerStorage); c->setPeerStorage(peerStorage);
c->setBtAnnounce(btAnnounce); c->setBtAnnounce(btAnnounce);
commands.push_back(c); commands.push_back(std::move(c));
} }
if(metadataGetMode || !torrentAttrs->privateTorrent) { if(metadataGetMode || !torrentAttrs->privateTorrent) {
if(DHTRegistry::isInitialized()) { if(DHTRegistry::isInitialized()) {
DHTGetPeersCommand* command = auto command = make_unique<DHTGetPeersCommand>
new DHTGetPeersCommand(e->newCUID(), requestGroup, e); (e->newCUID(), requestGroup, e);
command->setTaskQueue(DHTRegistry::getData().taskQueue); command->setTaskQueue(DHTRegistry::getData().taskQueue);
command->setTaskFactory(DHTRegistry::getData().taskFactory); command->setTaskFactory(DHTRegistry::getData().taskFactory);
command->setBtRuntime(btRuntime); command->setBtRuntime(btRuntime);
command->setPeerStorage(peerStorage); command->setPeerStorage(peerStorage);
commands.push_back(command); commands.push_back(std::move(command));
} }
if(DHTRegistry::isInitialized6()) { if(DHTRegistry::isInitialized6()) {
DHTGetPeersCommand* command = auto command = make_unique<DHTGetPeersCommand>
new DHTGetPeersCommand(e->newCUID(), requestGroup, e); (e->newCUID(), requestGroup, e);
command->setTaskQueue(DHTRegistry::getData6().taskQueue); command->setTaskQueue(DHTRegistry::getData6().taskQueue);
command->setTaskFactory(DHTRegistry::getData6().taskFactory); command->setTaskFactory(DHTRegistry::getData6().taskFactory);
command->setBtRuntime(btRuntime); command->setBtRuntime(btRuntime);
command->setPeerStorage(peerStorage); command->setPeerStorage(peerStorage);
commands.push_back(command); commands.push_back(std::move(command));
} }
} }
if(!metadataGetMode) { if(!metadataGetMode) {
@ -178,19 +175,19 @@ void BtSetup::setup(std::vector<Command*>& commands,
} }
} }
if(!unionCri->getSeedCriterion().empty()) { if(!unionCri->getSeedCriterion().empty()) {
SeedCheckCommand* c = auto c = make_unique<SeedCheckCommand>
new SeedCheckCommand(e->newCUID(), requestGroup, e, unionCri); (e->newCUID(), requestGroup, e, unionCri);
c->setPieceStorage(pieceStorage); c->setPieceStorage(pieceStorage);
c->setBtRuntime(btRuntime); c->setBtRuntime(btRuntime);
commands.push_back(c); commands.push_back(std::move(c));
} }
} }
if(btReg->getTcpPort() == 0) { if(btReg->getTcpPort() == 0) {
static int families[] = { AF_INET, AF_INET6 }; static int families[] = { AF_INET, AF_INET6 };
size_t familiesLength = e->getOption()->getAsBool(PREF_DISABLE_IPV6)?1:2; size_t familiesLength = e->getOption()->getAsBool(PREF_DISABLE_IPV6)?1:2;
for(size_t i = 0; i < familiesLength; ++i) { for(size_t i = 0; i < familiesLength; ++i) {
PeerListenCommand* command = auto command = make_unique<PeerListenCommand>
new PeerListenCommand(e->newCUID(), e, families[i]); (e->newCUID(), e, families[i]);
bool ret; bool ret;
uint16_t port; uint16_t port;
if(btReg->getTcpPort()) { if(btReg->getTcpPort()) {
@ -207,9 +204,7 @@ void BtSetup::setup(std::vector<Command*>& commands,
if(ret) { if(ret) {
btReg->setTcpPort(port); btReg->setTcpPort(port);
// Add command to DownloadEngine directly. // Add command to DownloadEngine directly.
e->addCommand(command); e->addCommand(std::move(command));
} else {
delete command;
} }
} }
if(btReg->getTcpPort() == 0) { if(btReg->getTcpPort() == 0) {
@ -252,9 +247,8 @@ void BtSetup::setup(std::vector<Command*>& commands,
" localAddr=%s", " localAddr=%s",
LPD_MULTICAST_ADDR, LPD_MULTICAST_PORT, LPD_MULTICAST_ADDR, LPD_MULTICAST_PORT,
receiver->getLocalAddress().c_str())); receiver->getLocalAddress().c_str()));
LpdReceiveMessageCommand* cmd = e->addCommand(make_unique<LpdReceiveMessageCommand>
new LpdReceiveMessageCommand(e->newCUID(), receiver, e); (e->newCUID(), receiver, e));
e->addCommand(cmd);
} else { } else {
A2_LOG_INFO("LpdMessageReceiver not initialized."); A2_LOG_INFO("LpdMessageReceiver not initialized.");
} }
@ -271,10 +265,10 @@ void BtSetup::setup(std::vector<Command*>& commands,
if(dispatcher->init(btReg->getLpdMessageReceiver()->getLocalAddress(), if(dispatcher->init(btReg->getLpdMessageReceiver()->getLocalAddress(),
/*ttl*/1, /*loop*/1)) { /*ttl*/1, /*loop*/1)) {
A2_LOG_INFO("LpdMessageDispatcher initialized."); A2_LOG_INFO("LpdMessageDispatcher initialized.");
LpdDispatchMessageCommand* cmd = auto cmd = make_unique<LpdDispatchMessageCommand>
new LpdDispatchMessageCommand(e->newCUID(), dispatcher, e); (e->newCUID(), dispatcher, e);
cmd->setBtRuntime(btRuntime); cmd->setBtRuntime(btRuntime);
e->addCommand(cmd); e->addCommand(std::move(cmd));
} else { } else {
A2_LOG_INFO("LpdMessageDispatcher not initialized."); A2_LOG_INFO("LpdMessageDispatcher not initialized.");
} }
@ -282,11 +276,11 @@ void BtSetup::setup(std::vector<Command*>& commands,
} }
time_t btStopTimeout = option->getAsInt(PREF_BT_STOP_TIMEOUT); time_t btStopTimeout = option->getAsInt(PREF_BT_STOP_TIMEOUT);
if(btStopTimeout > 0) { if(btStopTimeout > 0) {
BtStopDownloadCommand* stopDownloadCommand = auto stopDownloadCommand = make_unique<BtStopDownloadCommand>
new BtStopDownloadCommand(e->newCUID(), requestGroup, e, btStopTimeout); (e->newCUID(), requestGroup, e, btStopTimeout);
stopDownloadCommand->setBtRuntime(btRuntime); stopDownloadCommand->setBtRuntime(btRuntime);
stopDownloadCommand->setPieceStorage(pieceStorage); stopDownloadCommand->setPieceStorage(pieceStorage);
commands.push_back(stopDownloadCommand); commands.push_back(std::move(stopDownloadCommand));
} }
btRuntime->setReady(true); btRuntime->setReady(true);
} }

View File

@ -36,7 +36,9 @@
#define D_BT_SETUP_H #define D_BT_SETUP_H
#include "common.h" #include "common.h"
#include <vector> #include <vector>
#include <memory>
namespace aria2 { namespace aria2 {
@ -49,7 +51,7 @@ class BtSetup {
public: public:
BtSetup(); BtSetup();
void setup(std::vector<Command*>& commands, void setup(std::vector<std::unique_ptr<Command>>& commands,
RequestGroup* requestGroup, RequestGroup* requestGroup,
DownloadEngine* e, DownloadEngine* e,
const Option* option); const Option* option);

View File

@ -74,25 +74,21 @@ bool CheckIntegrityCommand::executeInternal()
A2_LOG_NOTICE A2_LOG_NOTICE
(fmt(MSG_VERIFICATION_SUCCESSFUL, (fmt(MSG_VERIFICATION_SUCCESSFUL,
getRequestGroup()->getDownloadContext()->getBasePath().c_str())); getRequestGroup()->getDownloadContext()->getBasePath().c_str()));
std::vector<Command*>* commands = new std::vector<Command*>(); std::vector<std::unique_ptr<Command>> commands;
auto_delete_container<std::vector<Command*> > commandsDel(commands); entry_->onDownloadFinished(commands, getDownloadEngine());
entry_->onDownloadFinished(*commands, getDownloadEngine()); getDownloadEngine()->addCommand(std::move(commands));
getDownloadEngine()->addCommand(*commands);
commands->clear();
} else { } else {
A2_LOG_ERROR A2_LOG_ERROR
(fmt(MSG_VERIFICATION_FAILED, (fmt(MSG_VERIFICATION_FAILED,
getRequestGroup()->getDownloadContext()->getBasePath().c_str())); getRequestGroup()->getDownloadContext()->getBasePath().c_str()));
std::vector<Command*>* commands = new std::vector<Command*>(); std::vector<std::unique_ptr<Command>> commands;
auto_delete_container<std::vector<Command*> > commandsDel(commands); entry_->onDownloadIncomplete(commands, getDownloadEngine());
entry_->onDownloadIncomplete(*commands, getDownloadEngine()); getDownloadEngine()->addCommand(std::move(commands));
getDownloadEngine()->addCommand(*commands);
commands->clear();
} }
getDownloadEngine()->setNoWait(true); getDownloadEngine()->setNoWait(true);
return true; return true;
} else { } else {
getDownloadEngine()->addCommand(this); getDownloadEngine()->addCommand(std::unique_ptr<Command>(this));
return false; return false;
} }
} }

View File

@ -52,13 +52,13 @@ CheckIntegrityDispatcherCommand::CheckIntegrityDispatcherCommand
setStatusRealtime(); setStatusRealtime();
} }
Command* CheckIntegrityDispatcherCommand::createCommand std::unique_ptr<Command> CheckIntegrityDispatcherCommand::createCommand
(const std::shared_ptr<CheckIntegrityEntry>& entry) (const std::shared_ptr<CheckIntegrityEntry>& entry)
{ {
cuid_t newCUID = getDownloadEngine()->newCUID(); cuid_t newCUID = getDownloadEngine()->newCUID();
A2_LOG_INFO(fmt("CUID#%" PRId64 " - Dispatching CheckIntegrityCommand CUID#%" PRId64 ".", A2_LOG_INFO(fmt("CUID#%" PRId64 " - Dispatching CheckIntegrityCommand CUID#%" PRId64 ".",
getCuid(), newCUID)); getCuid(), newCUID));
return new CheckIntegrityCommand return make_unique<CheckIntegrityCommand>
(newCUID, entry->getRequestGroup(), getDownloadEngine(), entry); (newCUID, entry->getRequestGroup(), getDownloadEngine(), entry);
} }

View File

@ -50,7 +50,7 @@ public:
const std::shared_ptr<CheckIntegrityMan>& checkMan, const std::shared_ptr<CheckIntegrityMan>& checkMan,
DownloadEngine* e); DownloadEngine* e);
protected: protected:
virtual Command* createCommand virtual std::unique_ptr<Command> createCommand
(const std::shared_ptr<CheckIntegrityEntry>& entry); (const std::shared_ptr<CheckIntegrityEntry>& entry);
}; };

View File

@ -45,8 +45,8 @@
namespace aria2 { namespace aria2 {
CheckIntegrityEntry::CheckIntegrityEntry(RequestGroup* requestGroup, CheckIntegrityEntry::CheckIntegrityEntry(RequestGroup* requestGroup,
Command* nextCommand): std::unique_ptr<Command> nextCommand):
RequestGroupEntry(requestGroup, nextCommand) RequestGroupEntry(requestGroup, std::move(nextCommand))
{} {}
CheckIntegrityEntry::~CheckIntegrityEntry() {} CheckIntegrityEntry::~CheckIntegrityEntry() {}
@ -85,7 +85,7 @@ void CheckIntegrityEntry::cutTrailingGarbage()
} }
void CheckIntegrityEntry::proceedFileAllocation void CheckIntegrityEntry::proceedFileAllocation
(std::vector<Command*>& commands, (std::vector<std::unique_ptr<Command>>& commands,
const std::shared_ptr<FileAllocationEntry>& entry, const std::shared_ptr<FileAllocationEntry>& entry,
DownloadEngine* e) DownloadEngine* e)
{ {

View File

@ -55,11 +55,13 @@ private:
protected: protected:
void setValidator(const std::shared_ptr<IteratableValidator>& validator); void setValidator(const std::shared_ptr<IteratableValidator>& validator);
void proceedFileAllocation(std::vector<Command*>& commands, void proceedFileAllocation(std::vector<std::unique_ptr<Command>>& commands,
const std::shared_ptr<FileAllocationEntry>& entry, const std::shared_ptr<FileAllocationEntry>& entry,
DownloadEngine* e); DownloadEngine* e);
public: public:
CheckIntegrityEntry(RequestGroup* requestGroup, Command* nextCommand = 0); CheckIntegrityEntry(RequestGroup* requestGroup,
std::unique_ptr<Command> nextCommand =
std::unique_ptr<Command>());
virtual ~CheckIntegrityEntry(); virtual ~CheckIntegrityEntry();
@ -75,11 +77,13 @@ public:
virtual void initValidator() = 0; virtual void initValidator() = 0;
virtual void onDownloadFinished(std::vector<Command*>& commands, virtual void onDownloadFinished
DownloadEngine* e) = 0; (std::vector<std::unique_ptr<Command>>& commands,
DownloadEngine* e) = 0;
virtual void onDownloadIncomplete(std::vector<Command*>& commands, virtual void onDownloadIncomplete
DownloadEngine* e) = 0; (std::vector<std::unique_ptr<Command>>& commands,
DownloadEngine* e) = 0;
void cutTrailingGarbage(); void cutTrailingGarbage();
}; };

View File

@ -44,8 +44,9 @@
namespace aria2 { namespace aria2 {
ChecksumCheckIntegrityEntry::ChecksumCheckIntegrityEntry(RequestGroup* requestGroup, Command* nextCommand): ChecksumCheckIntegrityEntry::ChecksumCheckIntegrityEntry
CheckIntegrityEntry(requestGroup, nextCommand), (RequestGroup* requestGroup, std::unique_ptr<Command> nextCommand):
CheckIntegrityEntry(requestGroup, std::move(nextCommand)),
redownload_(false) {} redownload_(false) {}
ChecksumCheckIntegrityEntry::~ChecksumCheckIntegrityEntry() {} ChecksumCheckIntegrityEntry::~ChecksumCheckIntegrityEntry() {}
@ -68,12 +69,12 @@ void ChecksumCheckIntegrityEntry::initValidator()
void void
ChecksumCheckIntegrityEntry::onDownloadFinished ChecksumCheckIntegrityEntry::onDownloadFinished
(std::vector<Command*>& commands, DownloadEngine* e) (std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
{} {}
void void
ChecksumCheckIntegrityEntry::onDownloadIncomplete ChecksumCheckIntegrityEntry::onDownloadIncomplete
(std::vector<Command*>& commands, DownloadEngine* e) (std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
{ {
if(redownload_) { if(redownload_) {
std::shared_ptr<FileAllocationEntry> entry std::shared_ptr<FileAllocationEntry> entry

View File

@ -44,7 +44,9 @@ class ChecksumCheckIntegrityEntry:public CheckIntegrityEntry
private: private:
bool redownload_; bool redownload_;
public: public:
ChecksumCheckIntegrityEntry(RequestGroup* requestGroup, Command* nextCommand = 0); ChecksumCheckIntegrityEntry(RequestGroup* requestGroup,
std::unique_ptr<Command> nextCommand =
std::unique_ptr<Command>());
virtual ~ChecksumCheckIntegrityEntry(); virtual ~ChecksumCheckIntegrityEntry();
@ -52,11 +54,13 @@ public:
virtual void initValidator(); virtual void initValidator();
virtual void onDownloadFinished(std::vector<Command*>& commands, virtual void onDownloadFinished
DownloadEngine* e); (std::vector<std::unique_ptr<Command>>& commands,
DownloadEngine* e);
virtual void onDownloadIncomplete(std::vector<Command*>& commands, virtual void onDownloadIncomplete
DownloadEngine* e); (std::vector<std::unique_ptr<Command>>& commands,
DownloadEngine* e);
void setRedownload(bool redownload) void setRedownload(bool redownload)
{ {

View File

@ -105,16 +105,15 @@ bool CreateRequestCommand::executeInternal()
// counted (1 for pooled and another one in this command) and // counted (1 for pooled and another one in this command) and
// AbstractCommand::execute() will behave badly. // AbstractCommand::execute() will behave badly.
resetRequest(); resetRequest();
getDownloadEngine()->addCommand(this); addCommandSelf();
return false; return false;
} }
Command* command =
InitiateConnectionCommandFactory::createInitiateConnectionCommand
(getCuid(), getRequest(), getFileEntry(), getRequestGroup(),
getDownloadEngine());
getDownloadEngine()->setNoWait(true); getDownloadEngine()->setNoWait(true);
getDownloadEngine()->addCommand(command); getDownloadEngine()->addCommand
(InitiateConnectionCommandFactory::createInitiateConnectionCommand
(getCuid(), getRequest(), getFileEntry(), getRequestGroup(),
getDownloadEngine()));
return true; return true;
} }

View File

@ -99,7 +99,7 @@ bool DHTEntryPointNameResolveCommand::execute()
std::vector<std::string> res; std::vector<std::string> res;
int rv = resolveHostname(res, hostname); int rv = resolveHostname(res, hostname);
if(rv == 0) { if(rv == 0) {
e_->addCommand(this); e_->addCommand(std::unique_ptr<Command>(this));
return false; return false;
} else { } else {
if(rv == 1) { if(rv == 1) {

View File

@ -126,7 +126,7 @@ bool DHTGetPeersCommand::execute()
task_.reset(); task_.reset();
} }
e_->addCommand(this); e_->addCommand(std::unique_ptr<Command>(this));
return false; return false;
} }

View File

@ -138,7 +138,7 @@ bool DHTInteractionCommand::execute()
udpTrackerClient_->requestFail(UDPT_ERR_NETWORK); udpTrackerClient_->requestFail(UDPT_ERR_NETWORK);
} }
} }
e_->addCommand(this); e_->addCommand(std::unique_ptr<Command>(this));
return false; return false;
} }

View File

@ -78,21 +78,17 @@ DHTSetup::DHTSetup() {}
DHTSetup::~DHTSetup() {} DHTSetup::~DHTSetup() {}
void DHTSetup::setup std::vector<std::unique_ptr<Command>> DHTSetup::setup
(std::vector<Command*>& commands, DownloadEngine* e, int family) (DownloadEngine* e, int family)
{ {
if(family != AF_INET && family != AF_INET6) { std::vector<std::unique_ptr<Command> > tempCommands;
return; if((family != AF_INET && family != AF_INET6) ||
} (family == AF_INET && DHTRegistry::isInitialized()) ||
if((family == AF_INET && DHTRegistry::isInitialized()) ||
(family == AF_INET6 && DHTRegistry::isInitialized6())) { (family == AF_INET6 && DHTRegistry::isInitialized6())) {
return; return tempCommands;
} }
try { try {
std::vector<Command*>* tempCommands = new std::vector<Command*>();
auto_delete_container<std::vector<Command*> > commandsDel(tempCommands);
// load routing table and localnode id here // load routing table and localnode id here
std::shared_ptr<DHTNode> localNode; std::shared_ptr<DHTNode> localNode;
DHTRoutingTableDeserializer deserializer(family); DHTRoutingTableDeserializer deserializer(family);
@ -240,65 +236,60 @@ void DHTSetup::setup
e->getOption()->getAsInt(prefEntryPointPort)); e->getOption()->getAsInt(prefEntryPointPort));
std::vector<std::pair<std::string, uint16_t> > entryPoints; std::vector<std::pair<std::string, uint16_t> > entryPoints;
entryPoints.push_back(addr); entryPoints.push_back(addr);
DHTEntryPointNameResolveCommand* command = auto command = make_unique<DHTEntryPointNameResolveCommand>
new DHTEntryPointNameResolveCommand(e->newCUID(), e, entryPoints); (e->newCUID(), e, entryPoints);
command->setBootstrapEnabled(true); command->setBootstrapEnabled(true);
command->setTaskQueue(taskQueue); command->setTaskQueue(taskQueue);
command->setTaskFactory(taskFactory); command->setTaskFactory(taskFactory);
command->setRoutingTable(routingTable); command->setRoutingTable(routingTable);
command->setLocalNode(localNode); command->setLocalNode(localNode);
tempCommands->push_back(command); tempCommands.push_back(std::move(command));
} }
} else { } else {
A2_LOG_INFO("No DHT entry point specified."); A2_LOG_INFO("No DHT entry point specified.");
} }
{ {
DHTInteractionCommand* command = auto command = make_unique<DHTInteractionCommand>(e->newCUID(), e);
new DHTInteractionCommand(e->newCUID(), e);
command->setMessageDispatcher(dispatcher); command->setMessageDispatcher(dispatcher);
command->setMessageReceiver(receiver); command->setMessageReceiver(receiver);
command->setTaskQueue(taskQueue); command->setTaskQueue(taskQueue);
command->setReadCheckSocket(connection->getSocket()); command->setReadCheckSocket(connection->getSocket());
command->setConnection(connection); command->setConnection(connection);
command->setUDPTrackerClient(udpTrackerClient); command->setUDPTrackerClient(udpTrackerClient);
tempCommands->push_back(command); tempCommands.push_back(std::move(command));
} }
{ {
DHTTokenUpdateCommand* command = auto command = make_unique<DHTTokenUpdateCommand>
new DHTTokenUpdateCommand(e->newCUID(), e, DHT_TOKEN_UPDATE_INTERVAL); (e->newCUID(), e, DHT_TOKEN_UPDATE_INTERVAL);
command->setTokenTracker(tokenTracker); command->setTokenTracker(tokenTracker);
tempCommands->push_back(command); tempCommands.push_back(std::move(command));
} }
{ {
DHTBucketRefreshCommand* command = auto command = make_unique<DHTBucketRefreshCommand>
new DHTBucketRefreshCommand(e->newCUID(), e, (e->newCUID(), e, DHT_BUCKET_REFRESH_CHECK_INTERVAL);
DHT_BUCKET_REFRESH_CHECK_INTERVAL);
command->setTaskQueue(taskQueue); command->setTaskQueue(taskQueue);
command->setRoutingTable(routingTable); command->setRoutingTable(routingTable);
command->setTaskFactory(taskFactory); command->setTaskFactory(taskFactory);
tempCommands->push_back(command); tempCommands.push_back(std::move(command));
} }
{ {
DHTPeerAnnounceCommand* command = auto command = make_unique<DHTPeerAnnounceCommand>
new DHTPeerAnnounceCommand(e->newCUID(), e, (e->newCUID(), e, DHT_PEER_ANNOUNCE_CHECK_INTERVAL);
DHT_PEER_ANNOUNCE_CHECK_INTERVAL);
command->setPeerAnnounceStorage(peerAnnounceStorage); command->setPeerAnnounceStorage(peerAnnounceStorage);
tempCommands->push_back(command); tempCommands.push_back(std::move(command));
} }
{ {
DHTAutoSaveCommand* command = auto command = make_unique<DHTAutoSaveCommand>
new DHTAutoSaveCommand(e->newCUID(), e, family, 30*60); (e->newCUID(), e, family, 30*60);
command->setLocalNode(localNode); command->setLocalNode(localNode);
command->setRoutingTable(routingTable); command->setRoutingTable(routingTable);
tempCommands->push_back(command); tempCommands.push_back(std::move(command));
} }
if(family == AF_INET) { if(family == AF_INET) {
DHTRegistry::setInitialized(true); DHTRegistry::setInitialized(true);
} else { } else {
DHTRegistry::setInitialized6(true); DHTRegistry::setInitialized6(true);
} }
commands.insert(commands.end(), tempCommands->begin(), tempCommands->end());
tempCommands->clear();
if(e->getBtRegistry()->getUdpPort() == 0) { if(e->getBtRegistry()->getUdpPort() == 0) {
// We assign port last so that no exception gets in the way // We assign port last so that no exception gets in the way
e->getBtRegistry()->setUdpPort(port); e->getBtRegistry()->setUdpPort(port);
@ -307,6 +298,7 @@ void DHTSetup::setup
A2_LOG_ERROR_EX(fmt("Exception caught while initializing DHT functionality." A2_LOG_ERROR_EX(fmt("Exception caught while initializing DHT functionality."
" DHT is disabled."), " DHT is disabled."),
ex); ex);
tempCommands.clear();
if(family == AF_INET) { if(family == AF_INET) {
DHTRegistry::clearData(); DHTRegistry::clearData();
e->getBtRegistry()->setUDPTrackerClient e->getBtRegistry()->setUDPTrackerClient
@ -315,6 +307,7 @@ void DHTSetup::setup
DHTRegistry::clearData6(); DHTRegistry::clearData6();
} }
} }
return tempCommands;
} }
} // namespace aria2 } // namespace aria2

View File

@ -36,7 +36,9 @@
#define D_DHT_SETUP_H #define D_DHT_SETUP_H
#include "common.h" #include "common.h"
#include <vector> #include <vector>
#include <memory>
namespace aria2 { namespace aria2 {
@ -49,7 +51,7 @@ public:
~DHTSetup(); ~DHTSetup();
void setup(std::vector<Command*>& commands, DownloadEngine* e, int family); std::vector<std::unique_ptr<Command>> setup(DownloadEngine* e, int family);
}; };
} // namespace aria2 } // namespace aria2

View File

@ -143,7 +143,7 @@ void flushWrDiskCacheEntry(WrDiskCache* wrDiskCache,
bool DownloadCommand::executeInternal() { bool DownloadCommand::executeInternal() {
if(getDownloadEngine()->getRequestGroupMan()->doesOverallDownloadSpeedExceed() if(getDownloadEngine()->getRequestGroupMan()->doesOverallDownloadSpeedExceed()
|| getRequestGroup()->doesDownloadSpeedExceed()) { || getRequestGroup()->doesDownloadSpeedExceed()) {
getDownloadEngine()->addCommand(this); addCommandSelf();
disableReadCheckSocket(); disableReadCheckSocket();
return false; return false;
} }
@ -293,7 +293,7 @@ bool DownloadCommand::executeInternal() {
checkLowestDownloadSpeed(); checkLowestDownloadSpeed();
setWriteCheckSocketIf(getSocket(), getSocket()->wantWrite()); setWriteCheckSocketIf(getSocket(), getSocket()->wantWrite());
checkSocketRecvBuffer(); checkSocketRecvBuffer();
getDownloadEngine()->addCommand(this); addCommandSelf();
return false; return false;
} }
} }
@ -368,7 +368,7 @@ bool DownloadCommand::prepareForNextSegment() {
return prepareForRetry(0); return prepareForRetry(0);
} else { } else {
checkSocketRecvBuffer(); checkSocketRecvBuffer();
getDownloadEngine()->addCommand(this); addCommandSelf();
return false; return false;
} }
} else { } else {

View File

@ -40,6 +40,7 @@
#include <cerrno> #include <cerrno>
#include <algorithm> #include <algorithm>
#include <numeric> #include <numeric>
#include <iterator>
#include "StatCalc.h" #include "StatCalc.h"
#include "RequestGroup.h" #include "RequestGroup.h"
@ -107,40 +108,32 @@ DownloadEngine::DownloadEngine(const std::shared_ptr<EventPoll>& eventPoll)
sessionId_.assign(&sessionId[0], & sessionId[sizeof(sessionId)]); sessionId_.assign(&sessionId[0], & sessionId[sizeof(sessionId)]);
} }
namespace { DownloadEngine::~DownloadEngine()
void cleanQueue(std::deque<Command*>& commands) { {
std::for_each(commands.begin(), commands.end(), Deleter());
commands.clear();
}
} // namespace
DownloadEngine::~DownloadEngine() {
cleanQueue(commands_);
cleanQueue(routineCommands_);
#ifdef HAVE_ARES_ADDR_NODE #ifdef HAVE_ARES_ADDR_NODE
setAsyncDNSServers(0); setAsyncDNSServers(0);
#endif // HAVE_ARES_ADDR_NODE #endif // HAVE_ARES_ADDR_NODE
} }
namespace { namespace {
void executeCommand(std::deque<Command*>& commands, void executeCommand(std::deque<std::unique_ptr<Command>>& commands,
Command::STATUS statusFilter) Command::STATUS statusFilter)
{ {
size_t max = commands.size(); size_t max = commands.size();
for(size_t i = 0; i < max; ++i) { for(size_t i = 0; i < max; ++i) {
Command* com = commands.front(); std::unique_ptr<Command> com = std::move(commands.front());
commands.pop_front(); commands.pop_front();
if(com->statusMatch(statusFilter)) { if(com->statusMatch(statusFilter)) {
com->transitStatus(); com->transitStatus();
if(com->execute()) { if(com->execute()) {
delete com; com.reset();
com = 0; } else {
com->clearIOEvents();
com.release();
} }
} else { } else {
commands.push_back(com);
}
if(com) {
com->clearIOEvents(); com->clearIOEvents();
commands.push_back(std::move(com));
} }
} }
} }
@ -282,9 +275,9 @@ void DownloadEngine::setNoWait(bool b)
noWait_ = b; noWait_ = b;
} }
void DownloadEngine::addRoutineCommand(Command* command) void DownloadEngine::addRoutineCommand(std::unique_ptr<Command> command)
{ {
routineCommands_.push_back(command); routineCommands_.push_back(std::move(command));
} }
void DownloadEngine::poolSocket(const std::string& key, void DownloadEngine::poolSocket(const std::string& key,
@ -561,14 +554,17 @@ void DownloadEngine::setRefreshInterval(int64_t interval)
refreshInterval_ = std::min(static_cast<int64_t>(999), interval); refreshInterval_ = std::min(static_cast<int64_t>(999), interval);
} }
void DownloadEngine::addCommand(const std::vector<Command*>& commands) void DownloadEngine::addCommand
(std::vector<std::unique_ptr<Command>> commands)
{ {
commands_.insert(commands_.end(), commands.begin(), commands.end()); commands_.insert(commands_.end(),
std::make_move_iterator(std::begin(commands)),
std::make_move_iterator(std::end(commands)));
} }
void DownloadEngine::addCommand(Command* command) void DownloadEngine::addCommand(std::unique_ptr<Command> command)
{ {
commands_.push_back(command); commands_.push_back(std::move(command));
} }
void DownloadEngine::setRequestGroupMan void DownloadEngine::setRequestGroupMan

View File

@ -131,7 +131,7 @@ private:
int64_t refreshInterval_; int64_t refreshInterval_;
Timer lastRefresh_; Timer lastRefresh_;
std::deque<Command*> routineCommands_; std::deque<std::unique_ptr<Command>> routineCommands_;
std::shared_ptr<CookieStorage> cookieStorage_; std::shared_ptr<CookieStorage> cookieStorage_;
@ -167,7 +167,7 @@ private:
std::multimap<std::string, SocketPoolEntry>::iterator std::multimap<std::string, SocketPoolEntry>::iterator
findSocketPoolEntry(const std::string& key); findSocketPoolEntry(const std::string& key);
std::deque<Command*> commands_; std::deque<std::unique_ptr<Command>> commands_;
std::shared_ptr<RequestGroupMan> requestGroupMan_; std::shared_ptr<RequestGroupMan> requestGroupMan_;
std::shared_ptr<FileAllocationMan> fileAllocationMan_; std::shared_ptr<FileAllocationMan> fileAllocationMan_;
std::shared_ptr<CheckIntegrityMan> checkIntegrityMan_; std::shared_ptr<CheckIntegrityMan> checkIntegrityMan_;
@ -200,9 +200,9 @@ public:
Command* command); Command* command);
#endif // ENABLE_ASYNC_DNS #endif // ENABLE_ASYNC_DNS
void addCommand(const std::vector<Command*>& commands); void addCommand(std::vector<std::unique_ptr<Command>> commands);
void addCommand(Command* command); void addCommand(std::unique_ptr<Command> command);
const std::shared_ptr<RequestGroupMan>& getRequestGroupMan() const const std::shared_ptr<RequestGroupMan>& getRequestGroupMan() const
{ {
@ -253,7 +253,7 @@ public:
void setNoWait(bool b); void setNoWait(bool b);
void addRoutineCommand(Command* command); void addRoutineCommand(std::unique_ptr<Command> command);
void poolSocket(const std::string& ipaddr, uint16_t port, void poolSocket(const std::string& ipaddr, uint16_t port,
const std::string& username, const std::string& username,

View File

@ -159,35 +159,38 @@ DownloadEngineFactory::newDownloadEngine
e->setCheckIntegrityMan e->setCheckIntegrityMan
(std::shared_ptr<CheckIntegrityMan>(new CheckIntegrityMan())); (std::shared_ptr<CheckIntegrityMan>(new CheckIntegrityMan()));
#endif // ENABLE_MESSAGE_DIGEST #endif // ENABLE_MESSAGE_DIGEST
e->addRoutineCommand(new FillRequestGroupCommand(e->newCUID(), e.get())); e->addRoutineCommand(make_unique<FillRequestGroupCommand>
e->addRoutineCommand(new FileAllocationDispatcherCommand (e->newCUID(), e.get()));
e->addRoutineCommand(make_unique<FileAllocationDispatcherCommand>
(e->newCUID(), e->getFileAllocationMan(), e.get())); (e->newCUID(), e->getFileAllocationMan(), e.get()));
#ifdef ENABLE_MESSAGE_DIGEST #ifdef ENABLE_MESSAGE_DIGEST
e->addRoutineCommand(new CheckIntegrityDispatcherCommand e->addRoutineCommand(make_unique<CheckIntegrityDispatcherCommand>
(e->newCUID(), e->getCheckIntegrityMan(), e.get())); (e->newCUID(), e->getCheckIntegrityMan(), e.get()));
#endif // ENABLE_MESSAGE_DIGEST #endif // ENABLE_MESSAGE_DIGEST
if(op->getAsInt(PREF_AUTO_SAVE_INTERVAL) > 0) { if(op->getAsInt(PREF_AUTO_SAVE_INTERVAL) > 0) {
e->addRoutineCommand e->addRoutineCommand
(new AutoSaveCommand(e->newCUID(), e.get(), (make_unique<AutoSaveCommand>(e->newCUID(), e.get(),
op->getAsInt(PREF_AUTO_SAVE_INTERVAL))); op->getAsInt(PREF_AUTO_SAVE_INTERVAL)));
} }
if(op->getAsInt(PREF_SAVE_SESSION_INTERVAL) > 0) { if(op->getAsInt(PREF_SAVE_SESSION_INTERVAL) > 0) {
e->addRoutineCommand e->addRoutineCommand(make_unique<SaveSessionCommand>
(new SaveSessionCommand(e->newCUID(), e.get(), (e->newCUID(), e.get(),
op->getAsInt(PREF_SAVE_SESSION_INTERVAL))); op->getAsInt(PREF_SAVE_SESSION_INTERVAL)));
} }
e->addRoutineCommand(new HaveEraseCommand(e->newCUID(), e.get(), 10)); e->addRoutineCommand(make_unique<HaveEraseCommand>
(e->newCUID(), e.get(), 10));
{ {
time_t stopSec = op->getAsInt(PREF_STOP); time_t stopSec = op->getAsInt(PREF_STOP);
if(stopSec > 0) { if(stopSec > 0) {
e->addRoutineCommand(new TimedHaltCommand(e->newCUID(), e.get(), e->addRoutineCommand(make_unique<TimedHaltCommand>(e->newCUID(), e.get(),
stopSec)); stopSec));
} }
} }
if(op->defined(PREF_STOP_WITH_PROCESS)) { if(op->defined(PREF_STOP_WITH_PROCESS)) {
unsigned int pid = op->getAsInt(PREF_STOP_WITH_PROCESS); unsigned int pid = op->getAsInt(PREF_STOP_WITH_PROCESS);
e->addRoutineCommand(new WatchProcessCommand(e->newCUID(), e.get(), pid)); e->addRoutineCommand(make_unique<WatchProcessCommand>(e->newCUID(),
e.get(), pid));
} }
if(op->getAsBool(PREF_ENABLE_RPC)) { if(op->getAsBool(PREF_ENABLE_RPC)) {
bool ok = false; bool ok = false;
@ -198,13 +201,11 @@ DownloadEngineFactory::newDownloadEngine
static int families[] = { AF_INET, AF_INET6 }; static int families[] = { AF_INET, AF_INET6 };
size_t familiesLength = op->getAsBool(PREF_DISABLE_IPV6)?1:2; size_t familiesLength = op->getAsBool(PREF_DISABLE_IPV6)?1:2;
for(size_t i = 0; i < familiesLength; ++i) { for(size_t i = 0; i < familiesLength; ++i) {
HttpListenCommand* httpListenCommand = auto httpListenCommand = make_unique<HttpListenCommand>
new HttpListenCommand(e->newCUID(), e.get(), families[i], secure); (e->newCUID(), e.get(), families[i], secure);
if(httpListenCommand->bindPort(op->getAsInt(PREF_RPC_LISTEN_PORT))){ if(httpListenCommand->bindPort(op->getAsInt(PREF_RPC_LISTEN_PORT))){
e->addCommand(httpListenCommand); e->addCommand(std::move(httpListenCommand));
ok = true; ok = true;
} else {
delete httpListenCommand;
} }
} }
if(!ok) { if(!ok) {

View File

@ -74,15 +74,13 @@ bool FileAllocationCommand::executeInternal()
getRequestGroup()->getTotalLength())); getRequestGroup()->getTotalLength()));
getDownloadEngine()->getFileAllocationMan()->dropPickedEntry(); getDownloadEngine()->getFileAllocationMan()->dropPickedEntry();
std::vector<Command*>* commands = new std::vector<Command*>(); std::vector<std::unique_ptr<Command>> commands;
auto_delete_container<std::vector<Command*> > commandsDel(commands); fileAllocationEntry_->prepareForNextAction(commands, getDownloadEngine());
fileAllocationEntry_->prepareForNextAction(*commands, getDownloadEngine()); getDownloadEngine()->addCommand(std::move(commands));
getDownloadEngine()->addCommand(*commands);
commands->clear();
getDownloadEngine()->setNoWait(true); getDownloadEngine()->setNoWait(true);
return true; return true;
} else { } else {
getDownloadEngine()->addCommand(this); getDownloadEngine()->addCommand(std::unique_ptr<Command>(this));
return false; return false;
} }
} }

View File

@ -50,15 +50,13 @@ FileAllocationDispatcherCommand::FileAllocationDispatcherCommand
: SequentialDispatcherCommand<FileAllocationEntry>(cuid, fileAllocMan, e) : SequentialDispatcherCommand<FileAllocationEntry>(cuid, fileAllocMan, e)
{} {}
Command* FileAllocationDispatcherCommand::createCommand std::unique_ptr<Command> FileAllocationDispatcherCommand::createCommand
(const std::shared_ptr<FileAllocationEntry>& entry) (const std::shared_ptr<FileAllocationEntry>& entry)
{ {
cuid_t newCUID = getDownloadEngine()->newCUID(); cuid_t newCUID = getDownloadEngine()->newCUID();
A2_LOG_INFO(fmt(MSG_FILE_ALLOCATION_DISPATCH, newCUID)); A2_LOG_INFO(fmt(MSG_FILE_ALLOCATION_DISPATCH, newCUID));
FileAllocationCommand* command = return make_unique<FileAllocationCommand>
new FileAllocationCommand(newCUID, entry->getRequestGroup(), (newCUID, entry->getRequestGroup(), getDownloadEngine(), entry);
getDownloadEngine(), entry);
return command;
} }
} // namespace aria2 } // namespace aria2

View File

@ -50,7 +50,7 @@ public:
const std::shared_ptr<FileAllocationMan>& fileAllocMan, const std::shared_ptr<FileAllocationMan>& fileAllocMan,
DownloadEngine* e); DownloadEngine* e);
protected: protected:
virtual Command* createCommand virtual std::unique_ptr<Command> createCommand
(const std::shared_ptr<FileAllocationEntry>& entry); (const std::shared_ptr<FileAllocationEntry>& entry);
}; };

View File

@ -41,8 +41,9 @@
namespace aria2 { namespace aria2 {
FileAllocationEntry::FileAllocationEntry(RequestGroup* requestGroup, Command* nextCommand): FileAllocationEntry::FileAllocationEntry(RequestGroup* requestGroup,
RequestGroupEntry(requestGroup, nextCommand), std::unique_ptr<Command> nextCommand):
RequestGroupEntry(requestGroup, std::move(nextCommand)),
fileAllocationIterator_(requestGroup->getPieceStorage()->getDiskAdaptor()->fileAllocationIterator()) fileAllocationIterator_(requestGroup->getPieceStorage()->getDiskAdaptor()->fileAllocationIterator())
{} {}

View File

@ -52,7 +52,9 @@ class FileAllocationEntry : public RequestGroupEntry, public ProgressAwareEntry
private: private:
std::shared_ptr<FileAllocationIterator> fileAllocationIterator_; std::shared_ptr<FileAllocationIterator> fileAllocationIterator_;
public: public:
FileAllocationEntry(RequestGroup* requestGroup, Command* nextCommand = 0); FileAllocationEntry(RequestGroup* requestGroup,
std::unique_ptr<Command> nextCommand =
std::unique_ptr<Command>());
~FileAllocationEntry(); ~FileAllocationEntry();
@ -64,8 +66,9 @@ public:
void allocateChunk(); void allocateChunk();
virtual void prepareForNextAction(std::vector<Command*>& commands, virtual void prepareForNextAction
DownloadEngine* e) = 0; (std::vector<std::unique_ptr<Command>>& commands,
DownloadEngine* e) = 0;
}; };
} // namespace aria2 } // namespace aria2

View File

@ -80,7 +80,7 @@ bool FillRequestGroupCommand::execute()
return true; return true;
} }
} }
e_->addRoutineCommand(this); e_->addRoutineCommand(std::unique_ptr<Command>(this));
return false; return false;
} }

View File

@ -70,10 +70,10 @@ bool FtpDownloadCommand::prepareForNextSegment()
if(getOption()->getAsBool(PREF_FTP_REUSE_CONNECTION) && if(getOption()->getAsBool(PREF_FTP_REUSE_CONNECTION) &&
getFileEntry()->gtoloff(getSegments().front()->getPositionToWrite()) == getFileEntry()->gtoloff(getSegments().front()->getPositionToWrite()) ==
getFileEntry()->getLength()) { getFileEntry()->getLength()) {
Command* command = new FtpFinishDownloadCommand getDownloadEngine()->addCommand
(getCuid(), getRequest(), getFileEntry(), getRequestGroup(), (make_unique<FtpFinishDownloadCommand>
ftpConnection_, getDownloadEngine(), ctrlSocket_); (getCuid(), getRequest(), getFileEntry(), getRequestGroup(),
getDownloadEngine()->addCommand(command); ftpConnection_, getDownloadEngine(), ctrlSocket_));
if(getRequestGroup()->downloadFinished()) { if(getRequestGroup()->downloadFinished()) {
// To run checksum checking, we had to call following function here. // To run checksum checking, we had to call following function here.

View File

@ -80,7 +80,7 @@ bool FtpFinishDownloadCommand::execute()
getCheckPoint() = global::wallclock(); getCheckPoint() = global::wallclock();
int status = ftpConnection_->receiveResponse(); int status = ftpConnection_->receiveResponse();
if(status == 0) { if(status == 0) {
getDownloadEngine()->addCommand(this); addCommandSelf();
return false; return false;
} }
if(status == 226) { if(status == 226) {
@ -97,7 +97,7 @@ bool FtpFinishDownloadCommand::execute()
A2_LOG_INFO(fmt("CUID#%" PRId64 " - Timeout before receiving transfer complete.", A2_LOG_INFO(fmt("CUID#%" PRId64 " - Timeout before receiving transfer complete.",
getCuid())); getCuid()));
} else { } else {
getDownloadEngine()->addCommand(this); addCommandSelf();
return false; return false;
} }
} catch(RecoverableException& e) { } catch(RecoverableException& e) {

View File

@ -73,12 +73,11 @@ FtpInitiateConnectionCommand::FtpInitiateConnectionCommand
FtpInitiateConnectionCommand::~FtpInitiateConnectionCommand() {} FtpInitiateConnectionCommand::~FtpInitiateConnectionCommand() {}
Command* FtpInitiateConnectionCommand::createNextCommand std::unique_ptr<Command> FtpInitiateConnectionCommand::createNextCommand
(const std::string& hostname, const std::string& addr, uint16_t port, (const std::string& hostname, const std::string& addr, uint16_t port,
const std::vector<std::string>& resolvedAddresses, const std::vector<std::string>& resolvedAddresses,
const std::shared_ptr<Request>& proxyRequest) const std::shared_ptr<Request>& proxyRequest)
{ {
Command* command;
if(proxyRequest) { if(proxyRequest) {
std::string options; std::string options;
std::shared_ptr<SocketCore> pooledSocket; std::shared_ptr<SocketCore> pooledSocket;
@ -102,13 +101,13 @@ Command* FtpInitiateConnectionCommand::createNextCommand
getRequest()->setConnectedAddrInfo(hostname, addr, port); getRequest()->setConnectedAddrInfo(hostname, addr, port);
ConnectCommand* c = new ConnectCommand(getCuid(), auto c = make_unique<ConnectCommand>(getCuid(),
getRequest(), getRequest(),
proxyRequest, proxyRequest,
getFileEntry(), getFileEntry(),
getRequestGroup(), getRequestGroup(),
getDownloadEngine(), getDownloadEngine(),
getSocket()); getSocket());
if(proxyMethod == V_GET) { if(proxyMethod == V_GET) {
// Use GET for FTP via HTTP proxy. // Use GET for FTP via HTTP proxy.
getRequest()->setMethod(Request::METHOD_GET); getRequest()->setMethod(Request::METHOD_GET);
@ -123,13 +122,13 @@ Command* FtpInitiateConnectionCommand::createNextCommand
// Unreachable // Unreachable
assert(0); assert(0);
} }
setupBackupConnection(hostname, addr, port, c); setupBackupConnection(hostname, addr, port, c.get());
command = c; return std::move(c);
} else { } else {
setConnectedAddrInfo(getRequest(), hostname, pooledSocket); setConnectedAddrInfo(getRequest(), hostname, pooledSocket);
if(proxyMethod == V_TUNNEL) { if(proxyMethod == V_TUNNEL) {
// options contains "baseWorkingDir" // options contains "baseWorkingDir"
command = new FtpNegotiationCommand return make_unique<FtpNegotiationCommand>
(getCuid(), (getCuid(),
getRequest(), getRequest(),
getFileEntry(), getFileEntry(),
@ -146,15 +145,15 @@ Command* FtpInitiateConnectionCommand::createNextCommand
std::shared_ptr<HttpConnection> hc std::shared_ptr<HttpConnection> hc
(new HttpConnection(getCuid(), pooledSocket, socketRecvBuffer)); (new HttpConnection(getCuid(), pooledSocket, socketRecvBuffer));
HttpRequestCommand* c = new HttpRequestCommand(getCuid(), auto c = make_unique<HttpRequestCommand>(getCuid(),
getRequest(), getRequest(),
getFileEntry(), getFileEntry(),
getRequestGroup(), getRequestGroup(),
hc, hc,
getDownloadEngine(), getDownloadEngine(),
pooledSocket); pooledSocket);
c->setProxyRequest(proxyRequest); c->setProxyRequest(proxyRequest);
command = c; return std::move(c);
} else { } else {
// Unreachable // Unreachable
assert(0); assert(0);
@ -174,21 +173,21 @@ Command* FtpInitiateConnectionCommand::createNextCommand
createSocket(); createSocket();
getSocket()->establishConnection(addr, port); getSocket()->establishConnection(addr, port);
getRequest()->setConnectedAddrInfo(hostname, addr, port); getRequest()->setConnectedAddrInfo(hostname, addr, port);
ConnectCommand* c = new ConnectCommand(getCuid(), auto c = make_unique<ConnectCommand>(getCuid(),
getRequest(), getRequest(),
proxyRequest, // must be null proxyRequest, // must be null
getFileEntry(), getFileEntry(),
getRequestGroup(), getRequestGroup(),
getDownloadEngine(), getDownloadEngine(),
getSocket()); getSocket());
std::shared_ptr<FtpNegotiationConnectChain> chain std::shared_ptr<FtpNegotiationConnectChain> chain
(new FtpNegotiationConnectChain()); (new FtpNegotiationConnectChain());
c->setControlChain(chain); c->setControlChain(chain);
setupBackupConnection(hostname, addr, port, c); setupBackupConnection(hostname, addr, port, c.get());
command = c; return std::move(c);
} else { } else {
// options contains "baseWorkingDir" // options contains "baseWorkingDir"
command = new FtpNegotiationCommand auto command = make_unique<FtpNegotiationCommand>
(getCuid(), (getCuid(),
getRequest(), getRequest(),
getFileEntry(), getFileEntry(),
@ -198,9 +197,9 @@ Command* FtpInitiateConnectionCommand::createNextCommand
FtpNegotiationCommand::SEQ_SEND_CWD_PREP, FtpNegotiationCommand::SEQ_SEND_CWD_PREP,
options); options);
setConnectedAddrInfo(getRequest(), hostname, pooledSocket); setConnectedAddrInfo(getRequest(), hostname, pooledSocket);
return std::move(command);
} }
} }
return command;
} }
} // namespace aria2 } // namespace aria2

View File

@ -41,7 +41,7 @@ namespace aria2 {
class FtpInitiateConnectionCommand : public InitiateConnectionCommand { class FtpInitiateConnectionCommand : public InitiateConnectionCommand {
protected: protected:
virtual Command* createNextCommand virtual std::unique_ptr<Command> createNextCommand
(const std::string& hostname, const std::string& addr, uint16_t port, (const std::string& hostname, const std::string& addr, uint16_t port,
const std::vector<std::string>& resolvedAddresses, const std::vector<std::string>& resolvedAddresses,
const std::shared_ptr<Request>& proxyRequest); const std::shared_ptr<Request>& proxyRequest);

View File

@ -110,8 +110,7 @@ bool FtpNegotiationCommand::executeInternal() {
if(sequence_ == SEQ_RETRY) { if(sequence_ == SEQ_RETRY) {
return prepareForRetry(0); return prepareForRetry(0);
} else if(sequence_ == SEQ_NEGOTIATION_COMPLETED) { } else if(sequence_ == SEQ_NEGOTIATION_COMPLETED) {
FtpDownloadCommand* command = auto command = make_unique<FtpDownloadCommand>
new FtpDownloadCommand
(getCuid(), getRequest(), getFileEntry(), getRequestGroup(), ftp_, (getCuid(), getRequest(), getFileEntry(), getRequestGroup(), ftp_,
getDownloadEngine(), dataSocket_, getSocket()); getDownloadEngine(), dataSocket_, getSocket());
command->setStartupIdleTime(getOption()->getAsInt(PREF_STARTUP_IDLE_TIME)); command->setStartupIdleTime(getOption()->getAsInt(PREF_STARTUP_IDLE_TIME));
@ -121,8 +120,8 @@ bool FtpNegotiationCommand::executeInternal() {
getFileEntry()->removeURIWhoseHostnameIs(getRequest()->getHost()); getFileEntry()->removeURIWhoseHostnameIs(getRequest()->getHost());
} }
getRequestGroup()->getURISelector()->tuneDownloadCommand getRequestGroup()->getURISelector()->tuneDownloadCommand
(getFileEntry()->getRemainingUris(), command); (getFileEntry()->getRemainingUris(), command.get());
getDownloadEngine()->addCommand(command); getDownloadEngine()->addCommand(std::move(command));
return true; return true;
} else if(sequence_ == SEQ_HEAD_OK || } else if(sequence_ == SEQ_HEAD_OK ||
sequence_ == SEQ_DOWNLOAD_ALREADY_COMPLETED) { sequence_ == SEQ_DOWNLOAD_ALREADY_COMPLETED) {
@ -137,7 +136,7 @@ bool FtpNegotiationCommand::executeInternal() {
} else if(sequence_ == SEQ_EXIT) { } else if(sequence_ == SEQ_EXIT) {
return true; return true;
} else { } else {
getDownloadEngine()->addCommand(this); addCommandSelf();
return false; return false;
} }
} }
@ -473,7 +472,7 @@ bool FtpNegotiationCommand::onFileSizeDetermined(int64_t totalLength)
poolConnection(); poolConnection();
return false; return false;
} }
checkIntegrityEntry->pushNextCommand(this); checkIntegrityEntry->pushNextCommand(std::unique_ptr<Command>(this));
// We have to make sure that command that has Request object must // We have to make sure that command that has Request object must
// have segment after PieceStorage is initialized. See // have segment after PieceStorage is initialized. See
// AbstractCommand::execute() // AbstractCommand::execute()

View File

@ -47,7 +47,7 @@ struct FtpNegotiationConnectChain : public ControlChain<ConnectCommand*> {
virtual ~FtpNegotiationConnectChain() {} virtual ~FtpNegotiationConnectChain() {}
virtual int run(ConnectCommand* t, DownloadEngine* e) virtual int run(ConnectCommand* t, DownloadEngine* e)
{ {
FtpNegotiationCommand* c = new FtpNegotiationCommand auto c = make_unique<FtpNegotiationCommand>
(t->getCuid(), (t->getCuid(),
t->getRequest(), t->getRequest(),
t->getFileEntry(), t->getFileEntry(),
@ -56,7 +56,7 @@ struct FtpNegotiationConnectChain : public ControlChain<ConnectCommand*> {
t->getSocket()); t->getSocket());
c->setStatus(Command::STATUS_ONESHOT_REALTIME); c->setStatus(Command::STATUS_ONESHOT_REALTIME);
e->setNoWait(true); e->setNoWait(true);
e->addCommand(c); e->addCommand(std::move(c));
return 0; return 0;
} }
}; };

View File

@ -38,6 +38,7 @@
#include "SocketCore.h" #include "SocketCore.h"
#include "DownloadContext.h" #include "DownloadContext.h"
#include "SocketRecvBuffer.h" #include "SocketRecvBuffer.h"
#include "a2functional.h"
namespace aria2 { namespace aria2 {
@ -56,9 +57,9 @@ FtpTunnelRequestCommand::FtpTunnelRequestCommand
FtpTunnelRequestCommand::~FtpTunnelRequestCommand() {} FtpTunnelRequestCommand::~FtpTunnelRequestCommand() {}
Command* FtpTunnelRequestCommand::getNextCommand() std::unique_ptr<Command> FtpTunnelRequestCommand::getNextCommand()
{ {
return new FtpTunnelResponseCommand return make_unique<FtpTunnelResponseCommand>
(getCuid(), getRequest(), getFileEntry(), getRequestGroup(), (getCuid(), getRequest(), getFileEntry(), getRequestGroup(),
getHttpConnection(), getDownloadEngine(), getSocket()); getHttpConnection(), getDownloadEngine(), getSocket());
} }

View File

@ -52,7 +52,7 @@ public:
const std::shared_ptr<SocketCore>& s); const std::shared_ptr<SocketCore>& s);
virtual ~FtpTunnelRequestCommand(); virtual ~FtpTunnelRequestCommand();
virtual Command* getNextCommand(); virtual std::unique_ptr<Command> getNextCommand();
}; };
} // namespace aria2 } // namespace aria2

View File

@ -47,7 +47,7 @@ struct FtpTunnelRequestConnectChain : public ControlChain<ConnectCommand*> {
virtual ~FtpTunnelRequestConnectChain() {} virtual ~FtpTunnelRequestConnectChain() {}
virtual int run(ConnectCommand* t, DownloadEngine* e) virtual int run(ConnectCommand* t, DownloadEngine* e)
{ {
FtpTunnelRequestCommand* c = new FtpTunnelRequestCommand auto c = make_unique<FtpTunnelRequestCommand>
(t->getCuid(), (t->getCuid(),
t->getRequest(), t->getRequest(),
t->getFileEntry(), t->getFileEntry(),
@ -57,7 +57,7 @@ struct FtpTunnelRequestConnectChain : public ControlChain<ConnectCommand*> {
t->getSocket()); t->getSocket());
c->setStatus(Command::STATUS_ONESHOT_REALTIME); c->setStatus(Command::STATUS_ONESHOT_REALTIME);
e->setNoWait(true); e->setNoWait(true);
e->addCommand(c); e->addCommand(std::move(c));
return 0; return 0;
} }
}; };

View File

@ -57,11 +57,12 @@ FtpTunnelResponseCommand::FtpTunnelResponseCommand
FtpTunnelResponseCommand::~FtpTunnelResponseCommand() {} FtpTunnelResponseCommand::~FtpTunnelResponseCommand() {}
Command* FtpTunnelResponseCommand::getNextCommand() std::unique_ptr<Command> FtpTunnelResponseCommand::getNextCommand()
{ {
return new FtpNegotiationCommand(getCuid(), getRequest(), getFileEntry(), return make_unique<FtpNegotiationCommand>
getRequestGroup(), getDownloadEngine(), (getCuid(), getRequest(), getFileEntry(),
getSocket()); getRequestGroup(), getDownloadEngine(),
getSocket());
} }
} // namespace aria2 } // namespace aria2

View File

@ -52,7 +52,7 @@ public:
const std::shared_ptr<SocketCore>& s); const std::shared_ptr<SocketCore>& s);
virtual ~FtpTunnelResponseCommand(); virtual ~FtpTunnelResponseCommand();
virtual Command* getNextCommand(); virtual std::unique_ptr<Command> getNextCommand();
}; };
} // namespace aria2 } // namespace aria2

View File

@ -75,16 +75,16 @@ HttpDownloadCommand::~HttpDownloadCommand() {}
bool HttpDownloadCommand::prepareForNextSegment() { bool HttpDownloadCommand::prepareForNextSegment() {
bool downloadFinished = getRequestGroup()->downloadFinished(); bool downloadFinished = getRequestGroup()->downloadFinished();
if(getRequest()->isPipeliningEnabled() && !downloadFinished) { if(getRequest()->isPipeliningEnabled() && !downloadFinished) {
HttpRequestCommand* command = auto command = make_unique<HttpRequestCommand>
new HttpRequestCommand(getCuid(), getRequest(), getFileEntry(), (getCuid(), getRequest(), getFileEntry(),
getRequestGroup(), httpConnection_, getRequestGroup(), httpConnection_,
getDownloadEngine(), getSocket()); getDownloadEngine(), getSocket());
// Set proxy request here. aria2 sends the HTTP request specialized for // Set proxy request here. aria2 sends the HTTP request specialized for
// proxy. // proxy.
if(resolveProxyMethod(getRequest()->getProtocol()) == V_GET) { if(resolveProxyMethod(getRequest()->getProtocol()) == V_GET) {
command->setProxyRequest(createProxyRequest()); command->setProxyRequest(createProxyRequest());
} }
getDownloadEngine()->addCommand(command); getDownloadEngine()->addCommand(std::move(command));
return true; return true;
} else { } else {
const std::string& streamFilterName = getStreamFilter()->getName(); const std::string& streamFilterName = getStreamFilter()->getName();

View File

@ -69,12 +69,11 @@ HttpInitiateConnectionCommand::HttpInitiateConnectionCommand
HttpInitiateConnectionCommand::~HttpInitiateConnectionCommand() {} HttpInitiateConnectionCommand::~HttpInitiateConnectionCommand() {}
Command* HttpInitiateConnectionCommand::createNextCommand std::unique_ptr<Command> HttpInitiateConnectionCommand::createNextCommand
(const std::string& hostname, const std::string& addr, uint16_t port, (const std::string& hostname, const std::string& addr, uint16_t port,
const std::vector<std::string>& resolvedAddresses, const std::vector<std::string>& resolvedAddresses,
const std::shared_ptr<Request>& proxyRequest) const std::shared_ptr<Request>& proxyRequest)
{ {
Command* command;
if(proxyRequest) { if(proxyRequest) {
std::shared_ptr<SocketCore> pooledSocket = std::shared_ptr<SocketCore> pooledSocket =
getDownloadEngine()->popPooledSocket getDownloadEngine()->popPooledSocket
@ -88,13 +87,13 @@ Command* HttpInitiateConnectionCommand::createNextCommand
getSocket()->establishConnection(addr, port); getSocket()->establishConnection(addr, port);
getRequest()->setConnectedAddrInfo(hostname, addr, port); getRequest()->setConnectedAddrInfo(hostname, addr, port);
ConnectCommand* c = new ConnectCommand(getCuid(), auto c = make_unique<ConnectCommand>(getCuid(),
getRequest(), getRequest(),
proxyRequest, proxyRequest,
getFileEntry(), getFileEntry(),
getRequestGroup(), getRequestGroup(),
getDownloadEngine(), getDownloadEngine(),
getSocket()); getSocket());
if(proxyMethod == V_TUNNEL) { if(proxyMethod == V_TUNNEL) {
std::shared_ptr<HttpProxyRequestConnectChain> chain std::shared_ptr<HttpProxyRequestConnectChain> chain
(new HttpProxyRequestConnectChain()); (new HttpProxyRequestConnectChain());
@ -107,25 +106,25 @@ Command* HttpInitiateConnectionCommand::createNextCommand
// Unreachable // Unreachable
assert(0); assert(0);
} }
setupBackupConnection(hostname, addr, port, c); setupBackupConnection(hostname, addr, port, c.get());
command = c; return std::move(c);
} else { } else {
setConnectedAddrInfo(getRequest(), hostname, pooledSocket); setConnectedAddrInfo(getRequest(), hostname, pooledSocket);
std::shared_ptr<SocketRecvBuffer> socketRecvBuffer std::shared_ptr<SocketRecvBuffer> socketRecvBuffer
(new SocketRecvBuffer(pooledSocket)); (new SocketRecvBuffer(pooledSocket));
std::shared_ptr<HttpConnection> httpConnection std::shared_ptr<HttpConnection> httpConnection
(new HttpConnection(getCuid(), pooledSocket, socketRecvBuffer)); (new HttpConnection(getCuid(), pooledSocket, socketRecvBuffer));
HttpRequestCommand* c = new HttpRequestCommand(getCuid(), auto c = make_unique<HttpRequestCommand>(getCuid(),
getRequest(), getRequest(),
getFileEntry(), getFileEntry(),
getRequestGroup(), getRequestGroup(),
httpConnection, httpConnection,
getDownloadEngine(), getDownloadEngine(),
pooledSocket); pooledSocket);
if(proxyMethod == V_GET) { if(proxyMethod == V_GET) {
c->setProxyRequest(proxyRequest); c->setProxyRequest(proxyRequest);
} }
command = c; return std::move(c);
} }
} else { } else {
std::shared_ptr<SocketCore> pooledSocket = std::shared_ptr<SocketCore> pooledSocket =
@ -138,18 +137,18 @@ Command* HttpInitiateConnectionCommand::createNextCommand
getSocket()->establishConnection(addr, port); getSocket()->establishConnection(addr, port);
getRequest()->setConnectedAddrInfo(hostname, addr, port); getRequest()->setConnectedAddrInfo(hostname, addr, port);
ConnectCommand* c = new ConnectCommand(getCuid(), auto c = make_unique<ConnectCommand>(getCuid(),
getRequest(), getRequest(),
proxyRequest, // must be null proxyRequest, // must be null
getFileEntry(), getFileEntry(),
getRequestGroup(), getRequestGroup(),
getDownloadEngine(), getDownloadEngine(),
getSocket()); getSocket());
std::shared_ptr<HttpRequestConnectChain> chain std::shared_ptr<HttpRequestConnectChain> chain
(new HttpRequestConnectChain()); (new HttpRequestConnectChain());
c->setControlChain(chain); c->setControlChain(chain);
setupBackupConnection(hostname, addr, port, c); setupBackupConnection(hostname, addr, port, c.get());
command = c; return std::move(c);
} else { } else {
setSocket(pooledSocket); setSocket(pooledSocket);
setConnectedAddrInfo(getRequest(), hostname, pooledSocket); setConnectedAddrInfo(getRequest(), hostname, pooledSocket);
@ -158,16 +157,15 @@ Command* HttpInitiateConnectionCommand::createNextCommand
(new SocketRecvBuffer(getSocket())); (new SocketRecvBuffer(getSocket()));
std::shared_ptr<HttpConnection> httpConnection std::shared_ptr<HttpConnection> httpConnection
(new HttpConnection(getCuid(), getSocket(), socketRecvBuffer)); (new HttpConnection(getCuid(), getSocket(), socketRecvBuffer));
command = new HttpRequestCommand(getCuid(), return make_unique<HttpRequestCommand>(getCuid(),
getRequest(), getRequest(),
getFileEntry(), getFileEntry(),
getRequestGroup(), getRequestGroup(),
httpConnection, httpConnection,
getDownloadEngine(), getDownloadEngine(),
getSocket()); getSocket());
} }
} }
return command;
} }
} // namespace aria2 } // namespace aria2

View File

@ -68,7 +68,7 @@ namespace aria2 {
// calling execute() returns true. // calling execute() returns true.
class HttpInitiateConnectionCommand : public InitiateConnectionCommand { class HttpInitiateConnectionCommand : public InitiateConnectionCommand {
protected: protected:
virtual Command* createNextCommand virtual std::unique_ptr<Command> createNextCommand
(const std::string& hostname, const std::string& addr, uint16_t port, (const std::string& hostname, const std::string& addr, uint16_t port,
const std::vector<std::string>& resolvedAddresses, const std::vector<std::string>& resolvedAddresses,
const std::shared_ptr<Request>& proxyRequest); const std::shared_ptr<Request>& proxyRequest);

View File

@ -80,15 +80,14 @@ bool HttpListenCommand::execute()
A2_LOG_INFO(fmt("RPC: Accepted the connection from %s:%u.", A2_LOG_INFO(fmt("RPC: Accepted the connection from %s:%u.",
peerInfo.first.c_str(), peerInfo.second)); peerInfo.first.c_str(), peerInfo.second));
HttpServerCommand* c =
new HttpServerCommand(e_->newCUID(), e_, socket, secure_);
e_->setNoWait(true); e_->setNoWait(true);
e_->addCommand(c); e_->addCommand(make_unique<HttpServerCommand>
(e_->newCUID(), e_, socket, secure_));
} }
} catch(RecoverableException& e) { } catch(RecoverableException& e) {
A2_LOG_DEBUG_EX(fmt(MSG_ACCEPT_FAILURE, getCuid()), e); A2_LOG_DEBUG_EX(fmt(MSG_ACCEPT_FAILURE, getCuid()), e);
} }
e_->addCommand(this); e_->addCommand(std::unique_ptr<Command>(this));
return false; return false;
} }

View File

@ -37,6 +37,7 @@
#include "Request.h" #include "Request.h"
#include "SocketCore.h" #include "SocketCore.h"
#include "SocketRecvBuffer.h" #include "SocketRecvBuffer.h"
#include "a2functional.h"
namespace aria2 { namespace aria2 {
@ -55,9 +56,9 @@ HttpProxyRequestCommand::HttpProxyRequestCommand
HttpProxyRequestCommand::~HttpProxyRequestCommand() {} HttpProxyRequestCommand::~HttpProxyRequestCommand() {}
Command* HttpProxyRequestCommand::getNextCommand() std::unique_ptr<Command> HttpProxyRequestCommand::getNextCommand()
{ {
return new HttpProxyResponseCommand return make_unique<HttpProxyResponseCommand>
(getCuid(), getRequest(), getFileEntry(), getRequestGroup(), (getCuid(), getRequest(), getFileEntry(), getRequestGroup(),
getHttpConnection(), getDownloadEngine(), getSocket()); getHttpConnection(), getDownloadEngine(), getSocket());
} }

View File

@ -52,7 +52,7 @@ public:
const std::shared_ptr<SocketCore>& s); const std::shared_ptr<SocketCore>& s);
virtual ~HttpProxyRequestCommand(); virtual ~HttpProxyRequestCommand();
virtual Command* getNextCommand(); virtual std::unique_ptr<Command> getNextCommand();
}; };
} // namespace aria2 } // namespace aria2

View File

@ -47,7 +47,7 @@ struct HttpProxyRequestConnectChain : public ControlChain<ConnectCommand*> {
virtual ~HttpProxyRequestConnectChain() {} virtual ~HttpProxyRequestConnectChain() {}
virtual int run(ConnectCommand* t, DownloadEngine* e) virtual int run(ConnectCommand* t, DownloadEngine* e)
{ {
HttpProxyRequestCommand* c = new HttpProxyRequestCommand auto c = make_unique<HttpProxyRequestCommand>
(t->getCuid(), (t->getCuid(),
t->getRequest(), t->getRequest(),
t->getFileEntry(), t->getFileEntry(),
@ -57,7 +57,7 @@ struct HttpProxyRequestConnectChain : public ControlChain<ConnectCommand*> {
t->getSocket()); t->getSocket());
c->setStatus(Command::STATUS_ONESHOT_REALTIME); c->setStatus(Command::STATUS_ONESHOT_REALTIME);
e->setNoWait(true); e->setNoWait(true);
e->addCommand(c); e->addCommand(std::move(c));
return 0; return 0;
} }
}; };

View File

@ -57,11 +57,12 @@ HttpProxyResponseCommand::HttpProxyResponseCommand
HttpProxyResponseCommand::~HttpProxyResponseCommand() {} HttpProxyResponseCommand::~HttpProxyResponseCommand() {}
Command* HttpProxyResponseCommand::getNextCommand() std::unique_ptr<Command> HttpProxyResponseCommand::getNextCommand()
{ {
return new HttpRequestCommand(getCuid(), getRequest(), getFileEntry(), return make_unique<HttpRequestCommand>
getRequestGroup(), getHttpConnection(), (getCuid(), getRequest(), getFileEntry(),
getDownloadEngine(), getSocket()); getRequestGroup(), getHttpConnection(),
getDownloadEngine(), getSocket());
} }
} // namespace aria2 } // namespace aria2

View File

@ -52,7 +52,7 @@ public:
const std::shared_ptr<SocketCore>& s); const std::shared_ptr<SocketCore>& s);
virtual ~HttpProxyResponseCommand(); virtual ~HttpProxyResponseCommand();
virtual Command* getNextCommand(); virtual std::unique_ptr<Command> getNextCommand();
}; };
} // namespace aria2 } // namespace aria2

View File

@ -130,7 +130,7 @@ bool HttpRequestCommand::executeInternal() {
if(!getSocket()->tlsConnect(getRequest()->getHost())) { if(!getSocket()->tlsConnect(getRequest()->getHost())) {
setReadCheckSocketIf(getSocket(), getSocket()->wantRead()); setReadCheckSocketIf(getSocket(), getSocket()->wantRead());
setWriteCheckSocketIf(getSocket(), getSocket()->wantWrite()); setWriteCheckSocketIf(getSocket(), getSocket()->wantWrite());
getDownloadEngine()->addCommand(this); addCommandSelf();
return false; return false;
} }
} }
@ -207,19 +207,19 @@ bool HttpRequestCommand::executeInternal() {
httpConnection_->sendPendingData(); httpConnection_->sendPendingData();
} }
if(httpConnection_->sendBufferIsEmpty()) { if(httpConnection_->sendBufferIsEmpty()) {
Command* command = new HttpResponseCommand(getCuid(), getDownloadEngine()->addCommand(make_unique<HttpResponseCommand>
getRequest(), (getCuid(),
getFileEntry(), getRequest(),
getRequestGroup(), getFileEntry(),
httpConnection_, getRequestGroup(),
getDownloadEngine(), httpConnection_,
getSocket()); getDownloadEngine(),
getDownloadEngine()->addCommand(command); getSocket()));
return true; return true;
} else { } else {
setReadCheckSocketIf(getSocket(), getSocket()->wantRead()); setReadCheckSocketIf(getSocket(), getSocket()->wantRead());
setWriteCheckSocketIf(getSocket(), getSocket()->wantWrite()); setWriteCheckSocketIf(getSocket(), getSocket()->wantWrite());
getDownloadEngine()->addCommand(this); addCommandSelf();
return false; return false;
} }
} }

View File

@ -53,17 +53,17 @@ struct HttpRequestConnectChain : public ControlChain<ConnectCommand*> {
(new SocketRecvBuffer(t->getSocket())); (new SocketRecvBuffer(t->getSocket()));
std::shared_ptr<HttpConnection> httpConnection std::shared_ptr<HttpConnection> httpConnection
(new HttpConnection(t->getCuid(), t->getSocket(), socketRecvBuffer)); (new HttpConnection(t->getCuid(), t->getSocket(), socketRecvBuffer));
HttpRequestCommand* c = new HttpRequestCommand(t->getCuid(), auto c = make_unique<HttpRequestCommand>(t->getCuid(),
t->getRequest(), t->getRequest(),
t->getFileEntry(), t->getFileEntry(),
t->getRequestGroup(), t->getRequestGroup(),
httpConnection, httpConnection,
e, e,
t->getSocket()); t->getSocket());
c->setProxyRequest(t->getProxyRequest()); c->setProxyRequest(t->getProxyRequest());
c->setStatus(Command::STATUS_ONESHOT_REALTIME); c->setStatus(Command::STATUS_ONESHOT_REALTIME);
e->setNoWait(true); e->setNoWait(true);
e->addCommand(c); e->addCommand(std::move(c));
return 0; return 0;
} }
}; };

View File

@ -158,7 +158,7 @@ bool HttpResponseCommand::executeInternal()
// For socket->wantRead() == true, setReadCheckSocket(socket) is already // For socket->wantRead() == true, setReadCheckSocket(socket) is already
// done in the constructor. // done in the constructor.
setWriteCheckSocketIf(getSocket(), getSocket()->wantWrite()); setWriteCheckSocketIf(getSocket(), getSocket()->wantWrite());
getDownloadEngine()->addCommand(this); addCommandSelf();
return false; return false;
} }
// check HTTP status number // check HTTP status number
@ -377,21 +377,17 @@ bool HttpResponseCommand::handleDefaultEncoding
// we can't continue to use this socket because server sends all entity // we can't continue to use this socket because server sends all entity
// body instead of a segment. // body instead of a segment.
// Therefore, we shutdown the socket here if pipelining is enabled. // Therefore, we shutdown the socket here if pipelining is enabled.
DownloadCommand* command = 0;
if(getRequest()->getMethod() == Request::METHOD_GET && if(getRequest()->getMethod() == Request::METHOD_GET &&
segment && segment->getPositionToWrite() == 0 && segment && segment->getPositionToWrite() == 0 &&
!getRequest()->isPipeliningEnabled()) { !getRequest()->isPipeliningEnabled()) {
command = createHttpDownloadCommand checkEntry->pushNextCommand
(httpResponse, (createHttpDownloadCommand
getTransferEncodingStreamFilter(httpResponse)); (httpResponse,
getTransferEncodingStreamFilter(httpResponse)));
} else { } else {
getSegmentMan()->cancelSegment(getCuid()); getSegmentMan()->cancelSegment(getCuid());
getFileEntry()->poolRequest(getRequest()); getFileEntry()->poolRequest(getRequest());
} }
// After command is passed to prepareForNextAction(), it is managed
// by CheckIntegrityEntry.
checkEntry->pushNextCommand(command);
command = 0;
prepareForNextAction(checkEntry); prepareForNextAction(checkEntry);
@ -505,7 +501,7 @@ bool HttpResponseCommand::skipResponseBody
// We don't use Content-Encoding here because this response body is just // We don't use Content-Encoding here because this response body is just
// thrown away. // thrown away.
HttpSkipResponseCommand* command = new HttpSkipResponseCommand auto command = make_unique<HttpSkipResponseCommand>
(getCuid(), getRequest(), getFileEntry(), getRequestGroup(), (getCuid(), getRequest(), getFileEntry(), getRequestGroup(),
httpConnection_, httpResponse, httpConnection_, httpResponse,
getDownloadEngine(), getSocket()); getDownloadEngine(), getSocket());
@ -522,7 +518,7 @@ bool HttpResponseCommand::skipResponseBody
getDownloadEngine()->setNoWait(true); getDownloadEngine()->setNoWait(true);
} }
getDownloadEngine()->addCommand(command); getDownloadEngine()->addCommand(std::move(command));
return true; return true;
} }
@ -544,16 +540,17 @@ bool decideFileAllocation
} }
} // namespace } // namespace
HttpDownloadCommand* HttpResponseCommand::createHttpDownloadCommand std::unique_ptr<HttpDownloadCommand>
HttpResponseCommand::createHttpDownloadCommand
(const std::shared_ptr<HttpResponse>& httpResponse, (const std::shared_ptr<HttpResponse>& httpResponse,
const std::shared_ptr<StreamFilter>& filter) const std::shared_ptr<StreamFilter>& filter)
{ {
HttpDownloadCommand* command = auto command = make_unique<HttpDownloadCommand>
new HttpDownloadCommand(getCuid(), getRequest(), getFileEntry(), (getCuid(), getRequest(), getFileEntry(),
getRequestGroup(), getRequestGroup(),
httpResponse, httpConnection_, httpResponse, httpConnection_,
getDownloadEngine(), getSocket()); getDownloadEngine(), getSocket());
command->setStartupIdleTime(getOption()->getAsInt(PREF_STARTUP_IDLE_TIME)); command->setStartupIdleTime(getOption()->getAsInt(PREF_STARTUP_IDLE_TIME));
command->setLowestDownloadSpeedLimit command->setLowestDownloadSpeedLimit
(getOption()->getAsInt(PREF_LOWEST_SPEED_LIMIT)); (getOption()->getAsInt(PREF_LOWEST_SPEED_LIMIT));
@ -563,9 +560,9 @@ HttpDownloadCommand* HttpResponseCommand::createHttpDownloadCommand
getRequestGroup()->setFileAllocationEnabled(false); getRequestGroup()->setFileAllocationEnabled(false);
} }
getRequestGroup()->getURISelector()->tuneDownloadCommand getRequestGroup()->getURISelector()->tuneDownloadCommand
(getFileEntry()->getRemainingUris(), command); (getFileEntry()->getRemainingUris(), command.get());
return command; return std::move(command);
} }
void HttpResponseCommand::poolConnection() void HttpResponseCommand::poolConnection()

View File

@ -67,7 +67,7 @@ private:
bool handleOtherEncoding(const std::shared_ptr<HttpResponse>& httpResponse); bool handleOtherEncoding(const std::shared_ptr<HttpResponse>& httpResponse);
bool skipResponseBody(const std::shared_ptr<HttpResponse>& httpResponse); bool skipResponseBody(const std::shared_ptr<HttpResponse>& httpResponse);
HttpDownloadCommand* std::unique_ptr<HttpDownloadCommand>
createHttpDownloadCommand createHttpDownloadCommand
(const std::shared_ptr<HttpResponse>& httpResponse, (const std::shared_ptr<HttpResponse>& httpResponse,
const std::shared_ptr<StreamFilter>& streamFilter); const std::shared_ptr<StreamFilter>& streamFilter);

View File

@ -142,9 +142,8 @@ void HttpServerBodyCommand::sendJsonRpcBatchResponse
void HttpServerBodyCommand::addHttpServerResponseCommand() void HttpServerBodyCommand::addHttpServerResponseCommand()
{ {
Command* command = e_->addCommand(make_unique<HttpServerResponseCommand>
new HttpServerResponseCommand(getCuid(), httpServer_, e_, socket_); (getCuid(), httpServer_, e_, socket_));
e_->addCommand(command);
e_->setNoWait(true); e_->setNoWait(true);
} }
@ -309,7 +308,7 @@ bool HttpServerBodyCommand::execute()
} }
} else { } else {
updateWriteCheck(); updateWriteCheck();
e_->addCommand(this); e_->addCommand(std::unique_ptr<Command>(this));
return false; return false;
} }
} else { } else {
@ -317,7 +316,7 @@ bool HttpServerBodyCommand::execute()
A2_LOG_INFO("HTTP request body timeout."); A2_LOG_INFO("HTTP request body timeout.");
return true; return true;
} else { } else {
e_->addCommand(this); e_->addCommand(std::unique_ptr<Command>(this));
return false; return false;
} }
} }

View File

@ -184,7 +184,7 @@ bool HttpServerCommand::execute()
// finished. // finished.
if(!socket_->tlsAccept()) { if(!socket_->tlsAccept()) {
updateWriteCheck(); updateWriteCheck();
e_->addCommand(this); e_->addCommand(std::unique_ptr<Command>(this));
return false; return false;
} }
} }
@ -194,7 +194,7 @@ bool HttpServerCommand::execute()
header = httpServer_->receiveRequest(); header = httpServer_->receiveRequest();
if(!header) { if(!header) {
updateWriteCheck(); updateWriteCheck();
e_->addCommand(this); e_->addCommand(std::unique_ptr<Command>(this));
return false; return false;
} }
// CORS preflight request uses OPTIONS method. It is not // CORS preflight request uses OPTIONS method. It is not
@ -204,9 +204,8 @@ bool HttpServerCommand::execute()
httpServer_->disableKeepAlive(); httpServer_->disableKeepAlive();
httpServer_->feedResponse httpServer_->feedResponse
(401, "WWW-Authenticate: Basic realm=\"aria2\"\r\n"); (401, "WWW-Authenticate: Basic realm=\"aria2\"\r\n");
Command* command = e_->addCommand(make_unique<HttpServerResponseCommand>
new HttpServerResponseCommand(getCuid(), httpServer_, e_, socket_); (getCuid(), httpServer_, e_, socket_));
e_->addCommand(command);
e_->setNoWait(true); e_->setNoWait(true);
return true; return true;
} }
@ -214,7 +213,6 @@ bool HttpServerCommand::execute()
header->fieldContains(HttpHeader::CONNECTION, "upgrade")) { header->fieldContains(HttpHeader::CONNECTION, "upgrade")) {
#ifdef ENABLE_WEBSOCKET #ifdef ENABLE_WEBSOCKET
int status = websocketHandshake(header); int status = websocketHandshake(header);
Command* command;
if(status == 101) { if(status == 101) {
std::string serverKey = std::string serverKey =
createWebSocketServerKey createWebSocketServerKey
@ -222,26 +220,23 @@ bool HttpServerCommand::execute()
httpServer_->feedUpgradeResponse("websocket", httpServer_->feedUpgradeResponse("websocket",
fmt("Sec-WebSocket-Accept: %s\r\n", fmt("Sec-WebSocket-Accept: %s\r\n",
serverKey.c_str())); serverKey.c_str()));
command = new rpc::WebSocketResponseCommand(getCuid(), httpServer_, e_->addCommand(make_unique<rpc::WebSocketResponseCommand>
e_, socket_); (getCuid(), httpServer_, e_, socket_));
} else { } else {
if(status == 426) { if(status == 426) {
httpServer_->feedResponse(426, "Sec-WebSocket-Version: 13\r\n"); httpServer_->feedResponse(426, "Sec-WebSocket-Version: 13\r\n");
} else { } else {
httpServer_->feedResponse(status); httpServer_->feedResponse(status);
} }
command = new HttpServerResponseCommand(getCuid(), httpServer_, e_, e_->addCommand(make_unique<HttpServerResponseCommand>
socket_); (getCuid(), httpServer_, e_, socket_));
} }
e_->addCommand(command);
e_->setNoWait(true); e_->setNoWait(true);
return true; return true;
#else // !ENABLE_WEBSOCKET #else // !ENABLE_WEBSOCKET
httpServer_->feedResponse(400); httpServer_->feedResponse(400);
Command* command = new HttpServerResponseCommand(getCuid(), e_->addCommand(make_unique<HttpServerResponseCommand>
httpServer_, e_, (getCuid(), httpServer_, e_, socket_));
socket_);
e_->addCommand(command);
e_->setNoWait(true); e_->setNoWait(true);
return true; return true;
#endif // !ENABLE_WEBSOCKET #endif // !ENABLE_WEBSOCKET
@ -255,9 +250,8 @@ bool HttpServerCommand::execute()
httpServer_->getContentLength())); httpServer_->getContentLength()));
return true; return true;
} }
Command* command = new HttpServerBodyCommand(getCuid(), httpServer_, e_, e_->addCommand(make_unique<HttpServerBodyCommand>
socket_); (getCuid(), httpServer_, e_, socket_));
e_->addCommand(command);
e_->setNoWait(true); e_->setNoWait(true);
return true; return true;
} }
@ -266,7 +260,7 @@ bool HttpServerCommand::execute()
A2_LOG_INFO("HTTP request timeout."); A2_LOG_INFO("HTTP request timeout.");
return true; return true;
} else { } else {
e_->addCommand(this); e_->addCommand(std::unique_ptr<Command>(this));
return false; return false;
} }
} }

View File

@ -63,8 +63,8 @@ void HttpServerResponseCommand::afterSend
A2_LOG_INFO(fmt("CUID#%" PRId64 " - Persist connection.", A2_LOG_INFO(fmt("CUID#%" PRId64 " - Persist connection.",
getCuid())); getCuid()));
e->addCommand e->addCommand
(new HttpServerCommand(getCuid(), httpServer, e, (make_unique<HttpServerCommand>(getCuid(), httpServer, e,
httpServer->getSocket())); httpServer->getSocket()));
} }
} }

View File

@ -173,7 +173,7 @@ bool HttpSkipResponseCommand::executeInternal()
return processResponse(); return processResponse();
} else { } else {
setWriteCheckSocketIf(getSocket(), getSocket()->wantWrite()); setWriteCheckSocketIf(getSocket(), getSocket()->wantWrite());
getDownloadEngine()->addCommand(this); addCommandSelf();
return false; return false;
} }
} }

View File

@ -87,13 +87,12 @@ bool InitiateConnectionCommand::executeInternal() {
std::vector<std::string> addrs; std::vector<std::string> addrs;
std::string ipaddr = resolveHostname(addrs, hostname, port); std::string ipaddr = resolveHostname(addrs, hostname, port);
if(ipaddr.empty()) { if(ipaddr.empty()) {
getDownloadEngine()->addCommand(this); addCommandSelf();
return false; return false;
} }
try { try {
Command* command = createNextCommand(hostname, ipaddr, port, getDownloadEngine()->addCommand(createNextCommand(hostname, ipaddr, port,
addrs, proxyRequest); addrs, proxyRequest));
getDownloadEngine()->addCommand(command);
return true; return true;
} catch(RecoverableException& ex) { } catch(RecoverableException& ex) {
// Catch exception and retry another address. // Catch exception and retry another address.
@ -106,12 +105,12 @@ bool InitiateConnectionCommand::executeInternal() {
A2_LOG_INFO(fmt(MSG_CONNECT_FAILED_AND_RETRY, A2_LOG_INFO(fmt(MSG_CONNECT_FAILED_AND_RETRY,
getCuid(), getCuid(),
ipaddr.c_str(), port)); ipaddr.c_str(), port));
Command* command = auto command =
InitiateConnectionCommandFactory::createInitiateConnectionCommand InitiateConnectionCommandFactory::createInitiateConnectionCommand
(getCuid(), getRequest(), getFileEntry(), getRequestGroup(), (getCuid(), getRequest(), getFileEntry(), getRequestGroup(),
getDownloadEngine()); getDownloadEngine());
getDownloadEngine()->setNoWait(true); getDownloadEngine()->setNoWait(true);
getDownloadEngine()->addCommand(command); getDownloadEngine()->addCommand(std::move(command));
return true; return true;
} }
getDownloadEngine()->removeCachedIPAddress(hostname, port); getDownloadEngine()->removeCachedIPAddress(hostname, port);
@ -149,12 +148,12 @@ InitiateConnectionCommand::createBackupIPv4ConnectCommand
eoi = addrs.end(); i != eoi; ++i) { eoi = addrs.end(); i != eoi; ++i) {
if(inetPton(AF_INET, (*i).c_str(), &buf) == 0) { if(inetPton(AF_INET, (*i).c_str(), &buf) == 0) {
info.reset(new BackupConnectInfo()); info.reset(new BackupConnectInfo());
BackupIPv4ConnectCommand* command = new BackupIPv4ConnectCommand auto command = make_unique<BackupIPv4ConnectCommand>
(getDownloadEngine()->newCUID(), *i, port, info, mainCommand, (getDownloadEngine()->newCUID(), *i, port, info, mainCommand,
getRequestGroup(), getDownloadEngine()); getRequestGroup(), getDownloadEngine());
A2_LOG_INFO(fmt("Issue backup connection command CUID#%" PRId64 A2_LOG_INFO(fmt("Issue backup connection command CUID#%" PRId64
", addr=%s", command->getCuid(), (*i).c_str())); ", addr=%s", command->getCuid(), (*i).c_str()));
getDownloadEngine()->addCommand(command); getDownloadEngine()->addCommand(std::move(command));
return info; return info;
} }
} }

View File

@ -58,7 +58,7 @@ protected:
// use this address this time. resolvedAddresses are all addresses // use this address this time. resolvedAddresses are all addresses
// resolved. proxyRequest is set if we are going to use proxy // resolved. proxyRequest is set if we are going to use proxy
// server. // server.
virtual Command* createNextCommand virtual std::unique_ptr<Command> createNextCommand
(const std::string& hostname, const std::string& addr, uint16_t port, (const std::string& hostname, const std::string& addr, uint16_t port,
const std::vector<std::string>& resolvedAddresses, const std::vector<std::string>& resolvedAddresses,
const std::shared_ptr<Request>& proxyRequest) = 0; const std::shared_ptr<Request>& proxyRequest) = 0;

View File

@ -47,7 +47,7 @@
namespace aria2 { namespace aria2 {
Command* std::unique_ptr<Command>
InitiateConnectionCommandFactory::createInitiateConnectionCommand InitiateConnectionCommandFactory::createInitiateConnectionCommand
(cuid_t cuid, (cuid_t cuid,
const std::shared_ptr<Request>& req, const std::shared_ptr<Request>& req,
@ -69,16 +69,16 @@ InitiateConnectionCommandFactory::createInitiateConnectionCommand
req->setPipeliningHint(true); req->setPipeliningHint(true);
} }
return return make_unique<HttpInitiateConnectionCommand>(cuid, req, fileEntry,
new HttpInitiateConnectionCommand(cuid, req, fileEntry, requestGroup, e); requestGroup, e);
} else if(req->getProtocol() == "ftp") { } else if(req->getProtocol() == "ftp") {
if(req->getFile().empty()) { if(req->getFile().empty()) {
throw DL_ABORT_EX throw DL_ABORT_EX
(fmt("FTP URI %s doesn't contain file path.", (fmt("FTP URI %s doesn't contain file path.",
req->getUri().c_str())); req->getUri().c_str()));
} }
return return make_unique<FtpInitiateConnectionCommand>(cuid, req, fileEntry,
new FtpInitiateConnectionCommand(cuid, req, fileEntry, requestGroup, e); requestGroup, e);
} else { } else {
// these protocols are not supported yet // these protocols are not supported yet
throw DL_ABORT_EX throw DL_ABORT_EX

View File

@ -50,7 +50,7 @@ class FileEntry;
class InitiateConnectionCommandFactory { class InitiateConnectionCommandFactory {
public: public:
static Command* static std::unique_ptr<Command>
createInitiateConnectionCommand(cuid_t cuid, createInitiateConnectionCommand(cuid_t cuid,
const std::shared_ptr<Request>& req, const std::shared_ptr<Request>& req,
const std::shared_ptr<FileEntry>& fileEntry, const std::shared_ptr<FileEntry>& fileEntry,

View File

@ -97,7 +97,7 @@ bool InitiatorMSEHandshakeCommand::executeInternal() {
switch(sequence_) { switch(sequence_) {
case INITIATOR_SEND_KEY: { case INITIATOR_SEND_KEY: {
if(!getSocket()->isWritable(0)) { if(!getSocket()->isWritable(0)) {
getDownloadEngine()->addCommand(this); addCommandSelf();
return false; return false;
} }
setTimeout(getOption()->getAsInt(PREF_BT_TIMEOUT)); setTimeout(getOption()->getAsInt(PREF_BT_TIMEOUT));
@ -164,15 +164,15 @@ bool InitiatorMSEHandshakeCommand::executeInternal() {
peerConnection->presetBuffer(mseHandshake_->getBuffer(), peerConnection->presetBuffer(mseHandshake_->getBuffer(),
mseHandshake_->getBufferLength()); mseHandshake_->getBufferLength());
} }
PeerInteractionCommand* c = getDownloadEngine()->addCommand
new PeerInteractionCommand (make_unique<PeerInteractionCommand>
(getCuid(), requestGroup_, getPeer(), getDownloadEngine(), btRuntime_, (getCuid(), requestGroup_, getPeer(),
pieceStorage_, getDownloadEngine(), btRuntime_,
peerStorage_, pieceStorage_,
getSocket(), peerStorage_,
PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE, getSocket(),
peerConnection); PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE,
getDownloadEngine()->addCommand(c); peerConnection));
return true; return true;
} else { } else {
done = true; done = true;
@ -191,7 +191,7 @@ bool InitiatorMSEHandshakeCommand::executeInternal() {
} else { } else {
disableWriteCheckSocket(); disableWriteCheckSocket();
} }
getDownloadEngine()->addCommand(this); addCommandSelf();
return false; return false;
} }
@ -202,13 +202,11 @@ void InitiatorMSEHandshakeCommand::tryNewPeer()
std::shared_ptr<Peer> peer = peerStorage_->checkoutPeer(ncuid); std::shared_ptr<Peer> peer = peerStorage_->checkoutPeer(ncuid);
// sanity check // sanity check
if(peer) { if(peer) {
PeerInitiateConnectionCommand* command; auto command = make_unique<PeerInitiateConnectionCommand>
command = new PeerInitiateConnectionCommand(ncuid, requestGroup_, peer, (ncuid, requestGroup_, peer, getDownloadEngine(), btRuntime_);
getDownloadEngine(),
btRuntime_);
command->setPeerStorage(peerStorage_); command->setPeerStorage(peerStorage_);
command->setPieceStorage(pieceStorage_); command->setPieceStorage(pieceStorage_);
getDownloadEngine()->addCommand(command); getDownloadEngine()->addCommand(std::move(command));
} }
} }
} }
@ -230,12 +228,12 @@ bool InitiatorMSEHandshakeCommand::prepareForNextPeer(time_t wait)
// try legacy BitTorrent handshake // try legacy BitTorrent handshake
A2_LOG_INFO(fmt("CUID#%" PRId64 " - Retry using legacy BitTorrent handshake.", A2_LOG_INFO(fmt("CUID#%" PRId64 " - Retry using legacy BitTorrent handshake.",
getCuid())); getCuid()));
PeerInitiateConnectionCommand* command = auto command = make_unique<PeerInitiateConnectionCommand>
new PeerInitiateConnectionCommand(getCuid(), requestGroup_, getPeer(), (getCuid(), requestGroup_, getPeer(),
getDownloadEngine(), btRuntime_, false); getDownloadEngine(), btRuntime_, false);
command->setPeerStorage(peerStorage_); command->setPeerStorage(peerStorage_);
command->setPieceStorage(pieceStorage_); command->setPieceStorage(pieceStorage_);
getDownloadEngine()->addCommand(command); getDownloadEngine()->addCommand(std::move(command));
return true; return true;
} }
} }

View File

@ -87,7 +87,7 @@ bool LpdDispatchMessageCommand::execute()
tryCount_ = 0; tryCount_ = 0;
} }
} }
e_->addCommand(this); e_->addCommand(std::unique_ptr<Command>(this));
return false; return false;
} }

View File

@ -105,7 +105,7 @@ bool LpdReceiveMessageCommand::execute()
peer->isLocalPeer()?1:0)); peer->isLocalPeer()?1:0));
} }
} }
e_->addCommand(this); e_->addCommand(std::unique_ptr<Command>(this));
return false; return false;
} }

View File

@ -24,7 +24,6 @@ SRCS = option_processing.cc\
FtpDownloadCommand.cc FtpDownloadCommand.h\ FtpDownloadCommand.cc FtpDownloadCommand.h\
FtpTunnelRequestCommand.cc FtpTunnelRequestCommand.h\ FtpTunnelRequestCommand.cc FtpTunnelRequestCommand.h\
FtpTunnelResponseCommand.cc FtpTunnelResponseCommand.h\ FtpTunnelResponseCommand.cc FtpTunnelResponseCommand.h\
SleepCommand.cc SleepCommand.h\
DownloadEngine.cc DownloadEngine.h\ DownloadEngine.cc DownloadEngine.h\
Segment.h\ Segment.h\
GrowSegment.cc GrowSegment.h\ GrowSegment.cc GrowSegment.h\

View File

@ -95,7 +95,7 @@ bool NameResolveCommand::execute()
#ifdef ENABLE_ASYNC_DNS #ifdef ENABLE_ASYNC_DNS
if(e_->getOption()->getAsBool(PREF_ASYNC_DNS)) { if(e_->getOption()->getAsBool(PREF_ASYNC_DNS)) {
if(resolveHostname(res, hostname) == 0) { if(resolveHostname(res, hostname) == 0) {
e_->addCommand(this); e_->addCommand(std::unique_ptr<Command>(this));
return false; return false;
} }
} else } else

View File

@ -198,4 +198,9 @@ void PeerAbstractCommand::createSocket()
socket_.reset(new SocketCore()); socket_.reset(new SocketCore());
} }
void PeerAbstractCommand::addCommandSelf()
{
e_->addCommand(std::unique_ptr<Command>(this));
}
} // namespace aria2 } // namespace aria2

View File

@ -93,6 +93,7 @@ protected:
void disableWriteCheckSocket(); void disableWriteCheckSocket();
void setNoCheck(bool check); void setNoCheck(bool check);
void updateKeepAlive(); void updateKeepAlive();
void addCommandSelf();
public: public:
PeerAbstractCommand(cuid_t cuid, PeerAbstractCommand(cuid_t cuid,
const std::shared_ptr<Peer>& peer, const std::shared_ptr<Peer>& peer,

View File

@ -53,7 +53,7 @@ bool PeerChokeCommand::execute() {
if(peerStorage_->chokeRoundIntervalElapsed()) { if(peerStorage_->chokeRoundIntervalElapsed()) {
peerStorage_->executeChoke(); peerStorage_->executeChoke();
} }
e_->addCommand(this); e_->addCommand(std::unique_ptr<Command>(this));
return false; return false;
} }

View File

@ -84,20 +84,20 @@ bool PeerInitiateConnectionCommand::executeInternal() {
getSocket()->establishConnection(getPeer()->getIPAddress(), getSocket()->establishConnection(getPeer()->getIPAddress(),
getPeer()->getPort(), false); getPeer()->getPort(), false);
if(mseHandshakeEnabled_) { if(mseHandshakeEnabled_) {
InitiatorMSEHandshakeCommand* c = auto c = make_unique<InitiatorMSEHandshakeCommand>
new InitiatorMSEHandshakeCommand(getCuid(), requestGroup_, getPeer(), (getCuid(), requestGroup_, getPeer(),
getDownloadEngine(), getDownloadEngine(), btRuntime_, getSocket());
btRuntime_, getSocket());
c->setPeerStorage(peerStorage_); c->setPeerStorage(peerStorage_);
c->setPieceStorage(pieceStorage_); c->setPieceStorage(pieceStorage_);
getDownloadEngine()->addCommand(c); getDownloadEngine()->addCommand(std::move(c));
} else { } else {
PeerInteractionCommand* command = getDownloadEngine()->addCommand
new PeerInteractionCommand (make_unique<PeerInteractionCommand>
(getCuid(), requestGroup_, getPeer(), getDownloadEngine(), (getCuid(), requestGroup_, getPeer(),
btRuntime_, pieceStorage_, peerStorage_, getDownloadEngine(),
getSocket(), PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE); btRuntime_, pieceStorage_, peerStorage_,
getDownloadEngine()->addCommand(command); getSocket(),
PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE));
} }
return true; return true;
} }
@ -109,13 +109,11 @@ bool PeerInitiateConnectionCommand::prepareForNextPeer(time_t wait) {
std::shared_ptr<Peer> peer = peerStorage_->checkoutPeer(ncuid); std::shared_ptr<Peer> peer = peerStorage_->checkoutPeer(ncuid);
// sanity check // sanity check
if(peer) { if(peer) {
PeerInitiateConnectionCommand* command; auto command = make_unique<PeerInitiateConnectionCommand>
command = new PeerInitiateConnectionCommand(ncuid, requestGroup_, peer, (ncuid, requestGroup_, peer, getDownloadEngine(), btRuntime_);
getDownloadEngine(),
btRuntime_);
command->setPeerStorage(peerStorage_); command->setPeerStorage(peerStorage_);
command->setPieceStorage(pieceStorage_); command->setPieceStorage(pieceStorage_);
getDownloadEngine()->addCommand(command); getDownloadEngine()->addCommand(std::move(command));
} }
} }
return true; return true;

View File

@ -384,7 +384,7 @@ bool PeerInteractionCommand::executeInternal() {
if(btInteractive_->countPendingMessage() > 0) { if(btInteractive_->countPendingMessage() > 0) {
setNoCheck(true); setNoCheck(true);
} }
getDownloadEngine()->addCommand(this); addCommandSelf();
return false; return false;
} }
@ -395,13 +395,11 @@ bool PeerInteractionCommand::prepareForNextPeer(time_t wait) {
std::shared_ptr<Peer> peer = peerStorage_->checkoutPeer(ncuid); std::shared_ptr<Peer> peer = peerStorage_->checkoutPeer(ncuid);
// sanity check // sanity check
if(peer) { if(peer) {
PeerInitiateConnectionCommand* command; auto command = make_unique<PeerInitiateConnectionCommand>
command = new PeerInitiateConnectionCommand(ncuid, requestGroup_, peer, (ncuid, requestGroup_, peer, getDownloadEngine(), btRuntime_);
getDownloadEngine(),
btRuntime_);
command->setPeerStorage(peerStorage_); command->setPeerStorage(peerStorage_);
command->setPieceStorage(pieceStorage_); command->setPieceStorage(pieceStorage_);
getDownloadEngine()->addCommand(command); getDownloadEngine()->addCommand(std::move(command));
} }
} }
return true; return true;

View File

@ -115,9 +115,8 @@ bool PeerListenCommand::execute() {
std::shared_ptr<Peer> peer(new Peer(peerInfo.first, peerInfo.second, true)); std::shared_ptr<Peer> peer(new Peer(peerInfo.first, peerInfo.second, true));
cuid_t cuid = e_->newCUID(); cuid_t cuid = e_->newCUID();
Command* command = e_->addCommand(make_unique<ReceiverMSEHandshakeCommand>
new ReceiverMSEHandshakeCommand(cuid, peer, e_, peerSocket); (cuid, peer, e_, peerSocket));
e_->addCommand(command);
A2_LOG_DEBUG(fmt("Accepted the connection from %s:%u.", A2_LOG_DEBUG(fmt("Accepted the connection from %s:%u.",
peer->getIPAddress().c_str(), peer->getIPAddress().c_str(),
peer->getPort())); peer->getPort()));
@ -129,7 +128,7 @@ bool PeerListenCommand::execute() {
ex); ex);
} }
} }
e_->addCommand(this); e_->addCommand(std::unique_ptr<Command>(this));
return false; return false;
} }

View File

@ -142,8 +142,7 @@ bool PeerReceiveHandshakeCommand::executeInternal()
// that the added peer must be checked out. // that the added peer must be checked out.
if(peerStorage->addPeer(getPeer()) && if(peerStorage->addPeer(getPeer()) &&
peerStorage->checkoutPeer(getCuid())) { peerStorage->checkoutPeer(getCuid())) {
PeerInteractionCommand* command = getDownloadEngine()->addCommand(make_unique<PeerInteractionCommand>
new PeerInteractionCommand
(getCuid(), (getCuid(),
downloadContext->getOwnerRequestGroup(), downloadContext->getOwnerRequestGroup(),
getPeer(), getPeer(),
@ -153,8 +152,7 @@ bool PeerReceiveHandshakeCommand::executeInternal()
peerStorage, peerStorage,
getSocket(), getSocket(),
PeerInteractionCommand::RECEIVER_WAIT_HANDSHAKE, PeerInteractionCommand::RECEIVER_WAIT_HANDSHAKE,
peerConnection_); peerConnection_));
getDownloadEngine()->addCommand(command);
A2_LOG_DEBUG(fmt(MSG_INCOMING_PEER_CONNECTION, A2_LOG_DEBUG(fmt(MSG_INCOMING_PEER_CONNECTION,
getCuid(), getCuid(),
getPeer()->usedBy())); getPeer()->usedBy()));
@ -162,7 +160,7 @@ bool PeerReceiveHandshakeCommand::executeInternal()
} }
return true; return true;
} else { } else {
getDownloadEngine()->addCommand(this); addCommandSelf();
return false; return false;
} }
} }

View File

@ -42,8 +42,8 @@ namespace aria2 {
PieceHashCheckIntegrityEntry::PieceHashCheckIntegrityEntry PieceHashCheckIntegrityEntry::PieceHashCheckIntegrityEntry
(RequestGroup* requestGroup, (RequestGroup* requestGroup,
Command* nextCommand): std::unique_ptr<Command> nextCommand):
CheckIntegrityEntry(requestGroup, nextCommand) {} CheckIntegrityEntry(requestGroup, std::move(nextCommand)) {}
PieceHashCheckIntegrityEntry::~PieceHashCheckIntegrityEntry() {} PieceHashCheckIntegrityEntry::~PieceHashCheckIntegrityEntry() {}

View File

@ -42,7 +42,9 @@ namespace aria2 {
class PieceHashCheckIntegrityEntry : public CheckIntegrityEntry class PieceHashCheckIntegrityEntry : public CheckIntegrityEntry
{ {
public: public:
PieceHashCheckIntegrityEntry(RequestGroup* requestGroup, Command* nextCommand = 0); PieceHashCheckIntegrityEntry(RequestGroup* requestGroup,
std::unique_ptr<Command> nextCommand =
std::unique_ptr<Command>());
virtual ~PieceHashCheckIntegrityEntry(); virtual ~PieceHashCheckIntegrityEntry();

View File

@ -107,12 +107,12 @@ bool ReceiverMSEHandshakeCommand::executeInternal()
(new PeerConnection(getCuid(), getPeer(), getSocket())); (new PeerConnection(getCuid(), getPeer(), getSocket()));
peerConnection->presetBuffer(mseHandshake_->getBuffer(), peerConnection->presetBuffer(mseHandshake_->getBuffer(),
mseHandshake_->getBufferLength()); mseHandshake_->getBufferLength());
Command* c = new PeerReceiveHandshakeCommand(getCuid(), getDownloadEngine()->addCommand
getPeer(), (make_unique<PeerReceiveHandshakeCommand>(getCuid(),
getDownloadEngine(), getPeer(),
getSocket(), getDownloadEngine(),
peerConnection); getSocket(),
getDownloadEngine()->addCommand(c); peerConnection));
return true; return true;
} }
default: default:
@ -200,7 +200,7 @@ bool ReceiverMSEHandshakeCommand::executeInternal()
} else { } else {
disableWriteCheckSocket(); disableWriteCheckSocket();
} }
getDownloadEngine()->addCommand(this); addCommandSelf();
return false; return false;
} }
@ -219,10 +219,9 @@ void ReceiverMSEHandshakeCommand::createCommand()
// TODO add mseHandshake_->getInfoHash() to PeerReceiveHandshakeCommand // TODO add mseHandshake_->getInfoHash() to PeerReceiveHandshakeCommand
// as a hint. If this info hash and one in BitTorrent Handshake does not // as a hint. If this info hash and one in BitTorrent Handshake does not
// match, then drop connection. // match, then drop connection.
Command* c = getDownloadEngine()->addCommand(make_unique<PeerReceiveHandshakeCommand>
new PeerReceiveHandshakeCommand(getCuid(), getPeer(), getDownloadEngine(), (getCuid(), getPeer(), getDownloadEngine(),
getSocket(), peerConnection); getSocket(), peerConnection));
getDownloadEngine()->addCommand(c);
} }
} // namespace aria2 } // namespace aria2

View File

@ -277,7 +277,7 @@ std::shared_ptr<CheckIntegrityEntry> RequestGroup::createCheckIntegrityEntry()
} }
void RequestGroup::createInitialCommand void RequestGroup::createInitialCommand
(std::vector<Command*>& commands, DownloadEngine* e) (std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
{ {
// Start session timer here. When file size becomes known, it will // Start session timer here. When file size becomes known, it will
// be reset again in *FileAllocationEntry, because hash check and // be reset again in *FileAllocationEntry, because hash check and
@ -369,15 +369,11 @@ void RequestGroup::createInitialCommand
(!e->getOption()->getAsBool(PREF_DISABLE_IPV6) && (!e->getOption()->getAsBool(PREF_DISABLE_IPV6) &&
option_->getAsBool(PREF_ENABLE_DHT6))) { option_->getAsBool(PREF_ENABLE_DHT6))) {
if(option_->getAsBool(PREF_ENABLE_DHT)) { if(option_->getAsBool(PREF_ENABLE_DHT)) {
std::vector<Command*> dhtCommands; e->addCommand(DHTSetup().setup(e, AF_INET));
DHTSetup().setup(dhtCommands, e, AF_INET);
e->addCommand(dhtCommands);
} }
if(!e->getOption()->getAsBool(PREF_DISABLE_IPV6) && if(!e->getOption()->getAsBool(PREF_DISABLE_IPV6) &&
option_->getAsBool(PREF_ENABLE_DHT6)) { option_->getAsBool(PREF_ENABLE_DHT6)) {
std::vector<Command*> dhtCommands; e->addCommand(DHTSetup().setup(e, AF_INET6));
DHTSetup().setup(dhtCommands, e, AF_INET6);
e->addCommand(dhtCommands);
} }
} else { } else {
A2_LOG_NOTICE(_("For BitTorrent Magnet URI, enabling DHT is strongly" A2_LOG_NOTICE(_("For BitTorrent Magnet URI, enabling DHT is strongly"
@ -439,27 +435,23 @@ void RequestGroup::createInitialCommand
(!e->getOption()->getAsBool(PREF_DISABLE_IPV6) && (!e->getOption()->getAsBool(PREF_DISABLE_IPV6) &&
option_->getAsBool(PREF_ENABLE_DHT6)))) { option_->getAsBool(PREF_ENABLE_DHT6)))) {
if(option_->getAsBool(PREF_ENABLE_DHT)) { if(option_->getAsBool(PREF_ENABLE_DHT)) {
std::vector<Command*> dhtCommands; e->addCommand(DHTSetup().setup(e, AF_INET));
DHTSetup().setup(dhtCommands, e, AF_INET);
e->addCommand(dhtCommands);
} }
if(!e->getOption()->getAsBool(PREF_DISABLE_IPV6) && if(!e->getOption()->getAsBool(PREF_DISABLE_IPV6) &&
option_->getAsBool(PREF_ENABLE_DHT6)) { option_->getAsBool(PREF_ENABLE_DHT6)) {
std::vector<Command*> dhtCommands; e->addCommand(DHTSetup().setup(e, AF_INET6));
DHTSetup().setup(dhtCommands, e, AF_INET6);
e->addCommand(dhtCommands);
} }
const std::vector<std::pair<std::string, uint16_t> >& nodes = const std::vector<std::pair<std::string, uint16_t> >& nodes =
torrentAttrs->nodes; torrentAttrs->nodes;
// TODO Are nodes in torrent IPv4 only? // TODO Are nodes in torrent IPv4 only?
if(!nodes.empty() && DHTRegistry::isInitialized()) { if(!nodes.empty() && DHTRegistry::isInitialized()) {
DHTEntryPointNameResolveCommand* command = auto command = make_unique<DHTEntryPointNameResolveCommand>
new DHTEntryPointNameResolveCommand(e->newCUID(), e, nodes); (e->newCUID(), e, nodes);
command->setTaskQueue(DHTRegistry::getData().taskQueue); command->setTaskQueue(DHTRegistry::getData().taskQueue);
command->setTaskFactory(DHTRegistry::getData().taskFactory); command->setTaskFactory(DHTRegistry::getData().taskFactory);
command->setRoutingTable(DHTRegistry::getData().routingTable); command->setRoutingTable(DHTRegistry::getData().routingTable);
command->setLocalNode(DHTRegistry::getData().localNode); command->setLocalNode(DHTRegistry::getData().localNode);
e->addCommand(command); e->addCommand(std::move(command));
} }
} }
std::shared_ptr<CheckIntegrityEntry> entry(new BtCheckIntegrityEntry(this)); std::shared_ptr<CheckIntegrityEntry> entry(new BtCheckIntegrityEntry(this));
@ -553,7 +545,7 @@ void RequestGroup::createInitialCommand
} }
void RequestGroup::processCheckIntegrityEntry void RequestGroup::processCheckIntegrityEntry
(std::vector<Command*>& commands, (std::vector<std::unique_ptr<Command>>& commands,
const std::shared_ptr<CheckIntegrityEntry>& entry, const std::shared_ptr<CheckIntegrityEntry>& entry,
DownloadEngine* e) DownloadEngine* e)
{ {
@ -804,8 +796,9 @@ bool RequestGroup::tryAutoFileRenaming()
return false; return false;
} }
void RequestGroup::createNextCommandWithAdj(std::vector<Command*>& commands, void RequestGroup::createNextCommandWithAdj
DownloadEngine* e, int numAdj) (std::vector<std::unique_ptr<Command>>& commands,
DownloadEngine* e, int numAdj)
{ {
int numCommand; int numCommand;
if(getTotalLength() == 0) { if(getTotalLength() == 0) {
@ -820,8 +813,9 @@ void RequestGroup::createNextCommandWithAdj(std::vector<Command*>& commands,
} }
} }
void RequestGroup::createNextCommand(std::vector<Command*>& commands, void RequestGroup::createNextCommand
DownloadEngine* e) (std::vector<std::unique_ptr<Command>>& commands,
DownloadEngine* e)
{ {
int numCommand; int numCommand;
if(getTotalLength() == 0) { if(getTotalLength() == 0) {
@ -844,13 +838,14 @@ void RequestGroup::createNextCommand(std::vector<Command*>& commands,
} }
} }
void RequestGroup::createNextCommand(std::vector<Command*>& commands, void RequestGroup::createNextCommand
DownloadEngine* e, (std::vector<std::unique_ptr<Command>>& commands,
int numCommand) DownloadEngine* e,
int numCommand)
{ {
for(; numCommand > 0; --numCommand) { for(; numCommand > 0; --numCommand) {
Command* command = new CreateRequestCommand(e->newCUID(), this, e); commands.push_back(make_unique<CreateRequestCommand>
commands.push_back(command); (e->newCUID(), this, e));
} }
if(!commands.empty()) { if(!commands.empty()) {
e->setNoWait(true); e->setNoWait(true);

View File

@ -215,16 +215,18 @@ public:
// Returns first bootstrap commands to initiate a download. // Returns first bootstrap commands to initiate a download.
// If this is HTTP/FTP download and file size is unknown, only 1 command // If this is HTTP/FTP download and file size is unknown, only 1 command
// (usually, HttpInitiateConnection or FtpInitiateConnection) will be created. // (usually, HttpInitiateConnection or FtpInitiateConnection) will be created.
void createInitialCommand(std::vector<Command*>& commands, void createInitialCommand(std::vector<std::unique_ptr<Command>>& commands,
DownloadEngine* e); DownloadEngine* e);
void createNextCommandWithAdj(std::vector<Command*>& commands, void createNextCommandWithAdj
DownloadEngine* e, int numAdj); (std::vector<std::unique_ptr<Command>>& commands,
DownloadEngine* e, int numAdj);
void createNextCommand(std::vector<Command*>& commands, void createNextCommand(std::vector<std::unique_ptr<Command>>& commands,
DownloadEngine* e, int numCommand); DownloadEngine* e, int numCommand);
void createNextCommand(std::vector<Command*>& commands, DownloadEngine* e); void createNextCommand(std::vector<std::unique_ptr<Command>>& commands,
DownloadEngine* e);
bool downloadFinished() const; bool downloadFinished() const;
@ -383,9 +385,10 @@ public:
void clearPreDownloadHandler(); void clearPreDownloadHandler();
void processCheckIntegrityEntry(std::vector<Command*>& commands, void processCheckIntegrityEntry
const std::shared_ptr<CheckIntegrityEntry>& entry, (std::vector<std::unique_ptr<Command>>& commands,
DownloadEngine* e); const std::shared_ptr<CheckIntegrityEntry>& entry,
DownloadEngine* e);
// Initializes pieceStorage_ and segmentMan_. We guarantee that // Initializes pieceStorage_ and segmentMan_. We guarantee that
// either both of pieceStorage_ and segmentMan_ are initialized or // either both of pieceStorage_ and segmentMan_ are initialized or

View File

@ -40,9 +40,9 @@
namespace aria2 { namespace aria2 {
RequestGroupEntry::RequestGroupEntry(RequestGroup* requestGroup, RequestGroupEntry::RequestGroupEntry(RequestGroup* requestGroup,
Command* nextCommand): std::unique_ptr<Command> nextCommand):
requestGroup_(requestGroup), requestGroup_(requestGroup),
nextCommand_(nextCommand) nextCommand_(std::move(nextCommand))
{ {
requestGroup_->increaseNumCommand(); requestGroup_->increaseNumCommand();
} }
@ -50,20 +50,16 @@ RequestGroupEntry::RequestGroupEntry(RequestGroup* requestGroup,
RequestGroupEntry::~RequestGroupEntry() RequestGroupEntry::~RequestGroupEntry()
{ {
requestGroup_->decreaseNumCommand(); requestGroup_->decreaseNumCommand();
delete nextCommand_;
} }
Command* RequestGroupEntry::popNextCommand() std::unique_ptr<Command> RequestGroupEntry::popNextCommand()
{ {
Command* temp = nextCommand_; return std::move(nextCommand_);
nextCommand_ = 0;
return temp;
} }
void RequestGroupEntry::pushNextCommand(Command* nextCommand) void RequestGroupEntry::pushNextCommand(std::unique_ptr<Command> nextCommand)
{ {
delete nextCommand_; nextCommand_ = std::move(nextCommand);
nextCommand_ = nextCommand;
} }
} // namespace aria2 } // namespace aria2

View File

@ -37,6 +37,8 @@
#include "common.h" #include "common.h"
#include <memory>
namespace aria2 { namespace aria2 {
class RequestGroup; class RequestGroup;
@ -45,10 +47,11 @@ class Command;
class RequestGroupEntry { class RequestGroupEntry {
private: private:
RequestGroup* requestGroup_; RequestGroup* requestGroup_;
Command* nextCommand_; std::unique_ptr<Command> nextCommand_;
public: public:
RequestGroupEntry(RequestGroup* requestGroup, RequestGroupEntry(RequestGroup* requestGroup,
Command* nextCommand = 0); std::unique_ptr<Command> nextCommand =
std::unique_ptr<Command>());
virtual ~RequestGroupEntry(); virtual ~RequestGroupEntry();
@ -59,12 +62,12 @@ public:
Command* getNextCommand() const Command* getNextCommand() const
{ {
return nextCommand_; return nextCommand_.get();
} }
Command* popNextCommand(); std::unique_ptr<Command> popNextCommand();
void pushNextCommand(Command* nextCommand); void pushNextCommand(std::unique_ptr<Command> nextCommand);
bool operator==(const RequestGroupEntry& entry) const bool operator==(const RequestGroupEntry& entry) const
{ {

View File

@ -438,11 +438,12 @@ void RequestGroupMan::configureRequestGroup
} }
namespace { namespace {
void createInitialCommand(const std::shared_ptr<RequestGroup>& requestGroup, std::vector<std::unique_ptr<Command>> createInitialCommand
std::vector<Command*>& commands, (const std::shared_ptr<RequestGroup>& requestGroup, DownloadEngine* e)
DownloadEngine* e)
{ {
requestGroup->createInitialCommand(commands, e); std::vector<std::unique_ptr<Command>> res;
requestGroup->createInitialCommand(res, e);
return res;
} }
} // namespace } // namespace
@ -483,24 +484,21 @@ void RequestGroupMan::fillRequestGroupFromReserver(DownloadEngine* e)
groupToAdd->dropPieceStorage(); groupToAdd->dropPieceStorage();
configureRequestGroup(groupToAdd); configureRequestGroup(groupToAdd);
groupToAdd->setRequestGroupMan(this); groupToAdd->setRequestGroupMan(this);
std::vector<Command*> commands;
try { try {
createInitialCommand(groupToAdd, commands, e); auto res = createInitialCommand(groupToAdd, e);
++count; ++count;
if(res.empty()) {
requestQueueCheck();
} else {
e->addCommand(std::move(res));
}
} catch(RecoverableException& ex) { } catch(RecoverableException& ex) {
A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, ex); A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, ex);
A2_LOG_DEBUG("Deleting temporal commands."); A2_LOG_DEBUG("Deleting temporal commands.");
std::for_each(commands.begin(), commands.end(), Deleter());
commands.clear();
A2_LOG_DEBUG("Commands deleted");
groupToAdd->setLastErrorCode(ex.getErrorCode()); groupToAdd->setLastErrorCode(ex.getErrorCode());
// We add groupToAdd to e later in order to it is processed in // We add groupToAdd to e later in order to it is processed in
// removeStoppedGroup(). // removeStoppedGroup().
}
if(commands.empty()) {
requestQueueCheck(); requestQueueCheck();
} else {
e->addCommand(commands);
} }
groupToAdd->setState(RequestGroup::STATE_ACTIVE); groupToAdd->setState(RequestGroup::STATE_ACTIVE);
requestGroups_.push_back(groupToAdd->getGID(), groupToAdd); requestGroups_.push_back(groupToAdd->getGID(), groupToAdd);

View File

@ -1312,9 +1312,9 @@ std::shared_ptr<ValueBase> ChangeUriRpcMethod::process
} }
} }
if(addcount && group->getPieceStorage()) { if(addcount && group->getPieceStorage()) {
std::vector<Command*> commands; std::vector<std::unique_ptr<Command>> commands;
group->createNextCommand(commands, e); group->createNextCommand(commands, e);
e->addCommand(commands); e->addCommand(std::move(commands));
group->getSegmentMan()->recognizeSegmentFor(s); group->getSegmentMan()->recognizeSegmentFor(s);
} }
std::shared_ptr<List> res = List::g(); std::shared_ptr<List> res = List::g();
@ -1329,7 +1329,8 @@ std::shared_ptr<ValueBase> goingShutdown
{ {
// Schedule shutdown after 3seconds to give time to client to // Schedule shutdown after 3seconds to give time to client to
// receive RPC response. // receive RPC response.
e->addRoutineCommand(new TimedHaltCommand(e->newCUID(), e, 3, forceHalt)); e->addRoutineCommand(make_unique<TimedHaltCommand>
(e->newCUID(), e, 3, forceHalt));
A2_LOG_INFO("Scheduled shutdown in 3 seconds."); A2_LOG_INFO("Scheduled shutdown in 3 seconds.");
return VLB_OK; return VLB_OK;
} }

View File

@ -84,7 +84,7 @@ bool SeedCheckCommand::execute() {
btRuntime_->setHalt(true); btRuntime_->setHalt(true);
} }
} }
e_->addCommand(this); e_->addCommand(std::unique_ptr<Command>(this));
return false; return false;
} }

View File

@ -78,12 +78,13 @@ public:
e_->setNoWait(true); e_->setNoWait(true);
} }
e_->addRoutineCommand(this); e_->addRoutineCommand(std::unique_ptr<Command>(this));
return false; return false;
} }
protected: protected:
virtual Command* createCommand(const std::shared_ptr<T>& entry) = 0; virtual std::unique_ptr<Command> createCommand
(const std::shared_ptr<T>& entry) = 0;
}; };
} // namespace aria2 } // namespace aria2

View File

@ -1,67 +0,0 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "SleepCommand.h"
#include "RequestGroup.h"
#include "DownloadEngine.h"
#include "wallclock.h"
namespace aria2 {
SleepCommand::SleepCommand(cuid_t cuid, DownloadEngine* e,
RequestGroup* requestGroup,
Command* nextCommand, time_t wait):
Command(cuid), engine_(e), requestGroup_(requestGroup),
nextCommand_(nextCommand), wait_(wait), checkPoint_(global::wallclock()) {}
SleepCommand::~SleepCommand() {
delete nextCommand_;
}
bool SleepCommand::execute() {
if(requestGroup_->downloadFinished() || requestGroup_->isHaltRequested()) {
return true;
} else if(checkPoint_.differenceInMillis(global::wallclock())+A2_DELTA_MILLIS
>= wait_*1000) {
engine_->addCommand(nextCommand_);
nextCommand_ = 0;
engine_->setNoWait(true);
return true;
} else {
engine_->addCommand(this);
return false;
}
}
} // namespace aria2

View File

@ -1,62 +0,0 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef D_SLEEP_COMMAND_H
#define D_SLEEP_COMMAND_H
#include "Command.h"
#include "TimerA2.h"
namespace aria2 {
class DownloadEngine;
class RequestGroup;
class SleepCommand:public Command {
private:
DownloadEngine* engine_;
RequestGroup* requestGroup_;
Command* nextCommand_;
time_t wait_;
Timer checkPoint_;
public:
SleepCommand(cuid_t cuid, DownloadEngine* e, RequestGroup* requestGroup,
Command* nextCommand, time_t wait);
virtual ~SleepCommand();
bool execute();
};
} // namespace aria2
#endif // D_SLEEP_COMMAND_H

View File

@ -42,15 +42,15 @@
namespace aria2 { namespace aria2 {
StreamCheckIntegrityEntry::StreamCheckIntegrityEntry(RequestGroup* requestGroup, StreamCheckIntegrityEntry::StreamCheckIntegrityEntry
Command* nextCommand): (RequestGroup* requestGroup, std::unique_ptr<Command> nextCommand):
PieceHashCheckIntegrityEntry(requestGroup, nextCommand) PieceHashCheckIntegrityEntry(requestGroup, std::move(nextCommand))
{} {}
StreamCheckIntegrityEntry::~StreamCheckIntegrityEntry() {} StreamCheckIntegrityEntry::~StreamCheckIntegrityEntry() {}
void StreamCheckIntegrityEntry::onDownloadIncomplete void StreamCheckIntegrityEntry::onDownloadIncomplete
(std::vector<Command*>& commands, DownloadEngine* e) (std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
{ {
const std::shared_ptr<PieceStorage>& ps = getRequestGroup()->getPieceStorage(); const std::shared_ptr<PieceStorage>& ps = getRequestGroup()->getPieceStorage();
ps->onDownloadIncomplete(); ps->onDownloadIncomplete();
@ -63,7 +63,7 @@ void StreamCheckIntegrityEntry::onDownloadIncomplete
} }
void StreamCheckIntegrityEntry::onDownloadFinished void StreamCheckIntegrityEntry::onDownloadFinished
(std::vector<Command*>& commands, DownloadEngine* e) (std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
{} {}
} // namespace aria2 } // namespace aria2

View File

@ -43,15 +43,16 @@ class StreamCheckIntegrityEntry:public PieceHashCheckIntegrityEntry
{ {
public: public:
StreamCheckIntegrityEntry(RequestGroup* requestGroup, StreamCheckIntegrityEntry(RequestGroup* requestGroup,
Command* nextCommand = 0); std::unique_ptr<Command> nextCommand =
std::unique_ptr<Command>());
virtual ~StreamCheckIntegrityEntry(); virtual ~StreamCheckIntegrityEntry();
virtual void onDownloadFinished(std::vector<Command*>& commands, virtual void onDownloadFinished
DownloadEngine* e); (std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e);
virtual void onDownloadIncomplete(std::vector<Command*>& commands, virtual void onDownloadIncomplete
DownloadEngine* e); (std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e);
}; };
} // namespace aria2 } // namespace aria2

View File

@ -49,15 +49,15 @@
namespace aria2 { namespace aria2 {
StreamFileAllocationEntry::StreamFileAllocationEntry(RequestGroup* requestGroup, StreamFileAllocationEntry::StreamFileAllocationEntry
Command* nextCommand): (RequestGroup* requestGroup, std::unique_ptr<Command> nextCommand):
FileAllocationEntry(requestGroup, nextCommand) FileAllocationEntry(requestGroup, std::move(nextCommand))
{} {}
StreamFileAllocationEntry::~StreamFileAllocationEntry() {} StreamFileAllocationEntry::~StreamFileAllocationEntry() {}
void StreamFileAllocationEntry::prepareForNextAction void StreamFileAllocationEntry::prepareForNextAction
(std::vector<Command*>& commands, (std::vector<std::unique_ptr<Command>>& commands,
DownloadEngine* e) DownloadEngine* e)
{ {
// For DownloadContext::resetDownloadStartTime(), see also // For DownloadContext::resetDownloadStartTime(), see also

View File

@ -42,12 +42,14 @@ namespace aria2 {
class StreamFileAllocationEntry : public FileAllocationEntry { class StreamFileAllocationEntry : public FileAllocationEntry {
public: public:
StreamFileAllocationEntry(RequestGroup* requestGroup, StreamFileAllocationEntry(RequestGroup* requestGroup,
Command* nextCommand = 0); std::unique_ptr<Command> nextCommand =
std::unique_ptr<Command>());
virtual ~StreamFileAllocationEntry(); virtual ~StreamFileAllocationEntry();
virtual void prepareForNextAction(std::vector<Command*>& commands, virtual void prepareForNextAction
DownloadEngine* e); (std::vector<std::unique_ptr<Command>>& commands,
DownloadEngine* e);
}; };
} // namespace aria2 } // namespace aria2

View File

@ -64,9 +64,9 @@ bool TimeBasedCommand::execute()
return true; return true;
} }
if(routineCommand_) { if(routineCommand_) {
e_->addRoutineCommand(this); e_->addRoutineCommand(std::unique_ptr<Command>(this));
} else { } else {
e_->addCommand(this); e_->addCommand(std::unique_ptr<Command>(this));
} }
return false; return false;
} }

Some files were not shown because too many files have changed in this diff Show More