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 #include "internal/CatchConfig.hpp"
00045
00046 namespace RTT {
00047 using namespace detail;
00048
00049 using namespace std;
00050
00051 TaskCore::TaskCore(TaskState initial_state )
00052 : ee( new ExecutionEngine(this) )
00053 ,mTaskState(initial_state)
00054 ,mInitialState(initial_state)
00055 ,mTargetState(initial_state)
00056 {
00057 }
00058
00059 TaskCore::TaskCore( ExecutionEngine* parent, TaskState initial_state )
00060 : ee( parent )
00061 ,mTaskState(initial_state)
00062 ,mInitialState(initial_state)
00063 ,mTargetState(initial_state)
00064 {
00065 parent->addChild( this );
00066 }
00067
00068
00069 TaskCore::~TaskCore()
00070 {
00071 if ( ee->getParent() == this ) {
00072 delete ee;
00073 } else {
00074 ee->removeChild(this);
00075 }
00076
00077
00078
00079
00080 }
00081
00082 TaskCore::TaskState TaskCore::getTaskState() const {
00083 return mTaskState;
00084 }
00085
00086 TaskCore::TaskState TaskCore::getTargetState() const {
00087 return mTargetState;
00088 }
00089
00090 bool TaskCore::update()
00091 {
00092 if ( !this->engine()->getActivity() )
00093 return false;
00094 return this->engine()->getActivity()->execute();
00095 }
00096
00097 bool TaskCore::trigger()
00098 {
00099 if ( !this->engine()->getActivity() )
00100 return false;
00101 return this->engine()->getActivity()->trigger();
00102 }
00103
00104 bool TaskCore::configure() {
00105 if ( mTaskState == Stopped || mTaskState == PreOperational) {
00106 TRY(
00107 mTargetState = Stopped;
00108 if (configureHook() ) {
00109 mTaskState = Stopped;
00110 return true;
00111 } else {
00112 mTargetState = mTaskState = PreOperational;
00113 return false;
00114 }
00115 ) CATCH(std::exception const& e,
00116 log(Error) << "in configure(): switching to exception state because of unhandled exception" << endlog();
00117 log(Error) << " " << e.what() << endlog();
00118 exception();
00119 ) CATCH_ALL(
00120 log(Error) << "in configure(): switching to exception state because of unhandled exception" << endlog();
00121 exception();
00122 )
00123 }
00124 return false;
00125 }
00126
00127 bool TaskCore::cleanup() {
00128 if ( mTaskState == Stopped ) {
00129 TRY(
00130 mTargetState = PreOperational;
00131 cleanupHook();
00132 mTaskState = PreOperational;
00133 return true;
00134 ) CATCH(std::exception const& e,
00135 log(Error) << "in cleanup(): switching to exception state because of unhandled exception" << endlog();
00136 log(Error) << " " << e.what() << endlog();
00137 exception();
00138 ) CATCH_ALL (
00139 log(Error) << "in cleanup(): switching to exception state because of unhandled exception" << endlog();
00140 exception();
00141 )
00142 }
00143 return false;
00144 }
00145
00146 void TaskCore::fatal() {
00147 mTargetState = mTaskState = FatalError;
00148 if ( engine()->getActivity() )
00149 engine()->getActivity()->stop();
00150 }
00151
00152 void TaskCore::error() {
00153
00154 if (mTargetState < Running)
00155 return;
00156 mTargetState = mTaskState = RunTimeError;
00157 }
00158
00159 void TaskCore::exception() {
00160
00161 TaskState copy = mTaskState;
00162 mTargetState = mTaskState = Exception;
00163 TRY (
00164 if ( copy >= Running ) {
00165 stopHook();
00166 }
00167 if ( copy >= Stopped && mInitialState == PreOperational ) {
00168 cleanupHook();
00169 }
00170 exceptionHook();
00171 ) CATCH(std::exception const& e,
00172 log(RTT::Error) << "stopHook(), cleanupHook() and/or exceptionHook() raised " << e.what() << ", going into Fatal" << endlog();
00173 fatal();
00174 ) CATCH_ALL (
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_ALL (
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_ALL (
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