168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// found in the LICENSE file.
468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#ifndef CHROME_TEST_CHROMEDRIVER_NET_PORT_SERVER_H_
668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#define CHROME_TEST_CHROMEDRIVER_NET_PORT_SERVER_H_
768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <list>
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <set>
1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <string>
1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/callback.h"
1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/synchronization/lock.h"
1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class Status;
1768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class PortReservation {
1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) public:
2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  PortReservation(const base::Closure& on_free_func, int port);
2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ~PortReservation();
2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  void Leak();
2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) private:
2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::Closure on_free_func_;
2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int port_;
2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)};
2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Communicates with a port reservation management server.
3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class PortServer {
3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) public:
3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Construct a port server that communicates via the unix domain socket with
3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // the given path. Must use the Linux abstract namespace.
3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  explicit PortServer(const std::string& path);
3668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ~PortServer();
3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  Status ReservePort(int* port, scoped_ptr<PortReservation>* reservation);
3968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) private:
4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  Status RequestPort(int* port);
4268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  void ReleasePort(int port);
4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::string path_;
4568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::Lock free_lock_;
4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::list<int> free_;
4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)};
4968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Manages reservation of a block of local ports.
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class PortManager {
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  PortManager(int min_port, int max_port);
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ~PortManager();
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Status ReservePort(int* port, scoped_ptr<PortReservation>* reservation);
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void ReleasePort(int port);
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::Lock taken_lock_;
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::set<int> taken_;
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int min_port_;
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int max_port_;
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif  // CHROME_TEST_CHROMEDRIVER_NET_PORT_SERVER_H_
69