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 |