mavtables  0.2.1
MAVLink router and firewall.
AddressPool.hpp
Go to the documentation of this file.
1 // MAVLink router and firewall.
2 // Copyright (C) 2018 Michael R. Shannon <mrshannon.aerospace@gmail.com>
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 
17 
18 #ifndef ADDRESSPOOL_HPP_
19 #define ADDRESSPOOL_HPP_
20 
21 
22 #include <chrono>
23 #include <map>
24 #include <mutex>
25 #include <vector>
26 
27 #include "config.hpp"
28 #include "MAVAddress.hpp"
29 
30 
31 /** A threadsafe container for addresses that expire after a given time.
32  */
33 template <class TC = std::chrono::steady_clock>
35 {
36  public:
37  AddressPool(std::chrono::milliseconds timeout =
38  std::chrono::milliseconds(120000));
39  // LCOV_EXCL_START
40  TEST_VIRTUAL ~AddressPool() = default;
41  // LCOV_EXCL_STOP
42  TEST_VIRTUAL void add(MAVAddress address);
43  TEST_VIRTUAL std::vector<MAVAddress> addresses();
44  TEST_VIRTUAL bool contains(const MAVAddress &address);
45 
46  private:
47  std::map<MAVAddress, std::chrono::time_point<TC>> addresses_;
48  std::chrono::milliseconds timeout_;
49  std::mutex mutex_;
50 };
51 
52 
53 /** Construct a new address pool.
54  *
55  * \param timeout The amount of time (in milliseconds) before a component will
56  * be considered offline and removed from the pool, unless its time is
57  * updated with \ref add.
58  */
59 template <class TC>
60 AddressPool<TC>::AddressPool(std::chrono::milliseconds timeout)
61  : timeout_(std::move(timeout))
62 {
63 }
64 
65 
66 /** Add a MAVLink address to the pool.
67  *
68  * \note Addresses will be removed after the timeout (set in the
69  * constructor) has run out. Re-adding the address (even before this time
70  * runs out) will reset the timeout.
71  *
72  * \param address The MAVLink address to add or update the timeout for.
73  * \remarks
74  * Threadsafe (locking).
75  */
76 template <class TC>
78 {
79  std::lock_guard<std::mutex> lock(mutex_);
80  addresses_.insert_or_assign(std::move(address), TC::now());
81 }
82 
83 
84 /** Get a vector of all the addresses in the pool.
85  *
86  * \note A copy is returned instead of using iterators in order to make the
87  * call thread safe.
88  *
89  * \returns A vector of the addresses in the pool.
90  * \remarks
91  * Threadsafe (locking).
92  */
93 template <class TC>
94 std::vector<MAVAddress> AddressPool<TC>::addresses()
95 {
96  std::lock_guard<std::mutex> lock(mutex_);
97  std::vector<MAVAddress> addresses;
98  addresses.reserve(addresses_.size());
99  auto current_time = TC::now();
100 
101  // Loop over addresses.
102  for (auto it = addresses_.cbegin(); it != addresses_.cend();)
103  {
104  // Remove the address if it has expired.
105  if ((current_time - it->second) > timeout_)
106  {
107  it = addresses_.erase(it);
108  }
109  // Store the address.
110  else
111  {
112  addresses.push_back((it++)->first);
113  }
114  }
115 
116  return addresses;
117 }
118 
119 
120 /** Determine if the pool contains a given MAVLink address.
121  *
122  * \param address The MAVLink address to test for.
123  * \retval true %If the pool contains \p address.
124  * \retval false %If the pool does not contain \p address.
125  * \remarks
126  * Threadsafe (locking).
127  */
128 template <class TC>
130 {
131  std::lock_guard<std::mutex> lock(mutex_);
132  auto it = addresses_.find(address);
133 
134  if (it != addresses_.end())
135  {
136  auto current_time = TC::now();
137 
138  if (current_time - it->second > timeout_)
139  {
140  addresses_.erase(it);
141  return false;
142  }
143 
144  return true;
145  }
146 
147  return false;
148 }
149 
150 
151 #endif // ADDRESSPOOL_HPP_
TEST_VIRTUAL void add(MAVAddress address)
Definition: AddressPool.hpp:77
AddressPool(std::chrono::milliseconds timeout=std::chrono::milliseconds(120000))
Definition: AddressPool.hpp:60
STL namespace.
TEST_VIRTUAL ~AddressPool()=default
TEST_VIRTUAL bool contains(const MAVAddress &address)
TEST_VIRTUAL std::vector< MAVAddress > addresses()
Definition: AddressPool.hpp:94