Skip to content

Commit

Permalink
Fixed shutdown/close
Browse files Browse the repository at this point in the history
  • Loading branch information
5cript committed Oct 27, 2023
1 parent c0657b1 commit 9e60320
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 54 deletions.
62 changes: 26 additions & 36 deletions include/roar/client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,53 +328,42 @@ namespace Roar
});
}

Detail::PromiseTypeBind<Detail::PromiseTypeBindThen<>, Detail::PromiseTypeBindFail<Error>> shutdown()
Detail::PromiseTypeBind<Detail::PromiseTypeBindThen<>, Detail::PromiseTypeBindFail<Error>> close()
{
return promise::newPromise([&, this](promise::Defer d) mutable {
bool isClosed = false;
resolver_.cancel();
withLowerLayerDo([&](auto& socket) {
if (!socket.socket().is_open())
isClosed = true;
if (socket.socket().is_open())
{
socket.cancel();
socket.close();
}
});
return d.resolve();
});
}

if (isClosed)
return d.resolve();

Detail::PromiseTypeBind<Detail::PromiseTypeBindThen<>, Detail::PromiseTypeBindFail<Error>>
shutdownSsl(std::chrono::seconds timeout = defaultTimeout)
{
return promise::newPromise([&, this](promise::Defer d) mutable {
if (std::holds_alternative<boost::beast::tcp_stream>(socket_))
{
auto& socket = std::get<boost::beast::tcp_stream>(socket_);
socket.cancel();
socket.close();
return d.resolve();
}
else
{
auto& socket = std::get<boost::beast::ssl_stream<boost::beast::tcp_stream>>(socket_);
socket.async_shutdown([d = std::move(d)](boost::beast::error_code ec) mutable {
if (ec == boost::asio::error::eof)
ec = {};

if (ec)
return d.reject(Error{.error = ec, .additionalInfo = "Stream shutdown failed."});
withLowerLayerDo([timeout](auto& socket) {
socket.expires_after(timeout);
});
auto& socket = std::get<boost::beast::ssl_stream<boost::beast::tcp_stream>>(socket_);
socket.async_shutdown([d = std::move(d)](boost::beast::error_code ec) mutable {
if (ec == boost::asio::error::eof)
ec = {};

d.resolve();
});
}
});
}
if (ec)
return d.reject(Error{.error = ec, .additionalInfo = "Stream shutdown failed."});

std::future_status shutdownSync(std::chrono::seconds timeout = defaultTimeout)
{
std::promise<void> waiter;
auto waiterFuture = waiter.get_future();
shutdown()
.then([&waiter]() mutable {
waiter.set_value();
})
.fail([&waiter](auto) mutable {
waiter.set_value();
d.resolve();
});
return waiterFuture.wait_for(timeout);
});
}

public:
Expand Down Expand Up @@ -483,6 +472,7 @@ namespace Roar

private:
std::optional<SslOptions> sslOptions_;
boost::asio::ip::tcp::resolver resolver_;
std::shared_ptr<boost::beast::flat_buffer> buffer_;
std::variant<boost::beast::ssl_stream<boost::beast::tcp_stream>, boost::beast::tcp_stream> socket_;
boost::asio::ip::tcp::resolver::results_type::endpoint_type endpoint_;
Expand Down
24 changes: 6 additions & 18 deletions src/roar/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace Roar
// ##################################################################################################################
Client::Client(ConstructionArguments&& args)
: sslOptions_{std::move(args.sslOptions)}
, resolver_{args.executor}
, buffer_{std::make_shared<boost::beast::flat_buffer>()}
, socket_{[this, &args]() -> decltype(socket_) {
if (args.sslOptions)
Expand All @@ -30,7 +31,7 @@ namespace Roar
//------------------------------------------------------------------------------------------------------------------
Client::~Client()
{
shutdownSync();
close();
}
//------------------------------------------------------------------------------------------------------------------
std::optional<Error> Client::setupSsl(std::string const& host)
Expand Down Expand Up @@ -136,24 +137,11 @@ namespace Roar
std::function<void(boost::beast::error_code ec, boost::asio::ip::tcp::resolver::results_type results)>
onResolve)
{
withLowerLayerDo([&](auto& socket) {
struct ResolveCtx
{
boost::asio::ip::tcp::resolver resolver;
boost::asio::ip::tcp::resolver::query query;
};
auto resolveCtx = std::make_shared<ResolveCtx>(ResolveCtx{
.resolver = boost::asio::ip::tcp::resolver{socket.get_executor()},
.query =
boost::asio::ip::tcp::resolver::query{
host, port, boost::asio::ip::resolver_query_base::numeric_service},
resolver_.async_resolve(
boost::asio::ip::tcp::resolver::query{host, port, boost::asio::ip::resolver_query_base::numeric_service},
[onResolve = std::move(onResolve)](boost::beast::error_code ec, auto results) mutable {
onResolve(ec, std::move(results));
});
resolveCtx->resolver.async_resolve(
resolveCtx->query,
[onResolve = std::move(onResolve), resolveCtx](boost::beast::error_code ec, auto results) mutable {
onResolve(ec, std::move(results));
});
});
}
// ##################################################################################################################
}

0 comments on commit 9e60320

Please sign in to comment.