enhanded guardProcess() with setpgid() and kill()
This commit is contained in:
parent
1218015572
commit
0dd7cc2d65
@ -88,7 +88,7 @@ public:
|
|||||||
static int setSignalHandler (int sig, SignalHandler sighr);
|
static int setSignalHandler (int sig, SignalHandler sighr);
|
||||||
static int unsetSignalHandler (int sig, bool ignore = false);
|
static int unsetSignalHandler (int sig, bool ignore = false);
|
||||||
|
|
||||||
int guardProcess (const qse_mchar_t* proc_name, const SignalSet& signals);
|
int guardProcess (const SignalSet& signals, const qse_mchar_t* proc_name = QSE_NULL);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
App* _prev_app;
|
App* _prev_app;
|
||||||
@ -116,26 +116,6 @@ protected:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// functor as a template parameter
|
|
||||||
template <typename F>
|
|
||||||
class QSE_EXPORT AppF: public App
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AppF (Mmgr* mmgr = QSE_NULL) QSE_CPP_NOEXCEPT: App(mmgr) {}
|
|
||||||
AppF (const F& f, Mmgr* mmgr = QSE_NULL) QSE_CPP_NOEXCEPT: App(mmgr), __lfunc(f) {}
|
|
||||||
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
|
|
||||||
AppF (F&& f, Mmgr* mmgr = QSE_NULL) QSE_CPP_NOEXCEPT: App(mmgr), __lfunc(QSE_CPP_RVREF(f)) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
protected:
|
|
||||||
F __lfunc;
|
|
||||||
|
|
||||||
void on_signal (int sig)
|
|
||||||
{
|
|
||||||
this->__lfunc(this, sig);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
QSE_END_NAMESPACE(QSE)
|
QSE_END_NAMESPACE(QSE)
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
#include "../cmn/syscall.h"
|
#include "../cmn/syscall.h"
|
||||||
#include <qse/cmn/mbwc.h>
|
#include <qse/cmn/mbwc.h>
|
||||||
|
|
||||||
extern "C" { int printf (const char* fmt, ...); }
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
QSE_BEGIN_NAMESPACE(QSE)
|
QSE_BEGIN_NAMESPACE(QSE)
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
@ -43,7 +42,6 @@ static struct
|
|||||||
sigset_t sa_mask;
|
sigset_t sa_mask;
|
||||||
int sa_flags;
|
int sa_flags;
|
||||||
} g_app_oldsi[QSE_NSIGS] = { { 0, 0 }, };
|
} g_app_oldsi[QSE_NSIGS] = { { 0, 0 }, };
|
||||||
static bool g_app_sigign_on_exit = false;
|
|
||||||
|
|
||||||
class SigScopedMutexLocker
|
class SigScopedMutexLocker
|
||||||
{
|
{
|
||||||
@ -334,7 +332,6 @@ int App::unset_signal_handler_no_mutex(int sig, int ignore)
|
|||||||
|
|
||||||
void App::on_guard_signal (int sig)
|
void App::on_guard_signal (int sig)
|
||||||
{
|
{
|
||||||
printf ("relaying %d to %d\n", sig, (int)this->_guarded_child_pid);
|
|
||||||
::kill (this->_guarded_child_pid, sig);
|
::kill (this->_guarded_child_pid, sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,7 +419,7 @@ int App::set_signal_subscription_no_mutex (int sig, SignalState reqstate)
|
|||||||
return reqstate;
|
return reqstate;
|
||||||
}
|
}
|
||||||
|
|
||||||
int App::guardProcess (const qse_mchar_t* proc_name, const SignalSet& signals)
|
int App::guardProcess (const SignalSet& signals, const qse_mchar_t* proc_name)
|
||||||
{
|
{
|
||||||
SignalState old_ss[QSE_NSIGS];
|
SignalState old_ss[QSE_NSIGS];
|
||||||
|
|
||||||
@ -430,7 +427,11 @@ int App::guardProcess (const qse_mchar_t* proc_name, const SignalSet& signals)
|
|||||||
{
|
{
|
||||||
pid_t pid = ::fork();
|
pid_t pid = ::fork();
|
||||||
if (pid == -1) return -1;
|
if (pid == -1) return -1;
|
||||||
if (pid == 0) break; // child
|
if (pid == 0)
|
||||||
|
{
|
||||||
|
::setpgid (0, 0); // change the process group id.
|
||||||
|
break; // child
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < QSE_NSIGS; i++)
|
for (int i = 0; i < QSE_NSIGS; i++)
|
||||||
{
|
{
|
||||||
@ -460,10 +461,22 @@ int App::guardProcess (const qse_mchar_t* proc_name, const SignalSet& signals)
|
|||||||
if (signals.isSet(i)) this->setSignalSubscription (i, old_ss[i]);
|
if (signals.isSet(i)) this->setSignalSubscription (i, old_ss[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("child exited - exited %d exit status %d\n", WIFEXITED(status), WEXITSTATUS(status));
|
if (WIFEXITED(status))
|
||||||
if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
|
|
||||||
{
|
{
|
||||||
return 0;
|
if (WEXITSTATUS(status) == 0)
|
||||||
|
{
|
||||||
|
// the child has terminated normally and successfully.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// the child process aborted or crashed.
|
||||||
|
// let's kill all other processes in the same process group as the child
|
||||||
|
// but is it safe to do this after waitpid() has been called on 'pid'?
|
||||||
|
// it should be mostly safe because most OSes doesn't reuse the same pid
|
||||||
|
// within a very short time.
|
||||||
|
::kill (-pid, SIGKILL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,9 +81,9 @@ public:
|
|||||||
signals.set (SIGTERM);
|
signals.set (SIGTERM);
|
||||||
signals.set (SIGUSR1);
|
signals.set (SIGUSR1);
|
||||||
signals.set (SIGUSR2);
|
signals.set (SIGUSR2);
|
||||||
if (this->guardProcess("myapp", signals) > 0)
|
if (this->guardProcess(signals) > 0)
|
||||||
{
|
{
|
||||||
qse_printf (QSE_T("Stareting workd\n"));
|
qse_printf (QSE_T("Stareting server\n"));
|
||||||
this->server.setThreadStackSize (256000);
|
this->server.setThreadStackSize (256000);
|
||||||
return this->server.start (QSE_T("[::]:9998,0.0.0.0:9998"));
|
return this->server.start (QSE_T("[::]:9998,0.0.0.0:9998"));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user