Commit fe9beab7 authored by ricea@chromium.org's avatar ricea@chromium.org

Fix WebSocket race between close and connect.

If the WebSocket handshake was cancelled immediately after the connect
succeeded before the ClientSocketHandle was fully initialised, then the
socket would not be released back to the pool, and as a result the
endpoint would not be unlocked.

Fix by actively reclaiming the socket in
WebSocketTransportClientSocketPool::CancelRequest().

Also add a test for this condition.

BUG=394268, 389084
TEST=net_unittests

Review URL: https://codereview.chromium.org/394113003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@285175 0039d316-1c4b-4281-b951-d872f2087c98
parent d77baf89
......@@ -360,8 +360,12 @@ void WebSocketTransportClientSocketPool::RequestSockets(
void WebSocketTransportClientSocketPool::CancelRequest(
const std::string& group_name,
ClientSocketHandle* handle) {
DCHECK(!handle->is_initialized());
if (DeleteStalledRequest(handle))
return;
scoped_ptr<StreamSocket> socket = handle->PassSocket();
if (socket)
ReleaseSocket(handle->group_name(), socket.Pass(), handle->id());
if (!DeleteJob(handle))
pending_callbacks_.erase(handle);
if (!ReachedMaxSocketsLimit() && !stalled_request_queue_.empty())
......
......@@ -1085,6 +1085,31 @@ TEST_F(WebSocketTransportClientSocketPoolTest,
request(0)->handle()->Reset();
}
// Sockets should not be leaked if CancelRequest() is called in between
// SetSocket() being called on the ClientSocketHandle and InvokeUserCallback().
TEST_F(WebSocketTransportClientSocketPoolTest, CancelRequestReclaimsSockets) {
host_resolver_->set_synchronous_mode(true);
MockTransportClientSocketFactory::ClientSocketType socket_types[] = {
MockTransportClientSocketFactory::MOCK_TRIGGERABLE_CLIENT_SOCKET,
MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET};
client_socket_factory_.set_client_socket_types(socket_types,
arraysize(socket_types));
EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
base::Closure connect_trigger =
client_socket_factory_.WaitForTriggerableSocketCreation();
connect_trigger.Run(); // Calls InvokeUserCallbackLater()
request(0)->handle()->Reset(); // calls CancelRequest()
// We should now be able to create a new connection without blocking on the
// endpoint lock.
EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
}
} // namespace
} // namespace net
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment