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

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

Issue 8340012: Close idle connections / SPDY sessions when needed. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: OVERRIDE Created 9 years, 1 month 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
OLDNEW
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 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/task.h" 36 #include "base/task.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 16 matching lines...) Expand all
290 int NumActiveSocketsInGroup(const std::string& group_name) const { 299 int NumActiveSocketsInGroup(const std::string& group_name) const {
291 return group_map_.find(group_name)->second->active_socket_count(); 300 return group_map_.find(group_name)->second->active_socket_count();
292 } 301 }
293 302
294 bool HasGroup(const std::string& group_name) const; 303 bool HasGroup(const std::string& group_name) const;
295 304
296 // Closes all idle sockets if |force| is true. Else, only closes idle 305 // Closes all idle sockets if |force| is true. Else, only closes idle
297 // sockets that timed out or can't be reused. Made public for testing. 306 // sockets that timed out or can't be reused. Made public for testing.
298 void CleanupIdleSockets(bool force); 307 void CleanupIdleSockets(bool force);
299 308
309 // Closes one idle socket. Picks the first one encountered.
310 // TODO(willchan): Consider a better algorithm for doing this. Perhaps we
311 // should keep an ordered list of idle sockets, and close them in order.
312 // Requires maintaining more state. It's not clear if it's worth it since
313 // I'm not sure if we hit this situation often.
314 bool CloseOneIdleSocket();
315
300 // See ClientSocketPool::GetInfoAsValue for documentation on this function. 316 // See ClientSocketPool::GetInfoAsValue for documentation on this function.
301 base::DictionaryValue* GetInfoAsValue(const std::string& name, 317 base::DictionaryValue* GetInfoAsValue(const std::string& name,
302 const std::string& type) const; 318 const std::string& type) const;
303 319
304 base::TimeDelta ConnectionTimeout() const { 320 base::TimeDelta ConnectionTimeout() const {
305 return connect_job_factory_->ConnectionTimeout(); 321 return connect_job_factory_->ConnectionTimeout();
306 } 322 }
307 323
308 static bool connect_backup_jobs_enabled(); 324 static bool connect_backup_jobs_enabled();
309 static bool set_connect_backup_jobs_enabled(bool enabled); 325 static bool set_connect_backup_jobs_enabled(bool enabled);
310 326
311 void EnableConnectBackupJobs(); 327 void EnableConnectBackupJobs();
312 328
313 // ConnectJob::Delegate methods: 329 // ConnectJob::Delegate methods:
314 virtual void OnConnectJobComplete(int result, ConnectJob* job); 330 virtual void OnConnectJobComplete(int result, ConnectJob* job);
315 331
332 // Checks layered pools to see if they can close an idle connection.
333 bool CloseOneIdleConnectionInLayeredPool();
334
316 // NetworkChangeNotifier::IPAddressObserver methods: 335 // NetworkChangeNotifier::IPAddressObserver methods:
317 virtual void OnIPAddressChanged(); 336 virtual void OnIPAddressChanged();
318 337
319 private: 338 private:
320 friend class base::RefCounted<ClientSocketPoolBaseHelper>; 339 friend class base::RefCounted<ClientSocketPoolBaseHelper>;
321 340
322 // Entry for a persistent socket which became idle at time |start_time|. 341 // Entry for a persistent socket which became idle at time |start_time|.
323 struct IdleSocket { 342 struct IdleSocket {
324 IdleSocket() : socket(NULL) {} 343 IdleSocket() : socket(NULL) {}
325 344
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 void RemoveGroup(GroupMap::iterator it); 458 void RemoveGroup(GroupMap::iterator it);
440 459
441 // Called when the number of idle sockets changes. 460 // Called when the number of idle sockets changes.
442 void IncrementIdleCount(); 461 void IncrementIdleCount();
443 void DecrementIdleCount(); 462 void DecrementIdleCount();
444 463
445 // Scans the group map for groups which have an available socket slot and 464 // Scans the group map for groups which have an available socket slot and
446 // at least one pending request. Returns true if any groups are stalled, and 465 // at least one pending request. Returns true if any groups are stalled, and
447 // if so, fills |group| and |group_name| with data of the stalled group 466 // if so, fills |group| and |group_name| with data of the stalled group
448 // having highest priority. 467 // having highest priority.
449 bool FindTopStalledGroup(Group** group, std::string* group_name); 468 bool FindTopStalledGroup(Group** group, std::string* group_name) const;
450 469
451 // Called when timer_ fires. This method scans the idle sockets removing 470 // Called when timer_ fires. This method scans the idle sockets removing
452 // sockets that timed out or can't be reused. 471 // sockets that timed out or can't be reused.
453 void OnCleanupTimerFired() { 472 void OnCleanupTimerFired() {
454 CleanupIdleSockets(false); 473 CleanupIdleSockets(false);
455 } 474 }
456 475
457 // Removes |job| from |connect_job_set_|. Also updates |group| if non-NULL. 476 // Removes |job| from |connect_job_set_|. Also updates |group| if non-NULL.
458 void RemoveConnectJob(ConnectJob* job, Group* group); 477 void RemoveConnectJob(ConnectJob* job, Group* group);
459 478
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 int RequestSocketInternal(const std::string& group_name, 510 int RequestSocketInternal(const std::string& group_name,
492 const Request* request); 511 const Request* request);
493 512
494 // Assigns an idle socket for the group to the request. 513 // Assigns an idle socket for the group to the request.
495 // Returns |true| if an idle socket is available, false otherwise. 514 // Returns |true| if an idle socket is available, false otherwise.
496 bool AssignIdleSocketToGroup(const Request* request, Group* group); 515 bool AssignIdleSocketToGroup(const Request* request, Group* group);
497 516
498 static void LogBoundConnectJobToRequest( 517 static void LogBoundConnectJobToRequest(
499 const NetLog::Source& connect_job_source, const Request* request); 518 const NetLog::Source& connect_job_source, const Request* request);
500 519
501 // Closes one idle socket. Picks the first one encountered.
502 // TODO(willchan): Consider a better algorithm for doing this. Perhaps we
503 // should keep an ordered list of idle sockets, and close them in order.
504 // Requires maintaining more state. It's not clear if it's worth it since
505 // I'm not sure if we hit this situation often.
506 void CloseOneIdleSocket();
507
508 // Same as CloseOneIdleSocket() except it won't close an idle socket in 520 // Same as CloseOneIdleSocket() except it won't close an idle socket in
509 // |group|. If |group| is NULL, it is ignored. Returns true if it closed a 521 // |group|. If |group| is NULL, it is ignored. Returns true if it closed a
510 // socket. 522 // socket.
511 bool CloseOneIdleSocketExceptInGroup(const Group* group); 523 bool CloseOneIdleSocketExceptInGroup(const Group* group);
512 524
513 // Checks if there are stalled socket groups that should be notified 525 // Checks if there are stalled socket groups that should be notified
514 // for possible wakeup. 526 // for possible wakeup.
515 void CheckForStalledSocketGroups(); 527 void CheckForStalledSocketGroups();
516 528
517 // Posts a task to call InvokeUserCallback() on the next iteration through the 529 // Posts a task to call InvokeUserCallback() on the next iteration through the
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 const scoped_ptr<ConnectJobFactory> connect_job_factory_; 571 const scoped_ptr<ConnectJobFactory> connect_job_factory_;
560 572
561 // TODO(vandebo) Remove when backup jobs move to TransportClientSocketPool 573 // TODO(vandebo) Remove when backup jobs move to TransportClientSocketPool
562 bool connect_backup_jobs_enabled_; 574 bool connect_backup_jobs_enabled_;
563 575
564 // A unique id for the pool. It gets incremented every time we Flush() the 576 // A unique id for the pool. It gets incremented every time we Flush() the
565 // pool. This is so that when sockets get released back to the pool, we can 577 // pool. This is so that when sockets get released back to the pool, we can
566 // make sure that they are discarded rather than reused. 578 // make sure that they are discarded rather than reused.
567 int pool_generation_number_; 579 int pool_generation_number_;
568 580
581 std::set<LayeredPool*> higher_layer_pools_;
582
569 ScopedRunnableMethodFactory<ClientSocketPoolBaseHelper> method_factory_; 583 ScopedRunnableMethodFactory<ClientSocketPoolBaseHelper> method_factory_;
570 584
571 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBaseHelper); 585 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBaseHelper);
572 }; 586 };
573 587
574 } // namespace internal 588 } // namespace internal
575 589
576 template <typename SocketParams> 590 template <typename SocketParams>
577 class ClientSocketPoolBase { 591 class ClientSocketPoolBase {
578 public: 592 public:
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 base::TimeDelta used_idle_socket_timeout, 639 base::TimeDelta used_idle_socket_timeout,
626 ConnectJobFactory* connect_job_factory) 640 ConnectJobFactory* connect_job_factory)
627 : histograms_(histograms), 641 : histograms_(histograms),
628 helper_(max_sockets, max_sockets_per_group, 642 helper_(max_sockets, max_sockets_per_group,
629 unused_idle_socket_timeout, used_idle_socket_timeout, 643 unused_idle_socket_timeout, used_idle_socket_timeout,
630 new ConnectJobFactoryAdaptor(connect_job_factory)) {} 644 new ConnectJobFactoryAdaptor(connect_job_factory)) {}
631 645
632 virtual ~ClientSocketPoolBase() {} 646 virtual ~ClientSocketPoolBase() {}
633 647
634 // These member functions simply forward to ClientSocketPoolBaseHelper. 648 // These member functions simply forward to ClientSocketPoolBaseHelper.
649 void AddLayeredPool(LayeredPool* pool) {
650 helper_.AddLayeredPool(pool);
651 }
652
653 void RemoveLayeredPool(LayeredPool* pool) {
654 helper_.RemoveLayeredPool(pool);
655 }
635 656
636 // RequestSocket bundles up the parameters into a Request and then forwards to 657 // RequestSocket bundles up the parameters into a Request and then forwards to
637 // ClientSocketPoolBaseHelper::RequestSocket(). 658 // ClientSocketPoolBaseHelper::RequestSocket().
638 int RequestSocket(const std::string& group_name, 659 int RequestSocket(const std::string& group_name,
639 const scoped_refptr<SocketParams>& params, 660 const scoped_refptr<SocketParams>& params,
640 RequestPriority priority, 661 RequestPriority priority,
641 ClientSocketHandle* handle, 662 ClientSocketHandle* handle,
642 OldCompletionCallback* callback, 663 OldCompletionCallback* callback,
643 const BoundNetLog& net_log) { 664 const BoundNetLog& net_log) {
644 Request* request = 665 Request* request =
(...skipping 24 matching lines...) Expand all
669 void CancelRequest(const std::string& group_name, 690 void CancelRequest(const std::string& group_name,
670 ClientSocketHandle* handle) { 691 ClientSocketHandle* handle) {
671 return helper_.CancelRequest(group_name, handle); 692 return helper_.CancelRequest(group_name, handle);
672 } 693 }
673 694
674 void ReleaseSocket(const std::string& group_name, StreamSocket* socket, 695 void ReleaseSocket(const std::string& group_name, StreamSocket* socket,
675 int id) { 696 int id) {
676 return helper_.ReleaseSocket(group_name, socket, id); 697 return helper_.ReleaseSocket(group_name, socket, id);
677 } 698 }
678 699
700 void Flush() { helper_.Flush(); }
701
702 bool IsStalled() const { return helper_.IsStalled(); }
703
679 void CloseIdleSockets() { return helper_.CloseIdleSockets(); } 704 void CloseIdleSockets() { return helper_.CloseIdleSockets(); }
680 705
681 int idle_socket_count() const { return helper_.idle_socket_count(); } 706 int idle_socket_count() const { return helper_.idle_socket_count(); }
682 707
683 int IdleSocketCountInGroup(const std::string& group_name) const { 708 int IdleSocketCountInGroup(const std::string& group_name) const {
684 return helper_.IdleSocketCountInGroup(group_name); 709 return helper_.IdleSocketCountInGroup(group_name);
685 } 710 }
686 711
687 LoadState GetLoadState(const std::string& group_name, 712 LoadState GetLoadState(const std::string& group_name,
688 const ClientSocketHandle* handle) const { 713 const ClientSocketHandle* handle) const {
(...skipping 28 matching lines...) Expand all
717 base::TimeDelta ConnectionTimeout() const { 742 base::TimeDelta ConnectionTimeout() const {
718 return helper_.ConnectionTimeout(); 743 return helper_.ConnectionTimeout();
719 } 744 }
720 745
721 ClientSocketPoolHistograms* histograms() const { 746 ClientSocketPoolHistograms* histograms() const {
722 return histograms_; 747 return histograms_;
723 } 748 }
724 749
725 void EnableConnectBackupJobs() { helper_.EnableConnectBackupJobs(); } 750 void EnableConnectBackupJobs() { helper_.EnableConnectBackupJobs(); }
726 751
727 void Flush() { helper_.Flush(); } 752 bool CloseOneIdleSocket() { return helper_.CloseOneIdleSocket(); }
753
754 bool CloseOneIdleConnectionInLayeredPool() {
755 return helper_.CloseOneIdleConnectionInLayeredPool();
756 }
728 757
729 private: 758 private:
730 // This adaptor class exists to bridge the 759 // This adaptor class exists to bridge the
731 // internal::ClientSocketPoolBaseHelper::ConnectJobFactory and 760 // internal::ClientSocketPoolBaseHelper::ConnectJobFactory and
732 // ClientSocketPoolBase::ConnectJobFactory types, allowing clients to use the 761 // ClientSocketPoolBase::ConnectJobFactory types, allowing clients to use the
733 // typesafe ClientSocketPoolBase::ConnectJobFactory, rather than having to 762 // typesafe ClientSocketPoolBase::ConnectJobFactory, rather than having to
734 // static_cast themselves. 763 // static_cast themselves.
735 class ConnectJobFactoryAdaptor 764 class ConnectJobFactoryAdaptor
736 : public internal::ClientSocketPoolBaseHelper::ConnectJobFactory { 765 : public internal::ClientSocketPoolBaseHelper::ConnectJobFactory {
737 public: 766 public:
(...skipping 23 matching lines...) Expand all
761 // Histograms for the pool 790 // Histograms for the pool
762 ClientSocketPoolHistograms* const histograms_; 791 ClientSocketPoolHistograms* const histograms_;
763 internal::ClientSocketPoolBaseHelper helper_; 792 internal::ClientSocketPoolBaseHelper helper_;
764 793
765 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); 794 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase);
766 }; 795 };
767 796
768 } // namespace net 797 } // namespace net
769 798
770 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ 799 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698