Tekkotsu Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
FailsafeThread.hGo to the documentation of this file.00001 //-*-c++-*- 00002 #ifndef INCLUDED_FailsafeThread_h_ 00003 #define INCLUDED_FailsafeThread_h_ 00004 00005 #include <unistd.h> // for usleep 00006 00007 #include "Shared/TimeET.h" 00008 00009 //! Enforces a timeout on another thread 00010 /*! The target thread needs to either complete execution or set the progressFlag to 'true' 00011 * within the specified timeout period. If the progressFlag is set, it will be cleared at the 00012 * end of the timeout, thus requiring the target to re-set within the next timeout period. */ 00013 class FailsafeThread : public Thread { 00014 public: 00015 //! constructor, specify target thread, timeout period, and optionally whether to start now 00016 FailsafeThread(Thread& th, const TimeET& delayTime, bool autostart=false) 00017 : Thread(), restartFlag(false), progressFlag(false), delay(useconds_t(delayTime.Value()*1000000)), engageFunc(&Thread::stop), target(th), engaged(false) { if(autostart) start(); } 00018 00019 //! if set to true, the failsafe thread will restart the target if it times out instead of just stopping it 00020 volatile bool restartFlag; 00021 00022 //! should be set by target thread if it's still making progress and wants another #delay 00023 volatile bool progressFlag; 00024 00025 //! microseconds to wait between checks on #progressFlag 00026 /*! Changing this value won't change the @e current timeout period. You would need to stop and 00027 * restart the thread for a change to immediately take effect. */ 00028 volatile useconds_t delay; 00029 00030 //! the function to call on the target thread, defaults to Thread::stop, but Thread::interrupt may be useful 00031 Thread& (Thread::*engageFunc)(); 00032 00033 //! returns true if the FailsafeThread is waiting for the target to stop running 00034 /*! This is useful for the target thread to check whether it is being stopped from a timeout 00035 * (in which case isEngaged() will return true), or if it has been stopped for some other reason. */ 00036 bool isEngaged() const { return engaged; } 00037 00038 protected: 00039 virtual unsigned int runloop() { 00040 engaged=false; 00041 // sleep as long as progress is being made 00042 usleep(delay); 00043 testCancel(); 00044 while(progressFlag) { 00045 progressFlag=false; 00046 usleep(delay); 00047 testCancel(); 00048 } 00049 // no more progress -- is the thread still running? 00050 if(!target.isStarted()) 00051 return -1U; // no, go away 00052 // yes, stop it 00053 //std::cout << "failsafe engaged" << std::endl; 00054 engaged=true; 00055 (target.*engageFunc)(); 00056 // we killed it... restart it? 00057 if(!restartFlag) 00058 return -1U; // no, go away 00059 // yes, wait for stop to go through, then start it again 00060 target.join(); 00061 if(!restartFlag) // check again just in case restart was changed while waiting for join() 00062 return -1U; 00063 testCancel(); 00064 target.start(); 00065 engaged=false; 00066 return 0; 00067 } 00068 00069 //virtual void cancelled() { engaged=false; } 00070 00071 //! the thread being monitored (or at least the one that will be stopped if progressFlag isn't set) 00072 Thread& target; 00073 00074 //! set to true when FailsafeThread is in the process of stopping (and possibly restarting) the target thread 00075 bool engaged; 00076 }; 00077 00078 00079 /*! @file 00080 * @brief Describes FailsafeThread, which enforces a timeout on another thread 00081 * @author Ethan Tira-Thompson (ejt) (Creator) 00082 */ 00083 00084 #endif |
Tekkotsu v5.1CVS |
Generated Mon May 9 04:58:38 2016 by Doxygen 1.6.3 |