Add thread signal handling

Send SIGUSR2 to interrupt xmlrpc and arq_socket threads
Restore the default signal disposition for various signals
handled by xmlrpc-c's abyss server
pull/2/head
Stelios Bounanos 2008-09-23 21:13:33 +01:00
rodzic 3c560ae5aa
commit 667f672480
5 zmienionych plików z 59 dodań i 33 usunięć

Wyświetl plik

@ -48,6 +48,7 @@ extern void arq_init();
extern void arq_close();
extern void WriteARQ(unsigned int);
extern void checkTLF();
void setup_signal_handlers(void);
#define ARQBUFSIZ 8192

Wyświetl plik

@ -124,7 +124,6 @@ void debug_exec(char** argv);
void set_platform_ui(void);
double speed_test(int converter, unsigned repeat);
int main(int argc, char ** argv)
{
appname = argv[0];
@ -139,11 +138,7 @@ int main(int argc, char ** argv)
set_unexpected(handle_unexpected);
set_terminate(diediedie);
signal(SIGSEGV, handle_signal);
signal(SIGILL, handle_signal);
signal(SIGABRT, handle_signal);
signal(SIGCHLD, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
setup_signal_handlers();
setlocale(LC_TIME, "");
@ -768,3 +763,37 @@ double speed_test(int converter, unsigned repeat)
t0 = t1 - t0;
return repeat / (t0.tv_sec + t0.tv_nsec/1e9);
}
void setup_signal_handlers(void)
{
struct sigaction action;
memset(&action, 0, sizeof(struct sigaction));
action.sa_handler = SIG_DFL;
// no child stopped notifications, no zombies
action.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT;
sigaction(SIGCHLD, &action, NULL);
action.sa_flags = 0;
// undo xmlrpc-c's signal handling
#if USE_XMLRPC
sigaction(SIGTERM, &action, NULL);
sigaction(SIGINT, &action, NULL);
sigaction(SIGHUP, &action, NULL);
sigaction(SIGUSR1, &action, NULL);
#endif
action.sa_handler = handle_signal;
sigaction(SIGSEGV, &action, NULL);
sigaction(SIGILL, &action, NULL);
sigaction(SIGABRT, &action, NULL);
sigaction(SIGUSR2, &action, NULL);
action.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &action, NULL);
sigemptyset(&action.sa_mask);
sigaddset(&action.sa_mask, SIGUSR2);
pthread_sigmask((GET_THREAD_ID() == FLMAIN_TID ? SIG_BLOCK : SIG_UNBLOCK),
&action.sa_mask, NULL);
}

Wyświetl plik

@ -37,6 +37,8 @@
# include <sys/msg.h>
#endif
#include <signal.h>
#include "main.h"
#include "configuration.h"
#include "fl_digi.h"
@ -291,11 +293,10 @@ ARQ_SOCKET_Server::ARQ_SOCKET_Server()
ARQ_SOCKET_Server::~ARQ_SOCKET_Server()
{
run = false;
if (arq_socket_thread) {
pthread_kill(*arq_socket_thread, SIGUSR2);
pthread_join(*arq_socket_thread, NULL);
delete arq_socket_thread;
}
}
bool ARQ_SOCKET_Server::start(const char* node, const char* service)
{
@ -307,9 +308,6 @@ bool ARQ_SOCKET_Server::start(const char* node, const char* service)
try {
inst->server_socket->open(Address(node, service));
inst->server_socket->bind();
struct timeval t = { 0, 200000 };
inst->server_socket->set_timeout(t);
inst->server_socket->set_nonblocking();
}
catch (const SocketException& e) {
errstring = "Could not start ARQ server (";
@ -342,18 +340,23 @@ void* ARQ_SOCKET_Server::thread_func(void*)
{
SET_THREAD_ID(ARQSOCKET_TID);
setup_signal_handlers();
while (inst->run) {
try {
arq_run(inst->server_socket->accept());
}
catch (const SocketException& e) {
if (e.error() != ETIMEDOUT) {
if (e.error() != EINTR) {
errstring = e.what();
LOG_ERROR("%s", errstring.c_str());
Fl::add_timeout(0.0, popup_msg, (void*)errstring.c_str());
break;
}
}
catch (...) {
break;
}
}
arq_stop();
inst->server_socket->close();
@ -362,10 +365,7 @@ void* ARQ_SOCKET_Server::thread_func(void*)
void arq_run(Socket s)
{
struct timeval t = { 0, 20000 }; // 0.02 second timeout
arqclient = s;
arqclient.set_timeout(t);
arqclient.set_nonblocking();
isSocketConnected = true;
arqmode = true;
}

Wyświetl plik

@ -80,6 +80,8 @@ void handle_unexpected(void)
// this may not give us anything useful, but we can try...
void handle_signal(int s)
{
signum = s;
diediedie();
if (s != SIGUSR2) {
signum = s;
diediedie();
}
}

Wyświetl plik

@ -33,6 +33,8 @@
#include <exception>
#include <cstdlib>
#include <signal.h>
#include <xmlrpc-c/base.hpp>
#include <xmlrpc-c/registry.hpp>
#include <xmlrpc-c/server_abyss.hpp>
@ -86,6 +88,7 @@ XML_RPC_Server::XML_RPC_Server()
XML_RPC_Server::~XML_RPC_Server()
{
run = false;
pthread_kill(*server_thread, SIGUSR2);
pthread_join(*server_thread, NULL);
delete server_thread;
delete methods;
@ -102,6 +105,7 @@ void XML_RPC_Server::start(const char* node, const char* service)
try {
inst->server_socket->open(Address(node, service));
inst->server_socket->bind();
}
catch (const SocketException& e) {
LOG_ERROR("Could not start XML-RPC server (%s)", e.what());
@ -134,33 +138,23 @@ void* XML_RPC_Server::thread_func(void*)
#endif
);
try {
inst->server_socket->bind();
struct timeval t = { 0, 200000 };
inst->server_socket->set_timeout(t);
inst->server_socket->set_nonblocking();
}
catch (const SocketException& e) {
LOG_ERROR("Could not start XML-RPC server (%s)", e.what());
goto ret;
}
setup_signal_handlers();
while (inst->run) {
Socket client;
try {
server.runConn(inst->server_socket->accept().fd());
}
catch (const SocketException& e) {
if (e.error() != ETIMEDOUT) {
if (e.error() != EINTR)
LOG_ERROR("%s", e.what());
break;
}
break;
}
catch (...) {
break;
}
}
ret:
inst->server_socket->close();
return NULL;
}