Orocos Real-Time Toolkit  2.9.0
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  ,mTriggerOnStart(true)
57  ,mCycleCounter(0)
58  ,mIOCounter(0)
59  ,mTimeOutCounter(0)
60  ,mTriggerCounter(0)
61  {
62  }
63 
65  {
66  if ( ee->getParent() == this ) {
67  delete ee;
68  }
69  // Note: calling cleanup() here has no use or even dangerous, as
70  // cleanupHook() is a virtual function and the user code is already
71  // destroyed. The user's subclass is responsible to make this state
72  // transition in its destructor if required.
73  }
74 
76  return mTaskState;
77  }
78 
80  return mTargetState;
81  }
82 
84  {
85  return this->engine()->getActivity() && this->engine()->getActivity()->execute();
86  }
87 
89  {
90  return this->engine()->getActivity() && this->engine()->getActivity()->timeout();
91  }
92 
95  TRY(
96  mTargetState = Stopped;
97  if (configureHook() ) {
99  return true;
100  } else {
101  mTargetState = mTaskState = PreOperational;
102  return false;
103  }
104  ) CATCH(std::exception const& e,
105  log(Error) << "in configure(): switching to exception state because of unhandled exception" << endlog();
106  log(Error) << " " << e.what() << endlog();
107  exception();
108  ) CATCH_ALL(
109  log(Error) << "in configure(): switching to exception state because of unhandled exception" << endlog();
110  exception();
111  )
112  }
113  return false; // no configure when running.
114  }
115 
117  if ( mTaskState == Stopped ) {
118  TRY(
119  mTargetState = PreOperational;
120  cleanupHook();
122  return true;
123  ) CATCH(std::exception const& e,
124  log(Error) << "in cleanup(): switching to exception state because of unhandled exception" << endlog();
125  log(Error) << " " << e.what() << endlog();
126  exception();
127  ) CATCH_ALL (
128  log(Error) << "in cleanup(): switching to exception state because of unhandled exception" << endlog();
129  exception();
130  )
131  }
132  return false; // no cleanup when running or not configured.
133  }
134 
136  mTargetState = mTaskState = FatalError;
137  this->engine()->getActivity() && engine()->getActivity()->stop();
138  }
139 
141  // detects error() from within start():
142  if (mTargetState < Running)
143  return;
144  mTargetState = mTaskState = RunTimeError;
145  }
146 
148  //log(Error) <<"Exception happend in TaskCore."<<endlog();
149  TaskState copy = mTaskState;
150  mTargetState = mTaskState = Exception;
151  TRY (
152  if ( copy >= Running ) {
153  stopHook();
154  }
155  if ( copy >= Stopped && mInitialState == PreOperational ) {
156  cleanupHook();
157  }
158  exceptionHook();
159  ) CATCH(std::exception const& e,
160  log(RTT::Error) << "stopHook(), cleanupHook() and/or exceptionHook() raised " << e.what() << ", going into Fatal" << endlog();
161  fatal();
162  ) CATCH_ALL (
163  log(Error) << "stopHook(), cleanupHook() and/or exceptionHook() raised an exception, going into Fatal" << endlog();
164  fatal();
165  )
166  }
167 
169  if ( mTaskState == Exception ) {
170  mTargetState = mTaskState = mInitialState;
171  return true;
172  }
173  if (mTaskState == RunTimeError && mTargetState >= Running) {
174  mTargetState = mTaskState = Running;
175  return true;
176  }
177  return false;
178  }
179 
181  if ( mTaskState == Stopped ) {
182  TRY (
183  mTargetState = Running;
184  if ( startHook() ) {
186  if ( mTriggerOnStart )
187  trigger(); // triggers updateHook() in case of non periodic!
188  return true;
189  }
190  mTargetState = Stopped;
191  ) CATCH(std::exception const& e,
192  log(Error) << "in start(): switching to exception state because of unhandled exception" << endlog();
193  log(Error) << " " << e.what() << endlog();
194  exception();
195  ) CATCH_ALL (
196  log(Error) << "in start(): switching to exception state because of unhandled exception" << endlog();
197  exception();
198  )
199  }
200  return false;
201  }
202 
203  bool TaskCore::stop() {
204  TaskState orig = mTaskState;
205  if ( mTaskState >= Running ) {
206  TRY(
207  mTargetState = Stopped;
208  if ( engine()->stopTask(this) ) {
209  stopHook();
211  return true;
212  } else {
213  mTaskState = orig;
214  mTargetState = orig;
215  }
216  ) CATCH(std::exception const& e,
217  log(Error) << "in stop(): switching to exception state because of unhandled exception" << endlog();
218  log(Error) << " " << e.what() << endlog();
219  exception();
220  ) CATCH_ALL (
221  log(Error) << "in stop(): switching to exception state because of unhandled exception" << endlog();
222  exception();
223  )
224  }
225  return false;
226  }
227 
229  this->engine()->getActivity() && this->engine()->getActivity()->start();
230  return isActive();
231  }
232 
234  }
235 
236  bool TaskCore::isRunning() const {
237  return mTaskState >= Running;
238  }
239 
240  bool TaskCore::isConfigured() const {
241  return mTaskState >= Stopped;
242  }
243 
244  bool TaskCore::inFatalError() const {
245  return mTaskState == FatalError;
246  }
247 
248  bool TaskCore::inException() const {
249  return mTaskState == Exception;
250  }
251 
253  return mTaskState == RunTimeError;
254  }
255 
256  bool TaskCore::isActive() const
257  {
258  return this->engine()->getActivity() && this->engine()->getActivity()->isActive();
259  }
260 
262  {
263  return this->engine()->getActivity() ? this->engine()->getActivity()->getPeriod() : -1.0;
264  }
265 
267  {
268  return this->engine()->getActivity() && this->engine()->getActivity()->setPeriod(s);
269  }
270 
271  unsigned TaskCore::getCpuAffinity() const
272  {
273  return this->engine()->getActivity() ? this->engine()->getActivity()->getCpuAffinity() : ~0;
274  }
275 
276  bool TaskCore::setCpuAffinity(unsigned cpu)
277  {
278  return this->engine()->getActivity() && this->engine()->getActivity()->setCpuAffinity(cpu);
279  }
280 
282  return true;
283  }
284 
286  {
287  return true;
288  }
289 
291  }
292 
294  {
295  }
296 
298  {
299  return true;
300  }
301 
303  }
304 
306  {
307  }
308 }
309 
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
#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:88
virtual bool configureHook()
Implement this method such that it contains the code which will be executed when configure() is calle...
Definition: TaskCore.cpp:281
virtual void updateHook()
Function where the user must insert his &#39;application&#39; code.
Definition: TaskCore.cpp:293
virtual bool recover()
Call this method in a RunTimeError or Exception state to indicate that the run-time error conditions ...
Definition: TaskCore.cpp:168
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:79
virtual bool timeout()=0
Requests this Activity to wakeup and call step() + work(Timeout).
virtual bool startHook()
Implement this method such that it contains the code which will be executed when start() is called...
Definition: TaskCore.cpp:285
virtual bool isActive() const =0
Query if the activity is started.
TaskState mTaskState
Definition: TaskCore.hpp:446
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:240
virtual bool activate()
This method starts the ExecutionEngine of this component in case it was not running.
Definition: TaskCore.cpp:228
virtual bool setCpuAffinity(unsigned cpu)
Sets the cpu affinity of this component.
Definition: TaskCore.cpp:276
virtual void stopHook()
Implement this method such that it contains the code which will be executed when stop() is called...
Definition: TaskCore.cpp:305
virtual bool isRunning() const
Inspect if the component is in the Running or RunTimeError state.
Definition: TaskCore.cpp:236
virtual bool configure()
This method instructs the component to (re-)read configuration data and try to enter the Stopped stat...
Definition: TaskCore.cpp:93
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:140
virtual Seconds getPeriod() const
Get the configured execution period of this component.
Definition: TaskCore.cpp:261
virtual bool inException() const
Inspect if the component is in the Exception state.
Definition: TaskCore.cpp:248
#define CATCH(T, C)
Definition: CatchConfig.hpp:57
virtual bool inFatalError() const
Inspect if the component is in the FatalError state.
Definition: TaskCore.cpp:244
virtual void errorHook()
Implement this method to contain code that must be executed in the RunTimeError state, instead of updateHook().
Definition: TaskCore.cpp:290
bool mTriggerOnStart
Set to false in order to not trigger() when calling start().
Definition: TaskCore.hpp:469
virtual bool update()
Invoke this method to execute the ExecutionEngine and the update() method.
Definition: TaskCore.cpp:83
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:302
virtual void fatal()
Call this method from any place to indicate that this component encountered a fatal error...
Definition: TaskCore.cpp:135
virtual void exception()
Call this method to indicate a run-time exception happend.
Definition: TaskCore.cpp:147
#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:297
virtual TaskState getTaskState() const
Returns the current state of the TaskCore.
Definition: TaskCore.cpp:75
virtual bool isActive() const
Inspect if the component&#39;s ExecutionEngine is processing requests.
Definition: TaskCore.cpp:256
virtual void cleanupHook()
Implement this method such that it contains the code which will be executed when cleanup() is called...
Definition: TaskCore.cpp:233
virtual bool inRunTimeError() const
Inspect if the component is in the RunTimeError state.
Definition: TaskCore.cpp:252
The state indicating the component is running [green].
Definition: TaskCore.hpp:105
virtual ~TaskCore()
Definition: TaskCore.cpp:64
virtual unsigned getCpuAffinity() const
Get the configured cpu affinity of this component.
Definition: TaskCore.cpp:271
virtual bool start()=0
Start the activity.
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:52
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:203
ExecutionEngine * ee
The execution engine which calls update() and processes our commands, events etc. ...
Definition: TaskCore.hpp:444
virtual bool setPeriod(Seconds s)
Sets the period of this component.
Definition: TaskCore.cpp:266
const ExecutionEngine * engine() const
Get a const pointer to the ExecutionEngine of this Task.
Definition: TaskCore.hpp:306
virtual bool cleanup()
This method instructs a stopped component to enter the pre-operational state again.
Definition: TaskCore.cpp:116
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:180
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...