Gaudi Framework, version v23r2

Home   Generated: Thu Jun 28 2012

WatchdogThread.cpp

Go to the documentation of this file.
00001 /*
00002  * Implementation of the class WatchdogThread.
00003  */
00004 
00005 #include "GaudiKernel/WatchdogThread.h"
00006 #include "GaudiKernel/Sleep.h"
00007 
00008 #include <functional>
00009 
00010 #include <boost/thread/thread.hpp>
00011 
00012 WatchdogThread::WatchdogThread(boost::posix_time::time_duration timeout, bool autostart):
00013   m_timeout(timeout), m_running(false)
00014 {
00015   // Start the thread immediately if requested.
00016   if (autostart) start();
00017 }
00018 
00019 WatchdogThread::~WatchdogThread() {
00020   // Make sure the thread is stopped before exiting.
00021   stop();
00022 }
00023 
00024 void WatchdogThread::start() {
00025   if (!m_thread.get()) { // can be started only if the thread is not yet started
00026     m_running = true;
00027     // call user-defined function
00028     onStart();
00029     // Initialize the first "last ping"
00030     ping();
00031     // Start a new thread telling it to call the member function i_run()
00032     m_thread = std::auto_ptr<boost::thread>(new boost::thread(std::mem_fun(&WatchdogThread::i_run), this));
00033   }
00034 }
00035 
00036 void WatchdogThread::stop() {
00037   if (m_thread.get()) {
00038     m_running = false; // mark the thread as stopped (interrupt doesn't work if the thread is not sleeping)
00039     Gaudi::NanoSleep(1000000); // Wait a bit (1ms) to be sure that the interrupt happens during the sleep
00040     m_thread->interrupt(); // tell the thread to stop (if it is waiting)
00041     m_thread->join(); // wait for it
00042     m_thread.reset(); // delete it
00043     // call user-defined function
00044     onStop();
00045   }
00046 }
00047 
00048 void WatchdogThread::i_run() {
00049   // Copy of the last ping
00050   boost::system_time lastPing = getLastPing();
00051 
00052   // set initial check time
00053   boost::system_time nextCheck = lastPing + getTimeout();
00054 
00055   try {
00056     // enter infinite loop
00057     while (m_running) {
00058       // Wait until the next check point time is reached.
00059       // An early exit must be triggered by a call to this->interrupt(), which
00060       // will produce an exception during the sleep.
00061       boost::thread::sleep(nextCheck);
00062       // Check if there was a ping while we were sleeping
00063       if ( lastPing == getLastPing() ) { // no further accesses
00064         action();
00065         // schedule the next check for now + dt (seems a good estimate)
00066         nextCheck = boost::get_system_time() + getTimeout();
00067       } else { // there was a ping
00068         // schedule the next check for last_access + dt
00069         nextCheck = lastPing = getLastPing();
00070         nextCheck += getTimeout();
00071       }
00072     }
00073   }
00074   // Ignore the exception since it is used only to exit from the loop.
00075   catch (boost::thread_interrupted&) {}
00076 }
00077 
00078 // Default implementation: empty
00079 void WatchdogThread::action() {
00080 }
00081 
00082 // Default implementation: empty
00083 void WatchdogThread::onPing() {
00084 }
00085 
00086 // Default implementation: empty
00087 void WatchdogThread::onStart() {
00088 }
00089 
00090 // Default implementation: empty
00091 void WatchdogThread::onStop() {
00092 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Thu Jun 28 2012 23:27:25 for Gaudi Framework, version v23r2 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004