Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(527)

Side by Side Diff: net/spdy/spdy_session_pool.cc

Issue 18546008: [SPDY] Use WeakPtr<SpdySession> everywhere but SpdySessionPool (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix test, other minor formatting/comment changes Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/spdy/spdy_session_pool.h ('k') | net/spdy/spdy_session_pool_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/spdy/spdy_session_pool.h" 5 #include "net/spdy/spdy_session_pool.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/values.h" 9 #include "base/values.h"
10 #include "net/base/address_list.h" 10 #include "net/base/address_list.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 ssl_config_service_->RemoveObserver(this); 73 ssl_config_service_->RemoveObserver(this);
74 NetworkChangeNotifier::RemoveIPAddressObserver(this); 74 NetworkChangeNotifier::RemoveIPAddressObserver(this);
75 CertDatabase::GetInstance()->RemoveObserver(this); 75 CertDatabase::GetInstance()->RemoveObserver(this);
76 } 76 }
77 77
78 net::Error SpdySessionPool::CreateAvailableSessionFromSocket( 78 net::Error SpdySessionPool::CreateAvailableSessionFromSocket(
79 const SpdySessionKey& key, 79 const SpdySessionKey& key,
80 scoped_ptr<ClientSocketHandle> connection, 80 scoped_ptr<ClientSocketHandle> connection,
81 const BoundNetLog& net_log, 81 const BoundNetLog& net_log,
82 int certificate_error_code, 82 int certificate_error_code,
83 scoped_refptr<SpdySession>* available_session, 83 base::WeakPtr<SpdySession>* available_session,
84 bool is_secure) { 84 bool is_secure) {
85 UMA_HISTOGRAM_ENUMERATION( 85 UMA_HISTOGRAM_ENUMERATION(
86 "Net.SpdySessionGet", IMPORTED_FROM_SOCKET, SPDY_SESSION_GET_MAX); 86 "Net.SpdySessionGet", IMPORTED_FROM_SOCKET, SPDY_SESSION_GET_MAX);
87 87
88 scoped_refptr<SpdySession> new_session( 88 scoped_refptr<SpdySession> new_session(
89 new SpdySession(key, 89 new SpdySession(key,
90 http_server_properties_, 90 http_server_properties_,
91 verify_domain_authentication_, 91 verify_domain_authentication_,
92 enable_sending_initial_settings_, 92 enable_sending_initial_settings_,
93 enable_credential_frames_, 93 enable_credential_frames_,
94 enable_compression_, 94 enable_compression_,
95 enable_ping_based_connection_checking_, 95 enable_ping_based_connection_checking_,
96 default_protocol_, 96 default_protocol_,
97 stream_initial_recv_window_size_, 97 stream_initial_recv_window_size_,
98 initial_max_concurrent_streams_, 98 initial_max_concurrent_streams_,
99 max_concurrent_streams_limit_, 99 max_concurrent_streams_limit_,
100 time_func_, 100 time_func_,
101 trusted_spdy_proxy_, 101 trusted_spdy_proxy_,
102 net_log.net_log())); 102 net_log.net_log()));
103 103
104 Error error = new_session->InitializeWithSocket( 104 Error error = new_session->InitializeWithSocket(
105 connection.Pass(), this, is_secure, certificate_error_code); 105 connection.Pass(), this, is_secure, certificate_error_code);
106 DCHECK_NE(error, ERR_IO_PENDING); 106 DCHECK_NE(error, ERR_IO_PENDING);
107 107
108 if (error != OK) { 108 if (error != OK) {
109 new_session = NULL; 109 new_session = NULL;
110 *available_session = NULL; 110 available_session->reset();
111 return error; 111 return error;
112 } 112 }
113 113
114 sessions_.insert(new_session); 114 sessions_.insert(new_session);
115 available_session->swap(new_session); 115 *available_session = new_session->GetWeakPtr();
116 MapKeyToAvailableSession(key, *available_session); 116 MapKeyToAvailableSession(key, *available_session);
117 117
118 net_log.AddEvent( 118 net_log.AddEvent(
119 NetLog::TYPE_SPDY_SESSION_POOL_IMPORTED_SESSION_FROM_SOCKET, 119 NetLog::TYPE_SPDY_SESSION_POOL_IMPORTED_SESSION_FROM_SOCKET,
120 (*available_session)->net_log().source().ToEventParametersCallback()); 120 (*available_session)->net_log().source().ToEventParametersCallback());
121 121
122 // Look up the IP address for this session so that we can match 122 // Look up the IP address for this session so that we can match
123 // future sessions (potentially to different domains) which can 123 // future sessions (potentially to different domains) which can
124 // potentially be pooled with this one. Because GetPeerAddress() 124 // potentially be pooled with this one. Because GetPeerAddress()
125 // reports the proxy's address instead of the origin server, check 125 // reports the proxy's address instead of the origin server, check
126 // to see if this is a direct connection. 126 // to see if this is a direct connection.
127 if (enable_ip_pooling_ && key.proxy_server().is_direct()) { 127 if (enable_ip_pooling_ && key.proxy_server().is_direct()) {
128 IPEndPoint address; 128 IPEndPoint address;
129 if ((*available_session)->GetPeerAddress(&address) == OK) 129 if ((*available_session)->GetPeerAddress(&address) == OK)
130 aliases_[address] = key; 130 aliases_[address] = key;
131 } 131 }
132 132
133 return error; 133 return error;
134 } 134 }
135 135
136 scoped_refptr<SpdySession> SpdySessionPool::FindAvailableSession( 136 base::WeakPtr<SpdySession> SpdySessionPool::FindAvailableSession(
137 const SpdySessionKey& key, 137 const SpdySessionKey& key,
138 const BoundNetLog& net_log) { 138 const BoundNetLog& net_log) {
139 AvailableSessionMap::iterator it = LookupAvailableSessionByKey(key); 139 AvailableSessionMap::iterator it = LookupAvailableSessionByKey(key);
140 if (it != available_sessions_.end()) { 140 if (it != available_sessions_.end()) {
141 UMA_HISTOGRAM_ENUMERATION( 141 UMA_HISTOGRAM_ENUMERATION(
142 "Net.SpdySessionGet", FOUND_EXISTING, SPDY_SESSION_GET_MAX); 142 "Net.SpdySessionGet", FOUND_EXISTING, SPDY_SESSION_GET_MAX);
143 net_log.AddEvent( 143 net_log.AddEvent(
144 NetLog::TYPE_SPDY_SESSION_POOL_FOUND_EXISTING_SESSION, 144 NetLog::TYPE_SPDY_SESSION_POOL_FOUND_EXISTING_SESSION,
145 it->second->net_log().source().ToEventParametersCallback()); 145 it->second->net_log().source().ToEventParametersCallback());
146 return it->second; 146 return it->second;
147 } 147 }
148 148
149 if (!enable_ip_pooling_) 149 if (!enable_ip_pooling_)
150 return scoped_refptr<SpdySession>(); 150 return base::WeakPtr<SpdySession>();
151 151
152 // Look up the key's from the resolver's cache. 152 // Look up the key's from the resolver's cache.
153 net::HostResolver::RequestInfo resolve_info(key.host_port_pair()); 153 net::HostResolver::RequestInfo resolve_info(key.host_port_pair());
154 AddressList addresses; 154 AddressList addresses;
155 int rv = resolver_->ResolveFromCache(resolve_info, &addresses, net_log); 155 int rv = resolver_->ResolveFromCache(resolve_info, &addresses, net_log);
156 DCHECK_NE(rv, ERR_IO_PENDING); 156 DCHECK_NE(rv, ERR_IO_PENDING);
157 if (rv != OK) 157 if (rv != OK)
158 return scoped_refptr<SpdySession>(); 158 return base::WeakPtr<SpdySession>();
159 159
160 // Check if we have a session through a domain alias. 160 // Check if we have a session through a domain alias.
161 for (AddressList::const_iterator address_it = addresses.begin(); 161 for (AddressList::const_iterator address_it = addresses.begin();
162 address_it != addresses.end(); 162 address_it != addresses.end();
163 ++address_it) { 163 ++address_it) {
164 AliasMap::const_iterator alias_it = aliases_.find(*address_it); 164 AliasMap::const_iterator alias_it = aliases_.find(*address_it);
165 if (alias_it == aliases_.end()) 165 if (alias_it == aliases_.end())
166 continue; 166 continue;
167 167
168 // We found an alias. 168 // We found an alias.
169 const SpdySessionKey& alias_key = alias_it->second; 169 const SpdySessionKey& alias_key = alias_it->second;
170 170
171 // We can reuse this session only if the proxy and privacy 171 // We can reuse this session only if the proxy and privacy
172 // settings match. 172 // settings match.
173 if (!(alias_key.proxy_server() == key.proxy_server()) || 173 if (!(alias_key.proxy_server() == key.proxy_server()) ||
174 !(alias_key.privacy_mode() == key.privacy_mode())) 174 !(alias_key.privacy_mode() == key.privacy_mode()))
175 continue; 175 continue;
176 176
177 AvailableSessionMap::iterator available_session_it = 177 AvailableSessionMap::iterator available_session_it =
178 LookupAvailableSessionByKey(alias_key); 178 LookupAvailableSessionByKey(alias_key);
179 if (available_session_it == available_sessions_.end()) { 179 if (available_session_it == available_sessions_.end()) {
180 NOTREACHED(); // It shouldn't be in the aliases table if we can't get it! 180 NOTREACHED(); // It shouldn't be in the aliases table if we can't get it!
181 continue; 181 continue;
182 } 182 }
183 183
184 const scoped_refptr<SpdySession>& available_session = 184 const base::WeakPtr<SpdySession>& available_session =
185 available_session_it->second; 185 available_session_it->second;
186 DCHECK(ContainsKey(sessions_, available_session)); 186 DCHECK(ContainsKey(sessions_, available_session.get()));
187 // If the session is a secure one, we need to verify that the 187 // If the session is a secure one, we need to verify that the
188 // server is authenticated to serve traffic for |host_port_proxy_pair| too. 188 // server is authenticated to serve traffic for |host_port_proxy_pair| too.
189 if (!available_session->VerifyDomainAuthentication( 189 if (!available_session->VerifyDomainAuthentication(
190 key.host_port_pair().host())) { 190 key.host_port_pair().host())) {
191 UMA_HISTOGRAM_ENUMERATION("Net.SpdyIPPoolDomainMatch", 0, 2); 191 UMA_HISTOGRAM_ENUMERATION("Net.SpdyIPPoolDomainMatch", 0, 2);
192 continue; 192 continue;
193 } 193 }
194 194
195 UMA_HISTOGRAM_ENUMERATION("Net.SpdyIPPoolDomainMatch", 1, 2); 195 UMA_HISTOGRAM_ENUMERATION("Net.SpdyIPPoolDomainMatch", 1, 2);
196 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", 196 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet",
197 FOUND_EXISTING_FROM_IP_POOL, 197 FOUND_EXISTING_FROM_IP_POOL,
198 SPDY_SESSION_GET_MAX); 198 SPDY_SESSION_GET_MAX);
199 net_log.AddEvent( 199 net_log.AddEvent(
200 NetLog::TYPE_SPDY_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL, 200 NetLog::TYPE_SPDY_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL,
201 available_session->net_log().source().ToEventParametersCallback()); 201 available_session->net_log().source().ToEventParametersCallback());
202 // Add this session to the map so that we can find it next time. 202 // Add this session to the map so that we can find it next time.
203 MapKeyToAvailableSession(key, available_session); 203 MapKeyToAvailableSession(key, available_session);
204 available_session->AddPooledAlias(key); 204 available_session->AddPooledAlias(key);
205 return available_session; 205 return available_session;
206 } 206 }
207 207
208 return scoped_refptr<SpdySession>(); 208 return base::WeakPtr<SpdySession>();
209 } 209 }
210 210
211 void SpdySessionPool::MakeSessionUnavailable( 211 void SpdySessionPool::MakeSessionUnavailable(
212 const scoped_refptr<SpdySession>& available_session) { 212 const base::WeakPtr<SpdySession>& available_session) {
213 UnmapKey(available_session->spdy_session_key()); 213 UnmapKey(available_session->spdy_session_key());
214 RemoveAliases(available_session->spdy_session_key()); 214 RemoveAliases(available_session->spdy_session_key());
215 const std::set<SpdySessionKey>& aliases = available_session->pooled_aliases(); 215 const std::set<SpdySessionKey>& aliases = available_session->pooled_aliases();
216 for (std::set<SpdySessionKey>::const_iterator it = aliases.begin(); 216 for (std::set<SpdySessionKey>::const_iterator it = aliases.begin();
217 it != aliases.end(); ++it) { 217 it != aliases.end(); ++it) {
218 UnmapKey(*it); 218 UnmapKey(*it);
219 RemoveAliases(*it); 219 RemoveAliases(*it);
220 } 220 }
221 DCHECK(!IsSessionAvailable(available_session)); 221 DCHECK(!IsSessionAvailable(available_session));
222 } 222 }
223 223
224 void SpdySessionPool::RemoveUnavailableSession( 224 void SpdySessionPool::RemoveUnavailableSession(
225 const scoped_refptr<SpdySession>& unavailable_session) { 225 const base::WeakPtr<SpdySession>& unavailable_session) {
226 DCHECK(!IsSessionAvailable(unavailable_session)); 226 DCHECK(!IsSessionAvailable(unavailable_session));
227 227
228 unavailable_session->net_log().AddEvent( 228 unavailable_session->net_log().AddEvent(
229 NetLog::TYPE_SPDY_SESSION_POOL_REMOVE_SESSION, 229 NetLog::TYPE_SPDY_SESSION_POOL_REMOVE_SESSION,
230 unavailable_session->net_log().source().ToEventParametersCallback()); 230 unavailable_session->net_log().source().ToEventParametersCallback());
231 231
232 SessionSet::iterator it = sessions_.find(unavailable_session); 232 SessionSet::iterator it = sessions_.find(unavailable_session.get());
233 CHECK(it != sessions_.end()); 233 CHECK(it != sessions_.end());
234 sessions_.erase(it); 234 sessions_.erase(it);
235 } 235 }
236 236
237 // Make a copy of |sessions_| in the Close* functions below to avoid 237 // Make a copy of |sessions_| in the Close* functions below to avoid
238 // reentrancy problems. Since arbitrary functions get called by close 238 // reentrancy problems. Since arbitrary functions get called by close
239 // handlers, it doesn't suffice to simply increment the iterator 239 // handlers, it doesn't suffice to simply increment the iterator
240 // before closing. 240 // before closing.
241 241
242 void SpdySessionPool::CloseCurrentSessions(net::Error error) { 242 void SpdySessionPool::CloseCurrentSessions(net::Error error) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 286
287 void SpdySessionPool::OnCertTrustChanged(const X509Certificate* cert) { 287 void SpdySessionPool::OnCertTrustChanged(const X509Certificate* cert) {
288 // Per wtc, we actually only need to CloseCurrentSessions when trust is 288 // Per wtc, we actually only need to CloseCurrentSessions when trust is
289 // reduced. CloseCurrentSessions now because OnCertTrustChanged does not 289 // reduced. CloseCurrentSessions now because OnCertTrustChanged does not
290 // tell us this. 290 // tell us this.
291 // See comments in ClientSocketPoolManager::OnCertTrustChanged. 291 // See comments in ClientSocketPoolManager::OnCertTrustChanged.
292 CloseCurrentSessions(ERR_NETWORK_CHANGED); 292 CloseCurrentSessions(ERR_NETWORK_CHANGED);
293 } 293 }
294 294
295 bool SpdySessionPool::IsSessionAvailable( 295 bool SpdySessionPool::IsSessionAvailable(
296 const scoped_refptr<SpdySession>& session) const { 296 const base::WeakPtr<SpdySession>& session) const {
297 for (AvailableSessionMap::const_iterator it = available_sessions_.begin(); 297 for (AvailableSessionMap::const_iterator it = available_sessions_.begin();
298 it != available_sessions_.end(); ++it) { 298 it != available_sessions_.end(); ++it) {
299 if (it->second == session) 299 if (it->second.get() == session.get())
300 return true; 300 return true;
301 } 301 }
302 return false; 302 return false;
303 } 303 }
304 304
305 const SpdySessionKey& SpdySessionPool::NormalizeListKey( 305 const SpdySessionKey& SpdySessionPool::NormalizeListKey(
306 const SpdySessionKey& key) const { 306 const SpdySessionKey& key) const {
307 if (!force_single_domain_) 307 if (!force_single_domain_)
308 return key; 308 return key;
309 309
310 static SpdySessionKey* single_domain_key = NULL; 310 static SpdySessionKey* single_domain_key = NULL;
311 if (!single_domain_key) { 311 if (!single_domain_key) {
312 HostPortPair single_domain = HostPortPair("singledomain.com", 80); 312 HostPortPair single_domain = HostPortPair("singledomain.com", 80);
313 single_domain_key = new SpdySessionKey(single_domain, 313 single_domain_key = new SpdySessionKey(single_domain,
314 ProxyServer::Direct(), 314 ProxyServer::Direct(),
315 kPrivacyModeDisabled); 315 kPrivacyModeDisabled);
316 } 316 }
317 return *single_domain_key; 317 return *single_domain_key;
318 } 318 }
319 319
320 void SpdySessionPool::MapKeyToAvailableSession( 320 void SpdySessionPool::MapKeyToAvailableSession(
321 const SpdySessionKey& key, 321 const SpdySessionKey& key,
322 const scoped_refptr<SpdySession>& session) { 322 const base::WeakPtr<SpdySession>& session) {
323 DCHECK(ContainsKey(sessions_, session)); 323 DCHECK(ContainsKey(sessions_, scoped_refptr<SpdySession>(session.get())));
324 const SpdySessionKey& normalized_key = NormalizeListKey(key); 324 const SpdySessionKey& normalized_key = NormalizeListKey(key);
325 std::pair<AvailableSessionMap::iterator, bool> result = 325 std::pair<AvailableSessionMap::iterator, bool> result =
326 available_sessions_.insert(std::make_pair(normalized_key, session)); 326 available_sessions_.insert(std::make_pair(normalized_key, session));
327 CHECK(result.second); 327 CHECK(result.second);
328 } 328 }
329 329
330 SpdySessionPool::AvailableSessionMap::iterator 330 SpdySessionPool::AvailableSessionMap::iterator
331 SpdySessionPool::LookupAvailableSessionByKey( 331 SpdySessionPool::LookupAvailableSessionByKey(
332 const SpdySessionKey& key) { 332 const SpdySessionKey& key) {
333 const SpdySessionKey& normalized_key = NormalizeListKey(key); 333 const SpdySessionKey& normalized_key = NormalizeListKey(key);
(...skipping 27 matching lines...) Expand all
361 SessionSet current_sessions = sessions_; 361 SessionSet current_sessions = sessions_;
362 for (SessionSet::const_iterator it = current_sessions.begin(); 362 for (SessionSet::const_iterator it = current_sessions.begin();
363 it != current_sessions.end(); ++it) { 363 it != current_sessions.end(); ++it) {
364 if (!ContainsKey(sessions_, *it)) 364 if (!ContainsKey(sessions_, *it))
365 continue; 365 continue;
366 366
367 if (idle_only && (*it)->is_active()) 367 if (idle_only && (*it)->is_active())
368 continue; 368 continue;
369 369
370 (*it)->CloseSessionOnError(error, description); 370 (*it)->CloseSessionOnError(error, description);
371 DCHECK(!IsSessionAvailable(*it)); 371 DCHECK(!IsSessionAvailable((*it)->GetWeakPtr()));
372 DCHECK(!ContainsKey(sessions_, *it)); 372 DCHECK(!ContainsKey(sessions_, *it));
373 } 373 }
374 } 374 }
375 375
376 } // namespace net 376 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_session_pool.h ('k') | net/spdy/spdy_session_pool_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698