ENH: improve code isolation for signal-handling

- file-local static for saving the old action, which moves system
  dependencies out of the header files.

- set/reset of signals as file-local functions

STYLE: use csignal header instead of signal.h
This commit is contained in:
Mark Olesen
2019-04-02 11:38:09 +02:00
committed by Andrew Heather
parent 36fae9fd98
commit c24fbfd7e3
21 changed files with 402 additions and 456 deletions

View File

@ -3,14 +3,16 @@ clockValue/clockValue.C
cpuInfo/cpuInfo.C
cpuTime/cpuTime.C
memInfo/memInfo.C
signals/sigFpe.C
signals/sigSegv.C
signals/sigInt.C
signals/sigQuit.C
signals/sigStopAtWriteNow.C
signals/sigWriteNow.C
signals/timer.C
regExpPosix.C
timer.C
fileStat.C
POSIX.C

View File

@ -41,7 +41,7 @@ SourceFiles
#define cpuTime_H
#include <string>
#include <time.h>
#include <ctime>
#include <sys/times.h>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2015 OpenFOAM Foundation
@ -54,6 +54,7 @@ SourceFiles
namespace Foam
{
// Forward Declarations
class fileMonitor;
class fileMonitorWatcher;
@ -63,7 +64,6 @@ class fileMonitorWatcher;
class fileMonitor
{
public:
// Public data types
@ -79,6 +79,7 @@ public:
static const Enum<fileState> fileStateNames_;
private:
// Private data
//- Whether to use inotify (requires -DFOAM_USE_INOTIFY, see above)

View File

@ -29,7 +29,6 @@ License
#include "IOstreams.H"
#include "timer.H"
#include <signal.h>
#include <unistd.h>
#ifndef darwin
#include <sys/sysmacros.h>

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2015 OpenFOAM Foundation
@ -33,6 +33,8 @@ License
#include "Switch.H"
#include "UList.H"
#include <limits>
#if defined(__linux__) && defined(__GNUC__)
#ifndef __USE_GNU
#define __USE_GNU // To use feenableexcept()
@ -47,7 +49,9 @@ License
#include "feexceptErsatz.H"
#endif
#include <limits>
// File-local functions
#include "signalMacros.C"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -57,8 +61,6 @@ bool Foam::sigFpe::switchNan_(Foam::debug::optimisationSwitch("setNaN", 0));
bool Foam::sigFpe::sigActive_ = false;
bool Foam::sigFpe::nanActive_ = false;
struct sigaction Foam::sigFpe::oldAction_;
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
@ -123,17 +125,11 @@ void Foam::sigFpe::sigHandler(int)
{
#if (defined(__linux__) && defined(__GNUC__)) || defined(darwin)
// Reset old handling
if (sigaction(SIGFPE, &oldAction_, nullptr) < 0)
{
FatalErrorInFunction
<< "Cannot reset SIGFPE trapping"
<< abort(FatalError);
}
resetHandler("SIGFPE", SIGFPE);
jobInfo.signalEnd(); // Update jobInfo file
error::printStack(Perr);
raise(SIGFPE); // Throw signal (to old handler)
::raise(SIGFPE); // Throw signal (to old handler)
#endif // (__linux__ && __GNUC__) || darwin
}
@ -203,17 +199,7 @@ void Foam::sigFpe::set(bool verbose)
| FE_OVERFLOW
);
struct sigaction newAction;
newAction.sa_handler = sigHandler;
newAction.sa_flags = SA_NODEFER;
sigemptyset(&newAction.sa_mask);
if (sigaction(SIGFPE, &newAction, &oldAction_) < 0)
{
FatalErrorInFunction
<< "Cannot set SIGFPE trapping"
<< abort(FatalError);
}
setHandler("SIGFPE", SIGFPE, sigHandler);
sigActive_ = true;
@ -293,12 +279,7 @@ void Foam::sigFpe::unset(bool verbose)
<< endl;
}
if (sigaction(SIGFPE, &oldAction_, nullptr) < 0)
{
FatalErrorInFunction
<< "Cannot reset SIGFPE trapping"
<< abort(FatalError);
}
resetHandler("SIGFPE", SIGFPE);
// Reset exception raising
const int oldExcept = fedisableexcept

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
@ -56,7 +56,6 @@ SourceFiles
#ifndef sigFpe_H
#define sigFpe_H
#include <signal.h>
#include "scalar.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -64,7 +63,7 @@ SourceFiles
namespace Foam
{
// Forward declarations
// Forward Declarations
template<class T> class UList;
/*---------------------------------------------------------------------------*\
@ -73,7 +72,7 @@ template<class T> class UList;
class sigFpe
{
// Private data
// Private Data
//- Flag that floating point trapping should be used.
// Can override with FOAM_SIGFPE env variable
@ -83,20 +82,16 @@ class sigFpe
// Can override with FOAM_SETNAN env variable
static bool switchNan_;
//- Flag to indicate floating point trapping is currently active
//- Floating point trapping currently active?
static bool sigActive_;
//- Flag to indicate mallocNan is currently active
static bool nanActive_;
//- Saved old signal trapping setting
static struct sigaction oldAction_;
// Private Member Functions
//- Handler for caught signals.
// Ends job and prints stack
//- Handler for caught signals - ends job and prints stack
static void sigHandler(int);

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2015 OpenFOAM Foundation
@ -30,9 +30,11 @@ License
#include "JobInfo.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// File-local functions
#include "signalMacros.C"
struct sigaction Foam::sigInt::oldAction_;
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
bool Foam::sigInt::sigActive_ = false;
@ -41,16 +43,10 @@ bool Foam::sigInt::sigActive_ = false;
void Foam::sigInt::sigHandler(int)
{
// Reset old handling
if (sigaction(SIGINT, &oldAction_, nullptr) < 0)
{
FatalErrorInFunction
<< "Cannot reset SIGINT trapping"
<< abort(FatalError);
}
resetHandler("SIGINT", SIGINT);
jobInfo.signalEnd(); // Update jobInfo file
raise(SIGINT); // Throw signal (to old handler)
::raise(SIGINT); // Throw signal (to old handler)
}
@ -74,35 +70,25 @@ Foam::sigInt::~sigInt()
void Foam::sigInt::set(bool)
{
if (!sigActive_)
if (sigActive_)
{
struct sigaction newAction;
newAction.sa_handler = sigHandler;
newAction.sa_flags = SA_NODEFER;
sigemptyset(&newAction.sa_mask);
if (sigaction(SIGINT, &newAction, &oldAction_) < 0)
{
FatalErrorInFunction
<< "Cannot call sigInt::set() more than once"
<< abort(FatalError);
}
sigActive_ = true;
return;
}
sigActive_ = true;
setHandler("SIGINT", SIGINT, sigHandler);
}
void Foam::sigInt::unset(bool)
{
if (sigActive_)
if (!sigActive_)
{
if (sigaction(SIGINT, &oldAction_, nullptr) < 0)
{
FatalErrorInFunction
<< "Cannot set SIGINT trapping"
<< abort(FatalError);
}
sigActive_ = false;
return;
}
sigActive_ = false;
resetHandler("SIGINT", SIGINT);
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
@ -47,8 +47,6 @@ SourceFiles
#ifndef sigInt_H
#define sigInt_H
#include <signal.h>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
@ -62,10 +60,7 @@ class sigInt
{
// Private data
//- Saved old signal trapping setting
static struct sigaction oldAction_;
//- Flag to indicate signal trapping is enabled
//- Signal trapping enabled?
static bool sigActive_;

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2015 OpenFOAM Foundation
@ -30,9 +30,11 @@ License
#include "JobInfo.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// File-local functions
#include "signalMacros.C"
struct sigaction Foam::sigQuit::oldAction_;
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
bool Foam::sigQuit::sigActive_ = false;
@ -41,17 +43,11 @@ bool Foam::sigQuit::sigActive_ = false;
void Foam::sigQuit::sigHandler(int)
{
// Reset old handling
if (sigaction(SIGQUIT, &oldAction_, nullptr) < 0)
{
FatalErrorInFunction
<< "Cannot reset SIGQUIT trapping"
<< abort(FatalError);
}
resetHandler("SIGQUIT", SIGQUIT);
jobInfo.signalEnd(); // Update jobInfo file
error::printStack(Perr);
raise(SIGQUIT); // Throw signal (to old handler)
::raise(SIGQUIT); // Throw signal (to old handler)
}
@ -75,35 +71,25 @@ Foam::sigQuit::~sigQuit()
void Foam::sigQuit::set(bool)
{
if (!sigActive_)
if (sigActive_)
{
struct sigaction newAction;
newAction.sa_handler = sigHandler;
newAction.sa_flags = SA_NODEFER;
sigemptyset(&newAction.sa_mask);
if (sigaction(SIGQUIT, &newAction, &oldAction_) < 0)
{
FatalErrorInFunction
<< "Cannot call more than once"
<< abort(FatalError);
}
sigActive_ = true;
return;
}
sigActive_ = true;
setHandler("SIGQUIT", SIGQUIT, sigHandler);
}
void Foam::sigQuit::unset(bool)
{
if (sigActive_)
if (!sigActive_)
{
if (sigaction(SIGQUIT, &oldAction_, nullptr) < 0)
{
FatalErrorInFunction
<< "Cannot unset SIGQUIT trapping"
<< abort(FatalError);
}
sigActive_ = false;
return;
}
sigActive_ = false;
resetHandler("SIGQUIT", SIGQUIT);
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
@ -46,8 +46,6 @@ SourceFiles
#ifndef sigQuit_H
#define sigQuit_H
#include <signal.h>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
@ -59,12 +57,9 @@ namespace Foam
class sigQuit
{
// Private data
// Private Data
//- Saved old signal trapping setting
static struct sigaction oldAction_;
//- Flag to indicate signal trapping is enabled
//- Signal trapping enabled?
static bool sigActive_;
@ -86,7 +81,7 @@ public:
~sigQuit();
// Member functions
// Member Functions
//- Activate SIGQUIT signal handler
static void set(bool verbose=false);

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2015 OpenFOAM Foundation
@ -30,9 +30,11 @@ License
#include "JobInfo.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// File-local functions
#include "signalMacros.C"
struct sigaction Foam::sigSegv::oldAction_;
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
bool Foam::sigSegv::sigActive_ = false;
@ -41,17 +43,11 @@ bool Foam::sigSegv::sigActive_ = false;
void Foam::sigSegv::sigHandler(int)
{
// Reset old handling
if (sigaction(SIGSEGV, &oldAction_, nullptr) < 0)
{
FatalErrorInFunction
<< "Cannot reset SIGSEGV trapping"
<< abort(FatalError);
}
resetHandler("SIGSEGV", SIGSEGV);
jobInfo.signalEnd(); // Update jobInfo file
error::printStack(Perr);
raise(SIGSEGV); // Throw signal (to old handler)
::raise(SIGSEGV); // Throw signal (to old handler)
}
@ -75,35 +71,25 @@ Foam::sigSegv::~sigSegv()
void Foam::sigSegv::set(bool)
{
if (!sigActive_)
if (sigActive_)
{
struct sigaction newAction;
newAction.sa_handler = sigHandler;
newAction.sa_flags = SA_NODEFER;
sigemptyset(&newAction.sa_mask);
if (sigaction(SIGSEGV, &newAction, &oldAction_) < 0)
{
FatalErrorInFunction
<< "Cannot call more than once"
<< abort(FatalError);
}
sigActive_ = true;
return;
}
sigActive_ = true;
setHandler("SIGSEGV", SIGSEGV, sigHandler);
}
void Foam::sigSegv::unset(bool)
{
if (sigActive_)
if (!sigActive_)
{
if (sigaction(SIGSEGV, &oldAction_, nullptr) < 0)
{
FatalErrorInFunction
<< "Cannot unset SIGSEGV trapping"
<< abort(FatalError);
}
sigActive_ = false;
return;
}
sigActive_ = false;
resetHandler("SIGSEGV", SIGSEGV);
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
@ -46,8 +46,6 @@ SourceFiles
#ifndef sigSegv_H
#define sigSegv_H
#include <signal.h>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
@ -59,12 +57,9 @@ namespace Foam
class sigSegv
{
// Private data
// Private Data
//- Saved old signal trapping setting
static struct sigaction oldAction_;
//- Flag to indicate signal trapping is enabled
//- Signal trapping enabled?
static bool sigActive_;

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
@ -25,12 +25,17 @@ License
\*---------------------------------------------------------------------------*/
#include "sigWriteNow.H"
#include "sigStopAtWriteNow.H"
#include "error.H"
#include "JobInfo.H"
#include "IOstreams.H"
#include "Time.H"
// File-local functions
#include "signalMacros.C"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// Signal number to catch
@ -39,21 +44,19 @@ int Foam::sigStopAtWriteNow::signal_
Foam::debug::optimisationSwitch("stopAtWriteNowSignal", -1)
);
Foam::Time const* Foam::sigStopAtWriteNow::runTimePtr_ = nullptr;
// Pointer to Time (file-local variable)
static Foam::Time const* runTimePtr_ = nullptr;
struct sigaction Foam::sigStopAtWriteNow::oldAction_;
// * * * * * * * * * * * * * * * Local Classes * * * * * * * * * * * * * * * //
namespace Foam
{
// Register re-reader
class addstopAtWriteNowSignalToOpt
struct addstopAtWriteNowSignalToOpt
:
public ::Foam::simpleRegIOobject
{
public:
addstopAtWriteNowSignalToOpt(const char* name)
:
::Foam::simpleRegIOobject(Foam::debug::addOptimisationObject, name)
@ -85,15 +88,9 @@ addstopAtWriteNowSignalToOpt addstopAtWriteNowSignalToOpt_
void Foam::sigStopAtWriteNow::sigHandler(int)
{
// Reset old handling
if (sigaction(signal_, &oldAction_, nullptr) < 0)
{
FatalErrorInFunction
<< "Cannot reset " << signal_ << " trapping"
<< abort(FatalError);
}
resetHandler("stopAtWriteNow", signal_);
jobInfo.signalEnd(); // Update jobInfo file
jobInfo.signalEnd(); // Update jobInfo file
if (runTimePtr_)
{
@ -113,7 +110,7 @@ Foam::sigStopAtWriteNow::sigStopAtWriteNow()
Foam::sigStopAtWriteNow::sigStopAtWriteNow(const Time& runTime, bool verbose)
{
runTimePtr_ = &runTime; // Store runTime
runTimePtr_ = &runTime; // Store runTime
set(verbose);
}
@ -122,61 +119,55 @@ Foam::sigStopAtWriteNow::sigStopAtWriteNow(const Time& runTime, bool verbose)
Foam::sigStopAtWriteNow::~sigStopAtWriteNow()
{
// Reset old handling
if (signal_ > 0)
if (!active())
{
if (sigaction(signal_, &oldAction_, nullptr) < 0)
{
FatalErrorInFunction
<< "Cannot reset " << signal_ << " trapping"
<< abort(FatalError);
}
return;
}
resetHandler("stopAtWriteNow", signal_);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::sigStopAtWriteNow::set(bool verbose)
{
if (signal_ > 0)
{
// Check that the signal is different from the writeNowSignal
if (sigWriteNow::signal_ == signal_)
{
FatalErrorInFunction
<< "stopAtWriteNowSignal : " << signal_
<< " cannot be the same as the writeNowSignal."
<< " Please change this in the etc/controlDict."
<< exit(FatalError);
}
struct sigaction newAction;
newAction.sa_handler = sigHandler;
newAction.sa_flags = SA_NODEFER;
sigemptyset(&newAction.sa_mask);
if (sigaction(signal_, &newAction, &oldAction_) < 0)
{
FatalErrorInFunction
<< "Cannot set " << signal_ << " trapping"
<< abort(FatalError);
}
if (verbose)
{
Info<< "sigStopAtWriteNow :"
<< " Enabling writing and stopping upon signal " << signal_
<< endl;
}
}
}
bool Foam::sigStopAtWriteNow::active() const
bool Foam::sigStopAtWriteNow::active()
{
return signal_ > 0;
}
int Foam::sigStopAtWriteNow::signalNumber()
{
return signal_;
}
void Foam::sigStopAtWriteNow::set(bool verbose)
{
if (!active())
{
return;
}
// Check that the signal is different from the writeNowSignal
if (sigWriteNow::signalNumber() == signal_)
{
FatalErrorInFunction
<< "stopAtWriteNowSignal : " << signal_
<< " cannot be the same as the writeNowSignal."
<< " Please change this in the etc/controlDict."
<< exit(FatalError);
}
if (verbose)
{
Info<< "sigStopAtWriteNow :"
<< " Enabling writing and stopping upon signal " << signal_
<< endl;
}
setHandler("stopAtWriteNow", signal_, sigHandler);
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
@ -27,10 +27,8 @@ Class
Foam::sigStopAtWriteNow
Description
Signal handler for interupt defined by
OptimisationSwitches::stopAtWriteNowSignal
Write and stop the job.
Signal handler to write and stop the job.
The interrupt is defined by OptimisationSwitches::stopAtWriteNowSignal
SourceFiles
sigStopAtWriteNow.C
@ -40,32 +38,25 @@ SourceFiles
#ifndef sigStopAtWriteNow_H
#define sigStopAtWriteNow_H
#include <signal.h>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
class Time;
/*---------------------------------------------------------------------------*\
Class sigStopAtWriteNow Declaration
Class sigStopAtWriteNow Declaration
\*---------------------------------------------------------------------------*/
class sigStopAtWriteNow
{
// Private data
// Private Data
//- Number of signal to use
//- Signal number to use
static int signal_;
//- Pointer to Time
static Time const* runTimePtr_;
//- Saved old signal trapping setting
static struct sigaction oldAction_;
// Private Member Functions
@ -92,13 +83,16 @@ public:
~sigStopAtWriteNow();
// Member functions
//- (re)set signal catcher
static void set(bool verbose=false);
// Member Functions
//- Is active?
bool active() const;
static bool active();
//- Signal number being used
static int signalNumber();
//- Set/reset signal handler
static void set(bool verbose=false);
};

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
@ -31,6 +31,10 @@ License
#include "IOstreams.H"
#include "Time.H"
// File-local functions
#include "signalMacros.C"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// Signal number to catch
@ -39,22 +43,20 @@ int Foam::sigWriteNow::signal_
Foam::debug::optimisationSwitch("writeNowSignal", -1)
);
Foam::Time* Foam::sigWriteNow::runTimePtr_ = nullptr;
// Pointer to Time (file-local variable)
static Foam::Time* runTimePtr_ = nullptr;
struct sigaction Foam::sigWriteNow::oldAction_;
// * * * * * * * * * * * * * * * Local Classes * * * * * * * * * * * * * * * //
namespace Foam
{
// Register re-reader
class addwriteNowSignalToOpt
struct addwriteNowSignalToOpt
:
public ::Foam::simpleRegIOobject
{
public:
addwriteNowSignalToOpt(const char* name)
:
::Foam::simpleRegIOobject(Foam::debug::addOptimisationObject, name)
@ -100,7 +102,7 @@ Foam::sigWriteNow::sigWriteNow()
Foam::sigWriteNow::sigWriteNow(Time& runTime, bool verbose)
{
runTimePtr_ = &runTime; // Store runTime
runTimePtr_ = &runTime; // Store runTime
set(verbose);
}
@ -109,50 +111,44 @@ Foam::sigWriteNow::sigWriteNow(Time& runTime, bool verbose)
Foam::sigWriteNow::~sigWriteNow()
{
// Reset old handling
if (signal_ > 0)
if (!active())
{
if (sigaction(signal_, &oldAction_, nullptr) < 0)
{
FatalErrorInFunction
<< "Cannot reset " << signal_ << " trapping"
<< abort(FatalError);
}
return;
}
resetHandler("writeNow", signal_);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::sigWriteNow::set(bool verbose)
{
if (signal_ >= 0)
{
struct sigaction newAction;
newAction.sa_handler = sigHandler;
newAction.sa_flags = SA_NODEFER;
sigemptyset(&newAction.sa_mask);
if (sigaction(signal_, &newAction, &oldAction_) < 0)
{
FatalErrorInFunction
<< "Cannot set " << signal_ << " trapping"
<< abort(FatalError);
}
if (verbose)
{
Info<< "sigWriteNow :"
<< " Enabling writing upon signal " << signal_
<< endl;
}
}
}
bool Foam::sigWriteNow::active() const
bool Foam::sigWriteNow::active()
{
return signal_ > 0;
}
int Foam::sigWriteNow::signalNumber()
{
return signal_;
}
void Foam::sigWriteNow::set(bool verbose)
{
if (!active())
{
return;
}
if (verbose)
{
Info<< "sigWriteNow :"
<< " Enabling writing upon signal " << signal_ << nl;
}
setHandler("writeNow", signal_, sigHandler);
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
@ -27,9 +27,8 @@ Class
Foam::sigWriteNow
Description
Signal handler for interupt defined by OptimisationSwitches::writeNowSignal
Write once and continue.
Signal handler to write once and continue.
The interrupt is defined by OptimisationSwitches::writeNowSignal
SourceFiles
sigWriteNow.C
@ -39,32 +38,25 @@ SourceFiles
#ifndef sigWriteNow_H
#define sigWriteNow_H
#include <signal.h>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
class Time;
/*---------------------------------------------------------------------------*\
Class sigWriteNow Declaration
Class sigWriteNow Declaration
\*---------------------------------------------------------------------------*/
class sigWriteNow
{
// Private data
// Private Data
//- Number of signal to use
//- Signal number to use
static int signal_;
//- Pointer to Time
static Time* runTimePtr_;
//- Saved old signal trapping setting
static struct sigaction oldAction_;
// Private Member Functions
@ -74,8 +66,6 @@ class sigWriteNow
public:
friend class sigStopAtWriteNow;
//- Allow setter access to signal_
friend class addwriteNowSignalToOpt;
@ -96,9 +86,12 @@ public:
// Member Functions
//- Is active?
bool active() const;
static bool active();
//- (re)set signal catcher
//- The signal number being used
static int signalNumber();
//- Set/reset signal handler
static void set(bool verbose=false);
};

View File

@ -0,0 +1,74 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Description
File-local code for setting/resetting signal handlers.
SourceFiles
signalMacros.C
\*---------------------------------------------------------------------------*/
#include "error.H"
#include <csignal>
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Saved old signal trapping setting (file-local variable)
static struct sigaction oldAction_;
static void resetHandler(const char *what, int sigNum)
{
if (sigaction(sigNum, &oldAction_, nullptr) < 0)
{
FatalError
<< "Cannot unset " << what << " signal (" << sigNum
<< ") trapping" << endl
<< abort(FatalError);
}
}
static void setHandler(const char *what, int sigNum, void (*handler)(int))
{
struct sigaction newAction;
newAction.sa_handler = handler;
newAction.sa_flags = SA_NODEFER;
sigemptyset(&newAction.sa_mask);
if (sigaction(sigNum, &newAction, &oldAction_) < 0)
{
FatalError
<< "Could not set " << what << " signal (" << sigNum
<< ") trapping" << endl
<< abort(FatalError);
}
}
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,114 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010, 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "timer.H"
#include <unistd.h>
// File-local functions
#include "signalMacros.C"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(timer, 0);
}
jmp_buf Foam::timer::envAlarm;
unsigned int Foam::timer::oldTimeOut_ = 0;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::timer::sigHandler(int)
{
DebugInFunction<< "Timed out. Jumping." << endl;
longjmp(envAlarm, 1);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::timer::timer(unsigned int seconds)
:
timeOut_(seconds)
{
if (!timeOut_)
{
return;
}
// Singleton since handler is static function
if (oldTimeOut_)
{
FatalErrorInFunction
<< "timer already used."
<< abort(FatalError);
}
// Set alarm signal handler
// - do not block any signals while in it
// - clear list of signals to mask
setHandler("SIGALRM", SIGALRM, sigHandler);
// Set alarm timer
oldTimeOut_ = ::alarm(timeOut_);
DebugInFunction
<< "Installing timeout " << int(timeOut_) << " seconds"
<< " (overriding old timeout " << int(oldTimeOut_) << ")." << endl;
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::timer::~timer()
{
if (!timeOut_)
{
return;
}
DebugInFunction
<< "timeOut=" << int(timeOut_)
<< " : resetting timeOut to " << int(oldTimeOut_) << endl;
// Reset alarm timer
::alarm(oldTimeOut_);
oldTimeOut_ = 0;
resetHandler("SIGALRM", SIGALRM);
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2015 OpenFOAM Foundation
@ -46,14 +46,15 @@ Description
Constructor set signal handler on sigalarm and alarm(). Destructor
clears these.
timedOut is macro because setjmp can't be in member function of timer.
?something to do with stack frames.
Warning
The setjmp restores complete register state so including local vars
held in regs. So if in blocking part something gets calced in a stack
based variable make sure it is declared 'volatile'.
Note
timedOut is macro because setjmp can't be in member function of timer.
?something to do with stack frames.
SourceFiles
timer.C
@ -63,16 +64,14 @@ SourceFiles
#define timer_H
#include "className.H"
#include <signal.h>
#include <setjmp.h>
#include <csetjmp>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Check it a timeout has occured
//- Check if timeout has occurred
// keep setjmp in same stack frame so no function calls
#define timedOut(x) \
(((x).newTimeOut_ > 0) ? setjmp(Foam::timer::envAlarm) : false)
((x).timeOut_ ? setjmp(Foam::timer::envAlarm) : false)
namespace Foam
{
@ -83,10 +82,7 @@ namespace Foam
class timer
{
// Private data
//- Old signal masks
static struct sigaction oldAction_;
// Private Data
//- Old alarm() value
static unsigned int oldTimeOut_;
@ -95,18 +91,18 @@ class timer
// Private Member Functions
//- Alarm handler
static void signalHandler(int);
static void sigHandler(int);
public:
// Public data
// Public Data
//- Declare name of the class and its debug switch
ClassName("timer");
//- Current time out value. Needed by macro timedOut
unsigned int newTimeOut_;
//- The time-out value (seconds). Needed by macro timedOut
unsigned int timeOut_;
//- State for setjmp. Needed by macro timedOut
static jmp_buf envAlarm;
@ -118,7 +114,7 @@ public:
explicit timer(unsigned int seconds);
//- Destructor
//- Destructor. Restores the alarm and signal handler as required.
~timer();
};

View File

@ -1,133 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include <unistd.h>
#include "error.H"
#include "timer.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(timer, 0);
jmp_buf timer::envAlarm;
struct sigaction timer::oldAction_;
unsigned int timer::oldTimeOut_ = 0;
}
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
void Foam::timer::signalHandler(int)
{
if (debug)
{
InfoInFunction<< "Timed out. Jumping."
<< endl;
}
longjmp(envAlarm, 1);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::timer::timer(const unsigned int newTimeOut)
:
newTimeOut_(newTimeOut)
{
if (newTimeOut > 0)
{
// Is singleton since handler is static function
if (oldTimeOut_ != 0)
{
FatalErrorInFunction
<< "timer already used."
<< abort(FatalError);
}
// Install alarm signal handler:
// - do not block any signals while in it
// - clear list of signals to mask
struct sigaction newAction;
newAction.sa_handler = timer::signalHandler;
newAction.sa_flags = SA_NODEFER;
sigemptyset(&newAction.sa_mask);
if (sigaction(SIGALRM, &newAction, &oldAction_) < 0)
{
FatalErrorInFunction
<< "sigaction(SIGALRM) error"
<< abort(FatalError);
}
oldTimeOut_ = ::alarm(newTimeOut);
if (debug)
{
InfoInFunction
<< "Installing timeout " << int(newTimeOut_)
<< " seconds"
<< " (overriding old timeout " << int(oldTimeOut_)
<< ")." << endl;
}
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::timer::~timer()
{
if (newTimeOut_ > 0)
{
if (debug)
{
InfoInFunction
<< "timeOut=" << int(newTimeOut_)
<< " : resetting timeOut to " << int(oldTimeOut_) << endl;
}
// Reset timer
::alarm(oldTimeOut_);
oldTimeOut_ = 0;
// Restore signal handler
if (sigaction(SIGALRM, &oldAction_, nullptr) < 0)
{
FatalErrorInFunction
<< "sigaction(SIGALRM) error"
<< abort(FatalError);
}
}
}
// ************************************************************************* //