Servatrice: refactor signal handling and permit config reloading

This commit is contained in:
Fabio Bas 2015-06-30 22:21:26 +02:00
parent 9947af7be9
commit 6cf3db7e6b
12 changed files with 163 additions and 95 deletions

View file

@ -0,0 +1,98 @@
#include <QSocketNotifier>
#include "signalhandler.h"
#include "server_logger.h"
#include "settingscache.h"
#include "main.h"
#ifdef Q_OS_UNIX
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <signal.h>
#include <execinfo.h>
#include <iostream>
#include <cstdio>
#endif
#define SIGSEGV_TRACE_LINES 40
int SignalHandler::sigHupFD[2];
SignalHandler::SignalHandler(QObject *parent)
: QObject(parent)
{
#ifdef Q_OS_UNIX
::socketpair(AF_UNIX, SOCK_STREAM, 0, sigHupFD);
snHup = new QSocketNotifier(sigHupFD[1], QSocketNotifier::Read, this);
connect(snHup, SIGNAL(activated(int)), this, SLOT(internalSigHupHandler()));
struct sigaction hup;
hup.sa_handler = SignalHandler::sigHupHandler;
sigemptyset(&hup.sa_mask);
hup.sa_flags = 0;
hup.sa_flags |= SA_RESTART;
sigaction(SIGHUP, &hup, 0);
struct sigaction segv;
segv.sa_handler = SignalHandler::sigSegvHandler;
segv.sa_flags = SA_RESETHAND;
sigemptyset(&segv.sa_mask);
sigaction(SIGSEGV, &segv, 0);
sigaction(SIGABRT, &segv, 0);
signal(SIGPIPE, SIG_IGN);
#endif
}
void SignalHandler::sigHupHandler(int /* sig */)
{
char a = 1;
ssize_t writeValue = ::write(sigHupFD[0], &a, sizeof(a));
Q_UNUSED(writeValue);
}
void SignalHandler::internalSigHupHandler()
{
snHup->setEnabled(false);
char tmp;
ssize_t readValue = ::read(sigHupFD[1], &tmp, sizeof(tmp));
Q_UNUSED(readValue);
#ifdef Q_OS_UNIX
std::cerr << "Received SIGHUP" << std::endl;
#endif
logger->logMessage("Received SIGHUP");
logger->rotateLogs();
settingsCache->sync();
snHup->setEnabled(true);
}
void SignalHandler::sigSegvHandler(int sig)
{
#ifdef Q_OS_UNIX
void *array[SIGSEGV_TRACE_LINES];
size_t size;
// get void*'s for all entries on the stack
size = backtrace(array, SIGSEGV_TRACE_LINES);
// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, STDERR_FILENO);
#endif
if (sig == SIGSEGV)
logger->logMessage("CRASH: SIGSEGV");
else if (sig == SIGABRT)
logger->logMessage("CRASH: SIGABRT");
logger->deleteLater();
loggerThread->wait();
delete loggerThread;
raise(sig);
}