timer.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2011 Symscape
10  Copyright (C) 2019 OpenCFD Ltd.
11 -------------------------------------------------------------------------------
12 License
13  This file is part of OpenFOAM.
14 
15  OpenFOAM is free software: you can redistribute it and/or modify it
16  under the terms of the GNU General Public License as published by
17  the Free Software Foundation, either version 3 of the License, or
18  (at your option) any later version.
19 
20  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
21  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23  for more details.
24 
25  You should have received a copy of the GNU General Public License
26  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
27 
28 \*---------------------------------------------------------------------------*/
29 
30 #include "timer.H"
31 #include "error.H"
32 #include "MSwindows.H"
33 #undef DebugInfo // Windows name clash with OpenFOAM messageStream
34 
35 #define WIN32_LEAN_AND_MEAN
36 #undef WINVER
37 #define WINVER 0x0500 // To access CreateTimerQueueTimer
38 #include <windows.h>
39 
40 // File-local functions
41 #include "signalMacros.C"
42 
43 #define SIGALRM 14
44 
45 
46 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
47 
48 namespace Foam
49 {
50  defineTypeNameAndDebug(timer, 0);
51 }
52 
53 jmp_buf Foam::timer::envAlarm;
54 
55 unsigned int Foam::timer::oldTimeOut_ = 0;
56 
57 static HANDLE hTimer_ = nullptr;
58 
59 
60 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
61 
62 static VOID CALLBACK timerExpired(PVOID lpParam, BOOLEAN TimerOrWaitFired)
63 {
64  ::raise(SIGALRM);
65 }
66 
67 
68 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
69 
70 void Foam::timer::sigHandler(int)
71 {
72  DebugInFunction << "Timed out. Jumping." << endl;
73 
74  longjmp(envAlarm, 1);
75 }
76 
77 
78 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
79 
80 Foam::timer::timer(unsigned int seconds)
81 :
82  timeOut_(seconds)
83 {
84  if (!timeOut_)
85  {
86  return;
87  }
88 
89  // Singleton since handler is static function
90  if (hTimer_)
91  {
93  << "timer already used."
94  << abort(FatalError);
95  }
96 
97  // Set alarm signal handler
98  setHandler("SIGALRM", SIGALRM, sigHandler);
99 
100  // Set alarm timer
101  const bool ok = ::CreateTimerQueueTimer
102  (
103  &hTimer_,
104  nullptr,
105  static_cast<WAITORTIMERCALLBACK>(timerExpired),
106  nullptr,
107  timeOut_ * 1000,
108  0,
109  0
110  );
111 
112  if (!ok)
113  {
114  hTimer_ = nullptr;
116  << "CreateTimerQueueTimer, "
117  << MSwindows::lastError() << nl
118  << abort(FatalError);
119  }
120 
122  << "Installing timeout " << int(timeOut_) << " seconds"
123  << " (overriding old timeout " << int(oldTimeOut_) << ")." << endl;
124 }
125 
126 
127 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
128 
130 {
131  if (!timeOut_)
132  {
133  return;
134  }
135 
137  << "timeOut=" << int(timeOut_)
138  << " : resetting timeOut to " << int(oldTimeOut_) << endl;
139 
140  // Reset alarm timer
141  const bool ok = ::DeleteTimerQueueTimer(nullptr, hTimer_, nullptr);
142 
143  hTimer_ = nullptr;
144 
145  if (!ok)
146  {
148  << "DeleteTimerQueueTimer, "
149  << MSwindows::lastError() << nl
150  << abort(FatalError);
151  }
152 
153  resetHandler("SIGALRM", SIGALRM);
154 }
155 
156 
157 // ************************************************************************* //
Foam::timer::~timer
~timer()
Destructor. Restores the alarm and signal handler as required.
Definition: timer.C:129
Foam::resetHandler
static void resetHandler(const char *what, int sigNum)
Definition: signalMacros.C:46
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
error.H
DebugInFunction
#define DebugInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:388
Foam::timer::timer
timer(unsigned int seconds)
Construct with specified time-out, a value of 0 makes it a no-op.
Definition: timer.C:80
Foam::timer::envAlarm
static jmp_buf envAlarm
State for setjmp. Needed by macro timedOut.
Definition: timer.H:108
signalMacros.C
File-local code for setting/resetting signal handlers.
Foam::FatalError
error FatalError
timer.H
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::MSwindows::lastError
std::string lastError()
The last Windows API error from GetLastError.
Definition: MSwindows.C:253
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
timerExpired
static VOID CALLBACK timerExpired(PVOID lpParam, BOOLEAN TimerOrWaitFired)
Definition: timer.C:62
hTimer_
static HANDLE hTimer_
Definition: timer.C:57
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::setHandler
static void setHandler(const char *what, int sigNum, void(*handler)(int))
Definition: signalMacros.C:61
Foam::nl
constexpr char nl
Definition: Ostream.H:404
MSwindows.H
Foam::timer::timeOut_
unsigned int timeOut_
The time-out value (seconds). Needed by macro timedOut.
Definition: timer.H:105
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
SIGALRM
#define SIGALRM
Definition: timer.C:43