2010-06-20 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Use auto_delete_container to delete created Command when exception
	is thrown rather than deleting them in catch block.
	* src/AbstractCommand.cc
	* src/CheckIntegrityCommand.cc
	* src/DHTSetup.cc
	* src/FileAllocationCommand.cc
	* src/TrackerWatcherCommand.cc
	* src/a2functional.h
pull/1/head
Tatsuhiro Tsujikawa 2010-06-20 11:37:47 +00:00
parent cb4e25e4b4
commit 0f0fc5f198
7 changed files with 68 additions and 51 deletions

View File

@ -1,3 +1,14 @@
2010-06-20 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Use auto_delete_container to delete created Command when exception
is thrown rather than deleting them in catch block.
* src/AbstractCommand.cc
* src/CheckIntegrityCommand.cc
* src/DHTSetup.cc
* src/FileAllocationCommand.cc
* src/TrackerWatcherCommand.cc
* src/a2functional.h
2010-06-20 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net> 2010-06-20 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Removed BDE and bencode Removed BDE and bencode

View File

@ -722,14 +722,11 @@ void AbstractCommand::prepareForNextAction(Command* nextCommand)
SharedHandle<CheckIntegrityEntry> entry SharedHandle<CheckIntegrityEntry> entry
(new StreamCheckIntegrityEntry(_requestGroup, nextCommand)); (new StreamCheckIntegrityEntry(_requestGroup, nextCommand));
std::vector<Command*> commands; std::vector<Command*>* commands = new std::vector<Command*>();
try { auto_delete_container<std::vector<Command*> > commandsDel(commands);
_requestGroup->processCheckIntegrityEntry(commands, entry, _e); _requestGroup->processCheckIntegrityEntry(*commands, entry, _e);
} catch(RecoverableException& e) { _e->addCommand(*commands);
std::for_each(commands.begin(), commands.end(), Deleter()); commands->clear();
throw;
}
_e->addCommand(commands);
_e->setNoWait(true); _e->setNoWait(true);
} }

View File

@ -75,26 +75,20 @@ bool CheckIntegrityCommand::executeInternal()
getLogger()->notice getLogger()->notice
(MSG_VERIFICATION_SUCCESSFUL, (MSG_VERIFICATION_SUCCESSFUL,
getRequestGroup()->getDownloadContext()->getBasePath().c_str()); getRequestGroup()->getDownloadContext()->getBasePath().c_str());
std::vector<Command*> commands; std::vector<Command*>* commands = new std::vector<Command*>();
try { auto_delete_container<std::vector<Command*> > commandsDel(commands);
_entry->onDownloadFinished(commands, getDownloadEngine()); _entry->onDownloadFinished(*commands, getDownloadEngine());
} catch(RecoverableException& e) { getDownloadEngine()->addCommand(*commands);
std::for_each(commands.begin(), commands.end(), Deleter()); commands->clear();
throw;
}
getDownloadEngine()->addCommand(commands);
} else { } else {
getLogger()->error getLogger()->error
(MSG_VERIFICATION_FAILED, (MSG_VERIFICATION_FAILED,
getRequestGroup()->getDownloadContext()->getBasePath().c_str()); getRequestGroup()->getDownloadContext()->getBasePath().c_str());
std::vector<Command*> commands; std::vector<Command*>* commands = new std::vector<Command*>();
try { auto_delete_container<std::vector<Command*> > commandsDel(commands);
_entry->onDownloadIncomplete(commands, getDownloadEngine()); _entry->onDownloadIncomplete(*commands, getDownloadEngine());
} catch(RecoverableException& e) { getDownloadEngine()->addCommand(*commands);
std::for_each(commands.begin(), commands.end(), Deleter()); commands->clear();
throw;
}
getDownloadEngine()->addCommand(commands);
} }
getDownloadEngine()->setNoWait(true); getDownloadEngine()->setNoWait(true);
return true; return true;

View File

@ -91,8 +91,9 @@ void DHTSetup::setup(std::vector<Command*>& commands, DownloadEngine* e)
if(_initialized) { if(_initialized) {
return; return;
} }
std::vector<Command*> 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
SharedHandle<DHTNode> localNode; SharedHandle<DHTNode> localNode;
@ -219,7 +220,7 @@ void DHTSetup::setup(std::vector<Command*>& commands, DownloadEngine* e)
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(command);
} }
} else { } else {
_logger->info("No DHT entry point specified."); _logger->info("No DHT entry point specified.");
@ -231,13 +232,13 @@ void DHTSetup::setup(std::vector<Command*>& commands, DownloadEngine* e)
command->setMessageReceiver(receiver); command->setMessageReceiver(receiver);
command->setTaskQueue(taskQueue); command->setTaskQueue(taskQueue);
command->setReadCheckSocket(connection->getSocket()); command->setReadCheckSocket(connection->getSocket());
tempCommands.push_back(command); tempCommands->push_back(command);
} }
{ {
DHTTokenUpdateCommand* command = DHTTokenUpdateCommand* command =
new DHTTokenUpdateCommand(e->newCUID(), e, DHT_TOKEN_UPDATE_INTERVAL); new DHTTokenUpdateCommand(e->newCUID(), e, DHT_TOKEN_UPDATE_INTERVAL);
command->setTokenTracker(tokenTracker); command->setTokenTracker(tokenTracker);
tempCommands.push_back(command); tempCommands->push_back(command);
} }
{ {
DHTBucketRefreshCommand* command = DHTBucketRefreshCommand* command =
@ -246,28 +247,29 @@ void DHTSetup::setup(std::vector<Command*>& commands, DownloadEngine* e)
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(command);
} }
{ {
DHTPeerAnnounceCommand* command = DHTPeerAnnounceCommand* command =
new DHTPeerAnnounceCommand(e->newCUID(), e, new DHTPeerAnnounceCommand(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(command);
} }
{ {
DHTAutoSaveCommand* command = DHTAutoSaveCommand* command =
new DHTAutoSaveCommand(e->newCUID(), e, 30*60); new DHTAutoSaveCommand(e->newCUID(), e, 30*60);
command->setLocalNode(localNode); command->setLocalNode(localNode);
command->setRoutingTable(routingTable); command->setRoutingTable(routingTable);
tempCommands.push_back(command); tempCommands->push_back(command);
} }
_initialized = true; _initialized = true;
commands.insert(commands.end(), tempCommands.begin(), tempCommands.end()); commands.insert(commands.end(), tempCommands->begin(), tempCommands->end());
tempCommands->clear();
} catch(RecoverableException& e) { } catch(RecoverableException& e) {
_logger->error("Exception caught while initializing DHT functionality. DHT is disabled.", e); _logger->error("Exception caught while initializing DHT functionality."
" DHT is disabled.", e);
DHTRegistry::clearData(); DHTRegistry::clearData();
std::for_each(tempCommands.begin(), tempCommands.end(), Deleter());
} }
} }

View File

@ -76,14 +76,11 @@ bool FileAllocationCommand::executeInternal()
} }
getDownloadEngine()->getFileAllocationMan()->dropPickedEntry(); getDownloadEngine()->getFileAllocationMan()->dropPickedEntry();
std::vector<Command*> commands; std::vector<Command*>* commands = new std::vector<Command*>();
try { auto_delete_container<std::vector<Command*> > commandsDel(commands);
_fileAllocationEntry->prepareForNextAction(commands, getDownloadEngine()); _fileAllocationEntry->prepareForNextAction(*commands, getDownloadEngine());
} catch(RecoverableException& e) { getDownloadEngine()->addCommand(*commands);
std::for_each(commands.begin(), commands.end(), Deleter()); commands->clear();
throw;
}
getDownloadEngine()->addCommand(commands);
getDownloadEngine()->setNoWait(true); getDownloadEngine()->setNoWait(true);
return true; return true;
} else { } else {

View File

@ -104,17 +104,17 @@ bool TrackerWatcherCommand::execute() {
if(_trackerRequestGroup.isNull()) { if(_trackerRequestGroup.isNull()) {
_trackerRequestGroup = createAnnounce(); _trackerRequestGroup = createAnnounce();
if(!_trackerRequestGroup.isNull()) { if(!_trackerRequestGroup.isNull()) {
std::vector<Command*> commands;
try { try {
_trackerRequestGroup->createInitialCommand(commands, _e); std::vector<Command*>* commands = new std::vector<Command*>();
auto_delete_container<std::vector<Command*> > commandsDel(commands);
_trackerRequestGroup->createInitialCommand(*commands, _e);
_e->addCommand(*commands);
commands->clear();
if(getLogger()->debug()) {
getLogger()->debug("added tracker request command");
}
} catch(RecoverableException& ex) { } catch(RecoverableException& ex) {
getLogger()->error(EX_EXCEPTION_CAUGHT, ex); getLogger()->error(EX_EXCEPTION_CAUGHT, ex);
std::for_each(commands.begin(), commands.end(), Deleter());
commands.clear();
}
_e->addCommand(commands);
if(getLogger()->debug()) {
getLogger()->debug("added tracker request command");
} }
} }
} else if(_trackerRequestGroup->downloadFinished()){ } else if(_trackerRequestGroup->downloadFinished()){

View File

@ -36,9 +36,11 @@
#define _D_A2_FUNCTIONAL_H_ #define _D_A2_FUNCTIONAL_H_
#include <functional> #include <functional>
#include <string>
#include <algorithm>
#include "SharedHandle.h" #include "SharedHandle.h"
#include "A2STR.h" #include "A2STR.h"
#include <string>
namespace aria2 { namespace aria2 {
@ -204,6 +206,20 @@ public:
} }
}; };
template<class Container>
class auto_delete_container {
private:
Container* _c;
public:
auto_delete_container(Container* c):_c(c) {}
~auto_delete_container()
{
std::for_each(_c->begin(), _c->end(), Deleter());
delete _c;
}
};
template<typename InputIterator, typename DelimiterType> template<typename InputIterator, typename DelimiterType>
std::string strjoin(InputIterator first, InputIterator last, std::string strjoin(InputIterator first, InputIterator last,
const DelimiterType& delim) const DelimiterType& delim)