diff options
Diffstat (limited to 'net/socket/client_socket_pool_base.h')
-rw-r--r-- | net/socket/client_socket_pool_base.h | 108 |
1 files changed, 90 insertions, 18 deletions
diff --git a/net/socket/client_socket_pool_base.h b/net/socket/client_socket_pool_base.h index a39eeaa..6c626f7 100644 --- a/net/socket/client_socket_pool_base.h +++ b/net/socket/client_socket_pool_base.h @@ -76,6 +76,16 @@ class ConnectJob { // Accessors const std::string& group_name() const { return group_name_; } const BoundNetLog& net_log() { return net_log_; } + bool is_preconnect() const { return preconnect_state_ != NOT_PRECONNECT; } + bool is_unused_preconnect() const { + return preconnect_state_ == UNUSED_PRECONNECT; + } + + // Initialized by the ClientSocketPoolBaseHelper. + // TODO(willchan): Move most of the constructor arguments over here. We + // shouldn't give the ConnectJobFactory (subclasses) the ability to screw up + // the initialization. + void Initialize(bool is_preconnect); // Releases |socket_| to the client. On connection error, this should return // NULL. @@ -89,6 +99,10 @@ class ConnectJob { // if it succeeded. int Connect(); + // Precondition: is_unused_preconnect() must be true. Marks the job as a + // used preconnect job. + void UseForNormalRequest(); + virtual LoadState GetLoadState() const = 0; // If Connect returns an error (or OnConnectJobComplete reports an error @@ -105,6 +119,12 @@ class ConnectJob { void ResetTimer(base::TimeDelta remainingTime); private: + enum PreconnectState { + NOT_PRECONNECT, + UNUSED_PRECONNECT, + USED_PRECONNECT, + }; + virtual int ConnectInternal() = 0; void LogConnectStart(); @@ -122,6 +142,7 @@ class ConnectJob { BoundNetLog net_log_; // A ConnectJob is idle until Connect() has been called. bool idle_; + PreconnectState preconnect_state_; DISALLOW_COPY_AND_ASSIGN(ConnectJob); }; @@ -137,11 +158,20 @@ class ClientSocketPoolBaseHelper : public ConnectJob::Delegate, public NetworkChangeNotifier::Observer { public: + // Used to specify specific behavior for the ClientSocketPool. + enum Flag { + NORMAL = 0, // Normal behavior. + NO_IDLE_SOCKETS = 0x1, // Do not return an idle socket. Create a new one. + }; + + typedef uint32 Flags; + class Request { public: Request(ClientSocketHandle* handle, CompletionCallback* callback, RequestPriority priority, + Flags flags, const BoundNetLog& net_log); virtual ~Request(); @@ -149,12 +179,14 @@ class ClientSocketPoolBaseHelper ClientSocketHandle* handle() const { return handle_; } CompletionCallback* callback() const { return callback_; } RequestPriority priority() const { return priority_; } + const Flags flags() const { return flags_; } const BoundNetLog& net_log() const { return net_log_; } private: ClientSocketHandle* const handle_; CompletionCallback* const callback_; const RequestPriority priority_; + const Flags flags_; BoundNetLog net_log_; DISALLOW_COPY_AND_ASSIGN(Request); @@ -190,6 +222,11 @@ class ClientSocketPoolBaseHelper // heap allocated. int RequestSocket(const std::string& group_name, const Request* request); + // See ClientSocketPool::RequestSocket for documentation on this function. + void RequestSockets(const std::string& group_name, + const Request& request, + int num_sockets); + // See ClientSocketPool::CancelRequest for documentation on this function. void CancelRequest(const std::string& group_name, ClientSocketHandle* handle); @@ -234,6 +271,10 @@ class ClientSocketPoolBaseHelper return group_map_.find(group_name)->second->jobs().size(); } + int NumActiveSocketsInGroup(const std::string& group_name) const { + return group_map_.find(group_name)->second->active_socket_count(); + } + bool HasGroup(const std::string& group_name) const; // Closes all idle sockets if |force| is true. Else, only closes idle @@ -271,7 +312,7 @@ class ClientSocketPoolBaseHelper bool ShouldCleanup(base::TimeTicks now, base::TimeDelta timeout) const; }; - typedef std::deque<const Request*> RequestQueue; + typedef std::deque<const Request* > RequestQueue; typedef std::map<const ClientSocketHandle*, const Request*> RequestMap; // A Group is allocated per group_name when there are idle sockets or pending @@ -288,8 +329,12 @@ class ClientSocketPoolBaseHelper } bool HasAvailableSocketSlot(int max_sockets_per_group) const { - return active_socket_count_ + static_cast<int>(jobs_.size()) < - max_sockets_per_group; + return NumActiveSocketSlots() < max_sockets_per_group; + } + + int NumActiveSocketSlots() const { + return active_socket_count_ + static_cast<int>(jobs_.size()) + + static_cast<int>(idle_sockets_.size()); } bool IsStalled(int max_sockets_per_group) const { @@ -311,19 +356,18 @@ class ClientSocketPoolBaseHelper void StartBackupSocketTimer(const std::string& group_name, ClientSocketPoolBaseHelper* pool); - // Called when the backup socket timer fires. - void OnBackupSocketTimerFired( - std::string group_name, - ClientSocketPoolBaseHelper* pool); + // Searches |jobs_| to see if there's a preconnect ConnectJob, and if so, + // uses it. Returns true on success. Otherwise, returns false. + bool TryToUsePreconnectConnectJob(); - void AddJob(const ConnectJob* job) { jobs_.insert(job); } - void RemoveJob(const ConnectJob* job) { jobs_.erase(job); } + void AddJob(ConnectJob* job) { jobs_.insert(job); } + void RemoveJob(ConnectJob* job) { jobs_.erase(job); } void RemoveAllJobs(); void IncrementActiveSocketCount() { active_socket_count_++; } void DecrementActiveSocketCount() { active_socket_count_--; } - const std::set<const ConnectJob*>& jobs() const { return jobs_; } + const std::set<ConnectJob*>& jobs() const { return jobs_; } const std::list<IdleSocket>& idle_sockets() const { return idle_sockets_; } const RequestQueue& pending_requests() const { return pending_requests_; } int active_socket_count() const { return active_socket_count_; } @@ -331,8 +375,13 @@ class ClientSocketPoolBaseHelper std::list<IdleSocket>* mutable_idle_sockets() { return &idle_sockets_; } private: + // Called when the backup socket timer fires. + void OnBackupSocketTimerFired( + std::string group_name, + ClientSocketPoolBaseHelper* pool); + std::list<IdleSocket> idle_sockets_; - std::set<const ConnectJob*> jobs_; + std::set<ConnectJob*> jobs_; RequestQueue pending_requests_; int active_socket_count_; // number of active sockets used by clients // A factory to pin the backup_job tasks. @@ -341,7 +390,7 @@ class ClientSocketPoolBaseHelper typedef std::map<std::string, Group*> GroupMap; - typedef std::set<const ConnectJob*> ConnectJobSet; + typedef std::set<ConnectJob*> ConnectJobSet; struct CallbackResultPair { CallbackResultPair() : callback(NULL), result(OK) {} @@ -381,7 +430,7 @@ class ClientSocketPoolBaseHelper } // Removes |job| from |connect_job_set_|. Also updates |group| if non-NULL. - void RemoveConnectJob(const ConnectJob* job, Group* group); + void RemoveConnectJob(ConnectJob* job, Group* group); // Tries to see if we can handle any more requests for |group|. void OnAvailableSocketSlot(const std::string& group_name, Group* group); @@ -505,16 +554,17 @@ class ClientSocketPoolBase { Request(ClientSocketHandle* handle, CompletionCallback* callback, RequestPriority priority, + internal::ClientSocketPoolBaseHelper::Flags flags, const scoped_refptr<SocketParams>& params, const BoundNetLog& net_log) : internal::ClientSocketPoolBaseHelper::Request( - handle, callback, priority, net_log), + handle, callback, priority, flags, net_log), params_(params) {} const scoped_refptr<SocketParams>& params() const { return params_; } private: - scoped_refptr<SocketParams> params_; + const scoped_refptr<SocketParams> params_; }; class ConnectJobFactory { @@ -556,18 +606,36 @@ class ClientSocketPoolBase { // These member functions simply forward to ClientSocketPoolBaseHelper. // RequestSocket bundles up the parameters into a Request and then forwards to - // ClientSocketPoolBaseHelper::RequestSocket(). Note that the memory - // ownership is transferred in the asynchronous (ERR_IO_PENDING) case. + // ClientSocketPoolBaseHelper::RequestSocket(). int RequestSocket(const std::string& group_name, const scoped_refptr<SocketParams>& params, RequestPriority priority, ClientSocketHandle* handle, CompletionCallback* callback, const BoundNetLog& net_log) { - Request* request = new Request(handle, callback, priority, params, net_log); + Request* request = + new Request(handle, callback, priority, + internal::ClientSocketPoolBaseHelper::NORMAL, + params, net_log); return helper_.RequestSocket(group_name, request); } + // RequestSockets bundles up the parameters into a Request and then forwards + // to ClientSocketPoolBaseHelper::RequestSockets(). Note that it assigns the + // priority to LOWEST and specifies the NO_IDLE_SOCKETS flag. + void RequestSockets(const std::string& group_name, + const scoped_refptr<SocketParams>& params, + int num_sockets, + const BoundNetLog& net_log) { + const Request request(NULL /* no handle */, + NULL /* no callback */, + LOWEST, + internal::ClientSocketPoolBaseHelper::NO_IDLE_SOCKETS, + params, + net_log); + helper_.RequestSockets(group_name, request, num_sockets); + } + void CancelRequest(const std::string& group_name, ClientSocketHandle* handle) { return helper_.CancelRequest(group_name, handle); @@ -599,6 +667,10 @@ class ClientSocketPoolBase { return helper_.NumConnectJobsInGroup(group_name); } + int NumActiveSocketsInGroup(const std::string& group_name) const { + return helper_.NumActiveSocketsInGroup(group_name); + } + bool HasGroup(const std::string& group_name) const { return helper_.HasGroup(group_name); } |