Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "TaskCore.hpp"
00041 #include "../ExecutionEngine.hpp"
00042 #include "ActivityInterface.hpp"
00043 #include "Logger.hpp"
00044
00045 namespace RTT {
00046 using namespace detail;
00047
00048 using namespace std;
00049
00050 TaskCore::TaskCore(TaskState initial_state )
00051 : ee( new ExecutionEngine(this) )
00052 ,mTaskState(initial_state)
00053 ,mInitialState(initial_state)
00054 ,mTargetState(initial_state)
00055 {
00056 }
00057
00058 TaskCore::TaskCore( ExecutionEngine* parent, TaskState initial_state )
00059 : ee( parent )
00060 ,mTaskState(initial_state)
00061 ,mInitialState(initial_state)
00062 ,mTargetState(initial_state)
00063 {
00064 parent->addChild( this );
00065 }
00066
00067
00068 TaskCore::~TaskCore()
00069 {
00070 if ( ee->getParent() == this ) {
00071 delete ee;
00072 } else {
00073 ee->removeChild(this);
00074 }
00075
00076
00077
00078
00079 }
00080
00081 TaskCore::TaskState TaskCore::getTaskState() const {
00082 return mTaskState;
00083 }
00084
00085 TaskCore::TaskState TaskCore::getTargetState() const {
00086 return mTargetState;
00087 }
00088
00089 bool TaskCore::update()
00090 {
00091 if ( !this->engine()->getActivity() )
00092 return false;
00093 return this->engine()->getActivity()->execute();
00094 }
00095
00096 bool TaskCore::trigger()
00097 {
00098 if ( !this->engine()->getActivity() )
00099 return false;
00100 return this->engine()->getActivity()->trigger();
00101 }
00102
00103 bool TaskCore::configure() {
00104 if ( mTaskState == Stopped || mTaskState == PreOperational) {
00105 try {
00106 mTargetState = Stopped;
00107 if (configureHook() ) {
00108 mTaskState = Stopped;
00109 return true;
00110 } else {
00111 mTargetState = mTaskState = PreOperational;
00112 return false;
00113 }
00114 } catch(std::exception const& e) {
00115 log(Error) << "in configure(): switching to exception state because of unhandled exception" << endlog();
00116 log(Error) << " " << e.what() << endlog();
00117 exception();
00118 } catch(...) {
00119 log(Error) << "in configure(): switching to exception state because of unhandled exception" << endlog();
00120 exception();
00121 }
00122 }
00123 return false;
00124 }
00125
00126 bool TaskCore::cleanup() {
00127 if ( mTaskState == Stopped ) {
00128 try {
00129 mTargetState = PreOperational;
00130 cleanupHook();
00131 mTaskState = PreOperational;
00132 return true;
00133 } catch(std::exception const& e) {
00134 log(Error) << "in cleanup(): switching to exception state because of unhandled exception" << endlog();
00135 log(Error) << " " << e.what() << endlog();
00136 exception();
00137 } catch (...) {
00138 log(Error) << "in cleanup(): switching to exception state because of unhandled exception" << endlog();
00139 exception();
00140 }
00141 }
00142 return false;
00143 }
00144
00145 void TaskCore::fatal() {
00146 mTargetState = mTaskState = FatalError;
00147 if ( engine()->getActivity() )
00148 engine()->getActivity()->stop();
00149 }
00150
00151 void TaskCore::error() {
00152
00153 if (mTargetState < Running)
00154 return;
00155 mTargetState = mTaskState = RunTimeError;
00156 }
00157
00158 void TaskCore::exception() {
00159
00160 TaskState copy = mTaskState;
00161 mTargetState = mTaskState = Exception;
00162 try {
00163 if ( copy >= Running ) {
00164 stopHook();
00165 }
00166 if ( copy >= Stopped && mInitialState == PreOperational ) {
00167 cleanupHook();
00168 }
00169 exceptionHook();
00170 } catch(std::exception const& e) {
00171 log(RTT::Error) << "stopHook(), cleanupHook() and/or exceptionHook() raised " << e.what() << ", going into Fatal" << endlog();
00172 fatal();
00173 }
00174 catch (...) {
00175 log(Error) << "stopHook(), cleanupHook() and/or exceptionHook() raised an exception, going into Fatal" << endlog();
00176 fatal();
00177 }
00178 }
00179
00180 bool TaskCore::recover() {
00181 if ( mTaskState == Exception ) {
00182 mTargetState = mTaskState = mInitialState;
00183 return true;
00184 }
00185 if (mTaskState == RunTimeError ) {
00186 mTargetState = mTaskState = Running;
00187 return true;
00188 }
00189 return false;
00190 }
00191
00192 bool TaskCore::start() {
00193 if ( mTaskState == Stopped ) {
00194 try {
00195 mTargetState = Running;
00196 if ( startHook() ) {
00197 mTaskState = Running;
00198 trigger();
00199 return true;
00200 }
00201 mTargetState = Stopped;
00202 } catch(std::exception const& e) {
00203 log(Error) << "in start(): switching to exception state because of unhandled exception" << endlog();
00204 log(Error) << " " << e.what() << endlog();
00205 exception();
00206 } catch (...) {
00207 log(Error) << "in start(): switching to exception state because of unhandled exception" << endlog();
00208 exception();
00209 }
00210 }
00211 return false;
00212 }
00213
00214 bool TaskCore::stop() {
00215 TaskState orig = mTaskState;
00216 if ( mTaskState >= Running ) {
00217 try {
00218 mTargetState = Stopped;
00219 if ( engine()->stopTask(this) ) {
00220 stopHook();
00221 mTaskState = Stopped;
00222 return true;
00223 } else {
00224 mTaskState = orig;
00225 mTargetState = orig;
00226 }
00227 } catch(std::exception const& e) {
00228 log(Error) << "in stop(): switching to exception state because of unhandled exception" << endlog();
00229 log(Error) << " " << e.what() << endlog();
00230 exception();
00231 } catch (...) {
00232 log(Error) << "in stop(): switching to exception state because of unhandled exception" << endlog();
00233 exception();
00234 }
00235 }
00236 return false;
00237 }
00238
00239 bool TaskCore::activate() {
00240 this->engine() && this->engine()->getActivity() && this->engine()->getActivity()->start();
00241 return isActive();
00242 }
00243
00244 void TaskCore::cleanupHook() {
00245 }
00246
00247 bool TaskCore::isRunning() const {
00248 return mTaskState >= Running;
00249 }
00250
00251 bool TaskCore::isConfigured() const {
00252 return mTaskState >= Stopped;
00253 }
00254
00255 bool TaskCore::inFatalError() const {
00256 return mTaskState == FatalError;
00257 }
00258
00259 bool TaskCore::inException() const {
00260 return mTaskState == Exception;
00261 }
00262
00263 bool TaskCore::inRunTimeError() const {
00264 return mTaskState == RunTimeError;
00265 }
00266
00267 bool TaskCore::isActive() const
00268 {
00269 return this->engine() && this->engine()->getActivity() && this->engine()->getActivity()->isActive();
00270 }
00271
00272 Seconds TaskCore::getPeriod() const
00273 {
00274 return this->engine()->getActivity() ? this->engine()->getActivity()->getPeriod() : -1.0;
00275 }
00276
00277 bool TaskCore::setPeriod(Seconds s)
00278 {
00279 return this->engine()->getActivity() ? this->engine()->getActivity()->setPeriod(s) : false;
00280 }
00281
00282 unsigned TaskCore::getCpuAffinity() const
00283 {
00284 return this->engine()->getActivity() ? this->engine()->getActivity()->getCpuAffinity() : ~0;
00285 }
00286
00287 bool TaskCore::setCpuAffinity(unsigned cpu)
00288 {
00289 return this->engine()->getActivity() ? this->engine()->getActivity()->setCpuAffinity(cpu) : false;
00290 }
00291
00292 bool TaskCore::configureHook() {
00293 return true;
00294 }
00295
00296 bool TaskCore::startHook()
00297 {
00298 return true;
00299 }
00300
00301 void TaskCore::errorHook() {
00302 }
00303
00304 void TaskCore::prepareUpdateHook() {
00305 }
00306
00307 void TaskCore::updateHook()
00308 {
00309 }
00310
00311 bool TaskCore::breakUpdateHook()
00312 {
00313 return true;
00314 }
00315
00316 void TaskCore::exceptionHook() {
00317 }
00318
00319 void TaskCore::stopHook()
00320 {
00321 }
00322
00323 void TaskCore::setExecutionEngine(ExecutionEngine* engine) {
00324 if ( ee == engine )
00325 return;
00326
00327 if ( ee->getParent() == this )
00328 delete ee;
00329 else
00330 ee->removeChild(this);
00331
00332 if ( engine ) {
00333 this->ee = engine;
00334 engine->addChild(this);
00335 } else {
00336 this->ee = new ExecutionEngine(this);
00337 }
00338 }
00339
00340 }
00341