make sure signals are only handled by the main thread. Fix bus error on rclmon exit (double delete)
This commit is contained in:
+24
-1
@@ -1,5 +1,5 @@
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#$Id: rclinit.cpp,v 1.8 2006-11-08 15:34:20 dockes Exp $ (C) 2004 J.F.Dockes";
|
||||
static char rcsid[] = "@(#$Id: rclinit.cpp,v 1.9 2007-05-21 13:30:21 dockes Exp $ (C) 2004 J.F.Dockes";
|
||||
#endif
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -21,6 +21,7 @@ static char rcsid[] = "@(#$Id: rclinit.cpp,v 1.8 2006-11-08 15:34:20 dockes Exp
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <locale.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "debuglog.h"
|
||||
#include "rclconfig.h"
|
||||
@@ -36,6 +37,16 @@ RclConfig *recollinit(RclInitFlags flags,
|
||||
if (cleanup)
|
||||
atexit(cleanup);
|
||||
|
||||
// We ignore SIGPIPE always. All pieces of code which can write to a pipe
|
||||
// must check write() return values.
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
// We block SIGCLD globally. We intend to properly wait for our children
|
||||
sigset_t sset;
|
||||
sigemptyset(&sset);
|
||||
sigaddset(&sset, SIGCHLD);
|
||||
pthread_sigmask(SIG_BLOCK, &sset, 0);
|
||||
|
||||
if (sigcleanup) {
|
||||
for (unsigned int i = 0; i < sizeof(catchedSigs) / sizeof(int); i++)
|
||||
if (signal(catchedSigs[i], SIG_IGN) != SIG_IGN)
|
||||
@@ -86,3 +97,15 @@ RclConfig *recollinit(RclInitFlags flags,
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
// Signals are handled by the main thread. All others should call this routine
|
||||
// to block possible signals
|
||||
void recoll_threadinit()
|
||||
{
|
||||
sigset_t sset;
|
||||
sigemptyset(&sset);
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(catchedSigs) / sizeof(int); i++)
|
||||
sigaddset(&sset, catchedSigs[i]);
|
||||
pthread_sigmask(SIG_BLOCK, &sset, 0);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
#ifndef _RCLINIT_H_INCLUDED_
|
||||
#define _RCLINIT_H_INCLUDED_
|
||||
/* @(#$Id: rclinit.h,v 1.5 2006-11-08 07:22:14 dockes Exp $ (C) 2004 J.F.Dockes */
|
||||
/* @(#$Id: rclinit.h,v 1.6 2007-05-21 13:30:21 dockes Exp $ (C) 2004 J.F.Dockes */
|
||||
|
||||
#include <string>
|
||||
#ifndef NO_NAMESPACES
|
||||
@@ -26,6 +26,10 @@ using std::string;
|
||||
class RclConfig;
|
||||
/**
|
||||
* Initialize by reading configuration, opening log file, etc.
|
||||
*
|
||||
* This must be called from the main thread before starting any others. It sets
|
||||
* up the global signal handling. other threads must call recoll_threadinit()
|
||||
* when starting.
|
||||
*
|
||||
* @param flags misc modifiers
|
||||
* @param cleanup function to call before exiting (atexit)
|
||||
@@ -46,5 +50,7 @@ inline RclConfig *recollinit(void (*cleanup)(void), void (*sigcleanup)(int),
|
||||
string &reason, const string *argcnf = 0) {
|
||||
return recollinit(RCLINIT_NONE, cleanup, sigcleanup, reason, argcnf);
|
||||
}
|
||||
// Threads need to call this. The main thread handles all signals.
|
||||
extern void recoll_threadinit();
|
||||
|
||||
#endif /* _RCLINIT_H_INCLUDED_ */
|
||||
|
||||
Reference in New Issue
Block a user