aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@gmail.com>2018-11-30 16:52:54 +0100
committerFelix Morgner <felix.morgner@gmail.com>2018-11-30 16:52:54 +0100
commit3abece6f0a7edca476ee0c493f30dda8f8bcefd5 (patch)
treee794f512a262cca92db6d0a5f9d41b6be64d9db0 /src
parent9c2231c8fb45f32c7b1d23e14125bc58ea405e60 (diff)
downloadwanda-3abece6f0a7edca476ee0c493f30dda8f8bcefd5.tar.xz
wanda-3abece6f0a7edca476ee0c493f30dda8f8bcefd5.zip
core: stop ownership circles in connection
Diffstat (limited to 'src')
-rw-r--r--src/commander.cpp12
-rw-r--r--src/commander.hpp3
-rw-r--r--src/control_connection.cpp6
-rw-r--r--src/control_connection.hpp6
-rw-r--r--src/control_interface.cpp26
-rw-r--r--src/control_interface.hpp13
-rw-r--r--src/message.cpp3
7 files changed, 56 insertions, 13 deletions
diff --git a/src/commander.cpp b/src/commander.cpp
index 2dada6a..762cd83 100644
--- a/src/commander.cpp
+++ b/src/commander.cpp
@@ -6,7 +6,8 @@
namespace wanda
{
commander::commander(boost::asio::io_service &service, std::filesystem::path socket)
- : m_endpoint{socket.string()},
+ : m_service{service},
+ m_endpoint{socket.string()},
m_socket{service}
{
}
@@ -23,9 +24,9 @@ void commander::start()
{
std::clog << "[commander::start] Control connection established\n";
m_connection = wanda::make_control_connection(std::move(m_socket));
+ m_connection->add(this);
m_connection->start();
send({"C", "HELLO", "1.0.0"});
- m_connection->close();
}
});
}
@@ -34,7 +35,7 @@ void commander::send(message message)
{
if (m_connection)
{
- std::clog << "[commander::send] sending message: " << message;
+ std::clog << "[commander::send] sending message: " << message << '\n';
m_connection->send(std::move(message));
}
}
@@ -44,4 +45,9 @@ void commander::on_error(wanda::control_connection::pointer connection, boost::s
std::cerr << "[commander::on_error] error occured: " << error.message() << '\n';
}
+void commander::on_received(wanda::control_connection::pointer connection, message message)
+{
+ std::clog << "[commander::on_receive] Received message: " << message << '\n';
+}
+
} // namespace wanda \ No newline at end of file
diff --git a/src/commander.hpp b/src/commander.hpp
index 89c476a..70b231d 100644
--- a/src/commander.hpp
+++ b/src/commander.hpp
@@ -4,6 +4,7 @@
#include "control_connection.hpp"
#include "message.hpp"
+#include <boost/asio.hpp>
#include <boost/system/error_code.hpp>
#include <filesystem>
@@ -20,8 +21,10 @@ struct commander : wanda::control_connection::listener
void send(message message);
void on_error(wanda::control_connection::pointer connection, boost::system::error_code error) override;
+ void on_received(wanda::control_connection::pointer connection, message message) override;
private:
+ boost::asio::io_service & m_service;
wanda::control_connection::protocol::endpoint m_endpoint;
wanda::control_connection::protocol::socket m_socket;
wanda::control_connection::pointer m_connection;
diff --git a/src/control_connection.cpp b/src/control_connection.cpp
index 586b5de..c06d489 100644
--- a/src/control_connection.cpp
+++ b/src/control_connection.cpp
@@ -17,13 +17,13 @@ control_connection::control_connection(control_connection::key key, control_conn
{
}
-bool control_connection::add(std::shared_ptr<control_connection::listener> listener)
+bool control_connection::add(listener * listener)
{
auto [_, inserted] = m_listeners.insert(listener);
return inserted;
}
-bool control_connection::remove(std::shared_ptr<control_connection::listener> listener)
+bool control_connection::remove(listener * listener)
{
return m_listeners.erase(listener);
}
@@ -92,9 +92,9 @@ void control_connection::perform_read()
{
auto msg = message{};
m_input >> msg;
- m_input.ignore(std::numeric_limits<std::streamsize>::max());
if (!m_input)
{
+ m_input.ignore(std::numeric_limits<std::streamsize>::max());
m_input.clear();
}
else
diff --git a/src/control_connection.hpp b/src/control_connection.hpp
index ea2475c..679a2ff 100644
--- a/src/control_connection.hpp
+++ b/src/control_connection.hpp
@@ -40,14 +40,14 @@ struct control_connection : keyed<control_connection>, std::enable_shared_from_t
*
* @returns <code>true</code> iff. the listener was not already in the listener set
*/
- bool add(std::shared_ptr<listener> listener);
+ bool add(listener * listener);
/**
* @brief Remove the given listener from this control connection's listener set
*
* @return <code>true</code> iff. the listener was previously registered with this control connection
*/
- bool remove(std::shared_ptr<listener> listener);
+ bool remove(listener * listener);
/**
* @brief Start I/O processing for this control connection
@@ -71,7 +71,7 @@ struct control_connection : keyed<control_connection>, std::enable_shared_from_t
boost::asio::streambuf m_out{};
std::istream m_input{&m_in};
std::ostream m_output{&m_out};
- std::set<std::shared_ptr<listener>> m_listeners{};
+ std::set<listener *> m_listeners{};
bool m_running{};
};
diff --git a/src/control_interface.cpp b/src/control_interface.cpp
index 2b368dd..29f3f4f 100644
--- a/src/control_interface.cpp
+++ b/src/control_interface.cpp
@@ -58,7 +58,7 @@ boost::system::error_code control_interface::start()
boost::system::error_code control_interface::shutdown()
{
- for(auto & connection : m_connections)
+ for (auto &connection : m_connections)
{
connection->close();
}
@@ -77,9 +77,10 @@ void control_interface::perform_accept()
else
{
auto [connection, inserted] = m_connections.insert(make_control_connection(std::move(m_socket)));
- if(inserted)
+ if (inserted)
{
- (*connection)->add(shared_from_this());
+ m_states[*connection] = state::fresh;
+ (*connection)->add(this);
(*connection)->start();
}
perform_accept();
@@ -92,6 +93,25 @@ void control_interface::on_close(control_connection::pointer connection)
m_connections.erase(connection);
}
+void control_interface::on_received(control_connection::pointer connection, message message)
+{
+ if (m_states.find(connection) == m_states.cend())
+ {
+ // TODO: Handle unknown connection
+ return;
+ }
+
+ switch (m_states[connection])
+ {
+ case state::fresh:
+ if (message.command == "HELLO")
+ {
+ m_states[connection] = state::greeted;
+ connection->send({"D", "HELLO", "1.0.0"});
+ }
+ }
+}
+
control_interface::pointer make_interface(boost::asio::io_service &service, std::filesystem::path file)
{
if (std::filesystem::exists(file))
diff --git a/src/control_interface.hpp b/src/control_interface.hpp
index c69aeb4..51d8c62 100644
--- a/src/control_interface.hpp
+++ b/src/control_interface.hpp
@@ -7,11 +7,14 @@
#include <boost/asio.hpp>
#include <boost/system/error_code.hpp>
+#include <cstddef>
#include <filesystem>
#include <istream>
+#include <map>
#include <memory>
#include <set>
#include <string>
+#include <type_traits>
namespace wanda
{
@@ -33,9 +36,16 @@ struct control_interface : control_connection::listener, keyed<control_interface
boost::system::error_code start();
boost::system::error_code shutdown();
- void on_close(control_connection::pointer) override;
+ void on_close(control_connection::pointer connection) override;
+ void on_received(control_connection::pointer connection, message message) override;
private:
+ enum struct state : std::underlying_type_t<std::byte>
+ {
+ fresh,
+ greeted,
+ };
+
void perform_accept();
friend pointer make_interface(boost::asio::io_service &service, std::filesystem::path file);
@@ -46,6 +56,7 @@ struct control_interface : control_connection::listener, keyed<control_interface
protocol::acceptor m_acceptor;
socket_deleter m_deleter{m_endpoint.path()};
std::set<control_connection::pointer> m_connections;
+ std::map<control_connection::pointer, state> m_states;
};
control_interface::pointer make_interface(boost::asio::io_service &service, std::filesystem::path file);
diff --git a/src/message.cpp b/src/message.cpp
index ad76897..9900939 100644
--- a/src/message.cpp
+++ b/src/message.cpp
@@ -4,6 +4,8 @@
#include <ios>
#include <sstream>
+#include <iostream>
+
namespace wanda
{
@@ -64,6 +66,7 @@ std::istream &operator>>(std::istream &in, message &message)
message.argument = std::optional{std::move(buffer)};
}
+ in.clear(in.rdstate() ^ std::ios_base::failbit);
return in;
}