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 |