1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NET_SOCKET_CLIENT_SOCKET_HANDLE_H_ 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NET_SOCKET_CLIENT_SOCKET_HANDLE_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string> 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h" 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/time.h" 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/completion_callback.h" 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/load_states.h" 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/net_errors.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log.h" 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/request_priority.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_response_info.h" 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/client_socket.h" 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/client_socket_pool.h" 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net { 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A container for a ClientSocket. 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The handle's |group_name| uniquely identifies the origin and type of the 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// connection. It is used by the ClientSocketPool to group similar connected 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// client socket objects. 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ClientSocketHandle { 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen enum SocketReuseType { 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott UNUSED = 0, // unused socket that just finished connecting 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott UNUSED_IDLE, // unused socket that has been idle for awhile 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott REUSED_IDLE, // previously used socket 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NUM_TYPES, 3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen }; 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ClientSocketHandle(); 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~ClientSocketHandle(); 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Initializes a ClientSocketHandle object, which involves talking to the 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ClientSocketPool to obtain a connected socket, possibly reusing one. This 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // method returns either OK or ERR_IO_PENDING. On ERR_IO_PENDING, |priority| 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // is used to determine the placement in ClientSocketPool's wait list. 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If this method succeeds, then the socket member will be set to an existing 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // connected socket if an existing connected socket was available to reuse, 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // otherwise it will be set to a new connected socket. Consumers can then 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // call is_reused() to see if the socket was reused. If not reusing an 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // existing socket, ClientSocketPool may need to establish a new 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // connection using |socket_params|. 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This method returns ERR_IO_PENDING if it cannot complete synchronously, in 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // which case the consumer will be notified of completion via |callback|. 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If the pool was not able to reuse an existing socket, the new socket 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // may report a recoverable error. In this case, the return value will 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // indicate an error and the socket member will be set. If it is determined 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // that the error is not recoverable, the Disconnect method should be used 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // on the socket, so that it does not get reused. 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // A non-recoverable error may set additional state in the ClientSocketHandle 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to allow the caller to determine what went wrong. 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Init may be called multiple times. 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Profiling information for the request is saved to |net_log| if non-NULL. 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott template <typename SocketParams, typename PoolType> 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int Init(const std::string& group_name, 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const scoped_refptr<SocketParams>& socket_params, 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RequestPriority priority, 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallback* callback, 773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PoolType* pool, 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& net_log); 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // An initialized handle can be reset, which causes it to return to the 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // un-initialized state. This releases the underlying socket, which in the 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // case of a socket that still has an established connection, indicates that 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the socket may be kept alive for use by a subsequent ClientSocketHandle. 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // NOTE: To prevent the socket from being kept alive, be sure to call its 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Disconnect method. This will result in the ClientSocketPool deleting the 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ClientSocket. 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Reset(); 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Used after Init() is called, but before the ClientSocketPool has 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // initialized the ClientSocketHandle. 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LoadState GetLoadState() const; 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns true when Init() has completed successfully. 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool is_initialized() const { return is_initialized_; } 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns the time tick when Init() was called. 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::TimeTicks init_time() const { return init_time_; } 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the time between Init() and when is_initialized() becomes true. 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::TimeDelta setup_time() const { return setup_time_; } 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Used by ClientSocketPool to initialize the ClientSocketHandle. 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void set_is_reused(bool is_reused) { is_reused_ = is_reused; } 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void set_socket(ClientSocket* s) { socket_.reset(s); } 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void set_idle_time(base::TimeDelta idle_time) { idle_time_ = idle_time; } 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_pool_id(int id) { pool_id_ = id; } 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_is_ssl_error(bool is_ssl_error) { is_ssl_error_ = is_ssl_error; } 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_ssl_error_response_info(const HttpResponseInfo& ssl_error_state) { 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ssl_error_response_info_ = ssl_error_state; 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void set_pending_http_proxy_connection(ClientSocketHandle* connection) { 1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick pending_http_proxy_connection_.reset(connection); 1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Only valid if there is no |socket_|. 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool is_ssl_error() const { 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(socket_.get() == NULL); 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return is_ssl_error_; 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // On an ERR_PROXY_AUTH_REQUESTED error, the |headers| and |auth_challenge| 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // fields are filled in. On an ERR_SSL_CLIENT_AUTH_CERT_NEEDED error, 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the |cert_request_info| field is set. 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const HttpResponseInfo& ssl_error_response_info() const { 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ssl_error_response_info_; 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ClientSocketHandle* release_pending_http_proxy_connection() { 1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return pending_http_proxy_connection_.release(); 1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // These may only be used if is_initialized() is true. 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string& group_name() const { return group_name_; } 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int id() const { return pool_id_; } 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ClientSocket* socket() { return socket_.get(); } 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ClientSocket* release_socket() { return socket_.release(); } 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool is_reused() const { return is_reused_; } 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::TimeDelta idle_time() const { return idle_time_; } 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SocketReuseType reuse_type() const { 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (is_reused()) { 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return REUSED_IDLE; 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else if (idle_time() == base::TimeDelta()) { 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return UNUSED; 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return UNUSED_IDLE; 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Called on asynchronous completion of an Init() request. 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void OnIOComplete(int result); 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Called on completion (both asynchronous & synchronous) of an Init() 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // request. 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void HandleInitCompletion(int result); 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Resets the state of the ClientSocketHandle. |cancel| indicates whether or 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // not to try to cancel the request with the ClientSocketPool. Does not 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // reset the supplemental error state. 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void ResetInternal(bool cancel); 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Resets the supplemental error state. 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ResetErrorState(); 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool is_initialized_; 1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ClientSocketPool* pool_; 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<ClientSocket> socket_; 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string group_name_; 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool is_reused_; 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallbackImpl<ClientSocketHandle> callback_; 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallback* user_callback_; 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::TimeDelta idle_time_; 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int pool_id_; // See ClientSocketPool::ReleaseSocket() for an explanation. 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool is_ssl_error_; 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpResponseInfo ssl_error_response_info_; 1753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<ClientSocketHandle> pending_http_proxy_connection_; 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::TimeTicks init_time_; 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::TimeDelta setup_time_; 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NetLog::Source requesting_source_; 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(ClientSocketHandle); 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Template function implementation: 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <typename SocketParams, typename PoolType> 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint ClientSocketHandle::Init(const std::string& group_name, 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const scoped_refptr<SocketParams>& socket_params, 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RequestPriority priority, 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallback* callback, 1903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PoolType* pool, 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BoundNetLog& net_log) { 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch requesting_source_ = net_log.source(); 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CHECK(!group_name.empty()); 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note that this will result in a compile error if the SocketParams has not 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // been registered for the PoolType via REGISTER_SOCKET_PARAMS_FOR_POOL 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (defined in client_socket_pool.h). 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CheckIsValidSocketParamsForPool<PoolType, SocketParams>(); 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ResetInternal(true); 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ResetErrorState(); 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pool_ = pool; 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott group_name_ = group_name; 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott init_time_ = base::TimeTicks::Now(); 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int rv = pool_->RequestSocket( 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch group_name, &socket_params, priority, this, &callback_, net_log); 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv == ERR_IO_PENDING) { 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott user_callback_ = callback; 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HandleInitCompletion(rv); 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return rv; 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace net 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // NET_SOCKET_CLIENT_SOCKET_HANDLE_H_ 217