User Manual, Developers Guide and API Documentation

PeriodicRealTimeout.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * This file is part of openWNS (open Wireless Network Simulator)
00003  * _____________________________________________________________________________
00004  *
00005  * Copyright (C) 2004-2007
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 16, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 #include <WNS/simulator/ISimulator.hpp>
00029 #include <WNS/events/scheduler/Interface.hpp>
00030 #include <WNS/events/scheduler/NullCommand.hpp>
00031 
00032 #include <WNS/events/PeriodicRealTimeout.hpp>
00033 #include <WNS/TypeInfo.hpp>
00034 
00035 using namespace wns::events;
00036 
00037 PeriodicRealTimeout::PeriodicRealTimeout() :
00038     mutex(),
00039     period(0),
00040     delay(0),
00041     running(false),
00042     thread(),
00043     currentCommand(scheduler::makeNullCommand())
00044 {
00045     pthread_mutex_init(&this->mutex, 0);
00046     pthread_cond_init(&this->dataRead, 0);
00047 } // PeriodicRealTimeout
00048 
00049 
00050 PeriodicRealTimeout::~PeriodicRealTimeout()
00051 {
00052     this->cancelPeriodicRealTimeout();
00053     pthread_cond_destroy(&this->dataRead);
00054     pthread_mutex_destroy(&this->mutex);
00055 } // ~PeriodicRealTimeout
00056 
00057 
00058 void
00059 PeriodicRealTimeout::startPeriodicTimeout(double _period, double _delay)
00060 {
00061     this->cancelPeriodicRealTimeout();
00062 
00063     pthread_mutex_lock(&this->mutex);
00064     {
00065         this->period = _period;
00066         this->delay = _delay;
00067 
00068         pthread_create(&this->thread, 0, PeriodicRealTimeout::worker, this);
00069         pthread_cond_wait( &this->dataRead, &this->mutex );
00070     }
00071     pthread_mutex_unlock(&this->mutex);
00072 } // setPeriodicRealTimeout
00073 
00074 
00075 bool
00076 PeriodicRealTimeout::hasPeriodicRealTimeoutSet()
00077 {
00078     return this->running;   // this is a funky method anyway...
00079 } // hasPeriodicRealTimeoutSet
00080 
00081 
00082 void
00083 PeriodicRealTimeout::cancelPeriodicRealTimeout()
00084 {
00085     pthread_mutex_lock(&this->mutex);
00086     if (this->running)
00087     {
00088         if (this->currentCommand->isQueued())
00089         {
00090             wns::simulator::getEventScheduler()->dequeueCommand(this->currentCommand);
00091         }
00092         pthread_cancel(this->thread);
00093         pthread_join(this->thread, 0);
00094         this->running = false;
00095         this->currentCommand = scheduler::makeNullCommand();
00096     }
00097     pthread_mutex_unlock(&this->mutex);
00098 } // cancelPeriodicRealTimeout
00099 
00100 
00101 void*
00102 PeriodicRealTimeout::worker(void* _arg)
00103 {
00104     PeriodicRealTimeout* it = (PeriodicRealTimeout*) _arg;
00105 
00106     pthread_mutex_lock(&it->mutex);
00107     it->running = true;
00108     double delay;
00109     double period;
00110     delay = it->delay;
00111     period = it->period;
00112     pthread_mutex_unlock(&it->mutex);
00113     pthread_cond_signal(&it->dataRead);
00114 
00115     {
00116         timespec t;
00117         t.tv_sec = static_cast<time_t>(delay);
00118         t.tv_nsec = static_cast<long>((delay-t.tv_sec)*1E9);
00119         nanosleep(&t, NULL);
00120     }
00121 
00122     while(true) {
00123 
00124         int oldState;
00125         pthread_testcancel();
00126         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
00127         pthread_mutex_lock(&it->mutex);
00128         {
00129             if(it->currentCommand->isFinished() || it->currentCommand->isNotSubmitted())
00130             {
00131                 it->currentCommand =
00132                     wns::simulator::getEventScheduler()->queueCommand(PeriodicRealTimeoutCommand(it));
00133             } else {
00134                 // old event has not yet been executed, wait
00135                 // until next iteration
00136             }
00137         }
00138         pthread_mutex_unlock(&it->mutex);
00139         pthread_setcancelstate(oldState, 0);
00140         pthread_testcancel();
00141 
00142         {
00143             timespec t;
00144             t.tv_sec = static_cast<time_t>(period);
00145             t.tv_nsec = static_cast<long>((period-t.tv_sec)*1E9);
00146             nanosleep(&t, NULL);
00147         }
00148     }
00149 
00150     return 0;
00151 } // worker
00152 
00153 

Generated on Fri May 25 03:31:38 2012 for openWNS by  doxygen 1.5.5