From 0dd7cc2d659af5c723bdd27507f4be917377e2f8 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Tue, 11 Sep 2018 15:11:48 +0000 Subject: [PATCH] enhanded guardProcess() with setpgid() and kill() --- qse/include/qse/si/App.hpp | 22 +--------------------- qse/lib/si/App.cpp | 29 +++++++++++++++++++++-------- qse/samples/si/tcpsvr01.cpp | 4 ++-- 3 files changed, 24 insertions(+), 31 deletions(-) diff --git a/qse/include/qse/si/App.hpp b/qse/include/qse/si/App.hpp index 46c083c9..915757c3 100644 --- a/qse/include/qse/si/App.hpp +++ b/qse/include/qse/si/App.hpp @@ -88,7 +88,7 @@ public: static int setSignalHandler (int sig, SignalHandler sighr); 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: App* _prev_app; @@ -116,26 +116,6 @@ protected: }; -// functor as a template parameter -template -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) ///////////////////////////////// diff --git a/qse/lib/si/App.cpp b/qse/lib/si/App.cpp index 58328378..5c122256 100644 --- a/qse/lib/si/App.cpp +++ b/qse/lib/si/App.cpp @@ -30,7 +30,6 @@ #include "../cmn/syscall.h" #include -extern "C" { int printf (const char* fmt, ...); } ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) ///////////////////////////////// @@ -43,7 +42,6 @@ static struct sigset_t sa_mask; int sa_flags; } g_app_oldsi[QSE_NSIGS] = { { 0, 0 }, }; -static bool g_app_sigign_on_exit = false; class SigScopedMutexLocker { @@ -334,7 +332,6 @@ int App::unset_signal_handler_no_mutex(int sig, int ignore) 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); } @@ -422,7 +419,7 @@ int App::set_signal_subscription_no_mutex (int sig, SignalState 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]; @@ -430,7 +427,11 @@ int App::guardProcess (const qse_mchar_t* proc_name, const SignalSet& signals) { pid_t pid = ::fork(); 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++) { @@ -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]); } -printf ("child exited - exited %d exit status %d\n", WIFEXITED(status), WEXITSTATUS(status)); - if (WIFEXITED(status) && WEXITSTATUS(status) == 0) + if (WIFEXITED(status)) { - 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); } } diff --git a/qse/samples/si/tcpsvr01.cpp b/qse/samples/si/tcpsvr01.cpp index e23b6479..44b5e751 100644 --- a/qse/samples/si/tcpsvr01.cpp +++ b/qse/samples/si/tcpsvr01.cpp @@ -81,9 +81,9 @@ public: signals.set (SIGTERM); signals.set (SIGUSR1); 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); return this->server.start (QSE_T("[::]:9998,0.0.0.0:9998")); }