diff --git a/ChangeLog b/ChangeLog index 9c8989a3..e55adefa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2008-02-11 Tatsuhiro Tsujikawa + + Added the ability to stop aria2 itself when given time has passed + from start. Use --stop option to specify time in minutes. + When 0 is given, this feature is disabled. + * src/OptionHandlerFactory.cc + * src/TimeBasedCommand.h: Make _interval protected scope. + * src/HelpItemFactory.cc + * src/option_processing.cc + * src/prefs.h + * src/FillRequestGroupCommand.cc: Evaluate _e->isHaltRequested() + before calling RequestGroupMan::fillRequestGroupFromReserver(). + Without this modification, the result list shows "ERR" when aria2 is + stopped by --stop option. It should be "INPR". + * src/DownloadEngine.{h, cc} + * src/DownloadEngineFactory.cc + * src/usage_text.h + * src/TimedHaltCommand.{h, cc}: New class. + 2008-02-11 Tatsuhiro Tsujikawa Bootstrap through node added by port message. diff --git a/src/DownloadEngine.cc b/src/DownloadEngine.cc index da24c057..03e01590 100644 --- a/src/DownloadEngine.cc +++ b/src/DownloadEngine.cc @@ -293,8 +293,7 @@ void DownloadEngine::afterEachIteration() { if(globalHaltRequested == 1) { logger->notice(_("Shutdown sequence commencing... Press Ctrl-C again for emergency shutdown.")); - _haltRequested = true; - _requestGroupMan->halt(); + requestHalt(); globalHaltRequested = 2; } else if(globalHaltRequested == 3) { logger->notice(_("Emergency shutdown sequence commencing...")); @@ -303,6 +302,12 @@ void DownloadEngine::afterEachIteration() } } +void DownloadEngine::requestHalt() +{ + _haltRequested = true; + _requestGroupMan->halt(); +} + void DownloadEngine::fillCommand() { addCommand(_requestGroupMan->getInitialCommands(this)); diff --git a/src/DownloadEngine.h b/src/DownloadEngine.h index b895a999..fc3c074a 100644 --- a/src/DownloadEngine.h +++ b/src/DownloadEngine.h @@ -161,6 +161,8 @@ public: { return _haltRequested; } + + void requestHalt(); }; typedef SharedHandle DownloadEngineHandle; diff --git a/src/DownloadEngineFactory.cc b/src/DownloadEngineFactory.cc index 33c475ff..308ebc6f 100644 --- a/src/DownloadEngineFactory.cc +++ b/src/DownloadEngineFactory.cc @@ -49,6 +49,7 @@ #include "FileAllocationDispatcherCommand.h" #include "AutoSaveCommand.h" #include "HaveEraseCommand.h" +#include "TimedHaltCommand.h" #include "DownloadResult.h" #include @@ -86,7 +87,12 @@ DownloadEngineFactory::newDownloadEngine(Option* op, e->commands.push_back(new FileAllocationDispatcherCommand(CUIDCounterSingletonHolder::instance()->newID(), e.get())); e->commands.push_back(new AutoSaveCommand(CUIDCounterSingletonHolder::instance()->newID(), e.get(), op->getAsInt(PREF_AUTO_SAVE_INTERVAL))); e->commands.push_back(new HaveEraseCommand(CUIDCounterSingletonHolder::instance()->newID(), e.get(), 10)); - + { + int32_t stopMin = op->getAsInt(PREF_STOP); + if(stopMin > 0) { + e->commands.push_back(new TimedHaltCommand(CUIDCounterSingletonHolder::instance()->newID(), e.get(), stopMin*60)); + } + } return e; } diff --git a/src/FillRequestGroupCommand.cc b/src/FillRequestGroupCommand.cc index 4256b869..0fa2f8ab 100644 --- a/src/FillRequestGroupCommand.cc +++ b/src/FillRequestGroupCommand.cc @@ -56,13 +56,16 @@ FillRequestGroupCommand::~FillRequestGroupCommand() {} bool FillRequestGroupCommand::execute() { + if(_e->isHaltRequested()) { + return true; + } try { _e->_requestGroupMan->fillRequestGroupFromReserver(_e); } catch(RecoverableException* ex) { logger->error(EX_EXCEPTION_CAUGHT, ex); delete ex; } - if(_e->_requestGroupMan->downloadFinished() || _e->isHaltRequested()) { + if(_e->_requestGroupMan->downloadFinished()) { return true; } _e->commands.push_back(this); diff --git a/src/HelpItemFactory.cc b/src/HelpItemFactory.cc index 476c3b27..f94327ca 100644 --- a/src/HelpItemFactory.cc +++ b/src/HelpItemFactory.cc @@ -415,6 +415,11 @@ TagContainerHandle HelpItemFactory::createHelpItems() item->addTag(TAG_ADVANCED); tc->addItem(item); } + { + HelpItemHandle item = new HelpItem(PREF_STOP, TEXT_STOP, "0"); + item->addTag(TAG_ADVANCED); + tc->addItem(item); + } { HelpItemHandle item = new HelpItem("help", TEXT_HELP, TAG_BASIC); char buf[64]; diff --git a/src/Makefile.am b/src/Makefile.am index 80f96b4b..a586223f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -155,7 +155,8 @@ SRCS = Socket.h\ TaggedItem.cc\ TagContainer.cc\ HelpItemFactory.cc\ - SingleFileDownloadContext.cc + SingleFileDownloadContext.cc\ + TimedHaltCommand.cc # debug_new.cpp if ENABLE_MESSAGE_DIGEST diff --git a/src/Makefile.in b/src/Makefile.in index d715506a..6609258f 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -356,7 +356,7 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \ ByteArrayDiskWriter.h ByteArrayDiskWriterFactory.cc \ ServerHost.cc HelpItem.cc TaggedItem.cc TagContainer.cc \ HelpItemFactory.cc SingleFileDownloadContext.cc \ - IteratableChunkChecksumValidator.cc \ + TimedHaltCommand.cc IteratableChunkChecksumValidator.cc \ IteratableChunkChecksumValidator.h \ IteratableChecksumValidator.cc IteratableChecksumValidator.h \ CheckIntegrityCommand.cc CheckIntegrityCommand.h \ @@ -676,11 +676,11 @@ am__objects_14 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \ ByteArrayDiskWriterFactory.$(OBJEXT) ServerHost.$(OBJEXT) \ HelpItem.$(OBJEXT) TaggedItem.$(OBJEXT) TagContainer.$(OBJEXT) \ HelpItemFactory.$(OBJEXT) SingleFileDownloadContext.$(OBJEXT) \ - $(am__objects_1) $(am__objects_2) $(am__objects_3) \ - $(am__objects_4) $(am__objects_5) $(am__objects_6) \ - $(am__objects_7) $(am__objects_8) $(am__objects_9) \ - $(am__objects_10) $(am__objects_11) $(am__objects_12) \ - $(am__objects_13) + TimedHaltCommand.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) $(am__objects_4) $(am__objects_5) \ + $(am__objects_6) $(am__objects_7) $(am__objects_8) \ + $(am__objects_9) $(am__objects_10) $(am__objects_11) \ + $(am__objects_12) $(am__objects_13) am_libaria2c_a_OBJECTS = $(am__objects_14) libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS) am__installdirs = "$(DESTDIR)$(bindir)" @@ -1003,11 +1003,11 @@ SRCS = Socket.h SocketCore.cc SocketCore.h Command.cc Command.h \ ByteArrayDiskWriter.h ByteArrayDiskWriterFactory.cc \ ServerHost.cc HelpItem.cc TaggedItem.cc TagContainer.cc \ HelpItemFactory.cc SingleFileDownloadContext.cc \ - $(am__append_1) $(am__append_2) $(am__append_3) \ - $(am__append_4) $(am__append_5) $(am__append_6) \ - $(am__append_7) $(am__append_8) $(am__append_9) \ - $(am__append_10) $(am__append_11) $(am__append_12) \ - $(am__append_13) + TimedHaltCommand.cc $(am__append_1) $(am__append_2) \ + $(am__append_3) $(am__append_4) $(am__append_5) \ + $(am__append_6) $(am__append_7) $(am__append_8) \ + $(am__append_9) $(am__append_10) $(am__append_11) \ + $(am__append_12) $(am__append_13) noinst_LIBRARIES = libaria2c.a libaria2c_a_SOURCES = $(SRCS) aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\ @@ -1341,6 +1341,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TaggedItem.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeA2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeBasedCommand.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimedHaltCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerWatcherCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TransferStat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/URLMetalinkParserState.Po@am__quote@ diff --git a/src/OptionHandlerFactory.cc b/src/OptionHandlerFactory.cc index ffd74f1b..13aa5b79 100644 --- a/src/OptionHandlerFactory.cc +++ b/src/OptionHandlerFactory.cc @@ -118,7 +118,8 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers() handlers.push_back(new HostPortOptionHandler(PREF_DHT_ENTRY_POINT, PREF_DHT_ENTRY_POINT_HOST, PREF_DHT_ENTRY_POINT_PORT)); - + handlers.push_back(new NumberOptionHandler(PREF_STOP, 0, 35000000)); + return handlers; } diff --git a/src/TimeBasedCommand.h b/src/TimeBasedCommand.h index a2f95a0e..ab0d53c1 100644 --- a/src/TimeBasedCommand.h +++ b/src/TimeBasedCommand.h @@ -55,8 +55,9 @@ protected: * true. */ bool _exit; -private: + int32_t _interval; // unit: sec +private: Time _checkPoint; public: /** diff --git a/src/TimedHaltCommand.cc b/src/TimedHaltCommand.cc new file mode 100644 index 00000000..e29ceee6 --- /dev/null +++ b/src/TimedHaltCommand.cc @@ -0,0 +1,63 @@ +/* */ +#include "TimedHaltCommand.h" +#include "DownloadEngine.h" +#include "RequestGroupMan.h" +#include "Logger.h" + +namespace aria2 { + +TimedHaltCommand::TimedHaltCommand(int32_t cuid, DownloadEngine* e, + int32_t secondsToHalt): + TimeBasedCommand(cuid, e, secondsToHalt) {} + +TimedHaltCommand::~TimedHaltCommand() {} + +void TimedHaltCommand::preProcess() +{ + if(_e->_requestGroupMan->downloadFinished() || _e->isHaltRequested()) { + _exit = true; + } +} + +void TimedHaltCommand::process() +{ + if(!_e->isHaltRequested()) { + logger->notice("%d minutes passed. Stopping application.", _interval/60); + _e->requestHalt(); + } +} + +} // namespace aria2 diff --git a/src/TimedHaltCommand.h b/src/TimedHaltCommand.h new file mode 100644 index 00000000..099e6d73 --- /dev/null +++ b/src/TimedHaltCommand.h @@ -0,0 +1,55 @@ +/* */ +#ifndef _D_TIMED_HALT_COMMAND_H_ +#define _D_TIMED_HALT_COMMAND_H_ + +#include "TimeBasedCommand.h" + +namespace aria2 { + +class TimedHaltCommand:public TimeBasedCommand { +public: + TimedHaltCommand(int32_t cuid, DownloadEngine* e, int32_t secondsToHalt); + + virtual ~TimedHaltCommand(); + + virtual void preProcess(); + + virtual void process(); +}; + +} // namespace aria2 + +#endif // _D_TIMED_HALT_COMMAND_H_ diff --git a/src/option_processing.cc b/src/option_processing.cc index 7bac84dc..165f7a88 100644 --- a/src/option_processing.cc +++ b/src/option_processing.cc @@ -200,6 +200,7 @@ Option* option_processing(int argc, char* const argv[]) { PREF_ALLOW_PIECE_LENGTH_CHANGE, required_argument, &lopt, 211 }, { PREF_NO_CONF, no_argument, &lopt, 212 }, { PREF_CONF_PATH, required_argument, &lopt, 213 }, + { PREF_STOP, required_argument, &lopt, 214 }, #if defined ENABLE_BITTORRENT || ENABLE_METALINK { "show-files", no_argument, NULL, 'S' }, { "select-file", required_argument, &lopt, 21 }, @@ -387,6 +388,9 @@ Option* option_processing(int argc, char* const argv[]) case 213: ucfname = optarg; break; + case 214: + cmdstream << PREF_STOP << "=" << optarg << "\n"; + break; } break; } diff --git a/src/prefs.h b/src/prefs.h index 88426c3c..06fe79f6 100644 --- a/src/prefs.h +++ b/src/prefs.h @@ -124,6 +124,8 @@ #define PREF_NO_CONF "no-conf" // value: string #define PREF_CONF_PATH "conf-path" +// value: 1*digit +#define PREF_STOP "stop" /** * FTP related preferences diff --git a/src/usage_text.h b/src/usage_text.h index 914bacdf..221cc06e 100644 --- a/src/usage_text.h +++ b/src/usage_text.h @@ -317,3 +317,6 @@ _(" -h, --help[=CATEGORY] Print usage and exit.\n"\ _(" --no-conf Disable loading aria2.conf file.") #define TEXT_CONF_PATH \ _(" --conf-path=PATH Change the configuration file path to PATH.") +#define TEXT_STOP \ +_(" --stop=MINUTES Stop application after MINUTES minutes has passed.\n" \ + " If 0 is given, this feature is disabled.")