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

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

Issue 2077004: Reland my close on idle socket change. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Merge Created 10 years, 7 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
« no previous file with comments | « no previous file | 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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 } 218 }
219 219
220 // Closes all idle sockets if |force| is true. Else, only closes idle 220 // Closes all idle sockets if |force| is true. Else, only closes idle
221 // sockets that timed out or can't be reused. Made public for testing. 221 // sockets that timed out or can't be reused. Made public for testing.
222 void CleanupIdleSockets(bool force); 222 void CleanupIdleSockets(bool force);
223 223
224 base::TimeDelta ConnectionTimeout() const { 224 base::TimeDelta ConnectionTimeout() const {
225 return connect_job_factory_->ConnectionTimeout(); 225 return connect_job_factory_->ConnectionTimeout();
226 } 226 }
227 227
228 void enable_backup_jobs() { backup_jobs_enabled_ = true; }; 228 void EnableBackupJobs() { backup_jobs_enabled_ = true; };
229 229
230 private: 230 private:
231 friend class base::RefCounted<ClientSocketPoolBaseHelper>; 231 friend class base::RefCounted<ClientSocketPoolBaseHelper>;
232 232
233 ~ClientSocketPoolBaseHelper(); 233 ~ClientSocketPoolBaseHelper();
234 234
235 // Entry for a persistent socket which became idle at time |start_time|. 235 // Entry for a persistent socket which became idle at time |start_time|.
236 struct IdleSocket { 236 struct IdleSocket {
237 IdleSocket() : socket(NULL), used(false) {} 237 IdleSocket() : socket(NULL), used(false) {}
238 ClientSocket* socket; 238 ClientSocket* socket;
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 // |request|. 380 // |request|.
381 int RequestSocketInternal(const std::string& group_name, 381 int RequestSocketInternal(const std::string& group_name,
382 const Request* request); 382 const Request* request);
383 383
384 // Set a timer to create a backup socket if it takes too long to create one. 384 // Set a timer to create a backup socket if it takes too long to create one.
385 void StartBackupSocketTimer(const std::string& group_name); 385 void StartBackupSocketTimer(const std::string& group_name);
386 386
387 // Called when the backup socket timer fires. 387 // Called when the backup socket timer fires.
388 void OnBackupSocketTimerFired(const std::string& group_name); 388 void OnBackupSocketTimerFired(const std::string& group_name);
389 389
390 // Closes one idle socket. Picks the first one encountered.
391 // TODO(willchan): Consider a better algorithm for doing this. Perhaps we
392 // should keep an ordered list of idle sockets, and close them in order.
393 // Requires maintaining more state. It's not clear if it's worth it since
394 // I'm not sure if we hit this situation often.
395 void CloseOneIdleSocket();
396
390 GroupMap group_map_; 397 GroupMap group_map_;
391 398
392 // Timer used to periodically prune idle sockets that timed out or can't be 399 // Timer used to periodically prune idle sockets that timed out or can't be
393 // reused. 400 // reused.
394 base::RepeatingTimer<ClientSocketPoolBaseHelper> timer_; 401 base::RepeatingTimer<ClientSocketPoolBaseHelper> timer_;
395 402
396 // The total number of idle sockets in the system. 403 // The total number of idle sockets in the system.
397 int idle_socket_count_; 404 int idle_socket_count_;
398 405
399 // Number of connecting sockets across all groups. 406 // Number of connecting sockets across all groups.
(...skipping 19 matching lines...) Expand all
419 // have pending requests if it exceeds the "max sockets per group" limit. 426 // have pending requests if it exceeds the "max sockets per group" limit.
420 // 427 //
421 // This means when a socket is released, the only pending requests that can 428 // This means when a socket is released, the only pending requests that can
422 // be started next belong to the same group. 429 // be started next belong to the same group.
423 // 430 //
424 // However once the |max_sockets_| limit is reached, this stops being true: 431 // However once the |max_sockets_| limit is reached, this stops being true:
425 // groups can now have pending requests without having first reached the 432 // groups can now have pending requests without having first reached the
426 // |max_sockets_per_group_| limit. So choosing the next request involves 433 // |max_sockets_per_group_| limit. So choosing the next request involves
427 // selecting the highest priority request across *all* groups. 434 // selecting the highest priority request across *all* groups.
428 // 435 //
429 // Since reaching the maximum number of sockets is an edge case, we make note 436 // |may_have_stalled_group_| is not conclusive, since when we cancel pending
430 // of when it happens, and thus avoid doing the slower "scan all groups" 437 // requests, we may reach the situation where we have the maximum number of
431 // in the common case. 438 // sockets, but not request is stalled because of the global socket limit
439 // (although some requests may be blocked on the socket per group limit).
440 // We don't strictly maintain |may_have_stalled_group_|, since that would
441 // require a linear search through all groups in |group_map_| to see if one
442 // of them is stalled.
432 bool may_have_stalled_group_; 443 bool may_have_stalled_group_;
433 444
434 const scoped_ptr<ConnectJobFactory> connect_job_factory_; 445 const scoped_ptr<ConnectJobFactory> connect_job_factory_;
435 446
436 // TODO(vandebo) Remove when backup jobs move to TCPClientSocketPool 447 // TODO(vandebo) Remove when backup jobs move to TCPClientSocketPool
437 bool backup_jobs_enabled_; 448 bool backup_jobs_enabled_;
438 449
439 // A factory to pin the backup_job tasks. 450 // A factory to pin the backup_job tasks.
440 ScopedRunnableMethodFactory<ClientSocketPoolBaseHelper> method_factory_; 451 ScopedRunnableMethodFactory<ClientSocketPoolBaseHelper> method_factory_;
441 }; 452 };
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 void CleanupIdleSockets(bool force) { 572 void CleanupIdleSockets(bool force) {
562 return helper_->CleanupIdleSockets(force); 573 return helper_->CleanupIdleSockets(force);
563 } 574 }
564 575
565 base::TimeDelta ConnectionTimeout() const { 576 base::TimeDelta ConnectionTimeout() const {
566 return helper_->ConnectionTimeout(); 577 return helper_->ConnectionTimeout();
567 } 578 }
568 579
569 const std::string& name() const { return name_; } 580 const std::string& name() const { return name_; }
570 581
571 void enable_backup_jobs() { helper_->enable_backup_jobs(); }; 582 void EnableBackupJobs() { helper_->EnableBackupJobs(); };
572 583
573 private: 584 private:
574 // This adaptor class exists to bridge the 585 // This adaptor class exists to bridge the
575 // internal::ClientSocketPoolBaseHelper::ConnectJobFactory and 586 // internal::ClientSocketPoolBaseHelper::ConnectJobFactory and
576 // ClientSocketPoolBase::ConnectJobFactory types, allowing clients to use the 587 // ClientSocketPoolBase::ConnectJobFactory types, allowing clients to use the
577 // typesafe ClientSocketPoolBase::ConnectJobFactory, rather than having to 588 // typesafe ClientSocketPoolBase::ConnectJobFactory, rather than having to
578 // static_cast themselves. 589 // static_cast themselves.
579 class ConnectJobFactoryAdaptor 590 class ConnectJobFactoryAdaptor
580 : public internal::ClientSocketPoolBaseHelper::ConnectJobFactory { 591 : public internal::ClientSocketPoolBaseHelper::ConnectJobFactory {
581 public: 592 public:
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 // the posting of the task and the execution, then we'll hit the DCHECK that 624 // the posting of the task and the execution, then we'll hit the DCHECK that
614 // |ClientSocketPoolBaseHelper::group_map_| is empty. 625 // |ClientSocketPoolBaseHelper::group_map_| is empty.
615 scoped_refptr<internal::ClientSocketPoolBaseHelper> helper_; 626 scoped_refptr<internal::ClientSocketPoolBaseHelper> helper_;
616 627
617 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); 628 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase);
618 }; 629 };
619 630
620 } // namespace net 631 } // namespace net
621 632
622 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ 633 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_
OLDNEW
« no previous file with comments | « no previous file | net/socket/client_socket_pool_base.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698