Chromium Code Reviews| Index: chrome/test/chromedriver/net/port_server.cc |
| diff --git a/chrome/test/chromedriver/net/port_server.cc b/chrome/test/chromedriver/net/port_server.cc |
| index 972c9934dcbe3ccbb8437606eeaa23af019e6066..366000061f7b2269bc9b0e1fafb8d9044fb256ea 100644 |
| --- a/chrome/test/chromedriver/net/port_server.cc |
| +++ b/chrome/test/chromedriver/net/port_server.cc |
| @@ -134,8 +134,8 @@ void PortServer::ReleasePort(int port) { |
| free_.push_back(port); |
| } |
| -PortManager::PortManager(int min_port, int max_port) |
| - : min_port_(min_port), max_port_(max_port) { |
| +PortManager::PortManager(int min_port, int max_port, bool reuse) |
| + : min_port_(min_port), max_port_(max_port), reuse_(reuse) { |
| CHECK_GE(max_port_, min_port_); |
| } |
| @@ -143,38 +143,49 @@ PortManager::~PortManager() {} |
| Status PortManager::ReservePort(int* port, |
| scoped_ptr<PortReservation>* reservation) { |
| - base::AutoLock lock(taken_lock_); |
| - |
| - int start = base::RandInt(min_port_, max_port_); |
| - bool wrapped = false; |
| - for (int try_port = start; try_port != start || !wrapped; ++try_port) { |
| - if (try_port > max_port_) { |
| - wrapped = true; |
| - if (min_port_ == max_port_) |
| + base::AutoLock lock(lock_); |
| + int port_to_use = 0; |
| + if (reuse_ && unused_forwarded_port_.size()) { |
| + port_to_use = unused_forwarded_port_.front(); |
| + unused_forwarded_port_.pop_front(); |
| + } else { |
| + int start = base::RandInt(min_port_, max_port_); |
| + bool wrapped = false; |
| + for (int try_port = start; try_port != start || !wrapped; ++try_port) { |
| + if (try_port > max_port_) { |
| + wrapped = true; |
| + if (min_port_ == max_port_) |
| + break; |
| + try_port = min_port_; |
| + } |
| + if (taken_.count(try_port)) |
| + continue; |
| + |
| + char parts[] = {127, 0, 0, 1}; |
| + net::IPAddressNumber address(parts, parts + arraysize(parts)); |
| + net::NetLog::Source source; |
| + net::TCPServerSocket sock(NULL, source); |
| + if (sock.Listen(net::IPEndPoint(address, try_port), 1) == net::OK) { |
| + port_to_use = try_port; |
| break; |
| - try_port = min_port_; |
| + } |
| } |
| - if (taken_.count(try_port)) |
| - continue; |
| - |
| - char parts[] = {127, 0, 0, 1}; |
| - net::IPAddressNumber address(parts, parts + arraysize(parts)); |
| - net::NetLog::Source source; |
| - net::TCPServerSocket sock(NULL, source); |
| - if (sock.Listen(net::IPEndPoint(address, try_port), 1) != net::OK) |
| - continue; |
| - |
| - taken_.insert(try_port); |
| - *port = try_port; |
| - reservation->reset(new PortReservation( |
| - base::Bind(&PortManager::ReleasePort, base::Unretained(this), try_port), |
| - try_port)); |
| - return Status(kOk); |
| } |
| - return Status(kUnknownError, "unable to find open port"); |
| + if (!port_to_use) |
| + return Status(kUnknownError, "unable to find open port"); |
| + |
| + taken_.insert(port_to_use); |
| + *port = port_to_use; |
| + reservation->reset(new PortReservation( |
| + base::Bind(&PortManager::ReleasePort, base::Unretained(this), |
|
craigdh
2014/01/08 20:56:33
then just bind the correct version of ReleasePort
frankf
2014/01/08 21:57:25
Done.
|
| + port_to_use), |
| + port_to_use)); |
| + return Status(kOk); |
| } |
| void PortManager::ReleasePort(int port) { |
| - base::AutoLock lock(taken_lock_); |
| + base::AutoLock lock(lock_); |
| taken_.erase(port); |
| + if (reuse_) |
| + unused_forwarded_port_.push_back(port); |
| } |