kopia lustrzana https://github.com/jamescoxon/dl-fldigi
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 serverpull/2/head
rodzic
3c560ae5aa
commit
667f672480
|
@ -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
|
||||
|
||||
|
|
41
src/main.cxx
41
src/main.cxx
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue