Browse Source

2010-01-12 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	Fixed memory leak. Commands stored in std::deque<Command*> are not
	deleted when exception is thrown. Make sure that when passing
	std::deque<Command*> to function to store Commands, handle
	exception and delete these Commands.
	* src/AbstractCommand.cc
	* src/CheckIntegrityCommand.cc
	* src/FileAllocationCommand.cc
	* src/RequestGroup.cc
	* src/TrackerWatcherCommand.cc
Tatsuhiro Tsujikawa 15 years ago
parent
commit
f3b1defc97

+ 12 - 0
ChangeLog

@@ -1,3 +1,15 @@
+2010-01-12  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Fixed memory leak. Commands stored in std::deque<Command*> are not
+	deleted when exception is thrown. Make sure that when passing
+	std::deque<Command*> to function to store Commands, handle
+	exception and delete these Commands.
+	* src/AbstractCommand.cc
+	* src/CheckIntegrityCommand.cc
+	* src/FileAllocationCommand.cc
+	* src/RequestGroup.cc
+	* src/TrackerWatcherCommand.cc
+
 2010-01-11  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 
 	Replaced '/' and '_' with '_' in HTTP/FTP filename.

+ 6 - 2
src/AbstractCommand.cc

@@ -530,8 +530,12 @@ void AbstractCommand::prepareForNextAction(Command* nextCommand)
     (new StreamCheckIntegrityEntry(_requestGroup, nextCommand));
 
   std::deque<Command*> commands;
-  _requestGroup->processCheckIntegrityEntry(commands, entry, e);
-
+  try {
+    _requestGroup->processCheckIntegrityEntry(commands, entry, e);
+  } catch(RecoverableException& e) {
+    std::for_each(commands.begin(), commands.end(), Deleter());
+    throw;
+  }
   e->addCommand(commands);
   e->setNoWait(true);
 }

+ 14 - 2
src/CheckIntegrityCommand.cc

@@ -40,6 +40,8 @@
 #include "message.h"
 #include "prefs.h"
 #include "DownloadContext.h"
+#include "a2functional.h"
+#include "RecoverableException.h"
 
 namespace aria2 {
 
@@ -68,13 +70,23 @@ bool CheckIntegrityCommand::executeInternal()
       logger->notice(MSG_VERIFICATION_SUCCESSFUL,
                      _requestGroup->getDownloadContext()->getBasePath().c_str());
       std::deque<Command*> commands;
-      _entry->onDownloadFinished(commands, _e);
+      try {
+        _entry->onDownloadFinished(commands, _e);
+      } catch(RecoverableException& e) {
+        std::for_each(commands.begin(), commands.end(), Deleter());
+        throw;
+      }
       _e->addCommand(commands);
     } else {
       logger->error(MSG_VERIFICATION_FAILED,
                     _requestGroup->getDownloadContext()->getBasePath().c_str());
       std::deque<Command*> commands;
-      _entry->onDownloadIncomplete(commands,_e);
+      try {
+        _entry->onDownloadIncomplete(commands,_e);
+      } catch(RecoverableException& e) {
+        std::for_each(commands.begin(), commands.end(), Deleter());
+        throw;
+      }
       _e->addCommand(commands);
     }
     _e->setNoWait(true);

+ 8 - 1
src/FileAllocationCommand.cc

@@ -43,6 +43,8 @@
 #include "util.h"
 #include "DownloadEngine.h"
 #include "DownloadContext.h"
+#include "a2functional.h"
+#include "RecoverableException.h"
 
 namespace aria2 {
 
@@ -65,7 +67,12 @@ bool FileAllocationCommand::executeInternal()
     _e->_fileAllocationMan->dropPickedEntry();
     
     std::deque<Command*> commands;
-    _fileAllocationEntry->prepareForNextAction(commands, _e);
+    try {
+      _fileAllocationEntry->prepareForNextAction(commands, _e);
+    } catch(RecoverableException& e) {
+      std::for_each(commands.begin(), commands.end(), Deleter());
+      throw;
+    }
     _e->addCommand(commands);
     _e->setNoWait(true);
     return true;

+ 3 - 3
src/RequestGroup.cc

@@ -346,9 +346,9 @@ void RequestGroup::createInitialCommand
 
       if(torrentAttrs[bittorrent::PRIVATE].i() == 0 &&
          _option->getAsBool(PREF_ENABLE_DHT)) {
-        std::deque<Command*> commands;
-        DHTSetup().setup(commands, e, _option.get());
-        e->addCommand(commands);
+        std::deque<Command*> dhtCommands;
+        DHTSetup().setup(dhtCommands, e, _option.get());
+        e->addCommand(dhtCommands);
         if(!torrentAttrs[bittorrent::NODES].empty() && DHTSetup::initialized()) {
           std::deque<std::pair<std::string, uint16_t> > entryPoints;
           const BDE& nodes = torrentAttrs[bittorrent::NODES];

+ 8 - 1
src/TrackerWatcherCommand.cc

@@ -59,6 +59,7 @@
 #include "AnnounceTier.h"
 #include "DownloadContext.h"
 #include "bittorrent_helper.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -97,7 +98,13 @@ bool TrackerWatcherCommand::execute() {
     _trackerRequestGroup = createAnnounce();
     if(!_trackerRequestGroup.isNull()) {
       std::deque<Command*> commands;
-      _trackerRequestGroup->createInitialCommand(commands, e);
+      try {
+        _trackerRequestGroup->createInitialCommand(commands, e);
+      } catch(RecoverableException& ex) {
+        logger->error(EX_EXCEPTION_CAUGHT, ex);
+        std::for_each(commands.begin(), commands.end(), Deleter());
+        commands.clear();
+      }
       e->addCommand(commands);
       logger->debug("added tracker request command");
     }