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

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

Issue 8526006: Close idle sockets next time we are about to send data. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: use global variable. 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
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 #include "net/socket/client_socket_pool_base.h" 5 #include "net/socket/client_socket_pool_base.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/format_macros.h" 9 #include "base/format_macros.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "base/metrics/stats_counters.h" 12 #include "base/metrics/stats_counters.h"
13 #include "base/stl_util.h" 13 #include "base/stl_util.h"
14 #include "base/string_number_conversions.h" 14 #include "base/string_number_conversions.h"
15 #include "base/string_util.h" 15 #include "base/string_util.h"
16 #include "base/time.h" 16 #include "base/time.h"
17 #include "base/values.h" 17 #include "base/values.h"
18 #include "net/base/net_log.h" 18 #include "net/base/net_log.h"
19 #include "net/base/net_errors.h" 19 #include "net/base/net_errors.h"
20 #include "net/socket/client_socket_handle.h" 20 #include "net/socket/client_socket_handle.h"
21 21
22 using base::TimeDelta; 22 using base::TimeDelta;
23 23
24 namespace { 24 namespace {
25 25
26 // Indicate whether we should enable idle socket cleanup timer. When timer is
27 // disabled, sockets are closed next time a socket request is made.
28 bool g_cleanup_timer_enabled = true;
willchan no longer on Chromium 2011/11/16 00:51:40 We should probably set a different default for win
selim 2011/11/16 01:01:08 We want the timer enabled (true) for windows due t
willchan no longer on Chromium 2011/11/16 01:04:29 Sorry, I had the boolean value's effect flipped in
29
26 // The timeout value, in seconds, used to clean up idle sockets that can't be 30 // The timeout value, in seconds, used to clean up idle sockets that can't be
27 // reused. 31 // reused.
28 // 32 //
29 // Note: It's important to close idle sockets that have received data as soon 33 // Note: It's important to close idle sockets that have received data as soon
30 // as possible because the received data may cause BSOD on Windows XP under 34 // as possible because the received data may cause BSOD on Windows XP under
31 // some conditions. See http://crbug.com/4606. 35 // some conditions. See http://crbug.com/4606.
32 const int kCleanupInterval = 10; // DO NOT INCREASE THIS TIMEOUT. 36 const int kCleanupInterval = 10; // DO NOT INCREASE THIS TIMEOUT.
33 37
34 // Indicate whether or not we should establish a new transport layer connection 38 // Indicate whether or not we should establish a new transport layer connection
35 // after a certain timeout has passed without receiving an ACK. 39 // after a certain timeout has passed without receiving an ACK.
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 int max_sockets, 179 int max_sockets,
176 int max_sockets_per_group, 180 int max_sockets_per_group,
177 base::TimeDelta unused_idle_socket_timeout, 181 base::TimeDelta unused_idle_socket_timeout,
178 base::TimeDelta used_idle_socket_timeout, 182 base::TimeDelta used_idle_socket_timeout,
179 ConnectJobFactory* connect_job_factory) 183 ConnectJobFactory* connect_job_factory)
180 : idle_socket_count_(0), 184 : idle_socket_count_(0),
181 connecting_socket_count_(0), 185 connecting_socket_count_(0),
182 handed_out_socket_count_(0), 186 handed_out_socket_count_(0),
183 max_sockets_(max_sockets), 187 max_sockets_(max_sockets),
184 max_sockets_per_group_(max_sockets_per_group), 188 max_sockets_per_group_(max_sockets_per_group),
189 use_cleanup_timer_(g_cleanup_timer_enabled),
185 unused_idle_socket_timeout_(unused_idle_socket_timeout), 190 unused_idle_socket_timeout_(unused_idle_socket_timeout),
186 used_idle_socket_timeout_(used_idle_socket_timeout), 191 used_idle_socket_timeout_(used_idle_socket_timeout),
187 connect_job_factory_(connect_job_factory), 192 connect_job_factory_(connect_job_factory),
188 connect_backup_jobs_enabled_(false), 193 connect_backup_jobs_enabled_(false),
189 pool_generation_number_(0), 194 pool_generation_number_(0),
190 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { 195 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
191 DCHECK_LE(0, max_sockets_per_group); 196 DCHECK_LE(0, max_sockets_per_group);
192 DCHECK_LE(max_sockets_per_group, max_sockets); 197 DCHECK_LE(max_sockets_per_group, max_sockets);
193 198
194 NetworkChangeNotifier::AddIPAddressObserver(this); 199 NetworkChangeNotifier::AddIPAddressObserver(this);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 group->CleanupBackupJob(); 235 group->CleanupBackupJob();
231 return req; 236 return req;
232 } 237 }
233 238
234 int ClientSocketPoolBaseHelper::RequestSocket( 239 int ClientSocketPoolBaseHelper::RequestSocket(
235 const std::string& group_name, 240 const std::string& group_name,
236 const Request* request) { 241 const Request* request) {
237 CHECK(request->callback()); 242 CHECK(request->callback());
238 CHECK(request->handle()); 243 CHECK(request->handle());
239 244
245 // Cleanup any timed-out idle sockets if no timer is used.
246 if (!use_cleanup_timer_)
247 CleanupIdleSockets(false);
248
240 request->net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL, NULL); 249 request->net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL, NULL);
241 Group* group = GetOrCreateGroup(group_name); 250 Group* group = GetOrCreateGroup(group_name);
242 251
243 int rv = RequestSocketInternal(group_name, request); 252 int rv = RequestSocketInternal(group_name, request);
244 if (rv != ERR_IO_PENDING) { 253 if (rv != ERR_IO_PENDING) {
245 request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv); 254 request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv);
246 CHECK(!request->handle()->is_initialized()); 255 CHECK(!request->handle()->is_initialized());
247 delete request; 256 delete request;
248 } else { 257 } else {
249 InsertRequestIntoQueue(request, group->mutable_pending_requests()); 258 InsertRequestIntoQueue(request, group->mutable_pending_requests());
250 } 259 }
251 return rv; 260 return rv;
252 } 261 }
253 262
254 void ClientSocketPoolBaseHelper::RequestSockets( 263 void ClientSocketPoolBaseHelper::RequestSockets(
255 const std::string& group_name, 264 const std::string& group_name,
256 const Request& request, 265 const Request& request,
257 int num_sockets) { 266 int num_sockets) {
258 DCHECK(!request.callback()); 267 DCHECK(!request.callback());
259 DCHECK(!request.handle()); 268 DCHECK(!request.handle());
260 269
270 // Cleanup any timed out idle sockets if no timer is used.
271 if (!use_cleanup_timer_)
272 CleanupIdleSockets(false);
273
261 if (num_sockets > max_sockets_per_group_) { 274 if (num_sockets > max_sockets_per_group_) {
262 num_sockets = max_sockets_per_group_; 275 num_sockets = max_sockets_per_group_;
263 } 276 }
264 277
265 request.net_log().BeginEvent( 278 request.net_log().BeginEvent(
266 NetLog::TYPE_SOCKET_POOL_CONNECTING_N_SOCKETS, 279 NetLog::TYPE_SOCKET_POOL_CONNECTING_N_SOCKETS,
267 make_scoped_refptr(new NetLogIntegerParameter( 280 make_scoped_refptr(new NetLogIntegerParameter(
268 "num_sockets", num_sockets))); 281 "num_sockets", num_sockets)));
269 282
270 Group* group = GetOrCreateGroup(group_name); 283 Group* group = GetOrCreateGroup(group_name);
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 bool old_value = g_connect_backup_jobs_enabled; 702 bool old_value = g_connect_backup_jobs_enabled;
690 g_connect_backup_jobs_enabled = enabled; 703 g_connect_backup_jobs_enabled = enabled;
691 return old_value; 704 return old_value;
692 } 705 }
693 706
694 void ClientSocketPoolBaseHelper::EnableConnectBackupJobs() { 707 void ClientSocketPoolBaseHelper::EnableConnectBackupJobs() {
695 connect_backup_jobs_enabled_ = g_connect_backup_jobs_enabled; 708 connect_backup_jobs_enabled_ = g_connect_backup_jobs_enabled;
696 } 709 }
697 710
698 void ClientSocketPoolBaseHelper::IncrementIdleCount() { 711 void ClientSocketPoolBaseHelper::IncrementIdleCount() {
699 if (++idle_socket_count_ == 1) 712 if (++idle_socket_count_ == 1 && use_cleanup_timer_)
700 timer_.Start(FROM_HERE, TimeDelta::FromSeconds(kCleanupInterval), this, 713 StartIdleSocketTimer();
701 &ClientSocketPoolBaseHelper::OnCleanupTimerFired);
702 } 714 }
703 715
704 void ClientSocketPoolBaseHelper::DecrementIdleCount() { 716 void ClientSocketPoolBaseHelper::DecrementIdleCount() {
705 if (--idle_socket_count_ == 0) 717 if (--idle_socket_count_ == 0)
706 timer_.Stop(); 718 timer_.Stop();
707 } 719 }
708 720
721 // static
722 bool ClientSocketPoolBaseHelper::cleanup_timer_enabled() {
723 return g_cleanup_timer_enabled;
724 }
725
726 // static
727 bool ClientSocketPoolBaseHelper::set_cleanup_timer_enabled(bool enabled) {
728 bool old_value = g_cleanup_timer_enabled;
729 g_cleanup_timer_enabled = enabled;
730 return old_value;
731 }
732
733 void ClientSocketPoolBaseHelper::StartIdleSocketTimer() {
734 timer_.Start(FROM_HERE, TimeDelta::FromSeconds(kCleanupInterval), this,
735 &ClientSocketPoolBaseHelper::OnCleanupTimerFired);
736 }
737
709 void ClientSocketPoolBaseHelper::ReleaseSocket(const std::string& group_name, 738 void ClientSocketPoolBaseHelper::ReleaseSocket(const std::string& group_name,
710 StreamSocket* socket, 739 StreamSocket* socket,
711 int id) { 740 int id) {
712 GroupMap::iterator i = group_map_.find(group_name); 741 GroupMap::iterator i = group_map_.find(group_name);
713 CHECK(i != group_map_.end()); 742 CHECK(i != group_map_.end());
714 743
715 Group* group = i->second; 744 Group* group = i->second;
716 745
717 CHECK_GT(handed_out_socket_count_, 0); 746 CHECK_GT(handed_out_socket_count_, 0);
718 handed_out_socket_count_--; 747 handed_out_socket_count_--;
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
889 const std::string& group_name, Group* group) { 918 const std::string& group_name, Group* group) {
890 int rv = RequestSocketInternal(group_name, 919 int rv = RequestSocketInternal(group_name,
891 *group->pending_requests().begin()); 920 *group->pending_requests().begin());
892 if (rv != ERR_IO_PENDING) { 921 if (rv != ERR_IO_PENDING) {
893 scoped_ptr<const Request> request(RemoveRequestFromQueue( 922 scoped_ptr<const Request> request(RemoveRequestFromQueue(
894 group->mutable_pending_requests()->begin(), group)); 923 group->mutable_pending_requests()->begin(), group));
895 if (group->IsEmpty()) 924 if (group->IsEmpty())
896 RemoveGroup(group_name); 925 RemoveGroup(group_name);
897 926
898 request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv); 927 request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv);
899 InvokeUserCallbackLater( 928 InvokeUserCallbackLater(request->handle(), request->callback(), rv);
900 request->handle(), request->callback(), rv);
901 } 929 }
902 } 930 }
903 931
904 void ClientSocketPoolBaseHelper::HandOutSocket( 932 void ClientSocketPoolBaseHelper::HandOutSocket(
905 StreamSocket* socket, 933 StreamSocket* socket,
906 bool reused, 934 bool reused,
907 ClientSocketHandle* handle, 935 ClientSocketHandle* handle,
908 base::TimeDelta idle_time, 936 base::TimeDelta idle_time,
909 Group* group, 937 Group* group,
910 const BoundNetLog& net_log) { 938 const BoundNetLog& net_log) {
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1123 // Delete active jobs. 1151 // Delete active jobs.
1124 STLDeleteElements(&jobs_); 1152 STLDeleteElements(&jobs_);
1125 1153
1126 // Cancel pending backup job. 1154 // Cancel pending backup job.
1127 method_factory_.RevokeAll(); 1155 method_factory_.RevokeAll();
1128 } 1156 }
1129 1157
1130 } // namespace internal 1158 } // namespace internal
1131 1159
1132 } // namespace net 1160 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698