Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Donald Haase
Cockatrice
Commits
6504a889
Commit
6504a889
authored
Apr 06, 2011
by
Max-Wilhelm Bruker
Browse files
threaded logging; sigsegv handler to flush logfile before crashing
parent
1fca2e5d
Changes
3
Hide whitespace changes
Inline
Side-by-side
servatrice/src/main.cpp
View file @
6504a889
...
...
@@ -32,6 +32,7 @@
RNG_Abstract
*
rng
;
ServerLogger
*
logger
;
ServerLoggerThread
*
loggerThread
;
void
testRNG
()
{
...
...
@@ -72,6 +73,14 @@ void myMessageOutput(QtMsgType /*type*/, const char *msg)
logger
->
logMessage
(
msg
);
}
void
sigSegvHandler
(
int
sig
)
{
logger
->
logMessage
(
"SIGSEGV"
);
usleep
(
1000
);
delete
loggerThread
;
raise
(
sig
);
}
int
main
(
int
argc
,
char
*
argv
[])
{
QCoreApplication
app
(
argc
,
argv
);
...
...
@@ -86,7 +95,12 @@ int main(int argc, char *argv[])
QTextCodec
::
setCodecForCStrings
(
QTextCodec
::
codecForName
(
"UTF-8"
));
QSettings
*
settings
=
new
QSettings
(
"servatrice.ini"
,
QSettings
::
IniFormat
);
logger
=
new
ServerLogger
(
settings
->
value
(
"server/logfile"
).
toString
());
loggerThread
=
new
ServerLoggerThread
(
settings
->
value
(
"server/logfile"
).
toString
());
loggerThread
->
start
();
loggerThread
->
waitForInit
();
logger
=
loggerThread
->
getLogger
();
qInstallMsgHandler
(
myMessageOutput
);
#ifdef Q_OS_UNIX
struct
sigaction
hup
;
...
...
@@ -95,6 +109,12 @@ int main(int argc, char *argv[])
hup
.
sa_flags
=
0
;
hup
.
sa_flags
|=
SA_RESTART
;
sigaction
(
SIGHUP
,
&
hup
,
0
);
struct
sigaction
segv
;
segv
.
sa_handler
=
sigSegvHandler
;
segv
.
sa_flags
=
SA_RESETHAND
;
sigemptyset
(
&
segv
.
sa_mask
);
sigaction
(
SIGSEGV
,
&
segv
,
0
);
#endif
rng
=
new
RNG_SFMT
;
...
...
servatrice/src/server_logger.cpp
View file @
6504a889
...
...
@@ -3,17 +3,14 @@
#include
<QFile>
#include
<QTextStream>
#include
<QDateTime>
#include
<QThread>
#ifdef Q_OS_UNIX
#include
<sys/types.h>
#include
<sys/socket.h>
#endif
ServerLogger
::
ServerLogger
(
const
QString
&
logFileName
,
QObject
*
parent
)
:
QObject
(
parent
)
:
QObject
(
parent
)
,
flushRunning
(
false
)
{
if
(
!
logFileName
.
isEmpty
())
{
logFile
=
new
QFile
(
logFileName
,
this
);
logFile
=
new
QFile
(
"server.log"
,
this
);
logFile
->
open
(
QIODevice
::
Append
);
#ifdef Q_OS_UNIX
::
socketpair
(
AF_UNIX
,
SOCK_STREAM
,
0
,
sigHupFD
);
...
...
@@ -22,6 +19,8 @@ ServerLogger::ServerLogger(const QString &logFileName, QObject *parent)
connect
(
snHup
,
SIGNAL
(
activated
(
int
)),
this
,
SLOT
(
handleSigHup
()));
}
else
logFile
=
0
;
connect
(
this
,
SIGNAL
(
sigFlushBuffer
()),
this
,
SLOT
(
flushBuffer
()),
Qt
::
QueuedConnection
);
}
ServerLogger
::~
ServerLogger
()
...
...
@@ -33,11 +32,33 @@ void ServerLogger::logMessage(QString message)
if
(
!
logFile
)
return
;
logFileMutex
.
lock
();
bufferMutex
.
lock
();
buffer
.
append
(
QDateTime
::
currentDateTime
().
toString
()
+
" "
+
QString
::
number
((
qulonglong
)
QThread
::
currentThread
(),
16
)
+
" "
+
message
);
bufferMutex
.
unlock
();
emit
sigFlushBuffer
();
}
void
ServerLogger
::
flushBuffer
()
{
if
(
flushRunning
)
return
;
flushRunning
=
true
;
QTextStream
stream
(
logFile
);
stream
<<
QDateTime
::
currentDateTime
().
toString
()
<<
" "
<<
((
void
*
)
QThread
::
currentThread
())
<<
" "
<<
message
<<
"
\n
"
;
stream
.
flush
();
logFileMutex
.
unlock
();
forever
{
bufferMutex
.
lock
();
if
(
buffer
.
isEmpty
())
{
bufferMutex
.
unlock
();
flushRunning
=
false
;
return
;
}
QString
message
=
buffer
.
takeFirst
();
bufferMutex
.
unlock
();
stream
<<
message
<<
"
\n
"
;
stream
.
flush
();
}
}
void
ServerLogger
::
hupSignalHandler
(
int
/*unused*/
)
...
...
@@ -66,3 +87,34 @@ void ServerLogger::handleSigHup()
QFile
*
ServerLogger
::
logFile
;
int
ServerLogger
::
sigHupFD
[
2
];
ServerLoggerThread
::
ServerLoggerThread
(
const
QString
&
_fileName
,
QObject
*
parent
)
:
QThread
(
parent
),
fileName
(
_fileName
)
{
}
ServerLoggerThread
::~
ServerLoggerThread
()
{
quit
();
wait
();
}
void
ServerLoggerThread
::
run
()
{
logger
=
new
ServerLogger
(
fileName
);
usleep
(
100
);
initWaitCondition
.
wakeAll
();
exec
();
delete
logger
;
}
void
ServerLoggerThread
::
waitForInit
()
{
QMutex
mutex
;
mutex
.
lock
();
initWaitCondition
.
wait
(
&
mutex
);
mutex
.
unlock
();
}
servatrice/src/server_logger.h
View file @
6504a889
...
...
@@ -2,7 +2,10 @@
#define SERVER_LOGGER_H
#include
<QObject>
#include
<QThread>
#include
<QMutex>
#include
<QWaitCondition>
#include
<QStringList>
class
QSocketNotifier
;
class
QFile
;
...
...
@@ -17,11 +20,31 @@ public slots:
void
logMessage
(
QString
message
);
private
slots
:
void
handleSigHup
();
void
flushBuffer
();
signals:
void
sigFlushBuffer
();
private:
static
int
sigHupFD
[
2
];
QSocketNotifier
*
snHup
;
static
QFile
*
logFile
;
QMutex
logFileMutex
;
bool
flushRunning
;
QStringList
buffer
;
QMutex
bufferMutex
;
};
class
ServerLoggerThread
:
public
QThread
{
Q_OBJECT
private:
QString
fileName
;
ServerLogger
*
logger
;
QWaitCondition
initWaitCondition
;
protected:
void
run
();
public:
ServerLoggerThread
(
const
QString
&
_fileName
,
QObject
*
parent
=
0
);
~
ServerLoggerThread
();
ServerLogger
*
getLogger
()
const
{
return
logger
;
}
void
waitForInit
();
};
#endif
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment