connectionmanager.cxx

来自「这是国外的resip协议栈」· CXX 代码 · 共 334 行

CXX
334
字号
#if defined(HAVE_CONFIG_H)#include "resip/stack/config.hxx"#endif#include "resip/stack/ConnectionManager.hxx"#include "rutil/Logger.hxx"#include "rutil/Inserter.hxx"#include <vector>using namespace resip;using namespace std;#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORTconst UInt64 ConnectionManager::MinimumGcAge = 1;ConnectionManager::ConnectionManager() :    mHead(0,Tuple(),0,Compression::Disabled),   mWriteHead(ConnectionWriteList::makeList(&mHead)),   mReadHead(ConnectionReadList::makeList(&mHead)),   mLRUHead(ConnectionLruList::makeList(&mHead)){   DebugLog(<<"ConnectionManager::ConnectionManager() called ");}ConnectionManager::~ConnectionManager(){   while (!mAddrMap.empty())   {      delete mAddrMap.begin()->second;   }   assert(mReadHead->empty());   assert(mWriteHead->empty());   assert(mLRUHead->empty());}Connection*ConnectionManager::findConnection(const Tuple& addr){   if (addr.mFlowKey != 0)   {      IdMap::iterator i = mIdMap.find(addr.mFlowKey);      if (i != mIdMap.end())      {         if(i->second->who()==addr)         {            DebugLog(<<"Found fd " << addr.mFlowKey);            return i->second;         }         else         {            DebugLog(<<"fd " << addr.mFlowKey                      << " exists, but does not match the destination. FD -> "                     << i->second->who() << ", tuple -> " << addr);         }      }      else      {         DebugLog(<<"fd " << addr.mFlowKey << " does not exist.");      }      if(addr.onlyUseExistingConnection)      {         return 0;      }   }      AddrMap::iterator i = mAddrMap.find(addr);   if (i != mAddrMap.end())   {      DebugLog(<<"Found connection for tuple "<< addr );      return i->second;   }      DebugLog(<<"Could not find a connection for " << addr);   return 0;}const Connection* ConnectionManager::findConnection(const Tuple& addr) const{   if (addr.mFlowKey != 0)   {      IdMap::const_iterator i = mIdMap.find(addr.mFlowKey);      if (i != mIdMap.end())      {         if(i->second->who()==addr)         {            DebugLog(<<"Found fd " << addr.mFlowKey);            return i->second;         }         else         {            DebugLog(<<"fd " << addr.mFlowKey                      << " exists, but does not match the destination. FD -> "                     << i->second->who() << ", tuple -> " << addr);         }      }      else      {         DebugLog(<<"fd " << addr.mFlowKey << " does not exist.");      }   }      AddrMap::const_iterator i = mAddrMap.find(addr);   if (i != mAddrMap.end())   {      DebugLog(<<"Found connection for tuple "<< addr );      return i->second;   }      DebugLog(<<"Could not find a connection for " << addr);   return 0;}voidConnectionManager::buildFdSet(FdSet& fdset){   for (ConnectionReadList::iterator i = mReadHead->begin();         i != mReadHead->end(); ++i)   {      fdset.setRead((*i)->getSocket());      fdset.setExcept((*i)->getSocket());   }   for (ConnectionWriteList::iterator i = mWriteHead->begin();         i != mWriteHead->end(); ++i)   {      fdset.setWrite((*i)->getSocket());      fdset.setExcept((*i)->getSocket());   }}voidConnectionManager::addToWritable(Connection* conn){   mWriteHead->push_back(conn);}voidConnectionManager::removeFromWritable(Connection* conn){   assert(!mWriteHead->empty());   conn->ConnectionWriteList::remove();}voidConnectionManager::addConnection(Connection* connection){   assert(mAddrMap.find(connection->who())==mAddrMap.end());   //DebugLog (<< "ConnectionManager::addConnection() " << connection->mWho.mFlowKey  << ":" << connection->mSocket);         mAddrMap[connection->who()] = connection;   mIdMap[connection->who().mFlowKey] = connection;   mReadHead->push_back(connection);   mLRUHead->push_back(connection);   //DebugLog (<< "count=" << mAddrMap.count(connection->who()) << "who=" << connection->who() << " mAddrMap=" << Inserter(mAddrMap));   //assert(mAddrMap.begin()->first == connection->who());   assert(mAddrMap.count(connection->who()) == 1);}voidConnectionManager::removeConnection(Connection* connection){   //DebugLog (<< "ConnectionManager::removeConnection()");   assert(!mReadHead->empty());   mIdMap.erase(connection->mWho.mFlowKey);   mAddrMap.erase(connection->mWho);   connection->ConnectionReadList::remove();   connection->ConnectionWriteList::remove();   connection->ConnectionLruList::remove();}// release excessively old connections (free up file descriptors)voidConnectionManager::gc(UInt64 relThreshhold){   UInt64 threshhold = Timer::getTimeMs() - relThreshhold;   InfoLog(<< "recycling connections older than " << relThreshhold/1000.0 << " seconds");   for (ConnectionLruList::iterator i = mLRUHead->begin();        i != mLRUHead->end();)   {      if ((*i)->whenLastUsed() < threshhold)      {         Connection* discard = *i;         InfoLog(<< "recycling connection: " << discard << " " << discard->getSocket());         // iterate before removing         ++i;         delete discard;      }      else      {         break;      }   }}// move to youngestvoidConnectionManager::touch(Connection* connection){   connection->ConnectionLruList::remove();   mLRUHead->push_back(connection);}voidConnectionManager::process(FdSet& fdset, Fifo<TransactionMessage>& fifo){   // process the write list   for (ConnectionWriteList::iterator writeIter = mWriteHead->begin();	writeIter != mWriteHead->end(); )   {      Connection* currConnection = *writeIter;      // update iterator to next first so that it can traverse safely      // even if current one is removed from the list later      ++writeIter;      if (!currConnection)	 continue;      if (fdset.readyToWrite(currConnection->getSocket()))      {	 currConnection->performWrite();      }      else if (fdset.hasException(currConnection->getSocket()))      {	 int errNum = 0;	 int errNumSize = sizeof(errNum);	 getsockopt(currConnection->getSocket(), SOL_SOCKET, SO_ERROR, (char *)&errNum, (socklen_t *)&errNumSize);	 InfoLog(<< "Exception writing to socket " << currConnection->getSocket() << " code: " << errNum << "; closing connection");	 delete currConnection;      }   }   // process the read list   for (ConnectionReadList::iterator readIter = mReadHead->begin();	readIter != mReadHead->end(); )   {      Connection* currConnection = *readIter;       // update iterator to next first so that it can traverse safely      // even if current one is removed from the list later      ++readIter;      if (!currConnection)	 continue;      if ( fdset.readyToRead(currConnection->getSocket()) ||	   currConnection->hasDataToRead() )      {	 fdset.clear(currConnection->getSocket());                  int bytesRead = currConnection->read(fifo);         DebugLog(<< "ConnectionManager::process() " << " read=" << bytesRead);         if (bytesRead < 0)         {            DebugLog(<< "Closing connection bytesRead=" << bytesRead);            delete currConnection;         }      }      else if (fdset.hasException(currConnection->getSocket()))      {	 int errNum = 0;	 int errNumSize = sizeof(errNum);	 getsockopt(currConnection->getSocket(), SOL_SOCKET, SO_ERROR, (char *)&errNum, (socklen_t *)&errNumSize);	 InfoLog(<< "Exception reading from socket " << currConnection->getSocket() << " code: " << errNum << "; closing connection");	 delete currConnection;      }   }}/* ==================================================================== * The Vovida Software License, Version 1.0  *  * Copyright (c) *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *  * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. *  * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. *  * 3. The names "VOCAL", "Vovida Open Communication Application Library", *    and "Vovida Open Communication Application Library (VOCAL)" must *    not be used to endorse or promote products derived from this *    software without prior written permission. For written *    permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor *    may "VOCAL" appear in their name, without prior written *    permission of Vovida Networks, Inc. *  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. *  * ==================================================================== *  * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc.  For more information on Vovida Networks, Inc., please see * <http://www.vovida.org/>. * */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?