15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NET_SOCKET_CLIENT_SOCKET_POOL_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_SOCKET_CLIENT_SOCKET_POOL_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/template_util.h"
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_states.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_export.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/request_priority.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/host_resolver.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DictionaryValue;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ClientSocketHandle;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ClientSocketPoolHistograms;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class StreamSocket;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ClientSocketPools are layered. This defines an interface for lower level
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// socket pools to communicate with higher layer pools.
343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class NET_EXPORT HigherLayeredPool {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~HigherLayeredPool() {}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Instructs the HigherLayeredPool to close an idle connection. Return true if
393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // one was closed.  Closing an idle connection will call into the lower layer
403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // pool it came from, so must be careful of re-entrancy when using this.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool CloseOneIdleConnection() = 0;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// ClientSocketPools are layered. This defines an interface for higher level
453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// socket pools to communicate with lower layer pools.
463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class NET_EXPORT LowerLayeredPool {
473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~LowerLayeredPool() {}
493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Returns true if a there is currently a request blocked on the per-pool
513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // (not per-host) max socket limit, either in this pool, or one that it is
523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // layered on top of.
533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool IsStalled() const = 0;
543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Called to add or remove a higher layer pool on top of |this|.  A higher
563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // layer pool may be added at most once to |this|, and must be removed prior
573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // to destruction of |this|.
583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void AddHigherLayeredPool(HigherLayeredPool* higher_pool) = 0;
593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) = 0;
603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A ClientSocketPool is used to restrict the number of sockets open at a time.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It also maintains a list of idle persistent sockets.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class NET_EXPORT ClientSocketPool : public LowerLayeredPool {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Subclasses must also have an inner class SocketParams which is
683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // the type for the |params| argument in RequestSocket() and
693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // RequestSockets() below.
703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Requests a connected socket for a group_name.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There are five possible results from calling this function:
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1) RequestSocket returns OK and initializes |handle| with a reused socket.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2) RequestSocket returns OK with a newly connected socket.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3) RequestSocket returns ERR_IO_PENDING.  The handle will be added to a
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // wait list until a socket is available to reuse or a new socket finishes
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connecting.  |priority| will determine the placement into the wait list.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 4) An error occurred early on, so RequestSocket returns an error code.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 5) A recoverable error occurred while setting up the socket.  An error
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // code is returned, but the |handle| is initialized with the new socket.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The caller must recover from the error before using the connection, or
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disconnect the socket before releasing or resetting the |handle|.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The current recoverable errors are: the errors accepted by
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IsCertificateError(err) and PROXY_AUTH_REQUESTED, or
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HTTPS_PROXY_TUNNEL_RESPONSE when reported by HttpProxyClientSocketPool.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If this function returns OK, then |handle| is initialized upon return.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The |handle|'s is_initialized method will return true in this case.  If a
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // StreamSocket was reused, then ClientSocketPool will call
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |handle|->set_reused(true).  In either case, the socket will have been
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // allocated and will be connected.  A client might want to know whether or
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not the socket is reused in order to request a new socket if he encounters
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // an error with the reused socket.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If ERR_IO_PENDING is returned, then the callback will be used to notify the
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // client of completion.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Profiling information for the request is saved to |net_log| if non-NULL.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int RequestSocket(const std::string& group_name,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const void* params,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            RequestPriority priority,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            ClientSocketHandle* handle,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const CompletionCallback& callback,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const BoundNetLog& net_log) = 0;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // RequestSockets is used to request that |num_sockets| be connected in the
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection group for |group_name|.  If the connection group already has
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |num_sockets| idle sockets / active sockets / currently connecting sockets,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // then this function doesn't do anything.  Otherwise, it will start up as
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // many connections as necessary to reach |num_sockets| total sockets for the
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // group.  It uses |params| to control how to connect the sockets.   The
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ClientSocketPool will assign a priority to the new connections, if any.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This priority will probably be lower than all others, since this method
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is intended to make sure ahead of time that |num_sockets| sockets are
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // available to talk to a host.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RequestSockets(const std::string& group_name,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const void* params,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              int num_sockets,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const BoundNetLog& net_log) = 0;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called to cancel a RequestSocket call that returned ERR_IO_PENDING.  The
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // same handle parameter must be passed to this method as was passed to the
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // RequestSocket call being cancelled.  The associated CompletionCallback is
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not run.  However, for performance, we will let one ConnectJob complete
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and go idle.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CancelRequest(const std::string& group_name,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ClientSocketHandle* handle) = 0;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called to release a socket once the socket is no longer needed.  If the
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // socket still has an established connection, then it will be added to the
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // set of idle sockets to be used to satisfy future RequestSocket calls.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Otherwise, the StreamSocket is destroyed.  |id| is used to differentiate
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // between updated versions of the same pool instance.  The pool's id will
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // change when it flushes, so it can use this |id| to discard sockets with
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mismatched ids.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ReleaseSocket(const std::string& group_name,
1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             scoped_ptr<StreamSocket> socket,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int id) = 0;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This flushes all state from the ClientSocketPool.  This means that all
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // idle and connecting sockets are discarded with the given |error|.
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Active sockets being held by ClientSocketPool clients will be discarded
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // when released back to the pool.
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Does not flush any pools wrapped by |this|.
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FlushWithError(int error) = 0;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called to close any idle connections held by the connection manager.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CloseIdleSockets() = 0;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The total number of idle sockets in the pool.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int IdleSocketCount() const = 0;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The total number of idle sockets in a connection group.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int IdleSocketCountInGroup(const std::string& group_name) const = 0;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Determine the LoadState of a connecting ClientSocketHandle.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual LoadState GetLoadState(const std::string& group_name,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const ClientSocketHandle* handle) const = 0;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieves information on the current state of the pool as a
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DictionaryValue.  Caller takes possession of the returned value.
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If |include_nested_pools| is true, the states of any nested
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ClientSocketPools will be included.
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual base::DictionaryValue* GetInfoAsValue(
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& name,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& type,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool include_nested_pools) const = 0;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the maximum amount of time to wait before retrying a connect.
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kMaxConnectRetryIntervalMs = 250;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The set of histograms specific to this pool.  We can't use the standard
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UMA_HISTOGRAM_* macros because they are callsite static.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ClientSocketPoolHistograms* histograms() const = 0;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static base::TimeDelta unused_idle_socket_timeout();
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void set_unused_idle_socket_timeout(base::TimeDelta timeout);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static base::TimeDelta used_idle_socket_timeout();
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void set_used_idle_socket_timeout(base::TimeDelta timeout);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketPool();
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ClientSocketPool();
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return the connection timeout for this pool.
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual base::TimeDelta ConnectionTimeout() const = 0;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ClientSocketPool);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)template <typename PoolType>
1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void RequestSocketsForPool(
1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    PoolType* pool,
1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::string& group_name,
1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const scoped_refptr<typename PoolType::SocketParams>& params,
1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    int num_sockets,
2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const BoundNetLog& net_log) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pool->RequestSockets(group_name, &params, num_sockets, net_log);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // NET_SOCKET_CLIENT_SOCKET_POOL_H_
207