00001
00002 #ifndef DDF_PERIODICTHREAD_HPP
00003 #define DDF_PERIODICTHREAD_HPP
00004
00005 #include "stopwatch.hpp"
00006
00007 namespace jafar
00008 {
00009 namespace ddf
00010 {
00011
00017 class Timer_Command
00018 {
00019 private:
00020 bool m_kill;
00021 bool m_run;
00022 bool m_initialized;
00023 mutable boost::mutex m_mutex;
00024
00025 public:
00026 Timer_Command(): m_kill(false), m_run(false), m_initialized(false) { }
00027
00028 void Kill(bool val) { boost::mutex::scoped_lock lock(m_mutex); m_kill = val; }
00029 void Run(bool val) { boost::mutex::scoped_lock lock(m_mutex); m_run = val; m_initialized = !m_run; }
00030 bool IsRunning() { return m_run; }
00031 bool IsInitialized() { boost::mutex::scoped_lock lock(m_mutex); return m_initialized;}
00032 void SetInitialized() { boost::mutex::scoped_lock lock(m_mutex); m_initialized = true; }
00033 bool IsKilled() { return m_kill; }
00034 };
00035
00040 template<typename T>
00041 class Thread_Periodic_Func
00042 {
00043
00044 private:
00045 time m_period;
00046 Timer_Command &m_pth_cmd;
00047 T *m_parent;
00048
00049 public:
00050
00051 Thread_Periodic_Func(time period, Timer_Command &pth_cmd, T *obj)
00052 : m_period(period), m_pth_cmd(pth_cmd) { m_parent = obj; }
00053
00054 ~Thread_Periodic_Func() { }
00055
00056 void operator()()
00057 {
00058 StopWatch period_check;
00059 time horizon = time::current();
00060 time elapsed, t_tmp(0,20000);
00061 bool first = true;
00062 int call_nr = 0;
00063
00064 while(1)
00065 {
00066 if(m_pth_cmd.IsRunning())
00067 {
00068 if(first)
00069 {
00070 horizon = m_parent->GetNextHorizon();
00071 period_check.Restart();
00072 first = false;
00073 m_pth_cmd.SetInitialized();
00074 }
00075 else
00076 {
00077 horizon = horizon + m_period;
00078 m_parent->SetNextHorizon(horizon);
00079 }
00080
00081
00082 horizon.sleep_until();
00083
00084 if (m_pth_cmd.IsRunning())
00085 {
00086
00087 elapsed = period_check.ElapsedAndReset();
00088
00089
00090 m_parent->ExecSyncThreadFunc(horizon, elapsed, call_nr++);
00091 }
00092 }
00093 else {
00094 first = true;
00095 call_nr = 0;
00096 t_tmp.sleep_period();
00097
00098 }
00099
00100 if(m_pth_cmd.IsKilled()) break;
00101 }
00102 }
00103 };
00104
00105 }
00106 }
00107 #endif