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

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

Issue 3191019: A/B experiment for re-establishing TCP connections (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 4 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_base.h ('k') | net/socket/client_socket_pool_base_unittest.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 #include "net/socket/client_socket_pool_base.h" 5 #include "net/socket/client_socket_pool_base.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/format_macros.h" 8 #include "base/format_macros.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/stats_counters.h" 10 #include "base/stats_counters.h"
11 #include "base/stl_util-inl.h" 11 #include "base/stl_util-inl.h"
12 #include "base/string_util.h" 12 #include "base/string_util.h"
13 #include "base/time.h" 13 #include "base/time.h"
14 #include "net/base/net_log.h" 14 #include "net/base/net_log.h"
15 #include "net/base/net_errors.h" 15 #include "net/base/net_errors.h"
16 #include "net/socket/client_socket_handle.h" 16 #include "net/socket/client_socket_handle.h"
17 17
18 using base::TimeDelta; 18 using base::TimeDelta;
19 19
20 namespace { 20 namespace {
21 21
22 // The timeout value, in seconds, used to clean up idle sockets that can't be 22 // The timeout value, in seconds, used to clean up idle sockets that can't be
23 // reused. 23 // reused.
24 // 24 //
25 // Note: It's important to close idle sockets that have received data as soon 25 // Note: It's important to close idle sockets that have received data as soon
26 // as possible because the received data may cause BSOD on Windows XP under 26 // as possible because the received data may cause BSOD on Windows XP under
27 // some conditions. See http://crbug.com/4606. 27 // some conditions. See http://crbug.com/4606.
28 const int kCleanupInterval = 10; // DO NOT INCREASE THIS TIMEOUT. 28 const int kCleanupInterval = 10; // DO NOT INCREASE THIS TIMEOUT.
29 29
30 // Indicate whether or not we should establish a new TCP connection after a
31 // certain timeout has passed without receiving an ACK.
32 bool g_connect_backup_jobs_enabled = true;
33
30 } // namespace 34 } // namespace
31 35
32 namespace net { 36 namespace net {
33 37
34 ConnectJob::ConnectJob(const std::string& group_name, 38 ConnectJob::ConnectJob(const std::string& group_name,
35 base::TimeDelta timeout_duration, 39 base::TimeDelta timeout_duration,
36 Delegate* delegate, 40 Delegate* delegate,
37 const BoundNetLog& net_log) 41 const BoundNetLog& net_log)
38 : group_name_(group_name), 42 : group_name_(group_name),
39 timeout_duration_(timeout_duration), 43 timeout_duration_(timeout_duration),
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 base::TimeDelta used_idle_socket_timeout, 134 base::TimeDelta used_idle_socket_timeout,
131 ConnectJobFactory* connect_job_factory) 135 ConnectJobFactory* connect_job_factory)
132 : idle_socket_count_(0), 136 : idle_socket_count_(0),
133 connecting_socket_count_(0), 137 connecting_socket_count_(0),
134 handed_out_socket_count_(0), 138 handed_out_socket_count_(0),
135 max_sockets_(max_sockets), 139 max_sockets_(max_sockets),
136 max_sockets_per_group_(max_sockets_per_group), 140 max_sockets_per_group_(max_sockets_per_group),
137 unused_idle_socket_timeout_(unused_idle_socket_timeout), 141 unused_idle_socket_timeout_(unused_idle_socket_timeout),
138 used_idle_socket_timeout_(used_idle_socket_timeout), 142 used_idle_socket_timeout_(used_idle_socket_timeout),
139 connect_job_factory_(connect_job_factory), 143 connect_job_factory_(connect_job_factory),
140 backup_jobs_enabled_(false), 144 connect_backup_jobs_enabled_(false),
141 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), 145 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
142 pool_generation_number_(0), 146 pool_generation_number_(0),
143 in_destructor_(false) { 147 in_destructor_(false) {
144 DCHECK_LE(0, max_sockets_per_group); 148 DCHECK_LE(0, max_sockets_per_group);
145 DCHECK_LE(max_sockets_per_group, max_sockets); 149 DCHECK_LE(max_sockets_per_group, max_sockets);
146 150
147 NetworkChangeNotifier::AddObserver(this); 151 NetworkChangeNotifier::AddObserver(this);
148 } 152 }
149 153
150 ClientSocketPoolBaseHelper::~ClientSocketPoolBaseHelper() { 154 ClientSocketPoolBaseHelper::~ClientSocketPoolBaseHelper() {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 244
241 int rv = connect_job->Connect(); 245 int rv = connect_job->Connect();
242 if (rv == OK) { 246 if (rv == OK) {
243 LogBoundConnectJobToRequest(connect_job->net_log().source(), request); 247 LogBoundConnectJobToRequest(connect_job->net_log().source(), request);
244 HandOutSocket(connect_job->ReleaseSocket(), false /* not reused */, 248 HandOutSocket(connect_job->ReleaseSocket(), false /* not reused */,
245 handle, base::TimeDelta(), &group, request->net_log()); 249 handle, base::TimeDelta(), &group, request->net_log());
246 } else if (rv == ERR_IO_PENDING) { 250 } else if (rv == ERR_IO_PENDING) {
247 // If we don't have any sockets in this group, set a timer for potentially 251 // If we don't have any sockets in this group, set a timer for potentially
248 // creating a new one. If the SYN is lost, this backup socket may complete 252 // creating a new one. If the SYN is lost, this backup socket may complete
249 // before the slow socket, improving end user latency. 253 // before the slow socket, improving end user latency.
250 if (group.IsEmpty() && !group.backup_job && backup_jobs_enabled_) { 254 if (group.IsEmpty() && !group.connect_backup_job &&
251 group.backup_job = connect_job_factory_->NewConnectJob(group_name, 255 connect_backup_jobs_enabled_) {
252 *request, 256 group.connect_backup_job = connect_job_factory_->NewConnectJob(group_name,
253 this); 257 *request,
258 this);
254 StartBackupSocketTimer(group_name); 259 StartBackupSocketTimer(group_name);
255 } 260 }
256 261
257 connecting_socket_count_++; 262 connecting_socket_count_++;
258 263
259 ConnectJob* job = connect_job.release(); 264 ConnectJob* job = connect_job.release();
260 group.jobs.insert(job); 265 group.jobs.insert(job);
261 } else { 266 } else {
262 LogBoundConnectJobToRequest(connect_job->net_log().source(), request); 267 LogBoundConnectJobToRequest(connect_job->net_log().source(), request);
263 connect_job->GetAdditionalErrorState(handle); 268 connect_job->GetAdditionalErrorState(handle);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 325
321 void ClientSocketPoolBaseHelper::OnBackupSocketTimerFired( 326 void ClientSocketPoolBaseHelper::OnBackupSocketTimerFired(
322 const std::string& group_name) { 327 const std::string& group_name) {
323 CHECK(ContainsKey(group_map_, group_name)); 328 CHECK(ContainsKey(group_map_, group_name));
324 329
325 Group& group = group_map_[group_name]; 330 Group& group = group_map_[group_name];
326 331
327 CHECK(group.backup_task); 332 CHECK(group.backup_task);
328 group.backup_task = NULL; 333 group.backup_task = NULL;
329 334
330 CHECK(group.backup_job); 335 CHECK(group.connect_backup_job);
331 336
332 // If there are no more jobs pending, there is no work to do. 337 // If there are no more jobs pending, there is no work to do.
333 // If we've done our cleanups correctly, this should not happen. 338 // If we've done our cleanups correctly, this should not happen.
334 if (group.jobs.empty()) { 339 if (group.jobs.empty()) {
335 NOTREACHED(); 340 NOTREACHED();
336 return; 341 return;
337 } 342 }
338 343
339 // If our backup job is waiting on DNS, or if we can't create any sockets 344 // If our backup job is waiting on DNS, or if we can't create any sockets
340 // right now due to limits, just reset the timer. 345 // right now due to limits, just reset the timer.
341 if (ReachedMaxSocketsLimit() || 346 if (ReachedMaxSocketsLimit() ||
342 !group.HasAvailableSocketSlot(max_sockets_per_group_) || 347 !group.HasAvailableSocketSlot(max_sockets_per_group_) ||
343 (*group.jobs.begin())->GetLoadState() == LOAD_STATE_RESOLVING_HOST) { 348 (*group.jobs.begin())->GetLoadState() == LOAD_STATE_RESOLVING_HOST) {
344 StartBackupSocketTimer(group_name); 349 StartBackupSocketTimer(group_name);
345 return; 350 return;
346 } 351 }
347 352
348 group.backup_job->net_log().AddEvent(NetLog::TYPE_SOCKET_BACKUP_CREATED, 353 group.connect_backup_job->net_log().AddEvent(
349 NULL); 354 NetLog::TYPE_SOCKET_BACKUP_CREATED,
355 NULL);
350 SIMPLE_STATS_COUNTER("socket.backup_created"); 356 SIMPLE_STATS_COUNTER("socket.backup_created");
351 int rv = group.backup_job->Connect(); 357 int rv = group.connect_backup_job->Connect();
352 connecting_socket_count_++; 358 connecting_socket_count_++;
353 group.jobs.insert(group.backup_job); 359 group.jobs.insert(group.connect_backup_job);
354 ConnectJob* job = group.backup_job; 360 ConnectJob* job = group.connect_backup_job;
355 group.backup_job = NULL; 361 group.connect_backup_job = NULL;
356 if (rv != ERR_IO_PENDING) 362 if (rv != ERR_IO_PENDING)
357 OnConnectJobComplete(rv, job); 363 OnConnectJobComplete(rv, job);
358 } 364 }
359 365
360 void ClientSocketPoolBaseHelper::CancelRequest( 366 void ClientSocketPoolBaseHelper::CancelRequest(
361 const std::string& group_name, ClientSocketHandle* handle) { 367 const std::string& group_name, ClientSocketHandle* handle) {
362 PendingCallbackMap::iterator callback_it = pending_callback_map_.find(handle); 368 PendingCallbackMap::iterator callback_it = pending_callback_map_.find(handle);
363 if (callback_it != pending_callback_map_.end()) { 369 if (callback_it != pending_callback_map_.end()) {
364 int result = callback_it->second.result; 370 int result = callback_it->second.result;
365 pending_callback_map_.erase(callback_it); 371 pending_callback_map_.erase(callback_it);
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 494
489 // Delete group if no longer needed. 495 // Delete group if no longer needed.
490 if (group.IsEmpty()) { 496 if (group.IsEmpty()) {
491 group_map_.erase(i++); 497 group_map_.erase(i++);
492 } else { 498 } else {
493 ++i; 499 ++i;
494 } 500 }
495 } 501 }
496 } 502 }
497 503
504 // static
505 void ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(bool enabled) {
506 g_connect_backup_jobs_enabled = enabled;
507 }
508
509 void ClientSocketPoolBaseHelper::EnableConnectBackupJobs() {
510 connect_backup_jobs_enabled_ = g_connect_backup_jobs_enabled;
511 }
512
498 void ClientSocketPoolBaseHelper::IncrementIdleCount() { 513 void ClientSocketPoolBaseHelper::IncrementIdleCount() {
499 if (++idle_socket_count_ == 1) 514 if (++idle_socket_count_ == 1)
500 timer_.Start(TimeDelta::FromSeconds(kCleanupInterval), this, 515 timer_.Start(TimeDelta::FromSeconds(kCleanupInterval), this,
501 &ClientSocketPoolBaseHelper::OnCleanupTimerFired); 516 &ClientSocketPoolBaseHelper::OnCleanupTimerFired);
502 } 517 }
503 518
504 void ClientSocketPoolBaseHelper::DecrementIdleCount() { 519 void ClientSocketPoolBaseHelper::DecrementIdleCount() {
505 if (--idle_socket_count_ == 0) 520 if (--idle_socket_count_ == 0)
506 timer_.Stop(); 521 timer_.Stop();
507 } 522 }
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 CHECK(!handle->is_initialized()); 830 CHECK(!handle->is_initialized());
816 CompletionCallback* callback = it->second.callback; 831 CompletionCallback* callback = it->second.callback;
817 int result = it->second.result; 832 int result = it->second.result;
818 pending_callback_map_.erase(it); 833 pending_callback_map_.erase(it);
819 callback->Run(result); 834 callback->Run(result);
820 } 835 }
821 836
822 } // namespace internal 837 } // namespace internal
823 838
824 } // namespace net 839 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/client_socket_pool_base.h ('k') | net/socket/client_socket_pool_base_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698