mavtables  0.2.1
MAVLink router and firewall.
ConnectionPool.cpp
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 #include <memory>
19 #include <mutex>
20 #include <shared_mutex>
21 #include <stdexcept>
22 #include <utility>
23 
24 #include "Connection.hpp"
25 #include "ConnectionPool.hpp"
26 #include "Logger.hpp"
27 #include "Packet.hpp"
28 #include "utility.hpp"
29 
30 
31 /** Add a connection to the pool.
32  *
33  * \param connection The connection to add to the pool.
34  */
35 void ConnectionPool::add(std::weak_ptr<Connection> connection)
36 {
37  std::lock_guard<std::shared_mutex> lock(mutex_);
38  connections_.insert(std::move(connection));
39 }
40 
41 
42 /** Remove a connection from the pool.
43  *
44  * \param connection The connection to remove from the pool.
45  */
46 void ConnectionPool::remove(const std::weak_ptr<Connection> &connection)
47 {
48  std::lock_guard<std::shared_mutex> lock(mutex_);
49  connections_.erase(connection);
50 }
51 
52 
53 /** Send a packet to every connection.
54  *
55  * \note Each connection may decide to ignore the packet based on it's filter
56  * rules.
57  *
58  * \param packet The packet to send to every connection, must not be nullptr.
59  * \throws std::invalid_argument if the \p packet pointer is null.
60  */
61 void ConnectionPool::send(std::unique_ptr<const Packet> packet)
62 {
63  if (packet == nullptr)
64  {
65  throw std::invalid_argument("Given packet pointer is null.");
66  }
67 
68  if (Logger::level() >= 2)
69  {
70  std::stringstream ss;
71  ss << "received " << str(*packet) << " source ";
72  auto connection = packet->connection();
73 
74  if (connection == nullptr)
75  {
76  ss << "unknown";
77  }
78  else
79  {
80  ss << *connection;
81  }
82 
83  Logger::log(2, ss.str());
84  }
85 
86  std::shared_lock<std::shared_mutex> lock(mutex_);
87  std::shared_ptr<const Packet> shared = std::move(packet);
88 
89  for (auto it = connections_.begin(); it != connections_.end();)
90  {
91  // Send packet on connection.
92  if (auto connection = it->lock())
93  {
94  connection->send(shared);
95  ++it;
96  }
97  // Remove connection.
98  else
99  {
100  it = connections_.erase(it);
101  }
102  }
103 }
std::string str(const T &object)
Definition: utility.hpp:128
static void log(std::string message)
Definition: Logger.cpp:37
TEST_VIRTUAL void send(std::unique_ptr< const Packet > packet)
void connection(std::weak_ptr< Connection > connection)
Definition: Packet.cpp:63
static unsigned int level()
Definition: Logger.cpp:96
TEST_VIRTUAL void remove(const std::weak_ptr< Connection > &connection)
TEST_VIRTUAL void add(std::weak_ptr< Connection > connection)