diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Context.cc | 15 | ||||
| -rw-r--r-- | src/KeepRunningCommand.cc | 3 | ||||
| -rw-r--r-- | src/MultiUrlRequestInfo.cc | 69 | ||||
| -rw-r--r-- | src/MultiUrlRequestInfo.h | 9 | ||||
| -rw-r--r-- | src/aria2api.cc | 25 | ||||
| -rw-r--r-- | src/includes/aria2/aria2.h | 33 |
6 files changed, 98 insertions, 56 deletions
diff --git a/src/Context.cc b/src/Context.cc index 81022e24..ad6b1af1 100644 --- a/src/Context.cc +++ b/src/Context.cc @@ -34,7 +34,6 @@ /* copyright --> */ #include "Context.h" -#include <signal.h> #include <unistd.h> #include <getopt.h> @@ -223,20 +222,6 @@ Context::Context(bool standalone, std::string iface = op->get(PREF_INTERFACE); SocketCore::bindAddress(iface); } - sigset_t mask; -#ifdef HAVE_SIGACTION - sigemptyset(&mask); -#else // !HAVE_SIGACTION - mask = 0; -#endif // !HAVE_SIGACTION -#ifdef SIGPIPE - util::setGlobalSignalHandler(SIGPIPE, &mask, SIG_IGN, 0); -#endif -#ifdef SIGCHLD - // Avoid to create zombie process when forked child processes are - // died. - util::setGlobalSignalHandler(SIGCHLD, &mask, SIG_IGN, 0); -#endif // SIGCHILD std::vector<SharedHandle<RequestGroup> > requestGroups; SharedHandle<UriListParser> uriListParser; #ifdef ENABLE_BITTORRENT diff --git a/src/KeepRunningCommand.cc b/src/KeepRunningCommand.cc index f917d5e1..995f3027 100644 --- a/src/KeepRunningCommand.cc +++ b/src/KeepRunningCommand.cc @@ -49,8 +49,7 @@ KeepRunningCommand::~KeepRunningCommand() {} bool KeepRunningCommand::execute() { - if(!e_->getRequestGroupMan()->getKeepRunning() || - e_->isHaltRequested()) { + if(e_->isHaltRequested()) { return true; } e_->addCommand(this); diff --git a/src/MultiUrlRequestInfo.cc b/src/MultiUrlRequestInfo.cc index 5746b748..7d16e33e 100644 --- a/src/MultiUrlRequestInfo.cc +++ b/src/MultiUrlRequestInfo.cc @@ -112,8 +112,9 @@ MultiUrlRequestInfo::MultiUrlRequestInfo : option_(op), statCalc_(statCalc), summaryOut_(summaryOut), - uriListParser_(uriListParser) + uriListParser_(uriListParser), // TODO init mask_ + useSignalHandler_(true) { requestGroups_.swap(requestGroups); } @@ -238,27 +239,15 @@ int MultiUrlRequestInfo::prepare() if(uriListParser_) { e_->getRequestGroupMan()->setUriListParser(uriListParser_); } -#ifdef HAVE_SIGACTION - sigemptyset(&mask_); - sigaddset(&mask_, SIGINT); - sigaddset(&mask_, SIGTERM); -#ifdef SIGHUP - sigaddset(&mask_, SIGHUP); -#endif // SIGHUP -#else // !HAVE_SIGACTION - mask_ = 0; -#endif // !HAVE_SIGACTION - -#ifdef SIGHUP - util::setGlobalSignalHandler(SIGHUP, &mask_, handler, 0); -#endif // SIGHUP - util::setGlobalSignalHandler(SIGINT, &mask_, handler, 0); - util::setGlobalSignalHandler(SIGTERM, &mask_, handler, 0); - + if(useSignalHandler_) { + setupSignalHandlers(); + } e_->getRequestGroupMan()->getNetStat().downloadStart(); } catch(RecoverableException& e) { SingletonHolder<Notifier>::clear(); - resetSignalHandlers(); + if(useSignalHandler_) { + resetSignalHandlers(); + } return -1; } return 0; @@ -319,10 +308,43 @@ error_code::Value MultiUrlRequestInfo::execute() A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, e); } error_code::Value returnValue = getResult(); - resetSignalHandlers(); + if(useSignalHandler_) { + resetSignalHandlers(); + } return returnValue; } +void MultiUrlRequestInfo::setupSignalHandlers() +{ +#ifdef HAVE_SIGACTION + sigemptyset(&mask_); +#else // !HAVE_SIGACTION + mask_ = 0; +#endif // !HAVE_SIGACTION +#ifdef SIGPIPE + util::setGlobalSignalHandler(SIGPIPE, &mask_, SIG_IGN, 0); +#endif // SIGPIPE +#ifdef SIGCHLD + // Avoid to create zombie process when forked child processes are + // died. + util::setGlobalSignalHandler(SIGCHLD, &mask_, SIG_IGN, 0); +#endif // SIGCHILD + +#ifdef HAVE_SIGACTION + sigaddset(&mask_, SIGINT); + sigaddset(&mask_, SIGTERM); +# ifdef SIGHUP + sigaddset(&mask_, SIGHUP); +# endif // SIGHUP +#endif // HAVE_SIGACTION + +#ifdef SIGHUP + util::setGlobalSignalHandler(SIGHUP, &mask_, handler, 0); +#endif // SIGHUP + util::setGlobalSignalHandler(SIGINT, &mask_, handler, 0); + util::setGlobalSignalHandler(SIGTERM, &mask_, handler, 0); +} + void MultiUrlRequestInfo::resetSignalHandlers() { #ifdef HAVE_SIGACTION @@ -333,6 +355,13 @@ void MultiUrlRequestInfo::resetSignalHandlers() #endif // SIGHUP util::setGlobalSignalHandler(SIGINT, &mask_, SIG_DFL, 0); util::setGlobalSignalHandler(SIGTERM, &mask_, SIG_DFL, 0); + +#ifdef SIGCHLD + util::setGlobalSignalHandler(SIGCHLD, &mask_, SIG_DFL, 0); +#endif // SIGCHILD +#ifdef SIGPIPE + util::setGlobalSignalHandler(SIGPIPE, &mask_, SIG_DFL, 0); +#endif // SIGPIPE } const SharedHandle<DownloadEngine>& diff --git a/src/MultiUrlRequestInfo.h b/src/MultiUrlRequestInfo.h index 1d0176dd..6a324af0 100644 --- a/src/MultiUrlRequestInfo.h +++ b/src/MultiUrlRequestInfo.h @@ -70,7 +70,10 @@ private: sigset_t mask_; + bool useSignalHandler_; + void printMessageForContinue(); + void setupSignalHandlers(); void resetSignalHandlers(); public: /* @@ -105,6 +108,12 @@ public: error_code::Value getResult(); const SharedHandle<DownloadEngine>& getDownloadEngine() const; + + // Signal handlers are not prepared if false is given. + void setUseSignalHandler(bool useSignalHandler) + { + useSignalHandler_ = useSignalHandler; + } }; } // namespace aria2 diff --git a/src/aria2api.cc b/src/aria2api.cc index dcf5a007..30f0b02e 100644 --- a/src/aria2api.cc +++ b/src/aria2api.cc @@ -68,6 +68,11 @@ Session::Session(const KeyVals& options) Session::~Session() {} +SessionConfig::SessionConfig() + : keepRunning(false), + useSignalHandler(true) +{} + namespace { Platform* platform = 0; } // namespace @@ -91,7 +96,7 @@ int libraryDeinit() return 0; } -Session* sessionNew(const KeyVals& options) +Session* sessionNew(const KeyVals& options, const SessionConfig& config) { int rv; Session* session; @@ -101,6 +106,9 @@ Session* sessionNew(const KeyVals& options) return 0; } if(session->context->reqinfo) { + if(!config.useSignalHandler) { + session->context->reqinfo->setUseSignalHandler(false); + } rv = session->context->reqinfo->prepare(); if(rv != 0) { delete session; @@ -108,9 +116,11 @@ Session* sessionNew(const KeyVals& options) } const SharedHandle<DownloadEngine>& e = session->context->reqinfo->getDownloadEngine(); - // Add command to make aria2 keep event polling if - // sessionConfigSetKeepRunning is set to true. - e->addCommand(new KeepRunningCommand(e->newCUID(), e.get())); + if(config.keepRunning) { + e->getRequestGroupMan()->setKeepRunning(true); + // Add command to make aria2 keep event polling + e->addCommand(new KeepRunningCommand(e->newCUID(), e.get())); + } } else { delete session; session = 0; @@ -125,13 +135,6 @@ int sessionFinal(Session* session) return rv; } -int sessionConfigSetKeepRunning(Session* session, bool flag) -{ - session->context->reqinfo->getDownloadEngine()->getRequestGroupMan() - ->setKeepRunning(flag); - return 0; -} - int run(Session* session, RUN_MODE mode) { const SharedHandle<DownloadEngine>& e = diff --git a/src/includes/aria2/aria2.h b/src/includes/aria2/aria2.h index 30284e55..add04f47 100644 --- a/src/includes/aria2/aria2.h +++ b/src/includes/aria2/aria2.h @@ -74,6 +74,30 @@ typedef uint64_t A2Gid; // type of Key/Value pairs typedef std::vector<std::pair<std::string, std::string> > KeyVals; +struct SessionConfig { + // The constructor fills default values for all members. + SessionConfig(); + // If the |keepRunning| member is true, run(session, RUN_ONCE) will + // return 1 even if there are no download to perform. The behavior + // is very similar to RPC server, except that this option does not + // enable RPC functionality. To stop aria2, use shutdown() function. + // The default value is false. + bool keepRunning; + // If the |useSignalHandler| is true, the library setups following + // signal handlers in sessionNew(). These signal handlers are + // removed in sessionFinal(). The default value is true. If the + // application sets this member to false, it must handle these + // signals and ensure that run() is repeatedly called until it + // returns 0 and sessionFinal() is called after that. Failing these + // steps will lead to not saving .aria2 control file and no session + // serialization. + // + // SIGPIPE, SIGCHLD: ignored + // SIGHUP, SIGTERM: handled like shutdown(session, true) is called. + // SIGINT: handled like shutdown(session, false) is called. + bool useSignalHandler; +}; + // Creates new Session object using the |options| as additional // parameters. The |options| is treated as if they are specified in // command-line to aria2c(1). This function returns the pointer to the @@ -81,7 +105,7 @@ typedef std::vector<std::pair<std::string, std::string> > KeyVals; // // Please note that only one Session object can be created per // process. -Session* sessionNew(const KeyVals& options); +Session* sessionNew(const KeyVals& options, const SessionConfig& config); // Performs post-download action, including saving sessions etc and // destroys the |session| object, releasing the allocated resources @@ -94,13 +118,6 @@ enum RUN_MODE { RUN_ONCE }; -// If the |flag| is true, run(session, RUN_ONCE) will return 1 even if -// there are no download to perform. The behavior is very similar to -// RPC server, except that this option does not enable RPC -// functionality. To stop aria2, use shutdown() function. This -// function returns 0 if it succeeds, or -1. -int sessionConfigSetKeepRunning(Session* session, bool flag); - // Performs event polling and actions for them. If the |mode| is // RUN_DEFAULT, this function returns when no downloads are left to be // processed. In this case, this function returns 0. |
