stablized the signal functions in the App class
This commit is contained in:
parent
9764d448af
commit
1218015572
@ -76,7 +76,6 @@ public:
|
||||
return this->setSignalSubscription (sig, SIGNAL_UNHANDLED);
|
||||
}
|
||||
|
||||
|
||||
typedef void (*SignalHandler) (int sig);
|
||||
static qse_size_t _sighrs[2][QSE_NSIGS];
|
||||
|
||||
@ -87,7 +86,7 @@ public:
|
||||
// yet, a subsequence call to subscribeToSignal() is doomed to fail too.
|
||||
// These two different interfaces are mutually exclusive.
|
||||
static int setSignalHandler (int sig, SignalHandler sighr);
|
||||
static int unsetSignalHandler (int sig);
|
||||
static int unsetSignalHandler (int sig, bool ignore = false);
|
||||
|
||||
int guardProcess (const qse_mchar_t* proc_name, const SignalSet& signals);
|
||||
|
||||
@ -108,14 +107,10 @@ private:
|
||||
|
||||
protected:
|
||||
static int set_signal_handler_no_mutex (int sig, SignalHandler sighr);
|
||||
static int unset_signal_handler_no_mutex (int sig);
|
||||
static int unset_signal_handler_no_mutex (int sig, int ignore);
|
||||
|
||||
int set_signal_subscription_no_mutex (int sig, SignalState reqstate);
|
||||
|
||||
int subscribe_to_signal_no_mutex (int sig, SignalState reqstate);
|
||||
void unsubscribe_from_signal_no_mutex (int sig);
|
||||
void unsubscribe_from_all_signals_no_mutex ();
|
||||
|
||||
void on_guard_signal (int sig);
|
||||
static void handle_signal (int sig);
|
||||
|
||||
|
@ -43,10 +43,34 @@ 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
|
||||
{
|
||||
public:
|
||||
SigScopedMutexLocker (Mutex& mutex): mutex(mutex)
|
||||
{
|
||||
sigset_t sigset;
|
||||
::sigfillset (&sigset);
|
||||
::sigprocmask (SIG_BLOCK, &sigset, &this->oldsigset);
|
||||
// TODO: would this work properly if this is called within a thread?
|
||||
// do i need to use pthread_sigmask() conditionally?
|
||||
this->mutex.lock ();
|
||||
}
|
||||
|
||||
~SigScopedMutexLocker ()
|
||||
{
|
||||
this->mutex.unlock ();
|
||||
::sigprocmask (SIG_SETMASK, &this->oldsigset, QSE_NULL);
|
||||
}
|
||||
protected:
|
||||
Mutex& mutex;
|
||||
sigset_t oldsigset;
|
||||
};
|
||||
|
||||
App::App (Mmgr* mmgr) QSE_CPP_NOEXCEPT: Mmged(mmgr), _prev_app(QSE_NULL), _next_app(QSE_NULL), _guarded_child_pid(-1)
|
||||
{
|
||||
ScopedMutexLocker sml(g_app_mutex);
|
||||
SigScopedMutexLocker sml(g_app_mutex);
|
||||
if (!g_app_top)
|
||||
{
|
||||
g_app_top = this;
|
||||
@ -60,8 +84,11 @@ App::App (Mmgr* mmgr) QSE_CPP_NOEXCEPT: Mmged(mmgr), _prev_app(QSE_NULL), _next_
|
||||
|
||||
App::~App () QSE_CPP_NOEXCEPT
|
||||
{
|
||||
ScopedMutexLocker sml(g_app_mutex);
|
||||
this->unsubscribe_from_all_signals_no_mutex ();
|
||||
SigScopedMutexLocker sml(g_app_mutex);
|
||||
for (int i = 0; i < QSE_NSIGS; i++)
|
||||
{
|
||||
this->set_signal_subscription_no_mutex (i, SIGNAL_UNHANDLED);
|
||||
}
|
||||
if (this->_next_app) this->_next_app->_prev_app = this->_prev_app;
|
||||
if (this->_prev_app) this->_prev_app->_next_app = this->_next_app;
|
||||
if (this == g_app_top)
|
||||
@ -207,7 +234,7 @@ static void dispatch_siginfo (int sig, siginfo_t* si, void* ctx)
|
||||
|
||||
int App::setSignalHandler (int sig, SignalHandler sighr)
|
||||
{
|
||||
ScopedMutexLocker sml(g_app_mutex);
|
||||
SigScopedMutexLocker sml(g_app_mutex);
|
||||
return App::set_signal_handler_no_mutex (sig, sighr);
|
||||
}
|
||||
|
||||
@ -222,13 +249,13 @@ int App::set_signal_handler_no_mutex (int sig, SignalHandler sighr)
|
||||
if (oldsa.sa_flags & SA_SIGINFO)
|
||||
{
|
||||
sa.sa_sigaction = dispatch_siginfo;
|
||||
sigemptyset (&sa.sa_mask);
|
||||
::sigfillset (&sa.sa_mask); // block all signals while the handler is being executed
|
||||
sa.sa_flags |= SA_SIGINFO;
|
||||
}
|
||||
else
|
||||
{
|
||||
sa.sa_handler = dispatch_signal;
|
||||
sigemptyset (&sa.sa_mask);
|
||||
::sigfillset (&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
//sa.sa_flags |= SA_INTERUPT;
|
||||
//sa.sa_flags |= SA_RESTART;
|
||||
@ -244,13 +271,13 @@ int App::set_signal_handler_no_mutex (int sig, SignalHandler sighr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int App::unsetSignalHandler (int sig)
|
||||
int App::unsetSignalHandler (int sig, bool ignore)
|
||||
{
|
||||
ScopedMutexLocker sml(g_app_mutex);
|
||||
return App::unset_signal_handler_no_mutex(sig);
|
||||
SigScopedMutexLocker sml(g_app_mutex);
|
||||
return App::unset_signal_handler_no_mutex(sig, ignore);
|
||||
}
|
||||
|
||||
int App::unset_signal_handler_no_mutex(int sig)
|
||||
int App::unset_signal_handler_no_mutex(int sig, int ignore)
|
||||
{
|
||||
if (!App::_sighrs[0][sig]) return -1;
|
||||
|
||||
@ -258,13 +285,18 @@ int App::unset_signal_handler_no_mutex(int sig)
|
||||
|
||||
sa.sa_mask = g_app_oldsi[sig].sa_mask;
|
||||
sa.sa_flags = g_app_oldsi[sig].sa_flags;
|
||||
if (sa.sa_flags & SA_SIGINFO)
|
||||
if (ignore)
|
||||
{
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sa.sa_flags &= ~SA_SIGINFO;
|
||||
}
|
||||
else if (sa.sa_flags & SA_SIGINFO)
|
||||
{
|
||||
sa.sa_sigaction = (void(*)(int,siginfo_t*,void*))App::_sighrs[1][sig];
|
||||
}
|
||||
else
|
||||
{
|
||||
sa.sa_handler = (SignalHandler)App::_sighrs[1][sig];
|
||||
printf ("unset signal handler......\n");
|
||||
sa.sa_handler = SIG_IGN;
|
||||
}
|
||||
|
||||
if (::sigaction (sig, &sa, QSE_NULL) <= -1) return -1;
|
||||
@ -274,10 +306,15 @@ sa.sa_handler = SIG_IGN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*static*/ void App::handle_signal (int sig)
|
||||
{
|
||||
// Note: i use ScopedMutexLocker in the signal handler
|
||||
// whereas I use SigScopedMutexLocker in other functions.
|
||||
// as SigScopedMutexLock blocks all signals, this signal handler
|
||||
// is not called while those other functions are holding on to
|
||||
// this mutex object.
|
||||
ScopedMutexLocker sml(g_app_mutex);
|
||||
|
||||
App* app = g_app_sig[sig];
|
||||
while (app)
|
||||
{
|
||||
@ -311,20 +348,8 @@ App::SignalState App::getSignalSubscription (int sig) const
|
||||
int App::setSignalSubscription (int sig, SignalState ss)
|
||||
{
|
||||
QSE_ASSERT (sig >= 0 && sig < QSE_NSIGS);
|
||||
|
||||
sigset_t sigset;
|
||||
::sigemptyset (&sigset);
|
||||
::sigaddset (&sigset, sig);
|
||||
::sigprocmask (SIG_BLOCK, &sigset, QSE_NULL);
|
||||
|
||||
int n;
|
||||
{
|
||||
ScopedMutexLocker sml(g_app_mutex);
|
||||
n = this->set_signal_subscription_no_mutex(sig, ss);
|
||||
}
|
||||
|
||||
::sigprocmask (SIG_UNBLOCK, &sigset, QSE_NULL);
|
||||
return n;
|
||||
SigScopedMutexLocker sml(g_app_mutex);
|
||||
return this->set_signal_subscription_no_mutex(sig, ss);
|
||||
}
|
||||
|
||||
int App::set_signal_subscription_no_mutex (int sig, SignalState reqstate)
|
||||
@ -342,7 +367,7 @@ int App::set_signal_subscription_no_mutex (int sig, SignalState reqstate)
|
||||
QSE_ASSERT (sl._prev == QSE_NULL);
|
||||
if (!sl._next)
|
||||
{
|
||||
if (App::unset_signal_handler_no_mutex (sig) <= -1) return -1;
|
||||
if (App::unset_signal_handler_no_mutex(sig, true) <= -1) return -1;
|
||||
}
|
||||
g_app_sig[sig] = sl._next;
|
||||
}
|
||||
@ -372,7 +397,7 @@ int App::set_signal_subscription_no_mutex (int sig, SignalState reqstate)
|
||||
else
|
||||
{
|
||||
// no application is set to accept this signal.
|
||||
// this is the first time to
|
||||
// it is the first time to set the system-level signal handler.
|
||||
if (App::set_signal_handler_no_mutex(sig, App::handle_signal) <= -1)
|
||||
{
|
||||
// roll back
|
||||
@ -397,95 +422,6 @@ int App::set_signal_subscription_no_mutex (int sig, SignalState reqstate)
|
||||
return reqstate;
|
||||
}
|
||||
|
||||
|
||||
int App::subscribe_to_signal_no_mutex (int sig, SignalState reqstate)
|
||||
{
|
||||
return this->set_signal_subscription_no_mutex (sig, reqstate);
|
||||
#if 0
|
||||
_SigLink& sl = this->_sig[sig];
|
||||
if (QSE_LIKELY(sl._state == SIGNAL_UNHANDLED))
|
||||
{
|
||||
QSE_ASSERT (sl._prev == QSE_NULL && sl._next == QSE_NULL);
|
||||
|
||||
App* xapp = g_app_sig[sig];
|
||||
App* xapp_xprev = QSE_NULL;
|
||||
|
||||
g_app_sig[sig] = this;
|
||||
sl._state = SIGNAL_ACCEPTED;
|
||||
sl._next = xapp;
|
||||
if (xapp)
|
||||
{
|
||||
xapp_xprev = xapp->_sig[sig]._prev;
|
||||
xapp->_sig[sig]._prev = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no application is set to accept this signal.
|
||||
// this is the first time to
|
||||
if (App::set_signal_handler_no_mutex(sig, App::handle_signal) <= -1)
|
||||
{
|
||||
// roll back
|
||||
g_app_sig[sig] = xapp;
|
||||
if (xapp) xapp->_sig[sig]._prev = xapp_xprev;
|
||||
sl._state = SIGNAL_UNHANDLED;
|
||||
sl._next = QSE_NULL;
|
||||
QSE_ASSERT (sl._prev == QSE_NULL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
QSE_ASSERT (sl._prev == QSE_NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// already configured to receive the signal. change the state only
|
||||
QSE_ASSERT (g_app_sig[sig] != QSE_NULL);
|
||||
sl._state = reqstate;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void App::unsubscribe_from_signal_no_mutex (int sig)
|
||||
{
|
||||
this->set_signal_subscription_no_mutex (sig, SIGNAL_UNHANDLED);
|
||||
#if 0
|
||||
_SigLink& sl = this->_sig[sig];
|
||||
if (QSE_UNLIKELY(sl._state == SIGNAL_UNHANDLED))
|
||||
{
|
||||
QSE_ASSERT (g_app_sig[sig] != this);
|
||||
QSE_ASSERT (sl._prev == QSE_NULL && sl._next == QSE_NULL);
|
||||
// nothing to do
|
||||
}
|
||||
else
|
||||
{
|
||||
QSE_ASSERT (g_app_sig[sig] != QSE_NULL);
|
||||
|
||||
if (g_app_sig[sig] == this)
|
||||
{
|
||||
QSE_ASSERT (sl._prev == QSE_NULL);
|
||||
if (!sl._next) App::unset_signal_handler_no_mutex (sig);
|
||||
g_app_sig[sig] = sl._next;
|
||||
}
|
||||
|
||||
if (sl._next) sl._next->_sig[sig]._prev = sl._prev;
|
||||
if (sl._prev) sl._prev->_sig[sig]._next = sl._next;
|
||||
sl._prev = QSE_NULL;
|
||||
sl._next = QSE_NULL;
|
||||
sl._state = SIGNAL_UNHANDLED;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void App::unsubscribe_from_all_signals_no_mutex()
|
||||
{
|
||||
for (int i = 0; i < QSE_NSIGS; i++)
|
||||
{
|
||||
this->unsubscribe_from_signal_no_mutex (i);
|
||||
}
|
||||
}
|
||||
|
||||
int App::guardProcess (const qse_mchar_t* proc_name, const SignalSet& signals)
|
||||
{
|
||||
SignalState old_ss[QSE_NSIGS];
|
||||
|
@ -147,7 +147,7 @@ int main ()
|
||||
UINT codepage = GetConsoleOutputCP();
|
||||
if (codepage == CP_UTF8)
|
||||
{
|
||||
/*SetConsoleOUtputCP (CP_UTF8);*/
|
||||
/*SetConsoleOutputCP (CP_UTF8);*/
|
||||
qse_setdflcmgrbyid (QSE_CMGR_UTF8);
|
||||
}
|
||||
else
|
||||
|
@ -274,7 +274,7 @@ int main ()
|
||||
UINT codepage = GetConsoleOutputCP();
|
||||
if (codepage == CP_UTF8)
|
||||
{
|
||||
/*SetConsoleOUtputCP (CP_UTF8);*/
|
||||
/*SetConsoleOutputCP (CP_UTF8);*/
|
||||
qse_setdflcmgrbyid (QSE_CMGR_UTF8);
|
||||
}
|
||||
else
|
||||
|
@ -129,7 +129,7 @@ int main ()
|
||||
UINT codepage = GetConsoleOutputCP();
|
||||
if (codepage == CP_UTF8)
|
||||
{
|
||||
/*SetConsoleOUtputCP (CP_UTF8);*/
|
||||
/*SetConsoleOutputCP (CP_UTF8);*/
|
||||
qse_setdflcmgrbyid (QSE_CMGR_UTF8);
|
||||
}
|
||||
else
|
||||
@ -150,96 +150,3 @@ int main ()
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if 0 ////////////////////////
|
||||
|
||||
static int test1 (void)
|
||||
{
|
||||
QSE::HeapMmgr heap_mmgr (QSE::Mmgr::getDFL(), 30000);
|
||||
|
||||
#if defined(QSE_LANG_CPP11)
|
||||
QSE::TcpServerL<int(QSE::TcpServer::Worker*)> server (
|
||||
|
||||
// workload by lambda
|
||||
([&server](QSE::TcpServer::Worker* worker) {
|
||||
qse_char_t addrbuf[128];
|
||||
qse_uint8_t bb[256];
|
||||
qse_ssize_t n;
|
||||
|
||||
worker->address.toStrBuf(addrbuf, QSE_COUNTOF(addrbuf));
|
||||
g_prt_mutex.lock();
|
||||
qse_printf (QSE_T("hello word..from %s -> wid %zu\n"), addrbuf, worker->getWid());
|
||||
g_prt_mutex.unlock();
|
||||
|
||||
while (!server.isStopRequested())
|
||||
{
|
||||
if ((n = worker->socket.receive(bb, QSE_COUNTOF(bb))) <= 0)
|
||||
{
|
||||
g_prt_mutex.lock();
|
||||
qse_printf (QSE_T("%zd bytes received from %s\n"), n, addrbuf);
|
||||
g_prt_mutex.unlock();
|
||||
break;
|
||||
}
|
||||
worker->socket.send (bb, n);
|
||||
}
|
||||
|
||||
g_prt_mutex.lock();
|
||||
qse_printf (QSE_T("byte to %s -> wid %zu\n"), addrbuf, worker->getWid());
|
||||
g_prt_mutex.unlock();
|
||||
return 0;
|
||||
}),
|
||||
|
||||
&heap_mmgr
|
||||
);
|
||||
#else
|
||||
QSE::TcpServerF<ClientHandler> server (&heap_mmgr);
|
||||
#endif
|
||||
|
||||
server.setThreadStackSize (256000);
|
||||
g_server = &server;
|
||||
//server.start (QSE_T("0.0.0.0:9998"));
|
||||
server.start (QSE_T("[::]:9998,0.0.0.0:9998"));
|
||||
//server.start (QSE_T("[fe80::1c4:a90d:a0f0:d52%wlan0]:9998,0.0.0.0:9998"));
|
||||
g_server = QSE_NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void handle_sigint (int sig)
|
||||
{
|
||||
if (g_server) g_server->stop ();
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
char locale[100];
|
||||
UINT codepage = GetConsoleOutputCP();
|
||||
if (codepage == CP_UTF8)
|
||||
{
|
||||
/*SetConsoleOUtputCP (CP_UTF8);*/
|
||||
qse_setdflcmgrbyid (QSE_CMGR_UTF8);
|
||||
}
|
||||
else
|
||||
{
|
||||
qse_mbsxfmt (locale, QSE_COUNTOF(locale), ".%u", (unsigned int)codepage);
|
||||
setlocale (LC_ALL, locale);
|
||||
/*qse_setdflcmgrbyid (QSE_CMGR_SLMB);*/
|
||||
}
|
||||
#else
|
||||
setlocale (LC_ALL, "");
|
||||
/*qse_setdflcmgrbyid (QSE_CMGR_SLMB);*/
|
||||
#endif
|
||||
|
||||
qse_open_stdsios ();
|
||||
|
||||
//QSE::App::setSignalHandler (SIGINT, handle_sigint);
|
||||
test1();
|
||||
//QSE::App::unsetSignalHandler (SIGINT);
|
||||
|
||||
qse_close_stdsios ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif ////////////////////////
|
||||
|
@ -126,7 +126,7 @@ int main ()
|
||||
UINT codepage = GetConsoleOutputCP();
|
||||
if (codepage == CP_UTF8)
|
||||
{
|
||||
/*SetConsoleOUtputCP (CP_UTF8);*/
|
||||
/*SetConsoleOutputCP (CP_UTF8);*/
|
||||
qse_setdflcmgrbyid (QSE_CMGR_UTF8);
|
||||
}
|
||||
else
|
||||
|
@ -117,7 +117,7 @@ int main ()
|
||||
UINT codepage = GetConsoleOutputCP();
|
||||
if (codepage == CP_UTF8)
|
||||
{
|
||||
/*SetConsoleOUtputCP (CP_UTF8);*/
|
||||
/*SetConsoleOutputCP (CP_UTF8);*/
|
||||
qse_setdflcmgrbyid (QSE_CMGR_UTF8);
|
||||
}
|
||||
else
|
||||
|
@ -263,7 +263,7 @@ int main ()
|
||||
UINT codepage = GetConsoleOutputCP();
|
||||
if (codepage == CP_UTF8)
|
||||
{
|
||||
/*SetConsoleOUtputCP (CP_UTF8);*/
|
||||
/*SetConsoleOutputCP (CP_UTF8);*/
|
||||
qse_setdflcmgrbyid (QSE_CMGR_UTF8);
|
||||
}
|
||||
else
|
||||
|
@ -158,7 +158,7 @@ int main ()
|
||||
UINT codepage = GetConsoleOutputCP();
|
||||
if (codepage == CP_UTF8)
|
||||
{
|
||||
/*SetConsoleOUtputCP (CP_UTF8);*/
|
||||
/*SetConsoleOutputCP (CP_UTF8);*/
|
||||
qse_setdflcmgrbyid (QSE_CMGR_UTF8);
|
||||
}
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user