Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: net/socket/client_socket_pool_base.h

Issue 10026024: Attempting to re-land a small portion of this change... Simply add links from (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix willchan's nit Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/socket/client_socket_pool.cc ('k') | net/socket/client_socket_pool_base.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 10 matching lines...) Expand all
21 // 21 //
22 #ifndef NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ 22 #ifndef NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_
23 #define NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ 23 #define NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_
24 #pragma once 24 #pragma once
25 25
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 32
32 #include "base/basictypes.h" 33 #include "base/basictypes.h"
33 #include "base/memory/ref_counted.h" 34 #include "base/memory/ref_counted.h"
34 #include "base/memory/scoped_ptr.h" 35 #include "base/memory/scoped_ptr.h"
35 #include "base/memory/weak_ptr.h" 36 #include "base/memory/weak_ptr.h"
36 #include "base/time.h" 37 #include "base/time.h"
37 #include "base/timer.h" 38 #include "base/timer.h"
38 #include "net/base/address_list.h" 39 #include "net/base/address_list.h"
39 #include "net/base/completion_callback.h" 40 #include "net/base/completion_callback.h"
40 #include "net/base/load_states.h" 41 #include "net/base/load_states.h"
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 233
233 ClientSocketPoolBaseHelper( 234 ClientSocketPoolBaseHelper(
234 int max_sockets, 235 int max_sockets,
235 int max_sockets_per_group, 236 int max_sockets_per_group,
236 base::TimeDelta unused_idle_socket_timeout, 237 base::TimeDelta unused_idle_socket_timeout,
237 base::TimeDelta used_idle_socket_timeout, 238 base::TimeDelta used_idle_socket_timeout,
238 ConnectJobFactory* connect_job_factory); 239 ConnectJobFactory* connect_job_factory);
239 240
240 virtual ~ClientSocketPoolBaseHelper(); 241 virtual ~ClientSocketPoolBaseHelper();
241 242
243 // Adds/Removes layered pools. It is expected in the destructor that no
244 // layered pools remain.
245 void AddLayeredPool(LayeredPool* pool);
246 void RemoveLayeredPool(LayeredPool* pool);
247
242 // See ClientSocketPool::RequestSocket for documentation on this function. 248 // See ClientSocketPool::RequestSocket for documentation on this function.
243 // ClientSocketPoolBaseHelper takes ownership of |request|, which must be 249 // ClientSocketPoolBaseHelper takes ownership of |request|, which must be
244 // heap allocated. 250 // heap allocated.
245 int RequestSocket(const std::string& group_name, const Request* request); 251 int RequestSocket(const std::string& group_name, const Request* request);
246 252
247 // See ClientSocketPool::RequestSocket for documentation on this function. 253 // See ClientSocketPool::RequestSocket for documentation on this function.
248 void RequestSockets(const std::string& group_name, 254 void RequestSockets(const std::string& group_name,
249 const Request& request, 255 const Request& request,
250 int num_sockets); 256 int num_sockets);
251 257
252 // See ClientSocketPool::CancelRequest for documentation on this function. 258 // See ClientSocketPool::CancelRequest for documentation on this function.
253 void CancelRequest(const std::string& group_name, 259 void CancelRequest(const std::string& group_name,
254 ClientSocketHandle* handle); 260 ClientSocketHandle* handle);
255 261
256 // See ClientSocketPool::ReleaseSocket for documentation on this function. 262 // See ClientSocketPool::ReleaseSocket for documentation on this function.
257 void ReleaseSocket(const std::string& group_name, 263 void ReleaseSocket(const std::string& group_name,
258 StreamSocket* socket, 264 StreamSocket* socket,
259 int id); 265 int id);
260 266
261 // See ClientSocketPool::Flush for documentation on this function. 267 // See ClientSocketPool::Flush for documentation on this function.
262 void Flush(); 268 void Flush();
263 269
270 // See ClientSocketPool::IsStalled for documentation on this function.
271 bool IsStalled() const;
272
264 // See ClientSocketPool::CloseIdleSockets for documentation on this function. 273 // See ClientSocketPool::CloseIdleSockets for documentation on this function.
265 void CloseIdleSockets(); 274 void CloseIdleSockets();
266 275
267 // See ClientSocketPool::IdleSocketCount() for documentation on this function. 276 // See ClientSocketPool::IdleSocketCount() for documentation on this function.
268 int idle_socket_count() const { 277 int idle_socket_count() const {
269 return idle_socket_count_; 278 return idle_socket_count_;
270 } 279 }
271 280
272 // See ClientSocketPool::IdleSocketCountInGroup() for documentation on this 281 // See ClientSocketPool::IdleSocketCountInGroup() for documentation on this
273 // function. 282 // function.
(...skipping 25 matching lines...) Expand all
299 // by kCleanupInterval are cleaned up using a timer. Otherwise they are 308 // by kCleanupInterval are cleaned up using a timer. Otherwise they are
300 // closed next time client makes a request. This may reduce network 309 // closed next time client makes a request. This may reduce network
301 // activity and power consumption. 310 // activity and power consumption.
302 static bool cleanup_timer_enabled(); 311 static bool cleanup_timer_enabled();
303 static bool set_cleanup_timer_enabled(bool enabled); 312 static bool set_cleanup_timer_enabled(bool enabled);
304 313
305 // Closes all idle sockets if |force| is true. Else, only closes idle 314 // Closes all idle sockets if |force| is true. Else, only closes idle
306 // sockets that timed out or can't be reused. Made public for testing. 315 // sockets that timed out or can't be reused. Made public for testing.
307 void CleanupIdleSockets(bool force); 316 void CleanupIdleSockets(bool force);
308 317
318 // Closes one idle socket. Picks the first one encountered.
319 // TODO(willchan): Consider a better algorithm for doing this. Perhaps we
320 // should keep an ordered list of idle sockets, and close them in order.
321 // Requires maintaining more state. It's not clear if it's worth it since
322 // I'm not sure if we hit this situation often.
323 bool CloseOneIdleSocket();
324
325 // Checks layered pools to see if they can close an idle connection.
326 bool CloseOneIdleConnectionInLayeredPool();
327
309 // See ClientSocketPool::GetInfoAsValue for documentation on this function. 328 // See ClientSocketPool::GetInfoAsValue for documentation on this function.
310 base::DictionaryValue* GetInfoAsValue(const std::string& name, 329 base::DictionaryValue* GetInfoAsValue(const std::string& name,
311 const std::string& type) const; 330 const std::string& type) const;
312 331
313 base::TimeDelta ConnectionTimeout() const { 332 base::TimeDelta ConnectionTimeout() const {
314 return connect_job_factory_->ConnectionTimeout(); 333 return connect_job_factory_->ConnectionTimeout();
315 } 334 }
316 335
317 static bool connect_backup_jobs_enabled(); 336 static bool connect_backup_jobs_enabled();
318 static bool set_connect_backup_jobs_enabled(bool enabled); 337 static bool set_connect_backup_jobs_enabled(bool enabled);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 383
365 bool HasAvailableSocketSlot(int max_sockets_per_group) const { 384 bool HasAvailableSocketSlot(int max_sockets_per_group) const {
366 return NumActiveSocketSlots() < max_sockets_per_group; 385 return NumActiveSocketSlots() < max_sockets_per_group;
367 } 386 }
368 387
369 int NumActiveSocketSlots() const { 388 int NumActiveSocketSlots() const {
370 return active_socket_count_ + static_cast<int>(jobs_.size()) + 389 return active_socket_count_ + static_cast<int>(jobs_.size()) +
371 static_cast<int>(idle_sockets_.size()); 390 static_cast<int>(idle_sockets_.size());
372 } 391 }
373 392
374 bool IsStalled(int max_sockets_per_group) const { 393 bool IsStalledOnPoolMaxSockets(int max_sockets_per_group) const {
375 return HasAvailableSocketSlot(max_sockets_per_group) && 394 return HasAvailableSocketSlot(max_sockets_per_group) &&
376 pending_requests_.size() > jobs_.size(); 395 pending_requests_.size() > jobs_.size();
377 } 396 }
378 397
379 RequestPriority TopPendingPriority() const { 398 RequestPriority TopPendingPriority() const {
380 return pending_requests_.front()->priority(); 399 return pending_requests_.front()->priority();
381 } 400 }
382 401
383 bool HasBackupJob() const { return weak_factory_.HasWeakPtrs(); } 402 bool HasBackupJob() const { return weak_factory_.HasWeakPtrs(); }
384 403
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 469
451 // Called when the number of idle sockets changes. 470 // Called when the number of idle sockets changes.
452 void IncrementIdleCount(); 471 void IncrementIdleCount();
453 void DecrementIdleCount(); 472 void DecrementIdleCount();
454 473
455 // Start cleanup timer for idle sockets. 474 // Start cleanup timer for idle sockets.
456 void StartIdleSocketTimer(); 475 void StartIdleSocketTimer();
457 476
458 // Scans the group map for groups which have an available socket slot and 477 // Scans the group map for groups which have an available socket slot and
459 // at least one pending request. Returns true if any groups are stalled, and 478 // at least one pending request. Returns true if any groups are stalled, and
460 // if so, fills |group| and |group_name| with data of the stalled group 479 // if so (and if both |group| and |group_name| are not NULL), fills |group|
461 // having highest priority. 480 // and |group_name| with data of the stalled group having highest priority.
462 bool FindTopStalledGroup(Group** group, std::string* group_name); 481 bool FindTopStalledGroup(Group** group, std::string* group_name) const;
463 482
464 // Called when timer_ fires. This method scans the idle sockets removing 483 // Called when timer_ fires. This method scans the idle sockets removing
465 // sockets that timed out or can't be reused. 484 // sockets that timed out or can't be reused.
466 void OnCleanupTimerFired() { 485 void OnCleanupTimerFired() {
467 CleanupIdleSockets(false); 486 CleanupIdleSockets(false);
468 } 487 }
469 488
470 // Removes |job| from |connect_job_set_|. Also updates |group| if non-NULL. 489 // Removes |job| from |connect_job_set_|. Also updates |group| if non-NULL.
471 void RemoveConnectJob(ConnectJob* job, Group* group); 490 void RemoveConnectJob(ConnectJob* job, Group* group);
472 491
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 int RequestSocketInternal(const std::string& group_name, 523 int RequestSocketInternal(const std::string& group_name,
505 const Request* request); 524 const Request* request);
506 525
507 // Assigns an idle socket for the group to the request. 526 // Assigns an idle socket for the group to the request.
508 // Returns |true| if an idle socket is available, false otherwise. 527 // Returns |true| if an idle socket is available, false otherwise.
509 bool AssignIdleSocketToGroup(const Request* request, Group* group); 528 bool AssignIdleSocketToGroup(const Request* request, Group* group);
510 529
511 static void LogBoundConnectJobToRequest( 530 static void LogBoundConnectJobToRequest(
512 const NetLog::Source& connect_job_source, const Request* request); 531 const NetLog::Source& connect_job_source, const Request* request);
513 532
514 // Closes one idle socket. Picks the first one encountered.
515 // TODO(willchan): Consider a better algorithm for doing this. Perhaps we
516 // should keep an ordered list of idle sockets, and close them in order.
517 // Requires maintaining more state. It's not clear if it's worth it since
518 // I'm not sure if we hit this situation often.
519 void CloseOneIdleSocket();
520
521 // Same as CloseOneIdleSocket() except it won't close an idle socket in 533 // Same as CloseOneIdleSocket() except it won't close an idle socket in
522 // |group|. If |group| is NULL, it is ignored. Returns true if it closed a 534 // |group|. If |group| is NULL, it is ignored. Returns true if it closed a
523 // socket. 535 // socket.
524 bool CloseOneIdleSocketExceptInGroup(const Group* group); 536 bool CloseOneIdleSocketExceptInGroup(const Group* group);
525 537
526 // Checks if there are stalled socket groups that should be notified 538 // Checks if there are stalled socket groups that should be notified
527 // for possible wakeup. 539 // for possible wakeup.
528 void CheckForStalledSocketGroups(); 540 void CheckForStalledSocketGroups();
529 541
530 // 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
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 const scoped_ptr<ConnectJobFactory> connect_job_factory_; 587 const scoped_ptr<ConnectJobFactory> connect_job_factory_;
576 588
577 // TODO(vandebo) Remove when backup jobs move to TransportClientSocketPool 589 // TODO(vandebo) Remove when backup jobs move to TransportClientSocketPool
578 bool connect_backup_jobs_enabled_; 590 bool connect_backup_jobs_enabled_;
579 591
580 // 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
581 // 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
582 // make sure that they are discarded rather than reused. 594 // make sure that they are discarded rather than reused.
583 int pool_generation_number_; 595 int pool_generation_number_;
584 596
597 std::set<LayeredPool*> higher_layer_pools_;
598
585 base::WeakPtrFactory<ClientSocketPoolBaseHelper> weak_factory_; 599 base::WeakPtrFactory<ClientSocketPoolBaseHelper> weak_factory_;
586 600
587 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBaseHelper); 601 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBaseHelper);
588 }; 602 };
589 603
590 } // namespace internal 604 } // namespace internal
591 605
592 template <typename SocketParams> 606 template <typename SocketParams>
593 class ClientSocketPoolBase { 607 class ClientSocketPoolBase {
594 public: 608 public:
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 base::TimeDelta used_idle_socket_timeout, 655 base::TimeDelta used_idle_socket_timeout,
642 ConnectJobFactory* connect_job_factory) 656 ConnectJobFactory* connect_job_factory)
643 : histograms_(histograms), 657 : histograms_(histograms),
644 helper_(max_sockets, max_sockets_per_group, 658 helper_(max_sockets, max_sockets_per_group,
645 unused_idle_socket_timeout, used_idle_socket_timeout, 659 unused_idle_socket_timeout, used_idle_socket_timeout,
646 new ConnectJobFactoryAdaptor(connect_job_factory)) {} 660 new ConnectJobFactoryAdaptor(connect_job_factory)) {}
647 661
648 virtual ~ClientSocketPoolBase() {} 662 virtual ~ClientSocketPoolBase() {}
649 663
650 // These member functions simply forward to ClientSocketPoolBaseHelper. 664 // These member functions simply forward to ClientSocketPoolBaseHelper.
665 void AddLayeredPool(LayeredPool* pool) {
666 helper_.AddLayeredPool(pool);
667 }
668
669 void RemoveLayeredPool(LayeredPool* pool) {
670 helper_.RemoveLayeredPool(pool);
671 }
651 672
652 // 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
653 // ClientSocketPoolBaseHelper::RequestSocket(). 674 // ClientSocketPoolBaseHelper::RequestSocket().
654 int RequestSocket(const std::string& group_name, 675 int RequestSocket(const std::string& group_name,
655 const scoped_refptr<SocketParams>& params, 676 const scoped_refptr<SocketParams>& params,
656 RequestPriority priority, 677 RequestPriority priority,
657 ClientSocketHandle* handle, 678 ClientSocketHandle* handle,
658 const CompletionCallback& callback, 679 const CompletionCallback& callback,
659 const BoundNetLog& net_log) { 680 const BoundNetLog& net_log) {
660 Request* request = 681 Request* request =
(...skipping 24 matching lines...) Expand all
685 void CancelRequest(const std::string& group_name, 706 void CancelRequest(const std::string& group_name,
686 ClientSocketHandle* handle) { 707 ClientSocketHandle* handle) {
687 return helper_.CancelRequest(group_name, handle); 708 return helper_.CancelRequest(group_name, handle);
688 } 709 }
689 710
690 void ReleaseSocket(const std::string& group_name, StreamSocket* socket, 711 void ReleaseSocket(const std::string& group_name, StreamSocket* socket,
691 int id) { 712 int id) {
692 return helper_.ReleaseSocket(group_name, socket, id); 713 return helper_.ReleaseSocket(group_name, socket, id);
693 } 714 }
694 715
716 void Flush() { helper_.Flush(); }
717
718 bool IsStalled() const { return helper_.IsStalled(); }
719
695 void CloseIdleSockets() { return helper_.CloseIdleSockets(); } 720 void CloseIdleSockets() { return helper_.CloseIdleSockets(); }
696 721
697 int idle_socket_count() const { return helper_.idle_socket_count(); } 722 int idle_socket_count() const { return helper_.idle_socket_count(); }
698 723
699 int IdleSocketCountInGroup(const std::string& group_name) const { 724 int IdleSocketCountInGroup(const std::string& group_name) const {
700 return helper_.IdleSocketCountInGroup(group_name); 725 return helper_.IdleSocketCountInGroup(group_name);
701 } 726 }
702 727
703 LoadState GetLoadState(const std::string& group_name, 728 LoadState GetLoadState(const std::string& group_name,
704 const ClientSocketHandle* handle) const { 729 const ClientSocketHandle* handle) const {
(...skipping 28 matching lines...) Expand all
733 base::TimeDelta ConnectionTimeout() const { 758 base::TimeDelta ConnectionTimeout() const {
734 return helper_.ConnectionTimeout(); 759 return helper_.ConnectionTimeout();
735 } 760 }
736 761
737 ClientSocketPoolHistograms* histograms() const { 762 ClientSocketPoolHistograms* histograms() const {
738 return histograms_; 763 return histograms_;
739 } 764 }
740 765
741 void EnableConnectBackupJobs() { helper_.EnableConnectBackupJobs(); } 766 void EnableConnectBackupJobs() { helper_.EnableConnectBackupJobs(); }
742 767
743 void Flush() { helper_.Flush(); } 768 bool CloseOneIdleSocket() { return helper_.CloseOneIdleSocket(); }
769
770 bool CloseOneIdleConnectionInLayeredPool() {
771 return helper_.CloseOneIdleConnectionInLayeredPool();
772 }
744 773
745 private: 774 private:
746 // This adaptor class exists to bridge the 775 // This adaptor class exists to bridge the
747 // internal::ClientSocketPoolBaseHelper::ConnectJobFactory and 776 // internal::ClientSocketPoolBaseHelper::ConnectJobFactory and
748 // ClientSocketPoolBase::ConnectJobFactory types, allowing clients to use the 777 // ClientSocketPoolBase::ConnectJobFactory types, allowing clients to use the
749 // typesafe ClientSocketPoolBase::ConnectJobFactory, rather than having to 778 // typesafe ClientSocketPoolBase::ConnectJobFactory, rather than having to
750 // static_cast themselves. 779 // static_cast themselves.
751 class ConnectJobFactoryAdaptor 780 class ConnectJobFactoryAdaptor
752 : public internal::ClientSocketPoolBaseHelper::ConnectJobFactory { 781 : public internal::ClientSocketPoolBaseHelper::ConnectJobFactory {
753 public: 782 public:
(...skipping 23 matching lines...) Expand all
777 // Histograms for the pool 806 // Histograms for the pool
778 ClientSocketPoolHistograms* const histograms_; 807 ClientSocketPoolHistograms* const histograms_;
779 internal::ClientSocketPoolBaseHelper helper_; 808 internal::ClientSocketPoolBaseHelper helper_;
780 809
781 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); 810 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase);
782 }; 811 };
783 812
784 } // namespace net 813 } // namespace net
785 814
786 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ 815 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_
OLDNEW
« no previous file with comments | « net/socket/client_socket_pool.cc ('k') | net/socket/client_socket_pool_base.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698