I'm trying to write an abstraction layer on top of asio and asio::thread_pool. I currently have two methods, read(..)
and write(..)
that use strands and async methods to send and receive data from a socket backed by an asio::thread_pool
:
template <typename T>
auto abstract_connection<T>::write(std::vector<char> packet,
std::function<void(std::error_code ec, std::size_t len)> cb) noexcept -> void {
m_buffer = std::move(packet);
asio::dispatch(m_strand, [&]() {
asio::async_write(m_socket, asio::buffer(m_buffer),
[&, cb](std::error_code ec, std::size_t len) { cb(ec, len); });
});
}
template <typename T>
auto abstract_connection<T>::read(std::function<void(std::error_code ec, std::vector<char> packet)> cb) noexcept -> void {
m_buffer.clear();
asio::dispatch(m_strand, [&, cb]() {
asio::async_read(m_socket, asio::dynamic_buffer(m_buffer), asio::transfer_exactly(1),
[&, cb](std::error_code ec, std::size_t len) {
if (ec) {
cb(ec, std::move(m_buffer));
}
const auto available = m_socket.available();
asio::async_read(
m_socket, asio::dynamic_buffer(m_buffer), asio::transfer_exactly(available),
[&, cb](std::error_code ec, std::size_t len) { cb(ec, std::move(m_buffer)); });
});
});
}
I understand that sequences of handlers should be wrapped within a strand to guarantee sequential execution, but is it safe to interleave calls to asio::dispatch
within a thread pool, like this:
write(startup, [&](std::error_code e_code, std::size_t len) {
if (e_code) {
ec = e_code;
return;
}
read([&](std::error_code ec, packet packet) { std::cerr << packet.size() << std::endl; });
});
Aucun commentaire:
Enregistrer un commentaire