Timer.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package ArmarXCore::core
19  * @author Clemens Wallrath ( uagzs at student dot kit dot edu )
20  * @date 2015
21  * @copyright http://www.gnu.org/licenses/gpl.txt
22  * GNU General Public License
23  */
24 
25 #include <Ice/PropertiesF.h> // for upCast
26 
27 #include "../application/Application.h" // for Application, etc
30 #include "ArmarXCore/core/time/TimeUtil.h" // for TimeUtil
31 #include "ArmarXCore/interface/core/UserException.h"
32 #include "Timer.h"
33 
34 namespace armarx
35 {
36 
37  Timer::Timer(bool forceSystemTime):
38  called(false)
39  {
40 
41  useSystemTime = forceSystemTime || !Application::getInstance() || !Application::getInstance()->getProperty<bool>("UseTimeServer").getValue();
42 
43  if (useSystemTime)
44  {
45  iceTimer = new IceUtil::Timer;
46  }
47  else
48  {
49  running = true;
50  start();
51  }
52  }
53 
54  void Timer::schedule(const IceUtil::TimerTaskPtr& task, const IceUtil::Time& interval)
55  {
56 
57  if (useSystemTime)
58  {
59  iceTimer->schedule(task, interval);
60  }
61  else
62  {
64  {
65  std::unique_lock lock(scheduledTasksMutex);
66  scheduledTasks.push_back(ScheduledTask {task, endTime});
67  }
68  TimeUtil::GetTimeServer()->registerTimer(endTime, static_cast<CallbackReceiver*>(this));
69  }
70  }
71 
72  void Timer::scheduleRepeated(const IceUtil::TimerTaskPtr& task, const IceUtil::Time& interval)
73  {
74  throw NotImplementedYetException("scheduleReleated: function not yet implemented.");
75  }
76 
77  bool Timer::cancel(const IceUtil::TimerTaskPtr& task)
78  {
79  if (useSystemTime)
80  {
81  iceTimer->cancel(task);
82  }
83 
84  bool found = false;
85  {
86  std::unique_lock lock(scheduledTasksMutex);
87 
88  for (std::vector<ScheduledTask>::iterator it = scheduledTasks.begin(); it != scheduledTasks.end();)
89  {
90  if (it->task.get() == task.get())
91  {
92  it = scheduledTasks.erase(it);
93  found = true;
94  }
95  else
96  {
97  ++it;
98  }
99  }
100  }
101 
102  return found;
103  }
104 
105  void Timer::run()
106  {
107 
108  std::unique_lock lockWait(callbackWaitMutex);
109 
110  while (running)
111  {
112  std::vector<IceUtil::TimerTaskPtr> tasksToRun;
113  {
114  std::unique_lock lock(scheduledTasksMutex);
115 
116  for (std::vector<ScheduledTask>::iterator it = scheduledTasks.begin(); it != scheduledTasks.end();)
117  {
118  if (it->endTime < TimeUtil::GetTime())
119  {
120  tasksToRun.emplace_back(it->task);
121  it = scheduledTasks.erase(it);
122  }
123  else
124  {
125  ++it;
126  }
127  }
128  }
129 
130  for (std::vector<IceUtil::TimerTaskPtr>::iterator it = tasksToRun.begin(); it != tasksToRun.end(); ++it)
131  {
132  (*it)->runTimerTask();
133  }
134 
135  while (!called)
136  {
137  condWait.wait(lockWait); // wait for unlock via call() from LocalTimeServer
138  }
139  called = false;
140  }
141  }
142 
143  void Timer::call()
144  {
145  {
146  std::unique_lock lock(callbackWaitMutex);
147  called = true;
148  }
149  condWait.notify_all();
150  }
151 
153  {
154  return useSystemTime;
155  }
156 
158  {
159  //TODO: no schedule() after destroy()
160 
161  if (useSystemTime)
162  {
163  iceTimer->destroy();
164  return;
165  }
166  else
167  {
168  TimeUtil::GetTimeServer()->unregisterTimer(static_cast<CallbackReceiver*>(this));
169  }
170 
171  if (!isAlive())
172  {
173  return;
174  }
175 
176  running = false;
177  call(); //unlock the timer thread
178 
179  if (IceUtil::ThreadControl().id() == getThreadControl().id()) // called from Timer thread
180  {
181  getThreadControl().detach();
182  }
183  else // called from another thread
184  {
185  getThreadControl().join();
186  }
187  }
188 
190  {
191  destroy();
192 
193  if (scheduledTasksMutex.try_lock())
194  {
195  scheduledTasksMutex.unlock();
196  }
197  else
198  {
199  }
200 
201  if (callbackWaitMutex.try_lock())
202  {
203  callbackWaitMutex.unlock();
204  }
205  else
206  {
207  }
208 
209  }
210 }
armarx::Timer::destroy
void destroy()
destroys the Timer and detaches the exection thread if the calling thread is the timer thread,...
Definition: Timer.cpp:157
armarx::Timer::scheduledTasksMutex
std::mutex scheduledTasksMutex
used for locking scheduledTasks
Definition: Timer.h:131
armarx::ScheduledTask
Definition: Timer.h:41
armarx::Timer::iceTimer
IceUtil::TimerPtr iceTimer
timer for use in system time mode
Definition: Timer.h:146
armarx::TimeUtil::GetTimeServer
static LocalTimeServerPtr GetTimeServer()
Definition: TimeUtil.cpp:109
armarx::Timer::running
bool running
set to false to stop the execution thread
Definition: Timer.h:136
armarx::Timer::run
void run() override
the execution thread main method
Definition: Timer.cpp:105
armarx::Timer::schedule
void schedule(const IceUtil::TimerTaskPtr &task, const IceUtil::Time &interval)
schedules a task for execution
Definition: Timer.cpp:54
LocalTimeServer.h
armarx::Timer::callbackWaitMutex
std::mutex callbackWaitMutex
used for waiting for a callback from the LocalTimeServer
Definition: Timer.h:121
Property.h
armarx::interval
Interval< T > interval(T lo, T hi)
Definition: OccupancyGrid.h:26
Timer.h
armarx::CallbackReceiver
Used by CallbackWaitLock.
Definition: LocalTimeServer.h:42
armarx::Timer::~Timer
~Timer() override
Definition: Timer.cpp:189
armarx::Application::getInstance
static ApplicationPtr getInstance()
Retrieve shared pointer to the application object.
Definition: Application.cpp:289
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::TimeUtil::GetTime
static IceUtil::Time GetTime(TimeMode timeMode=TimeMode::VirtualTime)
Get the current time.
Definition: TimeUtil.cpp:42
armarx::Timer::call
void call() override
wakes up the execution thread to check if a task has to run
Definition: Timer.cpp:143
TimeUtil.h
armarx::Timer::scheduledTasks
std::vector< ScheduledTask > scheduledTasks
list of scheduled tasks
Definition: Timer.h:151
armarx::Timer::condWait
std::condition_variable condWait
used for waiting for a callback from the LocalTimeServer
Definition: Timer.h:126
armarx::Timer::scheduleRepeated
void scheduleRepeated(const IceUtil::TimerTaskPtr &task, const IceUtil::Time &interval)
schedules a task for repeated execution
Definition: Timer.cpp:72
armarx::Timer::called
bool called
if call() has been called.
Definition: Timer.h:141
armarx::Timer::getUseSystemTime
bool getUseSystemTime() const
Definition: Timer.cpp:152
armarx::Timer::useSystemTime
bool useSystemTime
if we are using the system time (or the TimeServer time)
Definition: Timer.h:116
armarx::Timer::cancel
bool cancel(const IceUtil::TimerTaskPtr &task)
cancels a task, returns true if the task was successfully canceled (i.e.
Definition: Timer.cpp:77
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::Timer::Timer
Timer(bool forceSystemTime=false)
constructs a new Timer and starts its execution thread.
Definition: Timer.cpp:37