00001 // -*- C++ -*- 00019 #include <coil/Listener.h> 00020 #include <coil/Timer.h> 00021 #include <coil/Time.h> 00022 namespace coil 00023 { 00031 Timer::Timer(TimeValue& interval) 00032 : m_interval(interval), m_running(false) 00033 { 00034 } 00035 00043 Timer::~Timer() 00044 { 00045 stop(); 00046 wait(); 00047 } 00048 00056 int Timer::open(void *args) 00057 { 00058 activate(); 00059 return 0; 00060 } 00061 00069 int Timer::svc(void) 00070 { 00071 TimeValue t_curr, t_pre, tm;; 00072 while (m_running) 00073 { 00074 invoke(); 00075 coil::sleep(m_interval); 00076 } 00077 return 0; 00078 } 00079 00080 //============================================================ 00081 // public functions 00082 //============================================================ 00090 void Timer::start() 00091 { 00092 Guard guard(m_runningMutex); 00093 if (!m_running) 00094 { 00095 m_running = true; 00096 open(0); 00097 } 00098 } 00099 00107 void Timer::stop() 00108 { 00109 Guard guard(m_runningMutex); 00110 m_running = false; 00111 } 00112 00120 void Timer::invoke() 00121 { 00122 Guard guard(m_taskMutex); 00123 for (size_t i(0), len(m_tasks.size()); i < len; ++i) 00124 { 00125 m_tasks[i].remains = m_tasks[i].remains - m_interval; 00126 if (m_tasks[i].remains.sign() <= 0) 00127 { 00128 m_tasks[i].listener->invoke(); 00129 m_tasks[i].remains = m_tasks[i].period; 00130 } 00131 } 00132 } 00133 00141 ListenerId Timer::registerListener(ListenerBase* listener, TimeValue tm) 00142 { 00143 Guard guard(m_taskMutex); 00144 00145 for (size_t i(0), len(m_tasks.size()); i < len; ++i) 00146 { 00147 if (m_tasks[i].listener == listener) 00148 { 00149 m_tasks[i].period = tm; 00150 m_tasks[i].remains = tm; 00151 return listener; 00152 } 00153 } 00154 m_tasks.push_back(Task(listener, tm)); 00155 return listener; 00156 } 00157 00165 bool Timer::unregisterListener(ListenerId id) 00166 { 00167 Guard guard(m_taskMutex); 00168 std::vector<Task>::iterator it; 00169 it = m_tasks.begin(); 00170 00171 for (size_t i(0), len(m_tasks.size()); i < len; ++i, ++it) 00172 { 00173 if (m_tasks[i].listener == id) 00174 { 00175 m_tasks.erase(it); 00176 return true; 00177 } 00178 } 00179 return false; 00180 } 00181 }; // namespace RTC