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