Home | History | Annotate | Download | only in flip
      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 
     15 FlipSessionPool::FlipSessionPool() {}
     16 FlipSessionPool::~FlipSessionPool() {
     17   CloseAllSessions();
     18 }
     19 
     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 
     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 
     59 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 
     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*
     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*
     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*
     90     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 
     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 
    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