mirror of
https://github.com/boostorg/mqtt5.git
synced 2025-10-04 12:50:54 +02:00
use associated executors for intermediate handlers
Summary: * per-operation cancellation changed: total/partial signals only prevent further resending, terminal signal cancels the whole client Reviewers: ivica Reviewed By: ivica Subscribers: korina Differential Revision: https://repo.mireo.local/D27246
This commit is contained in:
@@ -27,11 +27,11 @@ class unsubscribe_op {
|
||||
|
||||
std::shared_ptr<client_service> _svc_ptr;
|
||||
|
||||
cancellable_handler<
|
||||
using handler_type = cancellable_handler<
|
||||
Handler,
|
||||
typename client_service::executor_type,
|
||||
std::tuple<std::vector<reason_code>, unsuback_props>
|
||||
> _handler;
|
||||
typename client_service::executor_type
|
||||
>;
|
||||
handler_type _handler;
|
||||
|
||||
public:
|
||||
unsubscribe_op(
|
||||
@@ -39,18 +39,24 @@ public:
|
||||
Handler&& handler
|
||||
) :
|
||||
_svc_ptr(svc_ptr),
|
||||
_handler(std::move(handler), get_executor())
|
||||
{}
|
||||
_handler(std::move(handler), _svc_ptr->get_executor())
|
||||
{
|
||||
auto slot = asio::get_associated_cancellation_slot(_handler);
|
||||
if (slot.is_connected())
|
||||
slot.assign([&svc = *_svc_ptr](asio::cancellation_type_t) {
|
||||
svc.cancel();
|
||||
});
|
||||
}
|
||||
|
||||
unsubscribe_op(unsubscribe_op&&) noexcept = default;
|
||||
unsubscribe_op(const unsubscribe_op&) noexcept = delete;
|
||||
|
||||
using executor_type = typename client_service::executor_type;
|
||||
using executor_type = asio::associated_executor_t<handler_type>;
|
||||
executor_type get_executor() const noexcept {
|
||||
return _svc_ptr->get_executor();
|
||||
return asio::get_associated_executor(_handler);
|
||||
}
|
||||
|
||||
using allocator_type = asio::associated_allocator_t<Handler>;
|
||||
using allocator_type = asio::associated_allocator_t<handler_type>;
|
||||
allocator_type get_allocator() const noexcept {
|
||||
return asio::get_associated_allocator(_handler);
|
||||
}
|
||||
@@ -88,9 +94,6 @@ public:
|
||||
}
|
||||
|
||||
void send_unsubscribe(control_packet<allocator_type> unsubscribe) {
|
||||
if (_handler.empty()) // already cancelled
|
||||
return _svc_ptr->free_pid(unsubscribe.packet_id());
|
||||
|
||||
auto wire_data = unsubscribe.wire_data();
|
||||
_svc_ptr->async_send(
|
||||
wire_data,
|
||||
@@ -101,17 +104,25 @@ public:
|
||||
);
|
||||
}
|
||||
|
||||
void resend_unsubscribe(control_packet<allocator_type> subscribe) {
|
||||
if (_handler.cancelled() != asio::cancellation_type_t::none)
|
||||
return complete(
|
||||
asio::error::operation_aborted, subscribe.packet_id()
|
||||
);
|
||||
send_unsubscribe(std::move(subscribe));
|
||||
}
|
||||
|
||||
void operator()(
|
||||
on_unsubscribe, control_packet<allocator_type> packet,
|
||||
error_code ec
|
||||
) {
|
||||
if (ec == asio::error::try_again)
|
||||
return send_unsubscribe(std::move(packet));
|
||||
return resend_unsubscribe(std::move(packet));
|
||||
|
||||
auto packet_id = packet.packet_id();
|
||||
|
||||
if (ec)
|
||||
return complete(ec, packet_id, {}, {});
|
||||
return complete(ec, packet_id);
|
||||
|
||||
_svc_ptr->async_wait_reply(
|
||||
control_code_e::unsuback, packet_id,
|
||||
@@ -124,19 +135,19 @@ public:
|
||||
error_code ec, byte_citer first, byte_citer last
|
||||
) {
|
||||
if (ec == asio::error::try_again) // "resend unanswered"
|
||||
return send_unsubscribe(std::move(packet));
|
||||
return resend_unsubscribe(std::move(packet));
|
||||
|
||||
uint16_t packet_id = packet.packet_id();
|
||||
|
||||
if (ec)
|
||||
return complete(ec, packet_id, {}, {});
|
||||
return complete(ec, packet_id);
|
||||
|
||||
auto unsuback = decoders::decode_unsuback(
|
||||
static_cast<uint32_t>(std::distance(first, last)), first
|
||||
);
|
||||
if (!unsuback.has_value()) {
|
||||
on_malformed_packet("Malformed UNSUBACK: cannot decode");
|
||||
return send_unsubscribe(std::move(packet));
|
||||
return resend_unsubscribe(std::move(packet));
|
||||
}
|
||||
|
||||
auto& [props, reason_codes] = *unsuback;
|
||||
@@ -189,14 +200,14 @@ private:
|
||||
if (packet_id != 0)
|
||||
_svc_ptr->free_pid(packet_id);
|
||||
_handler.complete_post(
|
||||
ec, std::vector<reason_code> { num_topics, reason_codes::empty },
|
||||
ec, std::vector<reason_code>(num_topics, reason_codes::empty),
|
||||
unsuback_props {}
|
||||
);
|
||||
}
|
||||
|
||||
void complete(
|
||||
error_code ec, uint16_t packet_id,
|
||||
std::vector<reason_code> reason_codes, unsuback_props props
|
||||
std::vector<reason_code> reason_codes = {}, unsuback_props props = {}
|
||||
) {
|
||||
_svc_ptr->free_pid(packet_id);
|
||||
_handler.complete(ec, std::move(reason_codes), std::move(props));
|
||||
|
Reference in New Issue
Block a user