All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups 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(timeout), m_running(false)
14 {
15  // Start the thread immediately if requested.
16  if (autostart) start();
17 }
18 
20  // Make sure the thread is stopped before exiting.
21  stop();
22 }
23 
25  if (!m_thread.get()) { // can be started only if the thread is not yet started
26  m_running = true;
27  // call user-defined function
28  onStart();
29  // Initialize the first "last ping"
30  ping();
31  // Start a new thread telling it to call the member function i_run()
32  m_thread = std::auto_ptr<boost::thread>(new boost::thread(std::mem_fun(&WatchdogThread::i_run), this));
33  }
34 }
35 
37  if (m_thread.get()) {
38  m_running = false; // mark the thread as stopped (interrupt doesn't work if the thread is not sleeping)
39  Gaudi::NanoSleep(1000000); // Wait a bit (1ms) to be sure that the interrupt happens during the sleep
40  m_thread->interrupt(); // tell the thread to stop (if it is waiting)
41  m_thread->join(); // wait for it
42  m_thread.reset(); // delete it
43  // call user-defined function
44  onStop();
45  }
46 }
47 
49  // Copy of the last ping
50  boost::system_time lastPing = getLastPing();
51 
52  // set initial check time
53  boost::system_time nextCheck = lastPing + getTimeout();
54 
55  try {
56  // enter infinite loop
57  while (m_running) {
58  // Wait until the next check point time is reached.
59  // An early exit must be triggered by a call to this->interrupt(), which
60  // will produce an exception during the sleep.
61  boost::thread::sleep(nextCheck);
62  // Check if there was a ping while we were sleeping
63  if ( lastPing == getLastPing() ) { // no further accesses
64  action();
65  // schedule the next check for now + dt (seems a good estimate)
66  nextCheck = boost::get_system_time() + getTimeout();
67  } else { // there was a ping
68  // schedule the next check for last_access + dt
69  nextCheck = lastPing = getLastPing();
70  nextCheck += getTimeout();
71  }
72  }
73  }
74  // Ignore the exception since it is used only to exit from the loop.
75  catch (boost::thread_interrupted&) {}
76 }
77 
78 // Default implementation: empty
80 }
81 
82 // Default implementation: empty
84 }
85 
86 // Default implementation: empty
88 }
89 
90 // Default implementation: empty
92 }
std::auto_ptr< boost::thread > m_thread
Pointer to the running thread;.
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.
GAUDI_API void NanoSleep(long long nsec)
Small variation on the sleep function for nanoseconds sleep.
Definition: Sleep.cpp:30
void ping()
Function to call to notify the watchdog thread that we are still alive.
virtual ~WatchdogThread()
Destructor.
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.
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.
boost::system_time getLastPing() const
Get the time of latest ping.
virtual void onStart()
User implemented function that will be called when starting.