Chromium Code Reviews| 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)) |
| 158 continue; | 155 continue; |
| 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), | |
|
craigdh
2014/01/09 01:45:06
nit: shouldn't this line be tabbed two more spaces
frankf
2014/01/09 01:55:19
Done.
| |
| 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), | |
|
craigdh
2014/01/09 01:45:06
ditto
frankf
2014/01/09 01:55:19
Done.
| |
| 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 |