![]() |
User Manual, Developers Guide and API Documentation |
![]() |
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
1.5.5