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
3// found in the LICENSE file.
4
5#ifndef CHROME_TEST_CHROMEDRIVER_NET_PORT_SERVER_H_
6#define CHROME_TEST_CHROMEDRIVER_NET_PORT_SERVER_H_
7
8#include <list>
9#include <set>
10#include <string>
11
12#include "base/callback.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/synchronization/lock.h"
15
16class Status;
17
18class PortReservation {
19 public:
20  PortReservation(const base::Closure& on_free_func, int port);
21  ~PortReservation();
22
23  void Leak();
24
25 private:
26  base::Closure on_free_func_;
27  int port_;
28};
29
30// Communicates with a port reservation management server.
31class PortServer {
32 public:
33  // Construct a port server that communicates via the unix domain socket with
34  // the given path. Must use the Linux abstract namespace.
35  explicit PortServer(const std::string& path);
36  ~PortServer();
37
38  Status ReservePort(int* port, scoped_ptr<PortReservation>* reservation);
39
40 private:
41  Status RequestPort(int* port);
42  void ReleasePort(int port);
43
44  std::string path_;
45
46  base::Lock free_lock_;
47  std::list<int> free_;
48};
49
50// Manages reservation of a block of local ports.
51class PortManager {
52 public:
53  PortManager(int min_port, int max_port);
54  ~PortManager();
55
56  Status ReservePort(int* port, scoped_ptr<PortReservation>* reservation);
57  // Since we cannot remove forwarded adb ports on older SDKs,
58  // maintain a pool of forwarded ports for reuse.
59  Status ReservePortFromPool(int* port,
60                             scoped_ptr<PortReservation>* reservation);
61
62 private:
63  int FindAvailablePort() const;
64  void ReleasePort(int port);
65  void ReleasePortToPool(int port);
66
67  base::Lock lock_;
68  std::set<int> taken_;
69  std::list<int> unused_forwarded_port_;
70  int min_port_;
71  int max_port_;
72};
73
74#endif  // CHROME_TEST_CHROMEDRIVER_NET_PORT_SERVER_H_
75