ENH: signals: refactored to make static methods

The signal handling can now be set and unset. This latter is important
for external libraries (e.g. VTK/OpenGL) that do not work with it.
This commit is contained in:
mattijs
2015-11-27 12:14:14 +00:00
parent 6cd4387b9f
commit 99bdd2c1d7
11 changed files with 211 additions and 130 deletions

View File

@ -45,6 +45,8 @@ License
struct sigaction Foam::sigFpe::oldAction_;
bool Foam::sigFpe::sigFpeActive_ = false;
void Foam::sigFpe::fillNan(UList<scalar>& lst)
{
lst = std::numeric_limits<scalar>::signaling_NaN();
@ -114,7 +116,7 @@ void Foam::sigFpe::sigHandler(int)
Foam::sigFpe::sigFpe()
{
oldAction_.sa_handler = NULL;
set(false);
}
@ -122,28 +124,7 @@ Foam::sigFpe::sigFpe()
Foam::sigFpe::~sigFpe()
{
if (env("FOAM_SIGFPE"))
{
#ifdef LINUX_GNUC
// Reset signal
if (oldAction_.sa_handler && sigaction(SIGFPE, &oldAction_, NULL) < 0)
{
FatalErrorIn
(
"Foam::sigFpe::~sigFpe()"
) << "Cannot reset SIGFPE trapping"
<< abort(FatalError);
}
#endif
}
if (env("FOAM_SETNAN"))
{
#ifdef LINUX
// Disable initialization to NaN
mallocNanActive_ = false;
#endif
}
unset(false);
}
@ -151,16 +132,7 @@ Foam::sigFpe::~sigFpe()
void Foam::sigFpe::set(const bool verbose)
{
if (oldAction_.sa_handler)
{
FatalErrorIn
(
"Foam::sigFpe::set()"
) << "Cannot call sigFpe::set() more than once"
<< abort(FatalError);
}
if (env("FOAM_SIGFPE"))
if (!sigFpeActive_ && env("FOAM_SIGFPE"))
{
bool supported = false;
@ -187,6 +159,7 @@ void Foam::sigFpe::set(const bool verbose)
<< abort(FatalError);
}
sigFpeActive_ = true;
#elif defined(sgiN32) || defined(sgiN32Gcc)
supported = true;
@ -209,6 +182,9 @@ void Foam::sigFpe::set(const bool verbose)
_ABORT_ON_ERROR,
NULL
);
sigFpeActive_ = true;
#endif
@ -251,4 +227,52 @@ void Foam::sigFpe::set(const bool verbose)
}
void Foam::sigFpe::unset(const bool verbose)
{
#ifdef LINUX_GNUC
// Reset signal
if (sigFpeActive_)
{
if (verbose)
{
Info<< "sigFpe : Disabling floating point exception trapping"
<< endl;
}
if (sigaction(SIGFPE, &oldAction_, NULL) < 0)
{
FatalErrorIn
(
"Foam::sigFpe::unset(const bool)"
) << "Cannot reset SIGFPE trapping"
<< abort(FatalError);
}
// Reset exception raising
int oldExcept = fedisableexcept
(
FE_DIVBYZERO
| FE_INVALID
| FE_OVERFLOW
);
if (oldExcept == -1)
{
FatalErrorIn
(
"sigFpe::unset(const bool)"
) << "Cannot reset SIGFPE trapping"
<< abort(FatalError);
}
sigFpeActive_ = false;
}
#endif
#ifdef LINUX
// Disable initialization to NaN
mallocNanActive_ = false;
#endif
}
// ************************************************************************* //

View File

@ -35,6 +35,10 @@ Description
also set, this will cause usage of uninitialized scalars to trigger
an abort.
Can be used either directly through the static member functions or
through the scope of the object (constructor sets trapping; destructor
restores original).
SourceFiles
sigFpe.C
@ -72,6 +76,9 @@ class sigFpe
//- Saved old signal trapping setting
static struct sigaction oldAction_;
//- Flag to indicate floating point trapping is enabled
static bool sigFpeActive_;
// Static data members
@ -98,7 +105,10 @@ public:
//- Activate SIGFPE signal handler when FOAM_SIGFPE is %set
// Fill memory with NaN when FOAM_SETNAN is %set
void set(const bool verbose);
static void set(const bool verbose);
//- Deactivate SIGFPE signal handler and NaN memory initialisation
static void unset(const bool verbose);
//- Flag to indicate mallocNan is enabled
static bool mallocNanActive_;

View File

@ -32,6 +32,8 @@ License
struct sigaction Foam::sigInt::oldAction_;
bool Foam::sigInt::sigActive_ = false;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -59,7 +61,7 @@ void Foam::sigInt::sigHandler(int)
Foam::sigInt::sigInt()
{
oldAction_.sa_handler = NULL;
set(false);
}
@ -67,15 +69,7 @@ Foam::sigInt::sigInt()
Foam::sigInt::~sigInt()
{
// Reset old handling
if (sigaction(SIGINT, &oldAction_, NULL) < 0)
{
FatalErrorIn
(
"Foam::sigInt::~sigInt()"
) << "Cannot reset SIGINT trapping"
<< abort(FatalError);
}
unset(false);
}
@ -83,26 +77,38 @@ Foam::sigInt::~sigInt()
void Foam::sigInt::set(const bool)
{
if (oldAction_.sa_handler)
if (!sigActive_)
{
FatalErrorIn
(
"Foam::sigInt::set()"
) << "Cannot call sigInt::set() more than once"
<< abort(FatalError);
struct sigaction newAction;
newAction.sa_handler = sigHandler;
newAction.sa_flags = SA_NODEFER;
sigemptyset(&newAction.sa_mask);
if (sigaction(SIGINT, &newAction, &oldAction_) < 0)
{
FatalErrorIn
(
"Foam::sigInt::set()"
) << "Cannot set SIGINT trapping"
<< abort(FatalError);
}
sigActive_ = true;
}
}
struct sigaction newAction;
newAction.sa_handler = sigHandler;
newAction.sa_flags = SA_NODEFER;
sigemptyset(&newAction.sa_mask);
if (sigaction(SIGINT, &newAction, &oldAction_) < 0)
void Foam::sigInt::unset(const bool)
{
if (sigActive_)
{
FatalErrorIn
(
"Foam::sigInt::set()"
) << "Cannot set SIGINT trapping"
<< abort(FatalError);
if (sigaction(SIGINT, &oldAction_, NULL) < 0)
{
FatalErrorIn
(
"Foam::sigInt::unset()"
) << "Cannot reset SIGINT trapping"
<< abort(FatalError);
}
sigActive_ = false;
}
}

View File

@ -30,6 +30,10 @@ Description
The standard interupt handler is overridden to ensure that the
runningJob file is removed.
Can be used either directly through the static member functions or
through the scope of the object (constructor sets trapping; destructor
restores original).
See Also
Foam::JobInfo
@ -59,6 +63,9 @@ class sigInt
//- Saved old signal trapping setting
static struct sigaction oldAction_;
//- Flag to indicate signal trapping is enabled
static bool sigActive_;
// Private Member Functions
@ -80,7 +87,10 @@ public:
// Member functions
//- Activate SIGINT signal handler
void set(const bool verbose);
static void set(const bool verbose);
//- Deactivate SIGINT signal handler
static void unset(const bool verbose);
};

View File

@ -32,6 +32,8 @@ License
struct sigaction Foam::sigQuit::oldAction_;
bool Foam::sigQuit::sigActive_ = false;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -61,7 +63,7 @@ void Foam::sigQuit::sigHandler(int)
Foam::sigQuit::sigQuit()
{
oldAction_.sa_handler = NULL;
set(false);
}
@ -69,15 +71,7 @@ Foam::sigQuit::sigQuit()
Foam::sigQuit::~sigQuit()
{
// Reset old handling
if (oldAction_.sa_handler && sigaction(SIGQUIT, &oldAction_, NULL) < 0)
{
FatalErrorIn
(
"Foam::sigQuit::~sigQuit()"
) << "Cannot reset SIGQUIT trapping"
<< abort(FatalError);
}
unset(false);
}
@ -85,26 +79,38 @@ Foam::sigQuit::~sigQuit()
void Foam::sigQuit::set(const bool verbose)
{
if (oldAction_.sa_handler)
if (!sigActive_)
{
FatalErrorIn
(
"Foam::sigQuit::set()"
) << "Cannot call sigQuit::set() more than once"
<< abort(FatalError);
struct sigaction newAction;
newAction.sa_handler = sigHandler;
newAction.sa_flags = SA_NODEFER;
sigemptyset(&newAction.sa_mask);
if (sigaction(SIGQUIT, &newAction, &oldAction_) < 0)
{
FatalErrorIn
(
"Foam::sigQuit::set()"
) << "Cannot set SIGQUIT trapping"
<< abort(FatalError);
}
sigActive_ = true;
}
}
struct sigaction newAction;
newAction.sa_handler = sigHandler;
newAction.sa_flags = SA_NODEFER;
sigemptyset(&newAction.sa_mask);
if (sigaction(SIGQUIT, &newAction, &oldAction_) < 0)
void Foam::sigQuit::unset(const bool)
{
if (sigActive_)
{
FatalErrorIn
(
"Foam::sigQuit::set()"
) << "Cannot set SIGQUIT trapping"
<< abort(FatalError);
if (sigaction(SIGQUIT, &oldAction_, NULL) < 0)
{
FatalErrorIn
(
"Foam::sigQuit::unset()"
) << "Cannot reset SIGQUIT trapping"
<< abort(FatalError);
}
sigActive_ = false;
}
}

View File

@ -29,6 +29,9 @@ Description
The standard interupt handler is overridden to ensure that the
runningJob file is removed.
Can be used either directly through the static member functions or
through the scope of the object (constructor sets trapping; destructor
restores original).
See Also
Foam::JobInfo
@ -59,6 +62,9 @@ class sigQuit
//- Saved old signal trapping setting
static struct sigaction oldAction_;
//- Flag to indicate signal trapping is enabled
static bool sigActive_;
// Private Member Functions
@ -81,7 +87,10 @@ public:
// Member functions
//- Activate SIGQUIT signal handler
void set(const bool verbose);
static void set(const bool verbose);
//- Deactivate SIGQUIT signal handler
static void unset(const bool verbose);
};

View File

@ -32,6 +32,8 @@ License
struct sigaction Foam::sigSegv::oldAction_;
bool Foam::sigSegv::sigActive_ = false;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -61,7 +63,7 @@ void Foam::sigSegv::sigHandler(int)
Foam::sigSegv::sigSegv()
{
oldAction_.sa_handler = NULL;
set(false);
}
@ -69,15 +71,7 @@ Foam::sigSegv::sigSegv()
Foam::sigSegv::~sigSegv()
{
// Reset old handling
if (sigaction(SIGSEGV, &oldAction_, NULL) < 0)
{
FatalErrorIn
(
"Foam::sigSegv::~sigSegv()"
) << "Cannot reset SIGSEGV trapping"
<< abort(FatalError);
}
unset(false);
}
@ -85,26 +79,38 @@ Foam::sigSegv::~sigSegv()
void Foam::sigSegv::set(const bool)
{
if (oldAction_.sa_handler)
if (!sigActive_)
{
FatalErrorIn
(
"Foam::sigSegv::set()"
) << "Cannot call sigSegv::set() more than once"
<< abort(FatalError);
struct sigaction newAction;
newAction.sa_handler = sigHandler;
newAction.sa_flags = SA_NODEFER;
sigemptyset(&newAction.sa_mask);
if (sigaction(SIGSEGV, &newAction, &oldAction_) < 0)
{
FatalErrorIn
(
"Foam::sigSegv::set()"
) << "Cannot set SIGSEGV trapping"
<< abort(FatalError);
}
sigActive_ = true;
}
}
struct sigaction newAction;
newAction.sa_handler = sigHandler;
newAction.sa_flags = SA_NODEFER;
sigemptyset(&newAction.sa_mask);
if (sigaction(SIGSEGV, &newAction, &oldAction_) < 0)
void Foam::sigSegv::unset(const bool)
{
if (sigActive_)
{
FatalErrorIn
(
"Foam::sigSegv::set()"
) << "Cannot set SIGSEGV trapping"
<< abort(FatalError);
if (sigaction(SIGSEGV, &oldAction_, NULL) < 0)
{
FatalErrorIn
(
"Foam::sigSegv::unset()"
) << "Cannot reset SIGSEGV trapping"
<< abort(FatalError);
}
sigActive_ = false;
}
}

View File

@ -29,6 +29,9 @@ Description
The standard interupt handler is overridden to ensure that the
runningJob file is removed.
Can be used either directly through the static member functions or
through the scope of the object (constructor sets trapping; destructor
restores original).
See Also
Foam::JobInfo
@ -59,6 +62,9 @@ class sigSegv
//- Saved old signal trapping setting
static struct sigaction oldAction_;
//- Flag to indicate signal trapping is enabled
static bool sigActive_;
// Private Member Functions
@ -81,7 +87,10 @@ public:
// Member functions
//- Activate SIGSEGV signal handler
void set(const bool verbose);
static void set(const bool verbose);
//- Deactivate SIGSEGV signal handler
static void unset(const bool verbose);
};

View File

@ -33,6 +33,10 @@ License
#include "labelList.H"
#include "regIOobject.H"
#include "dynamicCode.H"
#include "sigFpe.H"
#include "sigInt.H"
#include "sigQuit.H"
#include "sigSegv.H"
#include <cctype>
@ -868,10 +872,10 @@ void Foam::argList::parse
// Switch on signal trapping. We have to wait until after Pstream::init
// since this sets up its own ones.
sigFpe_.set(bannerEnabled);
sigInt_.set(bannerEnabled);
sigQuit_.set(bannerEnabled);
sigSegv_.set(bannerEnabled);
sigFpe::set(bannerEnabled);
sigInt::set(bannerEnabled);
sigQuit::set(bannerEnabled);
sigSegv::set(bannerEnabled);
if (bannerEnabled)
{

View File

@ -86,11 +86,6 @@ SourceFiles
#include "IStringStream.H"
#include "OSspecific.H"
#include "sigFpe.H"
#include "sigInt.H"
#include "sigQuit.H"
#include "sigSegv.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
@ -118,12 +113,6 @@ class argList
fileName case_;
string argListStr_;
// Signal handlers
sigFpe sigFpe_;
sigInt sigInt_;
sigQuit sigQuit_;
sigSegv sigSegv_;
// Private Member Functions

View File

@ -31,6 +31,7 @@ License
#include "surface.H"
#include "text.H"
#include "Time.H"
#include "sigFpe.H"
// VTK includes
#include "vtkPolyDataMapper.h"
@ -143,6 +144,10 @@ void Foam::runTimePostProcessing::write()
Info<< type() << " " << name_ << " output:" << nl
<< " Constructing scene" << endl;
// Unset any floating point trapping (some low-level rendering functionality
// does not like it)
sigFpe::unset(false);
// Initialise render window
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
@ -204,6 +209,9 @@ void Foam::runTimePostProcessing::write()
surfaces_[i].updateActors(position);
}
}
// Reset any floating point trapping
sigFpe::set(false);
}