|
reSIProcate/stack
9694
|
00001 #include "resip/stack/ConnectionTerminated.hxx" 00002 #include "resip/stack/KeepAlivePong.hxx" 00003 #include "resip/stack/TuSelector.hxx" 00004 #include "resip/stack/TransactionUser.hxx" 00005 #include "resip/stack/TransactionUserMessage.hxx" 00006 #include "resip/stack/SipStack.hxx" 00007 00008 #include "rutil/TimeLimitFifo.hxx" 00009 #include "rutil/AsyncProcessHandler.hxx" 00010 #include "rutil/WinLeakCheck.hxx" 00011 #include "rutil/Logger.hxx" 00012 #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSACTION 00013 00014 using namespace resip; 00015 00016 TuSelector::TuSelector(TimeLimitFifo<Message>& fallBackFifo) : 00017 mFallBackFifo(fallBackFifo), 00018 mCongestionManager(0), 00019 mFallbackPostNotify(0), 00020 mTuSelectorMode(false), 00021 mStatsPayload() 00022 { 00023 mShutdownFifo.setDescription("TuSelector::mShutdownFifo"); 00024 } 00025 00026 TuSelector::~TuSelector() 00027 { 00028 //assert(mTuList.empty()); 00029 } 00030 00031 00032 void 00033 TuSelector::setFallbackPostNotify(AsyncProcessHandler *handler) 00034 { 00035 mFallbackPostNotify = handler; 00036 } 00037 00038 void 00039 TuSelector::process() 00040 { 00041 if (mShutdownFifo.messageAvailable()) 00042 { 00043 TransactionUserMessage* msg = mShutdownFifo.getNext(); 00044 00045 switch (msg->type()) 00046 { 00047 case TransactionUserMessage::RequestShutdown: 00048 InfoLog (<< "TransactionUserMessage::RequestShutdown " << *(msg->getTransactionUser())); 00049 markShuttingDown(msg->getTransactionUser()); 00050 break; 00051 case TransactionUserMessage::RemoveTransactionUser: 00052 InfoLog (<< "TransactionUserMessage::RemoveTransactionUser " << *(msg->getTransactionUser())); 00053 remove(msg->getTransactionUser()); 00054 break; 00055 default: 00056 assert(0); 00057 break; 00058 } 00059 delete msg; 00060 } 00061 } 00062 00063 void 00064 TuSelector::add(Message* msg, TimeLimitFifo<Message>::DepthUsage usage) 00065 { 00066 if (msg->hasTransactionUser()) 00067 { 00068 if (exists(msg->getTransactionUser())) 00069 { 00070 DebugLog (<< "Send to TU: " << *(msg->getTransactionUser()) << " " << std::endl << std::endl << *msg); 00071 msg->getTransactionUser()->postToTransactionUser(msg, usage); 00072 } 00073 else 00074 { 00075 WarningLog (<< "Send to TU that no longer exists: " << std::endl << std::endl << *msg); 00076 delete msg; 00077 } 00078 } 00079 else 00080 { 00081 StatisticsMessage* stats = dynamic_cast<StatisticsMessage*>(msg); 00082 if (stats) 00083 { 00084 InfoLog(<< "Stats message " ); 00085 stats->loadOut(mStatsPayload); 00086 stats->logStats(RESIPROCATE_SUBSYSTEM, mStatsPayload); 00087 delete msg; 00088 } 00089 else 00090 { 00091 DebugLog(<< "Send to default TU: " << std::endl << std::endl << *msg); 00092 mFallBackFifo.add(msg, usage); 00093 if ( mFallbackPostNotify ) 00094 mFallbackPostNotify->handleProcessNotification(); 00095 } 00096 } 00097 } 00098 00099 void 00100 TuSelector::add(ConnectionTerminated* term) 00101 { 00102 InfoLog (<< "Sending " << *term << " to TUs"); 00103 00104 for(TuList::const_iterator it = mTuList.begin(); it != mTuList.end(); it++) 00105 { 00106 if (!it->shuttingDown && it->tu->isRegisteredForConnectionTermination()) 00107 { 00108 it->tu->post(term->clone()); 00109 } 00110 } 00111 } 00112 00113 void 00114 TuSelector::add(KeepAlivePong* pong) 00115 { 00116 //InfoLog (<< "Sending " << *pong << " to TUs"); 00117 00118 for(TuList::const_iterator it = mTuList.begin(); it != mTuList.end(); it++) 00119 { 00120 if (!it->shuttingDown && it->tu->isRegisteredForKeepAlivePongs()) 00121 { 00122 it->tu->post(pong->clone()); 00123 } 00124 } 00125 } 00126 00127 bool 00128 TuSelector::wouldAccept(TimeLimitFifo<Message>::DepthUsage usage) const 00129 { 00130 if (mTuSelectorMode) 00131 { 00132 for(TuList::const_iterator it = mTuList.begin(); it != mTuList.end(); it++) 00133 { 00134 if (!it->shuttingDown && !it->tu->wouldAccept(usage)) 00135 { 00136 return false; 00137 } 00138 } 00139 return true; 00140 } 00141 else 00142 { 00143 return mFallBackFifo.wouldAccept(usage); 00144 } 00145 } 00146 00147 unsigned int 00148 TuSelector::size() const 00149 { 00150 if (mTuSelectorMode) 00151 { 00152 unsigned int total=0; 00153 for(TuList::const_iterator it = mTuList.begin(); it != mTuList.end(); it++) 00154 { 00155 total += it->tu->size(); 00156 } 00157 return total; 00158 } 00159 else 00160 { 00161 return mFallBackFifo.size(); 00162 } 00163 } 00164 00165 void 00166 TuSelector::registerTransactionUser(TransactionUser& tu) 00167 { 00168 mTuSelectorMode = true; 00169 mTuList.push_back(Item(&tu)); 00170 } 00171 00172 void 00173 TuSelector::requestTransactionUserShutdown(TransactionUser& tu) 00174 { 00175 TransactionUserMessage* msg = new TransactionUserMessage(TransactionUserMessage::RequestShutdown, &tu); 00176 mShutdownFifo.add(msg); 00177 } 00178 00179 void 00180 TuSelector::unregisterTransactionUser(TransactionUser& tu) 00181 { 00182 TransactionUserMessage* msg = new TransactionUserMessage(TransactionUserMessage::RemoveTransactionUser, &tu); 00183 mShutdownFifo.add(msg); 00184 } 00185 00186 TransactionUser* 00187 TuSelector::selectTransactionUser(const SipMessage& msg) 00188 { 00189 for(TuList::iterator it = mTuList.begin(); it != mTuList.end(); it++) 00190 { 00191 if (it->tu->isForMe(msg)) 00192 { 00193 return it->tu; 00194 } 00195 } 00196 return 0; 00197 } 00198 00199 void 00200 TuSelector::markShuttingDown(TransactionUser* tu) 00201 { 00202 for(TuList::iterator it = mTuList.begin(); it != mTuList.end(); it++) 00203 { 00204 if (it->tu == tu) 00205 { 00206 it->shuttingDown = true; 00207 return; 00208 } 00209 } 00210 assert(0); 00211 } 00212 00213 void 00214 TuSelector::remove(TransactionUser* tu) 00215 { 00216 for(TuList::iterator it = mTuList.begin(); it != mTuList.end(); it++) 00217 { 00218 if (it->tu == tu) 00219 { 00220 TransactionUserMessage* done = new TransactionUserMessage(TransactionUserMessage::TransactionUserRemoved, tu); 00221 tu->post(done); 00222 mTuList.erase(it); 00223 return; 00224 } 00225 } 00226 assert(0); 00227 } 00228 00229 bool 00230 TuSelector::exists(TransactionUser* tu) 00231 { 00232 for(TuList::iterator it = mTuList.begin(); it != mTuList.end(); it++) 00233 { 00234 if (it->tu == tu) 00235 { 00236 return true; 00237 } 00238 } 00239 return false; 00240 } 00241 00242 unsigned int 00243 TuSelector::getTimeTillNextProcessMS() 00244 { 00245 if(mShutdownFifo.messageAvailable()) // || !mFallBackFifo.messageAvailable()) // .slg. fallback fifo is not really used 00246 { 00247 return 0; 00248 } 00249 else 00250 { 00251 return INT_MAX; 00252 } 00253 } 00254 00255 bool 00256 TuSelector::isTransactionUserStillRegistered(const TransactionUser* tu) const 00257 { 00258 if (mTuSelectorMode) 00259 { 00260 for(TuList::const_iterator it = mTuList.begin(); it != mTuList.end(); it++) 00261 { 00262 if (!it->shuttingDown && it->tu == tu) 00263 { 00264 return true; 00265 } 00266 } 00267 } 00268 return false; 00269 } 00270 00271 void 00272 TuSelector::setCongestionManager(CongestionManager* manager) 00273 { 00274 for(TuList::iterator i=mTuList.begin(); i!=mTuList.end();++i) 00275 { 00276 i->tu->setCongestionManager(manager); 00277 } 00278 00279 // Note: We are intentionally not registering the following Fifos 00280 // mFallbackFifo - this is the same fifo as SipStack::TuFifo (passed in 00281 // constructor). 00282 // mShutdownFifo - since it is only used at shutdown time, it doesn need 00283 // congestion management 00284 } 00285 00286 CongestionManager::RejectionBehavior 00287 TuSelector::getRejectionBehavior(TransactionUser* tu) const 00288 { 00289 if(!mCongestionManager) 00290 { 00291 return CongestionManager::NORMAL; 00292 } 00293 00294 if(tu) 00295 { 00296 return tu->getRejectionBehavior(); 00297 } 00298 00299 return mCongestionManager->getRejectionBehavior(&mFallBackFifo); 00300 } 00301 00302 UInt32 00303 TuSelector::getExpectedWait(TransactionUser* tu) const 00304 { 00305 if(tu) 00306 { 00307 return tu->getExpectedWait(); 00308 } 00309 00310 return (UInt32)mFallBackFifo.expectedWaitTimeMilliSec(); 00311 } 00312 00313 00314 00315 /* ==================================================================== 00316 * The Vovida Software License, Version 1.0 00317 * 00318 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00319 * 00320 * Redistribution and use in source and binary forms, with or without 00321 * modification, are permitted provided that the following conditions 00322 * are met: 00323 * 00324 * 1. Redistributions of source code must retain the above copyright 00325 * notice, this list of conditions and the following disclaimer. 00326 * 00327 * 2. Redistributions in binary form must reproduce the above copyright 00328 * notice, this list of conditions and the following disclaimer in 00329 * the documentation and/or other materials provided with the 00330 * distribution. 00331 * 00332 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00333 * and "Vovida Open Communication Application Library (VOCAL)" must 00334 * not be used to endorse or promote products derived from this 00335 * software without prior written permission. For written 00336 * permission, please contact vocal@vovida.org. 00337 * 00338 * 4. Products derived from this software may not be called "VOCAL", nor 00339 * may "VOCAL" appear in their name, without prior written 00340 * permission of Vovida Networks, Inc. 00341 * 00342 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00343 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00344 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00345 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00346 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00347 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00348 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00349 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00350 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00351 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00352 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00353 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00354 * DAMAGE. 00355 * 00356 * ==================================================================== 00357 * 00358 * This software consists of voluntary contributions made by Vovida 00359 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00360 * Inc. For more information on Vovida Networks, Inc., please see 00361 * <http://www.vovida.org/>. 00362 * 00363 */
1.7.5.1