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

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

Issue 2363003: Rework the logging for sockets/connectjobs.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 6 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"
(...skipping 24 matching lines...) Expand all
35 base::TimeDelta timeout_duration, 35 base::TimeDelta timeout_duration,
36 Delegate* delegate, 36 Delegate* delegate,
37 const BoundNetLog& net_log) 37 const BoundNetLog& net_log)
38 : group_name_(group_name), 38 : group_name_(group_name),
39 timeout_duration_(timeout_duration), 39 timeout_duration_(timeout_duration),
40 delegate_(delegate), 40 delegate_(delegate),
41 net_log_(net_log), 41 net_log_(net_log),
42 idle_(true) { 42 idle_(true) {
43 DCHECK(!group_name.empty()); 43 DCHECK(!group_name.empty());
44 DCHECK(delegate); 44 DCHECK(delegate);
45 net_log.BeginEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB, NULL);
45 } 46 }
46 47
47 ConnectJob::~ConnectJob() { 48 ConnectJob::~ConnectJob() {
48 if (delegate_ && !idle_) { 49 net_log().EndEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB, NULL);
49 // If the delegate was not NULLed, then NotifyDelegateOfCompletion has
50 // not been called yet. If we've started then we are cancelling.
51 net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL);
52 net_log_.EndEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB, NULL);
53 }
54 } 50 }
55 51
56 int ConnectJob::Connect() { 52 int ConnectJob::Connect() {
57 if (timeout_duration_ != base::TimeDelta()) 53 if (timeout_duration_ != base::TimeDelta())
58 timer_.Start(timeout_duration_, this, &ConnectJob::OnTimeout); 54 timer_.Start(timeout_duration_, this, &ConnectJob::OnTimeout);
59 55
60 net_log_.BeginEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB,
61 new NetLogStringParameter("group_name", group_name_));
62 idle_ = false; 56 idle_ = false;
63 57
58 LogConnectStart();
59
64 int rv = ConnectInternal(); 60 int rv = ConnectInternal();
65 61
66 if (rv != ERR_IO_PENDING) { 62 if (rv != ERR_IO_PENDING) {
63 LogConnectCompletion(rv);
67 delegate_ = NULL; 64 delegate_ = NULL;
68 net_log_.EndEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB, NULL);
69 } 65 }
70 66
71 return rv; 67 return rv;
72 } 68 }
73 69
70 void ConnectJob::set_socket(ClientSocket* socket) {
71 if (socket) {
72 net_log().AddEvent(NetLog::TYPE_CONNECT_JOB_SET_SOCKET,
73 new NetLogSourceParameter("source_dependency",
74 socket->NetLog().source()));
75 }
76 socket_.reset(socket);
77 }
78
74 void ConnectJob::NotifyDelegateOfCompletion(int rv) { 79 void ConnectJob::NotifyDelegateOfCompletion(int rv) {
75 // The delegate will delete |this|. 80 // The delegate will delete |this|.
76 Delegate *delegate = delegate_; 81 Delegate *delegate = delegate_;
77 delegate_ = NULL; 82 delegate_ = NULL;
78 83
79 net_log_.EndEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB, NULL); 84 LogConnectCompletion(rv);
80
81 delegate->OnConnectJobComplete(rv, this); 85 delegate->OnConnectJobComplete(rv, this);
82 } 86 }
83 87
84 void ConnectJob::ResetTimer(base::TimeDelta remaining_time) { 88 void ConnectJob::ResetTimer(base::TimeDelta remaining_time) {
85 timer_.Stop(); 89 timer_.Stop();
86 timer_.Start(remaining_time, this, &ConnectJob::OnTimeout); 90 timer_.Start(remaining_time, this, &ConnectJob::OnTimeout);
87 } 91 }
88 92
93 void ConnectJob::LogConnectStart() {
94 net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT,
95 new NetLogStringParameter("group_name", group_name_));
96 }
97
98 void ConnectJob::LogConnectCompletion(int net_error) {
99 scoped_refptr<NetLog::EventParameters> params;
100 if (net_error != OK)
101 params = new NetLogIntegerParameter("net_error", net_error);
102 net_log().EndEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT, params);
103 }
104
89 void ConnectJob::OnTimeout() { 105 void ConnectJob::OnTimeout() {
90 // Make sure the socket is NULL before calling into |delegate|. 106 // Make sure the socket is NULL before calling into |delegate|.
91 set_socket(NULL); 107 set_socket(NULL);
92 108
93 net_log_.AddEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT, NULL); 109 net_log_.AddEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT, NULL);
94 110
95 NotifyDelegateOfCompletion(ERR_TIMED_OUT); 111 NotifyDelegateOfCompletion(ERR_TIMED_OUT);
96 } 112 }
97 113
98 namespace internal { 114 namespace internal {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 delete idle_socket.socket; 245 delete idle_socket.socket;
230 } 246 }
231 247
232 // See if we already have enough connect jobs or sockets that will be released 248 // See if we already have enough connect jobs or sockets that will be released
233 // soon. 249 // soon.
234 if (group.HasReleasingSockets()) { 250 if (group.HasReleasingSockets()) {
235 return ERR_IO_PENDING; 251 return ERR_IO_PENDING;
236 } 252 }
237 253
238 // We couldn't find a socket to reuse, so allocate and connect a new one. 254 // We couldn't find a socket to reuse, so allocate and connect a new one.
239 BoundNetLog job_net_log = BoundNetLog::Make(
240 request->net_log().net_log(), NetLog::SOURCE_CONNECT_JOB);
241 request->net_log().BeginEvent(
242 NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID,
243 new NetLogIntegerParameter("source_id", job_net_log.source().id));
244
245 scoped_ptr<ConnectJob> connect_job( 255 scoped_ptr<ConnectJob> connect_job(
246 connect_job_factory_->NewConnectJob(group_name, *request, this, 256 connect_job_factory_->NewConnectJob(group_name, *request, this));
247 job_net_log));
248 257
249 int rv = connect_job->Connect(); 258 int rv = connect_job->Connect();
250 if (rv == OK) { 259 if (rv == OK) {
251 request->net_log().EndEvent( 260 LogBoundConnectJobToRequest(connect_job->net_log().source(), request);
252 NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID,
253 new NetLogIntegerParameter("source_id", job_net_log.source().id));
254 HandOutSocket(connect_job->ReleaseSocket(), false /* not reused */, 261 HandOutSocket(connect_job->ReleaseSocket(), false /* not reused */,
255 handle, base::TimeDelta(), &group, request->net_log()); 262 handle, base::TimeDelta(), &group, request->net_log());
256 } else if (rv == ERR_IO_PENDING) { 263 } else if (rv == ERR_IO_PENDING) {
257 // If we don't have any sockets in this group, set a timer for potentially 264 // If we don't have any sockets in this group, set a timer for potentially
258 // creating a new one. If the SYN is lost, this backup socket may complete 265 // creating a new one. If the SYN is lost, this backup socket may complete
259 // before the slow socket, improving end user latency. 266 // before the slow socket, improving end user latency.
260 if (group.IsEmpty() && !group.backup_job && backup_jobs_enabled_) { 267 if (group.IsEmpty() && !group.backup_job && backup_jobs_enabled_) {
261 group.backup_job = connect_job_factory_->NewConnectJob(group_name, 268 group.backup_job = connect_job_factory_->NewConnectJob(group_name,
262 *request, 269 *request,
263 this, 270 this);
264 job_net_log);
265 StartBackupSocketTimer(group_name); 271 StartBackupSocketTimer(group_name);
266 } 272 }
267 273
268 connecting_socket_count_++; 274 connecting_socket_count_++;
269 275
270 ConnectJob* job = connect_job.release(); 276 ConnectJob* job = connect_job.release();
271 group.jobs.insert(job); 277 group.jobs.insert(job);
272 } else { 278 } else {
273 request->net_log().EndEvent( 279 LogBoundConnectJobToRequest(connect_job->net_log().source(), request);
274 NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID,
275 new NetLogIntegerParameter("source_id", job_net_log.source().id));
276 if (group.IsEmpty()) 280 if (group.IsEmpty())
277 group_map_.erase(group_name); 281 group_map_.erase(group_name);
278 } 282 }
279 283
280 return rv; 284 return rv;
281 } 285 }
282 286
287 // static
288 void ClientSocketPoolBaseHelper::LogBoundConnectJobToRequest(
289 const NetLog::Source& connect_job_source, const Request* request) {
290 request->net_log().AddEvent(
291 NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB,
292 new NetLogSourceParameter("source_dependency", connect_job_source));
293 }
294
283 void ClientSocketPoolBaseHelper::StartBackupSocketTimer( 295 void ClientSocketPoolBaseHelper::StartBackupSocketTimer(
284 const std::string& group_name) { 296 const std::string& group_name) {
285 CHECK(ContainsKey(group_map_, group_name)); 297 CHECK(ContainsKey(group_map_, group_name));
286 Group& group = group_map_[group_name]; 298 Group& group = group_map_[group_name];
287 299
288 // Only allow one timer pending to create a backup socket. 300 // Only allow one timer pending to create a backup socket.
289 if (group.backup_task) 301 if (group.backup_task)
290 return; 302 return;
291 303
292 group.backup_task = method_factory_.NewRunnableMethod( 304 group.backup_task = method_factory_.NewRunnableMethod(
(...skipping 12 matching lines...) Expand all
305 group.backup_task = NULL; 317 group.backup_task = NULL;
306 318
307 CHECK(group.backup_job); 319 CHECK(group.backup_job);
308 320
309 // If our backup job is waiting on DNS, or if we can't create any sockets 321 // If our backup job is waiting on DNS, or if we can't create any sockets
310 // right now due to limits, just reset the timer. 322 // right now due to limits, just reset the timer.
311 CHECK(group.jobs.size()); 323 CHECK(group.jobs.size());
312 if (ReachedMaxSocketsLimit() || 324 if (ReachedMaxSocketsLimit() ||
313 !group.HasAvailableSocketSlot(max_sockets_per_group_) || 325 !group.HasAvailableSocketSlot(max_sockets_per_group_) ||
314 (*group.jobs.begin())->GetLoadState() == LOAD_STATE_RESOLVING_HOST) { 326 (*group.jobs.begin())->GetLoadState() == LOAD_STATE_RESOLVING_HOST) {
315 group.backup_job->net_log().AddEvent(
316 NetLog::TYPE_SOCKET_BACKUP_TIMER_EXTENDED, NULL);
317 StartBackupSocketTimer(group_name); 327 StartBackupSocketTimer(group_name);
318 return; 328 return;
319 } 329 }
320 330
321 group.backup_job->net_log().AddEvent(NetLog::TYPE_SOCKET_BACKUP_CREATED, 331 group.backup_job->net_log().AddEvent(NetLog::TYPE_SOCKET_BACKUP_CREATED,
322 NULL); 332 NULL);
323 SIMPLE_STATS_COUNTER("socket.backup_created"); 333 SIMPLE_STATS_COUNTER("socket.backup_created");
324 int rv = group.backup_job->Connect(); 334 int rv = group.backup_job->Connect();
325 connecting_socket_count_++; 335 connecting_socket_count_++;
326 group.jobs.insert(group.backup_job); 336 group.jobs.insert(group.backup_job);
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 scoped_ptr<ClientSocket> socket(job->ReleaseSocket()); 586 scoped_ptr<ClientSocket> socket(job->ReleaseSocket());
577 587
578 BoundNetLog job_log = job->net_log(); 588 BoundNetLog job_log = job->net_log();
579 RemoveConnectJob(job, &group); 589 RemoveConnectJob(job, &group);
580 590
581 if (result == OK) { 591 if (result == OK) {
582 DCHECK(socket.get()); 592 DCHECK(socket.get());
583 if (!group.pending_requests.empty()) { 593 if (!group.pending_requests.empty()) {
584 scoped_ptr<const Request> r(RemoveRequestFromQueue( 594 scoped_ptr<const Request> r(RemoveRequestFromQueue(
585 group.pending_requests.begin(), &group.pending_requests)); 595 group.pending_requests.begin(), &group.pending_requests));
586 r->net_log().EndEvent( 596 LogBoundConnectJobToRequest(job_log.source(), r.get());
587 NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID,
588 new NetLogIntegerParameter("source_id", job_log.source().id));
589 r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, NULL);
590 HandOutSocket( 597 HandOutSocket(
591 socket.release(), false /* unused socket */, r->handle(), 598 socket.release(), false /* unused socket */, r->handle(),
592 base::TimeDelta(), &group, r->net_log()); 599 base::TimeDelta(), &group, r->net_log());
600 r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, NULL);
593 r->callback()->Run(result); 601 r->callback()->Run(result);
594 } else { 602 } else {
595 AddIdleSocket(socket.release(), false /* unused socket */, &group); 603 AddIdleSocket(socket.release(), false /* unused socket */, &group);
596 OnAvailableSocketSlot(group_name, &group); 604 OnAvailableSocketSlot(group_name, &group);
597 } 605 }
598 } else { 606 } else {
599 DCHECK(!socket.get()); 607 DCHECK(!socket.get());
600 if (!group.pending_requests.empty()) { 608 if (!group.pending_requests.empty()) {
601 scoped_ptr<const Request> r(RemoveRequestFromQueue( 609 scoped_ptr<const Request> r(RemoveRequestFromQueue(
602 group.pending_requests.begin(), &group.pending_requests)); 610 group.pending_requests.begin(), &group.pending_requests));
603 r->net_log().EndEvent( 611 LogBoundConnectJobToRequest(job_log.source(), r.get());
604 NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID, 612 r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL,
605 new NetLogIntegerParameter("source_id", job_log.source().id)); 613 new NetLogIntegerParameter("net_error", result));
606 r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, NULL);
607 r->callback()->Run(result); 614 r->callback()->Run(result);
608 } 615 }
609 MaybeOnAvailableSocketSlot(group_name); 616 MaybeOnAvailableSocketSlot(group_name);
610 } 617 }
611 } 618 }
612 619
613 void ClientSocketPoolBaseHelper::OnIPAddressChanged() { 620 void ClientSocketPoolBaseHelper::OnIPAddressChanged() {
614 CloseIdleSockets(); 621 CloseIdleSockets();
615 } 622 }
616 623
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 } 667 }
661 } 668 }
662 669
663 void ClientSocketPoolBaseHelper::ProcessPendingRequest( 670 void ClientSocketPoolBaseHelper::ProcessPendingRequest(
664 const std::string& group_name, Group* group) { 671 const std::string& group_name, Group* group) {
665 int rv = RequestSocketInternal(group_name, *group->pending_requests.begin()); 672 int rv = RequestSocketInternal(group_name, *group->pending_requests.begin());
666 673
667 if (rv != ERR_IO_PENDING) { 674 if (rv != ERR_IO_PENDING) {
668 scoped_ptr<const Request> r(RemoveRequestFromQueue( 675 scoped_ptr<const Request> r(RemoveRequestFromQueue(
669 group->pending_requests.begin(), &group->pending_requests)); 676 group->pending_requests.begin(), &group->pending_requests));
670 r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, NULL); 677
678 scoped_refptr<NetLog::EventParameters> params;
679 if (rv != OK)
680 params = new NetLogIntegerParameter("net_error", rv);
681 r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, params);
671 r->callback()->Run(rv); 682 r->callback()->Run(rv);
672 if (rv != OK) { 683 if (rv != OK) {
673 // |group| may be invalid after the callback, we need to search 684 // |group| may be invalid after the callback, we need to search
674 // |group_map_| again. 685 // |group_map_| again.
675 MaybeOnAvailableSocketSlot(group_name); 686 MaybeOnAvailableSocketSlot(group_name);
676 } 687 }
677 } 688 }
678 } 689 }
679 690
680 void ClientSocketPoolBaseHelper::HandOutSocket( 691 void ClientSocketPoolBaseHelper::HandOutSocket(
681 ClientSocket* socket, 692 ClientSocket* socket,
682 bool reused, 693 bool reused,
683 ClientSocketHandle* handle, 694 ClientSocketHandle* handle,
684 base::TimeDelta idle_time, 695 base::TimeDelta idle_time,
685 Group* group, 696 Group* group,
686 const BoundNetLog& net_log) { 697 const BoundNetLog& net_log) {
687 DCHECK(socket); 698 DCHECK(socket);
688 handle->set_socket(socket); 699 handle->set_socket(socket);
689 handle->set_is_reused(reused); 700 handle->set_is_reused(reused);
690 handle->set_idle_time(idle_time); 701 handle->set_idle_time(idle_time);
691 702
692 if (reused) { 703 if (reused) {
693 net_log.AddEvent( 704 net_log.AddEvent(
694 NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET, 705 NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET,
695 new NetLogIntegerParameter( 706 new NetLogIntegerParameter(
696 "idle_ms", static_cast<int>(idle_time.InMilliseconds()))); 707 "idle_ms", static_cast<int>(idle_time.InMilliseconds())));
697 } 708 }
698 709
699 net_log.AddEvent(NetLog::TYPE_SOCKET_POOL_SOCKET_ID, 710 net_log.AddEvent(NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET,
700 new NetLogIntegerParameter( 711 new NetLogSourceParameter(
701 "source_id", socket->NetLog().source().id)); 712 "source_dependency", socket->NetLog().source()));
702 713
703 handed_out_socket_count_++; 714 handed_out_socket_count_++;
704 group->active_socket_count++; 715 group->active_socket_count++;
705 } 716 }
706 717
707 void ClientSocketPoolBaseHelper::AddIdleSocket( 718 void ClientSocketPoolBaseHelper::AddIdleSocket(
708 ClientSocket* socket, bool used, Group* group) { 719 ClientSocket* socket, bool used, Group* group) {
709 DCHECK(socket); 720 DCHECK(socket);
710 IdleSocket idle_socket; 721 IdleSocket idle_socket;
711 idle_socket.socket = socket; 722 idle_socket.socket = socket;
(...skipping 30 matching lines...) Expand all
742 DCHECK_LE(total, max_sockets_); 753 DCHECK_LE(total, max_sockets_);
743 if (total < max_sockets_) 754 if (total < max_sockets_)
744 return false; 755 return false;
745 LOG(WARNING) << "ReachedMaxSocketsLimit: " << total << "/" << max_sockets_; 756 LOG(WARNING) << "ReachedMaxSocketsLimit: " << total << "/" << max_sockets_;
746 return true; 757 return true;
747 } 758 }
748 759
749 } // namespace internal 760 } // namespace internal
750 761
751 } // namespace net 762 } // 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