summaryrefslogtreecommitdiffstats
path: root/chrome_frame
diff options
context:
space:
mode:
authorgrt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-28 00:41:28 +0000
committergrt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-28 00:41:28 +0000
commitb1e3ce73f05aa2a8a7e17e742c29a835caa8d0c9 (patch)
treee18f671dc97bad4337972925092e96a3d365d9bf /chrome_frame
parent5f51a24ba88116e24ced760570772fca2a82e2e8 (diff)
downloadchromium_src-b1e3ce73f05aa2a8a7e17e742c29a835caa8d0c9.zip
chromium_src-b1e3ce73f05aa2a8a7e17e742c29a835caa8d0c9.tar.gz
chromium_src-b1e3ce73f05aa2a8a7e17e742c29a835caa8d0c9.tar.bz2
Fix test crashes caused by toxic use of ListenSocket.
ListenSocket doesn't like it if delegates delete instances from within DidFoo() callbacks. Instead of releasing references to sockets from within ConfigurableConnection::SendWithOptions (which is invoked indirectly by way of HTTPTestServer::DidRead), post a task to do so. Handle the fact that there may be connections in an HTTPTestServer instance for which the underlying socket_ is NULL by harvesting them in HTTPTestServer::FindConnection(). As a result of all of this, it's possible that DidRead or DidClose may be called with a ListenSocket* that is no longer present in the server's connection list. This isn't an error condition, so simply handle it gracefully in Did{Read,Close}. BUG=120458 TEST=nothing special. chrome_frame_tests.exe should stop crashing so much. Review URL: http://codereview.chromium.org/9863048 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@129319 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame')
-rw-r--r--chrome_frame/test/test_server.cc28
-rw-r--r--chrome_frame/test/test_server.h5
2 files changed, 26 insertions, 7 deletions
diff --git a/chrome_frame/test/test_server.cc b/chrome_frame/test/test_server.cc
index f7a3abd..a4875fb 100644
--- a/chrome_frame/test/test_server.cc
+++ b/chrome_frame/test/test_server.cc
@@ -246,10 +246,18 @@ HTTPTestServer::~HTTPTestServer() {
std::list<scoped_refptr<ConfigurableConnection>>::iterator
HTTPTestServer::FindConnection(const net::ListenSocket* socket) {
ConnectionList::iterator it;
- for (it = connection_list_.begin(); it != connection_list_.end(); ++it) {
- if ((*it)->socket_ == socket) {
- break;
+ // Scan through the list searching for the desired socket. Along the way,
+ // erase any connections for which the corresponding socket has already been
+ // forgotten about as a result of all data having been sent.
+ for (it = connection_list_.begin(); it != connection_list_.end(); ) {
+ ConfigurableConnection* connection = it->get();
+ if (connection->socket_ == NULL) {
+ connection_list_.erase(it++);
+ continue;
}
+ if (connection->socket_ == socket)
+ break;
+ ++it;
}
return it;
@@ -290,8 +298,8 @@ void HTTPTestServer::DidRead(net::ListenSocket* socket,
void HTTPTestServer::DidClose(net::ListenSocket* socket) {
ConnectionList::iterator it = FindConnection(socket);
- DCHECK(it != connection_list_.end());
- connection_list_.erase(it);
+ if (it != connection_list_.end())
+ connection_list_.erase(it);
}
std::wstring HTTPTestServer::Resolve(const std::wstring& path) {
@@ -336,6 +344,10 @@ void ConfigurableConnection::SendChunk() {
}
}
+void ConfigurableConnection::Close() {
+ socket_ = NULL;
+}
+
void ConfigurableConnection::Send(const std::string& headers,
const std::string& content) {
SendOptions options(SendOptions::IMMEDIATE, 0, 0);
@@ -359,7 +371,11 @@ void ConfigurableConnection::SendWithOptions(const std::string& headers,
socket_->Send(headers);
socket_->Send(content_length_header, true);
socket_->Send(content);
- socket_ = 0; // close the connection.
+ // Post a task to close the socket since ListenSocket doesn't like instances
+ // to go away from within its callbacks.
+ MessageLoop::current()->PostTask(
+ FROM_HERE, base::Bind(&ConfigurableConnection::Close, this));
+
return;
}
diff --git a/chrome_frame/test/test_server.h b/chrome_frame/test/test_server.h
index 1b60645..aa706d8 100644
--- a/chrome_frame/test/test_server.h
+++ b/chrome_frame/test/test_server.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -360,6 +360,9 @@ class ConfigurableConnection : public base::RefCounted<ConfigurableConnection> {
// next chunk of |data_|.
void SendChunk();
+ // Closes the connection by releasing this instance's reference on its socket.
+ void Close();
+
scoped_refptr<net::ListenSocket> socket_;
Request r_;
SendOptions options_;