summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser_main.cc2
-rw-r--r--net/http/http_network_transaction_unittest.cc14
-rw-r--r--net/socket/client_socket_handle.cc19
-rw-r--r--net/socket/client_socket_handle.h32
-rw-r--r--net/socket/client_socket_pool.h2
-rw-r--r--net/socket/client_socket_pool_base.cc147
-rw-r--r--net/socket/client_socket_pool_base.h257
-rw-r--r--net/socket/client_socket_pool_base_unittest.cc66
-rw-r--r--net/socket/tcp_client_socket_pool.cc27
-rw-r--r--net/socket/tcp_client_socket_pool.h19
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);
};