| Index: net/socket/ssl_client_socket_pool.cc
|
| diff --git a/net/socket/ssl_client_socket_pool.cc b/net/socket/ssl_client_socket_pool.cc
|
| index 27fb87f85549feb374ba066d3361114ca29808dd..2566f3e0ffb3a79a10e5d537759f27ae0304ce04 100644
|
| --- a/net/socket/ssl_client_socket_pool.cc
|
| +++ b/net/socket/ssl_client_socket_pool.cc
|
| @@ -9,6 +9,7 @@
|
| #include "base/metrics/field_trial.h"
|
| #include "base/metrics/histogram.h"
|
| #include "base/metrics/sparse_histogram.h"
|
| +#include "base/thread_task_runner_handle.h"
|
| #include "base/values.h"
|
| #include "net/base/host_port_pair.h"
|
| #include "net/base/net_errors.h"
|
| @@ -94,6 +95,9 @@ SSLSocketParams::GetHttpProxyConnectionParams() const {
|
| return http_proxy_params_;
|
| }
|
|
|
| +SSLConnectJobMessenger::SSLConnectJobMessenger() : weak_factory_(this) {
|
| +}
|
| +
|
| bool SSLConnectJobMessenger::CanProceed(SSLClientSocket* ssl_socket) {
|
| // If the session is in the session cache, or there are no connecting
|
| // sockets allow the connection to proceed.
|
| @@ -105,11 +109,15 @@ bool SSLConnectJobMessenger::CanProceed(SSLClientSocket* ssl_socket) {
|
|
|
| void SSLConnectJobMessenger::MonitorConnectionResult(
|
| SSLClientSocket* ssl_socket) {
|
| + connecting_sockets_.push_back(ssl_socket);
|
| ssl_socket->SetIsLeader();
|
| - ssl_socket->SetSocketFailureCallback(
|
| - base::Bind(&SSLConnectJobMessenger::OnJobFailed, base::Unretained(this)));
|
| + // SSLConnectJobMessenger weak_ptrs are used here to ensure that
|
| + // tasks posted with these callbacks are deregistered if the
|
| + // SSLConnectJobMessenger should become invalid before they're run.
|
| + ssl_socket->SetSocketFailureCallback(base::Bind(
|
| + &SSLConnectJobMessenger::OnJobFailed, weak_factory_.GetWeakPtr()));
|
| ssl_socket->WatchSessionForCompletion(base::Bind(
|
| - &SSLConnectJobMessenger::OnJobSucceeded, base::Unretained(this)));
|
| + &SSLConnectJobMessenger::OnJobSucceeded, weak_factory_.GetWeakPtr()));
|
| }
|
|
|
| void SSLConnectJobMessenger::AddPendingSocket(SSLClientSocket* socket,
|
| @@ -125,23 +133,51 @@ void SSLConnectJobMessenger::OnJobSucceeded() {
|
| }
|
|
|
| void SSLConnectJobMessenger::OnJobFailed() {
|
| - if (pending_sockets_and_callbacks_.empty())
|
| - return;
|
| - base::Closure callback = pending_sockets_and_callbacks_[0].callback;
|
| + base::Closure callback = base::Bind(&SSLConnectJobMessenger::ConnectNewLeader,
|
| + weak_factory_.GetWeakPtr());
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
|
| +}
|
| +
|
| +void SSLConnectJobMessenger::ConnectNewLeader() {
|
| connecting_sockets_.erase(connecting_sockets_.begin());
|
| - SSLClientSocket* ssl_socket = pending_sockets_and_callbacks_[0].socket;
|
| - pending_sockets_and_callbacks_.erase(pending_sockets_and_callbacks_.begin());
|
| + std::vector<SocketAndCallback>::iterator it;
|
| + SSLClientSocket* ssl_socket;
|
| + base::Closure callback;
|
| +
|
| + // Connect the first pending socket that has not been deleted.
|
| + for (it = pending_sockets_and_callbacks_.begin();
|
| + it != pending_sockets_and_callbacks_.end();
|
| + ++it) {
|
| + if (it->socket != NULL) {
|
| + ssl_socket = it->socket;
|
| + callback = it->callback;
|
| + break;
|
| + }
|
| + }
|
| +
|
| + // If there were no valid pending sockets, return.
|
| + if (it == pending_sockets_and_callbacks_.end())
|
| + return;
|
| +
|
| + // Erase all deleted sockets and their callbacks, as well as the socket that
|
| + // will
|
| + // be connected next.
|
| + pending_sockets_and_callbacks_.erase(pending_sockets_and_callbacks_.begin(),
|
| + ++it);
|
| +
|
| MonitorConnectionResult(ssl_socket);
|
| callback.Run();
|
| }
|
|
|
| void SSLConnectJobMessenger::RunAllJobs(
|
| std::vector<SocketAndCallback>& pending_sockets_and_callbacks) {
|
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner =
|
| + base::ThreadTaskRunnerHandle::Get();
|
| for (std::vector<SocketAndCallback>::const_iterator it =
|
| pending_sockets_and_callbacks.begin();
|
| it != pending_sockets_and_callbacks.end();
|
| ++it)
|
| - it->callback.Run();
|
| + task_runner->PostTask(FROM_HERE, it->callback);
|
| }
|
|
|
| // Timeout for the SSL handshake portion of the connect.
|
|
|