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 "Timer.h"
26 
27 #include <Ice/PropertiesF.h> // for upCast
28 
31 #include "ArmarXCore/core/time/TimeUtil.h" // for TimeUtil
32 #include "ArmarXCore/interface/core/UserException.h"
33 
34 #include "../application/Application.h" // for Application, etc
35 
36 namespace armarx
37 {
38 
39  Timer::Timer(bool forceSystemTime) : called(false)
40  {
41 
42  useSystemTime = forceSystemTime || !Application::getInstance() ||
43  !Application::getInstance()->getProperty<bool>("UseTimeServer").getValue();
44 
45  if (useSystemTime)
46  {
47  iceTimer = new IceUtil::Timer;
48  }
49  else
50  {
51  running = true;
52  start();
53  }
54  }
55 
56  void
57  Timer::schedule(const IceUtil::TimerTaskPtr& task, const IceUtil::Time& interval)
58  {
59 
60  if (useSystemTime)
61  {
62  iceTimer->schedule(task, interval);
63  }
64  else
65  {
67  {
68  std::unique_lock lock(scheduledTasksMutex);
69  scheduledTasks.push_back(ScheduledTask{task, endTime});
70  }
71  TimeUtil::GetTimeServer()->registerTimer(endTime, static_cast<CallbackReceiver*>(this));
72  }
73  }
74 
75  void
76  Timer::scheduleRepeated(const IceUtil::TimerTaskPtr& task, const IceUtil::Time& interval)
77  {
78  throw NotImplementedYetException("scheduleReleated: function not yet implemented.");
79  }
80 
81  bool
82  Timer::cancel(const IceUtil::TimerTaskPtr& task)
83  {
84  if (useSystemTime)
85  {
86  iceTimer->cancel(task);
87  }
88 
89  bool found = false;
90  {
91  std::unique_lock lock(scheduledTasksMutex);
92 
93  for (std::vector<ScheduledTask>::iterator it = scheduledTasks.begin();
94  it != scheduledTasks.end();)
95  {
96  if (it->task.get() == task.get())
97  {
98  it = scheduledTasks.erase(it);
99  found = true;
100  }
101  else
102  {
103  ++it;
104  }
105  }
106  }
107 
108  return found;
109  }
110 
111  void
113  {
114 
115  std::unique_lock lockWait(callbackWaitMutex);
116 
117  while (running)
118  {
119  std::vector<IceUtil::TimerTaskPtr> tasksToRun;
120  {
121  std::unique_lock lock(scheduledTasksMutex);
122 
123  for (std::vector<ScheduledTask>::iterator it = scheduledTasks.begin();
124  it != scheduledTasks.end();)
125  {
126  if (it->endTime < TimeUtil::GetTime())
127  {
128  tasksToRun.emplace_back(it->task);
129  it = scheduledTasks.erase(it);
130  }
131  else
132  {
133  ++it;
134  }
135  }
136  }
137 
138  for (std::vector<IceUtil::TimerTaskPtr>::iterator it = tasksToRun.begin();
139  it != tasksToRun.end();
140  ++it)
141  {
142  (*it)->runTimerTask();
143  }
144 
145  while (!called)
146  {
147  condWait.wait(lockWait); // wait for unlock via call() from LocalTimeServer
148  }
149  called = false;
150  }
151  }
152 
153  void
155  {
156  {
157  std::unique_lock lock(callbackWaitMutex);
158  called = true;
159  }
160  condWait.notify_all();
161  }
162 
163  bool
165  {
166  return useSystemTime;
167  }
168 
169  void
171  {
172  //TODO: no schedule() after destroy()
173 
174  if (useSystemTime)
175  {
176  iceTimer->destroy();
177  return;
178  }
179  else
180  {
181  TimeUtil::GetTimeServer()->unregisterTimer(static_cast<CallbackReceiver*>(this));
182  }
183 
184  if (!isAlive())
185  {
186  return;
187  }
188 
189  running = false;
190  call(); //unlock the timer thread
191 
192  if (IceUtil::ThreadControl().id() == getThreadControl().id()) // called from Timer thread
193  {
194  getThreadControl().detach();
195  }
196  else // called from another thread
197  {
198  getThreadControl().join();
199  }
200  }
201 
203  {
204  destroy();
205 
206  if (scheduledTasksMutex.try_lock())
207  {
208  scheduledTasksMutex.unlock();
209  }
210  else
211  {
212  }
213 
214  if (callbackWaitMutex.try_lock())
215  {
216  callbackWaitMutex.unlock();
217  }
218  else
219  {
220  }
221  }
222 } // namespace armarx
armarx::Timer::destroy
void destroy()
destroys the Timer and detaches the exection thread if the calling thread is the timer thread,...
Definition: Timer.cpp:170
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:118
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:112
armarx::Timer::schedule
void schedule(const IceUtil::TimerTaskPtr &task, const IceUtil::Time &interval)
schedules a task for execution
Definition: Timer.cpp:57
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:33
Timer.h
armarx::CallbackReceiver
Used by CallbackWaitLock.
Definition: LocalTimeServer.h:42
armarx::Timer::~Timer
~Timer() override
Definition: Timer.cpp:202
armarx::Application::getInstance
static ApplicationPtr getInstance()
Retrieve shared pointer to the application object.
Definition: Application.cpp:315
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:154
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:76
armarx::Timer::called
bool called
if call() has been called.
Definition: Timer.h:141
armarx::Timer::getUseSystemTime
bool getUseSystemTime() const
Definition: Timer.cpp:164
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:82
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::Timer::Timer
Timer(bool forceSystemTime=false)
constructs a new Timer and starts its execution thread.
Definition: Timer.cpp:39