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 */