Orocos Real-Time Toolkit  2.8.3
TaskCore.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: FMTC Tue Mar 11 21:49:25 CET 2008 TaskCore.cpp
3 
4  TaskCore.cpp - description
5  -------------------
6  begin : Tue March 11 2008
7  copyright : (C) 2008 FMTC
8  email : peter.soetens@fmtc.be
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * Lesser General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
38 
39 
40 #include "TaskCore.hpp"
41 #include "../ExecutionEngine.hpp"
42 #include "ActivityInterface.hpp"
43 #include "Logger.hpp"
44 #include "internal/CatchConfig.hpp"
45 
46 namespace RTT {
47  using namespace detail;
48 
49  using namespace std;
50 
51  TaskCore::TaskCore(TaskState initial_state /*= Stopped*/ )
52  : ee( new ExecutionEngine(this) )
53  ,mTaskState(initial_state)
54  ,mInitialState(initial_state)
55  ,mTargetState(initial_state)
56  {
57  }
58 
59  TaskCore::TaskCore( ExecutionEngine* parent, TaskState initial_state /*= Stopped*/ )
60  : ee( parent )
61  ,mTaskState(initial_state)
62  ,mInitialState(initial_state)
63  ,mTargetState(initial_state)
64  {
65  parent->addChild( this );
66  }
67 
68 
70  {
71  if ( ee->getParent() == this ) {
72  delete ee;
73  } else {
74  ee->removeChild(this);
75  }
76  // Note: calling cleanup() here has no use or even dangerous, as
77  // cleanupHook() is a virtual function and the user code is already
78  // destroyed. The user's subclass is responsible to make this state
79  // transition in its destructor if required.
80  }
81 
83  return mTaskState;
84  }
85 
87  return mTargetState;
88  }
89 
91  {
92  if ( !this->engine()->getActivity() )
93  return false;
94  return this->engine()->getActivity()->execute();
95  }
96 
98  {
99  if ( !this->engine()->getActivity() )
100  return false;
101  return this->engine()->getActivity()->trigger();
102  }
103 
106  TRY(
107  mTargetState = Stopped;
108  bool successful = configureHook();
109  if (successful) {
110  if (mTaskState != Stopped && (mTaskState == mTargetState)) {
111  log(Error) << "in configure(): state has been changed inside the configureHook" << endlog();
112  log(Error) << " but configureHook returned true. Bailing out." << endlog();
113  exception();
114  return false;
115  }
116  else {
118  return true;
119  }
120  } else {
121  mTargetState = mTaskState = PreOperational;
122  return false;
123  }
124  ) CATCH(std::exception const& e,
125  log(Error) << "in configure(): switching to exception state because of unhandled exception" << endlog();
126  log(Error) << " " << e.what() << endlog();
127  exception();
128  ) CATCH_ALL(
129  log(Error) << "in configure(): switching to exception state because of unhandled exception" << endlog();
130  exception();
131  )
132  }
133  return false; // no configure when running.
134  }
135 
137  if ( mTaskState == Stopped ) {
138  TRY(
139  mTargetState = PreOperational;
140  cleanupHook();
141  if (mTaskState == Stopped)
143  return true;
144  ) CATCH(std::exception const& e,
145  log(Error) << "in cleanup(): switching to exception state because of unhandled exception" << endlog();
146  log(Error) << " " << e.what() << endlog();
147  exception();
148  ) CATCH_ALL (
149  log(Error) << "in cleanup(): switching to exception state because of unhandled exception" << endlog();
150  exception();
151  )
152  }
153  return false; // no cleanup when running or not configured.
154  }
155 
157  mTargetState = mTaskState = FatalError;
158  if ( engine()->getActivity() )
159  engine()->getActivity()->stop();
160  }
161 
163  // detects error() from within start():
164  if (mTargetState < Running)
165  return;
166  mTargetState = mTaskState = RunTimeError;
167  }
168 
170  //log(Error) <<"Exception happend in TaskCore."<<endlog();
171  TaskState copy = mTaskState;
172  mTargetState = mTaskState = Exception;
173  TRY (
174  if ( copy >= Running ) {
175  stopHook();
176  }
177  if ( copy >= Stopped && mInitialState == PreOperational ) {
178  cleanupHook();
179  }
180  exceptionHook();
181  ) CATCH(std::exception const& e,
182  log(RTT::Error) << "stopHook(), cleanupHook() and/or exceptionHook() raised " << e.what() << ", going into Fatal" << endlog();
183  fatal();
184  ) CATCH_ALL (
185  log(Error) << "stopHook(), cleanupHook() and/or exceptionHook() raised an exception, going into Fatal" << endlog();
186  fatal();
187  )
188  }
189 
191  if ( mTaskState == Exception ) {
192  mTargetState = mTaskState = mInitialState;
193  return true;
194  }
195  if (mTaskState == RunTimeError && mTargetState >= Running) {
196  mTargetState = mTaskState = Running;
197  return true;
198  }
199  return false;
200  }
201 
203  if ( mTaskState == Stopped ) {
204  TRY (
205  mTargetState = Running;
206  bool successful = startHook();
207  if (successful) {
208  if (mTaskState != Running && (mTargetState == mTaskState)) {
209  log(Error) << "in start(): state has been changed inside the startHook" << endlog();
210  log(Error) << " but startHook returned true. Bailing out." << endlog();
211  exception();
212  return false;
213  }
214  else {
216  trigger(); // triggers updateHook() in case of non periodic!
217  return true;
218  }
219  }
220  mTargetState = Stopped;
221  ) CATCH(std::exception const& e,
222  log(Error) << "in start(): switching to exception state because of unhandled exception" << endlog();
223  log(Error) << " " << e.what() << endlog();
224  exception();
225  ) CATCH_ALL (
226  log(Error) << "in start(): switching to exception state because of unhandled exception" << endlog();
227  exception();
228  )
229  }
230  return false;
231  }
232 
233  bool TaskCore::stop() {
234  TaskState orig = mTaskState;
235  if ( mTaskState >= Running ) {
236  TRY(
237  mTargetState = Stopped;
238  if ( engine()->stopTask(this) ) {
239  stopHook();
241  return true;
242  } else {
243  mTaskState = orig;
244  mTargetState = orig;
245  }
246  ) CATCH(std::exception const& e,
247  log(Error) << "in stop(): switching to exception state because of unhandled exception" << endlog();
248  log(Error) << " " << e.what() << endlog();
249  exception();
250  ) CATCH_ALL (
251  log(Error) << "in stop(): switching to exception state because of unhandled exception" << endlog();
252  exception();
253  )
254  }
255  return false;
256  }
257 
259  this->engine() && this->engine()->getActivity() && this->engine()->getActivity()->start();
260  return isActive();
261  }
262 
264  }
265 
266  bool TaskCore::isRunning() const {
267  return mTaskState >= Running;
268  }
269 
270  bool TaskCore::isConfigured() const {
271  return mTaskState >= Stopped;
272  }
273 
274  bool TaskCore::inFatalError() const {
275  return mTaskState == FatalError;
276  }
277 
278  bool TaskCore::inException() const {
279  return mTaskState == Exception;
280  }
281 
283  return mTaskState == RunTimeError;
284  }
285 
286  bool TaskCore::isActive() const
287  {
288  return this->engine() && this->engine()->getActivity() && this->engine()->getActivity()->isActive();
289  }
290 
292  {
293  return this->engine()->getActivity() ? this->engine()->getActivity()->getPeriod() : -1.0;
294  }
295 
297  {
298  return this->engine()->getActivity() ? this->engine()->getActivity()->setPeriod(s) : false;
299  }
300 
301  unsigned TaskCore::getCpuAffinity() const
302  {
303  return this->engine()->getActivity() ? this->engine()->getActivity()->getCpuAffinity() : ~0;
304  }
305 
306  bool TaskCore::setCpuAffinity(unsigned cpu)
307  {
308  return this->engine()->getActivity() ? this->engine()->getActivity()->setCpuAffinity(cpu) : false;
309  }
310 
312  return true;
313  }
314 
316  {
317  return true;
318  }
319 
321  }
322 
323  void TaskCore::prepareUpdateHook() {
324  }
325 
327  {
328  }
329 
331  {
332  return true;
333  }
334 
336  }
337 
339  {
340  }
341 
343  if ( ee == engine )
344  return;
345  // cleanup:
346  if ( ee->getParent() == this )
347  delete ee;
348  else
349  ee->removeChild(this);
350  // set new:
351  if ( engine ) {
352  this->ee = engine;
353  engine->addChild(this);
354  } else {
355  this->ee = new ExecutionEngine(this);
356  }
357  }
358 
359 }
360 
ActivityInterface * getActivity() const
Query for the task this interface is run in.
virtual bool setPeriod(Seconds s)=0
Set the periodicity of this activity in Seconds.
double Seconds
Seconds are stored as a double precision float.
Definition: Time.hpp:53
virtual bool trigger()=0
Trigger that work has to be done.
#define TRY(C)
Contains static global configuration variables and cached entries.
Definition: CatchConfig.hpp:56
The state indicating the component encountered a C++ exception.
Definition: TaskCore.hpp:103
virtual bool trigger()
Invoke this method to trigger the thread of this TaskContext to execute its ExecutionEngine and the u...
Definition: TaskCore.cpp:97
virtual bool configureHook()
Implement this method such that it contains the code which will be executed when configure() is calle...
Definition: TaskCore.cpp:311
virtual void updateHook()
Function where the user must insert his &#39;application&#39; code.
Definition: TaskCore.cpp:326
virtual bool recover()
Call this method in a RunTimeError or Exception state to indicate that the run-time error conditions ...
Definition: TaskCore.cpp:190
STL namespace.
virtual TaskState getTargetState() const
Returns the state this TaskCore is going to, or in case no transition is taking place, returns getTaskState().
Definition: TaskCore.cpp:86
virtual bool startHook()
Implement this method such that it contains the code which will be executed when start() is called...
Definition: TaskCore.cpp:315
virtual bool isActive() const =0
Query if the activity is started.
TaskState mTaskState
Definition: TaskCore.hpp:448
The state indicating that a run-time error has occured [red] and needs attention. ...
Definition: TaskCore.hpp:106
virtual bool isConfigured() const
Inspect if the component is configured, i.e.
Definition: TaskCore.cpp:270
virtual bool activate()
This method starts the ExecutionEngine of this component in case it was not running.
Definition: TaskCore.cpp:258
virtual bool setCpuAffinity(unsigned cpu)
Sets the cpu affinity of this component.
Definition: TaskCore.cpp:306
virtual void stopHook()
Implement this method such that it contains the code which will be executed when stop() is called...
Definition: TaskCore.cpp:338
virtual bool isRunning() const
Inspect if the component is in the Running or RunTimeError state.
Definition: TaskCore.cpp:266
virtual bool configure()
This method instructs the component to (re-)read configuration data and try to enter the Stopped stat...
Definition: TaskCore.cpp:104
virtual unsigned getCpuAffinity() const =0
Get the cpu affinity of this activity.
The state indicating additional configuration is required.
Definition: TaskCore.hpp:101
An execution engine serialises (executes one after the other) the execution of all commands...
virtual void error()
Call this method in a Running state to indicate a run-time error condition.
Definition: TaskCore.cpp:162
virtual Seconds getPeriod() const
Get the configured execution period of this component.
Definition: TaskCore.cpp:291
virtual bool inException() const
Inspect if the component is in the Exception state.
Definition: TaskCore.cpp:278
#define CATCH(T, C)
Definition: CatchConfig.hpp:57
virtual bool inFatalError() const
Inspect if the component is in the FatalError state.
Definition: TaskCore.cpp:274
virtual void errorHook()
Implement this method to contain code that must be executed in the RunTimeError state, instead of updateHook().
Definition: TaskCore.cpp:320
virtual bool update()
Invoke this method to execute the ExecutionEngine and the update() method.
Definition: TaskCore.cpp:90
virtual bool setCpuAffinity(unsigned cpu)=0
Set the cpu affinity of this activity.
The state indicating the component encountered a fatal error and is unable to execute.
Definition: TaskCore.hpp:102
virtual void exceptionHook()
Implement this method to contain code that must be executed when transitioning to the Exception state...
Definition: TaskCore.cpp:335
virtual void fatal()
Call this method from any place to indicate that this component encountered a fatal error...
Definition: TaskCore.cpp:156
virtual void exception()
Call this method to indicate a run-time exception happend.
Definition: TaskCore.cpp:169
#define CATCH_ALL(C)
Definition: CatchConfig.hpp:58
TaskState
Describes the different states a component can have.
Definition: TaskCore.hpp:99
base::TaskCore * getParent()
The base::TaskCore which created this ExecutionEngine.
virtual bool execute()=0
Execute this activity such that it executes a step or loop of the RunnableInterface.
virtual Seconds getPeriod() const =0
Get the periodicity of this activity in Seconds.
virtual bool breakUpdateHook()
Implement this function if your code might block for long times inside the updateHook() function...
Definition: TaskCore.cpp:330
virtual TaskState getTaskState() const
Returns the current state of the TaskCore.
Definition: TaskCore.cpp:82
virtual bool isActive() const
Inspect if the component&#39;s ExecutionEngine is processing requests.
Definition: TaskCore.cpp:286
virtual void cleanupHook()
Implement this method such that it contains the code which will be executed when cleanup() is called...
Definition: TaskCore.cpp:263
virtual bool inRunTimeError() const
Inspect if the component is in the RunTimeError state.
Definition: TaskCore.cpp:282
virtual void addChild(base::TaskCore *tc)
Add a base::TaskCore to execute.
The state indicating the component is running [green].
Definition: TaskCore.hpp:105
void setExecutionEngine(ExecutionEngine *engine)
Use this method to re-set the execution engine of this task core.
Definition: TaskCore.cpp:342
virtual ~TaskCore()
Definition: TaskCore.cpp:69
virtual unsigned getCpuAffinity() const
Get the configured cpu affinity of this component.
Definition: TaskCore.cpp:301
virtual bool start()=0
Start the activity.
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:51
The state indicating the component is ready to run.
Definition: TaskCore.hpp:104
virtual bool stop()
This method stops the execution of updateHook() of this component.
Definition: TaskCore.cpp:233
ExecutionEngine * ee
The execution engine which calls update() and processes our commands, events etc. ...
Definition: TaskCore.hpp:446
virtual bool setPeriod(Seconds s)
Sets the period of this component.
Definition: TaskCore.cpp:296
const ExecutionEngine * engine() const
Get a const pointer to the ExecutionEngine of this Task.
Definition: TaskCore.hpp:327
virtual bool cleanup()
This method instructs a stopped component to enter the pre-operational state again.
Definition: TaskCore.cpp:136
virtual void removeChild(base::TaskCore *tc)
Remove a base::TaskCore from execution.
TaskCore(TaskState initial_state=Stopped)
Create a TaskCore.
Definition: TaskCore.cpp:51
virtual bool start()
This method starts the execution of the updateHook() with each trigger or period. ...
Definition: TaskCore.cpp:202
virtual bool stop()=0
Stop the activity This will stop the activity by removing it from the &#39;run-queue&#39; of a thread or call...