summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-08 04:29:59 +0000
committerakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-08 04:29:59 +0000
commit04644d4599c4e3a5696cbf3feed3aaaae7ea99e9 (patch)
tree97171a1d44648a8ef2447fd360af233e6acbb1b9
parent27ec8b6653c97bf5ba26549b484cbaf878d40ccf (diff)
downloadchromium_src-04644d4599c4e3a5696cbf3feed3aaaae7ea99e9.zip
chromium_src-04644d4599c4e3a5696cbf3feed3aaaae7ea99e9.tar.gz
chromium_src-04644d4599c4e3a5696cbf3feed3aaaae7ea99e9.tar.bz2
[SPDY] Make SpdySessionPool keep track of available sessions
Split a SpdySessionPool's sessions into available ones and unavailable ones. Keep all sessions in a set, and all the available sessions in a map keyed by SpdySessionKey. This is in preparation for making SpdySessionPool own a session even if it receives a GOAWAY frame. Split SpdySessionPool::Remove() into two functions -- MakeSessionUnavailable() and RemoveUnavailableSession(). For now, sessions call them at the same time, but in the future RemoveUnavailableSession() may be called later than MakeSessionUnavailable() (for the GOAWAY case). Don't add a SpdySession to a pool if it encountered an error during initialization. Also, don't do some work in SpdySession::InitializeWithSocket() if initialization fails. Rename functions and variables in SpdySessionPool to be concise and consistent. Inline a bunch of one-off functions. Rewrite the loop in SpdySessionPool::RemoveAliases(). BUG=255701 Review URL: https://chromiumcodereview.appspot.com/18600010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@210344 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--net/http/http_proxy_client_socket_pool.cc6
-rw-r--r--net/http/http_stream_factory_impl_job.cc23
-rw-r--r--net/spdy/spdy_network_transaction_unittest.cc2
-rw-r--r--net/spdy/spdy_session.cc42
-rw-r--r--net/spdy/spdy_session.h14
-rw-r--r--net/spdy/spdy_session_pool.cc402
-rw-r--r--net/spdy/spdy_session_pool.h145
-rw-r--r--net/spdy/spdy_session_pool_unittest.cc12
-rw-r--r--net/spdy/spdy_session_unittest.cc33
-rw-r--r--net/spdy/spdy_test_util_common.cc6
-rw-r--r--net/websockets/websocket_job.cc2
11 files changed, 369 insertions, 318 deletions
diff --git a/net/http/http_proxy_client_socket_pool.cc b/net/http/http_proxy_client_socket_pool.cc
index 7b493ac..3e93008 100644
--- a/net/http/http_proxy_client_socket_pool.cc
+++ b/net/http/http_proxy_client_socket_pool.cc
@@ -204,7 +204,7 @@ int HttpProxyConnectJob::DoSSLConnect() {
SpdySessionKey key(params_->destination().host_port_pair(),
ProxyServer::Direct(),
kPrivacyModeDisabled);
- if (params_->spdy_session_pool()->GetIfExists(key, net_log())) {
+ if (params_->spdy_session_pool()->FindAvailableSession(key, net_log())) {
using_spdy_ = true;
next_state_ = STATE_SPDY_PROXY_CREATE_STREAM;
return OK;
@@ -303,7 +303,7 @@ int HttpProxyConnectJob::DoSpdyProxyCreateStream() {
kPrivacyModeDisabled);
SpdySessionPool* spdy_pool = params_->spdy_session_pool();
scoped_refptr<SpdySession> spdy_session =
- spdy_pool->GetIfExists(key, net_log());
+ spdy_pool->FindAvailableSession(key, net_log());
// It's possible that a session to the proxy has recently been created
if (spdy_session) {
if (transport_socket_handle_.get()) {
@@ -313,7 +313,7 @@ int HttpProxyConnectJob::DoSpdyProxyCreateStream() {
}
} else {
// Create a session direct to the proxy itself
- int rv = spdy_pool->GetSpdySessionFromSocket(
+ int rv = spdy_pool->CreateAvailableSessionFromSocket(
key, transport_socket_handle_.Pass(),
net_log(), OK, &spdy_session, /*using_ssl_*/ true);
if (rv < 0)
diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc
index f03ca2d..b6226ae 100644
--- a/net/http/http_stream_factory_impl_job.cc
+++ b/net/http/http_stream_factory_impl_job.cc
@@ -422,9 +422,9 @@ int HttpStreamFactoryImpl::Job::OnHostResolution(
// It is OK to dereference spdy_session_pool, because the
// ClientSocketPoolManager will be destroyed in the same callback that
// destroys the SpdySessionPool.
- bool has_session =
- spdy_session_pool->GetIfExists(spdy_session_key, net_log).get() != NULL;
- return has_session ? ERR_SPDY_SESSION_ALREADY_EXISTS : OK;
+ return
+ spdy_session_pool->FindAvailableSession(spdy_session_key, net_log) ?
+ ERR_SPDY_SESSION_ALREADY_EXISTS : OK;
}
void HttpStreamFactoryImpl::Job::OnIOComplete(int result) {
@@ -762,8 +762,9 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() {
// straight to using that.
SpdySessionKey spdy_session_key = GetSpdySessionKey();
scoped_refptr<SpdySession> spdy_session =
- session_->spdy_session_pool()->GetIfExists(spdy_session_key, net_log_);
- if (spdy_session.get() && CanUseExistingSpdySession()) {
+ session_->spdy_session_pool()->FindAvailableSession(
+ spdy_session_key, net_log_);
+ if (spdy_session && CanUseExistingSpdySession()) {
// If we're preconnecting, but we already have a SpdySession, we don't
// actually need to preconnect any sockets, so we're done.
if (IsPreconnecting())
@@ -876,8 +877,9 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) {
// probably an IP pooled connection.
SpdySessionKey spdy_session_key = GetSpdySessionKey();
existing_spdy_session_ =
- session_->spdy_session_pool()->GetIfExists(spdy_session_key, net_log_);
- if (existing_spdy_session_.get()) {
+ session_->spdy_session_pool()->FindAvailableSession(
+ spdy_session_key, net_log_);
+ if (existing_spdy_session_) {
using_spdy_ = true;
next_state_ = STATE_CREATE_STREAM;
} else {
@@ -1096,9 +1098,10 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() {
spdy_session.swap(existing_spdy_session_);
} else {
SpdySessionPool* spdy_pool = session_->spdy_session_pool();
- spdy_session = spdy_pool->GetIfExists(spdy_session_key, net_log_);
- if (!spdy_session.get()) {
- int error = spdy_pool->GetSpdySessionFromSocket(spdy_session_key,
+ spdy_session = spdy_pool->FindAvailableSession(spdy_session_key, net_log_);
+ if (!spdy_session) {
+ int error =
+ spdy_pool->CreateAvailableSessionFromSocket(spdy_session_key,
connection_.Pass(),
net_log_,
spdy_certificate_error_,
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc
index b533f29..e0e9cfc 100644
--- a/net/spdy/spdy_network_transaction_unittest.cc
+++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -563,7 +563,7 @@ class SpdyNetworkTransactionTest
BoundNetLog log;
const scoped_refptr<HttpNetworkSession>& session = helper.session();
scoped_refptr<SpdySession> spdy_session =
- session->spdy_session_pool()->GetIfExists(key, log);
+ session->spdy_session_pool()->FindAvailableSession(key, log);
ASSERT_TRUE(spdy_session != NULL);
EXPECT_EQ(0u, spdy_session->num_active_streams());
EXPECT_EQ(0u, spdy_session->num_unclaimed_pushed_streams());
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index 2ff50a028..ae995e6 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -333,7 +333,6 @@ SpdySession::PushedStreamInfo::PushedStreamInfo(
SpdySession::PushedStreamInfo::~PushedStreamInfo() {}
SpdySession::SpdySession(const SpdySessionKey& spdy_session_key,
- SpdySessionPool* spdy_session_pool,
HttpServerProperties* http_server_properties,
bool verify_domain_authentication,
bool enable_sending_initial_settings,
@@ -349,9 +348,8 @@ SpdySession::SpdySession(const SpdySessionKey& spdy_session_key,
NetLog* net_log)
: weak_factory_(this),
spdy_session_key_(spdy_session_key),
- spdy_session_pool_(spdy_session_pool),
+ spdy_session_pool_(NULL),
http_server_properties_(http_server_properties),
- connection_(new ClientSocketHandle),
read_buffer_(new IOBuffer(kReadBufferSize)),
stream_hi_water_mark_(kFirstStreamId),
write_pending_(false),
@@ -421,10 +419,11 @@ SpdySession::~SpdySession() {
CloseAllStreams(ERR_ABORTED);
}
- if (connection_->is_initialized()) {
- // With SPDY we can't recycle sockets.
- connection_->socket()->Disconnect();
- }
+ // TODO(akalin): Check connection->is_initialized() instead. This
+ // requires re-working CreateFakeSpdySession(), though.
+ DCHECK(connection_->socket());
+ // With SPDY we can't recycle sockets.
+ connection_->socket()->Disconnect();
// Streams should all be gone now.
DCHECK_EQ(0u, num_active_streams());
@@ -442,14 +441,17 @@ SpdySession::~SpdySession() {
Error SpdySession::InitializeWithSocket(
scoped_ptr<ClientSocketHandle> connection,
+ SpdySessionPool* spdy_session_pool,
bool is_secure,
int certificate_error_code) {
+ // TODO(akalin): Check connection->is_initialized() instead. This
+ // requires re-working CreateFakeSpdySession(), though.
+ DCHECK(connection->socket());
base::StatsCounter spdy_sessions("spdy.sessions");
spdy_sessions.Increment();
state_ = STATE_DO_READ;
connection_ = connection.Pass();
- connection_->AddLayeredPool(this);
is_secure_ = is_secure;
certificate_error_code_ = certificate_error_code;
@@ -485,18 +487,23 @@ Error SpdySession::InitializeWithSocket(
buffered_spdy_framer_.reset(
new BufferedSpdyFramer(NPNToSpdyVersion(protocol), enable_compression_));
buffered_spdy_framer_->set_visitor(this);
- SendInitialSettings();
UMA_HISTOGRAM_ENUMERATION("Net.SpdyVersion", protocol, kProtoMaximumVersion);
net_log_.AddEvent(
NetLog::TYPE_SPDY_SESSION_INITIALIZED,
connection_->socket()->NetLog().source().ToEventParametersCallback());
- // Write out any data that we might have to send, such as the settings frame.
- WriteSocketLater();
int error = DoLoop(OK);
if (error == ERR_IO_PENDING)
- return OK;
+ error = OK;
+ if (error == OK) {
+ connection_->AddLayeredPool(this);
+ SendInitialSettings();
+ // Write out any data that we might have to send, such as the
+ // settings frame.
+ WriteSocketLater();
+ spdy_session_pool_ = spdy_session_pool;
+ }
return static_cast<Error>(error);
}
@@ -685,14 +692,15 @@ int SpdySession::GetProtocolVersion() const {
}
bool SpdySession::CloseOneIdleConnection() {
- if (!spdy_session_pool_ || num_active_streams() > 0)
+ DCHECK(spdy_session_pool_);
+ if (num_active_streams() > 0)
return false;
base::WeakPtr<SpdySession> weak_ptr = weak_factory_.GetWeakPtr();
// Will remove a reference to this.
RemoveFromPool();
// Since the underlying socket is only returned when |this| is destroyed,
// we should only return true if |this| no longer exists.
- return weak_ptr.get() == NULL;
+ return !weak_ptr;
}
void SpdySession::EnqueueStreamWrite(
@@ -1074,7 +1082,7 @@ int SpdySession::DoRead() {
return ERR_IO_PENDING;
}
- CHECK(connection_.get());
+ CHECK(connection_);
CHECK(connection_->socket());
state_ = STATE_DO_READ_COMPLETE;
return connection_->socket()->Read(
@@ -1522,7 +1530,9 @@ void SpdySession::RemoveFromPool() {
if (spdy_session_pool_) {
SpdySessionPool* pool = spdy_session_pool_;
spdy_session_pool_ = NULL;
- pool->Remove(make_scoped_refptr(this));
+ scoped_refptr<SpdySession> self(this);
+ pool->MakeSessionUnavailable(self);
+ pool->RemoveUnavailableSession(self);
}
}
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h
index 28e53da..ed81c6c 100644
--- a/net/spdy/spdy_session.h
+++ b/net/spdy/spdy_session.h
@@ -200,7 +200,6 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
// |session| is the HttpNetworkSession. |net_log| is the NetLog that we log
// network events to.
SpdySession(const SpdySessionKey& spdy_session_key,
- SpdySessionPool* spdy_session_pool,
HttpServerProperties* http_server_properties,
bool verify_domain_authentication,
bool enable_sending_initial_settings,
@@ -236,11 +235,16 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
base::WeakPtr<SpdyStream>* spdy_stream,
const BoundNetLog& stream_net_log);
- // Used by SpdySessionPool to initialize with a pre-existing SSL socket. For
- // testing, setting is_secure to false allows initialization with a
- // pre-existing TCP socket.
- // Returns OK on success, or an error on failure.
+ // Initialize the session with the given connection. |is_secure|
+ // must indicate whether |connection| uses an SSL socket or not; it
+ // is usually true, but it can be false for testing or when SPDY is
+ // configured to work with non-secure sockets.
+ //
+ // Returns OK on success, or an error on failure. Never returns
+ // ERR_IO_PENDING. If an error is returned, the session must be
+ // destroyed immediately.
Error InitializeWithSocket(scoped_ptr<ClientSocketHandle> connection,
+ SpdySessionPool* spdy_session_pool,
bool is_secure,
int certificate_error_code);
diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc
index 0d4fb19..7c7e76c 100644
--- a/net/spdy/spdy_session_pool.cc
+++ b/net/spdy/spdy_session_pool.cc
@@ -75,153 +75,192 @@ SpdySessionPool::~SpdySessionPool() {
CertDatabase::GetInstance()->RemoveObserver(this);
}
-scoped_refptr<SpdySession> SpdySessionPool::GetIfExists(
- const SpdySessionKey& spdy_session_key,
+net::Error SpdySessionPool::CreateAvailableSessionFromSocket(
+ const SpdySessionKey& key,
+ scoped_ptr<ClientSocketHandle> connection,
+ const BoundNetLog& net_log,
+ int certificate_error_code,
+ scoped_refptr<SpdySession>* available_session,
+ bool is_secure) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "Net.SpdySessionGet", IMPORTED_FROM_SOCKET, SPDY_SESSION_GET_MAX);
+
+ scoped_refptr<SpdySession> new_session(
+ new SpdySession(key,
+ http_server_properties_,
+ verify_domain_authentication_,
+ enable_sending_initial_settings_,
+ enable_credential_frames_,
+ enable_compression_,
+ enable_ping_based_connection_checking_,
+ default_protocol_,
+ stream_initial_recv_window_size_,
+ initial_max_concurrent_streams_,
+ max_concurrent_streams_limit_,
+ time_func_,
+ trusted_spdy_proxy_,
+ net_log.net_log()));
+
+ Error error = new_session->InitializeWithSocket(
+ connection.Pass(), this, is_secure, certificate_error_code);
+ DCHECK_NE(error, ERR_IO_PENDING);
+
+ if (error != OK) {
+ new_session = NULL;
+ *available_session = NULL;
+ return error;
+ }
+
+ sessions_.insert(new_session);
+ available_session->swap(new_session);
+ MapKeyToAvailableSession(key, *available_session);
+
+ net_log.AddEvent(
+ NetLog::TYPE_SPDY_SESSION_POOL_IMPORTED_SESSION_FROM_SOCKET,
+ (*available_session)->net_log().source().ToEventParametersCallback());
+
+ // Look up the IP address for this session so that we can match
+ // future sessions (potentially to different domains) which can
+ // potentially be pooled with this one. Because GetPeerAddress()
+ // reports the proxy's address instead of the origin server, check
+ // to see if this is a direct connection.
+ if (enable_ip_pooling_ && key.proxy_server().is_direct()) {
+ IPEndPoint address;
+ if ((*available_session)->GetPeerAddress(&address) == OK)
+ aliases_[address] = key;
+ }
+
+ return error;
+}
+
+scoped_refptr<SpdySession> SpdySessionPool::FindAvailableSession(
+ const SpdySessionKey& key,
const BoundNetLog& net_log) {
- SpdySessionsMap::iterator it = FindSessionByKey(spdy_session_key);
- if (it != sessions_.end()) {
- UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet",
- FOUND_EXISTING,
- SPDY_SESSION_GET_MAX);
+ AvailableSessionMap::iterator it = LookupAvailableSessionByKey(key);
+ if (it != available_sessions_.end()) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "Net.SpdySessionGet", FOUND_EXISTING, SPDY_SESSION_GET_MAX);
net_log.AddEvent(
NetLog::TYPE_SPDY_SESSION_POOL_FOUND_EXISTING_SESSION,
it->second->net_log().source().ToEventParametersCallback());
return it->second;
}
- // Check if we have a Session through a domain alias.
- scoped_refptr<SpdySession> spdy_session =
- GetFromAlias(spdy_session_key, net_log, true);
- if (spdy_session) {
+ if (!enable_ip_pooling_)
+ return scoped_refptr<SpdySession>();
+
+ // Look up the key's from the resolver's cache.
+ net::HostResolver::RequestInfo resolve_info(key.host_port_pair());
+ AddressList addresses;
+ int rv = resolver_->ResolveFromCache(resolve_info, &addresses, net_log);
+ DCHECK_NE(rv, ERR_IO_PENDING);
+ if (rv != OK)
+ return scoped_refptr<SpdySession>();
+
+ // Check if we have a session through a domain alias.
+ for (AddressList::const_iterator address_it = addresses.begin();
+ address_it != addresses.end();
+ ++address_it) {
+ AliasMap::const_iterator alias_it = aliases_.find(*address_it);
+ if (alias_it == aliases_.end())
+ continue;
+
+ // We found an alias.
+ const SpdySessionKey& alias_key = alias_it->second;
+
+ // We can reuse this session only if the proxy and privacy
+ // settings match.
+ if (!(alias_key.proxy_server() == key.proxy_server()) ||
+ !(alias_key.privacy_mode() == key.privacy_mode()))
+ continue;
+
+ AvailableSessionMap::iterator available_session_it =
+ LookupAvailableSessionByKey(alias_key);
+ if (available_session_it == available_sessions_.end()) {
+ NOTREACHED(); // It shouldn't be in the aliases table if we can't get it!
+ continue;
+ }
+
+ const scoped_refptr<SpdySession>& available_session =
+ available_session_it->second;
+ DCHECK(ContainsKey(sessions_, available_session));
+ // If the session is a secure one, we need to verify that the
+ // server is authenticated to serve traffic for |host_port_proxy_pair| too.
+ if (!available_session->VerifyDomainAuthentication(
+ key.host_port_pair().host())) {
+ UMA_HISTOGRAM_ENUMERATION("Net.SpdyIPPoolDomainMatch", 0, 2);
+ continue;
+ }
+
+ UMA_HISTOGRAM_ENUMERATION("Net.SpdyIPPoolDomainMatch", 1, 2);
UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet",
FOUND_EXISTING_FROM_IP_POOL,
SPDY_SESSION_GET_MAX);
net_log.AddEvent(
NetLog::TYPE_SPDY_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL,
- spdy_session->net_log().source().ToEventParametersCallback());
+ available_session->net_log().source().ToEventParametersCallback());
// Add this session to the map so that we can find it next time.
- AddSession(spdy_session_key, spdy_session);
- spdy_session->AddPooledAlias(spdy_session_key);
- return spdy_session;
+ MapKeyToAvailableSession(key, available_session);
+ available_session->AddPooledAlias(key);
+ return available_session;
}
return scoped_refptr<SpdySession>();
}
-net::Error SpdySessionPool::GetSpdySessionFromSocket(
- const SpdySessionKey& spdy_session_key,
- scoped_ptr<ClientSocketHandle> connection,
- const BoundNetLog& net_log,
- int certificate_error_code,
- scoped_refptr<SpdySession>* spdy_session,
- bool is_secure) {
- UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet",
- IMPORTED_FROM_SOCKET,
- SPDY_SESSION_GET_MAX);
- // Create the SPDY session and add it to the pool.
- *spdy_session = new SpdySession(spdy_session_key, this,
- http_server_properties_,
- verify_domain_authentication_,
- enable_sending_initial_settings_,
- enable_credential_frames_,
- enable_compression_,
- enable_ping_based_connection_checking_,
- default_protocol_,
- stream_initial_recv_window_size_,
- initial_max_concurrent_streams_,
- max_concurrent_streams_limit_,
- time_func_,
- trusted_spdy_proxy_,
- net_log.net_log());
- AddSession(spdy_session_key, *spdy_session);
-
- net_log.AddEvent(
- NetLog::TYPE_SPDY_SESSION_POOL_IMPORTED_SESSION_FROM_SOCKET,
- (*spdy_session)->net_log().source().ToEventParametersCallback());
-
- // We have a new session. Lookup the IP address for this session so that we
- // can match future Sessions (potentially to different domains) which can
- // potentially be pooled with this one. Because GetPeerAddress() reports the
- // proxy's address instead of the origin server, check to see if this is a
- // direct connection.
- if (enable_ip_pooling_ &&
- spdy_session_key.proxy_server().is_direct()) {
- IPEndPoint address;
- if (connection->socket()->GetPeerAddress(&address) == OK)
- aliases_[address] = spdy_session_key;
+void SpdySessionPool::MakeSessionUnavailable(
+ const scoped_refptr<SpdySession>& available_session) {
+ UnmapKey(available_session->spdy_session_key());
+ RemoveAliases(available_session->spdy_session_key());
+ const std::set<SpdySessionKey>& aliases = available_session->pooled_aliases();
+ for (std::set<SpdySessionKey>::const_iterator it = aliases.begin();
+ it != aliases.end(); ++it) {
+ UnmapKey(*it);
+ RemoveAliases(*it);
}
+ DCHECK(!IsSessionAvailable(available_session));
+}
+
+void SpdySessionPool::RemoveUnavailableSession(
+ const scoped_refptr<SpdySession>& unavailable_session) {
+ DCHECK(!IsSessionAvailable(unavailable_session));
+
+ unavailable_session->net_log().AddEvent(
+ NetLog::TYPE_SPDY_SESSION_POOL_REMOVE_SESSION,
+ unavailable_session->net_log().source().ToEventParametersCallback());
- // Now we can initialize the session with the SSL socket.
- return (*spdy_session)->InitializeWithSocket(connection.Pass(), is_secure,
- certificate_error_code);
+ SessionSet::iterator it = sessions_.find(unavailable_session);
+ CHECK(it != sessions_.end());
+ sessions_.erase(it);
}
// Make a copy of |sessions_| in the Close* functions below to avoid
-// reentrancy problems. Due to aliases, it doesn't suffice to simply
-// increment the iterator before closing.
+// reentrancy problems. Since arbitrary functions get called by close
+// handlers, it doesn't suffice to simply increment the iterator
+// before closing.
void SpdySessionPool::CloseCurrentSessions(net::Error error) {
- SpdySessionsMap sessions_copy = sessions_;
- for (SpdySessionsMap::const_iterator it = sessions_copy.begin();
- it != sessions_copy.end(); ++it) {
- TryCloseSession(it->first, error, "Closing current sessions.");
- }
+ CloseCurrentSessionsHelper(error, "Closing current sessions.",
+ false /* idle_only */);
}
void SpdySessionPool::CloseCurrentIdleSessions() {
- SpdySessionsMap sessions_copy = sessions_;
- for (SpdySessionsMap::const_iterator it = sessions_copy.begin();
- it != sessions_copy.end(); ++it) {
- if (!it->second->is_active())
- TryCloseSession(it->first, ERR_ABORTED, "Closing idle sessions.");
- }
+ CloseCurrentSessionsHelper(ERR_ABORTED, "Closing idle sessions.",
+ true /* idle_only */);
}
void SpdySessionPool::CloseAllSessions() {
while (!sessions_.empty()) {
- SpdySessionsMap sessions_copy = sessions_;
- for (SpdySessionsMap::const_iterator it = sessions_copy.begin();
- it != sessions_copy.end(); ++it) {
- TryCloseSession(it->first, ERR_ABORTED, "Closing all sessions.");
- }
- }
-}
-
-void SpdySessionPool::TryCloseSession(const SpdySessionKey& key,
- net::Error error,
- const std::string& description) {
- SpdySessionsMap::const_iterator it = sessions_.find(key);
- if (it == sessions_.end())
- return;
- scoped_refptr<SpdySession> session = it->second;
- session->CloseSessionOnError(error, description);
- if (DCHECK_IS_ON()) {
- it = sessions_.find(key);
- // A new session with the same key may have been added, but it
- // must not be the one we just closed.
- if (it != sessions_.end())
- DCHECK_NE(it->second, session);
- }
-}
-
-void SpdySessionPool::Remove(const scoped_refptr<SpdySession>& session) {
- RemoveSession(session->spdy_session_key());
- session->net_log().AddEvent(
- NetLog::TYPE_SPDY_SESSION_POOL_REMOVE_SESSION,
- session->net_log().source().ToEventParametersCallback());
-
- const std::set<SpdySessionKey>& aliases = session->pooled_aliases();
- for (std::set<SpdySessionKey>::const_iterator it = aliases.begin();
- it != aliases.end(); ++it) {
- RemoveSession(*it);
+ CloseCurrentSessionsHelper(ERR_ABORTED, "Closing all sessions.",
+ false /* idle_only */);
}
}
base::Value* SpdySessionPool::SpdySessionPoolInfoToValue() const {
base::ListValue* list = new base::ListValue();
- for (SpdySessionsMap::const_iterator it = sessions_.begin();
- it != sessions_.end(); ++it) {
+ for (AvailableSessionMap::const_iterator it = available_sessions_.begin();
+ it != available_sessions_.end(); ++it) {
// Only add the session if the key in the map matches the main
// host_port_proxy_pair (not an alias).
const SpdySessionKey& key = it->first;
@@ -241,57 +280,6 @@ void SpdySessionPool::OnSSLConfigChanged() {
CloseCurrentSessions(ERR_NETWORK_CHANGED);
}
-scoped_refptr<SpdySession> SpdySessionPool::GetFromAlias(
- const SpdySessionKey& spdy_session_key,
- const BoundNetLog& net_log,
- bool record_histograms) {
- // We should only be checking aliases when there is no direct session.
- DCHECK(FindSessionByKey(spdy_session_key) == sessions_.end());
-
- if (!enable_ip_pooling_)
- return NULL;
-
- AddressList addresses;
- if (!LookupAddresses(spdy_session_key, net_log, &addresses))
- return NULL;
- for (AddressList::const_iterator iter = addresses.begin();
- iter != addresses.end();
- ++iter) {
- SpdyAliasMap::const_iterator alias_iter = aliases_.find(*iter);
- if (alias_iter == aliases_.end())
- continue;
-
- // We found an alias.
- const SpdySessionKey& alias_key = alias_iter->second;
-
- // If the proxy and privacy settings match, we can reuse this session.
- if (!(alias_key.proxy_server() == spdy_session_key.proxy_server()) ||
- !(alias_key.privacy_mode() ==
- spdy_session_key.privacy_mode()))
- continue;
-
- SpdySessionsMap::iterator it = FindSessionByKey(alias_key);
- if (it == sessions_.end()) {
- NOTREACHED(); // It shouldn't be in the aliases table if we can't get it!
- continue;
- }
-
- scoped_refptr<SpdySession> spdy_session = it->second;
- // If the SPDY session is a secure one, we need to verify that the server
- // is authenticated to serve traffic for |host_port_proxy_pair| too.
- if (!spdy_session->VerifyDomainAuthentication(
- spdy_session_key.host_port_pair().host())) {
- if (record_histograms)
- UMA_HISTOGRAM_ENUMERATION("Net.SpdyIPPoolDomainMatch", 0, 2);
- continue;
- }
- if (record_histograms)
- UMA_HISTOGRAM_ENUMERATION("Net.SpdyIPPoolDomainMatch", 1, 2);
- return spdy_session;
- }
- return NULL;
-}
-
void SpdySessionPool::OnCertAdded(const X509Certificate* cert) {
CloseCurrentSessions(ERR_NETWORK_CHANGED);
}
@@ -304,10 +292,20 @@ void SpdySessionPool::OnCertTrustChanged(const X509Certificate* cert) {
CloseCurrentSessions(ERR_NETWORK_CHANGED);
}
+bool SpdySessionPool::IsSessionAvailable(
+ const scoped_refptr<SpdySession>& session) const {
+ for (AvailableSessionMap::const_iterator it = available_sessions_.begin();
+ it != available_sessions_.end(); ++it) {
+ if (it->second == session)
+ return true;
+ }
+ return false;
+}
+
const SpdySessionKey& SpdySessionPool::NormalizeListKey(
- const SpdySessionKey& spdy_session_key) const {
+ const SpdySessionKey& key) const {
if (!force_single_domain_)
- return spdy_session_key;
+ return key;
static SpdySessionKey* single_domain_key = NULL;
if (!single_domain_key) {
@@ -319,49 +317,63 @@ const SpdySessionKey& SpdySessionPool::NormalizeListKey(
return *single_domain_key;
}
-void SpdySessionPool::AddSession(
- const SpdySessionKey& spdy_session_key,
- const scoped_refptr<SpdySession>& spdy_session) {
- const SpdySessionKey& key = NormalizeListKey(spdy_session_key);
- std::pair<SpdySessionsMap::iterator, bool> result =
- sessions_.insert(std::make_pair(key, spdy_session));
+void SpdySessionPool::MapKeyToAvailableSession(
+ const SpdySessionKey& key,
+ const scoped_refptr<SpdySession>& session) {
+ DCHECK(ContainsKey(sessions_, session));
+ const SpdySessionKey& normalized_key = NormalizeListKey(key);
+ std::pair<AvailableSessionMap::iterator, bool> result =
+ available_sessions_.insert(std::make_pair(normalized_key, session));
CHECK(result.second);
}
-SpdySessionPool::SpdySessionsMap::iterator
-SpdySessionPool::FindSessionByKey(const SpdySessionKey& spdy_session_key) {
- const SpdySessionKey& key = NormalizeListKey(spdy_session_key);
- return sessions_.find(key);
-}
-
-void SpdySessionPool::RemoveSession(const SpdySessionKey& spdy_session_key) {
- SpdySessionsMap::iterator it = FindSessionByKey(spdy_session_key);
- CHECK(it != sessions_.end());
- sessions_.erase(it);
- RemoveAliases(spdy_session_key);
+SpdySessionPool::AvailableSessionMap::iterator
+SpdySessionPool::LookupAvailableSessionByKey(
+ const SpdySessionKey& key) {
+ const SpdySessionKey& normalized_key = NormalizeListKey(key);
+ return available_sessions_.find(normalized_key);
}
-bool SpdySessionPool::LookupAddresses(const SpdySessionKey& spdy_session_key,
- const BoundNetLog& net_log,
- AddressList* addresses) const {
- net::HostResolver::RequestInfo resolve_info(
- spdy_session_key.host_port_pair());
- int rv = resolver_->ResolveFromCache(resolve_info, addresses, net_log);
- DCHECK_NE(ERR_IO_PENDING, rv);
- return rv == OK;
+void SpdySessionPool::UnmapKey(const SpdySessionKey& key) {
+ AvailableSessionMap::iterator it = LookupAvailableSessionByKey(key);
+ CHECK(it != available_sessions_.end());
+ available_sessions_.erase(it);
}
-void SpdySessionPool::RemoveAliases(const SpdySessionKey& spdy_session_key) {
+void SpdySessionPool::RemoveAliases(const SpdySessionKey& key) {
// Walk the aliases map, find references to this pair.
// TODO(mbelshe): Figure out if this is too expensive.
- SpdyAliasMap::iterator alias_it = aliases_.begin();
- while (alias_it != aliases_.end()) {
- if (alias_it->second.Equals(spdy_session_key)) {
- aliases_.erase(alias_it);
- alias_it = aliases_.begin(); // Iterator was invalidated.
- continue;
+ for (AliasMap::iterator it = aliases_.begin(); it != aliases_.end(); ) {
+ if (it->second.Equals(key)) {
+ AliasMap::iterator old_it = it;
+ ++it;
+ aliases_.erase(old_it);
+ } else {
+ ++it;
}
- ++alias_it;
+ }
+}
+
+void SpdySessionPool::CloseCurrentSessionsHelper(
+ Error error,
+ const std::string& description,
+ bool idle_only) {
+ SessionSet current_sessions = sessions_;
+ for (SessionSet::const_iterator it = current_sessions.begin();
+ it != current_sessions.end(); ++it) {
+ if (!ContainsKey(sessions_, *it))
+ continue;
+
+ // TODO(akalin): Handle unavailable sessions once those aren't
+ // removed immediately.
+ DCHECK(IsSessionAvailable(*it));
+
+ if (idle_only && (*it)->is_active())
+ continue;
+
+ (*it)->CloseSessionOnError(error, description);
+ DCHECK(!IsSessionAvailable(*it));
+ DCHECK(!ContainsKey(sessions_, *it));
}
}
diff --git a/net/spdy/spdy_session_pool.h b/net/spdy/spdy_session_pool.h
index 2e6b993..7152527 100644
--- a/net/spdy/spdy_session_pool.h
+++ b/net/spdy/spdy_session_pool.h
@@ -6,6 +6,7 @@
#define NET_SPDY_SPDY_SESSION_POOL_H_
#include <map>
+#include <set>
#include <string>
#include "base/basictypes.h"
@@ -56,32 +57,49 @@ class NET_EXPORT SpdySessionPool
const std::string& trusted_spdy_proxy);
virtual ~SpdySessionPool();
- // Returns the SPDY session for the given key, or NULL if there is
- // none.
- scoped_refptr<SpdySession> GetIfExists(
- const SpdySessionKey& spdy_session_key,
- const BoundNetLog& net_log);
+ // In the functions below, a session is "available" if this pool has
+ // a reference to it and there is some SpdySessionKey for which
+ // FindAvailableSession() will return it. A session is "unavailable"
+ // if this pool has a reference to it but it won't be returned by
+ // FindAvailableSession() for any SpdySessionKey; for example, this
+ // can happen when a session receives a GOAWAY frame and is still
+ // processing existing streams.
- // Builds a SpdySession from an existing SSL socket. There must not
- // already be a session for the given key. Note that ownership of
- // |connection| is transferred from the caller to the SpdySession.
+ // Create a new SPDY session from an existing socket. There must
+ // not already be a session for the given key.
//
- // |certificate_error_code| is used to indicate the certificate
- // error encountered when connecting the SSL socket. OK means there
- // was no error. For testing and when SPDY is configured to work
- // with non-secure sockets, setting is_secure to false allows Spdy
- // to connect with a pre-existing TCP socket.
+ // |is_secure| can be false for testing or when SPDY is configured
+ // to work with non-secure sockets. If |is_secure| is true,
+ // |certificate_error_code| indicates that the certificate error
+ // encountered when connecting the SSL socket, with OK meaning there
+ // was no error.
//
- // Returns OK on success, and the |spdy_session| will be provided.
- // Returns an error on failure, and |spdy_session| will be NULL.
- net::Error GetSpdySessionFromSocket(
- const SpdySessionKey& spdy_session_key,
+ // If successful, OK is returned and |available_session| will be
+ // non-NULL and available. Otherwise, an error is returned and
+ // |available_session| will be NULL.
+ net::Error CreateAvailableSessionFromSocket(
+ const SpdySessionKey& key,
scoped_ptr<ClientSocketHandle> connection,
const BoundNetLog& net_log,
int certificate_error_code,
- scoped_refptr<SpdySession>* spdy_session,
+ scoped_refptr<SpdySession>* available_session,
bool is_secure);
+ // Find an available session for the given key, or NULL if there isn't one.
+ scoped_refptr<SpdySession> FindAvailableSession(const SpdySessionKey& key,
+ const BoundNetLog& net_log);
+
+ // Remove all mappings and aliases for the given session, which must
+ // still be available. Except for in tests, this must be called by
+ // the given session itself.
+ void MakeSessionUnavailable(
+ const scoped_refptr<SpdySession>& available_session);
+
+ // Removes an unavailable session from the pool. Except for in
+ // tests, this must be called by the given session itself.
+ void RemoveUnavailableSession(
+ const scoped_refptr<SpdySession>& unavailable_session);
+
// Close only the currently existing SpdySessions with |error|.
// Let any new ones created while this method is running continue to
// live.
@@ -96,15 +114,6 @@ class NET_EXPORT SpdySessionPool
// closing the current ones.
void CloseAllSessions();
- // Look up the session for the given key and close it if found.
- void TryCloseSession(const SpdySessionKey& key,
- net::Error error,
- const std::string& description);
-
- // Removes a SpdySession from the SpdySessionPool. This should only be called
- // by SpdySession, because otherwise session->state_ is not set to CLOSED.
- void Remove(const scoped_refptr<SpdySession>& session);
-
// Creates a Value summary of the state of the spdy session pool. The caller
// responsible for deleting the returned value.
base::Value* SpdySessionPoolInfoToValue() const;
@@ -132,58 +141,54 @@ class NET_EXPORT SpdySessionPool
private:
friend class SpdySessionPoolPeer; // For testing.
- typedef std::map<SpdySessionKey, scoped_refptr<SpdySession> > SpdySessionsMap;
- typedef std::map<IPEndPoint, SpdySessionKey> SpdyAliasMap;
+ typedef std::set<scoped_refptr<SpdySession> > SessionSet;
+ typedef std::map<SpdySessionKey, scoped_refptr<SpdySession> >
+ AvailableSessionMap;
+ typedef std::map<IPEndPoint, SpdySessionKey> AliasMap;
- // Looks up any aliases for the given key, which must not already
- // have a session, and returns the session for first matching one,
- // or NULL if there is none. If a matching session is found, it is
- // then inserted into |sessions_|.
- scoped_refptr<SpdySession> GetFromAlias(
- const SpdySessionKey& spdy_session_key,
- const BoundNetLog& net_log,
- bool record_histograms);
+ // Returns true iff |session| is in |available_sessions_|.
+ bool IsSessionAvailable(const scoped_refptr<SpdySession>& session) const;
// Returns a normalized version of the given key suitable for lookup
- // into |sessions_|.
- const SpdySessionKey& NormalizeListKey(
- const SpdySessionKey& spdy_session_key) const;
-
- // Add the given key/session mapping. There must not already be a
- // session for the given key.
- void AddSession(const SpdySessionKey& spdy_session_key,
- const scoped_refptr<SpdySession>& spdy_session);
-
- // Returns an iterator into |sessions_| for the given key, which may
- // be equal to |sessions_.end()|.
- SpdySessionsMap::iterator FindSessionByKey(
- const SpdySessionKey& spdy_session_key);
-
- // Remove the session associated with |spdy_session_key|, which must
- // exist.
- void RemoveSession(const SpdySessionKey& spdy_session_key);
-
- // Does a DNS cache lookup for |spdy_session_key|, and returns
- // the |addresses| found.
- // Returns true if addresses found, false otherwise.
- bool LookupAddresses(const SpdySessionKey& spdy_session_key,
- const BoundNetLog& net_log,
- AddressList* addresses) const;
-
- // Remove all aliases for |spdy_session_key| from the aliases table.
- void RemoveAliases(const SpdySessionKey& spdy_session_key);
+ // into |available_sessions_|.
+ const SpdySessionKey& NormalizeListKey(const SpdySessionKey& key) const;
+
+ // Map the given key to the given session. There must not already be
+ // a mapping for |key|.
+ void MapKeyToAvailableSession(const SpdySessionKey& key,
+ const scoped_refptr<SpdySession>& session);
+
+ // Returns an iterator into |available_sessions_| for the given key,
+ // which may be equal to |available_sessions_.end()|.
+ AvailableSessionMap::iterator LookupAvailableSessionByKey(
+ const SpdySessionKey& key);
+
+ // Remove the mapping of the given key, which must exist.
+ void UnmapKey(const SpdySessionKey& key);
+
+ // Remove all aliases for |key| from the aliases table.
+ void RemoveAliases(const SpdySessionKey& key);
+
+ // Close only the currently existing SpdySessions with |error|. Let
+ // any new ones created while this method is running continue to
+ // live. If |idle_only| is true only idle sessions are closed.
+ void CloseCurrentSessionsHelper(
+ Error error,
+ const std::string& description,
+ bool idle_only);
HttpServerProperties* const http_server_properties_;
- // This is a map of session keys to sessions. A session may appear
+ // The set of all sessions. This is a superset of the sessions in
+ // |available_sessions_|.
+ SessionSet sessions_;
+
+ // This is a map of available sessions by key. A session may appear
// more than once in this map if it has aliases.
- //
- // TODO(akalin): Have a map which owns the sessions and another one
- // for the aliased session cache.
- SpdySessionsMap sessions_;
+ AvailableSessionMap available_sessions_;
// A map of IPEndPoint aliases for sessions.
- SpdyAliasMap aliases_;
+ AliasMap aliases_;
static bool g_force_single_domain;
diff --git a/net/spdy/spdy_session_pool_unittest.cc b/net/spdy/spdy_session_pool_unittest.cc
index 7d99ea3..576d30a 100644
--- a/net/spdy/spdy_session_pool_unittest.cc
+++ b/net/spdy/spdy_session_pool_unittest.cc
@@ -400,7 +400,8 @@ void SpdySessionPoolTest::RunIPPoolingTest(
// Grab the session to host 1 and verify that it is the same session
// we got with host 0, and that is a different from host 2's session.
scoped_refptr<SpdySession> session1 =
- spdy_session_pool_->GetIfExists(test_hosts[1].key, BoundNetLog());
+ spdy_session_pool_->FindAvailableSession(
+ test_hosts[1].key, BoundNetLog());
EXPECT_EQ(session.get(), session1.get());
EXPECT_NE(session2.get(), session1.get());
@@ -417,9 +418,11 @@ void SpdySessionPoolTest::RunIPPoolingTest(
// Cleanup the sessions.
switch (close_sessions_type) {
case SPDY_POOL_CLOSE_SESSIONS_MANUALLY:
- spdy_session_pool_->Remove(session);
+ spdy_session_pool_->MakeSessionUnavailable(session);
+ spdy_session_pool_->RemoveUnavailableSession(session);
session = NULL;
- spdy_session_pool_->Remove(session2);
+ spdy_session_pool_->MakeSessionUnavailable(session2);
+ spdy_session_pool_->RemoveUnavailableSession(session2);
session2 = NULL;
break;
case SPDY_POOL_CLOSE_CURRENT_SESSIONS:
@@ -469,7 +472,8 @@ void SpdySessionPoolTest::RunIPPoolingTest(
EXPECT_EQ(NULL, spdy_stream.get());
EXPECT_EQ(NULL, spdy_stream1.get());
EXPECT_EQ(NULL, spdy_stream2.get());
- spdy_session_pool_->Remove(session2);
+ spdy_session_pool_->MakeSessionUnavailable(session2);
+ spdy_session_pool_->RemoveUnavailableSession(session2);
session2 = NULL;
break;
}
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc
index dae5837..be14048 100644
--- a/net/spdy/spdy_session_unittest.cc
+++ b/net/spdy/spdy_session_unittest.cc
@@ -262,7 +262,8 @@ TEST_P(SpdySessionTest, GoAway) {
session = NULL;
// Delete the second session.
- spdy_session_pool_->Remove(session2);
+ spdy_session_pool_->MakeSessionUnavailable(session2);
+ spdy_session_pool_->RemoveUnavailableSession(session2);
session2 = NULL;
EXPECT_EQ(NULL, spdy_stream2.get());
}
@@ -1438,7 +1439,9 @@ TEST_P(SpdySessionTest, VerifyDomainAuthentication) {
HttpNetworkSession::NORMAL_SOCKET_POOL),
BoundNetLog()));
- EXPECT_EQ(OK, session->InitializeWithSocket(connection.Pass(), false, OK));
+ EXPECT_EQ(OK,
+ session->InitializeWithSocket(
+ connection.Pass(), spdy_session_pool_, false, OK));
EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org"));
EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org"));
EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.com"));
@@ -1508,7 +1511,9 @@ TEST_P(SpdySessionTest, ConnectionPooledWithTlsChannelId) {
HttpNetworkSession::NORMAL_SOCKET_POOL),
BoundNetLog()));
- EXPECT_EQ(OK, session->InitializeWithSocket(connection.Pass(), false, OK));
+ EXPECT_EQ(OK,
+ session->InitializeWithSocket(
+ connection.Pass(), spdy_session_pool_, false, OK));
EXPECT_TRUE(session->VerifyDomainAuthentication("www.example.org"));
EXPECT_TRUE(session->VerifyDomainAuthentication("mail.example.org"));
EXPECT_FALSE(session->VerifyDomainAuthentication("mail.example.com"));
@@ -1782,14 +1787,17 @@ TEST_P(SpdySessionTest, NeedsCredentials) {
HttpNetworkSession::NORMAL_SOCKET_POOL),
BoundNetLog()));
- EXPECT_EQ(OK, session->InitializeWithSocket(connection.Pass(), true, OK));
+ EXPECT_EQ(OK,
+ session->InitializeWithSocket(
+ connection.Pass(), spdy_session_pool_, true, OK));
EXPECT_EQ(spdy_util_.spdy_version() >= SPDY3, session->NeedsCredentials());
// Flush the SpdySession::OnReadComplete() task.
base::MessageLoop::current()->RunUntilIdle();
- spdy_session_pool_->Remove(session);
+ spdy_session_pool_->MakeSessionUnavailable(session);
+ spdy_session_pool_->RemoveUnavailableSession(session);
}
// Test that SpdySession::DoRead reads data from the socket without yielding.
@@ -2298,7 +2306,7 @@ TEST_P(SpdySessionTest, CloseOneIdleConnectionWithAlias) {
info, &addresses, CompletionCallback(), NULL, BoundNetLog());
// Get a session for |key2|, which should return the session created earlier.
scoped_refptr<SpdySession> session2 =
- spdy_session_pool_->GetIfExists(key2, BoundNetLog());
+ spdy_session_pool_->FindAvailableSession(key2, BoundNetLog());
ASSERT_EQ(session1.get(), session2.get());
EXPECT_FALSE(pool->IsStalled());
@@ -2501,11 +2509,13 @@ TEST_P(SpdySessionTest, SpdySessionKeyPrivacyMode) {
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
- spdy_session_pool_->Remove(session_privacy_enabled);
+ spdy_session_pool_->MakeSessionUnavailable(session_privacy_enabled);
+ spdy_session_pool_->RemoveUnavailableSession(session_privacy_enabled);
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
- spdy_session_pool_->Remove(session_privacy_disabled);
+ spdy_session_pool_->MakeSessionUnavailable(session_privacy_disabled);
+ spdy_session_pool_->RemoveUnavailableSession(session_privacy_disabled);
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
}
@@ -2572,13 +2582,16 @@ TEST_P(SpdySessionTest, SendCredentials) {
HttpNetworkSession::NORMAL_SOCKET_POOL),
BoundNetLog()));
- EXPECT_EQ(OK, session->InitializeWithSocket(connection.Pass(), true, OK));
+ EXPECT_EQ(OK,
+ session->InitializeWithSocket(
+ connection.Pass(), spdy_session_pool_, true, OK));
EXPECT_TRUE(session->NeedsCredentials());
// Flush the SpdySession::OnReadComplete() task.
base::MessageLoop::current()->RunUntilIdle();
- spdy_session_pool_->Remove(session);
+ spdy_session_pool_->MakeSessionUnavailable(session);
+ spdy_session_pool_->RemoveUnavailableSession(session);
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key));
}
diff --git a/net/spdy/spdy_test_util_common.cc b/net/spdy/spdy_test_util_common.cc
index 34da314..54982b9 100644
--- a/net/spdy/spdy_test_util_common.cc
+++ b/net/spdy/spdy_test_util_common.cc
@@ -482,7 +482,7 @@ SpdyURLRequestContext::~SpdyURLRequestContext() {
}
bool HasSpdySession(SpdySessionPool* pool, const SpdySessionKey& key) {
- return pool->GetIfExists(key, BoundNetLog()) != NULL;
+ return pool->FindAvailableSession(key, BoundNetLog()) != NULL;
}
namespace {
@@ -542,7 +542,7 @@ scoped_refptr<SpdySession> CreateSpdySessionHelper(
scoped_refptr<SpdySession> spdy_session;
EXPECT_EQ(
OK,
- http_session->spdy_session_pool()->GetSpdySessionFromSocket(
+ http_session->spdy_session_pool()->CreateAvailableSessionFromSocket(
key, connection.Pass(), net_log, OK, &spdy_session,
is_secure));
EXPECT_TRUE(HasSpdySession(http_session->spdy_session_pool(), key));
@@ -628,7 +628,7 @@ scoped_refptr<SpdySession> CreateFakeSpdySession(SpdySessionPool* pool,
handle->set_socket(new FakeSpdySessionClientSocket());
EXPECT_EQ(
OK,
- pool->GetSpdySessionFromSocket(
+ pool->CreateAvailableSessionFromSocket(
key, handle.Pass(), BoundNetLog(), OK, &spdy_session,
true /* is_secure */));
EXPECT_TRUE(HasSpdySession(pool, key));
diff --git a/net/websockets/websocket_job.cc b/net/websockets/websocket_job.cc
index 301f0ae..34d4a25 100644
--- a/net/websockets/websocket_job.cc
+++ b/net/websockets/websocket_job.cc
@@ -597,7 +597,7 @@ int WebSocketJob::TrySpdyStream() {
// Forbid wss downgrade to SPDY without SSL.
// TODO(toyoshim): Does it realize the same policy with HTTP?
scoped_refptr<SpdySession> spdy_session =
- spdy_pool->GetIfExists(key, *socket_->net_log());
+ spdy_pool->FindAvailableSession(key, *socket_->net_log());
if (!spdy_session)
return OK;