Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v31r0 (aeb156f0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
WatchdogThread.cpp
Go to the documentation of this file.
1 /*
2  * Implementation of the class WatchdogThread.
3  */
4 
6 #include "GaudiKernel/Sleep.h"
7 
8 #include <functional>
9 
10 #include <boost/thread/thread.hpp>
11 
12 WatchdogThread::WatchdogThread( boost::posix_time::time_duration timeout, bool autostart )
13  : m_timeout( std::move( timeout ) ), m_running( false ) {
14  // Start the thread immediately if requested.
15  if ( autostart ) start();
16 }
17 
19  // Make sure the thread is stopped before exiting.
20  stop();
21 }
22 
24  if ( !m_thread ) { // can be started only if the thread is not yet started
25  m_running = true;
26  // call user-defined function
27  onStart();
28  // Initialize the first "last ping"
29  ping();
30  // Start a new thread telling it to call the member function i_run()
31  m_thread = std::make_unique<boost::thread>( std::mem_fn( &WatchdogThread::i_run ), this );
32  }
33 }
34 
36  if ( m_thread ) {
37  m_running = false; // mark the thread as stopped (interrupt doesn't work if the thread is not sleeping)
38  Gaudi::NanoSleep( 1000000 ); // Wait a bit (1ms) to be sure that the interrupt happens during the sleep
39  m_thread->interrupt(); // tell the thread to stop (if it is waiting)
40  m_thread->join(); // wait for it
41  m_thread.reset(); // delete it
42  // call user-defined function
43  onStop();
44  }
45 }
46 
48  // Copy of the last ping
49  boost::system_time lastPing = getLastPing();
50 
51  // set initial check time
52  boost::system_time nextCheck = lastPing + getTimeout();
53 
54  try {
55  // enter infinite loop
56  while ( m_running ) {
57  // Wait until the next check point time is reached.
58  // An early exit must be triggered by a call to this->interrupt(), which
59  // will produce an exception during the sleep.
60  boost::thread::sleep( nextCheck );
61  // Check if there was a ping while we were sleeping
62  if ( lastPing == getLastPing() ) { // no further accesses
63  action();
64  // schedule the next check for now + dt (seems a good estimate)
65  nextCheck = boost::get_system_time() + getTimeout();
66  } else { // there was a ping
67  // schedule the next check for last_access + dt
68  nextCheck = lastPing = getLastPing();
69  nextCheck += getTimeout();
70  }
71  }
72  }
73  // Ignore the exception since it is used only to exit from the loop.
74  catch ( boost::thread_interrupted& ) {}
75 }
76 
77 // Default implementation: empty
79 
80 // Default implementation: empty
82 
83 // Default implementation: empty
85 
86 // Default implementation: empty
boost::posix_time::time_duration getTimeout() const
Get the current time-out value.
void start()
Start the watchdog thread.
virtual void onStop()
User implemented function that will be called when stopping.
STL namespace.
GAUDI_API void NanoSleep(long long nsec)
Small variation on the sleep function for nanoseconds sleep.
Definition: Sleep.cpp:9
void ping()
Function to call to notify the watchdog thread that we are still alive.
virtual ~WatchdogThread()
Destructor.
T reset(T...args)
bool m_running
Flag to mark the thread as running/stopped (avoid possible race conditions).
virtual void onPing()
User implemented function that will be called when ping is called.
void stop()
Signal the watchdog thread to stop and wait for it.
T mem_fn(T...args)
virtual void action()
User implemented function that will be called if the time-out is reached.
WatchdogThread(boost::posix_time::time_duration timeout, bool autostart=false)
Constructor.
void i_run()
Core function of the secondary thread.
std::unique_ptr< boost::thread > m_thread
Pointer to the running thread;.
boost::system_time getLastPing() const
Get the time of latest ping.
virtual void onStart()
User implemented function that will be called when starting.