• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/flip/flip_session_pool.h"
6 
7 #include "base/logging.h"
8 #include "net/flip/flip_session.h"
9 
10 namespace net {
11 
12 // The maximum number of sessions to open to a single domain.
13 static const size_t kMaxSessionsPerDomain = 1;
14 
FlipSessionPool()15 FlipSessionPool::FlipSessionPool() {}
~FlipSessionPool()16 FlipSessionPool::~FlipSessionPool() {
17   CloseAllSessions();
18 }
19 
Get(const HostResolver::RequestInfo & info,HttpNetworkSession * session)20 scoped_refptr<FlipSession> FlipSessionPool::Get(
21     const HostResolver::RequestInfo& info, HttpNetworkSession* session) {
22   const std::string& domain = info.hostname();
23   scoped_refptr<FlipSession> flip_session;
24   FlipSessionList* list = GetSessionList(domain);
25   if (list) {
26     if (list->size() >= kMaxSessionsPerDomain) {
27       flip_session = list->front();
28       list->pop_front();
29     }
30   } else {
31     list = AddSessionList(domain);
32   }
33 
34   DCHECK(list);
35   if (!flip_session)
36     flip_session = new FlipSession(domain, session);
37 
38   DCHECK(flip_session);
39   list->push_back(flip_session);
40   DCHECK(list->size() <= kMaxSessionsPerDomain);
41   return flip_session;
42 }
43 
GetFlipSessionFromSocket(const HostResolver::RequestInfo & info,HttpNetworkSession * session,ClientSocketHandle * connection)44 scoped_refptr<FlipSession> FlipSessionPool::GetFlipSessionFromSocket(
45     const HostResolver::RequestInfo& info,
46     HttpNetworkSession* session,
47     ClientSocketHandle* connection) {
48   const std::string& domain = info.hostname();
49   FlipSessionList* list = GetSessionList(domain);
50   if (!list)
51     list = AddSessionList(domain);
52   DCHECK(list->empty());
53   scoped_refptr<FlipSession> flip_session(new FlipSession(domain, session));
54   flip_session->InitializeWithSocket(connection);
55   list->push_back(flip_session);
56   return flip_session;
57 }
58 
HasSession(const HostResolver::RequestInfo & info) const59 bool FlipSessionPool::HasSession(const HostResolver::RequestInfo& info) const {
60   const std::string& domain = info.hostname();
61   if (GetSessionList(domain))
62     return true;
63   return false;
64 }
65 
Remove(const scoped_refptr<FlipSession> & session)66 void FlipSessionPool::Remove(const scoped_refptr<FlipSession>& session) {
67   std::string domain = session->domain();
68   FlipSessionList* list = GetSessionList(domain);
69   CHECK(list);
70   list->remove(session);
71   if (list->empty())
72     RemoveSessionList(domain);
73 }
74 
75 FlipSessionPool::FlipSessionList*
AddSessionList(const std::string & domain)76     FlipSessionPool::AddSessionList(const std::string& domain) {
77   DCHECK(sessions_.find(domain) == sessions_.end());
78   return sessions_[domain] = new FlipSessionList();
79 }
80 
81 FlipSessionPool::FlipSessionList*
GetSessionList(const std::string & domain)82     FlipSessionPool::GetSessionList(const std::string& domain) {
83   FlipSessionsMap::iterator it = sessions_.find(domain);
84   if (it == sessions_.end())
85     return NULL;
86   return it->second;
87 }
88 
89 const FlipSessionPool::FlipSessionList*
GetSessionList(const std::string & domain) const90     FlipSessionPool::GetSessionList(const std::string& domain) const {
91   FlipSessionsMap::const_iterator it = sessions_.find(domain);
92   if (it == sessions_.end())
93     return NULL;
94   return it->second;
95 }
96 
RemoveSessionList(const std::string & domain)97 void FlipSessionPool::RemoveSessionList(const std::string& domain) {
98   FlipSessionList* list = GetSessionList(domain);
99   if (list) {
100     delete list;
101     sessions_.erase(domain);
102   } else {
103     DCHECK(false) << "removing orphaned session list";
104   }
105 }
106 
CloseAllSessions()107 void FlipSessionPool::CloseAllSessions() {
108   while (sessions_.size()) {
109     FlipSessionList* list = sessions_.begin()->second;
110     DCHECK(list);
111     sessions_.erase(sessions_.begin()->first);
112     while (list->size()) {
113       scoped_refptr<FlipSession> session = list->front();
114       list->pop_front();
115       session->CloseAllStreams(net::ERR_ABORTED);
116     }
117     delete list;
118   }
119 }
120 
121 }  // namespace net
122