From d1493b48e1f12403d95ec1b21e1d4fdd47d86b5b Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 15 Dec 2023 13:50:04 +0100 Subject: [PATCH] Update rpclib to version 2.3.0 Signed-off-by: iabdalkader --- libraries/rpclib/src/rpc/client.h | 4 +- libraries/rpclib/src/rpc/client.inl | 2 +- .../rpclib/src/rpc/detail/async_writer.h | 50 +++--- .../rpclib/src/rpc/detail/client_error.cc | 15 ++ libraries/rpclib/src/rpc/detail/log.h | 10 +- libraries/rpclib/src/rpc/detail/response.cc | 65 ++++++++ .../rpclib/src/rpc/detail/server_session.h | 7 +- libraries/rpclib/src/rpc/dispatcher.cc | 143 ++++++++++++++++++ libraries/rpclib/src/rpc/dispatcher.h | 13 ++ libraries/rpclib/src/rpc/msgpack/unpack.h | 4 +- .../rpclib/src/rpc/msgpack/v1/unpack_decl.hpp | 4 +- .../rpc/nonstd/{optional.cpp => optional.cc} | 4 +- libraries/rpclib/src/rpc/nonstd/optional.hpp | 2 +- libraries/rpclib/src/rpc/rpc_error.cc | 26 ++++ libraries/rpclib/src/rpc/rpc_error.h | 21 ++- libraries/rpclib/src/rpc/server.h | 25 ++- libraries/rpclib/src/rpc/this_handler.cc | 27 ++++ libraries/rpclib/src/rpc/this_server.cc | 19 +++ libraries/rpclib/src/rpc/this_server.h | 3 +- libraries/rpclib/src/rpc/this_session.cc | 28 ++++ libraries/rpclib/src/rpc/version.h | 2 +- 21 files changed, 430 insertions(+), 44 deletions(-) create mode 100644 libraries/rpclib/src/rpc/detail/client_error.cc create mode 100644 libraries/rpclib/src/rpc/detail/response.cc create mode 100644 libraries/rpclib/src/rpc/dispatcher.cc rename libraries/rpclib/src/rpc/nonstd/{optional.cpp => optional.cc} (63%) create mode 100644 libraries/rpclib/src/rpc/rpc_error.cc create mode 100644 libraries/rpclib/src/rpc/this_handler.cc create mode 100644 libraries/rpclib/src/rpc/this_server.cc create mode 100644 libraries/rpclib/src/rpc/this_session.cc diff --git a/libraries/rpclib/src/rpc/client.h b/libraries/rpclib/src/rpc/client.h index 613c91fae..fcd16ebe3 100644 --- a/libraries/rpclib/src/rpc/client.h +++ b/libraries/rpclib/src/rpc/client.h @@ -88,7 +88,7 @@ class client { //! //! \param func_name The name of the notification to call. //! \param args The arguments to pass to the function. - //! \tparam Args THe types of the arguments. + //! \tparam Args The types of the arguments. //! //! \note This function returns immediately (possibly before the //! notification is written to the socket). @@ -144,4 +144,4 @@ class client { }; } -//#include "rpc/client.inl" +#include "rpc/client.inl" diff --git a/libraries/rpclib/src/rpc/client.inl b/libraries/rpclib/src/rpc/client.inl index 04dc825b4..f980f069b 100644 --- a/libraries/rpclib/src/rpc/client.inl +++ b/libraries/rpclib/src/rpc/client.inl @@ -47,7 +47,7 @@ client::async_call(std::string const &func_name, Args... args) { //! \param args The arguments to pass to the function. //! \note This function returns when the notification is written to the //! socket. -//! \tparam Args THe types of the arguments. +//! \tparam Args The types of the arguments. template void client::send(std::string const &func_name, Args... args) { RPCLIB_CREATE_LOG_CHANNEL(client) diff --git a/libraries/rpclib/src/rpc/detail/async_writer.h b/libraries/rpclib/src/rpc/detail/async_writer.h index 66488ff6b..508500a7a 100644 --- a/libraries/rpclib/src/rpc/detail/async_writer.h +++ b/libraries/rpclib/src/rpc/detail/async_writer.h @@ -23,6 +23,27 @@ class async_writer : public std::enable_shared_from_this { RPCLIB_ASIO::ip::tcp::socket socket) : socket_(std::move(socket)), write_strand_(*io), exit_(false) {} + void close() { + exit_ = true; + + auto self = shared_from_this(); + write_strand_.post([this, self]() { + LOG_INFO("Closing socket"); + std::error_code e; + socket_.shutdown( + RPCLIB_ASIO::ip::tcp::socket::shutdown_both, e); + if (e) { + LOG_WARN("std::system_error during socket shutdown. " + "Code: {}. Message: {}", e.value(), e.message()); + } + socket_.close(); + }); + } + + bool is_closed() const { + return exit_.load(); + } + void do_write() { if (exit_) { return; @@ -46,20 +67,6 @@ class async_writer : public std::enable_shared_from_this { } else { LOG_ERROR("Error while writing to socket: {}", ec); } - - if (exit_) { - LOG_INFO("Closing socket"); - try { - socket_.shutdown( - RPCLIB_ASIO::ip::tcp::socket::shutdown_both); - } - catch (std::system_error &e) { - (void)e; - LOG_WARN("std::system_error during socket shutdown. " - "Code: {}. Message: {}", e.code(), e.what()); - } - socket_.close(); - } })); } @@ -72,7 +79,9 @@ class async_writer : public std::enable_shared_from_this { do_write(); } - friend class rpc::client; + RPCLIB_ASIO::ip::tcp::socket& socket() { + return socket_; + } protected: template @@ -80,15 +89,14 @@ class async_writer : public std::enable_shared_from_this { return std::static_pointer_cast(shared_from_this()); } -protected: + RPCLIB_ASIO::strand& write_strand() { + return write_strand_; + } + +private: RPCLIB_ASIO::ip::tcp::socket socket_; RPCLIB_ASIO::strand write_strand_; std::atomic_bool exit_{false}; - bool exited_ = false; - std::mutex m_exit_; - std::condition_variable cv_exit_; - -private: std::deque write_queue_; RPCLIB_CREATE_LOG_CHANNEL(async_writer) }; diff --git a/libraries/rpclib/src/rpc/detail/client_error.cc b/libraries/rpclib/src/rpc/detail/client_error.cc new file mode 100644 index 000000000..263141f37 --- /dev/null +++ b/libraries/rpclib/src/rpc/detail/client_error.cc @@ -0,0 +1,15 @@ +#include "format.h" + +#include "rpc/detail/client_error.h" + +namespace rpc { +namespace detail { + +client_error::client_error(code c, const std::string &msg) + : what_(RPCLIB_FMT::format("client error C{0:04x}: {1}", + static_cast(c), msg)) {} + +const char *client_error::what() const noexcept { return what_.c_str(); } +} +} + diff --git a/libraries/rpclib/src/rpc/detail/log.h b/libraries/rpclib/src/rpc/detail/log.h index 0d5e51c61..09db735a6 100644 --- a/libraries/rpclib/src/rpc/detail/log.h +++ b/libraries/rpclib/src/rpc/detail/log.h @@ -83,11 +83,19 @@ class logger { std::stringstream ss; timespec now_t = {}; clock_gettime(CLOCK_REALTIME, &now_t); +#if __GNUC__ >= 5 ss << std::put_time( std::localtime(reinterpret_cast(&now_t.tv_sec)), "%F %T") - << RPCLIB_FMT::format( +#else + char mltime[128]; + strftime(mltime, sizeof(mltime), "%c %Z", + std::localtime(reinterpret_cast(&now_t.tv_sec))); + ss << mltime +#endif + << RPCLIB_FMT::format( ".{:03}", round(static_cast(now_t.tv_nsec) / 1.0e6)); + return ss.str(); } #endif diff --git a/libraries/rpclib/src/rpc/detail/response.cc b/libraries/rpclib/src/rpc/detail/response.cc new file mode 100644 index 000000000..6169c58ba --- /dev/null +++ b/libraries/rpclib/src/rpc/detail/response.cc @@ -0,0 +1,65 @@ +#include "rpc/detail/response.h" +#include "rpc/detail/log.h" +#include "rpc/detail/util.h" + +#include + +namespace rpc { +namespace detail { + +response::response() : id_(0), error_(), result_(), empty_(false) {} + +response::response(RPCLIB_MSGPACK::object_handle o) : response() { + response_type r; + o.get().convert(r); + // TODO: check protocol [t.szelei 2015-12-30] + id_ = std::get<1>(r); + auto &&error_obj = std::get<2>(r); + if (!error_obj.is_nil()) { + error_ = std::make_shared(); + *error_ = RPCLIB_MSGPACK::clone(error_obj); + } + result_ = std::make_shared( + std::get<3>(r), std::move(o.zone())); +} + +RPCLIB_MSGPACK::sbuffer response::get_data() const { + RPCLIB_MSGPACK::sbuffer data; + response_type r(1, id_, error_ ? error_->get() : RPCLIB_MSGPACK::object(), + result_ ? result_->get() : RPCLIB_MSGPACK::object()); + RPCLIB_MSGPACK::pack(data, r); + return data; +} + +uint32_t response::get_id() const { return id_; } + +std::shared_ptr response::get_error() const { return error_; } + +std::shared_ptr response::get_result() const { + return result_; +} + +response response::empty() { + response r; + r.empty_ = true; + return r; +} + +bool response::is_empty() const { return empty_; } + +void response::capture_result(RPCLIB_MSGPACK::object_handle &r) { + if (!result_) { + result_ = std::make_shared(); + } + result_->set(std::move(r).get()); +} + +void response::capture_error(RPCLIB_MSGPACK::object_handle &e) { + if (!error_) { + error_ = std::shared_ptr(); + } + error_->set(std::move(e).get()); +} + +} /* detail */ +} /* rpc */ diff --git a/libraries/rpclib/src/rpc/detail/server_session.h b/libraries/rpclib/src/rpc/detail/server_session.h index 0b848142a..3b96d7dae 100644 --- a/libraries/rpclib/src/rpc/detail/server_session.h +++ b/libraries/rpclib/src/rpc/detail/server_session.h @@ -3,6 +3,7 @@ #ifndef SESSION_H_5KG6ZMAB #define SESSION_H_5KG6ZMAB +#include "asio.hpp" #include #include @@ -21,7 +22,9 @@ namespace detail { class server_session : public async_writer { public: - server_session(server *srv, std::shared_ptr disp, bool suppress_exceptions); + server_session(server *srv, RPCLIB_ASIO::io_service *io, + RPCLIB_ASIO::ip::tcp::socket socket, + std::shared_ptr disp, bool suppress_exceptions); void start(); void close(); @@ -31,6 +34,8 @@ class server_session : public async_writer { private: server* parent_; + RPCLIB_ASIO::io_service *io_; + RPCLIB_ASIO::strand read_strand_; std::shared_ptr disp_; RPCLIB_MSGPACK::unpacker pac_; RPCLIB_MSGPACK::sbuffer output_buf_; diff --git a/libraries/rpclib/src/rpc/dispatcher.cc b/libraries/rpclib/src/rpc/dispatcher.cc new file mode 100644 index 000000000..0063bd07f --- /dev/null +++ b/libraries/rpclib/src/rpc/dispatcher.cc @@ -0,0 +1,143 @@ +#include "rpc/dispatcher.h" +#include "format.h" +#include "rpc/detail/client_error.h" +#include "rpc/this_handler.h" + +namespace rpc { +namespace detail { + +using detail::response; + +void dispatcher::dispatch(RPCLIB_MSGPACK::sbuffer const &msg) { + auto unpacked = RPCLIB_MSGPACK::unpack(msg.data(), msg.size()); + dispatch(unpacked.get()); +} + +response dispatcher::dispatch(RPCLIB_MSGPACK::object const &msg, + bool suppress_exceptions) { + switch (msg.via.array.size) { + case 3: + return dispatch_notification(msg, suppress_exceptions); + case 4: + return dispatch_call(msg, suppress_exceptions); + default: + return response::empty(); + } +} + +response dispatcher::dispatch_call(RPCLIB_MSGPACK::object const &msg, + bool suppress_exceptions) { + call_t the_call; + msg.convert(the_call); + + // TODO: proper validation of protocol (and responding to it) + // auto &&type = std::get<0>(the_call); + // assert(type == 0); + + auto &&id = std::get<1>(the_call); + auto &&name = std::get<2>(the_call); + auto &&args = std::get<3>(the_call); + + auto it_func = funcs_.find(name); + + if (it_func != end(funcs_)) { + LOG_DEBUG("Dispatching call to '{}'", name); + try { + auto result = (it_func->second)(args); + return response::make_result(id, std::move(result)); + } catch (rpc::detail::client_error &e) { + return response::make_error( + id, RPCLIB_FMT::format("rpclib: {}", e.what())); + } catch (std::exception &e) { + if (!suppress_exceptions) { + throw; + } + return response::make_error( + id, + RPCLIB_FMT::format("rpclib: function '{0}' (called with {1} " + "arg(s)) " + "threw an exception. The exception " + "contained this information: {2}.", + name, args.via.array.size, e.what())); + } catch (rpc::detail::handler_error &) { + // doing nothing, the exception was only thrown to + // return immediately + } catch (rpc::detail::handler_spec_response &) { + // doing nothing, the exception was only thrown to + // return immediately + } catch (...) { + if (!suppress_exceptions) { + throw; + } + return response::make_error( + id, + RPCLIB_FMT::format("rpclib: function '{0}' (called with {1} " + "arg(s)) threw an exception. The exception " + "is not derived from std::exception. No " + "further information available.", + name, args.via.array.size)); + } + } + return response::make_error( + id, RPCLIB_FMT::format("rpclib: server could not find " + "function '{0}' with argument count {1}.", + name, args.via.array.size)); +} + +response dispatcher::dispatch_notification(RPCLIB_MSGPACK::object const &msg, + bool suppress_exceptions) { + notification_t the_call; + msg.convert(the_call); + + // TODO: proper validation of protocol (and responding to it) + // auto &&type = std::get<0>(the_call); + // assert(type == static_cast(request_type::notification)); + + auto &&name = std::get<1>(the_call); + auto &&args = std::get<2>(the_call); + + auto it_func = funcs_.find(name); + + if (it_func != end(funcs_)) { + LOG_DEBUG("Dispatching call to '{}'", name); + try { + auto result = (it_func->second)(args); + } catch (rpc::detail::handler_error &) { + // doing nothing, the exception was only thrown to + // return immediately + } catch (rpc::detail::handler_spec_response &) { + // doing nothing, the exception was only thrown to + // return immediately + } catch (...) { + if (!suppress_exceptions) { + throw; + } + } + } + return response::empty(); +} + +void dispatcher::enforce_arg_count(std::string const &func, std::size_t found, + std::size_t expected) { + using detail::client_error; + if (found != expected) { + throw client_error( + client_error::code::wrong_arity, + RPCLIB_FMT::format( + "Function '{0}' was called with an invalid number of " + "arguments. Expected: {1}, got: {2}", + func, expected, found)); + } +} + +void dispatcher::enforce_unique_name(std::string const &func) { + auto pos = funcs_.find(func); + if (pos != end(funcs_)) { + throw std::logic_error( + RPCLIB_FMT::format("Function name already bound: '{}'. " + "Please use unique function names", func)); + } +} + +} +} /* rpc */ diff --git a/libraries/rpclib/src/rpc/dispatcher.h b/libraries/rpclib/src/rpc/dispatcher.h index 8044d4cb4..18dca30fc 100644 --- a/libraries/rpclib/src/rpc/dispatcher.h +++ b/libraries/rpclib/src/rpc/dispatcher.h @@ -60,6 +60,19 @@ class dispatcher { detail::tags::nonvoid_result const &, detail::tags::nonzero_arg const &); + //! \brief Unbind a functor with a given name from callable functors. + void unbind(std::string const &name) { + funcs_.erase(name); + } + + //! \brief returns a list of all names which functors are binded to + std::vector names() const { + std::vector names; + for(auto it = funcs_.begin(); it != funcs_.end(); ++it) + names.push_back(it->first); + return names; + } + //! @} //! \brief Processes a message that contains a call according to diff --git a/libraries/rpclib/src/rpc/msgpack/unpack.h b/libraries/rpclib/src/rpc/msgpack/unpack.h index f409dc2e5..14ed3cbc6 100644 --- a/libraries/rpclib/src/rpc/msgpack/unpack.h +++ b/libraries/rpclib/src/rpc/msgpack/unpack.h @@ -66,7 +66,7 @@ typedef struct msgpack_unpacker { #ifndef MSGPACK_UNPACKER_INIT_BUFFER_SIZE -#define MSGPACK_UNPACKER_INIT_BUFFER_SIZE (1024) +#define MSGPACK_UNPACKER_INIT_BUFFER_SIZE (4*1024) #endif /** @@ -98,7 +98,7 @@ void msgpack_unpacker_free(msgpack_unpacker* mpac); #ifndef MSGPACK_UNPACKER_RESERVE_SIZE -#define MSGPACK_UNPACKER_RESERVE_SIZE (1024) +#define MSGPACK_UNPACKER_RESERVE_SIZE (4*1024) #endif /** diff --git a/libraries/rpclib/src/rpc/msgpack/v1/unpack_decl.hpp b/libraries/rpclib/src/rpc/msgpack/v1/unpack_decl.hpp index 3219bd338..11384cfc9 100644 --- a/libraries/rpclib/src/rpc/msgpack/v1/unpack_decl.hpp +++ b/libraries/rpclib/src/rpc/msgpack/v1/unpack_decl.hpp @@ -40,11 +40,11 @@ const size_t COUNTER_SIZE = sizeof(_msgpack_atomic_counter_t); #ifndef MSGPACK_UNPACKER_INIT_BUFFER_SIZE -#define MSGPACK_UNPACKER_INIT_BUFFER_SIZE (1024) +#define MSGPACK_UNPACKER_INIT_BUFFER_SIZE (4*1024) #endif #ifndef MSGPACK_UNPACKER_RESERVE_SIZE -#define MSGPACK_UNPACKER_RESERVE_SIZE (1024) +#define MSGPACK_UNPACKER_RESERVE_SIZE (4*1024) #endif diff --git a/libraries/rpclib/src/rpc/nonstd/optional.cpp b/libraries/rpclib/src/rpc/nonstd/optional.cc similarity index 63% rename from libraries/rpclib/src/rpc/nonstd/optional.cpp rename to libraries/rpclib/src/rpc/nonstd/optional.cc index f80c93197..ac89d2985 100644 --- a/libraries/rpclib/src/rpc/nonstd/optional.cpp +++ b/libraries/rpclib/src/rpc/nonstd/optional.cc @@ -3,4 +3,6 @@ // This is no-op; the reason it exists is to avoid // the weak vtables problem. For more info, see // https://stackoverflow.com/a/23749273/140367 -nonstd::bad_optional_access::~bad_optional_access() {} +const char* nonstd::bad_optional_access::what() const noexcept { + return std::logic_error::what(); +} diff --git a/libraries/rpclib/src/rpc/nonstd/optional.hpp b/libraries/rpclib/src/rpc/nonstd/optional.hpp index d9888cf47..e6d941d5e 100644 --- a/libraries/rpclib/src/rpc/nonstd/optional.hpp +++ b/libraries/rpclib/src/rpc/nonstd/optional.hpp @@ -564,7 +564,7 @@ class bad_optional_access : public std::logic_error public: explicit bad_optional_access() : logic_error( "bad optional access" ) {} - ~bad_optional_access(); + const char* what() const noexcept; }; /// optional diff --git a/libraries/rpclib/src/rpc/rpc_error.cc b/libraries/rpclib/src/rpc/rpc_error.cc new file mode 100644 index 000000000..57df42445 --- /dev/null +++ b/libraries/rpclib/src/rpc/rpc_error.cc @@ -0,0 +1,26 @@ +#include "rpc/rpc_error.h" +#include "format.h" + +namespace rpc { + +rpc_error::rpc_error(std::string const &what_arg, + std::string const &function_name, + std::shared_ptr o) + : std::runtime_error(what_arg), + func_name_(function_name), + ob_h_(std::move(o)) {} + +std::string rpc_error::get_function_name() const { return func_name_; } + +RPCLIB_MSGPACK::object_handle &rpc_error::get_error() { return *ob_h_; } + +timeout::timeout(std::string const &what_arg) : std::runtime_error(what_arg) { + formatted = + RPCLIB_FMT::format("rpc::timeout: {}", std::runtime_error::what()); +} + +const char *timeout::what() const noexcept { return formatted.data(); } + +const char* system_error::what() const noexcept { return std::system_error::what(); } + +} /* rpc */ diff --git a/libraries/rpclib/src/rpc/rpc_error.h b/libraries/rpclib/src/rpc/rpc_error.h index e732c45a1..a5895659a 100644 --- a/libraries/rpclib/src/rpc/rpc_error.h +++ b/libraries/rpclib/src/rpc/rpc_error.h @@ -4,6 +4,7 @@ #define RPC_ERROR_H_NEOOSTKY #include +#include #include "rpc/config.h" #include "rpc/msgpack.hpp" @@ -18,6 +19,9 @@ namespace rpc { //! throw it, hence its constructor is private. class rpc_error : public std::runtime_error { public: + rpc_error(std::string const &what_arg, std::string const &function_name, + std::shared_ptr o); + //! \brief Returns the name of the function that was //! called on the server while the error occurred. std::string get_function_name() const; @@ -26,11 +30,6 @@ class rpc_error : public std::runtime_error { //! provided. virtual RPCLIB_MSGPACK::object_handle &get_error(); -private: - friend class client; - rpc_error(std::string const &what_arg, std::string const &function_name, - std::shared_ptr o); - private: std::string func_name_; std::shared_ptr ob_h_; @@ -41,15 +40,23 @@ class rpc_error : public std::runtime_error { //! \note There isn't necessarily a timeout set, it is an optional value. class timeout : public std::runtime_error { public: + explicit timeout(std::string const &what_arg); + //! \brief Describes the exception. const char *what() const noexcept override; private: - friend class client; - explicit timeout(std::string const &what_arg); std::string formatted; }; +//! \brief This exception is throw by the client when the connection or call +//! causes a system error +class system_error : public std::system_error { +public: + using std::system_error::system_error; + const char* what() const noexcept; +}; + } /* rpc */ diff --git a/libraries/rpclib/src/rpc/server.h b/libraries/rpclib/src/rpc/server.h index f240acf18..baeb9f7c5 100644 --- a/libraries/rpclib/src/rpc/server.h +++ b/libraries/rpclib/src/rpc/server.h @@ -93,6 +93,24 @@ class server { disp_->bind(name, func); } + //! \brief Unbinds a functor binded to a name. + //! + //! This function removes already binded function from RPC Ccallable functions + //! + //! \param name The name of the functor. + void unbind(std::string const &name) { + disp_->unbind(name); + } + + //! \brief Returns all binded names + //! + //! This function returns a list of all names which functors are binded to + //! + //! \param name The name of the functor. + std::vector names() const { + return disp_->names(); + } + //! \brief Sets the exception behavior in handlers. By default, //! handlers throwing will crash the server. If suppressing is on, //! the server will try to gather textual data and return it to @@ -104,12 +122,13 @@ class server { //! \note This should not be called from worker threads. void stop(); + //! \brief Returns port + //! \note The port + unsigned short port() const; + //! \brief Closes all sessions gracefully. void close_sessions(); - friend class detail::server_session; - -private: //! \brief Closes a specific session. void close_session(std::shared_ptr const& s); diff --git a/libraries/rpclib/src/rpc/this_handler.cc b/libraries/rpclib/src/rpc/this_handler.cc new file mode 100644 index 000000000..247931054 --- /dev/null +++ b/libraries/rpclib/src/rpc/this_handler.cc @@ -0,0 +1,27 @@ +#include "rpc/this_handler.h" + +namespace rpc { + +this_handler_t &this_handler() { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wexit-time-destructors" +#endif + static thread_local this_handler_t instance; +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + return instance; +} + +void this_handler_t::disable_response() { resp_enabled_ = false; } + +void this_handler_t::enable_response() { resp_enabled_ = true; } + +void this_handler_t::clear() { + error_.set(RPCLIB_MSGPACK::object()); + resp_.set(RPCLIB_MSGPACK::object()); + enable_response(); +} + +} /* rpc */ diff --git a/libraries/rpclib/src/rpc/this_server.cc b/libraries/rpclib/src/rpc/this_server.cc new file mode 100644 index 000000000..4e99e21de --- /dev/null +++ b/libraries/rpclib/src/rpc/this_server.cc @@ -0,0 +1,19 @@ +#include "rpc/this_server.h" + +namespace rpc +{ + +this_server_t &this_server() { + static thread_local this_server_t instance; + return instance; +} + +void this_server_t::stop() { + stopping_ = true; +} + +void this_server_t::cancel_stop() { + stopping_ = false; +} + +} /* rpc */ diff --git a/libraries/rpclib/src/rpc/this_server.h b/libraries/rpclib/src/rpc/this_server.h index 7e8826b69..d1954e4a9 100644 --- a/libraries/rpclib/src/rpc/this_server.h +++ b/libraries/rpclib/src/rpc/this_server.h @@ -19,7 +19,8 @@ class this_server_t { //! \brief Cancels a requested stop operation. void cancel_stop(); - friend class rpc::detail::server_session; + //! Check if a stop is requested + bool stopping() const { return stopping_; } private: bool stopping_; diff --git a/libraries/rpclib/src/rpc/this_session.cc b/libraries/rpclib/src/rpc/this_session.cc new file mode 100644 index 000000000..affd392ff --- /dev/null +++ b/libraries/rpclib/src/rpc/this_session.cc @@ -0,0 +1,28 @@ +#include "rpc/this_session.h" + +namespace rpc +{ + +this_session_t &this_session() { + static thread_local this_session_t instance; + return instance; +} + +void this_session_t::post_exit() { + exit_ = true; +} + +void this_session_t::clear() { + exit_ = false; +} + +session_id_t this_session_t::id() const { + return id_; +} + +void this_session_t::set_id(session_id_t value) { + id_ = value; +} + + +} /* rpc */ diff --git a/libraries/rpclib/src/rpc/version.h b/libraries/rpclib/src/rpc/version.h index 206c7c64e..47e19e926 100644 --- a/libraries/rpclib/src/rpc/version.h +++ b/libraries/rpclib/src/rpc/version.h @@ -6,7 +6,7 @@ namespace rpc { static constexpr unsigned VERSION_MAJOR = 2; -static constexpr unsigned VERSION_MINOR = 2; +static constexpr unsigned VERSION_MINOR = 3; static constexpr unsigned VERSION_PATCH = 0; } /* rpc */ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy