From 83c9d3b2874f4d599ce3954f0d9db108307461ea Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Fri, 22 Jun 2018 00:39:53 +0200 Subject: [PATCH] EHH: add sigFpe::ignore helper class (issue #897) - convenient way to temporarily suspend the SIGFPE handler. Eg, // Normal code with SIGFPE enabled ... sigFpe::set(); { // Ignore SIGFPE in this scope ... sigFpe::ignore noFpeHandling; ... } --- src/OSspecific/POSIX/signals/sigFpe.C | 27 ++++++++++++++++ src/OSspecific/POSIX/signals/sigFpe.H | 46 ++++++++++++++++++++++++--- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/OSspecific/POSIX/signals/sigFpe.C b/src/OSspecific/POSIX/signals/sigFpe.C index 5862efa061..4e05730b3f 100644 --- a/src/OSspecific/POSIX/signals/sigFpe.C +++ b/src/OSspecific/POSIX/signals/sigFpe.C @@ -145,6 +145,17 @@ Foam::sigFpe::sigFpe() } +Foam::sigFpe::ignore::ignore() +: + wasActive_(sigFpe::active()) +{ + if (wasActive_) + { + sigFpe::unset(); + } +} + + // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::sigFpe::~sigFpe() @@ -153,8 +164,24 @@ Foam::sigFpe::~sigFpe() } +Foam::sigFpe::ignore::~ignore() +{ + restore(); +} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +void Foam::sigFpe::ignore::restore() +{ + if (wasActive_) + { + sigFpe::set(); + } + wasActive_ = false; +} + + bool Foam::sigFpe::requested() { return isTrue("FOAM_SIGFPE", switchFpe_); diff --git a/src/OSspecific/POSIX/signals/sigFpe.H b/src/OSspecific/POSIX/signals/sigFpe.H index 1e9d21aadb..916d805e2e 100644 --- a/src/OSspecific/POSIX/signals/sigFpe.H +++ b/src/OSspecific/POSIX/signals/sigFpe.H @@ -93,7 +93,8 @@ class sigFpe // Private Member Functions - //- Handler for caught signals + //- Handler for caught signals. + // Ends job and prints stack static void sigHandler(int); @@ -101,15 +102,17 @@ public: // Constructors - //- Construct null + //- Constructor calls set() to activate the FPE signal handler if it + //- was was not previously activate and requested() returns true. sigFpe(); - //- Destructor + //- Destructor calls unset() to deactivate the FPE signal handler + //- as required. ~sigFpe(); - // Member Functions + // Static Member Functions //- Check if SIGFPE signals handler is to be enabled. // This is controlled by the trapFpe entry or the FOAM_SIGFPE @@ -142,6 +145,41 @@ public: //- Fill data block with NaN values static void fillNan(UList& list); + + + // Helper classes + + //- Helper to locally ignore SIGFPE handling. + // Restores the original state of the SIGFPE handler on destruction. + class ignore + { + //- The signal handler state when entering + bool wasActive_; + + //- No copy construct + ignore(const ignore&) = delete; + + //- No copy assignment + void operator=(const ignore&) = delete; + + //- No move construct + ignore(ignore&&) = delete; + + //- No move assignment + void operator=(ignore&&) = delete; + + + public: + + //- Constructor deactivates any previously active SIGFPE handler + ignore(); + + //- Destructor restores the original state of SIGFPE handler + ~ignore(); + + //- Restore the original state of SIGFPE handler + void restore(); + }; };