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); |
} |