Chops Net IP
Loading...
Searching...
No Matches
net_entity_common.hpp
Go to the documentation of this file.
1
27#ifndef NET_ENTITY_COMMON_HPP_INCLUDED
28#define NET_ENTITY_COMMON_HPP_INCLUDED
29
30#include "asio/any_io_executor.hpp"
31#include "asio/post.hpp"
32
33#include <atomic>
34#include <system_error>
35#include <functional> // std::function, for io state change and error callbacks
36#include <utility> // std::move
37#include <memory>
38#include <cstddef> // std::size_t
39#include <future>
40
43
44namespace chops {
45namespace net {
46namespace detail {
47
48template <typename IOT>
50public:
51 using io_state_chg_cb =
52 std::function<void (basic_io_interface<IOT>, std::size_t, bool)>;
53 using error_cb =
54 std::function<void (basic_io_interface<IOT>, std::error_code)>;
55
56private:
57 // use of atomic for m_started allows multiple threads to call concurrently
58 std::atomic_int m_started; // 0 - unstarted, 1 - started, 2 - stopped
59 io_state_chg_cb m_io_state_chg_cb;
60 error_cb m_error_cb;
61
62public:
63
64 net_entity_common() noexcept : m_started(0), m_io_state_chg_cb(), m_error_cb() { }
65
66 // following three methods can be called concurrently
67 bool is_started() const noexcept { return m_started == 1; }
68
69 bool is_stopped() const noexcept { return m_started == 2; }
70
71 // set_stopped is needed for when the net entity closes itself
72 // internally, due to an error or IO state change false return or
73 // similar internal reason
74 void set_stopped() noexcept { m_started = 2; }
75
76 template <typename F1, typename F2, typename SF>
77 std::error_code start(F1&& io_state_chg_func, F2&& err_func,
78 const asio::any_io_executor& exec,
79 SF&& start_func) {
80 int expected = 0;
81 if (!m_started.compare_exchange_strong(expected, 1)) {
82 return std::make_error_code(net_ip_errc::net_entity_already_started);
83 }
84 m_io_state_chg_cb = io_state_chg_func;
85 m_error_cb = err_func;
86 std::promise<std::error_code> prom;
87 auto fut = prom.get_future();
88 // start network entity processing in context of executor thread
89 asio::post(exec, [&start_func, p = std::move(prom)] () mutable {
90 p.set_value(start_func());
91 }
92 );
93 return fut.get();
94 }
95
96
97 template <typename SF>
98 std::error_code stop(const asio::any_io_executor& exec,
99 SF&& stop_func) {
100 int expected = 1;
101 if (!m_started.compare_exchange_strong(expected, 2)) {
102 return std::make_error_code(net_ip_errc::net_entity_already_stopped);
103 }
104 std::promise<std::error_code> prom;
105 auto fut = prom.get_future();
106 // start closing in context of executor thread
107 asio::post(exec, [&stop_func, p = std::move(prom)] () mutable {
108 p.set_value(stop_func());
109 }
110 );
111 return fut.get();
112 }
113
114 void call_io_state_chg_cb(std::shared_ptr<IOT> p, std::size_t sz, bool starting) {
115 m_io_state_chg_cb(basic_io_interface<IOT>(p), sz, starting);
116 }
117
118 void call_error_cb(std::shared_ptr<IOT> p, const std::error_code& err) {
119 m_error_cb(basic_io_interface<IOT>(p), err);
120 }
121
122
123};
124
125} // end detail namespace
126} // end net namespace
127} // end chops namespace
128
129#endif
130
basic_io_interface class template, providing start_io, stop_io, visit_socket, make_io_output and rela...
The basic_io_interface class template provides access to an underlying network IO handler (TCP or UDP...
Definition basic_io_interface.hpp:100
Definition net_entity_common.hpp:49
Error codes, exception class, and error category within Chops net_ip library.