diff options
author | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-14 07:07:49 +0000 |
---|---|---|
committer | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-14 07:07:49 +0000 |
commit | d80a432e2201c81d60508d8399129063baa63982 (patch) | |
tree | 00106740b6f9547148411a97fcc1328cc66b13c7 | |
parent | b8c904a326b28ad76146ab2a7366b2bbc2edaab9 (diff) | |
download | chromium_src-d80a432e2201c81d60508d8399129063baa63982.zip chromium_src-d80a432e2201c81d60508d8399129063baa63982.tar.gz chromium_src-d80a432e2201c81d60508d8399129063baa63982.tar.bz2 |
Make ClientSocketPool/ClientSocketPoolBase/ClientSocketHandle more generic.
This is in preparation for creating an SSLClientSocketPool.
ClientSocketPoolBase is now templated. Most of the implementation has moved to ClientSocketPoolBaseHelper which is not templated.
In order to make this possible, ClientSocketPoolBaseHelper's internal data structures do not use the full concrete Request type, but rather use a pointer to Request.
ClientSocketPoolBase takes a SocketParams as a template argument, primarily to allow RequestSocket to take a templated parameter that contains all the information necessary to connect the socket (be it TCP or SSL or whatever).
ClientSocketPool::RequestSocket() and ClientSocketHandle::Init() have been templated as well to handle this case.
I've left adding run-time type safety checks as a TODO.
TEST=net_unittests
BUG=http://crbug.com/13289
Review URL: http://codereview.chromium.org/160621
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23427 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/browser_main.cc | 2 | ||||
-rw-r--r-- | net/http/http_network_transaction_unittest.cc | 14 | ||||
-rw-r--r-- | net/socket/client_socket_handle.cc | 19 | ||||
-rw-r--r-- | net/socket/client_socket_handle.h | 32 | ||||
-rw-r--r-- | net/socket/client_socket_pool.h | 2 | ||||
-rw-r--r-- | net/socket/client_socket_pool_base.cc | 147 | ||||
-rw-r--r-- | net/socket/client_socket_pool_base.h | 257 | ||||
-rw-r--r-- | net/socket/client_socket_pool_base_unittest.cc | 66 | ||||
-rw-r--r-- | net/socket/tcp_client_socket_pool.cc | 27 | ||||
-rw-r--r-- | net/socket/tcp_client_socket_pool.h | 19 |
10 files changed, 383 insertions, 202 deletions
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc index 3501779..c111478 100644 --- a/chrome/browser/browser_main.cc +++ b/chrome/browser/browser_main.cc @@ -659,7 +659,7 @@ int BrowserMain(const MainFunctionParams& parameters) { const int late_binding_group = socket_late_binding_trial->AppendGroup("_enable_late_binding", 50); if (socket_late_binding_trial->group() == late_binding_group) - net::ClientSocketPoolBase::EnableLateBindingOfSockets(true); + net::EnableLateBindingOfSockets(true); #if defined(OS_WIN) // Init common control sex. diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 91c0d0b..e298f64 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -169,8 +169,12 @@ class CaptureGroupNameSocketPool : public ClientSocketPool { public: CaptureGroupNameSocketPool() { } + const std::string last_group_name_received() const { + return last_group_name_; + } + virtual int RequestSocket(const std::string& group_name, - const HostResolver::RequestInfo& resolve_info, + const void* socket_params, int priority, ClientSocketHandle* handle, CompletionCallback* callback, @@ -178,11 +182,6 @@ class CaptureGroupNameSocketPool : public ClientSocketPool { last_group_name_ = group_name; return ERR_IO_PENDING; } - - const std::string last_group_name_received() const { - return last_group_name_; - } - virtual void CancelRequest(const std::string& group_name, const ClientSocketHandle* handle) { } virtual void ReleaseSocket(const std::string& group_name, @@ -201,7 +200,8 @@ class CaptureGroupNameSocketPool : public ClientSocketPool { const ClientSocketHandle* handle) const { return LOAD_STATE_IDLE; } - protected: + + private: std::string last_group_name_; }; diff --git a/net/socket/client_socket_handle.cc b/net/socket/client_socket_handle.cc index 7c3b182..66ca4ab 100644 --- a/net/socket/client_socket_handle.cc +++ b/net/socket/client_socket_handle.cc @@ -7,7 +7,6 @@ #include "base/compiler_specific.h" #include "base/logging.h" #include "net/base/net_errors.h" -#include "net/socket/client_socket.h" #include "net/socket/client_socket_pool.h" namespace net { @@ -23,24 +22,6 @@ ClientSocketHandle::~ClientSocketHandle() { Reset(); } -int ClientSocketHandle::Init(const std::string& group_name, - const HostResolver::RequestInfo& resolve_info, - int priority, - CompletionCallback* callback, - LoadLog* load_log) { - CHECK(!group_name.empty()); - ResetInternal(true); - group_name_ = group_name; - int rv = pool_->RequestSocket( - group_name, resolve_info, priority, this, &callback_, load_log); - if (rv == ERR_IO_PENDING) { - user_callback_ = callback; - } else { - HandleInitCompletion(rv); - } - return rv; -} - void ClientSocketHandle::Reset() { ResetInternal(true); } diff --git a/net/socket/client_socket_handle.h b/net/socket/client_socket_handle.h index 0dbb1bc..67c6cb8 100644 --- a/net/socket/client_socket_handle.h +++ b/net/socket/client_socket_handle.h @@ -7,17 +7,17 @@ #include <string> +#include "base/logging.h" #include "base/ref_counted.h" #include "base/scoped_ptr.h" #include "net/base/completion_callback.h" -#include "net/base/host_resolver.h" #include "net/base/load_states.h" +#include "net/base/net_errors.h" #include "net/socket/client_socket.h" +#include "net/socket/client_socket_pool.h" namespace net { -class ClientSocketPool; - // A container for a ClientSocket. // // The handle's |group_name| uniquely identifies the origin and type of the @@ -39,7 +39,7 @@ class ClientSocketHandle { // otherwise it will be set to a new connected socket. Consumers can then // call is_reused() to see if the socket was reused. If not reusing an // existing socket, ClientSocketPool may need to establish a new - // connection to the |resolve_info.host| |resolve_info.port| pair. + // connection using |socket_params|. // // This method returns ERR_IO_PENDING if it cannot complete synchronously, in // which case the consumer will be notified of completion via |callback|. @@ -47,8 +47,10 @@ class ClientSocketHandle { // Init may be called multiple times. // // Profiling information for the request is saved to |load_log| if non-NULL. + // + template <typename SocketParams> int Init(const std::string& group_name, - const HostResolver::RequestInfo& resolve_info, + const SocketParams& socket_params, int priority, CompletionCallback* callback, LoadLog* load_log); @@ -102,6 +104,26 @@ class ClientSocketHandle { DISALLOW_COPY_AND_ASSIGN(ClientSocketHandle); }; +// Template function implementation: +template <typename SocketParams> +int ClientSocketHandle::Init(const std::string& group_name, + const SocketParams& socket_params, + int priority, + CompletionCallback* callback, + LoadLog* load_log) { + CHECK(!group_name.empty()); + ResetInternal(true); + group_name_ = group_name; + int rv = pool_->RequestSocket( + group_name, &socket_params, priority, this, &callback_, load_log); + if (rv == ERR_IO_PENDING) { + user_callback_ = callback; + } else { + HandleInitCompletion(rv); + } + return rv; +} + } // namespace net #endif // NET_SOCKET_CLIENT_SOCKET_HANDLE_H_ diff --git a/net/socket/client_socket_pool.h b/net/socket/client_socket_pool.h index ae0f48a..ffb34b7 100644 --- a/net/socket/client_socket_pool.h +++ b/net/socket/client_socket_pool.h @@ -48,7 +48,7 @@ class ClientSocketPool : public base::RefCounted<ClientSocketPool> { // // Profiling information for the request is saved to |load_log| if non-NULL. virtual int RequestSocket(const std::string& group_name, - const HostResolver::RequestInfo& resolve_info, + const void* params, int priority, ClientSocketHandle* handle, CompletionCallback* callback, diff --git a/net/socket/client_socket_pool_base.cc b/net/socket/client_socket_pool_base.cc index a45d74a..bfe8405 100644 --- a/net/socket/client_socket_pool_base.cc +++ b/net/socket/client_socket_pool_base.cc @@ -30,8 +30,6 @@ const int kIdleTimeout = 300; // 5 minutes. namespace net { -bool ClientSocketPoolBase::g_late_binding = false; - ConnectJob::ConnectJob(const std::string& group_name, const ClientSocketHandle* key_handle, base::TimeDelta timeout_duration, @@ -63,7 +61,11 @@ void ConnectJob::OnTimeout() { delegate->OnConnectJobComplete(ERR_TIMED_OUT, this); } -ClientSocketPoolBase::ClientSocketPoolBase( +namespace internal { + +bool ClientSocketPoolBaseHelper::g_late_binding = false; + +ClientSocketPoolBaseHelper::ClientSocketPoolBaseHelper( int max_sockets, int max_sockets_per_group, ConnectJobFactory* connect_job_factory) @@ -78,7 +80,7 @@ ClientSocketPoolBase::ClientSocketPoolBase( DCHECK_LE(max_sockets_per_group, max_sockets); } -ClientSocketPoolBase::~ClientSocketPoolBase() { +ClientSocketPoolBaseHelper::~ClientSocketPoolBaseHelper() { if (g_late_binding) CancelAllConnectJobs(); // Clean up any idle sockets. Assert that we have no remaining active @@ -94,24 +96,22 @@ ClientSocketPoolBase::~ClientSocketPoolBase() { // prioritized over requests of equal priority. // // static -void ClientSocketPoolBase::InsertRequestIntoQueue( - const Request& r, RequestQueue* pending_requests) { +void ClientSocketPoolBaseHelper::InsertRequestIntoQueue( + const Request* r, RequestQueue* pending_requests) { RequestQueue::iterator it = pending_requests->begin(); - while (it != pending_requests->end() && r.priority <= it->priority) + while (it != pending_requests->end() && r->priority() <= (*it)->priority()) ++it; pending_requests->insert(it, r); } -int ClientSocketPoolBase::RequestSocket( +int ClientSocketPoolBaseHelper::RequestSocket( const std::string& group_name, - const HostResolver::RequestInfo& resolve_info, - int priority, - ClientSocketHandle* handle, - CompletionCallback* callback, - LoadLog* load_log) { - DCHECK(!resolve_info.hostname().empty()); - DCHECK_GE(priority, 0); - DCHECK(callback); + const Request* request) { + DCHECK_GE(request->priority(), 0); + CompletionCallback* const callback = request->callback(); + CHECK(callback); + ClientSocketHandle* const handle = request->handle(); + CHECK(handle); Group& group = group_map_[group_name]; // Can we make another active socket now? @@ -122,9 +122,7 @@ int ClientSocketPoolBase::RequestSocket( // a scan of all groups, so just flip a flag here, and do the check later. may_have_stalled_group_ = true; } - CHECK(callback); - Request r(handle, callback, priority, resolve_info, load_log); - InsertRequestIntoQueue(r, &group.pending_requests); + InsertRequestIntoQueue(request, &group.pending_requests); return ERR_IO_PENDING; } @@ -134,7 +132,8 @@ int ClientSocketPoolBase::RequestSocket( DecrementIdleCount(); if (idle_socket.socket->IsConnectedAndIdle()) { // We found one we can reuse! - HandOutSocket(idle_socket.socket, idle_socket.used, handle, &group); + HandOutSocket( + idle_socket.socket, idle_socket.used, handle, &group); return OK; } delete idle_socket.socket; @@ -142,10 +141,8 @@ int ClientSocketPoolBase::RequestSocket( // We couldn't find a socket to reuse, so allocate and connect a new one. - CHECK(callback); - Request r(handle, callback, priority, resolve_info, load_log); scoped_ptr<ConnectJob> connect_job( - connect_job_factory_->NewConnectJob(group_name, r, this)); + connect_job_factory_->NewConnectJob(group_name, *request, this)); int rv = connect_job->Connect(); if (rv == OK) { @@ -157,9 +154,9 @@ int ClientSocketPoolBase::RequestSocket( ConnectJob* job = connect_job.release(); if (g_late_binding) { CHECK(!ContainsKey(connect_job_map_, handle)); - InsertRequestIntoQueue(r, &group.pending_requests); + InsertRequestIntoQueue(request, &group.pending_requests); } else { - group.connecting_requests[handle] = r; + group.connecting_requests[handle] = request; CHECK(!ContainsKey(connect_job_map_, handle)); connect_job_map_[handle] = job; } @@ -171,8 +168,8 @@ int ClientSocketPoolBase::RequestSocket( return rv; } -void ClientSocketPoolBase::CancelRequest(const std::string& group_name, - const ClientSocketHandle* handle) { +void ClientSocketPoolBaseHelper::CancelRequest( + const std::string& group_name, const ClientSocketHandle* handle) { CHECK(ContainsKey(group_map_, group_name)); Group& group = group_map_[group_name]; @@ -180,7 +177,8 @@ void ClientSocketPoolBase::CancelRequest(const std::string& group_name, // Search pending_requests for matching handle. RequestQueue::iterator it = group.pending_requests.begin(); for (; it != group.pending_requests.end(); ++it) { - if (it->handle == handle) { + if ((*it)->handle() == handle) { + delete *it; group.pending_requests.erase(it); if (g_late_binding && group.jobs.size() > group.pending_requests.size() + 1) { @@ -204,20 +202,20 @@ void ClientSocketPoolBase::CancelRequest(const std::string& group_name, } } -void ClientSocketPoolBase::ReleaseSocket(const std::string& group_name, - ClientSocket* socket) { +void ClientSocketPoolBaseHelper::ReleaseSocket(const std::string& group_name, + ClientSocket* socket) { // Run this asynchronously to allow the caller to finish before we let // another to begin doing work. This also avoids nasty recursion issues. // NOTE: We cannot refer to the handle argument after this method returns. MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( - this, &ClientSocketPoolBase::DoReleaseSocket, group_name, socket)); + this, &ClientSocketPoolBaseHelper::DoReleaseSocket, group_name, socket)); } -void ClientSocketPoolBase::CloseIdleSockets() { +void ClientSocketPoolBaseHelper::CloseIdleSockets() { CleanupIdleSockets(true); } -int ClientSocketPoolBase::IdleSocketCountInGroup( +int ClientSocketPoolBaseHelper::IdleSocketCountInGroup( const std::string& group_name) const { GroupMap::const_iterator i = group_map_.find(group_name); CHECK(i != group_map_.end()); @@ -225,7 +223,7 @@ int ClientSocketPoolBase::IdleSocketCountInGroup( return i->second.idle_sockets.size(); } -LoadState ClientSocketPoolBase::GetLoadState( +LoadState ClientSocketPoolBaseHelper::GetLoadState( const std::string& group_name, const ClientSocketHandle* handle) const { if (!ContainsKey(group_map_, group_name)) { @@ -251,7 +249,7 @@ LoadState ClientSocketPoolBase::GetLoadState( // Search pending_requests for matching handle. RequestQueue::const_iterator it = group.pending_requests.begin(); for (size_t i = 0; it != group.pending_requests.end(); ++it, ++i) { - if (it->handle == handle) { + if ((*it)->handle() == handle) { if (g_late_binding && i < group.jobs.size()) { LoadState max_state = LOAD_STATE_IDLE; for (ConnectJobSet::const_iterator job_it = group.jobs.begin(); @@ -271,7 +269,7 @@ LoadState ClientSocketPoolBase::GetLoadState( return LOAD_STATE_IDLE; } -bool ClientSocketPoolBase::IdleSocket::ShouldCleanup( +bool ClientSocketPoolBaseHelper::IdleSocket::ShouldCleanup( base::TimeTicks now) const { bool timed_out = (now - start_time) >= base::TimeDelta::FromSeconds(kIdleTimeout); @@ -279,7 +277,7 @@ bool ClientSocketPoolBase::IdleSocket::ShouldCleanup( !(used ? socket->IsConnectedAndIdle() : socket->IsConnected()); } -void ClientSocketPoolBase::CleanupIdleSockets(bool force) { +void ClientSocketPoolBaseHelper::CleanupIdleSockets(bool force) { if (idle_socket_count_ == 0) return; @@ -311,19 +309,19 @@ void ClientSocketPoolBase::CleanupIdleSockets(bool force) { } } -void ClientSocketPoolBase::IncrementIdleCount() { +void ClientSocketPoolBaseHelper::IncrementIdleCount() { if (++idle_socket_count_ == 1) timer_.Start(TimeDelta::FromSeconds(kCleanupInterval), this, - &ClientSocketPoolBase::OnCleanupTimerFired); + &ClientSocketPoolBaseHelper::OnCleanupTimerFired); } -void ClientSocketPoolBase::DecrementIdleCount() { +void ClientSocketPoolBaseHelper::DecrementIdleCount() { if (--idle_socket_count_ == 0) timer_.Stop(); } -void ClientSocketPoolBase::DoReleaseSocket(const std::string& group_name, - ClientSocket* socket) { +void ClientSocketPoolBaseHelper::DoReleaseSocket(const std::string& group_name, + ClientSocket* socket) { GroupMap::iterator i = group_map_.find(group_name); CHECK(i != group_map_.end()); @@ -349,8 +347,8 @@ void ClientSocketPoolBase::DoReleaseSocket(const std::string& group_name, // are not at the |max_sockets_per_group_| limit. Note: for requests with // the same priority, the winner is based on group hash ordering (and not // insertion order). -int ClientSocketPoolBase::FindTopStalledGroup(Group** group, - std::string* group_name) { +int ClientSocketPoolBaseHelper::FindTopStalledGroup(Group** group, + std::string* group_name) { Group* top_group = NULL; const std::string* top_group_name = NULL; int stalled_group_count = 0; @@ -377,7 +375,8 @@ int ClientSocketPoolBase::FindTopStalledGroup(Group** group, return stalled_group_count; } -void ClientSocketPoolBase::OnConnectJobComplete(int result, ConnectJob* job) { +void ClientSocketPoolBaseHelper::OnConnectJobComplete( + int result, ConnectJob* job) { DCHECK_NE(ERR_IO_PENDING, result); const std::string group_name = job->group_name(); GroupMap::iterator group_it = group_map_.find(group_name); @@ -393,11 +392,11 @@ void ClientSocketPoolBase::OnConnectJobComplete(int result, ConnectJob* job) { if (result == OK) { DCHECK(socket.get()); if (!group.pending_requests.empty()) { - Request r = group.pending_requests.front(); + scoped_ptr<const Request> r(group.pending_requests.front()); group.pending_requests.pop_front(); HandOutSocket( - socket.release(), false /* unused socket */, r.handle, &group); - r.callback->Run(result); + socket.release(), false /* unused socket */, r->handle(), &group); + r->callback()->Run(result); } else { AddIdleSocket(socket.release(), false /* unused socket */, &group); OnAvailableSocketSlot(group_name, &group); @@ -405,9 +404,9 @@ void ClientSocketPoolBase::OnConnectJobComplete(int result, ConnectJob* job) { } else { DCHECK(!socket.get()); if (!group.pending_requests.empty()) { - Request r = group.pending_requests.front(); + scoped_ptr<const Request> r(group.pending_requests.front()); group.pending_requests.pop_front(); - r.callback->Run(result); + r->callback()->Run(result); } MaybeOnAvailableSocketSlot(group_name); } @@ -418,8 +417,9 @@ void ClientSocketPoolBase::OnConnectJobComplete(int result, ConnectJob* job) { RequestMap* request_map = &group.connecting_requests; RequestMap::iterator it = request_map->find(key_handle); CHECK(it != request_map->end()); - ClientSocketHandle* const handle = it->second.handle; - CompletionCallback* const callback = it->second.callback; + const Request* request = it->second; + ClientSocketHandle* const handle = request->handle(); + CompletionCallback* const callback = request->callback(); RemoveConnectJob(key_handle, job, &group); @@ -436,11 +436,11 @@ void ClientSocketPoolBase::OnConnectJobComplete(int result, ConnectJob* job) { } } -void ClientSocketPoolBase::EnableLateBindingOfSockets(bool enabled) { +void ClientSocketPoolBaseHelper::EnableLateBindingOfSockets(bool enabled) { g_late_binding = enabled; } -void ClientSocketPoolBase::RemoveConnectJob( +void ClientSocketPoolBaseHelper::RemoveConnectJob( const ClientSocketHandle* handle, const ConnectJob *job, Group* group) { CHECK(connecting_socket_count_ > 0); connecting_socket_count_--; @@ -454,7 +454,11 @@ void ClientSocketPoolBase::RemoveConnectJob( job = it->second; delete job; connect_job_map_.erase(it); - group->connecting_requests.erase(handle); + RequestMap::iterator map_it = group->connecting_requests.find(handle); + CHECK(map_it != group->connecting_requests.end()); + const Request* request = map_it->second; + delete request; + group->connecting_requests.erase(map_it); } if (group) { @@ -463,7 +467,7 @@ void ClientSocketPoolBase::RemoveConnectJob( } } -void ClientSocketPoolBase::MaybeOnAvailableSocketSlot( +void ClientSocketPoolBaseHelper::MaybeOnAvailableSocketSlot( const std::string& group_name) { GroupMap::iterator it = group_map_.find(group_name); if (it != group_map_.end()) { @@ -473,8 +477,8 @@ void ClientSocketPoolBase::MaybeOnAvailableSocketSlot( } } -void ClientSocketPoolBase::OnAvailableSocketSlot(const std::string& group_name, - Group* group) { +void ClientSocketPoolBaseHelper::OnAvailableSocketSlot( + const std::string& group_name, Group* group) { if (may_have_stalled_group_) { std::string top_group_name; Group* top_group; @@ -493,25 +497,26 @@ void ClientSocketPoolBase::OnAvailableSocketSlot(const std::string& group_name, } } -void ClientSocketPoolBase::ProcessPendingRequest(const std::string& group_name, - Group* group) { - Request r = group->pending_requests.front(); +void ClientSocketPoolBaseHelper::ProcessPendingRequest( + const std::string& group_name, Group* group) { + scoped_ptr<const Request> r(group->pending_requests.front()); group->pending_requests.pop_front(); - int rv = RequestSocket( - group_name, r.resolve_info, r.priority, r.handle, r.callback, r.load_log); + int rv = RequestSocket(group_name, r.get()); if (rv != ERR_IO_PENDING) { - r.callback->Run(rv); + r->callback()->Run(rv); if (rv != OK) { // |group| may be invalid after the callback, we need to search // |group_map_| again. MaybeOnAvailableSocketSlot(group_name); } + } else { + r.release(); } } -void ClientSocketPoolBase::HandOutSocket( +void ClientSocketPoolBaseHelper::HandOutSocket( ClientSocket* socket, bool reused, ClientSocketHandle* handle, @@ -524,7 +529,7 @@ void ClientSocketPoolBase::HandOutSocket( group->active_socket_count++; } -void ClientSocketPoolBase::AddIdleSocket( +void ClientSocketPoolBaseHelper::AddIdleSocket( ClientSocket* socket, bool used, Group* group) { DCHECK(socket); IdleSocket idle_socket; @@ -536,7 +541,7 @@ void ClientSocketPoolBase::AddIdleSocket( IncrementIdleCount(); } -void ClientSocketPoolBase::CancelAllConnectJobs() { +void ClientSocketPoolBaseHelper::CancelAllConnectJobs() { for (GroupMap::iterator i = group_map_.begin(); i != group_map_.end();) { Group& group = i->second; STLDeleteElements(&group.jobs); @@ -550,11 +555,17 @@ void ClientSocketPoolBase::CancelAllConnectJobs() { } } -bool ClientSocketPoolBase::ReachedMaxSocketsLimit() const { +bool ClientSocketPoolBaseHelper::ReachedMaxSocketsLimit() const { // Each connecting socket will eventually connect and be handed out. int total = handed_out_socket_count_ + connecting_socket_count_; DCHECK_LE(total, max_sockets_); return total == max_sockets_; } +} // namespace internal + +void EnableLateBindingOfSockets(bool enabled) { + internal::ClientSocketPoolBaseHelper::EnableLateBindingOfSockets(enabled); +} + } // namespace net diff --git a/net/socket/client_socket_pool_base.h b/net/socket/client_socket_pool_base.h index 4ae96f8..bae88b7 100644 --- a/net/socket/client_socket_pool_base.h +++ b/net/socket/client_socket_pool_base.h @@ -1,7 +1,24 @@ // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. - +// +// A ClientSocketPoolBase is used to restrict the number of sockets open at +// a time. It also maintains a list of idle persistent sockets for reuse. +// Subclasses of ClientSocketPool should compose ClientSocketPoolBase to handle +// the core logic of (1) restricting the number of active (connected or +// connecting) sockets per "group" (generally speaking, the hostname), (2) +// maintaining a per-group list of idle, persistent sockets for reuse, and (3) +// limiting the total number of active sockets in the system. +// +// ClientSocketPoolBase abstracts socket connection details behind ConnectJob, +// ConnectJobFactory, and SocketParams. When a socket "slot" becomes available, +// the ClientSocketPoolBase will ask the ConnectJobFactory to create a +// ConnectJob with a SocketParams. Subclasses of ClientSocketPool should +// implement their socket specific connection by subclassing ConnectJob and +// implementing ConnectJob::ConnectInternal(). They can control the parameters +// passed to each new ConnectJob instance via their ConnectJobFactory subclass +// and templated SocketParams parameter. +// #ifndef NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ #define NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ @@ -16,16 +33,15 @@ #include "base/timer.h" #include "net/base/address_list.h" #include "net/base/completion_callback.h" -#include "net/base/host_resolver.h" #include "net/base/load_log.h" #include "net/base/load_states.h" +#include "net/base/net_errors.h" #include "net/socket/client_socket.h" #include "net/socket/client_socket_pool.h" namespace net { class ClientSocketHandle; -class ClientSocketPoolBase; // ConnectJob provides an abstract interface for "connecting" a socket. // The connection may involve host resolution, tcp connection, ssl connection, @@ -93,37 +109,39 @@ class ConnectJob { DISALLOW_COPY_AND_ASSIGN(ConnectJob); }; -// A ClientSocketPoolBase is used to restrict the number of sockets open at -// a time. It also maintains a list of idle persistent sockets. -// -class ClientSocketPoolBase - : public base::RefCounted<ClientSocketPoolBase>, +namespace internal { + +// ClientSocketPoolBaseHelper is an internal class that implements almost all +// the functionality from ClientSocketPoolBase without using templates. +// ClientSocketPoolBase adds templated definitions built on top of +// ClientSocketPoolBaseHelper. This class is not for external use, please use +// ClientSocketPoolBase instead. +class ClientSocketPoolBaseHelper + : public base::RefCounted<ClientSocketPoolBaseHelper>, public ConnectJob::Delegate { public: - // A Request is allocated per call to RequestSocket that results in - // ERR_IO_PENDING. - struct Request { - // HostResolver::RequestInfo has no default constructor, so fudge something. - Request() - : handle(NULL), - callback(NULL), - priority(0), - resolve_info(std::string(), 0) {} - + class Request { + public: Request(ClientSocketHandle* handle, CompletionCallback* callback, int priority, - const HostResolver::RequestInfo& resolve_info, LoadLog* load_log) - : load_log(load_log), handle(handle), callback(callback), - priority(priority), resolve_info(resolve_info) { - } + : handle_(handle), callback_(callback), priority_(priority) {} + + virtual ~Request() {} - scoped_refptr<LoadLog> load_log; - ClientSocketHandle* handle; - CompletionCallback* callback; - int priority; - HostResolver::RequestInfo resolve_info; + ClientSocketHandle* handle() const { return handle_; } + CompletionCallback* callback() const { return callback_; } + int priority() const { return priority_; } + LoadLog* load_log() const { return load_log_.get(); } + + private: + ClientSocketHandle* const handle_; + CompletionCallback* const callback_; + const int priority_; + const scoped_refptr<LoadLog> load_log_; + + DISALLOW_COPY_AND_ASSIGN(Request); }; class ConnectJobFactory { @@ -140,36 +158,42 @@ class ClientSocketPoolBase DISALLOW_COPY_AND_ASSIGN(ConnectJobFactory); }; - ClientSocketPoolBase(int max_sockets, - int max_sockets_per_group, - ConnectJobFactory* connect_job_factory); + ClientSocketPoolBaseHelper(int max_sockets, + int max_sockets_per_group, + ConnectJobFactory* connect_job_factory); - ~ClientSocketPoolBase(); + ~ClientSocketPoolBaseHelper(); - int RequestSocket(const std::string& group_name, - const HostResolver::RequestInfo& resolve_info, - int priority, - ClientSocketHandle* handle, - CompletionCallback* callback, - LoadLog* load_log); + // See ClientSocketPool::RequestSocket for documentation on this function. + // Note that |request| must be heap allocated. If ERR_IO_PENDING is returned, + // then ClientSocketPoolBaseHelper takes ownership of |request|. + int RequestSocket(const std::string& group_name, const Request* request); + // See ClientSocketPool::CancelRequest for documentation on this function. void CancelRequest(const std::string& group_name, const ClientSocketHandle* handle); + // See ClientSocketPool::ReleaseSocket for documentation on this function. void ReleaseSocket(const std::string& group_name, ClientSocket* socket); + // See ClientSocketPool::CloseIdleSockets for documentation on this function. void CloseIdleSockets(); + // See ClientSocketPool::IdleSocketCount() for documentation on this function. int idle_socket_count() const { return idle_socket_count_; } + // See ClientSocketPool::IdleSocketCountInGroup() for documentation on this + // function. int IdleSocketCountInGroup(const std::string& group_name) const; + // See ClientSocketPool::GetLoadState() for documentation on this function. LoadState GetLoadState(const std::string& group_name, const ClientSocketHandle* handle) const; + // ConnectJob::Delegate methods: virtual void OnConnectJobComplete(int result, ConnectJob* job); // Enables late binding of sockets. In this mode, socket requests are @@ -182,6 +206,7 @@ class ClientSocketPoolBase // For testing. bool may_have_stalled_group() const { return may_have_stalled_group_; } + int NumConnectJobsInGroup(const std::string& group_name) const { return group_map_.find(group_name)->second.jobs.size(); } @@ -204,8 +229,8 @@ class ClientSocketPoolBase bool ShouldCleanup(base::TimeTicks now) const; }; - typedef std::deque<Request> RequestQueue; - typedef std::map<const ClientSocketHandle*, Request> RequestMap; + typedef std::deque<const Request*> RequestQueue; + typedef std::map<const ClientSocketHandle*, const 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. @@ -223,7 +248,7 @@ class ClientSocketPoolBase } int TopPendingPriority() const { - return pending_requests.front().priority; + return pending_requests.front()->priority(); } std::deque<IdleSocket> idle_sockets; @@ -238,7 +263,7 @@ class ClientSocketPoolBase typedef std::map<const ClientSocketHandle*, ConnectJob*> ConnectJobMap; typedef std::set<const ConnectJob*> ConnectJobSet; - static void InsertRequestIntoQueue(const Request& r, + static void InsertRequestIntoQueue(const Request* r, RequestQueue* pending_requests); // Closes all idle sockets if |force| is true. Else, only closes idle @@ -267,7 +292,8 @@ class ClientSocketPoolBase // Removes the ConnectJob corresponding to |handle| from the // |connect_job_map_| or |connect_job_set_| depending on whether or not late // binding is enabled. |job| must be non-NULL when late binding is - // enabled. Also updates |group| if non-NULL. + // enabled. Also updates |group| if non-NULL. When late binding is disabled, + // this will also delete the Request from |group->connecting_requests|. void RemoveConnectJob(const ClientSocketHandle* handle, const ConnectJob* job, Group* group); @@ -307,7 +333,7 @@ class ClientSocketPoolBase // Timer used to periodically prune idle sockets that timed out or can't be // reused. - base::RepeatingTimer<ClientSocketPoolBase> timer_; + base::RepeatingTimer<ClientSocketPoolBaseHelper> timer_; // The total number of idle sockets in the system. int idle_socket_count_; @@ -345,9 +371,154 @@ class ClientSocketPoolBase // Controls whether or not we use late binding of sockets. static bool g_late_binding; +}; + +} // namespace internal + +template <typename SocketParams> +class ClientSocketPoolBase { + public: + class Request : public internal::ClientSocketPoolBaseHelper::Request { + public: + Request(ClientSocketHandle* handle, + CompletionCallback* callback, + int priority, + const SocketParams& params, + LoadLog* load_log) + : internal::ClientSocketPoolBaseHelper::Request( + handle, callback, priority, load_log), + params_(params) {} + + const SocketParams& params() const { return params_; } + + private: + SocketParams params_; + }; + + class ConnectJobFactory { + public: + ConnectJobFactory() {} + virtual ~ConnectJobFactory() {} + + virtual ConnectJob* NewConnectJob( + const std::string& group_name, + const Request& request, + ConnectJob::Delegate* delegate) const = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(ConnectJobFactory); + }; + + ClientSocketPoolBase(int max_sockets, + int max_sockets_per_group, + ConnectJobFactory* connect_job_factory) + : helper_(new internal::ClientSocketPoolBaseHelper( + max_sockets, max_sockets_per_group, + new ConnectJobFactoryAdaptor(connect_job_factory))) {} + + ~ClientSocketPoolBase() {} + + // These member functions simply forward to ClientSocketPoolBaseHelper. + + // RequestSocket bundles up the parameters into a Request and then forwards to + // ClientSocketPoolBaseHelper::RequestSocket(). Note that the memory + // ownership is transferred in the asynchronous (ERR_IO_PENDING) case. + int RequestSocket(const std::string& group_name, + const SocketParams& params, + int priority, + ClientSocketHandle* handle, + CompletionCallback* callback, + LoadLog* load_log) { + scoped_ptr<Request> request( + new Request(handle, callback, priority, params, load_log)); + int rv = helper_->RequestSocket(group_name, request.get()); + if (rv == ERR_IO_PENDING) + request.release(); + return rv; + } + + void CancelRequest(const std::string& group_name, + const ClientSocketHandle* handle) { + return helper_->CancelRequest(group_name, handle); + } + + void ReleaseSocket(const std::string& group_name, ClientSocket* socket) { + return helper_->ReleaseSocket(group_name, socket); + } + + void CloseIdleSockets() { return helper_->CloseIdleSockets(); } + + int idle_socket_count() const { return helper_->idle_socket_count(); } + + int IdleSocketCountInGroup(const std::string& group_name) const { + return helper_->IdleSocketCountInGroup(group_name); + } + + LoadState GetLoadState(const std::string& group_name, + const ClientSocketHandle* handle) const { + return helper_->GetLoadState(group_name, handle); + } + + virtual void OnConnectJobComplete(int result, ConnectJob* job) { + return helper_->OnConnectJobComplete(result, job); + } + + // For testing. + bool may_have_stalled_group() const { + return helper_->may_have_stalled_group(); + } + + int NumConnectJobsInGroup(const std::string& group_name) const { + return helper_->NumConnectJobsInGroup(group_name); + } + + private: + // This adaptor class exists to bridge the + // internal::ClientSocketPoolBaseHelper::ConnectJobFactory and + // ClientSocketPoolBase::ConnectJobFactory types, allowing clients to use the + // typesafe ClientSocketPoolBase::ConnectJobFactory, rather than having to + // static_cast themselves. + class ConnectJobFactoryAdaptor + : public internal::ClientSocketPoolBaseHelper::ConnectJobFactory { + public: + typedef typename ClientSocketPoolBase<SocketParams>::ConnectJobFactory + ConnectJobFactory; + + explicit ConnectJobFactoryAdaptor( + ConnectJobFactory* connect_job_factory) + : connect_job_factory_(connect_job_factory) {} + virtual ~ConnectJobFactoryAdaptor() {} + + virtual ConnectJob* NewConnectJob( + const std::string& group_name, + const internal::ClientSocketPoolBaseHelper::Request& request, + ConnectJob::Delegate* delegate) const { + const Request* casted_request = static_cast<const Request*>(&request); + return connect_job_factory_->NewConnectJob( + group_name, *casted_request, delegate); + } + + const scoped_ptr<ConnectJobFactory> connect_job_factory_; + }; + + // One might ask why ClientSocketPoolBaseHelper is also refcounted if its + // containing ClientSocketPool is already refcounted. The reason is because + // DoReleaseSocket() posts a task. If ClientSocketPool gets deleted between + // the posting of the task and the execution, then we'll hit the DCHECK that + // |ClientSocketPoolBaseHelper::group_map_| is empty. + scoped_refptr<internal::ClientSocketPoolBaseHelper> helper_; + DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); }; +// Enables late binding of sockets. In this mode, socket requests are +// decoupled from socket connection jobs. A socket request may initiate a +// socket connection job, but there is no guarantee that that socket +// connection will service the request (for example, a released socket may +// service the request sooner, or a higher priority request may come in +// afterward and receive the socket from the job). +void EnableLateBindingOfSockets(bool enabled); + } // namespace net #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc index 963d017..1f20c76 100644 --- a/net/socket/client_socket_pool_base_unittest.cc +++ b/net/socket/client_socket_pool_base_unittest.cc @@ -21,11 +21,11 @@ namespace net { namespace { const int kDefaultMaxSockets = 4; - const int kDefaultMaxSocketsPerGroup = 2; - const int kDefaultPriority = 5; +typedef ClientSocketPoolBase<const void*> TestClientSocketPoolBase; + class MockClientSocket : public ClientSocket { public: MockClientSocket() : connected_(false) {} @@ -107,11 +107,11 @@ class TestConnectJob : public ConnectJob { TestConnectJob(JobType job_type, const std::string& group_name, - const ClientSocketPoolBase::Request& request, + const TestClientSocketPoolBase::Request& request, base::TimeDelta timeout_duration, ConnectJob::Delegate* delegate, MockClientSocketFactory* client_socket_factory) - : ConnectJob(group_name, request.handle, timeout_duration, delegate), + : ConnectJob(group_name, request.handle(), timeout_duration, delegate), job_type_(job_type), client_socket_factory_(client_socket_factory), method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {} @@ -202,7 +202,8 @@ class TestConnectJob : public ConnectJob { DISALLOW_COPY_AND_ASSIGN(TestConnectJob); }; -class TestConnectJobFactory : public ClientSocketPoolBase::ConnectJobFactory { +class TestConnectJobFactory + : public TestClientSocketPoolBase::ConnectJobFactory { public: explicit TestConnectJobFactory(MockClientSocketFactory* client_socket_factory) : job_type_(TestConnectJob::kMockJob), @@ -220,7 +221,7 @@ class TestConnectJobFactory : public ClientSocketPoolBase::ConnectJobFactory { virtual ConnectJob* NewConnectJob( const std::string& group_name, - const ClientSocketPoolBase::Request& request, + const TestClientSocketPoolBase::Request& request, ConnectJob::Delegate* delegate) const { return new TestConnectJob(job_type_, group_name, @@ -243,56 +244,55 @@ class TestClientSocketPool : public ClientSocketPool { TestClientSocketPool( int max_sockets, int max_sockets_per_group, - ClientSocketPoolBase::ConnectJobFactory* connect_job_factory) - : base_(new ClientSocketPoolBase( - max_sockets, max_sockets_per_group, connect_job_factory)) {} + TestClientSocketPoolBase::ConnectJobFactory* connect_job_factory) + : base_(max_sockets, max_sockets_per_group, connect_job_factory) {} virtual int RequestSocket( const std::string& group_name, - const HostResolver::RequestInfo& resolve_info, + const void* params, int priority, ClientSocketHandle* handle, CompletionCallback* callback, LoadLog* load_log) { - return base_->RequestSocket( - group_name, resolve_info, priority, handle, callback, load_log); + return base_.RequestSocket( + group_name, params, priority, handle, callback, load_log); } virtual void CancelRequest( const std::string& group_name, const ClientSocketHandle* handle) { - base_->CancelRequest(group_name, handle); + base_.CancelRequest(group_name, handle); } virtual void ReleaseSocket( const std::string& group_name, ClientSocket* socket) { - base_->ReleaseSocket(group_name, socket); + base_.ReleaseSocket(group_name, socket); } virtual void CloseIdleSockets() { - base_->CloseIdleSockets(); + base_.CloseIdleSockets(); } - virtual int IdleSocketCount() const { return base_->idle_socket_count(); } + virtual int IdleSocketCount() const { return base_.idle_socket_count(); } virtual int IdleSocketCountInGroup(const std::string& group_name) const { - return base_->IdleSocketCountInGroup(group_name); + return base_.IdleSocketCountInGroup(group_name); } virtual LoadState GetLoadState(const std::string& group_name, const ClientSocketHandle* handle) const { - return base_->GetLoadState(group_name, handle); + return base_.GetLoadState(group_name, handle); } - const ClientSocketPoolBase* base() const { return base_.get(); } + const TestClientSocketPoolBase* base() const { return &base_; } int NumConnectJobsInGroup(const std::string& group_name) const { - return base_->NumConnectJobsInGroup(group_name); + return base_.NumConnectJobsInGroup(group_name); } private: - const scoped_refptr<ClientSocketPoolBase> base_; + TestClientSocketPoolBase base_; DISALLOW_COPY_AND_ASSIGN(TestClientSocketPool); }; @@ -366,7 +366,7 @@ class ClientSocketPoolBaseTest : public ClientSocketPoolTest { pool_ = NULL; requests_.reset(); - ClientSocketPoolBase::EnableLateBindingOfSockets(false); + EnableLateBindingOfSockets(false); ClientSocketPoolTest::TearDown(); } @@ -380,9 +380,9 @@ class ClientSocketPoolBaseTest : public ClientSocketPoolTest { // completion. TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) { TestConnectJobDelegate delegate; - ClientSocketPoolBase::Request request; - ClientSocketHandle ignored(pool_.get()); - request.handle = &ignored; + ClientSocketHandle ignored(NULL); + TestClientSocketPoolBase::Request request( + &ignored, NULL, kDefaultPriority, NULL, NULL); scoped_ptr<TestConnectJob> job( new TestConnectJob(TestConnectJob::kMockJob, "a", @@ -395,9 +395,9 @@ TEST_F(ClientSocketPoolBaseTest, ConnectJob_NoTimeoutOnSynchronousCompletion) { TEST_F(ClientSocketPoolBaseTest, ConnectJob_TimedOut) { TestConnectJobDelegate delegate; - ClientSocketPoolBase::Request request; - ClientSocketHandle ignored(pool_.get()); - request.handle = &ignored; + ClientSocketHandle ignored(NULL); + TestClientSocketPoolBase::Request request( + &ignored, NULL, kDefaultPriority, NULL, NULL); // Deleted by TestConnectJobDelegate. TestConnectJob* job = new TestConnectJob(TestConnectJob::kMockPendingJob, @@ -1027,7 +1027,7 @@ TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) { // available, the request will be serviced by the ConnectJob. TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) { CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); - ClientSocketPoolBase::EnableLateBindingOfSockets(false); + EnableLateBindingOfSockets(false); // Start job 1 (async OK) connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); @@ -1105,7 +1105,7 @@ class ClientSocketPoolBaseTest_LateBinding : public ClientSocketPoolBaseTest { protected: virtual void SetUp() { ClientSocketPoolBaseTest::SetUp(); - ClientSocketPoolBase::EnableLateBindingOfSockets(true); + EnableLateBindingOfSockets(true); } }; @@ -1114,9 +1114,8 @@ class ClientSocketPoolBaseTest_LateBinding : public ClientSocketPoolBaseTest { TEST_F(ClientSocketPoolBaseTest_LateBinding, ConnectJob_NoTimeoutOnSynchronousCompletion) { TestConnectJobDelegate delegate; - ClientSocketPoolBase::Request request; ClientSocketHandle ignored(pool_.get()); - request.handle = &ignored; + TestClientSocketPoolBase::Request request(&ignored, NULL, 0, NULL, NULL); scoped_ptr<TestConnectJob> job( new TestConnectJob(TestConnectJob::kMockJob, "a", @@ -1129,9 +1128,8 @@ TEST_F(ClientSocketPoolBaseTest_LateBinding, TEST_F(ClientSocketPoolBaseTest_LateBinding, ConnectJob_TimedOut) { TestConnectJobDelegate delegate; - ClientSocketPoolBase::Request request; ClientSocketHandle ignored(pool_.get()); - request.handle = &ignored; + TestClientSocketPoolBase::Request request(&ignored, NULL, 0, NULL, NULL); // Deleted by TestConnectJobDelegate. TestConnectJob* job = new TestConnectJob(TestConnectJob::kMockPendingJob, diff --git a/net/socket/tcp_client_socket_pool.cc b/net/socket/tcp_client_socket_pool.cc index ae080dd..2a23e55 100644 --- a/net/socket/tcp_client_socket_pool.cc +++ b/net/socket/tcp_client_socket_pool.cc @@ -129,10 +129,10 @@ int TCPConnectJob::DoTCPConnectComplete(int result) { ConnectJob* TCPClientSocketPool::TCPConnectJobFactory::NewConnectJob( const std::string& group_name, - const ClientSocketPoolBase::Request& request, + const PoolBase::Request& request, ConnectJob::Delegate* delegate) const { return new TCPConnectJob( - group_name, request.resolve_info, request.handle, + group_name, request.params(), request.handle(), base::TimeDelta::FromSeconds(kTCPConnectJobTimeoutInSeconds), client_socket_factory_, host_resolver_, delegate); } @@ -142,47 +142,48 @@ TCPClientSocketPool::TCPClientSocketPool( int max_sockets_per_group, HostResolver* host_resolver, ClientSocketFactory* client_socket_factory) - : base_(new ClientSocketPoolBase( - max_sockets, max_sockets_per_group, - new TCPConnectJobFactory(client_socket_factory, host_resolver))) {} + : base_(max_sockets, max_sockets_per_group, + new TCPConnectJobFactory(client_socket_factory, host_resolver)) {} TCPClientSocketPool::~TCPClientSocketPool() {} int TCPClientSocketPool::RequestSocket( const std::string& group_name, - const HostResolver::RequestInfo& resolve_info, + const void* resolve_info, int priority, ClientSocketHandle* handle, CompletionCallback* callback, LoadLog* load_log) { - return base_->RequestSocket( - group_name, resolve_info, priority, handle, callback, load_log); + const HostResolver::RequestInfo* casted_resolve_info = + static_cast<const HostResolver::RequestInfo*>(resolve_info); + return base_.RequestSocket( + group_name, *casted_resolve_info, priority, handle, callback, load_log); } void TCPClientSocketPool::CancelRequest( const std::string& group_name, const ClientSocketHandle* handle) { - base_->CancelRequest(group_name, handle); + base_.CancelRequest(group_name, handle); } void TCPClientSocketPool::ReleaseSocket( const std::string& group_name, ClientSocket* socket) { - base_->ReleaseSocket(group_name, socket); + base_.ReleaseSocket(group_name, socket); } void TCPClientSocketPool::CloseIdleSockets() { - base_->CloseIdleSockets(); + base_.CloseIdleSockets(); } int TCPClientSocketPool::IdleSocketCountInGroup( const std::string& group_name) const { - return base_->IdleSocketCountInGroup(group_name); + return base_.IdleSocketCountInGroup(group_name); } LoadState TCPClientSocketPool::GetLoadState( const std::string& group_name, const ClientSocketHandle* handle) const { - return base_->GetLoadState(group_name, handle); + return base_.GetLoadState(group_name, handle); } } // namespace net diff --git a/net/socket/tcp_client_socket_pool.h b/net/socket/tcp_client_socket_pool.h index 8533d0e..4532000 100644 --- a/net/socket/tcp_client_socket_pool.h +++ b/net/socket/tcp_client_socket_pool.h @@ -81,7 +81,7 @@ class TCPClientSocketPool : public ClientSocketPool { // ClientSocketPool methods: virtual int RequestSocket(const std::string& group_name, - const HostResolver::RequestInfo& resolve_info, + const void* resolve_info, int priority, ClientSocketHandle* handle, CompletionCallback* callback, @@ -96,7 +96,7 @@ class TCPClientSocketPool : public ClientSocketPool { virtual void CloseIdleSockets(); virtual int IdleSocketCount() const { - return base_->idle_socket_count(); + return base_.idle_socket_count(); } virtual int IdleSocketCountInGroup(const std::string& group_name) const; @@ -105,10 +105,10 @@ class TCPClientSocketPool : public ClientSocketPool { const ClientSocketHandle* handle) const; private: - virtual ~TCPClientSocketPool(); + typedef ClientSocketPoolBase<HostResolver::RequestInfo> PoolBase; class TCPConnectJobFactory - : public ClientSocketPoolBase::ConnectJobFactory { + : public PoolBase::ConnectJobFactory { public: TCPConnectJobFactory(ClientSocketFactory* client_socket_factory, HostResolver* host_resolver) @@ -121,7 +121,7 @@ class TCPClientSocketPool : public ClientSocketPool { virtual ConnectJob* NewConnectJob( const std::string& group_name, - const ClientSocketPoolBase::Request& request, + const PoolBase::Request& request, ConnectJob::Delegate* delegate) const; private: @@ -131,12 +131,9 @@ class TCPClientSocketPool : public ClientSocketPool { DISALLOW_COPY_AND_ASSIGN(TCPConnectJobFactory); }; - // One might ask why ClientSocketPoolBase is also refcounted if its - // containing ClientSocketPool is already refcounted. The reason is because - // DoReleaseSocket() posts a task. If ClientSocketPool gets deleted between - // the posting of the task and the execution, then we'll hit the DCHECK that - // |ClientSocketPoolBase::group_map_| is empty. - scoped_refptr<ClientSocketPoolBase> base_; + virtual ~TCPClientSocketPool(); + + PoolBase base_; DISALLOW_COPY_AND_ASSIGN(TCPClientSocketPool); }; |