8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 18:03:04 +01:00

Fixed CORE-87

This commit is contained in:
alexpeshkoff 2006-10-09 12:36:39 +00:00
parent ca5ba8c731
commit 3ed7326ec1

View File

@ -36,7 +36,7 @@
*
*/
/* $Id: isc_ipc.cpp,v 1.17 2005-09-15 16:42:34 alexpeshkoff Exp $ */
/* $Id: isc_ipc.cpp,v 1.18 2006-10-09 12:36:39 alexpeshkoff Exp $ */
#include "firebird.h"
#include <stdio.h>
@ -91,12 +91,14 @@ struct sig {
int sig_signal;
union {
FPTR_VOID_PTR user;
void (*client) (int);
void (*client1) (int);
void (*client3) (int, siginfo_t *, void *);
FPTR_INT_VOID_PTR informs;
FPTR_VOID untyped;
} sig_routine;
void* sig_arg;
USHORT sig_flags;
USHORT sig_w_siginfo;
};
typedef sig *SIG;
@ -129,9 +131,9 @@ static int volatile relay_pipe = 0;
static void cleanup(void* arg);
static void isc_signal2(int signal, FPTR_VOID handler, void* arg, ULONG);
static SLONG overflow_handler(void* arg);
static SIG que_signal(int signal, FPTR_VOID handler, void* arg, int flags);
static SIG que_signal(int signal, FPTR_VOID handler, void* arg, int flags, bool w_siginfo);
static void CLIB_ROUTINE signal_handler(int number);
static void CLIB_ROUTINE signal_action(int number, siginfo_t *siginfo, void *context);
#ifndef SIG_HOLD
#define SIG_HOLD SIG_DFL
@ -355,36 +357,32 @@ static void isc_signal2(
the old action was SIG_DFL, SIG_HOLD, SIG_IGN or our
multiplexor, there is no need to save it. */
bool old_sig_w_siginfo = false;
if (!sig) {
struct sigaction act, oact;
act.sa_handler = signal_handler;
act.sa_flags = SA_RESTART;
act.sa_sigaction = signal_action;
act.sa_flags = SA_RESTART | SA_SIGINFO;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask, signal_number);
sigaction(signal_number, &act, &oact);
if (
#ifdef SA_SIGINFO
// Do not queue user handlers requesting information.
// There is no easy and portable way to support them.
// Either Firebird or application should be adjusted to use another signal
!(oact.sa_flags & SA_SIGINFO) &&
#endif
oact.sa_handler != signal_handler &&
oact.sa_handler != SIG_DFL &&
oact.sa_handler != SIG_HOLD &&
oact.sa_handler != SIG_IGN
)
old_sig_w_siginfo = oact.sa_flags & SA_SIGINFO;
if (oact.sa_sigaction != signal_action &&
oact.sa_handler != SIG_DFL &&
oact.sa_handler != SIG_HOLD &&
oact.sa_handler != SIG_IGN)
{
que_signal(signal_number, reinterpret_cast<FPTR_VOID>(oact.sa_handler),
NULL, SIG_client);
que_signal(signal_number, old_sig_w_siginfo ?
reinterpret_cast<FPTR_VOID>(oact.sa_sigaction) :
reinterpret_cast<FPTR_VOID>(oact.sa_handler),
NULL, SIG_client, old_sig_w_siginfo);
}
}
/* Que up the new ISC signal handler routine */
que_signal(signal_number, handler, arg, flags);
que_signal(signal_number, handler, arg, flags, old_sig_w_siginfo);
THD_MUTEX_UNLOCK(&sig_mutex);
}
@ -493,7 +491,7 @@ static SLONG overflow_handler(void* arg)
/* If we're within ISC world (inside why-value) when the FPE occurs
* we handle it (basically by ignoring it). If it occurs outside of
* ISC world, return back a code that tells signal_handler to call any
* ISC world, return back a code that tells signal_action to call any
* customer provided handler.
*/
if (isc_enter_count) {
@ -502,20 +500,22 @@ static SLONG overflow_handler(void* arg)
fprintf(stderr, "SIGFPE in isc code ignored %d\n",
overflow_count);
#endif
/* We've "handled" the FPE - let signal_handler know not to chain
/* We've "handled" the FPE - let signal_action know not to chain
the signal to other handlers */
return SIG_informs_stop;
}
else {
/* We've NOT "handled" the FPE - let signal_handler know to chain
/* We've NOT "handled" the FPE - let signal_action know to chain
the signal to other handlers */
return SIG_informs_continue;
}
}
static SIG que_signal(
int signal_number,
FPTR_VOID handler, void* arg, int flags)
static SIG que_signal(int signal_number,
FPTR_VOID handler,
void* arg,
int flags,
bool sig_w_siginfo)
{
/**************************************
*
@ -546,6 +546,7 @@ static SIG que_signal(
sig->sig_routine.untyped = handler;
sig->sig_arg = arg;
sig->sig_flags = flags;
sig->sig_w_siginfo = sig_w_siginfo;
sig->sig_next = signals;
signals = sig;
@ -554,11 +555,11 @@ static SIG que_signal(
}
static void CLIB_ROUTINE signal_handler(int number)
static void CLIB_ROUTINE signal_action(int number, siginfo_t *siginfo, void *context)
{
/**************************************
*
* s i g n a l _ h a n d l e r ( G E N E R I C )
* s i g n a l _ a c t i o n
*
**************************************
*
@ -569,15 +570,33 @@ static void CLIB_ROUTINE signal_handler(int number)
/* Invoke everybody who may have expressed an interest. */
for (SIG sig = signals; sig; sig = sig->sig_next)
{
if (sig->sig_signal == number)
{
if (sig->sig_flags & SIG_client)
(*sig->sig_routine.client)(number);
else if (sig->sig_flags & SIG_informs) {
{
if (sig->sig_w_siginfo)
{
(*sig->sig_routine.client3)(number, siginfo, context);
}
else
{
(*sig->sig_routine.client1)(number);
}
}
else if (sig->sig_flags & SIG_informs)
{
/* Routine will tell us whether to chain the signal to other handlers */
if ((*sig->sig_routine.informs)(sig->sig_arg) == SIG_informs_stop)
{
break;
}
}
else
{
(*sig->sig_routine.user) (sig->sig_arg);
}
}
}
}