TaskCore.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002   tag: FMTC  Tue Mar 11 21:49:25 CET 2008  TaskCore.cpp
00003 
00004                         TaskCore.cpp -  description
00005                            -------------------
00006     begin                : Tue March 11 2008
00007     copyright            : (C) 2008 FMTC
00008     email                : peter.soetens@fmtc.be
00009 
00010  ***************************************************************************
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU General Public                   *
00013  *   License as published by the Free Software Foundation;                 *
00014  *   version 2 of the License.                                             *
00015  *                                                                         *
00016  *   As a special exception, you may use this file as part of a free       *
00017  *   software library without restriction.  Specifically, if other files   *
00018  *   instantiate templates or use macros or inline functions from this     *
00019  *   file, or you compile this file and link it with other files to        *
00020  *   produce an executable, this file does not by itself cause the         *
00021  *   resulting executable to be covered by the GNU General Public          *
00022  *   License.  This exception does not however invalidate any other        *
00023  *   reasons why the executable file might be covered by the GNU General   *
00024  *   Public License.                                                       *
00025  *                                                                         *
00026  *   This library is distributed in the hope that it will be useful,       *
00027  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00028  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00029  *   Lesser General Public License for more details.                       *
00030  *                                                                         *
00031  *   You should have received a copy of the GNU General Public             *
00032  *   License along with this library; if not, write to the Free Software   *
00033  *   Foundation, Inc., 59 Temple Place,                                    *
00034  *   Suite 330, Boston, MA  02111-1307  USA                                *
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 /*= Stopped*/ )
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 /*= Stopped*/  )
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         // Note: calling cleanup() here has no use or even dangerous, as
00077         // cleanupHook() is a virtual function and the user code is already
00078         // destroyed. The user's subclass is responsible to make this state
00079         // transition in its destructor if required.
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; // no configure when running.
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; // no cleanup when running or not configured.
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         // detects error() from within start():
00154         if (mTargetState < Running)
00155             return;
00156         mTargetState = mTaskState = RunTimeError;
00157     }
00158 
00159     void TaskCore::exception() {
00160         //log(Error) <<"Exception happend in TaskCore."<<endlog();
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(); // triggers updateHook() in case of non periodic!
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         // cleanup:
00327         if ( ee->getParent() == this )
00328             delete ee;
00329         else
00330             ee->removeChild(this);
00331         // set new:
00332         if ( engine ) {
00333             this->ee = engine;
00334             engine->addChild(this);
00335         } else {
00336             this->ee = new ExecutionEngine(this);
00337         }
00338     }
00339 
00340 }
00341 


rtt
Author(s): RTT Developers
autogenerated on Thu Jan 2 2014 11:35:39