![]() |
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. 5, 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/ldk/SequentlyCallingLinkHandler.hpp> 00029 00030 #include <WNS/ldk/fun/FUN.hpp> 00031 #include <WNS/ldk/FunctionalUnit.hpp> 00032 #include <WNS/ldk/PyConfigCreator.hpp> 00033 00034 #include <WNS/Assure.hpp> 00035 #include <WNS/Exception.hpp> 00036 00037 using namespace wns::ldk; 00038 00039 STATIC_FACTORY_REGISTER_WITH_CREATOR(SequentlyCallingLinkHandler, 00040 LinkHandlerInterface, 00041 "wns.ldk.SequentlyCallingLinkHandler", 00042 wns::ldk::PyConfigCreator); 00043 00044 SequentlyCallingLinkHandler::SequentlyCallingLinkHandler(const wns::pyconfig::View& _config) : 00045 inAction(false), 00046 pendingCompoundsContainingFUs(), 00047 sendDataPending(0), 00048 sendDataFUCompound(NULL, CompoundPtr()), 00049 wakeupFUs(), 00050 inWakeup(false), 00051 wakeupFUsInWakeup(), 00052 onDataFUCompounds(), 00053 00054 traceCompoundJourney(_config.get<bool>("traceCompoundJourney")), 00055 isAcceptingLogger(_config.get<wns::pyconfig::View>("isAcceptingLogger")), 00056 sendDataLogger(_config.get<wns::pyconfig::View>("sendDataLogger")), 00057 wakeupLogger(_config.get<wns::pyconfig::View>("wakeupLogger")), 00058 onDataLogger(_config.get<wns::pyconfig::View>("onDataLogger")) 00059 { 00060 } // SequentlyCallingLinkHandler 00061 00062 bool 00063 SequentlyCallingLinkHandler::isAcceptingForwarded(FunctionalUnit* fu, const CompoundPtr& compound) 00064 { 00065 if (sendDataPending) 00066 { 00067 MESSAGE_BEGIN(NORMAL, isAcceptingLogger, m, fu->getFUN()->getName()); 00068 m << " setting FU to be woken up"; 00069 MESSAGE_END(); 00070 00075 if (compound->getCallingFU()) 00076 pendingCompoundsContainingFUs.push_front(compound->getCallingFU()); 00077 else if (fu->getReceptor()->size() == 1) 00078 pendingCompoundsContainingFUs.push_front(fu->getReceptor()->get().front()); 00079 else 00080 throw wns::Exception("Don't know calling FU"); 00081 00082 return false; 00083 } 00084 00085 bool isAccepting = doIsAccepting(fu, compound); 00086 00087 MESSAGE_BEGIN(NORMAL, isAcceptingLogger, m, fu->getFUN()->getName()); 00088 m << " function isAccepting(...) of FU " 00089 << fu->getName() << " called: FU is "; 00090 if (isAccepting) 00091 m << "accepting"; 00092 else 00093 m << "not accepting"; 00094 m << ", compound: " << compound.getPtr(); 00095 MESSAGE_END(); 00096 00097 return isAccepting; 00098 } // isAcceptingForwarded 00099 00100 void 00101 SequentlyCallingLinkHandler::sendDataForwarded(FunctionalUnit* fu, const CompoundPtr& compound) 00102 { 00103 MESSAGE_BEGIN(NORMAL, sendDataLogger, m, fu->getFUN()->getName()); 00104 m << " queueing sendData(...) call of FU " 00105 << fu->getName() 00106 << ", compound: " << compound.getPtr(); 00107 MESSAGE_END(); 00108 00109 compound->setCallingFU(fu); 00110 00111 if (!inAction) 00112 sendDataHandler(fu, compound); 00113 else 00114 { 00115 ++sendDataPending; 00116 sendDataFUCompound = FUCompound(fu, compound); 00117 } 00118 } // sendDataForwarded 00119 00120 void 00121 SequentlyCallingLinkHandler::sendDataHandler(FunctionalUnit* fu, const CompoundPtr& compound) 00122 { 00123 inAction = true; 00124 00125 sendDataForwarded(fu, compound); 00126 00127 mainHandler(); 00128 00129 inAction = false; 00130 } // sendDataHandler 00131 00132 void 00133 SequentlyCallingLinkHandler::wakeupForwarded(FunctionalUnit* fu) 00134 { 00135 MESSAGE_BEGIN(NORMAL, wakeupLogger, m, fu->getFUN()->getName()); 00136 m << " queueing wakeup(...) call of FU " 00137 << fu->getName(); 00138 MESSAGE_END(); 00139 00140 if (!inAction) 00141 wakeupHandler(fu); 00142 else 00143 { 00144 if (inWakeup) 00145 wakeupFUsInWakeup.push_back(fu); 00146 else 00147 wakeupFUs.push_back(fu); 00148 } 00149 } // wakeupForwarded 00150 00151 void 00152 SequentlyCallingLinkHandler::wakeupHandler(FunctionalUnit* fu) 00153 { 00154 inAction = true; 00155 00156 wakeupForwarded(fu); 00157 00158 mainHandler(); 00159 00160 inAction = false; 00161 } // wakeupHandler 00162 00163 void 00164 SequentlyCallingLinkHandler::onDataForwarded(FunctionalUnit* fu, const CompoundPtr& compound) 00165 { 00166 MESSAGE_BEGIN(NORMAL, onDataLogger, m, fu->getFUN()->getName()); 00167 m << " queueing onData(...) call of FU " 00168 << fu->getName() 00169 << ", compound: " << compound.getPtr(); 00170 MESSAGE_END(); 00171 00172 if (!inAction) 00173 onDataHandler(fu, compound); 00174 else 00175 onDataFUCompounds.push_back(FUCompound(fu, compound)); 00176 } // onDataForwarded 00177 00178 void 00179 SequentlyCallingLinkHandler::onDataHandler(FunctionalUnit* fu, const CompoundPtr& compound) 00180 { 00181 inAction = true; 00182 00183 onDataForwarded(fu, compound); 00184 00185 mainHandler(); 00186 00187 inAction = false; 00188 } // onDataHandler 00189 00190 void 00191 SequentlyCallingLinkHandler::mainHandler() 00192 { 00193 while(true) 00194 { 00195 while (sendDataFUCompound.fu) 00196 { 00197 assure(sendDataPending < 2, "more than one compound is pending"); 00198 00199 MESSAGE_BEGIN(NORMAL, sendDataLogger, m, sendDataFUCompound.fu->getFUN()->getName()); 00200 m << " function sendData(...) of FU " 00201 << sendDataFUCompound.fu->getName() << " called" 00202 << ", compound: " << sendDataFUCompound.compound.getPtr(); 00203 MESSAGE_END(); 00204 00205 #ifndef WNS_NO_LOGGING 00206 if (traceCompoundJourney && sendDataFUCompound.compound) 00207 sendDataFUCompound.compound->visit(sendDataFUCompound.fu); // JOURNEY 00208 #endif 00209 00210 FUCompound sendDataFUCompoundHelp = sendDataFUCompound; 00211 00212 sendDataPending = 0; 00213 sendDataFUCompound.fu = NULL; 00214 sendDataFUCompound.compound = CompoundPtr(); 00215 00216 doSendData(sendDataFUCompoundHelp.fu, sendDataFUCompoundHelp.compound); 00217 } 00218 00219 if (!pendingCompoundsContainingFUs.empty()) 00220 { 00221 FunctionalUnit* pendingCompoundsContainingFUHelp = pendingCompoundsContainingFUs.front(); 00222 pendingCompoundsContainingFUs.pop_front(); 00223 00224 doWakeup(pendingCompoundsContainingFUHelp); 00225 00226 continue; 00227 } 00228 00229 if (!onDataFUCompounds.empty()) 00230 { 00231 FUCompound onDataFUCompoundHelp = onDataFUCompounds.front(); 00232 onDataFUCompounds.pop_front(); 00233 00234 MESSAGE_BEGIN(NORMAL, onDataLogger, m, onDataFUCompoundHelp.fu->getFUN()->getName()); 00235 m << " function onData(...) of FU " 00236 << onDataFUCompoundHelp.fu->getName() << " called" 00237 << ", compound: " << onDataFUCompoundHelp.compound.getPtr(); 00238 MESSAGE_END(); 00239 00240 #ifndef WNS_NO_LOGGING 00241 if (traceCompoundJourney && onDataFUCompoundHelp.compound) 00242 onDataFUCompoundHelp.compound->visit(onDataFUCompoundHelp.fu); // JOURNEY 00243 #endif 00244 00245 doOnData(onDataFUCompoundHelp.fu, onDataFUCompoundHelp.compound); 00246 00247 continue; 00248 } 00249 00250 if (!wakeupFUs.empty()) 00251 { 00252 FunctionalUnit* wakeupFUHelp = wakeupFUs.front(); 00253 wakeupFUs.pop_front(); 00254 00255 MESSAGE_BEGIN(NORMAL, wakeupLogger, m, wakeupFUHelp->getFUN()->getName()); 00256 m << " function wakeup(...) of FU " 00257 << wakeupFUHelp->getName() << " called"; 00258 MESSAGE_END(); 00259 00260 inWakeup = true; 00261 00262 doWakeup(wakeupFUHelp); 00263 wakeupFUs.insert(wakeupFUs.begin(), 00264 wakeupFUsInWakeup.begin(), 00265 wakeupFUsInWakeup.end()); 00266 wakeupFUsInWakeup.clear(); 00267 00268 inWakeup = false; 00269 } 00270 else 00271 { 00272 break; 00273 } 00274 } 00275 } // mainHandler 00276 00277
1.5.5