summaryrefslogtreecommitdiffstats
path: root/net/socket
diff options
context:
space:
mode:
authorwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-02 02:03:12 +0000
committerwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-02 02:03:12 +0000
commit3c819f52648d751ebe29ee2add8f79f6b41fc4d7 (patch)
tree335275c6d1543eaddc8f9100143036464dd604fd /net/socket
parent98228e2cb88a610a95174473cebe937beadcb82a (diff)
downloadchromium_src-3c819f52648d751ebe29ee2add8f79f6b41fc4d7.zip
chromium_src-3c819f52648d751ebe29ee2add8f79f6b41fc4d7.tar.gz
chromium_src-3c819f52648d751ebe29ee2add8f79f6b41fc4d7.tar.bz2
Fix ClientSocketPoolBaseHelper preconnect crasher.
It's caused by an invalid read that sometimes leads to an invalid write that causes a CHECK failure. BUG=64985 TEST=New unit test added, fails under valgrind without the fix. Review URL: http://codereview.chromium.org/5523001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67942 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/socket')
-rw-r--r--net/socket/client_socket_pool_base.cc14
-rw-r--r--net/socket/client_socket_pool_base_unittest.cc10
2 files changed, 23 insertions, 1 deletions
diff --git a/net/socket/client_socket_pool_base.cc b/net/socket/client_socket_pool_base.cc
index 02ac587..4f042bb 100644
--- a/net/socket/client_socket_pool_base.cc
+++ b/net/socket/client_socket_pool_base.cc
@@ -243,17 +243,29 @@ void ClientSocketPoolBaseHelper::RequestSockets(
Group* group = GetOrCreateGroup(group_name);
+ // RequestSocketsInternal() may delete the group.
+ bool deleted_group = false;
+
for (int num_iterations_left = num_sockets;
group->NumActiveSocketSlots() < num_sockets &&
num_iterations_left > 0 ; num_iterations_left--) {
int rv = RequestSocketInternal(group_name, &request);
if (rv < 0 && rv != ERR_IO_PENDING) {
// We're encountering a synchronous error. Give up.
+ if (!ContainsKey(group_map_, group_name))
+ deleted_group = true;
+ break;
+ }
+ if (!ContainsKey(group_map_, group_name)) {
+ // Unexpected. The group should only be getting deleted on synchronous
+ // error.
+ NOTREACHED();
+ deleted_group = true;
break;
}
}
- if (group->IsEmpty())
+ if (!deleted_group && group->IsEmpty())
RemoveGroup(group_name);
request.net_log().EndEvent(
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc
index fd9e337..fef0a5e 100644
--- a/net/socket/client_socket_pool_base_unittest.cc
+++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -2916,6 +2916,16 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) {
EXPECT_EQ(kDefaultMaxSocketsPerGroup, pool_->IdleSocketCountInGroup("b"));
}
+TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) {
+ CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
+ connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
+
+ pool_->RequestSockets("a", &params_, kDefaultMaxSocketsPerGroup,
+ BoundNetLog());
+
+ ASSERT_FALSE(pool_->HasGroup("a"));
+}
+
TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) {
CreatePool(4, 4);
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);