| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "base/stl_util-inl.h" | 9 #include "base/stl_util-inl.h" |
| 10 #include "base/time.h" | 10 #include "base/time.h" |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 // static | 96 // static |
| 97 void ClientSocketPoolBase::InsertRequestIntoQueue( | 97 void ClientSocketPoolBase::InsertRequestIntoQueue( |
| 98 const Request& r, RequestQueue* pending_requests) { | 98 const Request& r, RequestQueue* pending_requests) { |
| 99 RequestQueue::iterator it = pending_requests->begin(); | 99 RequestQueue::iterator it = pending_requests->begin(); |
| 100 while (it != pending_requests->end() && r.priority <= it->priority) | 100 while (it != pending_requests->end() && r.priority <= it->priority) |
| 101 ++it; | 101 ++it; |
| 102 pending_requests->insert(it, r); | 102 pending_requests->insert(it, r); |
| 103 } | 103 } |
| 104 | 104 |
| 105 int ClientSocketPoolBase::RequestSocket( | 105 int ClientSocketPoolBase::RequestSocket( |
| 106 LoadLog* load_log, |
| 106 const std::string& group_name, | 107 const std::string& group_name, |
| 107 const HostResolver::RequestInfo& resolve_info, | 108 const HostResolver::RequestInfo& resolve_info, |
| 108 int priority, | 109 int priority, |
| 109 ClientSocketHandle* handle, | 110 ClientSocketHandle* handle, |
| 110 CompletionCallback* callback) { | 111 CompletionCallback* callback) { |
| 111 DCHECK(!resolve_info.hostname().empty()); | 112 DCHECK(!resolve_info.hostname().empty()); |
| 112 DCHECK_GE(priority, 0); | 113 DCHECK_GE(priority, 0); |
| 113 DCHECK(callback); | 114 DCHECK(callback); |
| 114 Group& group = group_map_[group_name]; | 115 Group& group = group_map_[group_name]; |
| 115 | 116 |
| 116 // Can we make another active socket now? | 117 // Can we make another active socket now? |
| 117 if (ReachedMaxSocketsLimit() || | 118 if (ReachedMaxSocketsLimit() || |
| 118 !group.HasAvailableSocketSlot(max_sockets_per_group_)) { | 119 !group.HasAvailableSocketSlot(max_sockets_per_group_)) { |
| 119 if (ReachedMaxSocketsLimit()) { | 120 if (ReachedMaxSocketsLimit()) { |
| 120 // We could check if we really have a stalled group here, but it requires | 121 // We could check if we really have a stalled group here, but it requires |
| 121 // a scan of all groups, so just flip a flag here, and do the check later. | 122 // a scan of all groups, so just flip a flag here, and do the check later. |
| 122 may_have_stalled_group_ = true; | 123 may_have_stalled_group_ = true; |
| 123 } | 124 } |
| 124 CHECK(callback); | 125 CHECK(callback); |
| 125 Request r(handle, callback, priority, resolve_info); | 126 Request r(load_log, handle, callback, priority, resolve_info); |
| 126 InsertRequestIntoQueue(r, &group.pending_requests); | 127 InsertRequestIntoQueue(r, &group.pending_requests); |
| 127 return ERR_IO_PENDING; | 128 return ERR_IO_PENDING; |
| 128 } | 129 } |
| 129 | 130 |
| 130 while (!group.idle_sockets.empty()) { | 131 while (!group.idle_sockets.empty()) { |
| 131 IdleSocket idle_socket = group.idle_sockets.back(); | 132 IdleSocket idle_socket = group.idle_sockets.back(); |
| 132 group.idle_sockets.pop_back(); | 133 group.idle_sockets.pop_back(); |
| 133 DecrementIdleCount(); | 134 DecrementIdleCount(); |
| 134 if (idle_socket.socket->IsConnectedAndIdle()) { | 135 if (idle_socket.socket->IsConnectedAndIdle()) { |
| 135 // We found one we can reuse! | 136 // We found one we can reuse! |
| 136 HandOutSocket(idle_socket.socket, idle_socket.used, handle, &group); | 137 HandOutSocket(idle_socket.socket, idle_socket.used, handle, &group); |
| 137 return OK; | 138 return OK; |
| 138 } | 139 } |
| 139 delete idle_socket.socket; | 140 delete idle_socket.socket; |
| 140 } | 141 } |
| 141 | 142 |
| 142 // We couldn't find a socket to reuse, so allocate and connect a new one. | 143 // We couldn't find a socket to reuse, so allocate and connect a new one. |
| 143 | 144 |
| 144 CHECK(callback); | 145 CHECK(callback); |
| 145 Request r(handle, callback, priority, resolve_info); | 146 Request r(load_log, handle, callback, priority, resolve_info); |
| 146 scoped_ptr<ConnectJob> connect_job( | 147 scoped_ptr<ConnectJob> connect_job( |
| 147 connect_job_factory_->NewConnectJob(group_name, r, this)); | 148 connect_job_factory_->NewConnectJob(group_name, r, this)); |
| 148 | 149 |
| 149 int rv = connect_job->Connect(); | 150 int rv = connect_job->Connect(); |
| 150 if (rv == OK) { | 151 if (rv == OK) { |
| 151 HandOutSocket(connect_job->ReleaseSocket(), false /* not reused */, | 152 HandOutSocket(connect_job->ReleaseSocket(), false /* not reused */, |
| 152 handle, &group); | 153 handle, &group); |
| 153 } else if (rv == ERR_IO_PENDING) { | 154 } else if (rv == ERR_IO_PENDING) { |
| 154 connecting_socket_count_++; | 155 connecting_socket_count_++; |
| 155 | 156 |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 group_map_.erase(group_name); | 492 group_map_.erase(group_name); |
| 492 } | 493 } |
| 493 } | 494 } |
| 494 | 495 |
| 495 void ClientSocketPoolBase::ProcessPendingRequest(const std::string& group_name, | 496 void ClientSocketPoolBase::ProcessPendingRequest(const std::string& group_name, |
| 496 Group* group) { | 497 Group* group) { |
| 497 Request r = group->pending_requests.front(); | 498 Request r = group->pending_requests.front(); |
| 498 group->pending_requests.pop_front(); | 499 group->pending_requests.pop_front(); |
| 499 | 500 |
| 500 int rv = RequestSocket( | 501 int rv = RequestSocket( |
| 501 group_name, r.resolve_info, r.priority, r.handle, r.callback); | 502 r.load_log, group_name, r.resolve_info, r.priority, r.handle, r.callback); |
| 502 | 503 |
| 503 if (rv != ERR_IO_PENDING) { | 504 if (rv != ERR_IO_PENDING) { |
| 504 r.callback->Run(rv); | 505 r.callback->Run(rv); |
| 505 if (rv != OK) { | 506 if (rv != OK) { |
| 506 // |group| may be invalid after the callback, we need to search | 507 // |group| may be invalid after the callback, we need to search |
| 507 // |group_map_| again. | 508 // |group_map_| again. |
| 508 MaybeOnAvailableSocketSlot(group_name); | 509 MaybeOnAvailableSocketSlot(group_name); |
| 509 } | 510 } |
| 510 } | 511 } |
| 511 } | 512 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 } | 551 } |
| 551 | 552 |
| 552 bool ClientSocketPoolBase::ReachedMaxSocketsLimit() const { | 553 bool ClientSocketPoolBase::ReachedMaxSocketsLimit() const { |
| 553 // Each connecting socket will eventually connect and be handed out. | 554 // Each connecting socket will eventually connect and be handed out. |
| 554 int total = handed_out_socket_count_ + connecting_socket_count_; | 555 int total = handed_out_socket_count_ + connecting_socket_count_; |
| 555 DCHECK_LE(total, max_sockets_); | 556 DCHECK_LE(total, max_sockets_); |
| 556 return total == max_sockets_; | 557 return total == max_sockets_; |
| 557 } | 558 } |
| 558 | 559 |
| 559 } // namespace net | 560 } // namespace net |
| OLD | NEW |