diff --git a/include/mqtt/callable_overlay.hpp b/include/mqtt/callable_overlay.hpp index 75d0f532..41ca3d83 100644 --- a/include/mqtt/callable_overlay.hpp +++ b/include/mqtt/callable_overlay.hpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include namespace MQTT_NS { template @@ -727,14 +727,14 @@ struct callable_overlay final : public Impl * See http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718086
* 3.13 PINGREQ – PING request */ - using pingreq_handler = move_only_handler; + using pingreq_handler = copyable_handler; /** * @brief Pingresp handler * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901200
* 3.13 PINGRESP – PING response */ - using pingresp_handler = move_only_handler; + using pingresp_handler = copyable_handler; // MQTT v3_1_1 handlers @@ -775,7 +775,7 @@ struct callable_overlay final : public Impl * 3.1.2.10 Keep Alive * */ - using connect_handler = move_only_handler< + using connect_handler = copyable_handler< void(buffer client_id, optional user_name, optional password, @@ -794,7 +794,7 @@ struct callable_overlay final : public Impl * See http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718036
* 3.2.2.3 Connect Return code */ - using connack_handler = move_only_handler; + using connack_handler = copyable_handler; /** * @brief Publish handler @@ -812,7 +812,7 @@ struct callable_overlay final : public Impl * @param contents * Published contents */ - using publish_handler = move_only_handler packet_id, + using publish_handler = copyable_handler packet_id, publish_options pubopts, buffer topic_name, buffer contents)>; @@ -824,7 +824,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc398718045
* 3.4.2 Variable header */ - using puback_handler = move_only_handler; + using puback_handler = copyable_handler; /** * @brief Pubrec handler @@ -833,7 +833,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc398718050
* 3.5.2 Variable header */ - using pubrec_handler = move_only_handler; + using pubrec_handler = copyable_handler; /** * @brief Pubrel handler @@ -842,7 +842,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc385349791
* 3.6.2 Variable header */ - using pubrel_handler = move_only_handler; + using pubrel_handler = copyable_handler; /** * @brief Pubcomp handler @@ -851,7 +851,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc398718060
* 3.7.2 Variable header */ - using pubcomp_handler = move_only_handler; + using pubcomp_handler = copyable_handler; /** * @brief Subscribe handler @@ -862,7 +862,7 @@ struct callable_overlay final : public Impl * Collection of Share Name, Topic Filter, and QoS.
* See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc385349802
*/ - using subscribe_handler = move_only_handler entries)>; /** @@ -875,7 +875,7 @@ struct callable_overlay final : public Impl * If subscription is failure, the value is nullopt.
* See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc398718071
*/ - using suback_handler = move_only_handler qoss)>; /** @@ -887,7 +887,7 @@ struct callable_overlay final : public Impl * Collection of Share Name and Topic Filter
* See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc384800448
*/ - using unsubscribe_handler = move_only_handler entries)>; /** @@ -896,14 +896,14 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc398718045
* 3.11.2 Variable header */ - using unsuback_handler = move_only_handler; + using unsuback_handler = copyable_handler; /** * @brief Disconnect handler * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc384800463
* 3.14 DISCONNECT – Disconnect notification */ - using disconnect_handler = move_only_handler; + using disconnect_handler = copyable_handler; // MQTT v5 handlers @@ -949,7 +949,7 @@ struct callable_overlay final : public Impl * 3.1.2.11 CONNECT Properties * */ - using v5_connect_handler = move_only_handler< + using v5_connect_handler = copyable_handler< void(buffer client_id, optional user_name, optional password, @@ -974,7 +974,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901080
* 3.2.2.3 CONNACK Properties */ - using v5_connack_handler = move_only_handler< + using v5_connack_handler = copyable_handler< void(bool session_present, v5::connect_reason_code reason_code, v5::properties props) @@ -1004,7 +1004,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901109
* 3.3.2.3 PUBLISH Properties */ - using v5_publish_handler = move_only_handler< + using v5_publish_handler = copyable_handler< void(optional packet_id, publish_options pubopts, buffer topic_name, @@ -1027,7 +1027,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901125
* 3.4.2.2 PUBACK Properties */ - using v5_puback_handler = move_only_handler< + using v5_puback_handler = copyable_handler< void(packet_id_t packet_id, v5::puback_reason_code reason_code, v5::properties props) @@ -1048,7 +1048,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901135
* 3.5.2.2 PUBREC Properties */ - using v5_pubrec_handler = move_only_handler< + using v5_pubrec_handler = copyable_handler< void(packet_id_t packet_id, v5::pubrec_reason_code reason_code, v5::properties props) @@ -1069,7 +1069,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901145
* 3.6.2.2 PUBREL Properties */ - using v5_pubrel_handler = move_only_handler< + using v5_pubrel_handler = copyable_handler< void(packet_id_t packet_id, v5::pubrel_reason_code reason_code, v5::properties props) @@ -1090,7 +1090,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901155
* 3.7.2.2 PUBCOMP Properties */ - using v5_pubcomp_handler = move_only_handler< + using v5_pubcomp_handler = copyable_handler< void(packet_id_t packet_id, v5::pubcomp_reason_code reason_code, v5::properties props) @@ -1109,7 +1109,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901164
* 3.8.2.1 SUBSCRIBE Properties */ - using v5_subscribe_handler = move_only_handler< + using v5_subscribe_handler = copyable_handler< void(packet_id_t packet_id, std::vector entries, v5::properties props) @@ -1129,7 +1129,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901174
* 3.9.2.1 SUBACK Properties */ - using v5_suback_handler = move_only_handler< + using v5_suback_handler = copyable_handler< void(packet_id_t packet_id, std::vector reasons, v5::properties props) @@ -1149,7 +1149,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901182
* 3.10.2.1 UNSUBSCRIBE Properties */ - using v5_unsubscribe_handler = move_only_handler< + using v5_unsubscribe_handler = copyable_handler< void(packet_id_t packet_id, std::vector entries, v5::properties props) @@ -1169,7 +1169,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901190
* 3.11.2.1 UNSUBACK Properties */ - using v5_unsuback_handler = move_only_handler< + using v5_unsuback_handler = copyable_handler< void(packet_id_t, std::vector reasons, v5::properties props) @@ -1188,7 +1188,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901209
* 3.14.2.2 DISCONNECT Properties */ - using v5_disconnect_handler = move_only_handler< + using v5_disconnect_handler = copyable_handler< void(v5::disconnect_reason_code reason_code, v5::properties props) >; @@ -1206,7 +1206,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901221
* 3.15.2.2 AUTH Properties */ - using v5_auth_handler = move_only_handler< + using v5_auth_handler = copyable_handler< void(v5::auth_reason_code reason_code, v5::properties props) >; @@ -1220,7 +1220,7 @@ struct callable_overlay final : public Impl * This handler is called if the client called `disconnect()` and the server closed the socket cleanly. * If the socket is closed by other reasons, error_handler is called. */ - using close_handler = move_only_handler; + using close_handler = copyable_handler; /** * @brief Error handler @@ -1229,7 +1229,7 @@ struct callable_overlay final : public Impl * * @param ec error code */ - using error_handler = move_only_handler; + using error_handler = copyable_handler; /** * @brief Publish response sent handler @@ -1239,7 +1239,7 @@ struct callable_overlay final : public Impl * See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901026
* 2.2.1 Packet Identifier */ - using pub_res_sent_handler = move_only_handler; + using pub_res_sent_handler = copyable_handler; /** * @brief Serialize publish handler @@ -1247,7 +1247,7 @@ struct callable_overlay final : public Impl * To restore the message, use restore_serialized_message(). * @param msg publish message */ - using serialize_publish_message_handler = move_only_handler msg)>; + using serialize_publish_message_handler = copyable_handler msg)>; /** * @brief Serialize publish handler @@ -1255,7 +1255,7 @@ struct callable_overlay final : public Impl * To restore the message, use restore_serialized_message(). * @param msg v5::publish message */ - using serialize_v5_publish_message_handler = move_only_handler msg)>; + using serialize_v5_publish_message_handler = copyable_handler msg)>; /** * @brief Serialize publish handler @@ -1265,7 +1265,7 @@ struct callable_overlay final : public Impl * @param data pointer to the serializing message * @param size size of the serializing message */ - using serialize_publish_handler = move_only_handler; + using serialize_publish_handler = copyable_handler; /** * @brief Serialize pubrel handler @@ -1275,7 +1275,7 @@ struct callable_overlay final : public Impl * To restore the message, use restore_serialized_message(). * @param msg pubrel message */ - using serialize_pubrel_message_handler = move_only_handler msg)>; + using serialize_pubrel_message_handler = copyable_handler msg)>; /** * @brief Serialize pubrel handler @@ -1285,7 +1285,7 @@ struct callable_overlay final : public Impl * To restore the message, use restore_serialized_message(). * @param msg pubrel message */ - using serialize_v5_pubrel_message_handler = move_only_handler msg)>; + using serialize_v5_pubrel_message_handler = copyable_handler msg)>; /** * @brief Serialize pubrel handler @@ -1297,19 +1297,19 @@ struct callable_overlay final : public Impl * @param data pointer to the serializing message * @param size size of the serializing message */ - using serialize_pubrel_handler = move_only_handler; + using serialize_pubrel_handler = copyable_handler; /** * @brief Remove serialized message * @param packet_id packet identifier of the removing message */ - using serialize_remove_handler = move_only_handler; + using serialize_remove_handler = copyable_handler; /** * @brief Pre-send handler * This handler is called when any mqtt control packet is decided to send. */ - using pre_send_handler = move_only_handler; + using pre_send_handler = copyable_handler; /** * @brief is valid length handler @@ -1319,7 +1319,7 @@ struct callable_overlay final : public Impl * @return true if check is success, otherwise false */ using is_valid_length_handler = - move_only_function; + copyable_function; /** * @brief next read handler @@ -1327,7 +1327,7 @@ struct callable_overlay final : public Impl * @param func A callback function that is called when async operation will finish. */ using mqtt_message_processed_handler = - move_only_handler; + copyable_handler; @@ -2019,7 +2019,7 @@ struct callable_overlay final : public Impl * @brief Get error handler * @return handler */ - error_handler const& get_error_handler() const { + error_handler get_error_handler() const { return h_error_; } diff --git a/include/mqtt/copyable_function.hpp b/include/mqtt/copyable_function.hpp new file mode 100644 index 00000000..f59e66e6 --- /dev/null +++ b/include/mqtt/copyable_function.hpp @@ -0,0 +1,30 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(MQTT_COPYABLE_FUNCTION_HPP) +#define MQTT_COPYABLE_FUNCTION_HPP + +#pragma GCC diagnostic push +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Waddress" +#endif // defined(__GNUC__) + +#include + +#include + +namespace MQTT_NS { + +template +using copyable_function = fu2::function; + +} // namespace MQTT_NS + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif // defined(__GNUC__) + +#endif // MQTT_COPYABLE_FUNCTION_HPP diff --git a/include/mqtt/copyable_handler.hpp b/include/mqtt/copyable_handler.hpp new file mode 100644 index 00000000..919a6388 --- /dev/null +++ b/include/mqtt/copyable_handler.hpp @@ -0,0 +1,66 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(MQTT_COPYABLE_HANDLER_HPP) +#define MQTT_COPYABLE_HANDLER_HPP + +#include + +#include + +#include +#include +#include +#include + +namespace MQTT_NS { + +namespace as = boost::asio; + +template +struct copyable_handler { + using executor_type = as::any_io_executor; + + copyable_handler() = default; + + template < + typename Func, + typename std::enable_if_t< + std::is_convertible>::value + >* = nullptr + > + copyable_handler(Func&& f) + : exe_{as::get_associated_executor(f)}, + func_{std::forward(f)} + { + } + + executor_type get_executor() const { return exe_; } + + template + void operator()(Params&&... params) { + if (exe_ == as::system_executor()) { + func_(std::forward(params)...); + return; + } + as::dispatch( + exe_, + [func = func_, pt = std::tuple(std::forward(params)...)] () mutable { + MQTT_NS::apply(force_move(func), std::move(pt)); + } + ); + } + + operator bool() const { return static_cast(func_); } + +private: + executor_type exe_; + copyable_function func_; +}; + +} // namespace MQTT_NS + +#endif // MQTT_COPYABLE_HANDLER_HPP