| 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 |