Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 10:00:37

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
0003 *                                                                                   *
0004 * This software is distributed under the terms of the Apache version 2 licence,     *
0005 * copied verbatim in the file "LICENSE".                                            *
0006 *                                                                                   *
0007 * In applying this licence, CERN does not waive the privileges and immunities       *
0008 * granted to it by virtue of its status as an Intergovernmental Organization        *
0009 * or submit itself to any jurisdiction.                                             *
0010 \***********************************************************************************/
0011 #ifndef GAUDIKERNEL_WATCHDOGTHREAD_H_
0012 #define GAUDIKERNEL_WATCHDOGTHREAD_H_
0013 
0014 #include <memory>
0015 #include <mutex>
0016 
0017 #include "boost/date_time/posix_time/posix_time_types.hpp"
0018 #include "boost/thread/thread_time.hpp"
0019 
0020 // for GAUDI_API
0021 #include "GaudiKernel/Kernel.h"
0022 
0023 // forward declaration
0024 namespace boost {
0025   class thread;
0026 }
0027 
0028 /** @class WatchdogThread
0029  *  Simple class for asynchronous check of time-out.
0030  *
0031  *  The user must provide a callable with the action to be performed when the
0032  *  time-out occurs.
0033  *
0034  *  @author Marco Clemencic
0035  *  @date   2010-02-23
0036  */
0037 class GAUDI_API WatchdogThread {
0038 public:
0039   /// Constructor.
0040   //  @param timeout the time span that can occur between two pings.
0041   //  @param autostart if set to true, the second thread is started automatically
0042   //                   on construction, otherwise the user have to call start().
0043   WatchdogThread( boost::posix_time::time_duration timeout, bool autostart = false );
0044 
0045   /// Destructor.
0046   //  Stop the thread of not done earlier.
0047   virtual ~WatchdogThread();
0048 
0049   /// Start the watchdog thread
0050   void start();
0051 
0052   /// Signal the watchdog thread to stop and wait for it.
0053   void stop();
0054 
0055   /// Function to call to notify the watchdog thread that we are still alive.
0056   inline void ping() {
0057     auto lock  = std::scoped_lock{ m_lastPingMutex };
0058     m_lastPing = boost::get_system_time();
0059     onPing();
0060   }
0061 
0062   /// Change the duration of the time-out.
0063   inline void setTimeout( boost::posix_time::time_duration timeout ) { m_timeout = timeout; }
0064 
0065   /// Get the current time-out value.
0066   inline boost::posix_time::time_duration getTimeout() const { return m_timeout; }
0067 
0068   /// Get the time of latest ping.
0069   inline boost::system_time getLastPing() const {
0070     auto lock = std::scoped_lock{ m_lastPingMutex };
0071     return m_lastPing;
0072   }
0073 
0074 protected:
0075   /// User implemented function that will be called if the time-out is reached.
0076   virtual void action();
0077 
0078   /// User implemented function that will be called when ping is called.
0079   virtual void onPing();
0080 
0081   /// User implemented function that will be called when starting.
0082   virtual void onStart();
0083 
0084   /// User implemented function that will be called when stopping.
0085   virtual void onStop();
0086 
0087 private:
0088   /// Number of seconds allowed between pings.
0089   boost::posix_time::time_duration m_timeout;
0090 
0091   /// When the last ping was received.
0092   boost::system_time m_lastPing;
0093 
0094   /// Pointer to the running thread;
0095   std::unique_ptr<boost::thread> m_thread;
0096 
0097   /// Flag to mark the thread as running/stopped (avoid possible race conditions).
0098   bool m_running;
0099 
0100   /// Core function of the secondary thread.
0101   //  Waits for the time-out and if there was not a ping in the mean time, calls
0102   //  i_action().
0103   void i_run();
0104 
0105   /// Mutex for the access to the m_lastPing data member.
0106   mutable std::mutex m_lastPingMutex;
0107 };
0108 
0109 #endif /* WATCHDOGTHREAD_H_ */