summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/base/client_socket_handle.cc (renamed from net/http/http_connection.cc)22
-rw-r--r--net/base/client_socket_handle.h (renamed from net/http/http_connection.h)49
-rw-r--r--net/base/client_socket_pool.cc (renamed from net/http/http_connection_manager.cc)71
-rw-r--r--net/base/client_socket_pool.h (renamed from net/http/http_connection_manager.h)88
-rw-r--r--net/base/client_socket_pool_unittest.cc (renamed from net/http/http_connection_manager_unittest.cc)153
-rw-r--r--net/build/net.vcproj32
-rw-r--r--net/build/net_unittests.vcproj8
-rw-r--r--net/http/http_network_layer.cc2
-rw-r--r--net/http/http_network_session.h13
-rw-r--r--net/http/http_network_transaction.cc2
10 files changed, 231 insertions, 209 deletions
diff --git a/net/http/http_connection.cc b/net/base/client_socket_handle.cc
index 0ca8a3d..a7b668e 100644
--- a/net/http/http_connection.cc
+++ b/net/base/client_socket_handle.cc
@@ -27,36 +27,36 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "net/http/http_connection.h"
+#include "net/base/client_socket_handle.h"
#include "net/base/client_socket.h"
-#include "net/http/http_connection_manager.h"
+#include "net/base/client_socket_pool.h"
namespace net {
-HttpConnection::HttpConnection(HttpConnectionManager* mgr)
- : mgr_(mgr), socket_(NULL) {
+ClientSocketHandle::ClientSocketHandle(ClientSocketPool* pool)
+ : pool_(pool), socket_(NULL) {
}
-HttpConnection::~HttpConnection() {
+ClientSocketHandle::~ClientSocketHandle() {
Reset();
}
-int HttpConnection::Init(const std::string& group_name,
- CompletionCallback* callback) {
+int ClientSocketHandle::Init(const std::string& group_name,
+ CompletionCallback* callback) {
Reset();
group_name_ = group_name;
- return mgr_->RequestSocket(group_name_, &socket_, callback);
+ return pool_->RequestSocket(this, callback);
}
-void HttpConnection::Reset() {
+void ClientSocketHandle::Reset() {
if (group_name_.empty()) // Was Init called?
return;
if (socket_) {
- mgr_->ReleaseSocket(group_name_, socket_);
+ pool_->ReleaseSocket(this);
socket_ = NULL;
} else {
- mgr_->CancelRequest(group_name_, &socket_);
+ pool_->CancelRequest(this);
}
group_name_.clear();
}
diff --git a/net/http/http_connection.h b/net/base/client_socket_handle.h
index e3a6496..f5cab7f 100644
--- a/net/http/http_connection.h
+++ b/net/base/client_socket_handle.h
@@ -27,8 +27,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#ifndef NET_HTTP_HTTP_CONNECTION_H_
-#define NET_HTTP_HTTP_CONNECTION_H_
+#ifndef NET_BASE_CLIENT_SOCKET_HANDLE_H_
+#define NET_BASE_CLIENT_SOCKET_HANDLE_H_
#include <string>
@@ -39,29 +39,29 @@
namespace net {
-class HttpConnectionManager;
+class ClientSocketPool;
-// A container for a ClientSocket, representing a HTTP connection.
+// A container for a connected ClientSocket.
//
-// The connection's |group_name| uniquely identifies the origin and type of the
-// connection. It is used by the HttpConnectionManager to group similar http
-// connection objects.
+// The handle's |group_name| uniquely identifies the origin and type of the
+// connection. It is used by the ClientSocketPool to group similar connected
+// client socket objects.
//
-// A connection object is initialized with a null socket. It is the consumer's
-// job to initialize a ClientSocket object and set it on the connection.
+// A handle is initialized with a null socket. It is the consumer's job to
+// initialize a ClientSocket object and set it on the handle.
//
-class HttpConnection {
+class ClientSocketHandle {
public:
- explicit HttpConnection(HttpConnectionManager* mgr);
- ~HttpConnection();
+ explicit ClientSocketHandle(ClientSocketPool* pool);
+ ~ClientSocketHandle();
- // Initializes a HttpConnection object, which involves talking to the
- // HttpConnectionManager to locate a socket to possibly reuse. This method
+ // Initializes a ClientSocketHandle object, which involves talking to the
+ // ClientSocketPool to locate a socket to possibly reuse. This method
// returns either OK or ERR_IO_PENDING.
//
// If this method succeeds, then the socket member will be set to an existing
// socket if an existing socket was available to reuse. Otherwise, the
- // consumer should set the socket member of this connection object.
+ // consumer should set the socket member of this handle.
//
// This method returns ERR_IO_PENDING if it cannot complete synchronously, in
// which case the consumer should wait for the completion callback to run.
@@ -70,11 +70,14 @@ class HttpConnection {
//
int Init(const std::string& group_name, CompletionCallback* callback);
- // An initialized connection can be reset, which causes it to return to the
+ // An initialized handle can be reset, which causes it to return to the
// un-initialized state. This releases the underlying socket, which in the
- // case of a socket that is not disconnected, indicates that the socket may
- // be kept alive for use by a subsequent HttpConnection. NOTE: To prevent
- // the socket from being kept alive, be sure to call its Disconnect method.
+ // case of a socket that still has an established connection, indicates that
+ // the socket may be kept alive for use by a subsequent ClientSocketHandle.
+ //
+ // NOTE: To prevent the socket from being kept alive, be sure to call its
+ // Disconnect method.
+ //
void Reset();
// Returns true when Init has completed successfully.
@@ -85,13 +88,15 @@ class HttpConnection {
void set_socket(ClientSocket* s) { socket_->reset(s); }
private:
- scoped_refptr<HttpConnectionManager> mgr_;
+ friend class ClientSocketPool;
+
+ scoped_refptr<ClientSocketPool> pool_;
scoped_ptr<ClientSocket>* socket_;
std::string group_name_;
- DISALLOW_EVIL_CONSTRUCTORS(HttpConnection);
+ DISALLOW_COPY_AND_ASSIGN(ClientSocketHandle);
};
} // namespace net
-#endif // NET_HTTP_HTTP_CONNECTION_H_
+#endif // NET_BASE_CLIENT_SOCKET_HANDLE_H_
diff --git a/net/http/http_connection_manager.cc b/net/base/client_socket_pool.cc
index 7064c4f..fb81dce 100644
--- a/net/http/http_connection_manager.cc
+++ b/net/base/client_socket_pool.cc
@@ -27,10 +27,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "net/http/http_connection_manager.h"
+#include "net/base/client_socket_pool.h"
#include "base/message_loop.h"
#include "net/base/client_socket.h"
+#include "net/base/client_socket_handle.h"
#include "net/base/net_errors.h"
namespace {
@@ -42,13 +43,14 @@ const int kCleanupInterval = 5;
namespace net {
-HttpConnectionManager::HttpConnectionManager()
+ClientSocketPool::ClientSocketPool(int max_sockets_per_group)
: timer_(TimeDelta::FromSeconds(kCleanupInterval)),
- idle_socket_count_(0) {
+ idle_socket_count_(0),
+ max_sockets_per_group_(max_sockets_per_group) {
timer_.set_task(this);
}
-HttpConnectionManager::~HttpConnectionManager() {
+ClientSocketPool::~ClientSocketPool() {
timer_.set_task(NULL);
// Clean up any idle sockets. Assert that we have no remaining active sockets
@@ -59,15 +61,14 @@ HttpConnectionManager::~HttpConnectionManager() {
DCHECK(group_map_.empty());
}
-int HttpConnectionManager::RequestSocket(const std::string& group_name,
- SocketHandle** handle,
- CompletionCallback* callback) {
- Group& group = group_map_[group_name];
+int ClientSocketPool::RequestSocket(ClientSocketHandle* handle,
+ CompletionCallback* callback) {
+ Group& group = group_map_[handle->group_name_];
// Can we make another active socket now?
- if (group.active_socket_count == kMaxSocketsPerGroup) {
+ if (group.active_socket_count == max_sockets_per_group_) {
Request r;
- r.result = handle;
+ r.handle = handle;
DCHECK(callback);
r.callback = callback;
group.pending_requests.push_back(r);
@@ -80,53 +81,53 @@ int HttpConnectionManager::RequestSocket(const std::string& group_name,
// Use idle sockets in LIFO order because they're more likely to be
// still connected.
while (!group.idle_sockets.empty()) {
- SocketHandle* h = group.idle_sockets.back();
+ ClientSocketPtr* ptr = group.idle_sockets.back();
group.idle_sockets.pop_back();
DecrementIdleCount();
- if (h->get()->IsConnected()) {
+ if ((*ptr)->IsConnected()) {
// We found one we can reuse!
- *handle = h;
+ handle->socket_ = ptr;
return OK;
}
- delete h;
+ delete ptr;
}
- *handle = new SocketHandle();
+ handle->socket_ = new ClientSocketPtr();
return OK;
}
-void HttpConnectionManager::CancelRequest(const std::string& group_name,
- SocketHandle** handle) {
- Group& group = group_map_[group_name];
+void ClientSocketPool::CancelRequest(ClientSocketHandle* handle) {
+ Group& group = group_map_[handle->group_name_];
// In order for us to be canceling a pending request, we must have active
// sockets equaling the limit. NOTE: The correctness of the code doesn't
// require this assertion.
- DCHECK(group.active_socket_count == kMaxSocketsPerGroup);
+ DCHECK(group.active_socket_count == max_sockets_per_group_);
// Search pending_requests for matching handle.
std::deque<Request>::iterator it = group.pending_requests.begin();
for (; it != group.pending_requests.end(); ++it) {
- if (it->result == handle) {
+ if (it->handle == handle) {
group.pending_requests.erase(it);
break;
}
}
}
-void HttpConnectionManager::ReleaseSocket(const std::string& group_name,
- SocketHandle* handle) {
+void ClientSocketPool::ReleaseSocket(ClientSocketHandle* handle) {
// 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, &HttpConnectionManager::DoReleaseSocket, group_name, handle));
+ this, &ClientSocketPool::DoReleaseSocket, handle->group_name_,
+ handle->socket_));
}
-void HttpConnectionManager::CloseIdleSockets() {
+void ClientSocketPool::CloseIdleSockets() {
MaybeCloseIdleSockets(false);
}
-void HttpConnectionManager::MaybeCloseIdleSockets(
+void ClientSocketPool::MaybeCloseIdleSockets(
bool only_if_disconnected) {
if (idle_socket_count_ == 0)
return;
@@ -135,7 +136,7 @@ void HttpConnectionManager::MaybeCloseIdleSockets(
while (i != group_map_.end()) {
Group& group = i->second;
- std::deque<SocketHandle*>::iterator j = group.idle_sockets.begin();
+ std::deque<ClientSocketPtr*>::iterator j = group.idle_sockets.begin();
while (j != group.idle_sockets.end()) {
if (!only_if_disconnected || !(*j)->get()->IsConnected()) {
delete *j;
@@ -156,18 +157,18 @@ void HttpConnectionManager::MaybeCloseIdleSockets(
}
}
-void HttpConnectionManager::IncrementIdleCount() {
+void ClientSocketPool::IncrementIdleCount() {
if (++idle_socket_count_ == 1)
timer_.Start();
}
-void HttpConnectionManager::DecrementIdleCount() {
+void ClientSocketPool::DecrementIdleCount() {
if (--idle_socket_count_ == 0)
timer_.Stop();
}
-void HttpConnectionManager::DoReleaseSocket(const std::string& group_name,
- SocketHandle* handle) {
+void ClientSocketPool::DoReleaseSocket(const std::string& group_name,
+ ClientSocketPtr* ptr) {
GroupMap::iterator i = group_map_.find(group_name);
DCHECK(i != group_map_.end());
@@ -176,19 +177,19 @@ void HttpConnectionManager::DoReleaseSocket(const std::string& group_name,
DCHECK(group.active_socket_count > 0);
group.active_socket_count--;
- bool can_reuse = handle->get() && handle->get()->IsConnected();
+ bool can_reuse = ptr->get() && (*ptr)->IsConnected();
if (can_reuse) {
- group.idle_sockets.push_back(handle);
+ group.idle_sockets.push_back(ptr);
IncrementIdleCount();
} else {
- delete handle;
+ delete ptr;
}
// Process one pending request.
if (!group.pending_requests.empty()) {
Request r = group.pending_requests.front();
group.pending_requests.pop_front();
- int rv = RequestSocket(i->first, r.result, NULL);
+ int rv = RequestSocket(r.handle, NULL);
DCHECK(rv == OK);
r.callback->Run(rv);
return;
@@ -201,7 +202,7 @@ void HttpConnectionManager::DoReleaseSocket(const std::string& group_name,
}
}
-void HttpConnectionManager::Run() {
+void ClientSocketPool::Run() {
MaybeCloseIdleSockets(true);
}
diff --git a/net/http/http_connection_manager.h b/net/base/client_socket_pool.h
index fc5402c..1f43166 100644
--- a/net/http/http_connection_manager.h
+++ b/net/base/client_socket_pool.h
@@ -27,8 +27,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#ifndef NET_HTTP_HTTP_CONNECTION_MANAGER_H_
-#define NET_HTTP_HTTP_CONNECTION_MANAGER_H_
+#ifndef NET_BASE_CLIENT_SOCKET_POOL_H_
+#define NET_BASE_CLIENT_SOCKET_POOL_H_
#include <deque>
#include <map>
@@ -41,54 +41,61 @@
namespace net {
class ClientSocket;
+class ClientSocketHandle;
-// A HttpConnectionManager is used to restrict the number of HTTP sockets
-// open at a time. It also maintains a list of idle persistent sockets.
+// A ClientSocketPool is used to restrict the number of sockets open at a time.
+// It also maintains a list of idle persistent sockets.
//
-// The HttpConnectionManager allocates SocketHandle objects, but it is not
-// responsible for allocating the associated ClientSocket objects. The
-// consumer must do so if it gets a SocketHandle with a null ClientSocket.
+// The ClientSocketPool allocates scoped_ptr<ClientSocket> objects, but it is
+// not responsible for allocating the associated ClientSocket objects. The
+// consumer must do so if it gets a scoped_ptr<ClientSocket> with a null value.
//
-class HttpConnectionManager : public base::RefCounted<HttpConnectionManager>,
- public Task {
+class ClientSocketPool : public base::RefCounted<ClientSocketPool>,
+ public Task {
public:
- HttpConnectionManager();
-
- // The maximum number of simultaneous sockets per group.
- enum { kMaxSocketsPerGroup = 6 };
-
- typedef scoped_ptr<ClientSocket> SocketHandle;
-
- // Called to get access to a SocketHandle object for the given group name.
+ explicit ClientSocketPool(int max_sockets_per_group);
+
+ // Called to request a socket for the given handle. There are three possible
+ // results: 1) the handle will be initialized with a socket to reuse, 2) the
+ // handle will be initialized without a socket such that the consumer needs
+ // to supply a socket, or 3) the handle will be added to a wait list until a
+ // socket is available to reuse or the opportunity to create a new socket
+ // arises. The completion callback is notified in the 3rd case.
//
- // If this function returns OK, then |*handle| will reference a SocketHandle
- // object. If ERR_IO_PENDING is returned, then the completion callback will
- // be called when |*handle| has been populated.
+ // If this function returns OK, then |handle| is initialized upon return.
+ // The |handle|'s is_initialized method will return true in this case. If a
+ // ClientSocket was reused, then |handle|'s socket member will be non-NULL.
+ // Otherwise, the consumer will need to supply |handle| with a socket by
+ // allocating a new ClientSocket object and calling the |handle|'s set_socket
+ // method.
//
- // If the resultant SocketHandle object has a null member, then it is the
- // caller's job to create a ClientSocket and associate it with the handle.
+ // If ERR_IO_PENDING is returned, then the completion callback will be called
+ // when |handle| has been initialized.
//
- int RequestSocket(const std::string& group_name, SocketHandle** handle,
- CompletionCallback* callback);
+ int RequestSocket(ClientSocketHandle* handle, CompletionCallback* callback);
// Called to cancel a RequestSocket call that returned ERR_IO_PENDING. The
- // same group_name and handle parameters must be passed to this method as
- // were passed to the RequestSocket call being cancelled. The associated
- // CompletionCallback is not run.
- void CancelRequest(const std::string& group_name, SocketHandle** handle);
-
- // Called to release a SocketHandle object that is no longer in use. If the
- // handle has a ClientSocket that is still connected, then this handle may be
- // added to the keep-alive set of sockets.
- void ReleaseSocket(const std::string& group_name, SocketHandle* handle);
+ // same handle parameter must be passed to this method as was passed to the
+ // RequestSocket call being cancelled. The associated CompletionCallback is
+ // not run.
+ void CancelRequest(ClientSocketHandle* handle);
+
+ // Called to release the socket member of an initialized ClientSocketHandle
+ // once the socket is no longer needed. If the socket member is non-null and
+ // still has an established connection, then it will be added to the idle set
+ // of sockets to be used to satisfy future RequestSocket calls. Otherwise,
+ // the ClientSocket is destroyed.
+ void ReleaseSocket(ClientSocketHandle* handle);
// Called to close any idle connections held by the connection manager.
void CloseIdleSockets();
private:
- friend class base::RefCounted<HttpConnectionManager>;
+ friend class base::RefCounted<ClientSocketPool>;
+
+ typedef scoped_ptr<ClientSocket> ClientSocketPtr;
- ~HttpConnectionManager();
+ ~ClientSocketPool();
// Closes all idle sockets if |only_if_disconnected| is false. Else, only
// idle sockets that are disconnected get closed. "Maybe" refers to the
@@ -101,7 +108,7 @@ class HttpConnectionManager : public base::RefCounted<HttpConnectionManager>,
void DecrementIdleCount();
// Called via PostTask by ReleaseSocket.
- void DoReleaseSocket(const std::string& group_name, SocketHandle* handle);
+ void DoReleaseSocket(const std::string& group_name, ClientSocketPtr* ptr);
// Task implementation. This method scans the idle sockets checking to see
// if any have been disconnected.
@@ -110,7 +117,7 @@ class HttpConnectionManager : public base::RefCounted<HttpConnectionManager>,
// A Request is allocated per call to RequestSocket that results in
// ERR_IO_PENDING.
struct Request {
- SocketHandle** result;
+ ClientSocketHandle* handle;
CompletionCallback* callback;
};
@@ -118,7 +125,7 @@ class HttpConnectionManager : public base::RefCounted<HttpConnectionManager>,
// requests. Otherwise, the Group object is removed from the map.
struct Group {
Group() : active_socket_count(0) {}
- std::deque<SocketHandle*> idle_sockets;
+ std::deque<ClientSocketPtr*> idle_sockets;
std::deque<Request> pending_requests;
int active_socket_count;
};
@@ -131,8 +138,11 @@ class HttpConnectionManager : public base::RefCounted<HttpConnectionManager>,
// The total number of idle sockets in the system.
int idle_socket_count_;
+
+ // The maximum number of sockets kept per group.
+ int max_sockets_per_group_;
};
} // namespace net
-#endif // NET_HTTP_HTTP_CONNECTION_MANAGER_H_
+#endif // NET_BASE_CLIENT_SOCKET_POOL_H_
diff --git a/net/http/http_connection_manager_unittest.cc b/net/base/client_socket_pool_unittest.cc
index 503097b..8a89e6d 100644
--- a/net/http/http_connection_manager_unittest.cc
+++ b/net/base/client_socket_pool_unittest.cc
@@ -29,13 +29,16 @@
#include "base/message_loop.h"
#include "net/base/client_socket.h"
+#include "net/base/client_socket_handle.h"
+#include "net/base/client_socket_pool.h"
#include "net/base/net_errors.h"
-#include "net/http/http_connection_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
-typedef testing::Test HttpConnectionManagerTest;
+typedef testing::Test ClientSocketPoolTest;
+
+const int kMaxSocketsPerGroup = 6;
class MockClientSocket : public net::ClientSocket {
public:
@@ -78,22 +81,22 @@ int MockClientSocket::allocation_count = 0;
class TestSocketRequest : public CallbackRunner< Tuple1<int> > {
public:
- TestSocketRequest() : handle(NULL) {}
+ TestSocketRequest(net::ClientSocketPool* pool) : handle(pool) {}
- net::HttpConnectionManager::SocketHandle* handle;
+ net::ClientSocketHandle handle;
- void InitHandle() {
- DCHECK(handle);
- if (!handle->get()) {
- handle->reset(new MockClientSocket());
- handle->get()->Connect(NULL);
+ void EnsureSocket() {
+ DCHECK(handle.is_initialized());
+ if (!handle.socket()) {
+ handle.set_socket(new MockClientSocket());
+ handle.socket()->Connect(NULL);
}
}
virtual void RunWithParams(const Tuple1<int>& params) {
DCHECK(params.a == net::OK);
completion_count++;
- InitHandle();
+ EnsureSocket();
}
static int completion_count;
@@ -101,56 +104,56 @@ class TestSocketRequest : public CallbackRunner< Tuple1<int> > {
int TestSocketRequest::completion_count = 0;
-// Call ReleaseSocket and wait for it to complete. It runs via PostTask, so we
-// can just empty the MessageLoop to ensure that ReleaseSocket finished.
-void CallReleaseSocket(net::HttpConnectionManager* connection_mgr,
- const std::string& group_name,
- net::HttpConnectionManager::SocketHandle* handle) {
- connection_mgr->ReleaseSocket(group_name, handle);
- MessageLoop::current()->Quit();
- MessageLoop::current()->Run();
-}
-
} // namespace
-TEST(HttpConnectionManagerTest, Basic) {
- scoped_refptr<net::HttpConnectionManager> mgr =
- new net::HttpConnectionManager();
+TEST(ClientSocketPoolTest, Basic) {
+ scoped_refptr<net::ClientSocketPool> pool =
+ new net::ClientSocketPool(kMaxSocketsPerGroup);
- TestSocketRequest r;
+ TestSocketRequest r(pool);
int rv;
- rv = mgr->RequestSocket("a", &r.handle, &r);
+ rv = r.handle.Init("a", &r);
EXPECT_EQ(net::OK, rv);
- EXPECT_TRUE(r.handle != NULL);
+ EXPECT_TRUE(r.handle.is_initialized());
- CallReleaseSocket(mgr, "a", r.handle);
+ r.handle.Reset();
+
+ // The handle's Reset method may have posted a task.
+ MessageLoop::current()->RunAllPending();
}
-TEST(HttpConnectionManagerTest, WithIdleConnection) {
- scoped_refptr<net::HttpConnectionManager> mgr =
- new net::HttpConnectionManager();
+TEST(ClientSocketPoolTest, WithIdleConnection) {
+ scoped_refptr<net::ClientSocketPool> pool =
+ new net::ClientSocketPool(kMaxSocketsPerGroup);
- TestSocketRequest r;
+ TestSocketRequest r(pool);
int rv;
- rv = mgr->RequestSocket("a", &r.handle, &r);
+ rv = r.handle.Init("a", &r);
EXPECT_EQ(net::OK, rv);
- EXPECT_TRUE(r.handle != NULL);
+ EXPECT_TRUE(r.handle.is_initialized());
+
+ // Create a socket.
+ r.EnsureSocket();
- r.InitHandle();
+ // Release the socket. It should find its way into the idle list. We're
+ // testing that this does not trigger a crash.
+ r.handle.Reset();
- CallReleaseSocket(mgr, "a", r.handle);
+ // The handle's Reset method may have posted a task.
+ MessageLoop::current()->RunAllPending();
}
-TEST(HttpConnectionManagerTest, PendingRequests) {
- scoped_refptr<net::HttpConnectionManager> mgr =
- new net::HttpConnectionManager();
+TEST(ClientSocketPoolTest, PendingRequests) {
+ scoped_refptr<net::ClientSocketPool> pool =
+ new net::ClientSocketPool(kMaxSocketsPerGroup);
int rv;
- TestSocketRequest reqs[
- net::HttpConnectionManager::kMaxSocketsPerGroup + 10];
+ scoped_ptr<TestSocketRequest> reqs[kMaxSocketsPerGroup + 10];
+ for (size_t i = 0; i < arraysize(reqs); ++i)
+ reqs[i].reset(new TestSocketRequest(pool));
// Reset
MockClientSocket::allocation_count = 0;
@@ -158,10 +161,10 @@ TEST(HttpConnectionManagerTest, PendingRequests) {
// Create connections or queue up requests.
for (size_t i = 0; i < arraysize(reqs); ++i) {
- rv = mgr->RequestSocket("a", &reqs[i].handle, &reqs[i]);
+ rv = reqs[i]->handle.Init("a", reqs[i].get());
if (rv != net::ERR_IO_PENDING) {
EXPECT_EQ(net::OK, rv);
- reqs[i].InitHandle();
+ reqs[i]->EnsureSocket();
}
}
@@ -170,27 +173,27 @@ TEST(HttpConnectionManagerTest, PendingRequests) {
do {
released_one = false;
for (size_t i = 0; i < arraysize(reqs); ++i) {
- if (reqs[i].handle) {
- CallReleaseSocket(mgr, "a", reqs[i].handle);
- reqs[i].handle = NULL;
+ if (reqs[i]->handle.is_initialized()) {
+ reqs[i]->handle.Reset();
+ MessageLoop::current()->RunAllPending();
released_one = true;
}
}
} while (released_one);
- EXPECT_EQ(net::HttpConnectionManager::kMaxSocketsPerGroup,
- MockClientSocket::allocation_count);
+ EXPECT_EQ(kMaxSocketsPerGroup, MockClientSocket::allocation_count);
EXPECT_EQ(10, TestSocketRequest::completion_count);
}
-TEST(HttpConnectionManagerTest, PendingRequests_NoKeepAlive) {
- scoped_refptr<net::HttpConnectionManager> mgr =
- new net::HttpConnectionManager();
+TEST(ClientSocketPoolTest, PendingRequests_NoKeepAlive) {
+ scoped_refptr<net::ClientSocketPool> pool =
+ new net::ClientSocketPool(kMaxSocketsPerGroup);
int rv;
- TestSocketRequest reqs[
- net::HttpConnectionManager::kMaxSocketsPerGroup + 10];
+ scoped_ptr<TestSocketRequest> reqs[kMaxSocketsPerGroup + 10];
+ for (size_t i = 0; i < arraysize(reqs); ++i)
+ reqs[i].reset(new TestSocketRequest(pool));
// Reset
MockClientSocket::allocation_count = 0;
@@ -198,10 +201,10 @@ TEST(HttpConnectionManagerTest, PendingRequests_NoKeepAlive) {
// Create connections or queue up requests.
for (size_t i = 0; i < arraysize(reqs); ++i) {
- rv = mgr->RequestSocket("a", &reqs[i].handle, &reqs[i]);
+ rv = reqs[i]->handle.Init("a", reqs[i].get());
if (rv != net::ERR_IO_PENDING) {
EXPECT_EQ(net::OK, rv);
- reqs[i].InitHandle();
+ reqs[i]->EnsureSocket();
}
}
@@ -210,28 +213,28 @@ TEST(HttpConnectionManagerTest, PendingRequests_NoKeepAlive) {
do {
released_one = false;
for (size_t i = 0; i < arraysize(reqs); ++i) {
- if (reqs[i].handle) {
- reqs[i].handle->get()->Disconnect();
- CallReleaseSocket(mgr, "a", reqs[i].handle);
- reqs[i].handle = NULL;
+ if (reqs[i]->handle.is_initialized()) {
+ reqs[i]->handle.socket()->Disconnect();
+ reqs[i]->handle.Reset();
+ MessageLoop::current()->RunAllPending();
released_one = true;
}
}
} while (released_one);
- EXPECT_EQ(net::HttpConnectionManager::kMaxSocketsPerGroup + 10,
- MockClientSocket::allocation_count);
+ EXPECT_EQ(kMaxSocketsPerGroup + 10, MockClientSocket::allocation_count);
EXPECT_EQ(10, TestSocketRequest::completion_count);
}
-TEST(HttpConnectionManagerTest, CancelRequest) {
- scoped_refptr<net::HttpConnectionManager> mgr =
- new net::HttpConnectionManager();
+TEST(ClientSocketPoolTest, CancelRequest) {
+ scoped_refptr<net::ClientSocketPool> pool =
+ new net::ClientSocketPool(kMaxSocketsPerGroup);
int rv;
- TestSocketRequest reqs[
- net::HttpConnectionManager::kMaxSocketsPerGroup + 10];
+ scoped_ptr<TestSocketRequest> reqs[kMaxSocketsPerGroup + 10];
+ for (size_t i = 0; i < arraysize(reqs); ++i)
+ reqs[i].reset(new TestSocketRequest(pool));
// Reset
MockClientSocket::allocation_count = 0;
@@ -239,33 +242,31 @@ TEST(HttpConnectionManagerTest, CancelRequest) {
// Create connections or queue up requests.
for (size_t i = 0; i < arraysize(reqs); ++i) {
- rv = mgr->RequestSocket("a", &reqs[i].handle, &reqs[i]);
+ rv = reqs[i]->handle.Init("a", reqs[i].get());
if (rv != net::ERR_IO_PENDING) {
EXPECT_EQ(net::OK, rv);
- reqs[i].InitHandle();
+ reqs[i]->EnsureSocket();
}
}
// Cancel a request.
- size_t index_to_cancel =
- net::HttpConnectionManager::kMaxSocketsPerGroup + 2;
- EXPECT_TRUE(reqs[index_to_cancel].handle == NULL);
- mgr->CancelRequest("a", &reqs[index_to_cancel].handle);
+ size_t index_to_cancel = kMaxSocketsPerGroup + 2;
+ EXPECT_TRUE(!reqs[index_to_cancel]->handle.is_initialized());
+ reqs[index_to_cancel]->handle.Reset();
// Release any connections until we have no connections.
bool released_one;
do {
released_one = false;
for (size_t i = 0; i < arraysize(reqs); ++i) {
- if (reqs[i].handle) {
- CallReleaseSocket(mgr, "a", reqs[i].handle);
- reqs[i].handle = NULL;
+ if (reqs[i]->handle.is_initialized()) {
+ reqs[i]->handle.Reset();
+ MessageLoop::current()->RunAllPending();
released_one = true;
}
}
} while (released_one);
- EXPECT_EQ(net::HttpConnectionManager::kMaxSocketsPerGroup,
- MockClientSocket::allocation_count);
+ EXPECT_EQ(kMaxSocketsPerGroup, MockClientSocket::allocation_count);
EXPECT_EQ(9, TestSocketRequest::completion_count);
}
diff --git a/net/build/net.vcproj b/net/build/net.vcproj
index 8329527..3da1c7b 100644
--- a/net/build/net.vcproj
+++ b/net/build/net.vcproj
@@ -189,6 +189,22 @@
>
</File>
<File
+ RelativePath="..\base\client_socket_handle.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\base\client_socket_handle.h"
+ >
+ </File>
+ <File
+ RelativePath="..\base\client_socket_pool.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\base\client_socket_pool.h"
+ >
+ </File>
+ <File
RelativePath="..\base\completion_callback.h"
>
</File>
@@ -637,22 +653,6 @@
>
</File>
<File
- RelativePath="..\http\http_connection.cc"
- >
- </File>
- <File
- RelativePath="..\http\http_connection.h"
- >
- </File>
- <File
- RelativePath="..\http\http_connection_manager.cc"
- >
- </File>
- <File
- RelativePath="..\http\http_connection_manager.h"
- >
- </File>
- <File
RelativePath="..\http\http_network_layer.cc"
>
</File>
diff --git a/net/build/net_unittests.vcproj b/net/build/net_unittests.vcproj
index d31226e..3426bf0 100644
--- a/net/build/net_unittests.vcproj
+++ b/net/build/net_unittests.vcproj
@@ -235,10 +235,6 @@
>
</File>
<File
- RelativePath="..\http\http_connection_manager_unittest.cc"
- >
- </File>
- <File
RelativePath="..\http\http_network_layer_unittest.cc"
>
</File>
@@ -295,6 +291,10 @@
>
</File>
<File
+ RelativePath="..\base\client_socket_pool_unittest.cc"
+ >
+ </File>
+ <File
RelativePath="..\base\cookie_monster_unittest.cc"
>
</File>
diff --git a/net/http/http_network_layer.cc b/net/http/http_network_layer.cc
index 2fd846c..426b987 100644
--- a/net/http/http_network_layer.cc
+++ b/net/http/http_network_layer.cc
@@ -93,7 +93,7 @@ void HttpNetworkLayer::Suspend(bool suspend) {
suspended_ = suspend;
if (suspend)
- session_->connection_manager()->CloseIdleSockets();
+ session_->connection_pool()->CloseIdleSockets();
}
} // namespace net
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h
index dc31ed1..58cbb2f 100644
--- a/net/http/http_network_session.h
+++ b/net/http/http_network_session.h
@@ -32,7 +32,7 @@
#include "base/ref_counted.h"
#include "net/base/auth_cache.h"
-#include "net/http/http_connection_manager.h"
+#include "net/base/client_socket_pool.h"
#include "net/http/http_proxy_service.h"
namespace net {
@@ -40,19 +40,24 @@ namespace net {
// This class holds session objects used by HttpNetworkTransaction objects.
class HttpNetworkSession : public base::RefCounted<HttpNetworkSession> {
public:
+ // Allow up to 6 connections per host.
+ enum {
+ MAX_SOCKETS_PER_GROUP = 6
+ };
+
HttpNetworkSession(HttpProxyResolver* proxy_resolver)
- : connection_manager_(new HttpConnectionManager()),
+ : connection_pool_(new ClientSocketPool(MAX_SOCKETS_PER_GROUP)),
proxy_resolver_(proxy_resolver),
proxy_service_(proxy_resolver) {
}
AuthCache* auth_cache() { return &auth_cache_; }
- HttpConnectionManager* connection_manager() { return connection_manager_; }
+ ClientSocketPool* connection_pool() { return connection_pool_; }
HttpProxyService* proxy_service() { return &proxy_service_; }
private:
AuthCache auth_cache_;
- scoped_refptr<HttpConnectionManager> connection_manager_;
+ scoped_refptr<ClientSocketPool> connection_pool_;
scoped_ptr<HttpProxyResolver> proxy_resolver_;
HttpProxyService proxy_service_;
};
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 807c87d..1d45191 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -60,7 +60,7 @@ HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session,
request_(NULL),
pac_request_(NULL),
socket_factory_(csf),
- connection_(session->connection_manager()),
+ connection_(session->connection_pool()),
reused_socket_(false),
using_ssl_(false),
using_proxy_(false),