ActiveObjectAce.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright 2007, 2008, 2009, 2010, 2011 Instituto de Sistemas e Robotica, Instituto Superior Tecnico
00003 
00004 This file is part of MeRMaID.
00005 
00006 MeRMaID is free software: you can redistribute it and/or modify
00007 it under the terms of the GNU Lesser General Public License as published by
00008 the Free Software Foundation, either version 3 of the License, or
00009 (at your option) any later version.
00010 
00011 MeRMaID is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU Lesser General Public License for more details.
00015 
00016 You should have received a copy of the GNU Lesser General Public License
00017 along with MeRMaID.  If not, see <http://www.gnu.org/licenses/>.
00018 */
00019 
00020 
00021 
00022 /**
00023  * @Filename ActiveObjectAce.cpp
00024  * @Description ActiveObjectAce base implementation
00025  * @Status Work in Progress
00026  * @Version $Id: ActiveObjectAce.cpp 1 2011-03-04 18:13:18Z jreis $
00027  * @Maintainer nmsra (nmsra@mega.ist.utl.pt)
00028  */
00029 
00030 #include "config.h"
00031 
00032 #include <ActiveObjectAce.hpp>
00033 #include <ActiveObjectAceAddTaskMethod.hpp>
00034 #include <Exception.hpp>
00035 #include <Time.hpp>
00036 
00037 #include <iostream>
00038 
00039 #include <ace/Date_Time.h>
00040 #include <ace/Future.h>
00041 #include <ace/Method_Object.h>
00042 
00043 #include <stdexcept>
00044 
00045 using namespace mermaid::support::activeobject;
00046 using mermaid::support::errorhandling::Exception;
00047 using mermaid::support::system::Time;
00048 
00049 
00050 
00051 ActiveObjectAce::ActiveObjectAce (ActiveObjectManager * aom) : ActiveObject (aom), ACE_Task<ACE_MT_SYNCH>()
00052 {
00053   // std::cerr << "ActiveObjectAce::ActiveObjectAce()(this=" << this << ")" << std::endl;
00054 } // ActiveObjectAce()
00055 
00056 ActiveObjectAce::~ActiveObjectAce()
00057 {
00058   std::cerr << "ActiveObjectAce::~ActiveObjectAce()" << std::endl;
00059 } // ~ActiveObjectAce()
00060 
00061 
00062 
00063 void ActiveObjectAce::start()
00064 {
00065   // std::cerr << "ActiveObjectAce::start()(this=" << this << ")" << std::endl;
00066   
00067   if (getState() != INITIALIZED) {
00068     throw Exception ("ActiveObjectAce::doShutdown() : To run start(), the ActiveObject must have state = INITIALIZED, and the actual state is " + getStateString());
00069   }
00070   
00071   setState (RUNNING);
00072   this->activate();
00073 }
00074 
00075 
00076 
00077 void ActiveObjectAce::stop()
00078 {
00079   // std::cerr << "ActiveObjectAce::stop()(this=" << this << ")" << std::endl;
00080   
00081   if (getState() != RUNNING) {
00082     throw Exception ("ActiveObjectAce::doShutdown() : To run stop(), the ActiveObject must have state = RUNNING, and the actual state is " + getStateString());
00083   }
00084   
00085   setState (STOPPING);
00086   activationQueue_.queue()->close();
00087   this->wait();
00088 };
00089 
00090 
00091 //Private
00092 
00093 
00094 int ActiveObjectAce::svc (void)
00095 {
00096   Time lastTime = Time::getCurrentTime();
00097   
00098   try {
00099     while (1) {
00100       //std::cerr << std::endl;
00101       // calculate time until next object method should be run
00102       shared_ptr<Task> task = taskScheduler_->peakNextTask();
00103       
00104       if (task == false) {
00105         // no need to worry about times here
00106         // std::cerr << std::endl << std::endl << "ActiveObjectAce::svc() : dequeuing (empty scheduler)" << std::endl;
00107         shared_ptr<ACE_Method_Object> mo = shared_ptr<ACE_Method_Object> (activationQueue_.dequeue());
00108         
00109         if (mo) {
00110           // std::cerr << std::endl << std::endl << "ActiveObjectAce::svc() : calling method object (empty sxheduler)" << std::endl;
00111           {
00112             Time delta = Time::getCurrentTime() - lastTime;
00113             //std::cerr << "ActiveObjectAce::svc() : time since last run: sec=" << delta.sec() << " usec=" << delta.usec() << std::endl;
00114             lastTime = Time::getCurrentTime();
00115           }
00116           if (mo->call() == -1) {
00117             break;
00118           }
00119           // std::cerr << std::endl << std::endl << "ActiveObjectAce::svc() : returned from call to method object (empty scheduler)" << std::endl;
00120         }
00121         else {
00122           // interruption occured, active object is shutting down
00123           // std::cerr << "ActiveObjectAce::svc : interruption occured, shutting down" << std::endl;
00124           setState (STOPPED);
00125           return 0;
00126         }
00127       }
00128       else {
00129         // let's see how much time we have to wait
00130         Time scheduleTime = task->getScheduledTime();
00131         // std::cerr << std::endl << std::endl << "ActiveObjectAce::svc() : dequeuing (tasks in scheduler)" << std::endl;
00132         shared_ptr<ACE_Method_Object> mo = shared_ptr<ACE_Method_Object> (activationQueue_.dequeue ( (ACE_Time_Value*) & scheduleTime));
00133         
00134         //did a timeout occur?
00135         if (mo == false) {
00136           //check if timeout was because of active object shutdown
00137           if (getState() != RUNNING) {
00138             // std::cerr << "ActiveObjectAce::svc : interruption occured, shutting down" << std::endl;
00139             // std::cerr << "ActiveObjectAce::svc : remaining tasks will not be run." << std::endl;
00140             setState (STOPPED);
00141             return 0;
00142           }
00143           
00144           //it's a timeout, we have a task to execute
00145           shared_ptr<Task> t = taskScheduler_->getNextTask();
00146           // std::cerr << std::endl << std::endl << "ActiveObjectAce::svc() : running scheduled task(" << t.get() << ")" << std::endl;
00147           {
00148             Time delta = Time::getCurrentTime() - lastTime;
00149             // std::cerr << "ActiveObjectAce::svc() : time since last run: sec=" << delta.sec() << " usec=" << delta.usec() << std::endl;
00150             lastTime = Time::getCurrentTime();
00151           }
00152           
00153           if (t->isOkToRun() == true) {
00154             try {
00155               t->run();
00156             }
00157             catch (Exception &e) {
00158               std::cerr << "ActiveObjectAce::svc : caught an Exception from a Task : " << e.what() << std::endl;
00159             }
00160           }
00161           else {
00162             std::cerr << "ActiveObjectAce::svc : task not ok to run" << std::endl;
00163           }
00164           // std::cerr << "ActiveObjectAce::svc() : scheduled task(" << t.get() << ") ended running" << std::endl;
00165           
00166           //if task is to be repeated, reschedule
00167           if (t->hasRepeatScheduling()) {
00168             // std::cerr << "ActiveObjectAce::svc() : task(" << t.get() << ") has repeat schedule, rescheduling it" << std::endl;
00169             t->incrementScheduledTimeForRepeat();
00170             this->addTaskInternal (t);
00171           }
00172           else {
00173             // std::cerr << "ActiveObjectAce::svc() : task(" << t.get() << ") IS NOT repeatable, forgetting it" << std::endl;
00174           }
00175         }
00176         else {
00177           // not a timeout, we got a method object to execute
00178           // std::cerr << std::endl << std::endl << "ActiveObjectAce::svc() : calling method object (tasks in scheduler)" << std::endl;
00179           {
00180             Time delta = Time::getCurrentTime() - lastTime;
00181             //std::cerr << "ActiveObjectAce::svc() : time since last run: sec=" << delta.sec() << " usec=" << delta.usec() << std::endl;
00182             lastTime = Time::getCurrentTime();
00183           }
00184           if (mo->call() == -1) {
00185             break;
00186           }
00187           // std::cerr << std::endl << std::endl << "ActiveObjectAce::svc() : returned from call to method object (tasks in schedeuler)" << std::endl;
00188         } // else (timeout)
00189         
00190       } // else (valid task)
00191       
00192     } // the big while
00193   } // try
00194   catch (Exception &e) {
00195     std::cerr << "ActiveObjectAce::svc() : caught an Exception: " << e.what() << std::endl;
00196     
00197     setState (STOPPED);
00198     
00199     if (getState() != STOPPED) {
00200       std::cerr << "ActiveObjectAce::svc() : failed to set state to STOPPED" << std::endl;
00201     }
00202   }
00203   catch (std::runtime_error &e) {
00204     std::cerr << "ActiveObjectAce::svc() : caught a runtime_error exception: " << e.what() << std::endl;
00205     
00206     setState (STOPPED);
00207     
00208     if (getState() != STOPPED) {
00209       std::cerr << "ActiveObjectAce::svc() : failed to set state to STOPPED" << std::endl;
00210     }
00211   }
00212   catch (...) {
00213   
00214     //exit svc if something nasty happens...
00215     std::cerr << "ActiveObjectAce::svc() : something nasty happened" << std::endl;
00216     
00217     setState (STOPPED);
00218     
00219     if (getState() != STOPPED) {
00220       std::cerr << "ActiveObjectAce::svc() : failed to set state to STOPPED" << std::endl;
00221     }
00222     
00223     //std::cerr << "ActiveObjectAce(this=" << this << ").state_ = " << state_ << std::endl;
00224   }
00225   return 0;
00226 };
00227 
00228 
00229 
00230 void ActiveObjectAce::addTask (shared_ptr<Task> t)
00231 {
00232   // std::cerr << "ActiveObjectAce::addTask(this=" << this << ", task=" << t.get() << ")" << std::endl;
00233   
00234   ACE_Future<shared_ptr<Exception> > resultantFuture;
00235   
00236   this->activationQueue_.enqueue (new ActiveObjectAceAddTaskMethod (this, t, resultantFuture));
00237   
00238   shared_ptr<Exception> e;
00239   // std::cerr << "ActiveObjectAce::addTask : waiting for add task result" << std::endl;
00240   //! @TODO IMPORTANT: uncommenting the following line causes segfaults and/or memory corruption. The line should be uncommented and the cause of the error should be found and corrected.
00241   // resultantFuture.get(e);
00242   
00243   if (e) {
00244     throw Exception ("ActiveObjectAce::addTask : task added UNSUCCESSFULY");
00245   }
00246   else {
00247     // std::cerr << "ActiveObjectAce::addTask : task added successfuly" << std::endl;
00248   }
00249   
00250 }; // addTask()
00251 
00252 
00253 
00254 void ActiveObjectAce::addTaskInternal (shared_ptr<Task> t)
00255 {
00256   // std::cerr << "ActiveObjectAce::addTaskInternal(this=" << this << ", task=" << t.get() << ")" << std::endl;
00257   addTaskImplementation (t);
00258 }; // addTaskInternal()
00259 
00260 
00261 
00262 void ActiveObjectAce::addTaskImplementation (shared_ptr<Task> t)
00263 {
00264   // std::cerr << "ActiveObjectAce::addTaskImplementation(this=" << this << ", task=" << t.get() << ")" << std::endl;
00265   ActiveObject::addTask (t);
00266 }; // addTaskImplementation()
Generated on Fri Mar 4 22:14:58 2011 for MeRMaID::support by  doxygen 1.6.3