| OLD | NEW |
| 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 #include "net/socket/client_socket_pool_base.h" | 5 #include "net/socket/client_socket_pool_base.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| 11 #include "base/format_macros.h" | 11 #include "base/format_macros.h" |
| 12 #include "base/location.h" | 12 #include "base/location.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" |
| 15 #include "base/single_thread_task_runner.h" | 15 #include "base/single_thread_task_runner.h" |
| 16 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
| 17 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
| 18 #include "base/threading/thread_task_runner_handle.h" | 18 #include "base/threading/thread_task_runner_handle.h" |
| 19 #include "base/time/time.h" | 19 #include "base/time/time.h" |
| 20 #include "base/trace_event/trace_event.h" | 20 #include "base/trace_event/trace_event.h" |
| 21 #include "base/values.h" | 21 #include "base/values.h" |
| 22 #include "net/base/net_errors.h" | 22 #include "net/base/net_errors.h" |
| 23 #include "net/log/net_log.h" | 23 #include "net/log/net_log.h" |
| 24 #include "net/log/net_log_event_type.h" |
| 24 | 25 |
| 25 using base::TimeDelta; | 26 using base::TimeDelta; |
| 26 | 27 |
| 27 namespace net { | 28 namespace net { |
| 28 | 29 |
| 29 namespace { | 30 namespace { |
| 30 | 31 |
| 31 // Indicate whether or not we should establish a new transport layer connection | 32 // Indicate whether or not we should establish a new transport layer connection |
| 32 // after a certain timeout has passed without receiving an ACK. | 33 // after a certain timeout has passed without receiving an ACK. |
| 33 bool g_connect_backup_jobs_enabled = true; | 34 bool g_connect_backup_jobs_enabled = true; |
| 34 | 35 |
| 35 } // namespace | 36 } // namespace |
| 36 | 37 |
| 37 ConnectJob::ConnectJob(const std::string& group_name, | 38 ConnectJob::ConnectJob(const std::string& group_name, |
| 38 base::TimeDelta timeout_duration, | 39 base::TimeDelta timeout_duration, |
| 39 RequestPriority priority, | 40 RequestPriority priority, |
| 40 ClientSocketPool::RespectLimits respect_limits, | 41 ClientSocketPool::RespectLimits respect_limits, |
| 41 Delegate* delegate, | 42 Delegate* delegate, |
| 42 const BoundNetLog& net_log) | 43 const BoundNetLog& net_log) |
| 43 : group_name_(group_name), | 44 : group_name_(group_name), |
| 44 timeout_duration_(timeout_duration), | 45 timeout_duration_(timeout_duration), |
| 45 priority_(priority), | 46 priority_(priority), |
| 46 respect_limits_(respect_limits), | 47 respect_limits_(respect_limits), |
| 47 delegate_(delegate), | 48 delegate_(delegate), |
| 48 net_log_(net_log), | 49 net_log_(net_log), |
| 49 idle_(true) { | 50 idle_(true) { |
| 50 DCHECK(!group_name.empty()); | 51 DCHECK(!group_name.empty()); |
| 51 DCHECK(delegate); | 52 DCHECK(delegate); |
| 52 net_log.BeginEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB, | 53 net_log.BeginEvent(NetLogEventType::SOCKET_POOL_CONNECT_JOB, |
| 53 NetLog::StringCallback("group_name", &group_name_)); | 54 NetLog::StringCallback("group_name", &group_name_)); |
| 54 } | 55 } |
| 55 | 56 |
| 56 ConnectJob::~ConnectJob() { | 57 ConnectJob::~ConnectJob() { |
| 57 net_log().EndEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB); | 58 net_log().EndEvent(NetLogEventType::SOCKET_POOL_CONNECT_JOB); |
| 58 } | 59 } |
| 59 | 60 |
| 60 std::unique_ptr<StreamSocket> ConnectJob::PassSocket() { | 61 std::unique_ptr<StreamSocket> ConnectJob::PassSocket() { |
| 61 return std::move(socket_); | 62 return std::move(socket_); |
| 62 } | 63 } |
| 63 | 64 |
| 64 int ConnectJob::Connect() { | 65 int ConnectJob::Connect() { |
| 65 if (!timeout_duration_.is_zero()) | 66 if (!timeout_duration_.is_zero()) |
| 66 timer_.Start(FROM_HERE, timeout_duration_, this, &ConnectJob::OnTimeout); | 67 timer_.Start(FROM_HERE, timeout_duration_, this, &ConnectJob::OnTimeout); |
| 67 | 68 |
| 68 idle_ = false; | 69 idle_ = false; |
| 69 | 70 |
| 70 LogConnectStart(); | 71 LogConnectStart(); |
| 71 | 72 |
| 72 int rv = ConnectInternal(); | 73 int rv = ConnectInternal(); |
| 73 | 74 |
| 74 if (rv != ERR_IO_PENDING) { | 75 if (rv != ERR_IO_PENDING) { |
| 75 LogConnectCompletion(rv); | 76 LogConnectCompletion(rv); |
| 76 delegate_ = NULL; | 77 delegate_ = NULL; |
| 77 } | 78 } |
| 78 | 79 |
| 79 return rv; | 80 return rv; |
| 80 } | 81 } |
| 81 | 82 |
| 82 void ConnectJob::SetSocket(std::unique_ptr<StreamSocket> socket) { | 83 void ConnectJob::SetSocket(std::unique_ptr<StreamSocket> socket) { |
| 83 if (socket) { | 84 if (socket) { |
| 84 net_log().AddEvent(NetLog::TYPE_CONNECT_JOB_SET_SOCKET, | 85 net_log().AddEvent(NetLogEventType::CONNECT_JOB_SET_SOCKET, |
| 85 socket->NetLog().source().ToEventParametersCallback()); | 86 socket->NetLog().source().ToEventParametersCallback()); |
| 86 } | 87 } |
| 87 socket_ = std::move(socket); | 88 socket_ = std::move(socket); |
| 88 } | 89 } |
| 89 | 90 |
| 90 void ConnectJob::NotifyDelegateOfCompletion(int rv) { | 91 void ConnectJob::NotifyDelegateOfCompletion(int rv) { |
| 91 TRACE_EVENT0("net", "ConnectJob::NotifyDelegateOfCompletion"); | 92 TRACE_EVENT0("net", "ConnectJob::NotifyDelegateOfCompletion"); |
| 92 // The delegate will own |this|. | 93 // The delegate will own |this|. |
| 93 Delegate* delegate = delegate_; | 94 Delegate* delegate = delegate_; |
| 94 delegate_ = NULL; | 95 delegate_ = NULL; |
| 95 | 96 |
| 96 LogConnectCompletion(rv); | 97 LogConnectCompletion(rv); |
| 97 delegate->OnConnectJobComplete(rv, this); | 98 delegate->OnConnectJobComplete(rv, this); |
| 98 } | 99 } |
| 99 | 100 |
| 100 void ConnectJob::ResetTimer(base::TimeDelta remaining_time) { | 101 void ConnectJob::ResetTimer(base::TimeDelta remaining_time) { |
| 101 timer_.Stop(); | 102 timer_.Stop(); |
| 102 timer_.Start(FROM_HERE, remaining_time, this, &ConnectJob::OnTimeout); | 103 timer_.Start(FROM_HERE, remaining_time, this, &ConnectJob::OnTimeout); |
| 103 } | 104 } |
| 104 | 105 |
| 105 void ConnectJob::LogConnectStart() { | 106 void ConnectJob::LogConnectStart() { |
| 106 connect_timing_.connect_start = base::TimeTicks::Now(); | 107 connect_timing_.connect_start = base::TimeTicks::Now(); |
| 107 net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT); | 108 net_log().BeginEvent(NetLogEventType::SOCKET_POOL_CONNECT_JOB_CONNECT); |
| 108 } | 109 } |
| 109 | 110 |
| 110 void ConnectJob::LogConnectCompletion(int net_error) { | 111 void ConnectJob::LogConnectCompletion(int net_error) { |
| 111 connect_timing_.connect_end = base::TimeTicks::Now(); | 112 connect_timing_.connect_end = base::TimeTicks::Now(); |
| 112 net_log().EndEventWithNetErrorCode( | 113 net_log().EndEventWithNetErrorCode( |
| 113 NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT, net_error); | 114 NetLogEventType::SOCKET_POOL_CONNECT_JOB_CONNECT, net_error); |
| 114 } | 115 } |
| 115 | 116 |
| 116 void ConnectJob::OnTimeout() { | 117 void ConnectJob::OnTimeout() { |
| 117 // Make sure the socket is NULL before calling into |delegate|. | 118 // Make sure the socket is NULL before calling into |delegate|. |
| 118 SetSocket(std::unique_ptr<StreamSocket>()); | 119 SetSocket(std::unique_ptr<StreamSocket>()); |
| 119 | 120 |
| 120 net_log_.AddEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT); | 121 net_log_.AddEvent(NetLogEventType::SOCKET_POOL_CONNECT_JOB_TIMED_OUT); |
| 121 | 122 |
| 122 NotifyDelegateOfCompletion(ERR_TIMED_OUT); | 123 NotifyDelegateOfCompletion(ERR_TIMED_OUT); |
| 123 } | 124 } |
| 124 | 125 |
| 125 namespace internal { | 126 namespace internal { |
| 126 | 127 |
| 127 ClientSocketPoolBaseHelper::Request::Request( | 128 ClientSocketPoolBaseHelper::Request::Request( |
| 128 ClientSocketHandle* handle, | 129 ClientSocketHandle* handle, |
| 129 const CompletionCallback& callback, | 130 const CompletionCallback& callback, |
| 130 RequestPriority priority, | 131 RequestPriority priority, |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 | 262 |
| 262 int ClientSocketPoolBaseHelper::RequestSocket( | 263 int ClientSocketPoolBaseHelper::RequestSocket( |
| 263 const std::string& group_name, | 264 const std::string& group_name, |
| 264 std::unique_ptr<const Request> request) { | 265 std::unique_ptr<const Request> request) { |
| 265 CHECK(!request->callback().is_null()); | 266 CHECK(!request->callback().is_null()); |
| 266 CHECK(request->handle()); | 267 CHECK(request->handle()); |
| 267 | 268 |
| 268 // Cleanup any timed-out idle sockets. | 269 // Cleanup any timed-out idle sockets. |
| 269 CleanupIdleSockets(false); | 270 CleanupIdleSockets(false); |
| 270 | 271 |
| 271 request->net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL); | 272 request->net_log().BeginEvent(NetLogEventType::SOCKET_POOL); |
| 272 Group* group = GetOrCreateGroup(group_name); | 273 Group* group = GetOrCreateGroup(group_name); |
| 273 | 274 |
| 274 int rv = RequestSocketInternal(group_name, *request); | 275 int rv = RequestSocketInternal(group_name, *request); |
| 275 if (rv != ERR_IO_PENDING) { | 276 if (rv != ERR_IO_PENDING) { |
| 276 request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv); | 277 request->net_log().EndEventWithNetErrorCode( |
| 278 NetLogEventType::SOCKET_POOL, rv); |
| 277 CHECK(!request->handle()->is_initialized()); | 279 CHECK(!request->handle()->is_initialized()); |
| 278 request.reset(); | 280 request.reset(); |
| 279 } else { | 281 } else { |
| 280 group->InsertPendingRequest(std::move(request)); | 282 group->InsertPendingRequest(std::move(request)); |
| 281 // Have to do this asynchronously, as closing sockets in higher level pools | 283 // Have to do this asynchronously, as closing sockets in higher level pools |
| 282 // call back in to |this|, which will cause all sorts of fun and exciting | 284 // call back in to |this|, which will cause all sorts of fun and exciting |
| 283 // re-entrancy issues if the socket pool is doing something else at the | 285 // re-entrancy issues if the socket pool is doing something else at the |
| 284 // time. | 286 // time. |
| 285 if (group->CanUseAdditionalSocketSlot(max_sockets_per_group_)) { | 287 if (group->CanUseAdditionalSocketSlot(max_sockets_per_group_)) { |
| 286 base::ThreadTaskRunnerHandle::Get()->PostTask( | 288 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 300 DCHECK(request.callback().is_null()); | 302 DCHECK(request.callback().is_null()); |
| 301 DCHECK(!request.handle()); | 303 DCHECK(!request.handle()); |
| 302 | 304 |
| 303 // Cleanup any timed-out idle sockets. | 305 // Cleanup any timed-out idle sockets. |
| 304 CleanupIdleSockets(false); | 306 CleanupIdleSockets(false); |
| 305 | 307 |
| 306 if (num_sockets > max_sockets_per_group_) { | 308 if (num_sockets > max_sockets_per_group_) { |
| 307 num_sockets = max_sockets_per_group_; | 309 num_sockets = max_sockets_per_group_; |
| 308 } | 310 } |
| 309 | 311 |
| 310 request.net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL_CONNECTING_N_SOCKETS, | 312 request.net_log().BeginEvent( |
| 311 NetLog::IntCallback("num_sockets", num_sockets)); | 313 NetLogEventType::SOCKET_POOL_CONNECTING_N_SOCKETS, |
| 314 NetLog::IntCallback("num_sockets", num_sockets)); |
| 312 | 315 |
| 313 Group* group = GetOrCreateGroup(group_name); | 316 Group* group = GetOrCreateGroup(group_name); |
| 314 | 317 |
| 315 // RequestSocketsInternal() may delete the group. | 318 // RequestSocketsInternal() may delete the group. |
| 316 bool deleted_group = false; | 319 bool deleted_group = false; |
| 317 | 320 |
| 318 int rv = OK; | 321 int rv = OK; |
| 319 for (int num_iterations_left = num_sockets; | 322 for (int num_iterations_left = num_sockets; |
| 320 group->NumActiveSocketSlots() < num_sockets && | 323 group->NumActiveSocketSlots() < num_sockets && |
| 321 num_iterations_left > 0 ; num_iterations_left--) { | 324 num_iterations_left > 0 ; num_iterations_left--) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 334 break; | 337 break; |
| 335 } | 338 } |
| 336 } | 339 } |
| 337 | 340 |
| 338 if (!deleted_group && group->IsEmpty()) | 341 if (!deleted_group && group->IsEmpty()) |
| 339 RemoveGroup(group_name); | 342 RemoveGroup(group_name); |
| 340 | 343 |
| 341 if (rv == ERR_IO_PENDING) | 344 if (rv == ERR_IO_PENDING) |
| 342 rv = OK; | 345 rv = OK; |
| 343 request.net_log().EndEventWithNetErrorCode( | 346 request.net_log().EndEventWithNetErrorCode( |
| 344 NetLog::TYPE_SOCKET_POOL_CONNECTING_N_SOCKETS, rv); | 347 NetLogEventType::SOCKET_POOL_CONNECTING_N_SOCKETS, rv); |
| 345 } | 348 } |
| 346 | 349 |
| 347 int ClientSocketPoolBaseHelper::RequestSocketInternal( | 350 int ClientSocketPoolBaseHelper::RequestSocketInternal( |
| 348 const std::string& group_name, | 351 const std::string& group_name, |
| 349 const Request& request) { | 352 const Request& request) { |
| 350 ClientSocketHandle* const handle = request.handle(); | 353 ClientSocketHandle* const handle = request.handle(); |
| 351 const bool preconnecting = !handle; | 354 const bool preconnecting = !handle; |
| 352 Group* group = GetOrCreateGroup(group_name); | 355 Group* group = GetOrCreateGroup(group_name); |
| 353 | 356 |
| 354 if (!(request.flags() & NO_IDLE_SOCKETS)) { | 357 if (!(request.flags() & NO_IDLE_SOCKETS)) { |
| 355 // Try to reuse a socket. | 358 // Try to reuse a socket. |
| 356 if (AssignIdleSocketToRequest(request, group)) | 359 if (AssignIdleSocketToRequest(request, group)) |
| 357 return OK; | 360 return OK; |
| 358 } | 361 } |
| 359 | 362 |
| 360 // If there are more ConnectJobs than pending requests, don't need to do | 363 // If there are more ConnectJobs than pending requests, don't need to do |
| 361 // anything. Can just wait for the extra job to connect, and then assign it | 364 // anything. Can just wait for the extra job to connect, and then assign it |
| 362 // to the request. | 365 // to the request. |
| 363 if (!preconnecting && group->TryToUseUnassignedConnectJob()) | 366 if (!preconnecting && group->TryToUseUnassignedConnectJob()) |
| 364 return ERR_IO_PENDING; | 367 return ERR_IO_PENDING; |
| 365 | 368 |
| 366 // Can we make another active socket now? | 369 // Can we make another active socket now? |
| 367 if (!group->HasAvailableSocketSlot(max_sockets_per_group_) && | 370 if (!group->HasAvailableSocketSlot(max_sockets_per_group_) && |
| 368 request.respect_limits() == ClientSocketPool::RespectLimits::ENABLED) { | 371 request.respect_limits() == ClientSocketPool::RespectLimits::ENABLED) { |
| 369 // TODO(willchan): Consider whether or not we need to close a socket in a | 372 // TODO(willchan): Consider whether or not we need to close a socket in a |
| 370 // higher layered group. I don't think this makes sense since we would just | 373 // higher layered group. I don't think this makes sense since we would just |
| 371 // reuse that socket then if we needed one and wouldn't make it down to this | 374 // reuse that socket then if we needed one and wouldn't make it down to this |
| 372 // layer. | 375 // layer. |
| 373 request.net_log().AddEvent( | 376 request.net_log().AddEvent( |
| 374 NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS_PER_GROUP); | 377 NetLogEventType::SOCKET_POOL_STALLED_MAX_SOCKETS_PER_GROUP); |
| 375 return ERR_IO_PENDING; | 378 return ERR_IO_PENDING; |
| 376 } | 379 } |
| 377 | 380 |
| 378 if (ReachedMaxSocketsLimit() && | 381 if (ReachedMaxSocketsLimit() && |
| 379 request.respect_limits() == ClientSocketPool::RespectLimits::ENABLED) { | 382 request.respect_limits() == ClientSocketPool::RespectLimits::ENABLED) { |
| 380 // NOTE(mmenke): Wonder if we really need different code for each case | 383 // NOTE(mmenke): Wonder if we really need different code for each case |
| 381 // here. Only reason for them now seems to be preconnects. | 384 // here. Only reason for them now seems to be preconnects. |
| 382 if (idle_socket_count() > 0) { | 385 if (idle_socket_count() > 0) { |
| 383 // There's an idle socket in this pool. Either that's because there's | 386 // There's an idle socket in this pool. Either that's because there's |
| 384 // still one in this group, but we got here due to preconnecting bypassing | 387 // still one in this group, but we got here due to preconnecting bypassing |
| 385 // idle sockets, or because there's an idle socket in another group. | 388 // idle sockets, or because there's an idle socket in another group. |
| 386 bool closed = CloseOneIdleSocketExceptInGroup(group); | 389 bool closed = CloseOneIdleSocketExceptInGroup(group); |
| 387 if (preconnecting && !closed) | 390 if (preconnecting && !closed) |
| 388 return ERR_PRECONNECT_MAX_SOCKET_LIMIT; | 391 return ERR_PRECONNECT_MAX_SOCKET_LIMIT; |
| 389 } else { | 392 } else { |
| 390 // We could check if we really have a stalled group here, but it requires | 393 // We could check if we really have a stalled group here, but it requires |
| 391 // a scan of all groups, so just flip a flag here, and do the check later. | 394 // a scan of all groups, so just flip a flag here, and do the check later. |
| 392 request.net_log().AddEvent(NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS); | 395 request.net_log().AddEvent( |
| 396 NetLogEventType::SOCKET_POOL_STALLED_MAX_SOCKETS); |
| 393 return ERR_IO_PENDING; | 397 return ERR_IO_PENDING; |
| 394 } | 398 } |
| 395 } | 399 } |
| 396 | 400 |
| 397 // We couldn't find a socket to reuse, and there's space to allocate one, | 401 // We couldn't find a socket to reuse, and there's space to allocate one, |
| 398 // so allocate and connect a new one. | 402 // so allocate and connect a new one. |
| 399 std::unique_ptr<ConnectJob> connect_job( | 403 std::unique_ptr<ConnectJob> connect_job( |
| 400 connect_job_factory_->NewConnectJob(group_name, request, this)); | 404 connect_job_factory_->NewConnectJob(group_name, request, this)); |
| 401 | 405 |
| 402 int rv = connect_job->Connect(); | 406 int rv = connect_job->Connect(); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 group, request.net_log()); | 500 group, request.net_log()); |
| 497 return true; | 501 return true; |
| 498 } | 502 } |
| 499 | 503 |
| 500 return false; | 504 return false; |
| 501 } | 505 } |
| 502 | 506 |
| 503 // static | 507 // static |
| 504 void ClientSocketPoolBaseHelper::LogBoundConnectJobToRequest( | 508 void ClientSocketPoolBaseHelper::LogBoundConnectJobToRequest( |
| 505 const NetLog::Source& connect_job_source, const Request& request) { | 509 const NetLog::Source& connect_job_source, const Request& request) { |
| 506 request.net_log().AddEvent(NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB, | 510 request.net_log().AddEvent(NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB, |
| 507 connect_job_source.ToEventParametersCallback()); | 511 connect_job_source.ToEventParametersCallback()); |
| 508 } | 512 } |
| 509 | 513 |
| 510 void ClientSocketPoolBaseHelper::CancelRequest( | 514 void ClientSocketPoolBaseHelper::CancelRequest( |
| 511 const std::string& group_name, ClientSocketHandle* handle) { | 515 const std::string& group_name, ClientSocketHandle* handle) { |
| 512 PendingCallbackMap::iterator callback_it = pending_callback_map_.find(handle); | 516 PendingCallbackMap::iterator callback_it = pending_callback_map_.find(handle); |
| 513 if (callback_it != pending_callback_map_.end()) { | 517 if (callback_it != pending_callback_map_.end()) { |
| 514 int result = callback_it->second.result; | 518 int result = callback_it->second.result; |
| 515 pending_callback_map_.erase(callback_it); | 519 pending_callback_map_.erase(callback_it); |
| 516 std::unique_ptr<StreamSocket> socket = handle->PassSocket(); | 520 std::unique_ptr<StreamSocket> socket = handle->PassSocket(); |
| 517 if (socket) { | 521 if (socket) { |
| 518 if (result != OK) | 522 if (result != OK) |
| 519 socket->Disconnect(); | 523 socket->Disconnect(); |
| 520 ReleaseSocket(handle->group_name(), std::move(socket), handle->id()); | 524 ReleaseSocket(handle->group_name(), std::move(socket), handle->id()); |
| 521 } | 525 } |
| 522 return; | 526 return; |
| 523 } | 527 } |
| 524 | 528 |
| 525 CHECK(base::ContainsKey(group_map_, group_name)); | 529 CHECK(base::ContainsKey(group_map_, group_name)); |
| 526 | 530 |
| 527 Group* group = GetOrCreateGroup(group_name); | 531 Group* group = GetOrCreateGroup(group_name); |
| 528 | 532 |
| 529 // Search pending_requests for matching handle. | 533 // Search pending_requests for matching handle. |
| 530 std::unique_ptr<const Request> request = | 534 std::unique_ptr<const Request> request = |
| 531 group->FindAndRemovePendingRequest(handle); | 535 group->FindAndRemovePendingRequest(handle); |
| 532 if (request) { | 536 if (request) { |
| 533 request->net_log().AddEvent(NetLog::TYPE_CANCELLED); | 537 request->net_log().AddEvent(NetLogEventType::CANCELLED); |
| 534 request->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL); | 538 request->net_log().EndEvent(NetLogEventType::SOCKET_POOL); |
| 535 | 539 |
| 536 // We let the job run, unless we're at the socket limit and there is | 540 // We let the job run, unless we're at the socket limit and there is |
| 537 // not another request waiting on the job. | 541 // not another request waiting on the job. |
| 538 if (group->jobs().size() > group->pending_request_count() && | 542 if (group->jobs().size() > group->pending_request_count() && |
| 539 ReachedMaxSocketsLimit()) { | 543 ReachedMaxSocketsLimit()) { |
| 540 RemoveConnectJob(*group->jobs().begin(), group); | 544 RemoveConnectJob(*group->jobs().begin(), group); |
| 541 CheckForStalledSocketGroups(); | 545 CheckForStalledSocketGroups(); |
| 542 } | 546 } |
| 543 } | 547 } |
| 544 } | 548 } |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 864 | 868 |
| 865 if (result == OK) { | 869 if (result == OK) { |
| 866 DCHECK(socket.get()); | 870 DCHECK(socket.get()); |
| 867 RemoveConnectJob(job, group); | 871 RemoveConnectJob(job, group); |
| 868 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); | 872 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); |
| 869 if (request) { | 873 if (request) { |
| 870 LogBoundConnectJobToRequest(job_log.source(), *request); | 874 LogBoundConnectJobToRequest(job_log.source(), *request); |
| 871 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, | 875 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, |
| 872 connect_timing, request->handle(), base::TimeDelta(), group, | 876 connect_timing, request->handle(), base::TimeDelta(), group, |
| 873 request->net_log()); | 877 request->net_log()); |
| 874 request->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL); | 878 request->net_log().EndEvent(NetLogEventType::SOCKET_POOL); |
| 875 InvokeUserCallbackLater(request->handle(), request->callback(), result); | 879 InvokeUserCallbackLater(request->handle(), request->callback(), result); |
| 876 } else { | 880 } else { |
| 877 AddIdleSocket(std::move(socket), group); | 881 AddIdleSocket(std::move(socket), group); |
| 878 OnAvailableSocketSlot(group_name, group); | 882 OnAvailableSocketSlot(group_name, group); |
| 879 CheckForStalledSocketGroups(); | 883 CheckForStalledSocketGroups(); |
| 880 } | 884 } |
| 881 } else { | 885 } else { |
| 882 // If we got a socket, it must contain error information so pass that | 886 // If we got a socket, it must contain error information so pass that |
| 883 // up so that the caller can retrieve it. | 887 // up so that the caller can retrieve it. |
| 884 bool handed_out_socket = false; | 888 bool handed_out_socket = false; |
| 885 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); | 889 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); |
| 886 if (request) { | 890 if (request) { |
| 887 LogBoundConnectJobToRequest(job_log.source(), *request); | 891 LogBoundConnectJobToRequest(job_log.source(), *request); |
| 888 job->GetAdditionalErrorState(request->handle()); | 892 job->GetAdditionalErrorState(request->handle()); |
| 889 RemoveConnectJob(job, group); | 893 RemoveConnectJob(job, group); |
| 890 if (socket.get()) { | 894 if (socket.get()) { |
| 891 handed_out_socket = true; | 895 handed_out_socket = true; |
| 892 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, | 896 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, |
| 893 connect_timing, request->handle(), base::TimeDelta(), | 897 connect_timing, request->handle(), base::TimeDelta(), |
| 894 group, request->net_log()); | 898 group, request->net_log()); |
| 895 } | 899 } |
| 896 request->net_log().EndEventWithNetErrorCode( | 900 request->net_log().EndEventWithNetErrorCode( |
| 897 NetLog::TYPE_SOCKET_POOL, result); | 901 NetLogEventType::SOCKET_POOL, result); |
| 898 InvokeUserCallbackLater(request->handle(), request->callback(), result); | 902 InvokeUserCallbackLater(request->handle(), request->callback(), result); |
| 899 } else { | 903 } else { |
| 900 RemoveConnectJob(job, group); | 904 RemoveConnectJob(job, group); |
| 901 } | 905 } |
| 902 if (!handed_out_socket) { | 906 if (!handed_out_socket) { |
| 903 OnAvailableSocketSlot(group_name, group); | 907 OnAvailableSocketSlot(group_name, group); |
| 904 CheckForStalledSocketGroups(); | 908 CheckForStalledSocketGroups(); |
| 905 } | 909 } |
| 906 } | 910 } |
| 907 } | 911 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 949 return; | 953 return; |
| 950 } | 954 } |
| 951 | 955 |
| 952 int rv = RequestSocketInternal(group_name, *next_request); | 956 int rv = RequestSocketInternal(group_name, *next_request); |
| 953 if (rv != ERR_IO_PENDING) { | 957 if (rv != ERR_IO_PENDING) { |
| 954 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); | 958 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); |
| 955 DCHECK(request); | 959 DCHECK(request); |
| 956 if (group->IsEmpty()) | 960 if (group->IsEmpty()) |
| 957 RemoveGroup(group_name); | 961 RemoveGroup(group_name); |
| 958 | 962 |
| 959 request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv); | 963 request->net_log().EndEventWithNetErrorCode( |
| 964 NetLogEventType::SOCKET_POOL, rv); |
| 960 InvokeUserCallbackLater(request->handle(), request->callback(), rv); | 965 InvokeUserCallbackLater(request->handle(), request->callback(), rv); |
| 961 } | 966 } |
| 962 } | 967 } |
| 963 | 968 |
| 964 void ClientSocketPoolBaseHelper::HandOutSocket( | 969 void ClientSocketPoolBaseHelper::HandOutSocket( |
| 965 std::unique_ptr<StreamSocket> socket, | 970 std::unique_ptr<StreamSocket> socket, |
| 966 ClientSocketHandle::SocketReuseType reuse_type, | 971 ClientSocketHandle::SocketReuseType reuse_type, |
| 967 const LoadTimingInfo::ConnectTiming& connect_timing, | 972 const LoadTimingInfo::ConnectTiming& connect_timing, |
| 968 ClientSocketHandle* handle, | 973 ClientSocketHandle* handle, |
| 969 base::TimeDelta idle_time, | 974 base::TimeDelta idle_time, |
| 970 Group* group, | 975 Group* group, |
| 971 const BoundNetLog& net_log) { | 976 const BoundNetLog& net_log) { |
| 972 DCHECK(socket); | 977 DCHECK(socket); |
| 973 handle->SetSocket(std::move(socket)); | 978 handle->SetSocket(std::move(socket)); |
| 974 handle->set_reuse_type(reuse_type); | 979 handle->set_reuse_type(reuse_type); |
| 975 handle->set_idle_time(idle_time); | 980 handle->set_idle_time(idle_time); |
| 976 handle->set_pool_id(pool_generation_number_); | 981 handle->set_pool_id(pool_generation_number_); |
| 977 handle->set_connect_timing(connect_timing); | 982 handle->set_connect_timing(connect_timing); |
| 978 | 983 |
| 979 if (reuse_type == ClientSocketHandle::REUSED_IDLE) { | 984 if (reuse_type == ClientSocketHandle::REUSED_IDLE) { |
| 980 net_log.AddEvent( | 985 net_log.AddEvent( |
| 981 NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET, | 986 NetLogEventType::SOCKET_POOL_REUSED_AN_EXISTING_SOCKET, |
| 982 NetLog::IntCallback("idle_ms", | 987 NetLog::IntCallback("idle_ms", |
| 983 static_cast<int>(idle_time.InMilliseconds()))); | 988 static_cast<int>(idle_time.InMilliseconds()))); |
| 984 | 989 |
| 985 UMA_HISTOGRAM_COUNTS_1000("Net.Socket.IdleSocketReuseTime", | 990 UMA_HISTOGRAM_COUNTS_1000("Net.Socket.IdleSocketReuseTime", |
| 986 idle_time.InSeconds()); | 991 idle_time.InSeconds()); |
| 987 } | 992 } |
| 988 | 993 |
| 989 if (reuse_type != ClientSocketHandle::UNUSED) { | 994 if (reuse_type != ClientSocketHandle::UNUSED) { |
| 990 // The socket being handed out is no longer considered idle, but was | 995 // The socket being handed out is no longer considered idle, but was |
| 991 // considered idle until just before this method was called. | 996 // considered idle until just before this method was called. |
| 992 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.Socket.NumIdleSockets", | 997 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.Socket.NumIdleSockets", |
| 993 idle_socket_count() + 1, 1, 256, 50); | 998 idle_socket_count() + 1, 1, 256, 50); |
| 994 } | 999 } |
| 995 | 1000 |
| 996 net_log.AddEvent( | 1001 net_log.AddEvent( |
| 997 NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET, | 1002 NetLogEventType::SOCKET_POOL_BOUND_TO_SOCKET, |
| 998 handle->socket()->NetLog().source().ToEventParametersCallback()); | 1003 handle->socket()->NetLog().source().ToEventParametersCallback()); |
| 999 | 1004 |
| 1000 handed_out_socket_count_++; | 1005 handed_out_socket_count_++; |
| 1001 group->IncrementActiveSocketCount(); | 1006 group->IncrementActiveSocketCount(); |
| 1002 } | 1007 } |
| 1003 | 1008 |
| 1004 void ClientSocketPoolBaseHelper::AddIdleSocket( | 1009 void ClientSocketPoolBaseHelper::AddIdleSocket( |
| 1005 std::unique_ptr<StreamSocket> socket, | 1010 std::unique_ptr<StreamSocket> socket, |
| 1006 Group* group) { | 1011 Group* group) { |
| 1007 DCHECK(socket); | 1012 DCHECK(socket); |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1222 StartBackupJobTimer(group_name, pool); | 1227 StartBackupJobTimer(group_name, pool); |
| 1223 return; | 1228 return; |
| 1224 } | 1229 } |
| 1225 | 1230 |
| 1226 if (pending_requests_.empty()) | 1231 if (pending_requests_.empty()) |
| 1227 return; | 1232 return; |
| 1228 | 1233 |
| 1229 std::unique_ptr<ConnectJob> backup_job = | 1234 std::unique_ptr<ConnectJob> backup_job = |
| 1230 pool->connect_job_factory_->NewConnectJob( | 1235 pool->connect_job_factory_->NewConnectJob( |
| 1231 group_name, *pending_requests_.FirstMax().value(), pool); | 1236 group_name, *pending_requests_.FirstMax().value(), pool); |
| 1232 backup_job->net_log().AddEvent(NetLog::TYPE_BACKUP_CONNECT_JOB_CREATED); | 1237 backup_job->net_log().AddEvent(NetLogEventType::BACKUP_CONNECT_JOB_CREATED); |
| 1233 int rv = backup_job->Connect(); | 1238 int rv = backup_job->Connect(); |
| 1234 pool->connecting_socket_count_++; | 1239 pool->connecting_socket_count_++; |
| 1235 ConnectJob* raw_backup_job = backup_job.get(); | 1240 ConnectJob* raw_backup_job = backup_job.get(); |
| 1236 AddJob(std::move(backup_job), false); | 1241 AddJob(std::move(backup_job), false); |
| 1237 if (rv != ERR_IO_PENDING) | 1242 if (rv != ERR_IO_PENDING) |
| 1238 pool->OnConnectJobComplete(rv, raw_backup_job); | 1243 pool->OnConnectJobComplete(rv, raw_backup_job); |
| 1239 } | 1244 } |
| 1240 | 1245 |
| 1241 void ClientSocketPoolBaseHelper::Group::SanityCheck() { | 1246 void ClientSocketPoolBaseHelper::Group::SanityCheck() { |
| 1242 DCHECK_LE(unassigned_job_count_, jobs_.size()); | 1247 DCHECK_LE(unassigned_job_count_, jobs_.size()); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1320 // If there are no more requests, kill the backup timer. | 1325 // If there are no more requests, kill the backup timer. |
| 1321 if (pending_requests_.empty()) | 1326 if (pending_requests_.empty()) |
| 1322 backup_job_timer_.Stop(); | 1327 backup_job_timer_.Stop(); |
| 1323 request->CrashIfInvalid(); | 1328 request->CrashIfInvalid(); |
| 1324 return request; | 1329 return request; |
| 1325 } | 1330 } |
| 1326 | 1331 |
| 1327 } // namespace internal | 1332 } // namespace internal |
| 1328 | 1333 |
| 1329 } // namespace net | 1334 } // namespace net |
| OLD | NEW |