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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 127 #else | 127 #else |
| 128 return Status(kUnknownError, "not implemented for this platform"); | 128 return Status(kUnknownError, "not implemented for this platform"); |
| 129 #endif | 129 #endif |
| 130 } | 130 } |
| 131 | 131 |
| 132 void PortServer::ReleasePort(int port) { | 132 void PortServer::ReleasePort(int port) { |
| 133 base::AutoLock lock(free_lock_); | 133 base::AutoLock lock(free_lock_); |
| 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, bool reuse) |
| 138 : min_port_(min_port), max_port_(max_port) { | 138 : min_port_(min_port), max_port_(max_port), reuse_(reuse) { |
| 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 Status PortManager::ReservePort(int* port, |
| 145 scoped_ptr<PortReservation>* reservation) { | 145 scoped_ptr<PortReservation>* reservation) { |
| 146 base::AutoLock lock(taken_lock_); | 146 base::AutoLock lock(lock_); |
| 147 int port_to_use = 0; | |
| 148 if (reuse_ && unused_forwarded_port_.size()) { | |
| 149 port_to_use = unused_forwarded_port_.front(); | |
| 150 unused_forwarded_port_.pop_front(); | |
| 151 } else { | |
| 152 int start = base::RandInt(min_port_, max_port_); | |
| 153 bool wrapped = false; | |
| 154 for (int try_port = start; try_port != start || !wrapped; ++try_port) { | |
| 155 if (try_port > max_port_) { | |
| 156 wrapped = true; | |
| 157 if (min_port_ == max_port_) | |
| 158 break; | |
| 159 try_port = min_port_; | |
| 160 } | |
| 161 if (taken_.count(try_port)) | |
| 162 continue; | |
| 147 | 163 |
| 148 int start = base::RandInt(min_port_, max_port_); | 164 char parts[] = {127, 0, 0, 1}; |
| 149 bool wrapped = false; | 165 net::IPAddressNumber address(parts, parts + arraysize(parts)); |
| 150 for (int try_port = start; try_port != start || !wrapped; ++try_port) { | 166 net::NetLog::Source source; |
| 151 if (try_port > max_port_) { | 167 net::TCPServerSocket sock(NULL, source); |
| 152 wrapped = true; | 168 if (sock.Listen(net::IPEndPoint(address, try_port), 1) == net::OK) { |
| 153 if (min_port_ == max_port_) | 169 port_to_use = try_port; |
| 154 break; | 170 break; |
| 155 try_port = min_port_; | 171 } |
| 156 } | 172 } |
| 157 if (taken_.count(try_port)) | 173 } |
| 158 continue; | 174 if (!port_to_use) |
| 175 return Status(kUnknownError, "unable to find open port"); | |
| 159 | 176 |
| 160 char parts[] = {127, 0, 0, 1}; | 177 taken_.insert(port_to_use); |
| 161 net::IPAddressNumber address(parts, parts + arraysize(parts)); | 178 *port = port_to_use; |
| 162 net::NetLog::Source source; | 179 reservation->reset(new PortReservation( |
| 163 net::TCPServerSocket sock(NULL, source); | 180 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.
| |
| 164 if (sock.Listen(net::IPEndPoint(address, try_port), 1) != net::OK) | 181 port_to_use), |
| 165 continue; | 182 port_to_use)); |
| 166 | 183 return Status(kOk); |
| 167 taken_.insert(try_port); | |
| 168 *port = try_port; | |
| 169 reservation->reset(new PortReservation( | |
| 170 base::Bind(&PortManager::ReleasePort, base::Unretained(this), try_port), | |
| 171 try_port)); | |
| 172 return Status(kOk); | |
| 173 } | |
| 174 return Status(kUnknownError, "unable to find open port"); | |
| 175 } | 184 } |
| 176 | 185 |
| 177 void PortManager::ReleasePort(int port) { | 186 void PortManager::ReleasePort(int port) { |
| 178 base::AutoLock lock(taken_lock_); | 187 base::AutoLock lock(lock_); |
| 179 taken_.erase(port); | 188 taken_.erase(port); |
| 189 if (reuse_) | |
| 190 unused_forwarded_port_.push_back(port); | |
| 180 } | 191 } |
| OLD | NEW |