OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "chrome/test/chromedriver/net/port_server.h" | 5 #include "chrome/test/chromedriver/net/port_server.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/process/process_handle.h" | 10 #include "base/process/process_handle.h" |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
134 free_.push_back(port); | 134 free_.push_back(port); |
135 } | 135 } |
136 | 136 |
137 PortManager::PortManager(int min_port, int max_port) | 137 PortManager::PortManager(int min_port, int max_port) |
138 : min_port_(min_port), max_port_(max_port) { | 138 : min_port_(min_port), max_port_(max_port) { |
139 CHECK_GE(max_port_, min_port_); | 139 CHECK_GE(max_port_, min_port_); |
140 } | 140 } |
141 | 141 |
142 PortManager::~PortManager() {} | 142 PortManager::~PortManager() {} |
143 | 143 |
144 Status PortManager::ReservePort(int* port, | 144 int PortManager::FindAvailablePort() const { |
145 scoped_ptr<PortReservation>* reservation) { | |
146 base::AutoLock lock(taken_lock_); | |
147 | |
148 int start = base::RandInt(min_port_, max_port_); | 145 int start = base::RandInt(min_port_, max_port_); |
149 bool wrapped = false; | 146 bool wrapped = false; |
150 for (int try_port = start; try_port != start || !wrapped; ++try_port) { | 147 for (int try_port = start; try_port != start || !wrapped; ++try_port) { |
151 if (try_port > max_port_) { | 148 if (try_port > max_port_) { |
152 wrapped = true; | 149 wrapped = true; |
153 if (min_port_ == max_port_) | 150 if (min_port_ == max_port_) |
154 break; | 151 break; |
155 try_port = min_port_; | 152 try_port = min_port_; |
156 } | 153 } |
157 if (taken_.count(try_port)) | 154 if (taken_.count(try_port)) |
chrisgao (Use stgao instead)
2014/01/14 02:11:46
Maybe it is good to add a comment in port_server.h
| |
158 continue; | 155 continue; |
chrisgao (Use stgao instead)
2014/01/14 02:11:46
In a corner case, chromedriver is used to test on
| |
159 | 156 |
160 char parts[] = {127, 0, 0, 1}; | 157 char parts[] = {127, 0, 0, 1}; |
161 net::IPAddressNumber address(parts, parts + arraysize(parts)); | 158 net::IPAddressNumber address(parts, parts + arraysize(parts)); |
162 net::NetLog::Source source; | 159 net::NetLog::Source source; |
163 net::TCPServerSocket sock(NULL, source); | 160 net::TCPServerSocket sock(NULL, source); |
164 if (sock.Listen(net::IPEndPoint(address, try_port), 1) != net::OK) | 161 if (sock.Listen(net::IPEndPoint(address, try_port), 1) == net::OK) |
165 continue; | 162 return try_port; |
163 } | |
164 return 0; | |
165 } | |
166 | 166 |
167 taken_.insert(try_port); | 167 Status PortManager::ReservePort(int* port, |
168 *port = try_port; | 168 scoped_ptr<PortReservation>* reservation) { |
169 reservation->reset(new PortReservation( | 169 base::AutoLock lock(lock_); |
170 base::Bind(&PortManager::ReleasePort, base::Unretained(this), try_port), | 170 int port_to_use = FindAvailablePort(); |
171 try_port)); | 171 if (!port_to_use) |
172 return Status(kOk); | 172 return Status(kUnknownError, "unable to find open port"); |
173 | |
174 taken_.insert(port_to_use); | |
175 *port = port_to_use; | |
176 reservation->reset(new PortReservation( | |
177 base::Bind(&PortManager::ReleasePort, base::Unretained(this), | |
178 port_to_use), | |
179 port_to_use)); | |
180 return Status(kOk); | |
181 } | |
182 | |
183 Status PortManager::ReservePortFromPool( | |
184 int* port, scoped_ptr<PortReservation>* reservation) { | |
185 base::AutoLock lock(lock_); | |
186 int port_to_use = 0; | |
187 if (unused_forwarded_port_.size()) { | |
188 port_to_use = unused_forwarded_port_.front(); | |
189 unused_forwarded_port_.pop_front(); | |
190 } else { | |
191 port_to_use = FindAvailablePort(); | |
173 } | 192 } |
174 return Status(kUnknownError, "unable to find open port"); | 193 if (!port_to_use) |
194 return Status(kUnknownError, "unable to find open port"); | |
195 | |
196 taken_.insert(port_to_use); | |
197 *port = port_to_use; | |
198 reservation->reset(new PortReservation( | |
199 base::Bind(&PortManager::ReleasePortToPool, base::Unretained(this), | |
200 port_to_use), | |
201 port_to_use)); | |
202 return Status(kOk); | |
175 } | 203 } |
176 | 204 |
177 void PortManager::ReleasePort(int port) { | 205 void PortManager::ReleasePort(int port) { |
178 base::AutoLock lock(taken_lock_); | 206 base::AutoLock lock(lock_); |
179 taken_.erase(port); | 207 taken_.erase(port); |
180 } | 208 } |
209 | |
210 void PortManager::ReleasePortToPool(int port) { | |
211 base::AutoLock lock(lock_); | |
212 taken_.erase(port); | |
213 unused_forwarded_port_.push_back(port); | |
214 } | |
OLD | NEW |