summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2013-05-04 23:56:19 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2013-05-04 23:56:19 +0900
commitebfc5f55e50972520ead1fda7cabcdc494c61e3f (patch)
tree28f38146a71ace546d67ac3742b9e91855aed515
parent7d55341fded7b88f528b62a5527f9df8bc3259d8 (diff)
Add SessionConfig to store per Session config
sessionConfigSetKeepRunning() was removed and SessionConfig has keepRunning member instead. Signal handlers are now all prepared in MultiUrlRequestGroup object. Setting SessionConfig.useSignalHandler to false will avoid signal handler setup.
-rw-r--r--src/Context.cc15
-rw-r--r--src/KeepRunningCommand.cc3
-rw-r--r--src/MultiUrlRequestInfo.cc69
-rw-r--r--src/MultiUrlRequestInfo.h9
-rw-r--r--src/aria2api.cc25
-rw-r--r--src/includes/aria2/aria2.h33
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.