| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // A ClientSocketPoolBase is used to restrict the number of sockets open at | 5 // A ClientSocketPoolBase is used to restrict the number of sockets open at |
| 6 // a time. It also maintains a list of idle persistent sockets for reuse. | 6 // a time. It also maintains a list of idle persistent sockets for reuse. |
| 7 // Subclasses of ClientSocketPool should compose ClientSocketPoolBase to handle | 7 // Subclasses of ClientSocketPool should compose ClientSocketPoolBase to handle |
| 8 // the core logic of (1) restricting the number of active (connected or | 8 // the core logic of (1) restricting the number of active (connected or |
| 9 // connecting) sockets per "group" (generally speaking, the hostname), (2) | 9 // connecting) sockets per "group" (generally speaking, the hostname), (2) |
| 10 // maintaining a per-group list of idle, persistent sockets for reuse, and (3) | 10 // maintaining a per-group list of idle, persistent sockets for reuse, and (3) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 #include <deque> | 26 #include <deque> |
| 27 #include <list> | 27 #include <list> |
| 28 #include <map> | 28 #include <map> |
| 29 #include <set> | 29 #include <set> |
| 30 #include <string> | 30 #include <string> |
| 31 #include <vector> | 31 #include <vector> |
| 32 | 32 |
| 33 #include "base/basictypes.h" | 33 #include "base/basictypes.h" |
| 34 #include "base/memory/ref_counted.h" | 34 #include "base/memory/ref_counted.h" |
| 35 #include "base/memory/scoped_ptr.h" | 35 #include "base/memory/scoped_ptr.h" |
| 36 #include "base/memory/weak_ptr.h" |
| 36 #include "base/task.h" | 37 #include "base/task.h" |
| 37 #include "base/time.h" | 38 #include "base/time.h" |
| 38 #include "base/timer.h" | 39 #include "base/timer.h" |
| 39 #include "net/base/address_list.h" | 40 #include "net/base/address_list.h" |
| 40 #include "net/base/completion_callback.h" | 41 #include "net/base/completion_callback.h" |
| 41 #include "net/base/load_states.h" | 42 #include "net/base/load_states.h" |
| 42 #include "net/base/net_errors.h" | 43 #include "net/base/net_errors.h" |
| 43 #include "net/base/net_export.h" | 44 #include "net/base/net_export.h" |
| 44 #include "net/base/net_log.h" | 45 #include "net/base/net_log.h" |
| 45 #include "net/base/network_change_notifier.h" | 46 #include "net/base/network_change_notifier.h" |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 // Socket which scores highest on large bytes transferred and low idle time. | 183 // Socket which scores highest on large bytes transferred and low idle time. |
| 183 USE_WARM_SOCKET = 1, | 184 USE_WARM_SOCKET = 1, |
| 184 | 185 |
| 185 // Socket which was most recently used. | 186 // Socket which was most recently used. |
| 186 USE_LAST_ACCESSED_SOCKET = 2, | 187 USE_LAST_ACCESSED_SOCKET = 2, |
| 187 }; | 188 }; |
| 188 | 189 |
| 189 class NET_EXPORT_PRIVATE Request { | 190 class NET_EXPORT_PRIVATE Request { |
| 190 public: | 191 public: |
| 191 Request(ClientSocketHandle* handle, | 192 Request(ClientSocketHandle* handle, |
| 192 OldCompletionCallback* callback, | 193 const CompletionCallback& callback, |
| 193 RequestPriority priority, | 194 RequestPriority priority, |
| 194 bool ignore_limits, | 195 bool ignore_limits, |
| 195 Flags flags, | 196 Flags flags, |
| 196 const BoundNetLog& net_log); | 197 const BoundNetLog& net_log); |
| 197 | 198 |
| 198 virtual ~Request(); | 199 virtual ~Request(); |
| 199 | 200 |
| 200 ClientSocketHandle* handle() const { return handle_; } | 201 ClientSocketHandle* handle() const { return handle_; } |
| 201 OldCompletionCallback* callback() const { return callback_; } | 202 const CompletionCallback& callback() const { return callback_; } |
| 202 RequestPriority priority() const { return priority_; } | 203 RequestPriority priority() const { return priority_; } |
| 203 bool ignore_limits() const { return ignore_limits_; } | 204 bool ignore_limits() const { return ignore_limits_; } |
| 204 Flags flags() const { return flags_; } | 205 Flags flags() const { return flags_; } |
| 205 const BoundNetLog& net_log() const { return net_log_; } | 206 const BoundNetLog& net_log() const { return net_log_; } |
| 206 | 207 |
| 207 private: | 208 private: |
| 208 ClientSocketHandle* const handle_; | 209 ClientSocketHandle* const handle_; |
| 209 OldCompletionCallback* const callback_; | 210 CompletionCallback callback_; |
| 210 const RequestPriority priority_; | 211 const RequestPriority priority_; |
| 211 bool ignore_limits_; | 212 bool ignore_limits_; |
| 212 const Flags flags_; | 213 const Flags flags_; |
| 213 BoundNetLog net_log_; | 214 BoundNetLog net_log_; |
| 214 | 215 |
| 215 DISALLOW_COPY_AND_ASSIGN(Request); | 216 DISALLOW_COPY_AND_ASSIGN(Request); |
| 216 }; | 217 }; |
| 217 | 218 |
| 218 class ConnectJobFactory { | 219 class ConnectJobFactory { |
| 219 public: | 220 public: |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 | 392 |
| 392 bool IsStalled(int max_sockets_per_group) const { | 393 bool IsStalled(int max_sockets_per_group) const { |
| 393 return HasAvailableSocketSlot(max_sockets_per_group) && | 394 return HasAvailableSocketSlot(max_sockets_per_group) && |
| 394 pending_requests_.size() > jobs_.size(); | 395 pending_requests_.size() > jobs_.size(); |
| 395 } | 396 } |
| 396 | 397 |
| 397 RequestPriority TopPendingPriority() const { | 398 RequestPriority TopPendingPriority() const { |
| 398 return pending_requests_.front()->priority(); | 399 return pending_requests_.front()->priority(); |
| 399 } | 400 } |
| 400 | 401 |
| 401 bool HasBackupJob() const { return !method_factory_.empty(); } | 402 bool HasBackupJob() const { return weak_factory_.HasWeakPtrs(); } |
| 402 | 403 |
| 403 void CleanupBackupJob() { | 404 void CleanupBackupJob() { |
| 404 method_factory_.RevokeAll(); | 405 weak_factory_.InvalidateWeakPtrs(); |
| 405 } | 406 } |
| 406 | 407 |
| 407 // Set a timer to create a backup socket if it takes too long to create one. | 408 // Set a timer to create a backup socket if it takes too long to create one. |
| 408 void StartBackupSocketTimer(const std::string& group_name, | 409 void StartBackupSocketTimer(const std::string& group_name, |
| 409 ClientSocketPoolBaseHelper* pool); | 410 ClientSocketPoolBaseHelper* pool); |
| 410 | 411 |
| 411 // Searches |jobs_| to see if there's a preconnect ConnectJob, and if so, | 412 // Searches |jobs_| to see if there's a preconnect ConnectJob, and if so, |
| 412 // uses it. Returns true on success. Otherwise, returns false. | 413 // uses it. Returns true on success. Otherwise, returns false. |
| 413 bool TryToUsePreconnectConnectJob(); | 414 bool TryToUsePreconnectConnectJob(); |
| 414 | 415 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 430 // Called when the backup socket timer fires. | 431 // Called when the backup socket timer fires. |
| 431 void OnBackupSocketTimerFired( | 432 void OnBackupSocketTimerFired( |
| 432 std::string group_name, | 433 std::string group_name, |
| 433 ClientSocketPoolBaseHelper* pool); | 434 ClientSocketPoolBaseHelper* pool); |
| 434 | 435 |
| 435 std::list<IdleSocket> idle_sockets_; | 436 std::list<IdleSocket> idle_sockets_; |
| 436 std::set<ConnectJob*> jobs_; | 437 std::set<ConnectJob*> jobs_; |
| 437 RequestQueue pending_requests_; | 438 RequestQueue pending_requests_; |
| 438 int active_socket_count_; // number of active sockets used by clients | 439 int active_socket_count_; // number of active sockets used by clients |
| 439 // A factory to pin the backup_job tasks. | 440 // A factory to pin the backup_job tasks. |
| 440 ScopedRunnableMethodFactory<Group> method_factory_; | 441 base::WeakPtrFactory<Group> weak_factory_; |
| 441 }; | 442 }; |
| 442 | 443 |
| 443 typedef std::map<std::string, Group*> GroupMap; | 444 typedef std::map<std::string, Group*> GroupMap; |
| 444 | 445 |
| 445 typedef std::set<ConnectJob*> ConnectJobSet; | 446 typedef std::set<ConnectJob*> ConnectJobSet; |
| 446 | 447 |
| 447 struct CallbackResultPair { | 448 struct CallbackResultPair { |
| 448 CallbackResultPair() : callback(NULL), result(OK) {} | 449 CallbackResultPair() : result(OK) {} |
| 449 CallbackResultPair(OldCompletionCallback* callback_in, int result_in) | 450 CallbackResultPair(const CompletionCallback& callback_in, int result_in) |
| 450 : callback(callback_in), result(result_in) {} | 451 : callback(callback_in), result(result_in) {} |
| 452 ~CallbackResultPair(); |
| 451 | 453 |
| 452 OldCompletionCallback* callback; | 454 CompletionCallback callback; |
| 453 int result; | 455 int result; |
| 454 }; | 456 }; |
| 455 | 457 |
| 456 typedef std::map<const ClientSocketHandle*, CallbackResultPair> | 458 typedef std::map<const ClientSocketHandle*, CallbackResultPair> |
| 457 PendingCallbackMap; | 459 PendingCallbackMap; |
| 458 | 460 |
| 459 static void InsertRequestIntoQueue(const Request* r, | 461 static void InsertRequestIntoQueue(const Request* r, |
| 460 RequestQueue* pending_requests); | 462 RequestQueue* pending_requests); |
| 461 static const Request* RemoveRequestFromQueue(const RequestQueue::iterator& it, | 463 static const Request* RemoveRequestFromQueue(const RequestQueue::iterator& it, |
| 462 Group* group); | 464 Group* group); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 bool CloseOneIdleSocketExceptInGroup(const Group* group); | 536 bool CloseOneIdleSocketExceptInGroup(const Group* group); |
| 535 | 537 |
| 536 // Checks if there are stalled socket groups that should be notified | 538 // Checks if there are stalled socket groups that should be notified |
| 537 // for possible wakeup. | 539 // for possible wakeup. |
| 538 void CheckForStalledSocketGroups(); | 540 void CheckForStalledSocketGroups(); |
| 539 | 541 |
| 540 // Posts a task to call InvokeUserCallback() on the next iteration through the | 542 // Posts a task to call InvokeUserCallback() on the next iteration through the |
| 541 // current message loop. Inserts |callback| into |pending_callback_map_|, | 543 // current message loop. Inserts |callback| into |pending_callback_map_|, |
| 542 // keyed by |handle|. | 544 // keyed by |handle|. |
| 543 void InvokeUserCallbackLater( | 545 void InvokeUserCallbackLater( |
| 544 ClientSocketHandle* handle, OldCompletionCallback* callback, int rv); | 546 ClientSocketHandle* handle, const CompletionCallback& callback, int rv); |
| 545 | 547 |
| 546 // Invokes the user callback for |handle|. By the time this task has run, | 548 // Invokes the user callback for |handle|. By the time this task has run, |
| 547 // it's possible that the request has been cancelled, so |handle| may not | 549 // it's possible that the request has been cancelled, so |handle| may not |
| 548 // exist in |pending_callback_map_|. We look up the callback and result code | 550 // exist in |pending_callback_map_|. We look up the callback and result code |
| 549 // in |pending_callback_map_|. | 551 // in |pending_callback_map_|. |
| 550 void InvokeUserCallback(ClientSocketHandle* handle); | 552 void InvokeUserCallback(ClientSocketHandle* handle); |
| 551 | 553 |
| 552 GroupMap group_map_; | 554 GroupMap group_map_; |
| 553 | 555 |
| 554 // Map of the ClientSocketHandles for which we have a pending Task to invoke a | 556 // Map of the ClientSocketHandles for which we have a pending Task to invoke a |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 // TODO(vandebo) Remove when backup jobs move to TransportClientSocketPool | 589 // TODO(vandebo) Remove when backup jobs move to TransportClientSocketPool |
| 588 bool connect_backup_jobs_enabled_; | 590 bool connect_backup_jobs_enabled_; |
| 589 | 591 |
| 590 // A unique id for the pool. It gets incremented every time we Flush() the | 592 // A unique id for the pool. It gets incremented every time we Flush() the |
| 591 // pool. This is so that when sockets get released back to the pool, we can | 593 // pool. This is so that when sockets get released back to the pool, we can |
| 592 // make sure that they are discarded rather than reused. | 594 // make sure that they are discarded rather than reused. |
| 593 int pool_generation_number_; | 595 int pool_generation_number_; |
| 594 | 596 |
| 595 std::set<LayeredPool*> higher_layer_pools_; | 597 std::set<LayeredPool*> higher_layer_pools_; |
| 596 | 598 |
| 597 ScopedRunnableMethodFactory<ClientSocketPoolBaseHelper> method_factory_; | 599 base::WeakPtrFactory<ClientSocketPoolBaseHelper> weak_factory_; |
| 598 | 600 |
| 599 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBaseHelper); | 601 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBaseHelper); |
| 600 }; | 602 }; |
| 601 | 603 |
| 602 } // namespace internal | 604 } // namespace internal |
| 603 | 605 |
| 604 template <typename SocketParams> | 606 template <typename SocketParams> |
| 605 class ClientSocketPoolBase { | 607 class ClientSocketPoolBase { |
| 606 public: | 608 public: |
| 607 class Request : public internal::ClientSocketPoolBaseHelper::Request { | 609 class Request : public internal::ClientSocketPoolBaseHelper::Request { |
| 608 public: | 610 public: |
| 609 Request(ClientSocketHandle* handle, | 611 Request(ClientSocketHandle* handle, |
| 610 OldCompletionCallback* callback, | 612 const CompletionCallback& callback, |
| 611 RequestPriority priority, | 613 RequestPriority priority, |
| 612 internal::ClientSocketPoolBaseHelper::Flags flags, | 614 internal::ClientSocketPoolBaseHelper::Flags flags, |
| 613 bool ignore_limits, | 615 bool ignore_limits, |
| 614 const scoped_refptr<SocketParams>& params, | 616 const scoped_refptr<SocketParams>& params, |
| 615 const BoundNetLog& net_log) | 617 const BoundNetLog& net_log) |
| 616 : internal::ClientSocketPoolBaseHelper::Request( | 618 : internal::ClientSocketPoolBaseHelper::Request( |
| 617 handle, callback, priority, ignore_limits, flags, net_log), | 619 handle, callback, priority, ignore_limits, flags, net_log), |
| 618 params_(params) {} | 620 params_(params) {} |
| 619 | 621 |
| 620 const scoped_refptr<SocketParams>& params() const { return params_; } | 622 const scoped_refptr<SocketParams>& params() const { return params_; } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 667 void RemoveLayeredPool(LayeredPool* pool) { | 669 void RemoveLayeredPool(LayeredPool* pool) { |
| 668 helper_.RemoveLayeredPool(pool); | 670 helper_.RemoveLayeredPool(pool); |
| 669 } | 671 } |
| 670 | 672 |
| 671 // RequestSocket bundles up the parameters into a Request and then forwards to | 673 // RequestSocket bundles up the parameters into a Request and then forwards to |
| 672 // ClientSocketPoolBaseHelper::RequestSocket(). | 674 // ClientSocketPoolBaseHelper::RequestSocket(). |
| 673 int RequestSocket(const std::string& group_name, | 675 int RequestSocket(const std::string& group_name, |
| 674 const scoped_refptr<SocketParams>& params, | 676 const scoped_refptr<SocketParams>& params, |
| 675 RequestPriority priority, | 677 RequestPriority priority, |
| 676 ClientSocketHandle* handle, | 678 ClientSocketHandle* handle, |
| 677 OldCompletionCallback* callback, | 679 const CompletionCallback& callback, |
| 678 const BoundNetLog& net_log) { | 680 const BoundNetLog& net_log) { |
| 679 Request* request = | 681 Request* request = |
| 680 new Request(handle, callback, priority, | 682 new Request(handle, callback, priority, |
| 681 internal::ClientSocketPoolBaseHelper::NORMAL, | 683 internal::ClientSocketPoolBaseHelper::NORMAL, |
| 682 params->ignore_limits(), | 684 params->ignore_limits(), |
| 683 params, net_log); | 685 params, net_log); |
| 684 return helper_.RequestSocket(group_name, request); | 686 return helper_.RequestSocket(group_name, request); |
| 685 } | 687 } |
| 686 | 688 |
| 687 // RequestSockets bundles up the parameters into a Request and then forwards | 689 // RequestSockets bundles up the parameters into a Request and then forwards |
| 688 // to ClientSocketPoolBaseHelper::RequestSockets(). Note that it assigns the | 690 // to ClientSocketPoolBaseHelper::RequestSockets(). Note that it assigns the |
| 689 // priority to LOWEST and specifies the NO_IDLE_SOCKETS flag. | 691 // priority to LOWEST and specifies the NO_IDLE_SOCKETS flag. |
| 690 void RequestSockets(const std::string& group_name, | 692 void RequestSockets(const std::string& group_name, |
| 691 const scoped_refptr<SocketParams>& params, | 693 const scoped_refptr<SocketParams>& params, |
| 692 int num_sockets, | 694 int num_sockets, |
| 693 const BoundNetLog& net_log) { | 695 const BoundNetLog& net_log) { |
| 694 const Request request(NULL /* no handle */, | 696 const Request request(NULL /* no handle */, |
| 695 NULL /* no callback */, | 697 CompletionCallback(), |
| 696 LOWEST, | 698 LOWEST, |
| 697 internal::ClientSocketPoolBaseHelper::NO_IDLE_SOCKETS, | 699 internal::ClientSocketPoolBaseHelper::NO_IDLE_SOCKETS, |
| 698 params->ignore_limits(), | 700 params->ignore_limits(), |
| 699 params, | 701 params, |
| 700 net_log); | 702 net_log); |
| 701 helper_.RequestSockets(group_name, request, num_sockets); | 703 helper_.RequestSockets(group_name, request, num_sockets); |
| 702 } | 704 } |
| 703 | 705 |
| 704 void CancelRequest(const std::string& group_name, | 706 void CancelRequest(const std::string& group_name, |
| 705 ClientSocketHandle* handle) { | 707 ClientSocketHandle* handle) { |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 804 // Histograms for the pool | 806 // Histograms for the pool |
| 805 ClientSocketPoolHistograms* const histograms_; | 807 ClientSocketPoolHistograms* const histograms_; |
| 806 internal::ClientSocketPoolBaseHelper helper_; | 808 internal::ClientSocketPoolBaseHelper helper_; |
| 807 | 809 |
| 808 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); | 810 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); |
| 809 }; | 811 }; |
| 810 | 812 |
| 811 } // namespace net | 813 } // namespace net |
| 812 | 814 |
| 813 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ | 815 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ |
| OLD | NEW |