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.
libaria2
Tatsuhiro Tsujikawa 2013-05-04 23:56:19 +09:00
parent 7d55341fde
commit ebfc5f55e5
6 changed files with 98 additions and 56 deletions

View File

@ -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

View File

@ -49,8 +49,7 @@ KeepRunningCommand::~KeepRunningCommand() {}
bool KeepRunningCommand::execute()
{
if(!e_->getRequestGroupMan()->getKeepRunning() ||
e_->isHaltRequested()) {
if(e_->isHaltRequested()) {
return true;
}
e_->addCommand(this);

View File

@ -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>&

View File

@ -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

View File

@ -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 =

View File

@ -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.