mirror of https://github.com/aria2/aria2
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
parent
7d55341fde
commit
ebfc5f55e5
|
@ -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
|
||||
|
|
|
@ -49,8 +49,7 @@ KeepRunningCommand::~KeepRunningCommand() {}
|
|||
|
||||
bool KeepRunningCommand::execute()
|
||||
{
|
||||
if(!e_->getRequestGroupMan()->getKeepRunning() ||
|
||||
e_->isHaltRequested()) {
|
||||
if(e_->isHaltRequested()) {
|
||||
return true;
|
||||
}
|
||||
e_->addCommand(this);
|
||||
|
|
|
@ -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>&
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue