diff --git a/ChangeLog b/ChangeLog index aa1e8c26..ee30bd8f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2008-05-08 Tatsuhiro Tsujikawa + + Added timeout to socket pool. The default timeout is 15 seconds, + which is the same value Apache uses. + * src/DownloadEngine.cc + * src/DownloadEngine.h + +2008-05-08 Tatsuhiro Tsujikawa + + Fixed misuse of multimap::find() + * src/HttpHeader.cc + * test/HttpHeaderTest.cc + 2008-05-08 Tatsuhiro Tsujikawa Rewritten name resolver. Now async DNS can be disabled by --async-dns diff --git a/src/DownloadEngine.cc b/src/DownloadEngine.cc index c36fe7ef..6f8475ab 100644 --- a/src/DownloadEngine.cc +++ b/src/DownloadEngine.cc @@ -368,29 +368,36 @@ void DownloadEngine::addRoutineCommand(Command* command) } void DownloadEngine::poolSocket(const std::string& ipaddr, uint16_t port, - const SharedHandle& sock) + const SharedHandle& sock, + time_t timeout) { std::string addr = ipaddr+":"+Util::uitos(port); logger->info("Pool socket for %s", addr.c_str()); - std::multimap >::value_type newPair - (addr, sock); - _socketPool.insert(newPair); + + SocketPoolEntry e(sock, timeout); + std::multimap::value_type p(addr, e); + _socketPool.insert(p); } SharedHandle DownloadEngine::popPooledSocket(const std::string& ipaddr, uint16_t port) { + SharedHandle s; std::string addr = ipaddr+":"+Util::uitos(port); - std::multimap >::iterator i = - _socketPool.find(addr); - if(i == _socketPool.end()) { - return SharedHandle(); - } else { - logger->info("Reuse socket for %s", addr.c_str()); - SharedHandle s = (*i).second; - _socketPool.erase(i); - return s; + + std::multimap::iterator first = _socketPool.find(addr); + + for(std::multimap::iterator i = first; + i != _socketPool.end() && (*i).first == addr; ++i) { + const SocketPoolEntry& e = (*i).second; + if(!e.isTimeout()) { + logger->info("Reuse socket for %s", addr.c_str()); + s = e.getSocket(); + _socketPool.erase(first, ++i); + break; + } } + return s; } SharedHandle @@ -407,4 +414,22 @@ DownloadEngine::popPooledSocket return SharedHandle(); } +DownloadEngine::SocketPoolEntry::SocketPoolEntry +(const SharedHandle& socket, + time_t timeout): + _socket(socket), + _timeout(timeout) {} + +DownloadEngine::SocketPoolEntry::~SocketPoolEntry() {} + +bool DownloadEngine::SocketPoolEntry::isTimeout() const +{ + return _registeredTime.elapsed(_timeout); +} + +SharedHandle DownloadEngine::SocketPoolEntry::getSocket() const +{ + return _socket; +} + } // namespace aria2 diff --git a/src/DownloadEngine.h b/src/DownloadEngine.h index 70bd1f90..746b68a6 100644 --- a/src/DownloadEngine.h +++ b/src/DownloadEngine.h @@ -39,6 +39,7 @@ #include "SharedHandle.h" #include "Command.h" #include "a2netcompat.h" +#include "TimeA2.h" #include #include @@ -107,8 +108,26 @@ private: bool _haltRequested; - // key = IP address:port, value = Socket - std::multimap > _socketPool; + class SocketPoolEntry { + private: + SharedHandle _socket; + + time_t _timeout; + + Time _registeredTime; + public: + SocketPoolEntry(const SharedHandle& socket, + time_t timeout); + + ~SocketPoolEntry(); + + bool isTimeout() const; + + SharedHandle getSocket() const; + }; + + // key = IP address:port, value = SocketPoolEntry + std::multimap _socketPool; void shortSleep() const; bool addSocket(const SocketEntry& socketEntry); @@ -178,7 +197,7 @@ public: void addRoutineCommand(Command* command); void poolSocket(const std::string& ipaddr, uint16_t port, - const SharedHandle& sock); + const SharedHandle& sock, time_t timeout = 15); SharedHandle popPooledSocket(const std::string& ipaddr, uint16_t port);