OLD | NEW |
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 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 const Request* r, RequestQueue* pending_requests) { | 173 const Request* r, RequestQueue* pending_requests) { |
174 RequestQueue::iterator it = pending_requests->begin(); | 174 RequestQueue::iterator it = pending_requests->begin(); |
175 while (it != pending_requests->end() && r->priority() >= (*it)->priority()) | 175 while (it != pending_requests->end() && r->priority() >= (*it)->priority()) |
176 ++it; | 176 ++it; |
177 pending_requests->insert(it, r); | 177 pending_requests->insert(it, r); |
178 } | 178 } |
179 | 179 |
180 // static | 180 // static |
181 const ClientSocketPoolBaseHelper::Request* | 181 const ClientSocketPoolBaseHelper::Request* |
182 ClientSocketPoolBaseHelper::RemoveRequestFromQueue( | 182 ClientSocketPoolBaseHelper::RemoveRequestFromQueue( |
183 RequestQueue::iterator it, RequestQueue* pending_requests) { | 183 RequestQueue::iterator it, Group* group) { |
184 const Request* req = *it; | 184 const Request* req = *it; |
185 pending_requests->erase(it); | 185 group->mutable_pending_requests()->erase(it); |
| 186 // If there are no more requests, we kill the backup timer. |
| 187 if (group->pending_requests().empty()) |
| 188 group->CleanupBackupJob(); |
186 return req; | 189 return req; |
187 } | 190 } |
188 | 191 |
189 int ClientSocketPoolBaseHelper::RequestSocket( | 192 int ClientSocketPoolBaseHelper::RequestSocket( |
190 const std::string& group_name, | 193 const std::string& group_name, |
191 const Request* request) { | 194 const Request* request) { |
192 request->net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL, NULL); | 195 request->net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL, NULL); |
193 Group* group = GetOrCreateGroup(group_name); | 196 Group* group = GetOrCreateGroup(group_name); |
194 | 197 |
195 int rv = RequestSocketInternal(group_name, request); | 198 int rv = RequestSocketInternal(group_name, request); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 } | 320 } |
318 | 321 |
319 CHECK(ContainsKey(group_map_, group_name)); | 322 CHECK(ContainsKey(group_map_, group_name)); |
320 | 323 |
321 Group* group = GetOrCreateGroup(group_name); | 324 Group* group = GetOrCreateGroup(group_name); |
322 | 325 |
323 // Search pending_requests for matching handle. | 326 // Search pending_requests for matching handle. |
324 RequestQueue::iterator it = group->mutable_pending_requests()->begin(); | 327 RequestQueue::iterator it = group->mutable_pending_requests()->begin(); |
325 for (; it != group->pending_requests().end(); ++it) { | 328 for (; it != group->pending_requests().end(); ++it) { |
326 if ((*it)->handle() == handle) { | 329 if ((*it)->handle() == handle) { |
327 const Request* req = | 330 const Request* req = RemoveRequestFromQueue(it, group); |
328 RemoveRequestFromQueue(it, group->mutable_pending_requests()); | |
329 req->net_log().AddEvent(NetLog::TYPE_CANCELLED, NULL); | 331 req->net_log().AddEvent(NetLog::TYPE_CANCELLED, NULL); |
330 req->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, NULL); | 332 req->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, NULL); |
331 delete req; | 333 delete req; |
332 | 334 |
333 // We let the job run, unless we're at the socket limit. | 335 // We let the job run, unless we're at the socket limit. |
334 if (group->jobs().size() && ReachedMaxSocketsLimit()) { | 336 if (group->jobs().size() && ReachedMaxSocketsLimit()) { |
335 RemoveConnectJob(*group->jobs().begin(), group); | 337 RemoveConnectJob(*group->jobs().begin(), group); |
336 CheckForStalledSocketGroups(); | 338 CheckForStalledSocketGroups(); |
337 } | 339 } |
338 | |
339 // If there are no more requests, we kill the backup timer. | |
340 if (group->pending_requests().empty()) | |
341 group->CleanupBackupJob(); | |
342 break; | 340 break; |
343 } | 341 } |
344 } | 342 } |
345 } | 343 } |
346 | 344 |
347 bool ClientSocketPoolBaseHelper::HasGroup(const std::string& group_name) const { | 345 bool ClientSocketPoolBaseHelper::HasGroup(const std::string& group_name) const { |
348 return ContainsKey(group_map_, group_name); | 346 return ContainsKey(group_map_, group_name); |
349 } | 347 } |
350 | 348 |
351 void ClientSocketPoolBaseHelper::CloseIdleSockets() { | 349 void ClientSocketPoolBaseHelper::CloseIdleSockets() { |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 // this pool, so RemoveConnectJob() may eventually lead to something calling | 627 // this pool, so RemoveConnectJob() may eventually lead to something calling |
630 // Release() on |this| which deletes it in the middle of this function. Hold | 628 // Release() on |this| which deletes it in the middle of this function. Hold |
631 // a self-reference to prevent deletion of |this|. | 629 // a self-reference to prevent deletion of |this|. |
632 const scoped_refptr<ClientSocketPoolBaseHelper> self(this); | 630 const scoped_refptr<ClientSocketPoolBaseHelper> self(this); |
633 | 631 |
634 if (result == OK) { | 632 if (result == OK) { |
635 DCHECK(socket.get()); | 633 DCHECK(socket.get()); |
636 RemoveConnectJob(job, group); | 634 RemoveConnectJob(job, group); |
637 if (!group->pending_requests().empty()) { | 635 if (!group->pending_requests().empty()) { |
638 scoped_ptr<const Request> r(RemoveRequestFromQueue( | 636 scoped_ptr<const Request> r(RemoveRequestFromQueue( |
639 group->mutable_pending_requests()->begin(), | 637 group->mutable_pending_requests()->begin(), group)); |
640 group->mutable_pending_requests())); | |
641 LogBoundConnectJobToRequest(job_log.source(), r.get()); | 638 LogBoundConnectJobToRequest(job_log.source(), r.get()); |
642 HandOutSocket( | 639 HandOutSocket( |
643 socket.release(), false /* unused socket */, r->handle(), | 640 socket.release(), false /* unused socket */, r->handle(), |
644 base::TimeDelta(), group, r->net_log()); | 641 base::TimeDelta(), group, r->net_log()); |
645 r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, NULL); | 642 r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, NULL); |
646 InvokeUserCallbackLater(r->handle(), r->callback(), result); | 643 InvokeUserCallbackLater(r->handle(), r->callback(), result); |
647 } else { | 644 } else { |
648 AddIdleSocket(socket.release(), group); | 645 AddIdleSocket(socket.release(), group); |
649 OnAvailableSocketSlot(group_name, group); | 646 OnAvailableSocketSlot(group_name, group); |
650 CheckForStalledSocketGroups(); | 647 CheckForStalledSocketGroups(); |
651 } | 648 } |
652 } else { | 649 } else { |
653 // If we got a socket, it must contain error information so pass that | 650 // If we got a socket, it must contain error information so pass that |
654 // up so that the caller can retrieve it. | 651 // up so that the caller can retrieve it. |
655 bool handed_out_socket = false; | 652 bool handed_out_socket = false; |
656 if (!group->pending_requests().empty()) { | 653 if (!group->pending_requests().empty()) { |
657 scoped_ptr<const Request> r(RemoveRequestFromQueue( | 654 scoped_ptr<const Request> r(RemoveRequestFromQueue( |
658 group->mutable_pending_requests()->begin(), | 655 group->mutable_pending_requests()->begin(), group)); |
659 group->mutable_pending_requests())); | |
660 LogBoundConnectJobToRequest(job_log.source(), r.get()); | 656 LogBoundConnectJobToRequest(job_log.source(), r.get()); |
661 job->GetAdditionalErrorState(r->handle()); | 657 job->GetAdditionalErrorState(r->handle()); |
662 RemoveConnectJob(job, group); | 658 RemoveConnectJob(job, group); |
663 if (socket.get()) { | 659 if (socket.get()) { |
664 handed_out_socket = true; | 660 handed_out_socket = true; |
665 HandOutSocket(socket.release(), false /* unused socket */, r->handle(), | 661 HandOutSocket(socket.release(), false /* unused socket */, r->handle(), |
666 base::TimeDelta(), group, r->net_log()); | 662 base::TimeDelta(), group, r->net_log()); |
667 } | 663 } |
668 r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, | 664 r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, |
669 new NetLogIntegerParameter("net_error", result)); | 665 new NetLogIntegerParameter("net_error", result)); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 else if (!group->pending_requests().empty()) | 711 else if (!group->pending_requests().empty()) |
716 ProcessPendingRequest(group_name, group); | 712 ProcessPendingRequest(group_name, group); |
717 } | 713 } |
718 | 714 |
719 void ClientSocketPoolBaseHelper::ProcessPendingRequest( | 715 void ClientSocketPoolBaseHelper::ProcessPendingRequest( |
720 const std::string& group_name, Group* group) { | 716 const std::string& group_name, Group* group) { |
721 int rv = RequestSocketInternal(group_name, | 717 int rv = RequestSocketInternal(group_name, |
722 *group->pending_requests().begin()); | 718 *group->pending_requests().begin()); |
723 if (rv != ERR_IO_PENDING) { | 719 if (rv != ERR_IO_PENDING) { |
724 scoped_ptr<const Request> request(RemoveRequestFromQueue( | 720 scoped_ptr<const Request> request(RemoveRequestFromQueue( |
725 group->mutable_pending_requests()->begin(), | 721 group->mutable_pending_requests()->begin(), group)); |
726 group->mutable_pending_requests())); | |
727 if (group->IsEmpty()) | 722 if (group->IsEmpty()) |
728 RemoveGroup(group_name); | 723 RemoveGroup(group_name); |
729 | 724 |
730 scoped_refptr<NetLog::EventParameters> params; | 725 scoped_refptr<NetLog::EventParameters> params; |
731 if (rv != OK) | 726 if (rv != OK) |
732 params = new NetLogIntegerParameter("net_error", rv); | 727 params = new NetLogIntegerParameter("net_error", rv); |
733 request->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, params); | 728 request->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, params); |
734 InvokeUserCallbackLater( | 729 InvokeUserCallbackLater( |
735 request->handle(), request->callback(), rv); | 730 request->handle(), request->callback(), rv); |
736 } | 731 } |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
941 // Delete active jobs. | 936 // Delete active jobs. |
942 STLDeleteElements(&jobs_); | 937 STLDeleteElements(&jobs_); |
943 | 938 |
944 // Cancel pending backup job. | 939 // Cancel pending backup job. |
945 method_factory_.RevokeAll(); | 940 method_factory_.RevokeAll(); |
946 } | 941 } |
947 | 942 |
948 } // namespace internal | 943 } // namespace internal |
949 | 944 |
950 } // namespace net | 945 } // namespace net |
OLD | NEW |