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