diff options
author | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-10 08:12:22 +0000 |
---|---|---|
committer | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-10 08:12:22 +0000 |
commit | 1c67ccc3ab473fd54db8aa1d93b5e216edbe1d01 (patch) | |
tree | 822ef6b0d4cadc88e6bbecef58de21041735a083 /net/base/tcp_client_socket_pool.h | |
parent | 72a221c1f159a134671b9f9f12d8216f3527d8f5 (diff) | |
download | chromium_src-1c67ccc3ab473fd54db8aa1d93b5e216edbe1d01.zip chromium_src-1c67ccc3ab473fd54db8aa1d93b5e216edbe1d01.tar.gz chromium_src-1c67ccc3ab473fd54db8aa1d93b5e216edbe1d01.tar.bz2 |
Revert "Move much of the TCPClientSocketPool implementation out into ClientSocketPoolBase..."
This reverts r18034.
Review URL: http://codereview.chromium.org/119413
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18046 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/tcp_client_socket_pool.h')
-rw-r--r-- | net/base/tcp_client_socket_pool.h | 147 |
1 files changed, 130 insertions, 17 deletions
diff --git a/net/base/tcp_client_socket_pool.h b/net/base/tcp_client_socket_pool.h index c92a081..8d4a3bd 100644 --- a/net/base/tcp_client_socket_pool.h +++ b/net/base/tcp_client_socket_pool.h @@ -5,15 +5,19 @@ #ifndef NET_BASE_TCP_CLIENT_SOCKET_POOL_H_ #define NET_BASE_TCP_CLIENT_SOCKET_POOL_H_ +#include <deque> +#include <map> #include <string> +#include "base/scoped_ptr.h" +#include "base/timer.h" +#include "net/base/address_list.h" #include "net/base/client_socket_pool.h" -#include "net/base/client_socket_pool_base.h" +#include "net/base/host_resolver.h" namespace net { class ClientSocketFactory; -class TCPConnectingSocket; // A TCPClientSocketPool is used to restrict the number of TCP sockets open at // a time. It also maintains a list of idle persistent sockets. @@ -40,7 +44,9 @@ class TCPClientSocketPool : public ClientSocketPool { virtual void CloseIdleSockets(); - virtual int idle_socket_count() const { return base_->idle_socket_count(); } + virtual int idle_socket_count() const { + return idle_socket_count_; + } virtual int IdleSocketCountInGroup(const std::string& group_name) const; @@ -48,29 +54,136 @@ class TCPClientSocketPool : public ClientSocketPool { const ClientSocketHandle* handle) const; private: - class TCPConnectingSocketFactory - : public ClientSocketPoolBase::ConnectingSocketFactory { - public: - TCPConnectingSocketFactory( - const scoped_refptr<ClientSocketPoolBase>& base, - ClientSocketFactory* factory); - virtual ~TCPConnectingSocketFactory(); + // A Request is allocated per call to RequestSocket that results in + // ERR_IO_PENDING. + struct Request { + ClientSocketHandle* handle; + CompletionCallback* callback; + int priority; + std::string host; + int port; + LoadState load_state; + }; + + // Entry for a persistent socket which became idle at time |start_time|. + struct IdleSocket { + ClientSocket* socket; + base::TimeTicks start_time; + + // An idle socket should be removed if it can't be reused, or has been idle + // for too long. |now| is the current time value (TimeTicks::Now()). + // + // An idle socket can't be reused if it is disconnected or has received + // data unexpectedly (hence no longer idle). The unread data would be + // mistaken for the beginning of the next response if we were to reuse the + // socket for a new request. + bool ShouldCleanup(base::TimeTicks now) const; + }; + + typedef std::deque<Request> RequestQueue; + typedef std::map<const ClientSocketHandle*, Request> RequestMap; + + // A Group is allocated per group_name when there are idle sockets or pending + // requests. Otherwise, the Group object is removed from the map. + struct Group { + Group() : active_socket_count(0) {} + std::deque<IdleSocket> idle_sockets; + RequestQueue pending_requests; + RequestMap connecting_requests; + int active_socket_count; + }; + + typedef std::map<std::string, Group> GroupMap; - virtual TCPConnectingSocket* CreateConnectingSocket( - const std::string& group_name, - const ClientSocketPoolBase::Request& request) const; + // ConnectingSocket handles the host resolution necessary for socket creation + // and the Connect(). + class ConnectingSocket { + public: + enum State { + STATE_RESOLVE_HOST, + STATE_CONNECT + }; + + ConnectingSocket(const std::string& group_name, + const ClientSocketHandle* handle, + ClientSocketFactory* client_socket_factory, + TCPClientSocketPool* pool); + ~ConnectingSocket(); + + // Begins the host resolution and the TCP connect. Returns OK on success + // and ERR_IO_PENDING if it cannot immediately service the request. + // Otherwise, it returns a net error code. + int Connect(const std::string& host, int port); + + // Called by the TCPClientSocketPool to cancel this ConnectingSocket. Only + // necessary if a ClientSocketHandle is reused. + void Cancel(); private: - const scoped_refptr<ClientSocketPoolBase> base_; + // Handles asynchronous completion of IO. |result| represents the result of + // the IO operation. + void OnIOComplete(int result); + + // Handles both asynchronous and synchronous completion of IO. |result| + // represents the result of the IO operation. |synchronous| indicates + // whether or not the previous IO operation completed synchronously or + // asynchronously. OnIOCompleteInternal returns the result of the next IO + // operation that executes, or just the value of |result|. + int OnIOCompleteInternal(int result, bool synchronous); + + const std::string group_name_; + const ClientSocketHandle* const handle_; ClientSocketFactory* const client_socket_factory_; + CompletionCallbackImpl<ConnectingSocket> callback_; + scoped_ptr<ClientSocket> socket_; + scoped_refptr<TCPClientSocketPool> pool_; + HostResolver resolver_; + AddressList addresses_; + bool canceled_; - DISALLOW_COPY_AND_ASSIGN(TCPConnectingSocketFactory); + // The time the Connect() method was called (if it got called). + base::Time connect_start_time_; + + DISALLOW_COPY_AND_ASSIGN(ConnectingSocket); }; virtual ~TCPClientSocketPool(); - const scoped_refptr<ClientSocketPoolBase> base_; - const TCPConnectingSocketFactory connecting_socket_factory_; + static void InsertRequestIntoQueue(const Request& r, + RequestQueue* pending_requests); + + // Closes all idle sockets if |force| is true. Else, only closes idle + // sockets that timed out or can't be reused. + void CleanupIdleSockets(bool force); + + // Called when the number of idle sockets changes. + void IncrementIdleCount(); + void DecrementIdleCount(); + + // Called via PostTask by ReleaseSocket. + void DoReleaseSocket(const std::string& group_name, ClientSocket* socket); + + // Called when timer_ fires. This method scans the idle sockets removing + // sockets that timed out or can't be reused. + void OnCleanupTimerFired() { + CleanupIdleSockets(false); + } + + ClientSocketFactory* const client_socket_factory_; + + GroupMap group_map_; + + std::map<const ClientSocketHandle*, ConnectingSocket*> connecting_socket_map_; + + // Timer used to periodically prune idle sockets that timed out or can't be + // reused. + base::RepeatingTimer<TCPClientSocketPool> timer_; + + // The total number of idle sockets in the system. + int idle_socket_count_; + + // The maximum number of sockets kept per group. + const int max_sockets_per_group_; DISALLOW_COPY_AND_ASSIGN(TCPClientSocketPool); }; |