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

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

Issue 2749123002: ABANDONED Allow SpdySessionPool to find/create SpdySession with IP pooling disabled. (Closed)
Patch Set: Re: #7. Created 3 years, 9 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
« 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 <utility> 7 #include <utility>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 auto new_session = base::MakeUnique<SpdySession>( 100 auto new_session = base::MakeUnique<SpdySession>(
101 key, http_server_properties_, transport_security_state_, 101 key, http_server_properties_, transport_security_state_,
102 enable_sending_initial_data_, enable_ping_based_connection_checking_, 102 enable_sending_initial_data_, enable_ping_based_connection_checking_,
103 session_max_recv_window_size_, initial_settings_, time_func_, 103 session_max_recv_window_size_, initial_settings_, time_func_,
104 push_delegate_, proxy_delegate_, net_log.net_log()); 104 push_delegate_, proxy_delegate_, net_log.net_log());
105 105
106 new_session->InitializeWithSocket(std::move(connection), this, is_secure); 106 new_session->InitializeWithSocket(std::move(connection), this, is_secure);
107 107
108 base::WeakPtr<SpdySession> available_session = new_session->GetWeakPtr(); 108 base::WeakPtr<SpdySession> available_session = new_session->GetWeakPtr();
109 sessions_.insert(new_session.release()); 109 sessions_.insert(new_session.release());
110 MapKeyToAvailableSession(key, available_session); 110 MapKeyToAvailableSession(key, available_session, /* ip_pooled = */ false);
111 111
112 net_log.AddEvent( 112 net_log.AddEvent(
113 NetLogEventType::HTTP2_SESSION_POOL_IMPORTED_SESSION_FROM_SOCKET, 113 NetLogEventType::HTTP2_SESSION_POOL_IMPORTED_SESSION_FROM_SOCKET,
114 available_session->net_log().source().ToEventParametersCallback()); 114 available_session->net_log().source().ToEventParametersCallback());
115 115
116 // Look up the IP address for this session so that we can match 116 // Look up the IP address for this session so that we can match
117 // future sessions (potentially to different domains) which can 117 // future sessions (potentially to different domains) which can
118 // potentially be pooled with this one. Because GetPeerAddress() 118 // potentially be pooled with this one. Because GetPeerAddress()
119 // reports the proxy's address instead of the origin server, check 119 // reports the proxy's address instead of the origin server, check
120 // to see if this is a direct connection. 120 // to see if this is a direct connection.
121 if (key.proxy_server().is_direct()) { 121 if (key.proxy_server().is_direct()) {
122 IPEndPoint address; 122 IPEndPoint address;
123 if (available_session->GetPeerAddress(&address) == OK) 123 if (available_session->GetPeerAddress(&address) == OK)
124 aliases_[address] = key; 124 aliases_[address] = key;
125 } 125 }
126 126
127 return available_session; 127 return available_session;
128 } 128 }
129 129
130 base::WeakPtr<SpdySession> SpdySessionPool::FindAvailableSession( 130 base::WeakPtr<SpdySession> SpdySessionPool::FindAvailableSession(
131 const SpdySessionKey& key, 131 const SpdySessionKey& key,
132 const GURL& url, 132 const GURL& url,
133 bool enable_ip_based_pooling,
133 const NetLogWithSource& net_log) { 134 const NetLogWithSource& net_log) {
134 UnclaimedPushedStreamMap::iterator url_it = 135 UnclaimedPushedStreamMap::iterator url_it =
135 unclaimed_pushed_streams_.find(url); 136 unclaimed_pushed_streams_.find(url);
136 if (!url.is_empty() && url_it != unclaimed_pushed_streams_.end()) { 137 if (!url.is_empty() && url_it != unclaimed_pushed_streams_.end()) {
137 DCHECK(url.SchemeIsCryptographic()); 138 DCHECK(url.SchemeIsCryptographic());
138 for (WeakSessionList::iterator it = url_it->second.begin(); 139 for (WeakSessionList::iterator it = url_it->second.begin();
139 it != url_it->second.end();) { 140 it != url_it->second.end();) {
140 base::WeakPtr<SpdySession> spdy_session = *it; 141 base::WeakPtr<SpdySession> spdy_session = *it;
141 // Lazy deletion of destroyed SpdySessions. 142 // Lazy deletion of destroyed SpdySessions.
142 if (!spdy_session) { 143 if (!spdy_session) {
(...skipping 19 matching lines...) Expand all
162 163
163 AvailableSessionMap::iterator it = LookupAvailableSessionByKey(key); 164 AvailableSessionMap::iterator it = LookupAvailableSessionByKey(key);
164 if (it != available_sessions_.end()) { 165 if (it != available_sessions_.end()) {
165 if (key.Equals(it->second->spdy_session_key())) { 166 if (key.Equals(it->second->spdy_session_key())) {
166 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", FOUND_EXISTING, 167 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", FOUND_EXISTING,
167 SPDY_SESSION_GET_MAX); 168 SPDY_SESSION_GET_MAX);
168 net_log.AddEvent( 169 net_log.AddEvent(
169 NetLogEventType::HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION, 170 NetLogEventType::HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION,
170 it->second->net_log().source().ToEventParametersCallback()); 171 it->second->net_log().source().ToEventParametersCallback());
171 } else { 172 } else {
173 if (!enable_ip_based_pooling)
174 return base::WeakPtr<SpdySession>();
175
172 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", 176 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet",
173 FOUND_EXISTING_FROM_IP_POOL, 177 FOUND_EXISTING_FROM_IP_POOL,
174 SPDY_SESSION_GET_MAX); 178 SPDY_SESSION_GET_MAX);
175 net_log.AddEvent( 179 net_log.AddEvent(
176 NetLogEventType:: 180 NetLogEventType::
177 HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL, 181 HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL,
178 it->second->net_log().source().ToEventParametersCallback()); 182 it->second->net_log().source().ToEventParametersCallback());
179 } 183 }
180 return it->second; 184 return it->second;
181 } 185 }
182 186
187 if (!enable_ip_based_pooling)
188 return base::WeakPtr<SpdySession>();
189
183 // Look up IP addresses from resolver cache. 190 // Look up IP addresses from resolver cache.
184 HostResolver::RequestInfo resolve_info(key.host_port_pair()); 191 HostResolver::RequestInfo resolve_info(key.host_port_pair());
185 AddressList addresses; 192 AddressList addresses;
186 int rv = resolver_->ResolveFromCache(resolve_info, &addresses, net_log); 193 int rv = resolver_->ResolveFromCache(resolve_info, &addresses, net_log);
187 DCHECK_NE(rv, ERR_IO_PENDING); 194 DCHECK_NE(rv, ERR_IO_PENDING);
188 if (rv != OK) 195 if (rv != OK)
189 return base::WeakPtr<SpdySession>(); 196 return base::WeakPtr<SpdySession>();
190 197
191 // Check if we have a session through a domain alias. 198 // Check if we have a session through a domain alias.
192 for (AddressList::const_iterator address_it = addresses.begin(); 199 for (AddressList::const_iterator address_it = addresses.begin();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 } 231 }
225 232
226 UMA_HISTOGRAM_ENUMERATION("Net.SpdyIPPoolDomainMatch", 1, 2); 233 UMA_HISTOGRAM_ENUMERATION("Net.SpdyIPPoolDomainMatch", 1, 2);
227 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", 234 UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet",
228 FOUND_EXISTING_FROM_IP_POOL, 235 FOUND_EXISTING_FROM_IP_POOL,
229 SPDY_SESSION_GET_MAX); 236 SPDY_SESSION_GET_MAX);
230 net_log.AddEvent( 237 net_log.AddEvent(
231 NetLogEventType::HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL, 238 NetLogEventType::HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL,
232 available_session->net_log().source().ToEventParametersCallback()); 239 available_session->net_log().source().ToEventParametersCallback());
233 // Add this session to the map so that we can find it next time. 240 // Add this session to the map so that we can find it next time.
234 MapKeyToAvailableSession(key, available_session); 241 MapKeyToAvailableSession(key, available_session, /* ip_pooled = */ true);
235 available_session->AddPooledAlias(key); 242 available_session->AddPooledAlias(key);
236 return available_session; 243 return available_session;
237 } 244 }
238 245
239 return base::WeakPtr<SpdySession>(); 246 return base::WeakPtr<SpdySession>();
240 } 247 }
241 248
242 void SpdySessionPool::MakeSessionUnavailable( 249 void SpdySessionPool::MakeSessionUnavailable(
243 const base::WeakPtr<SpdySession>& available_session) { 250 const base::WeakPtr<SpdySession>& available_session) {
244 UnmapKey(available_session->spdy_session_key()); 251 // Remove the entry that was added by CreateAvailableSessionFromSocket() under
252 // |available_session|'s proper key.
253 UnmapKey(available_session->spdy_session_key(), /* ip_pooled = */ false);
245 RemoveAliases(available_session->spdy_session_key()); 254 RemoveAliases(available_session->spdy_session_key());
246 const std::set<SpdySessionKey>& aliases = available_session->pooled_aliases(); 255 const std::set<SpdySessionKey>& aliases = available_session->pooled_aliases();
247 for (std::set<SpdySessionKey>::const_iterator it = aliases.begin(); 256 for (std::set<SpdySessionKey>::const_iterator it = aliases.begin();
248 it != aliases.end(); ++it) { 257 it != aliases.end(); ++it) {
249 UnmapKey(*it); 258 // Remove all the pooled entries that map alias keys to this session.
259 UnmapKey(*it, /* ip_pooled = */ true);
250 RemoveAliases(*it); 260 RemoveAliases(*it);
251 } 261 }
252 DCHECK(!IsSessionAvailable(available_session)); 262 DCHECK(!IsSessionAvailable(available_session));
253 } 263 }
254 264
255 void SpdySessionPool::RemoveUnavailableSession( 265 void SpdySessionPool::RemoveUnavailableSession(
256 const base::WeakPtr<SpdySession>& unavailable_session) { 266 const base::WeakPtr<SpdySession>& unavailable_session) {
257 DCHECK(!IsSessionAvailable(unavailable_session)); 267 DCHECK(!IsSessionAvailable(unavailable_session));
258 268
259 unavailable_session->net_log().AddEvent( 269 unavailable_session->net_log().AddEvent(
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 base::trace_event::MemoryAllocatorDump::kUnitsBytes, 430 base::trace_event::MemoryAllocatorDump::kUnitsBytes,
421 buffer_size); 431 buffer_size);
422 dump->AddScalar("cert_count", 432 dump->AddScalar("cert_count",
423 base::trace_event::MemoryAllocatorDump::kUnitsObjects, 433 base::trace_event::MemoryAllocatorDump::kUnitsObjects,
424 cert_count); 434 cert_count);
425 dump->AddScalar("cert_size", 435 dump->AddScalar("cert_size",
426 base::trace_event::MemoryAllocatorDump::kUnitsBytes, 436 base::trace_event::MemoryAllocatorDump::kUnitsBytes,
427 cert_size); 437 cert_size);
428 } 438 }
429 439
440 template <class T, class U>
441 SpdySessionPool::AvailableSessionMap::Iterator<T, U>::Iterator()
442 : ip_pooled_(false), session_map_(nullptr) {}
443
444 template <class T, class U>
445 SpdySessionPool::AvailableSessionMap::Iterator<T, U>::Iterator(
446 const Iterator& other)
447 : iterator_(other.iterator_),
448 ip_pooled_(other.ip_pooled_),
449 session_map_(other.session_map_) {}
450
451 template <class T, class U>
452 void SpdySessionPool::AvailableSessionMap::Iterator<T, U>::operator=(
453 const Iterator& other) {
454 iterator_ = other.iterator_;
455 ip_pooled_ = other.ip_pooled_;
456 session_map_ = other.session_map_;
457 }
458
459 template <class T, class U>
460 SpdySessionPool::AvailableSessionMap::Iterator<T, U>::~Iterator() {}
461
462 // Must return a dereferencable iterator unless both maps are empty.
463 // static
464 template <class T, class U>
465 SpdySessionPool::AvailableSessionMap::Iterator<T, U>
466 SpdySessionPool::AvailableSessionMap::Iterator<T, U>::begin(U* session_map) {
467 if (session_map->non_ip_pooled_sessions_.empty()) {
468 // If |ip_pooled_sessions_| is not empty, this is deferencable.
469 // If |ip_pooled_sessions_| is empty, then |begin() == end()|,
470 // therefore the return value represents AvailableSessionMap::end().
471 return SpdySessionPool::AvailableSessionMap::Iterator<T, U>(
472 session_map->ip_pooled_sessions_.begin(), /* ip_pooled = */ true,
473 session_map);
474 }
475
476 // |non_ip_pooled_sessions_| is not empty, therefore this is dereferencable.
477 return SpdySessionPool::AvailableSessionMap::Iterator<T, U>(
478 session_map->non_ip_pooled_sessions_.begin(), /* ip_pooled = */ false,
479 session_map);
480 }
481
482 // static
483 template <class T, class U>
484 SpdySessionPool::AvailableSessionMap::Iterator<T, U>
485 SpdySessionPool::AvailableSessionMap::Iterator<T, U>::end(U* session_map) {
486 return SpdySessionPool::AvailableSessionMap::Iterator<T, U>(
487 session_map->ip_pooled_sessions_.end(), /* ip_pooled = */ true,
488 session_map);
489 }
490
491 template <class T, class U>
492 bool SpdySessionPool::AvailableSessionMap::Iterator<T, U>::operator==(
493 const SpdySessionPool::AvailableSessionMap::Iterator<T, U>& other) const {
494 // Compare |iterator_| last, because comparing iterators from different
495 // containers results in a runtime error when using debug_map.
496 return session_map_ == other.session_map_ && ip_pooled_ == other.ip_pooled_ &&
497 iterator_ == other.iterator_;
498 }
499
500 template <class T, class U>
501 bool SpdySessionPool::AvailableSessionMap::Iterator<T, U>::operator!=(
502 const SpdySessionPool::AvailableSessionMap::Iterator<T, U>& other) const {
503 return !(*this == other);
504 }
505
506 template <class T, class U>
507 T& SpdySessionPool::AvailableSessionMap::Iterator<T, U>::operator->() {
508 return iterator_;
509 }
510
511 template <class T, class U>
512 SpdySessionPool::AvailableSessionMap::Iterator<T, U>&
513 SpdySessionPool::AvailableSessionMap::Iterator<T, U>::operator++() {
514 // end() is a non-incrementable iterator.
515 DCHECK(*this != session_map_->end());
516
517 ++iterator_;
518
519 // If Iterator is already pointing to an element of |ip_pooled_sessions_|,
520 // then simply incrementing it will get to the next element.
521 if (ip_pooled_)
522 return *this;
523
524 // When the past-the-end iterator is reached in |non_ip_pooled_sessions_|, the
525 // Iterator should start iterating through elements of |ip_pooled_sessions_|,
526 // because every Iterator starting from begin() until end() is reached has to
527 // be dereferencable.
528 if (iterator_ == session_map_->non_ip_pooled_sessions_.end()) {
529 // This gives the correct result even if |ip_pooled_sessions_| is empty: in
530 // that case ip_pooled_sessions_.begin() is the same as
531 // ip_pooled_sessions_.end(), which yields the internal representation of
532 // available_session_map.end().
533 iterator_ = session_map_->ip_pooled_sessions_.begin();
534 ip_pooled_ = true;
535 }
536
537 return *this;
538 }
539
540 template <class T, class U>
541 SpdySessionPool::AvailableSessionMap::Iterator<T, U>::Iterator(T iterator,
542 bool ip_pooled,
543 U* session_map)
544 : iterator_(iterator), ip_pooled_(ip_pooled), session_map_(session_map) {}
545
546 SpdySessionPool::AvailableSessionMap::AvailableSessionMap() {}
547 SpdySessionPool::AvailableSessionMap::~AvailableSessionMap() {}
548
549 SpdySessionPool::AvailableSessionMap::iterator
550 SpdySessionPool::AvailableSessionMap::begin() {
551 return SpdySessionPool::AvailableSessionMap::Iterator<
552 MapType::iterator, AvailableSessionMap>::begin(this);
553 }
554
555 SpdySessionPool::AvailableSessionMap::iterator
556 SpdySessionPool::AvailableSessionMap::end() {
557 return SpdySessionPool::AvailableSessionMap::Iterator<
558 MapType::iterator, AvailableSessionMap>::end(this);
559 }
560
561 SpdySessionPool::AvailableSessionMap::const_iterator
562 SpdySessionPool::AvailableSessionMap::begin() const {
563 return SpdySessionPool::AvailableSessionMap::Iterator<
564 MapType::const_iterator, const AvailableSessionMap>::begin(this);
565 }
566
567 SpdySessionPool::AvailableSessionMap::const_iterator
568 SpdySessionPool::AvailableSessionMap::end() const {
569 return SpdySessionPool::AvailableSessionMap::Iterator<
570 MapType::const_iterator, const AvailableSessionMap>::end(this);
571 }
572
573 bool SpdySessionPool::AvailableSessionMap::empty() const {
574 return non_ip_pooled_sessions_.empty() && ip_pooled_sessions_.empty();
575 }
576
577 SpdySessionPool::AvailableSessionMap::iterator
578 SpdySessionPool::AvailableSessionMap::find(const key_type& key) {
579 MapType::iterator it = non_ip_pooled_sessions_.find(key);
580 if (it != non_ip_pooled_sessions_.end())
581 return SpdySessionPool::AvailableSessionMap::Iterator<
582 MapType::iterator, SpdySessionPool::AvailableSessionMap>(
583 it,
584 /* ip_pooled = */ false, this);
585
586 it = ip_pooled_sessions_.find(key);
587 // If |it == ip_pooled_sessions_.end()|, then this is the internal
588 // representation of AvailableSessionMap::end().
589 return SpdySessionPool::AvailableSessionMap::Iterator<
590 MapType::iterator, SpdySessionPool::AvailableSessionMap>(
591 it, /* ip_pooled = */ true, this);
592 }
593
594 void SpdySessionPool::AvailableSessionMap::insert(const value_type& value,
595 bool ip_pooled) {
596 // A session is non IP pooled with respect to the key
597 // iff the key matches the session's proper key.
598 CHECK_EQ(!ip_pooled, value.first.Equals(value.second->spdy_session_key()));
599
600 // There must not already be an entry with key |value.first| in the map.
601 std::pair<MapType::iterator, bool> result =
602 ip_pooled ? ip_pooled_sessions_.insert(value)
603 : non_ip_pooled_sessions_.insert(value);
604 CHECK(result.second);
605 }
606
607 void SpdySessionPool::AvailableSessionMap::erase(const key_type& key,
608 bool ip_pooled) {
609 // |key| must exist in the map.
610 if (ip_pooled) {
611 MapType::iterator it = ip_pooled_sessions_.find(key);
612 CHECK(it != ip_pooled_sessions_.end());
613 ip_pooled_sessions_.erase(it);
614 } else {
615 MapType::iterator it = non_ip_pooled_sessions_.find(key);
616 CHECK(it != non_ip_pooled_sessions_.end());
617 non_ip_pooled_sessions_.erase(it);
618 }
619 }
620
430 bool SpdySessionPool::IsSessionAvailable( 621 bool SpdySessionPool::IsSessionAvailable(
431 const base::WeakPtr<SpdySession>& session) const { 622 const base::WeakPtr<SpdySession>& session) const {
432 for (AvailableSessionMap::const_iterator it = available_sessions_.begin(); 623 for (AvailableSessionMap::const_iterator it = available_sessions_.begin();
433 it != available_sessions_.end(); ++it) { 624 it != available_sessions_.end(); ++it) {
434 if (it->second.get() == session.get()) 625 if (it->second.get() == session.get())
435 return true; 626 return true;
436 } 627 }
437 return false; 628 return false;
438 } 629 }
439 630
440 void SpdySessionPool::MapKeyToAvailableSession( 631 void SpdySessionPool::MapKeyToAvailableSession(
441 const SpdySessionKey& key, 632 const SpdySessionKey& key,
442 const base::WeakPtr<SpdySession>& session) { 633 const base::WeakPtr<SpdySession>& session,
634 bool ip_pooled) {
443 DCHECK(base::ContainsKey(sessions_, session.get())); 635 DCHECK(base::ContainsKey(sessions_, session.get()));
444 std::pair<AvailableSessionMap::iterator, bool> result = 636 available_sessions_.insert(std::make_pair(key, session), ip_pooled);
445 available_sessions_.insert(std::make_pair(key, session));
446 CHECK(result.second);
447 } 637 }
448 638
449 SpdySessionPool::AvailableSessionMap::iterator 639 SpdySessionPool::AvailableSessionMap::iterator
450 SpdySessionPool::LookupAvailableSessionByKey( 640 SpdySessionPool::LookupAvailableSessionByKey(
451 const SpdySessionKey& key) { 641 const SpdySessionKey& key) {
452 return available_sessions_.find(key); 642 return available_sessions_.find(key);
453 } 643 }
454 644
455 void SpdySessionPool::UnmapKey(const SpdySessionKey& key) { 645 void SpdySessionPool::UnmapKey(const SpdySessionKey& key, bool ip_pooled) {
456 AvailableSessionMap::iterator it = LookupAvailableSessionByKey(key); 646 available_sessions_.erase(key, ip_pooled);
457 CHECK(it != available_sessions_.end());
458 available_sessions_.erase(it);
459 } 647 }
460 648
461 void SpdySessionPool::RemoveAliases(const SpdySessionKey& key) { 649 void SpdySessionPool::RemoveAliases(const SpdySessionKey& key) {
462 // Walk the aliases map, find references to this pair. 650 // Walk the aliases map, find references to this pair.
463 // TODO(mbelshe): Figure out if this is too expensive. 651 // TODO(mbelshe): Figure out if this is too expensive.
464 for (AliasMap::iterator it = aliases_.begin(); it != aliases_.end(); ) { 652 for (AliasMap::iterator it = aliases_.begin(); it != aliases_.end(); ) {
465 if (it->second.Equals(key)) { 653 if (it->second.Equals(key)) {
466 AliasMap::iterator old_it = it; 654 AliasMap::iterator old_it = it;
467 ++it; 655 ++it;
468 aliases_.erase(old_it); 656 aliases_.erase(old_it);
(...skipping 24 matching lines...) Expand all
493 681
494 if (idle_only && (*it)->is_active()) 682 if (idle_only && (*it)->is_active())
495 continue; 683 continue;
496 684
497 (*it)->CloseSessionOnError(error, description); 685 (*it)->CloseSessionOnError(error, description);
498 DCHECK(!IsSessionAvailable(*it)); 686 DCHECK(!IsSessionAvailable(*it));
499 } 687 }
500 } 688 }
501 689
502 } // namespace net 690 } // 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