diff --git a/.clang-tidy b/.clang-tidy index 9c566e01..e3a37d17 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -20,6 +20,7 @@ modernize-*,\ -modernize-use-noexcept,\ -modernize-use-transparent-functors,\ -modernize-use-using,\ +-modernize-use-trailing-return-type,\ performance-*,\ -performance-inefficient-string-concatenation,\ readability-*,\ diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f4c1cf4..5e3a266f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.13 FATAL_ERROR) #----------------------------------------------------------------- # The project #----------------------------------------------------------------- -project (SolidFrame VERSION 12.3) +project (SolidFrame VERSION 13.0) message("SolidFrame version: ${PROJECT_VERSION} - ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") #----------------------------------------------------------------- @@ -33,19 +33,25 @@ find_package(Threads REQUIRED) #----------------------------------------------------------------- if(NOT CMAKE_CXX_STANDARD) - file (READ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/check/cpp20.cpp" source_code) + file (READ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/check/cpp23.cpp" source_code) - set(CMAKE_CXX_STANDARD 20) + set(CMAKE_CXX_STANDARD 23) include(CheckCXXSourceCompiles) - CHECK_CXX_SOURCE_COMPILES("${source_code}" SOLID_COMPILE_CXX20) - if(NOT SOLID_COMPILE_CXX20) - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_REQUIRED ON) - file (READ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/check/cpp17.cpp" source_code) - CHECK_CXX_SOURCE_COMPILES("${source_code}" SOLID_COMPILE_CXX17) - - if(NOT SOLID_COMPILE_CXX17) - message(FATAL_ERROR "SolidFrame needs at least CXX17!") + CHECK_CXX_SOURCE_COMPILES("${source_code}" SOLID_COMPILE_CXX23) + if(NOT SOLID_COMPILE_CXX23) + file (READ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/check/cpp20.cpp" source_code) + + set(CMAKE_CXX_STANDARD 20) + CHECK_CXX_SOURCE_COMPILES("${source_code}" SOLID_COMPILE_CXX20) + if(NOT SOLID_COMPILE_CXX20) + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + file (READ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/check/cpp17.cpp" source_code) + CHECK_CXX_SOURCE_COMPILES("${source_code}" SOLID_COMPILE_CXX17) + + if(NOT SOLID_COMPILE_CXX17) + message(FATAL_ERROR "SolidFrame needs at least CXX17!") + endif() endif() endif() endif() @@ -64,7 +70,7 @@ message("Install directory: \"${CMAKE_INSTALL_PREFIX}\"") message("External directory: \"${EXTERNAL_DIR}\"") message("Fortify: \"${FORTIFY}\"") -list(APPEND CMAKE_PREFIX_PATH ${EXTERNAL_PATH}) +list(APPEND CMAKE_PREFIX_PATH ${EXTERNAL_DIR}) #----------------------------------------------------------------- # Prepare the definitions for build types @@ -150,7 +156,6 @@ set(SYSTEM_BASIC_LIBRARIES "") option(SOLID_FRAME_AIO_REACTOR_USE_SPINLOCK "Use SpinLock on AIO Reactor" ON) -option(SOLID_MPRPC_USE_SHARED_PTR_MESSAGE "Use std::shared_ptr with mprpc::Message" OFF) #----------------------------------------------------------------- # Per OS configuration @@ -199,6 +204,10 @@ if(CMAKE_SYSTEM MATCHES "Darwin*") "$<$:SHELL: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -Wall -Wshorten-64-to-32 -Wunreachable-code -Wconditional-uninitialized -Wabi>" "$<$:>" ) + + if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + add_compile_options("-stdlib=libc++") + endif() string(APPEND CMAKE_EXE_LINKER_FLAGS "-framework ApplicationServices -framework CoreFoundation") @@ -328,7 +337,7 @@ if(NOT NO_EXTERNAL) include_directories(${CMAKE_BINARY_DIR}/external/include) if(EXTERNAL_DIR STREQUAL "" OR NOT EXISTS ${EXTERNAL_DIR}) - set(EXTERNAL_DIR "${CMAKE_CURRENT_BINARY_DIR}/external") + set(EXTERNAL_DIR "${CMAKE_BINARY_DIR}/external") include(cmake/build-openssl.cmake) else() diff --git a/JOURNAL.md b/JOURNAL.md index 05b7181d..b7915bb6 100644 --- a/JOURNAL.md +++ b/JOURNAL.md @@ -1,3 +1,6 @@ +## 20251220 + * release 13.0 - breaking changes on mprpc + ## 20250119 * release 12.3 * Experimental Mutable/ConstSharedBuffer diff --git a/RELEASES.md b/RELEASES.md index 659f5ba1..b5a4fc75 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,5 +1,17 @@ # SolidFrame Releases +## Version 13.0 + * solid/utility: + * MutableIntrusivePtr, ConstIntrusivePtr + * Pool of MutableIntrusivePtr of Poolable types + * MutableSharedBuffer, ConstSharedBuffer + * BufferPool of MutableSharedBuffers + * solid/frame/aio: + * Reactor improvements + * solid/frame/mprpc: + * breaking change related to write buffer - both the message header and the message chunk should fit in write buffer + * breaking change - switch to using MutableMessagePointer and ConstMessagePointer for Recv and Send messages respectively, in the message callback. + ## Version 12.2 * improvements and fixes on reflection * use std::variant in example_threadpool diff --git a/cmake/build-snappy.cmake b/cmake/build-snappy.cmake index 17756af9..48e5e0e4 100644 --- a/cmake/build-snappy.cmake +++ b/cmake/build-snappy.cmake @@ -13,7 +13,7 @@ ExternalProject_Add( URL https://github.com/google/snappy/archive/1.1.9.tar.gz DOWNLOAD_NO_PROGRESS ON CMAKE_ARGS - -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/external -DCMAKE_INSTALL_LIBDIR=lib -DSNAPPY_BUILD_TESTS=OFF -DSNAPPY_BUILD_BENCHMARKS=OFF + -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/external -DCMAKE_INSTALL_LIBDIR=lib -DSNAPPY_BUILD_TESTS=OFF -DSNAPPY_BUILD_BENCHMARKS=OFF -DCMAKE_POLICY_VERSION_MINIMUM=3.5 LOG_UPDATE ON LOG_CONFIGURE ON LOG_BUILD ON diff --git a/cmake/check/cpp23.cpp b/cmake/check/cpp23.cpp new file mode 100644 index 00000000..3cc5a1a3 --- /dev/null +++ b/cmake/check/cpp23.cpp @@ -0,0 +1,22 @@ +#include +#include + +using namespace std; + +struct base { + template + void f(this Self&& self) + { + print("{0}", typeid(Self).name()); + } +}; + +struct derived : base {}; + +int main() +{ + derived my_derived; + my_derived.f(); + + return 0; +} \ No newline at end of file diff --git a/configure b/configure index c3b0c920..827d3566 100755 --- a/configure +++ b/configure @@ -76,8 +76,6 @@ print_usage(){ echo "7) create a debug Ninja build for C++17" echo "./configure -b debug -e ../external -f debug -g Ninja -P \"-DCMAKE_CXX_STANDARD=17\"" echo - echo "8) create release build with using std::shared_ptr for solid::frame::mprpc::Message" - echo "./configure -f release_sp -e ../external/ -g Ninja -P \"-DSOLID_MPRPC_USE_SHARED_PTR_MESSAGE=on\"" echo exit } diff --git a/examples/frame/aio_echo/example_echo_auto_client.cpp b/examples/frame/aio_echo/example_echo_auto_client.cpp index 062ea9fd..b818381d 100644 --- a/examples/frame/aio_echo/example_echo_auto_client.cpp +++ b/examples/frame/aio_echo/example_echo_auto_client.cpp @@ -110,7 +110,7 @@ frame::aio::Resolver& async_resolver(frame::aio::Resolver* _pres = nullptr) return r; } -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; } // namespace diff --git a/examples/frame/aio_echo/example_secure_echo_client.cpp b/examples/frame/aio_echo/example_secure_echo_client.cpp index 069284e9..1532f3db 100644 --- a/examples/frame/aio_echo/example_secure_echo_client.cpp +++ b/examples/frame/aio_echo/example_secure_echo_client.cpp @@ -1,3 +1,11 @@ +#include "solid/utility/common.hpp" + +#ifdef SOLID_ON_WINDOWS +#define NOMINMAX +#include +#include +#endif + #include "solid/frame/aio/openssl/aiosecurecontext.hpp" #include "solid/frame/aio/openssl/aiosecuresocket.hpp" diff --git a/examples/frame/aio_echo/example_secure_echo_server.cpp b/examples/frame/aio_echo/example_secure_echo_server.cpp index b2412dc4..1d3c4a8c 100644 --- a/examples/frame/aio_echo/example_secure_echo_server.cpp +++ b/examples/frame/aio_echo/example_secure_echo_server.cpp @@ -7,6 +7,14 @@ */ +#include "solid/utility/common.hpp" + +#ifdef SOLID_ON_WINDOWS +#define NOMINMAX +#include +#include +#endif + #include "solid/frame/aio/openssl/aiosecurecontext.hpp" #include "solid/frame/aio/openssl/aiosecuresocket.hpp" @@ -277,7 +285,7 @@ bool parseArguments(Params& _par, int argc, char* argv[]) void Listener::onAccept(frame::aio::ReactorContext& _rctx, SocketDevice& _rsd) { solid_log(generic_logger, Info, ""); - unsigned repeatcnt = backlog_size(); + size_t repeatcnt = backlog_size(); do { if (!_rctx.error()) { diff --git a/examples/frame/mprpc_echo/example_mprpc_echo.cpp b/examples/frame/mprpc_echo/example_mprpc_echo.cpp index 4512fc75..3dc74f1e 100644 --- a/examples/frame/mprpc_echo/example_mprpc_echo.cpp +++ b/examples/frame/mprpc_echo/example_mprpc_echo.cpp @@ -1,3 +1,4 @@ +#include "solid/frame/mprpc/mprpcmessage.hpp" #include "solid/frame/mprpc/mprpcsocketstub_openssl.hpp" #include "solid/frame/manager.hpp" @@ -17,6 +18,7 @@ #include "solid/frame/mprpc/mprpcprotocol_serialization_v3.hpp" #include "solid/frame/mprpc/mprpcservice.hpp" +#include "solid/utility/intrusiveptr.hpp" #include "solid/utility/threadpool.hpp" #include "solid/system/socketaddress.hpp" @@ -86,11 +88,9 @@ typedef std::vector MessageVectorT; struct FirstMessage; namespace { -mutex mtx; -condition_variable cnd; -Params params; +Params params; -void broadcast_message(frame::mprpc::Service& _rsvc, frame::mprpc::MessagePointerT<>& _rmsgptr); +void broadcast_message(frame::mprpc::Service& _rsvc, frame::mprpc::SendMessagePointerT<> _rmsgptr); } // namespace struct FirstMessage : frame::mprpc::Message { @@ -191,8 +191,8 @@ int main(int argc, char* argv[]) return 1; } } else { - frame::mprpc::MessagePointerT<> msgptr = frame::mprpc::make_message(s); - broadcast_message(ipcsvc, msgptr); + frame::mprpc::SendMessagePointerT msgptr = frame::mprpc::make_message(s); + broadcast_message(ipcsvc, static_pointer_cast(std::move(msgptr))); } } while (s.size()); } @@ -212,14 +212,14 @@ bool restart( [&](auto& _rmap) { _rmap.template registerMessage(1, "FirstMessage", []( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsend_msg, - frame::mprpc::MessagePointerT& _rrecv_msg, - ErrorConditionT const& _rerr) { + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsend_msg, + frame::mprpc::RecvMessagePointerT& _rrecv_msg, + ErrorConditionT const& _rerr) { if (_rrecv_msg) { solid_log(generic_logger, Info, _rctx.recipientId() << " Message received: is_on_sender: " << _rrecv_msg->isOnSender() << ", is_on_peer: " << _rrecv_msg->isOnPeer() << ", is_back_on_sender: " << _rrecv_msg->isBackOnSender()); if (_rrecv_msg->isOnPeer()) { - _rctx.service().sendResponse(_rctx.recipientId(), _rrecv_msg); + _rctx.service().sendResponse(_rctx.recipientId(), std::move(_rrecv_msg)); } else if (_rrecv_msg->isBackOnSender()) { cout << "Received from " << _rctx.recipientName() << ": " << _rrecv_msg->str << endl; } @@ -252,16 +252,13 @@ bool restart( cfg.client.connection_start_fnc = &outgoing_connection_start; cfg.client.connection_start_state = frame::mprpc::ConnectionState::Active; cfg.server.connection_start_state = frame::mprpc::ConnectionState::Active; -#if 1 + if (params.secure) { // configure OpenSSL: solid_log(generic_logger, Info, "Configure SSL ---------------------------------------"); frame::mprpc::openssl::setup_client( cfg, [](frame::aio::openssl::Context& _rctx) -> ErrorCodeT { - //_rctx.loadVerifyFile("echo-ca-cert.pem"/*"/etc/pki/tls/certs/ca-bundle.crt"*/); - //_rctx.loadCertificateFile("echo-client-cert.pem"); - //_rctx.loadPrivateKeyFile("echo-client-key.pem"); _rctx.addVerifyAuthority(loadFile("echo-ca-cert.pem")); _rctx.loadCertificate(loadFile("echo-client-cert.pem")); _rctx.loadPrivateKey(loadFile("echo-client-key.pem")); @@ -280,7 +277,6 @@ bool restart( frame::mprpc::openssl::NameCheckSecureStart{"echo-client"} // does nothing - OpenSSL does not check for hostname on SSL_accept ); } -#endif { frame::mprpc::ServiceStartStatus start_status; @@ -341,7 +337,7 @@ std::string loadFile(const char* _path) namespace { -void broadcast_message(frame::mprpc::Service& _rsvc, frame::mprpc::MessagePointerT& _rmsgptr) +void broadcast_message(frame::mprpc::Service& _rsvc, frame::mprpc::SendMessagePointerT<> _rmsgptr) { solid_log(generic_logger, Verbose, "done stop==============================="); diff --git a/examples/frame/relay_server/example_relay_server_bi_cp.cpp b/examples/frame/relay_server/example_relay_server_bi_cp.cpp index 2e7f9d37..c417ab4f 100644 --- a/examples/frame/relay_server/example_relay_server_bi_cp.cpp +++ b/examples/frame/relay_server/example_relay_server_bi_cp.cpp @@ -279,7 +279,7 @@ bool parseArguments(Params& _par, int argc, char* argv[]) void Listener::onAccept(frame::aio::ReactorContext& _rctx, SocketDevice& _rsd) { solid_log(generic_logger, Info, ""); - unsigned repeatcnt = SocketInfo::max_listen_backlog_size(); + size_t repeatcnt = SocketInfo::max_listen_backlog_size(); do { if (!_rctx.error()) { diff --git a/examples/utility/algorithm/example_bit_count.cpp b/examples/utility/algorithm/example_bit_count.cpp index 27042e27..8ecd03df 100644 --- a/examples/utility/algorithm/example_bit_count.cpp +++ b/examples/utility/algorithm/example_bit_count.cpp @@ -22,7 +22,7 @@ int main(int argc, char* argv[]) if (argc == 2) { cout << "Generate table for [0, 255]:" << endl; cout << '{'; - for (size_t i = 0; i < 256; ++i) { + for (uint32_t i = 0; i < 256; ++i) { if (!(i % 16)) { cout << endl << "\t"; diff --git a/examples/utility/memory_file/example_memory_file.cpp b/examples/utility/memory_file/example_memory_file.cpp index 870947ee..c4af37f0 100644 --- a/examples/utility/memory_file/example_memory_file.cpp +++ b/examples/utility/memory_file/example_memory_file.cpp @@ -43,9 +43,9 @@ int main(int argc, char* argv[]) return 0; } cout << "File size: " << fd.size() << endl; - char b[20 * 1024]; - int rv; - int rc; + char b[20 * 1024]; + ssize_t rv; + ssize_t rc; do { rv = 2 * 1024; // randomsize(); // cout<; @@ -111,14 +111,12 @@ int main(int argc, char* argv[]) {1, 100, 0}, [](const size_t, Context&) {}, [](const size_t, Context&) {}, [](FileDevice* _pfile, Context& _rctx) { int64_t sz = _pfile->size(); - int toread; - int cnt = 0; + int64_t toread; while (sz > 0) { toread = _rctx.readsz; if (toread > sz) toread = sz; - int rv = _pfile->read(_rctx.buf, toread); - cnt += rv; + ssize_t rv = _pfile->read(_rctx.buf, toread); sz -= rv; } }, diff --git a/solid/frame/aio/aiodatagram.hpp b/solid/frame/aio/aiodatagram.hpp index 86ab79a7..8fc9ec52 100644 --- a/solid/frame/aio/aiodatagram.hpp +++ b/solid/frame/aio/aiodatagram.hpp @@ -16,6 +16,7 @@ #include "solid/system/common.hpp" #include "solid/system/socketdevice.hpp" #include "solid/utility/event.hpp" +#include "solid/utility/function.hpp" namespace solid { namespace frame { @@ -27,8 +28,8 @@ struct ReactorContex; template class Datagram : public CompletionHandler { using ThisT = Datagram; - using RecvFunctionT = solid_function_t(void(ThisT&, ReactorContext&)); - using SendFunctionT = solid_function_t(void(ThisT&, ReactorContext&)); + using RecvFunctionT = SmallFunction64T; + using SendFunctionT = SmallFunction64T; static void on_init_completion(CompletionHandler& _rch, ReactorContext& _rctx) { @@ -290,18 +291,18 @@ class Datagram : public CompletionHandler { bool hasPendingRecv() const { - return !solid_function_empty(recv_fnc); + return recv_fnc; } bool hasPendingSend() const { - return !solid_function_empty(send_fnc); + return send_fnc; } template bool connect(ReactorContext& _rctx, SocketAddressStub const& _rsas, F&& _f) { - if (solid_function_empty(send_fnc)) { + if (not send_fnc) { ErrorCodeT err; errorClear(_rctx); @@ -341,7 +342,7 @@ class Datagram : public CompletionHandler { char* _buf, size_t _bufcp, F&& _f) { - if (solid_function_empty(recv_fnc)) { + if (not recv_fnc) { using RealF = typename std::decay::type; recv_fnc = RecvFromFunctor{std::forward(_f)}; recv_buf = _buf; @@ -362,7 +363,7 @@ class Datagram : public CompletionHandler { char* _buf, size_t _bufcp, F&& _f) { - if (solid_function_empty(recv_fnc)) { + if (not recv_fnc) { using RealF = typename std::decay::type; recv_fnc = RecvFunctor{std::forward(_f)}; recv_buf = _buf; @@ -385,7 +386,7 @@ class Datagram : public CompletionHandler { SocketAddress& _raddr, size_t& _sz) { - if (solid_function_empty(recv_fnc)) { + if (not recv_fnc) { contextBind(_rctx); bool can_retry; @@ -426,7 +427,7 @@ class Datagram : public CompletionHandler { F&& _f, size_t& _sz) { - if (solid_function_empty(recv_fnc)) { + if (not recv_fnc) { contextBind(_rctx); bool can_retry; @@ -467,7 +468,7 @@ class Datagram : public CompletionHandler { SocketAddressStub const& _addrstub, F&& _f) { - if (solid_function_empty(send_fnc)) { + if (not send_fnc) { using RealF = typename std::decay::type; send_fnc = SendToFunctor{std::forward(_f)}; send_buf = _buf; @@ -490,7 +491,7 @@ class Datagram : public CompletionHandler { const char* _buf, size_t _bufcp, F&& _f) { - if (solid_function_empty(send_fnc)) { + if (not send_fnc) { using RealF = typename std::decay::type; send_fnc = SendFunctor{std::forward(_f)}; send_buf = _buf; @@ -513,7 +514,7 @@ class Datagram : public CompletionHandler { SocketAddressStub const& _addrstub, F&& _f) { - if (solid_function_empty(send_fnc)) { + if (not send_fnc) { contextBind(_rctx); bool can_retry; @@ -552,7 +553,7 @@ class Datagram : public CompletionHandler { F&& _f, size_t& _sz) { - if (solid_function_empty(send_fnc)) { + if (not send_fnc) { contextBind(_rctx); bool can_retry; @@ -595,7 +596,7 @@ class Datagram : public CompletionHandler { void doRecv(ReactorContext& _rctx) { - if (!recv_is_posted && !solid_function_empty(recv_fnc)) { + if (!recv_is_posted && recv_fnc) { errorClear(_rctx); recv_fnc(*this, _rctx); } @@ -603,7 +604,7 @@ class Datagram : public CompletionHandler { void doSend(ReactorContext& _rctx) { - if (!send_is_posted && !solid_function_empty(send_fnc)) { + if (!send_is_posted && send_fnc) { errorClear(_rctx); send_fnc(*this, _rctx); } @@ -614,24 +615,24 @@ class Datagram : public CompletionHandler { error(_rctx, error_datagram_socket); // TODO: set proper system error based on socket error - if (!solid_function_empty(send_fnc)) { + if (send_fnc) { send_fnc(*this, _rctx); } - if (!solid_function_empty(recv_fnc)) { + if (recv_fnc) { recv_fnc(*this, _rctx); } } void doClearRecv(ReactorContext& _rctx) { - solid_function_clear(recv_fnc); + recv_fnc = nullptr; recv_buf = nullptr; recv_buf_cp = 0; } void doClearSend(ReactorContext& _rctx) { - solid_function_clear(send_fnc); + send_fnc = nullptr; send_buf = nullptr; recv_buf_cp = 0; } diff --git a/solid/frame/aio/aiolistener.hpp b/solid/frame/aio/aiolistener.hpp index 15f7b953..197a12f6 100644 --- a/solid/frame/aio/aiolistener.hpp +++ b/solid/frame/aio/aiolistener.hpp @@ -16,6 +16,7 @@ #include "aioreactorcontext.hpp" #include "solid/frame/aio/aiocompletion.hpp" #include "solid/frame/aio/aiosocketbase.hpp" +#include "solid/utility/function.hpp" namespace solid { class EventBase; @@ -31,7 +32,7 @@ class Listener : public CompletionHandler { static void on_posted_accept(ReactorContext& _rctx, EventBase&&); static void on_dummy(ReactorContext&, SocketDevice&); - typedef solid_function_t(void(ReactorContext&, SocketDevice&)) FunctionT; + using FunctionT = SmallFunction64T; FunctionT f_; SocketBase s_; @@ -59,7 +60,7 @@ class Listener : public CompletionHandler { template bool postAccept(ReactorContext& _rctx, F&& _f) { - if (solid_function_empty(f_)) { + if (not f_) { f_ = std::forward(_f); doPostAccept(_rctx); return false; @@ -74,7 +75,7 @@ class Listener : public CompletionHandler { template bool accept(ReactorContext& _rctx, F&& _f, SocketDevice& _rsd) { - if (solid_function_empty(f_)) { + if (not f_) { contextBind(_rctx); if (this->doTryAccept(_rctx, _rsd)) { diff --git a/solid/frame/aio/aioreactor.hpp b/solid/frame/aio/aioreactor.hpp index 689234db..e693562c 100644 --- a/solid/frame/aio/aioreactor.hpp +++ b/solid/frame/aio/aioreactor.hpp @@ -10,6 +10,8 @@ #pragma once +#include +#include #include #include "solid/frame/aio/aiocommon.hpp" @@ -50,8 +52,10 @@ struct ReactorStatistic : ReactorStatisticBase { std::atomic_uint64_t post_count_; std::atomic_uint64_t post_stop_count_; std::atomic_size_t max_exec_size_; + std::atomic_size_t exec_count_; std::atomic_size_t actor_count_; std::atomic_size_t max_actor_count_; + std::atomic_size_t complete_events_total_ns_{0}; void actorCount(const size_t _count) { @@ -90,6 +94,7 @@ struct ReactorStatistic : ReactorStatisticBase { void execSize(const size_t _sz) { solid_statistic_max(max_exec_size_, _sz); + exec_count_ += _sz; } std::ostream& print(std::ostream& _ros) const override; @@ -122,17 +127,17 @@ class Reactor : public frame::ReactorBase { #else using MutexT = mutex; #endif - const size_t wake_capacity_; - ReactorStatistic& rstatistic_; - size_t actor_count_{0}; - size_t current_exec_size_{0}; - size_t pop_wake_index_{0}; - std::atomic_size_t pending_wake_count_{0}; - std::atomic_size_t push_wake_index_{0}; + const size_t wake_capacity_; + ReactorStatistic& rstatistic_; + size_t actor_count_{0}; + size_t current_exec_size_{0}; + size_t pop_wake_index_{0}; + /* alignas(hardware_destructive_interference_size) */ std::atomic_size_t pending_wake_count_{1u}; + /* alignas(hardware_destructive_interference_size) */ std::atomic_size_t push_wake_index_{0}; public: using StatisticT = ReactorStatistic; - using EventFunctionT = solid_function_t(void(ReactorContext&, EventBase&&)); + using EventFunctionT = solid::Function128T; bool start(); void stop() override; @@ -144,7 +149,7 @@ class Reactor : public frame::ReactorBase { std::tuple pushWakeIndex() noexcept { - const auto index = push_wake_index_.fetch_add(1); + const auto index = push_wake_index_.fetch_add(1, std::memory_order_relaxed); return {index % wake_capacity_, frame::impl::computeCounter(index, wake_capacity_)}; } @@ -230,7 +235,7 @@ class Reactor : public frame::ReactorBase { return ReactorContext(*this, _rcrttime); } - void update(ReactorContext& _rctx, const size_t _completion_handler_index, const size_t _actor_index) const + static void update(ReactorContext& _rctx, const size_t _completion_handler_index, const size_t _actor_index) { _rctx.completion_heandler_index_ = _completion_handler_index; _rctx.actor_index_ = _actor_index; @@ -247,7 +252,6 @@ class Reactor : public frame::ReactorBase { void doCompleteIo(NanoTime const& _rcrttime, const size_t _sz); void doCompleteTimer(NanoTime const& _rcrttime); - void doCompleteEvents(ReactorContext const& _rctx); void doCompleteEvents(NanoTime const& _rcrttime); void doStoreSpecific(); void doClearSpecific(); @@ -368,8 +372,8 @@ class Reactor : public impl::Reactor { using WakeStubT = impl::WakeStub; using ExecQueueT = Queue; - ExecQueueT exec_q_; - std::unique_ptr wake_arr_; + ExecQueueT exec_q_; + alignas(hardware_destructive_interference_size) std::unique_ptr wake_arr_; public: using ActorT = Actor; @@ -395,9 +399,9 @@ class Reactor : public impl::Reactor { rstub.reset(uid, _revent, std::move(_ract), &_rsvc); - notify = pending_wake_count_.fetch_add(1) == 0; - rstub.notifyWhilePush(); + + notify = pending_wake_count_.fetch_add(1, std::memory_order_release) == 0; } if (notify) { { @@ -424,9 +428,9 @@ class Reactor : public impl::Reactor { rstub.reset(uid, std::move(_revent), std::move(_ract), &_rsvc); - notify = pending_wake_count_.fetch_add(1) == 0; - rstub.notifyWhilePush(); + + notify = pending_wake_count_.fetch_add(1, std::memory_order_release) == 0; } if (notify) { @@ -452,9 +456,9 @@ class Reactor : public impl::Reactor { rstub.reset(_ractuid, _revent); - notify = pending_wake_count_.fetch_add(1) == 0; - rstub.notifyWhilePush(); + + notify = pending_wake_count_.fetch_add(1, std::memory_order_release) == 0; } if (notify) { { @@ -478,9 +482,9 @@ class Reactor : public impl::Reactor { rstub.reset(_ractuid, std::move(_revent)); - notify = pending_wake_count_.fetch_add(1) == 0; - rstub.notifyWhilePush(); + + notify = pending_wake_count_.fetch_add(1, std::memory_order_release) == 0; } if (notify) { { @@ -524,14 +528,8 @@ class Reactor : public impl::Reactor { void doCompleteEvents(NanoTime const& _rcrttime, const UniqueId& _completion_handler_uid) override { - solid_log(logger, Verbose, ""); - - if (pending_wake_count_.load(/* std::memory_order_relaxed */) && !emptyFreeUids()) { - std::lock_guard lock(mutex()); - pushFreeUids(); - } - ReactorContext ctx(context(_rcrttime)); + bool has_events = false; while (true) { const size_t index = pop_wake_index_ % wake_capacity_; @@ -543,14 +541,19 @@ class Reactor : public impl::Reactor { addActor(rstub.uid_, *rstub.pservice_, std::move(rstub.actor_ptr_)); } exec_q_.push(ExecStubT(rstub.uid_, &call_actor_on_event, _completion_handler_uid, std::move(rstub.event_))); - --pending_wake_count_; ++pop_wake_index_; + has_events = true; rstub.clear(); rstub.notifyWhilePop(); } else { break; } } + + if (has_events and not emptyFreeUids()) { + std::lock_guard lock(mutex()); + pushFreeUids(); + } } size_t doCompleteExec(NanoTime const& _rcrttime) override @@ -563,7 +566,6 @@ class Reactor : public impl::Reactor { while ((sz--) != 0) { auto& rexec(exec_q_.front()); - solid_log(logger, Verbose, sz << " qsz = " << exec_q_.size()); if (isValid(rexec.actor_uid_, rexec.completion_handler_uid_)) { ctx.clearError(); update(ctx, static_cast(rexec.completion_handler_uid_.index), static_cast(rexec.actor_uid_.index)); @@ -577,7 +579,7 @@ class Reactor : public impl::Reactor { }; constexpr size_t reactor_default_event_small_size = std::max(sizeof(Function), sizeof(std::function)); -using ReactorEventT = Event; +using ReactorEventT = Event; using ReactorT = Reactor; //----------------------------------------------------------------------------- diff --git a/solid/frame/aio/aiostream.hpp b/solid/frame/aio/aiostream.hpp index e333cbe4..b8bb302a 100644 --- a/solid/frame/aio/aiostream.hpp +++ b/solid/frame/aio/aiostream.hpp @@ -26,8 +26,8 @@ class ReactorContext; template class Stream : public CompletionHandler { using ThisT = Stream; - using RecvFunctionT = solid_function_t(void(ThisT&, ReactorContext&)); - using SendFunctionT = solid_function_t(void(ThisT&, ReactorContext&)); + using RecvFunctionT = solid::Function128T; + using SendFunctionT = solid::Function128T; static void on_init_completion(CompletionHandler& _rch, ReactorContext& _rctx) { @@ -329,14 +329,14 @@ class Stream : public CompletionHandler { this->deactivate(false); } - bool hasPendingRecv() const + [[nodiscard]] bool hasPendingRecv() const { - return !solid_function_empty(recv_fnc); + return recv_fnc.has_value(); } - bool hasPendingSend() const + [[nodiscard]] bool hasPendingSend() const { - return !solid_function_empty(send_fnc); + return send_fnc.has_value(); } SocketDevice& device() { @@ -370,7 +370,7 @@ class Stream : public CompletionHandler { template bool postRecvSome(ReactorContext& _rctx, char* _buf, size_t _bufcp, F&& _f) { - if (solid_function_empty(recv_fnc)) { + if (not recv_fnc) { using RealF = typename std::decay::type; recv_fnc = RecvSomeFunctor{std::forward(_f)}; recv_buf = _buf; @@ -389,7 +389,7 @@ class Stream : public CompletionHandler { template bool recvSome(ReactorContext& _rctx, char* _buf, size_t _bufcp, F&& _f, size_t& _sz) { - if (solid_function_empty(recv_fnc)) { + if (not recv_fnc) { errorClear(_rctx); contextBind(_rctx); @@ -420,7 +420,7 @@ class Stream : public CompletionHandler { template bool postSendAll(ReactorContext& _rctx, const char* _buf, size_t _bufcp, F&& _f) { - if (solid_function_empty(send_fnc)) { + if (not send_fnc) { using RealF = typename std::decay::type; send_fnc = SendAllFunctor{std::forward(_f)}; send_buf = _buf; @@ -439,7 +439,7 @@ class Stream : public CompletionHandler { template bool sendAll(ReactorContext& _rctx, const char* _buf, size_t _bufcp, F&& _f) { - if (solid_function_empty(send_fnc)) { + if (not send_fnc) { errorClear(_rctx); contextBind(_rctx); @@ -464,7 +464,7 @@ class Stream : public CompletionHandler { template bool connect(ReactorContext& _rctx, SocketAddressStub const& _rsas, F&& _f) { - if (solid_function_empty(send_fnc)) { + if (not send_fnc) { errorClear(_rctx); contextBind(_rctx); @@ -507,7 +507,7 @@ class Stream : public CompletionHandler { template bool secureConnect(ReactorContext& _rctx, F&& _f) { - if (solid_function_empty(send_fnc)) { + if (not send_fnc) { errorClear(_rctx); contextBind(_rctx); @@ -532,7 +532,7 @@ class Stream : public CompletionHandler { template bool secureAccept(ReactorContext& _rctx, F&& _f) { - if (solid_function_empty(recv_fnc)) { + if (not recv_fnc) { errorClear(_rctx); contextBind(_rctx); @@ -557,7 +557,7 @@ class Stream : public CompletionHandler { template bool secureShutdown(ReactorContext& _rctx, F&& _f) { - if (solid_function_empty(send_fnc)) { + if (not send_fnc) { errorClear(_rctx); contextBind(_rctx); @@ -640,7 +640,7 @@ class Stream : public CompletionHandler { void doRecv(ReactorContext& _rctx) { - if (!recv_is_posted && !solid_function_empty(recv_fnc)) { + if (!recv_is_posted && recv_fnc) { solid_log(logger, Verbose, ""); errorClear(_rctx); @@ -650,7 +650,7 @@ class Stream : public CompletionHandler { void doSend(ReactorContext& _rctx) { - if (!send_is_posted && !solid_function_empty(send_fnc)) { + if (!send_is_posted && send_fnc) { errorClear(_rctx); send_fnc(*this, _rctx); @@ -730,11 +730,11 @@ class Stream : public CompletionHandler { error(_rctx, error_stream_socket); systemError(_rctx, s.device().error()); - if (!solid_function_empty(send_fnc)) { + if (send_fnc) { send_buf_sz = send_buf_cp = 0; send_fnc(*this, _rctx); } - if (!solid_function_empty(recv_fnc)) { + if (recv_fnc) { recv_buf_sz = recv_buf_cp = 0; recv_fnc(*this, _rctx); } @@ -742,16 +742,16 @@ class Stream : public CompletionHandler { void doClearRecv(ReactorContext& _rctx) { - solid_function_clear(recv_fnc); - solid_assert_log(solid_function_empty(recv_fnc), generic_logger); + recv_fnc = nullptr; + solid_assert_log(not recv_fnc, generic_logger); recv_buf = nullptr; recv_buf_sz = recv_buf_cp = 0; } void doClearSend(ReactorContext& _rctx) { - solid_function_clear(send_fnc); - solid_assert_log(solid_function_empty(send_fnc), generic_logger); + send_fnc = nullptr; + solid_assert_log(not send_fnc, generic_logger); send_buf = nullptr; send_buf_sz = send_buf_cp = 0; } diff --git a/solid/frame/aio/aiotimer.hpp b/solid/frame/aio/aiotimer.hpp index e815b726..0ade3082 100644 --- a/solid/frame/aio/aiotimer.hpp +++ b/solid/frame/aio/aiotimer.hpp @@ -16,6 +16,7 @@ #include "aiocompletion.hpp" #include "aioerror.hpp" #include "aioreactorcontext.hpp" +#include "solid/utility/function.hpp" namespace solid { namespace frame { @@ -54,7 +55,7 @@ class SteadyTimer : public CompletionHandler { { } - typedef solid_function_t(void(ReactorContext&)) FunctionT; + using FunctionT = solid::Function96T; FunctionT function_; size_t storeidx_; @@ -81,7 +82,7 @@ class SteadyTimer : public CompletionHandler { bool hasPending() const { - return !solid_function_empty(function_); + return function_.has_value(); } // Returns false when the operation is scheduled for completion. On completion _f(...) will be called. @@ -119,7 +120,7 @@ class SteadyTimer : public CompletionHandler { void cancel(ReactorContext& _rctx) { - if (!solid_function_empty(function_)) { + if (function_) { remTimer(_rctx, storeidx_); error(_rctx, error_timer_cancel); doExec(_rctx); @@ -138,7 +139,7 @@ class SteadyTimer : public CompletionHandler { } void doClear(ReactorContext& _rctx) { - solid_function_clear(function_); + function_ = nullptr; remTimer(_rctx, storeidx_); storeidx_ = InvalidIndex(); } diff --git a/solid/frame/aio/openssl/aiosecurecontext.hpp b/solid/frame/aio/openssl/aiosecurecontext.hpp index 9bcf6670..fbe61b9f 100644 --- a/solid/frame/aio/openssl/aiosecurecontext.hpp +++ b/solid/frame/aio/openssl/aiosecurecontext.hpp @@ -9,15 +9,20 @@ // #pragma once +#include "solid/utility/common.hpp" +#ifdef SOLID_ON_WINDOWS + +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#endif #include "openssl/ssl.h" #include "solid/system/error.hpp" #include "solid/utility/function.hpp" -namespace solid { -namespace frame { -namespace aio { -namespace openssl { +namespace solid::frame::aio::openssl { enum struct PasswordPurpose { Read, @@ -89,14 +94,11 @@ class Context { ErrorCodeT doSetPasswordCallback(); private: - using PasswordFunctionT = solid_function_t(std::string(std::size_t, PasswordPurpose)); + using PasswordFunctionT = Function; friend class Socket; SSL_CTX* pctx; PasswordFunctionT pwdfnc; }; -} // namespace openssl -} // namespace aio -} // namespace frame -} // namespace solid +} // namespace solid::frame::aio::openssl diff --git a/solid/frame/aio/openssl/aiosecuresocket.hpp b/solid/frame/aio/openssl/aiosecuresocket.hpp index 5530d14c..a7229e7d 100644 --- a/solid/frame/aio/openssl/aiosecuresocket.hpp +++ b/solid/frame/aio/openssl/aiosecuresocket.hpp @@ -10,15 +10,22 @@ #pragma once +#include "solid/utility/common.hpp" +#ifdef SOLID_ON_WINDOWS + +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#endif + #include "openssl/ssl.h" #include "solid/frame/aio/aiosocketbase.hpp" #include "solid/system/socketdevice.hpp" #include "solid/utility/function.hpp" #include -namespace solid { -namespace frame { -namespace aio { +namespace solid::frame::aio { class ReactorContext; @@ -26,7 +33,7 @@ namespace openssl { class Context; -enum VerifyMode { +enum VerifyMode : std::uint8_t { VerifyModeNone = 1, VerifyModePeer = 2, VerifyModeFailIfNoPeerCert = 4, @@ -40,7 +47,7 @@ class Socket; struct VerifyContext { using NativeContextT = X509_STORE_CTX; - NativeContextT* nativeHandle() const + [[nodiscard]] NativeContextT* nativeHandle() const { return ssl_ctx; } @@ -57,7 +64,6 @@ struct VerifyContext { { } -private: NativeContextT* ssl_ctx; }; @@ -126,7 +132,7 @@ class Socket : public SocketBase { static int on_verify(int preverify_ok, X509_STORE_CTX* x509_ctx); private: - using VerifyFunctionT = solid_function_t(bool(void*, bool, VerifyContextT&)); + using VerifyFunctionT = Function; SSL* pssl; bool want_read_on_recv; @@ -142,6 +148,4 @@ inline Socket::NativeHandleT Socket::nativeHandle() const } } // namespace openssl -} // namespace aio -} // namespace frame -} // namespace solid +} // namespace solid::frame::aio diff --git a/solid/frame/aio/openssl/src/aiosecuresocket.cpp b/solid/frame/aio/openssl/src/aiosecuresocket.cpp index cd87f2b2..17356370 100644 --- a/solid/frame/aio/openssl/src/aiosecuresocket.cpp +++ b/solid/frame/aio/openssl/src/aiosecuresocket.cpp @@ -7,8 +7,17 @@ // 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. // -#include "solid/frame/aio/openssl/aiosecuresocket.hpp" + +#include "solid/utility/common.hpp" + +#ifdef SOLID_ON_WINDOWS +#define NOMINMAX +#include +#include +#endif + #include "solid/frame/aio/openssl/aiosecurecontext.hpp" +#include "solid/frame/aio/openssl/aiosecuresocket.hpp" #include "solid/frame/aio/aioerror.hpp" @@ -405,7 +414,7 @@ ErrorCodeT Context::doSetPasswordCallback() buf[0] = 0; - if (!solid_function_empty(rthis.pwdfnc)) { + if (rthis.pwdfnc) { std::string pwd = rthis.pwdfnc(size, rwflag == 1 ? PasswordPurpose::Write : PasswordPurpose::Read); size_t sz = strlen(pwd.c_str()); @@ -910,7 +919,7 @@ ErrorCodeT Socket::doPrepareVerifyCallback(VerifyMaskT _verify_mask) solid_check_log(ssl && pthis, logger); - if (!solid_function_empty(pthis->verify_cbk)) { + if (pthis->verify_cbk) { VerifyContext vctx(x509_ctx); bool rv = pthis->verify_cbk(pctx, preverify_ok != 0, vctx); diff --git a/solid/frame/aio/src/aiolistener.cpp b/solid/frame/aio/src/aiolistener.cpp index 63ed5b8e..955e5b3a 100644 --- a/solid/frame/aio/src/aiolistener.cpp +++ b/solid/frame/aio/src/aiolistener.cpp @@ -36,11 +36,11 @@ const LoggerT logger("solid::frame::aio"); switch (rthis.reactorEvent(_rctx)) { case ReactorEventE::Recv: - if (!solid_function_empty(rthis.f_)) { + if (rthis.f_) { SocketDevice sd; FunctionT tmpf; std::swap(tmpf, rthis.f_); - solid_assert_log(solid_function_empty(rthis.f_), logger); + solid_assert_log(not rthis.f_, logger); rthis.doAccept(_rctx, sd); tmpf(_rctx, sd); @@ -48,7 +48,7 @@ const LoggerT logger("solid::frame::aio"); break; case ReactorEventE::Error: case ReactorEventE::Hangup: - if (!solid_function_empty(rthis.f_)) { + if (rthis.f_) { SocketDevice sd; FunctionT tmpf; std::swap(tmpf, rthis.f_); @@ -72,7 +72,7 @@ const LoggerT logger("solid::frame::aio"); Listener& rthis = *pthis; SocketDevice sd; - if (!solid_function_empty(rthis.f_) && rthis.doTryAccept(_rctx, sd)) { + if (rthis.f_ && rthis.doTryAccept(_rctx, sd)) { FunctionT tmpf; std::swap(tmpf, rthis.f_); tmpf(_rctx, sd); @@ -134,7 +134,7 @@ void Listener::doAccept(ReactorContext& _rctx, SocketDevice& _rsd) void Listener::doClear(ReactorContext& _rctx) { - solid_function_clear(f_); + f_ = nullptr; remDevice(_rctx, s_.device()); f_ = &on_dummy; } diff --git a/solid/frame/aio/src/aioreactor.cpp b/solid/frame/aio/src/aioreactor.cpp index d74d6e16..49444490 100644 --- a/solid/frame/aio/src/aioreactor.cpp +++ b/solid/frame/aio/src/aioreactor.cpp @@ -7,9 +7,11 @@ // 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. // +#include #include #include "solid/system/common.hpp" +#include "solid/system/statistic.hpp" #if defined(SOLID_USE_EPOLL) @@ -64,9 +66,7 @@ using namespace std; -namespace solid { -namespace frame { -namespace aio { +namespace solid::frame::aio { namespace { @@ -122,7 +122,6 @@ struct ActorStub { //============================================================================= constexpr size_t min_event_capacity = 32; -constexpr size_t max_event_capacity = 1024 * 64; //============================================================================= @@ -407,6 +406,12 @@ bool Reactor::start() } } +//----------------------------------------------------------------------------- +inline void Reactor::doCompleteEvents(NanoTime const& _rcrttime) +{ + doCompleteEvents(_rcrttime, impl_->dummyCompletionHandlerUid()); +} + //----------------------------------------------------------------------------- /*NOTE: @@ -421,7 +426,7 @@ bool Reactor::start() to be delivered to the actor. */ -// #define SOLID_AIO_TRACE_DURATION +#define SOLID_AIO_TRACE_DURATION void Reactor::run() { using namespace std::chrono; @@ -431,41 +436,57 @@ void Reactor::run() bool running = true; int waitmsec; NanoTime waittime; - size_t waitcnt = 0; + auto previous_wake_count = pending_wake_count_.load(); while (running) { impl_->current_time_ = NanoTime::nowSteady(); - crtload = actor_count_ + impl_->device_count_ + current_exec_size_; + crtload = actor_count_ + impl_->device_count_ + current_exec_size_; + bool can_wait = current_exec_size_ == 0u; + { + decltype(previous_wake_count) new_count = not can_wait; + auto current_wake_count = pending_wake_count_.exchange(new_count, std::memory_order_acquire); + + can_wait = can_wait and (current_wake_count == previous_wake_count); + previous_wake_count = new_count; + } + #if defined(SOLID_USE_EPOLL2) - waittime = impl_->computeWaitDuration(impl_->current_time_, current_exec_size_ == 0 && pending_wake_count_.load() == 0); - solid_log(logger, Verbose, "epoll_wait wait = " << waittime << ' ' << impl_->reactor_fd_ << ' ' << impl_->event_vec_.size()); + waittime + = impl_->computeWaitDuration(impl_->current_time_, can_wait); + + // solid_log(logger, Verbose, "epoll_wait wait = " << waittime << ' ' << impl_->reactor_fd_ << ' ' << impl_->event_vec_.size()); selcnt = epoll_pwait2(impl_->reactor_fd_, impl_->event_vec_.data(), static_cast(impl_->event_vec_.size()), waittime != NanoTime::max() ? &waittime : nullptr, nullptr); - if (waittime.seconds() != 0 && waittime.nanoSeconds() != 0) { - ++waitcnt; - } #elif defined(SOLID_USE_EPOLL) - waitmsec = impl_->computeWaitDuration(impl_->current_time_, current_exec_size_ == 0 && pending_wake_count_.load() == 0); + waitmsec + = impl_->computeWaitDuration(impl_->current_time_, can_wait); solid_log(logger, Verbose, "epoll_wait wait = " << waitmsec); selcnt = epoll_wait(impl_->reactor_fd_, impl_->event_vec_.data(), static_cast(impl_->event_vec_.size()), waitmsec); + #elif defined(SOLID_USE_KQUEUE) - waittime = impl_->computeWaitDuration(impl_->current_time_, current_exec_size_ == 0 && pending_wake_count_.load() == 0); + waittime + = impl_->computeWaitDuration(impl_->current_time_, can_wait); solid_log(logger, Verbose, "kqueue wait = " << waittime); selcnt = kevent(impl_->reactor_fd_, nullptr, 0, impl_->event_vec_.data(), static_cast(impl_->event_vec_.size()), waittime != NanoTime::max() ? &waittime : nullptr); + #elif defined(SOLID_USE_WSAPOLL) - waitmsec = impl_->computeWaitDuration(impl_->current_time_, current_exec_size_ == 0 && pending_wake_count_.load() == 0); + waitmsec + = impl_->computeWaitDuration(impl_->current_time_, can_wait); solid_log(logger, Verbose, "wsapoll wait msec = " << waitmsec); selcnt = WSAPoll(impl_->event_vec_.data(), impl_->event_vec_.size(), waitmsec); + #endif - impl_->current_time_ = NanoTime::nowSteady(); -#ifdef SOLID_AIO_TRACE_DURATION - const auto start = high_resolution_clock::now(); -#endif + if (waittime) { + impl_->current_time_ = NanoTime::nowSteady(); + } + + doCompleteEvents(impl_->current_time_); // See NOTE above + #if defined(SOLID_USE_WSAPOLL) if (selcnt > 0 || impl_->connect_vec_.size()) { #else @@ -473,6 +494,7 @@ void Reactor::run() #endif crtload += selcnt; doCompleteIo(impl_->current_time_, selcnt); + impl_->current_time_ = NanoTime::nowSteady(); } else if (selcnt < 0 && errno != EINTR) { solid_log(logger, Error, "epoll_wait errno = " << last_system_error().message()); running = false; @@ -480,32 +502,20 @@ void Reactor::run() } else { solid_log(logger, Verbose, "epoll_wait done"); } -#ifdef SOLID_AIO_TRACE_DURATION - const auto elapsed_io = duration_cast(high_resolution_clock::now() - start).count(); -#endif - impl_->current_time_ = NanoTime::nowSteady(); + doCompleteTimer(impl_->current_time_); -#ifdef SOLID_AIO_TRACE_DURATION - const auto elapsed_timer = duration_cast(high_resolution_clock::now() - start).count(); +#if defined(SOLID_AIO_TRACE_DURATION) + auto const start_time = std::chrono::high_resolution_clock::now(); #endif - impl_->current_time_ = NanoTime::nowSteady(); - doCompleteEvents(impl_->current_time_); // See NOTE above -#ifdef SOLID_AIO_TRACE_DURATION - const auto elapsed_event = duration_cast(high_resolution_clock::now() - start).count(); -#endif - impl_->current_time_ = NanoTime::nowSteady(); - const auto execnt = doCompleteExec(impl_->current_time_); -#ifdef SOLID_AIO_TRACE_DURATION - const auto elapsed_total = duration_cast(high_resolution_clock::now() - start).count(); - if (elapsed_total >= 6000) { - solid_log(logger, Warning, "reactor loop duration: io " << elapsed_io << " timers " << elapsed_timer << " events " << elapsed_event << " total " << elapsed_total << " execnt " << execnt); - } + doCompleteExec(impl_->current_time_); +#if defined(SOLID_AIO_TRACE_DURATION) + auto const stop_time = std::chrono::high_resolution_clock::now(); + uint64_t const ns = std::chrono::duration_cast(stop_time - start_time).count(); + solid_statistic_add(rstatistic_.complete_events_total_ns_, ns); #endif - (void)execnt; running = impl_->running_ || (actor_count_ != 0) || current_exec_size_ != 0; } - solid_log(logger, Warning, "reactor waitcount = " << waitcnt); impl_->event_actor_ptr_->stop(); doClearSpecific(); @@ -908,18 +918,6 @@ void Reactor::doCompleteTimer(NanoTime const& _rcrttime) }); } -//----------------------------------------------------------------------------- -void Reactor::doCompleteEvents(ReactorContext const& _rctx) -{ - doCompleteEvents(_rctx.nanoTime(), impl_->dummyCompletionHandlerUid()); -} - -void Reactor::doCompleteEvents(NanoTime const& _rcrttime) -{ - ReactorContext ctx(*this, _rcrttime); - doCompleteEvents(ctx); -} - //----------------------------------------------------------------------------- /*static*/ void Reactor::call_actor_on_event(ReactorContext& _rctx, EventBase&& _uevent) @@ -1371,7 +1369,7 @@ void EventHandler::write(impl::Reactor& _rreactor) /*static*/ void EventHandler::on_completion(CompletionHandler& _rch, ReactorContext& _rctx) { - EventHandler& rthis = static_cast(_rch); + [[maybe_unused]] EventHandler& rthis = static_cast(_rch); #if defined(SOLID_USE_EPOLL) uint64_t v = -1; ssize_t rv; @@ -1389,7 +1387,6 @@ void EventHandler::write(impl::Reactor& _rreactor) rthis.contextBind(_rctx); rthis.reactor(_rctx).modDevice(_rctx, rthis.dev_, ReactorWaitRequestE::Read); #endif - rthis.reactor(_rctx).doCompleteEvents(_rctx); } //----------------------------------------------------------------------------- @@ -1440,8 +1437,10 @@ std::ostream& ReactorStatistic::print(std::ostream& _ros) const _ros << " post_count = " << post_count_; _ros << " post_stop_count = " << post_stop_count_; _ros << " max_exec_size = " << max_exec_size_; + _ros << " exec_count = " << exec_count_; _ros << " actor_count = " << actor_count_; _ros << " max_actor_count = " << max_actor_count_; + _ros << " complete_events_total_ms = " << (complete_events_total_ns_ / 1000000u); return _ros; } @@ -1459,6 +1458,4 @@ void ReactorStatistic::clear() max_actor_count_ = 0; } -} // namespace aio -} // namespace frame -} // namespace solid +} // namespace solid::frame::aio diff --git a/solid/frame/aio/test/test_echo_tcp_stress.cpp b/solid/frame/aio/test/test_echo_tcp_stress.cpp index bab2dbfc..91de9aca 100644 --- a/solid/frame/aio/test/test_echo_tcp_stress.cpp +++ b/solid/frame/aio/test/test_echo_tcp_stress.cpp @@ -37,7 +37,7 @@ namespace { using AioSchedulerT = frame::Scheduler; using AtomicSizeT = atomic; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; bool running = true; mutex mtx; @@ -990,7 +990,7 @@ namespace relay { void Listener::onAccept(frame::aio::ReactorContext& _rctx, SocketDevice& _rsd) { solid_dbg(generic_logger, Info, ""); - unsigned repeatcnt = SocketInfo::max_listen_backlog_size(); + size_t repeatcnt = SocketInfo::max_listen_backlog_size(); do { if (!_rctx.error()) { diff --git a/solid/frame/common.hpp b/solid/frame/common.hpp index b4822642..3807e432 100644 --- a/solid/frame/common.hpp +++ b/solid/frame/common.hpp @@ -16,10 +16,8 @@ #include "solid/reflection/reflection.hpp" #include "solid/system/convertors.hpp" #include "solid/utility/common.hpp" -#include "solid/utility/function.hpp" -namespace solid { -namespace frame { +namespace solid::frame { using IndexT = uint64_t; using UniqueT = uint32_t; @@ -41,11 +39,11 @@ struct UniqueId { { } - bool isInvalid() const + [[nodiscard]] bool isInvalid() const { return index == InvalidIndex(); } - bool isValid() const + [[nodiscard]] bool isValid() const { return !isInvalid(); } @@ -173,5 +171,4 @@ enum struct ReactorWaitRequestE { Error }; -} // namespace frame -} // namespace solid +} // namespace solid::frame diff --git a/solid/frame/mprpc/mprpccompression_snappy.hpp b/solid/frame/mprpc/mprpccompression_snappy.hpp index 1ca06f81..5b389069 100644 --- a/solid/frame/mprpc/mprpccompression_snappy.hpp +++ b/solid/frame/mprpc/mprpccompression_snappy.hpp @@ -16,10 +16,7 @@ #include "solid/frame/mprpc/mprpcconfiguration.hpp" #include "solid/frame/mprpc/mprpcprotocol.hpp" -namespace solid { -namespace frame { -namespace mprpc { -namespace snappy { +namespace solid::frame::mprpc::snappy { struct Engine { const size_t buff_threshold; @@ -37,7 +34,7 @@ struct Engine { if (_bufsz > buff_threshold) { - char tmpbuf[Protocol::MaxPacketDataSize]; + char tmpbuf[Protocol::max_packet_size]; size_t len = 0; @@ -80,7 +77,4 @@ inline void setup(mprpc::Configuration& _rcfg, size_t _buff_threshold = 1024, si _rcfg.writer.inplace_compress_fnc = Engine(_buff_threshold, _diff_threshold); } -} // namespace snappy -} // namespace mprpc -} // namespace frame -} // namespace solid +} // namespace solid::frame::mprpc::snappy diff --git a/solid/frame/mprpc/mprpcconfiguration.hpp b/solid/frame/mprpc/mprpcconfiguration.hpp index 19866071..4085e616 100644 --- a/solid/frame/mprpc/mprpcconfiguration.hpp +++ b/solid/frame/mprpc/mprpcconfiguration.hpp @@ -22,6 +22,7 @@ #include "solid/frame/mprpc/mprpcprotocol.hpp" #include "solid/frame/scheduler.hpp" +#include "solid/system/log.hpp" #include "solid/system/socketaddress.hpp" #include "solid/system/socketdevice.hpp" #include "solid/utility/function.hpp" @@ -39,14 +40,13 @@ struct ActorProxy; namespace mprpc { -enum struct ConnectionValues : size_t { - SocketEmplacementSize = 128 -}; +constexpr size_t socket_emplace_size = 512; +constexpr size_t socket_emplace_align = 16; class Service; class Connection; class MessageWriter; -struct ConnectionContext; +class ConnectionContext; class Configuration; typedef void (*OnSecureConnectF)(frame::aio::ReactorContext&); @@ -63,10 +63,8 @@ using RelayDataFlagsT = Flags; std::ostream& operator<<(std::ostream& _ros, const RelayDataFlagsT& _flags); struct RelayData { - SharedBuffer buffer_; - const char* pdata_ = nullptr; - size_t data_size_ = 0; - RelayData* pnext_ = nullptr; + SharedBufferView buffer_; + RelayData* pnext_ = nullptr; RelayDataFlagsT flags_; MessageHeader::FlagsT message_flags_ = 0; MessageHeader* pmessage_header_ = nullptr; @@ -76,8 +74,6 @@ struct RelayData { RelayData( RelayData&& _rrelmsg) noexcept : buffer_(std::move(_rrelmsg.buffer_)) - , pdata_(_rrelmsg.pdata_) - , data_size_(_rrelmsg.data_size_) , pnext_(nullptr) , flags_(_rrelmsg.flags_) , message_flags_(_rrelmsg.message_flags_) @@ -88,8 +84,6 @@ struct RelayData { RelayData& operator=(RelayData&& _rrelmsg) noexcept { buffer_ = std::move(_rrelmsg.buffer_); - pdata_ = _rrelmsg.pdata_; - data_size_ = _rrelmsg.data_size_; pnext_ = _rrelmsg.pnext_; flags_ = _rrelmsg.flags_; message_flags_ = _rrelmsg.message_flags_; @@ -102,9 +96,6 @@ struct RelayData { void clear() { - pdata_ = nullptr; - data_size_ = 0; - // connection_id_.clear(); buffer_.reset(); pnext_ = nullptr; flags_.reset(); @@ -112,27 +103,27 @@ struct RelayData { pmessage_header_ = nullptr; } - bool isMessageBegin() const + [[nodiscard]] bool isMessageBegin() const { return flags_.has(RelayDataFlagsE::First); } - bool isMessageEnd() const + [[nodiscard]] bool isMessageEnd() const { return flags_.has(RelayDataFlagsE::Last); } - bool isMessageLast() const + [[nodiscard]] bool isMessageLast() const { return isMessageEnd() && !Message::is_response_part(this->message_flags_); } - bool isMessagePart() const + [[nodiscard]] bool isMessagePart() const { return Message::is_response_part(this->message_flags_); } - bool isRequest() const + [[nodiscard]] bool isRequest() const { return Message::is_awaiting_response(this->message_flags_); } @@ -140,13 +131,9 @@ struct RelayData { private: friend class RelayConnection; RelayData( - const SharedBuffer& _buffer, - const char* _pdata, - size_t _data_size, - const bool _is_last) - : buffer_(_buffer) - , pdata_(_pdata) - , data_size_(_data_size) + SharedBufferView&& _buffer, + const bool _is_last) + : buffer_(std::move(_buffer)) { if (_is_last) { flags_.set(RelayDataFlagsE::Last); @@ -162,9 +149,9 @@ enum struct RelayEngineNotification { class RelayEngine { protected: - using PushFunctionT = solid_function_t(bool(RelayData*&, const MessageId&, MessageId&, bool&)); - using DoneFunctionT = solid_function_t(void(SharedBuffer&)); - using CancelFunctionT = solid_function_t(void(const MessageHeader&)); + using PushFunctionT = SmallFunctionT; + using DoneFunctionT = SmallFunctionT; + using CancelFunctionT = SmallFunctionT; RelayEngine() {} virtual ~RelayEngine(); @@ -279,25 +266,25 @@ class RelayEngine { }; using AddressVectorT = std::vector; -using ServerSetupSocketDeviceFunctionT = solid_function_t(bool(SocketDevice&)); -using ClientSetupSocketDeviceFunctionT = solid_function_t(bool(SocketDevice&)); -using ResolveCompleteFunctionT = solid_function_t(void(AddressVectorT&&)); -using ConnectionStopFunctionT = solid_function_t(void(ConnectionContext&)); -using ConnectionStartFunctionT = solid_function_t(void(ConnectionContext&)); -using SendAllocateBufferFunctionT = solid_function_t(SharedBuffer(const uint32_t)); -using RecvAllocateBufferFunctionT = solid_function_t(SharedBuffer(const uint32_t)); -using CompressFunctionT = solid_function_t(size_t(char*, size_t, ErrorConditionT&)); -using UncompressFunctionT = solid_function_t(size_t(char*, const char*, size_t, ErrorConditionT&)); -using ConnectionEnterActiveCompleteFunctionT = solid_function_t(void(ConnectionContext&, ErrorConditionT const&)); -using ConnectionPostCompleteFunctionT = solid_function_t(void(ConnectionContext&)); -using ConnectionSendTimeoutSoftFunctionT = solid_function_t(void(ConnectionContext&)); -using ConnectionEnterPassiveCompleteFunctionT = solid_function_t(void(ConnectionContext&, ErrorConditionT const&)); -using ConnectionSecureHandhakeCompleteFunctionT = solid_function_t(void(ConnectionContext&, ErrorConditionT const&)); -using ConnectionSendRawDataCompleteFunctionT = solid_function_t(void(ConnectionContext&, ErrorConditionT const&)); -using ConnectionRecvRawDataCompleteFunctionT = solid_function_t(void(ConnectionContext&, const char*, size_t&, ErrorConditionT const&)); -using ConnectionOnEventFunctionT = solid_function_t(void(ConnectionContext&, EventBase&)); -using PoolOnEventFunctionT = solid_function_t(void(ConnectionContext&, EventBase&&, const ErrorConditionT&)); -using ActorCreateFunctionT = solid_function_t(ActorIdT(aio::ActorPointerT&&, frame::Service&, EventBase&&, ErrorConditionT&)); +using ServerSetupSocketDeviceFunctionT = solid::Function; +using ClientSetupSocketDeviceFunctionT = solid::Function; +using ResolveCompleteFunctionT = solid::Function; +using ConnectionStopFunctionT = solid::Function; +using ConnectionStartFunctionT = solid::Function; +using SendAllocateBufferFunctionT = solid::Function; +using RecvAllocateBufferFunctionT = solid::Function; +using CompressFunctionT = solid::Function; +using UncompressFunctionT = solid::Function; +using ConnectionEnterActiveCompleteFunctionT = solid::Function; +using ConnectionPostCompleteFunctionT = solid::Function; +using ConnectionSendTimeoutSoftFunctionT = solid::Function; +using ConnectionEnterPassiveCompleteFunctionT = solid::Function; +using ConnectionSecureHandhakeCompleteFunctionT = solid::Function; +using ConnectionSendRawDataCompleteFunctionT = solid::Function; +using ConnectionRecvRawDataCompleteFunctionT = solid::Function; +using ConnectionOnEventFunctionT = solid::Function; +using PoolOnEventFunctionT = solid::Function; +using ActorCreateFunctionT = solid::Function; enum struct ConnectionState { Raw, @@ -343,25 +330,25 @@ class Configuration { ReaderConfiguration reader; WriterConfiguration writer; - std::chrono::milliseconds connection_timeout_recv = std::chrono::minutes(10); - std::chrono::milliseconds connection_timeout_send_soft = std::chrono::seconds(10); - std::chrono::milliseconds connection_timeout_send_hard = std::chrono::minutes(5); - uint8_t connection_recv_buffer_start_capacity_kb = 0; - uint8_t connection_recv_buffer_max_capacity_kb = 64; - uint8_t connection_send_buffer_start_capacity_kb = 0; - uint8_t connection_send_buffer_max_capacity_kb = 64; - uint16_t connection_relay_buffer_count = 8; - ConnectionStopFunctionT connection_stop_fnc; - ConnectionOnEventFunctionT connection_on_event_fnc; - ConnectionSendTimeoutSoftFunctionT connection_on_send_timeout_soft_ = [](ConnectionContext&) {}; - RecvAllocateBufferFunctionT connection_recv_buffer_allocate_fnc; - SendAllocateBufferFunctionT connection_send_buffer_allocate_fnc; - Protocol::PointerT protocol_ptr; - ActorCreateFunctionT actor_create_fnc; + std::chrono::milliseconds connection_timeout_recv = std::chrono::minutes(10); + std::chrono::milliseconds connection_timeout_send_soft = std::chrono::seconds(10); + std::chrono::milliseconds connection_timeout_send_hard = std::chrono::minutes(5); + /* [[deprecated("Not used anymore")]] */ uint8_t connection_recv_buffer_start_capacity_kb = 0; + /* [[deprecated("Not used anymore")]] */ uint8_t connection_recv_buffer_max_capacity_kb = 64; + /* [[deprecated("Not used anymore")]] */ uint8_t connection_send_buffer_start_capacity_kb = 0; + /* [[deprecated("Not used anymore")]] */ uint8_t connection_send_buffer_max_capacity_kb = 64; + uint16_t connection_relay_buffer_count = 8; + ConnectionStopFunctionT connection_stop_fnc; + ConnectionOnEventFunctionT connection_on_event_fnc; + ConnectionSendTimeoutSoftFunctionT connection_on_send_timeout_soft_ = [](ConnectionContext&) {}; + RecvAllocateBufferFunctionT connection_recv_buffer_allocate_fnc; + SendAllocateBufferFunctionT connection_send_buffer_allocate_fnc; + Protocol::PointerT protocol_ptr; + ActorCreateFunctionT actor_create_fnc; struct Server { - using ConnectionCreateSocketFunctionT = solid_function_t(SocketStubPtrT(Configuration const&, frame::aio::ActorProxy const&, SocketDevice&&, char*)); - using ConnectionSecureHandshakeFunctionT = solid_function_t(void(ConnectionContext&)); + using ConnectionCreateSocketFunctionT = solid::Function; + using ConnectionSecureHandshakeFunctionT = solid::Function; ConnectionCreateSocketFunctionT connection_create_socket_fnc; ConnectionState connection_start_state = ConnectionState::Passive; @@ -401,9 +388,9 @@ class Configuration { } server; struct Client { - using ConnectionCreateSocketFunctionT = solid_function_t(SocketStubPtrT(Configuration const&, frame::aio::ActorProxy const&, char*)); - using AsyncResolveFunctionT = solid_function_t(void(const std::string&, ResolveCompleteFunctionT&)); - using ConnectionSecureHandshakeFunctionT = solid_function_t(void(ConnectionContext&)); + using ConnectionCreateSocketFunctionT = solid::Function; + using AsyncResolveFunctionT = solid::Function64T; + using ConnectionSecureHandshakeFunctionT = solid::Function; std::chrono::milliseconds connection_timeout_reconnect = std::chrono::seconds(10); std::chrono::milliseconds connection_timeout_keepalive = std::chrono::seconds(5); @@ -498,7 +485,7 @@ class Configuration { bool isClient() const { - return !solid_function_empty(client.name_resolve_fnc); + return client.name_resolve_fnc.has_value(); } bool isServerOnly() const @@ -511,9 +498,9 @@ class Configuration { return !isServer() && isClient(); } - SharedBuffer allocateRecvBuffer() const; + [[nodiscard]] MutableSharedBuffer allocateRecvBuffer() const; - SharedBuffer allocateSendBuffer() const; + [[nodiscard]] MutableSharedBuffer allocateSendBuffer() const; void check() const; diff --git a/solid/frame/mprpc/mprpccontext.hpp b/solid/frame/mprpc/mprpccontext.hpp index d2e54aef..1a649eef 100644 --- a/solid/frame/mprpc/mprpccontext.hpp +++ b/solid/frame/mprpc/mprpccontext.hpp @@ -55,7 +55,7 @@ struct ConnectionProxy { ConnectionProxy() {} private: - friend struct ConnectionContext; + friend class ConnectionContext; Service& service(frame::aio::ReactorContext& _rctx) const; Connection& connection(frame::aio::ReactorContext& _rctx) const; }; @@ -80,37 +80,37 @@ class ConnectionContext : NonCopyable { { } - Service& service() const + [[nodiscard]] Service& service() const { return rservice_; } - Configuration const& configuration() const; + [[nodiscard]] Configuration const& configuration() const; - ActorIdT connectionId() const; + [[nodiscard]] ActorIdT connectionId() const; - const UniqueId& relayId() const; + [[nodiscard]] const UniqueId& relayId() const; - RecipientId recipientId() const; + [[nodiscard]] RecipientId recipientId() const; - const std::string& recipientName() const; + [[nodiscard]] const std::string& recipientName() const; - SocketDevice const& device() const; + [[nodiscard]] SocketDevice const& device() const; - bool isConnectionActive() const; - bool isConnectionServer() const; + [[nodiscard]] bool isConnectionActive() const; + [[nodiscard]] bool isConnectionServer() const; - const MessageFlagsT& messageFlags() const + [[nodiscard]] const MessageFlagsT& messageFlags() const { return message_flags_; } - MessageId const& localMessageId() const + [[nodiscard]] MessageId const& localMessageId() const { return message_id_; } - MessagePointerT<> fetchRequest(Message const& _rmsg) const; + [[nodiscard]] SendMessagePointerT<> fetchRequest(Message const& _rmsg) const; //! Keep any connection data Any<>& any(); @@ -125,7 +125,7 @@ class ConnectionContext : NonCopyable { private: // not used for now - RequestId const& requestId() const + [[nodiscard]] RequestId const& requestId() const { return request_id_; } diff --git a/solid/frame/mprpc/mprpcid.hpp b/solid/frame/mprpc/mprpcid.hpp index 8f3ec727..b6025c48 100644 --- a/solid/frame/mprpc/mprpcid.hpp +++ b/solid/frame/mprpc/mprpcid.hpp @@ -10,7 +10,7 @@ class EngineCore; } class Service; -struct ConnectionContext; +class ConnectionContext; //! A structure to uniquely indetify an IPC connection pool /*! @@ -31,7 +31,7 @@ struct ConnectionPoolId : UniqueId { class RecipientId { friend class Service; friend class Connection; - friend struct ConnectionContext; + friend class ConnectionContext; ConnectionPoolId pool_id_; ActorIdT connection_id_; diff --git a/solid/frame/mprpc/mprpcmessage.hpp b/solid/frame/mprpc/mprpcmessage.hpp index ef46b29e..f8bfa1b4 100644 --- a/solid/frame/mprpc/mprpcmessage.hpp +++ b/solid/frame/mprpc/mprpcmessage.hpp @@ -16,7 +16,6 @@ #include "solid/system/common.hpp" #include "solid/system/exception.hpp" -#include "solid/utility/cacheable.hpp" #include "solid/utility/function.hpp" #include "solid/utility/typetraits.hpp" @@ -24,13 +23,10 @@ #include "solid/frame/mprpc/mprpcmessageflags.hpp" #include "solid/reflection/v1/reflection.hpp" -#if !defined(SOLID_MPRPC_USE_SHARED_PTR_MESSAGE) #include "solid/utility/intrusiveptr.hpp" -#endif +#include "solid/utility/pool.hpp" -namespace solid { -namespace frame { -namespace mprpc { +namespace solid::frame::mprpc { class Service; class Connection; @@ -151,11 +147,8 @@ struct MessageHeader { } } }; -#if defined(SOLID_MPRPC_USE_SHARED_PTR_MESSAGE) -struct Message : SharedCacheable { -#else -struct Message : IntrusiveCacheable { -#endif + +struct Message : IntrusiveThreadSafeBase { using FlagsT = MessageFlagsValueT; @@ -379,31 +372,31 @@ struct Message : IntrusiveCacheable { MessageHeader header_; }; -#if defined(SOLID_MPRPC_USE_SHARED_PTR_MESSAGE) template -using MessagePointerT = std::shared_ptr; +using MutableMessagePointerT = MutableIntrusivePtr; -template -MessagePointerT make_message(Args&&... _args) -{ - return std::make_shared(std::forward(_args)...); -} +template +using ConstMessagePointerT = ConstIntrusivePtr; -#else template -using MessagePointerT = IntrusivePtr; +using RecvMessagePointerT = MutableMessagePointerT; + +template +using SendMessagePointerT = ConstMessagePointerT; template -MessagePointerT make_message(Args&&... _args) +auto make_message(Args&&... _args) { - return make_intrusive(std::forward(_args)...); + return make_mutable_intrusive(std::forward(_args)...); } -#endif +template +auto make_pool_message(Args&&... _args) +{ + return Pool::create(std::forward(_args)...); +} -using MessageCompleteFunctionT = solid_function_t(void( - ConnectionContext&, MessagePointerT<>&, MessagePointerT<>&, ErrorConditionT const&)); +using MessageCompleteFunctionT = Function128T&, RecvMessagePointerT<>&, ErrorConditionT const&)>; -} // namespace mprpc -} // namespace frame -} // namespace solid +} // namespace solid::frame::mprpc diff --git a/solid/frame/mprpc/mprpcprotocol.hpp b/solid/frame/mprpc/mprpcprotocol.hpp index 6cec470f..e504da61 100644 --- a/solid/frame/mprpc/mprpcprotocol.hpp +++ b/solid/frame/mprpc/mprpcprotocol.hpp @@ -17,9 +17,7 @@ #include -namespace solid { -namespace frame { -namespace mprpc { +namespace solid::frame::mprpc { class ConnectionContext; @@ -27,25 +25,25 @@ template struct message_complete_traits; template -struct message_complete_traits&, MessagePointerT&, ErrorConditionT const&)> { +struct message_complete_traits&, RecvMessagePointerT&, ErrorConditionT const&)> { typedef Req send_type; typedef Res recv_type; }; template -struct message_complete_traits&, MessagePointerT&, ErrorConditionT const&)> { +struct message_complete_traits&, RecvMessagePointerT&, ErrorConditionT const&)> { typedef Req send_type; typedef Res recv_type; }; template -struct message_complete_traits&, MessagePointerT&, ErrorConditionT const&)> { +struct message_complete_traits&, RecvMessagePointerT&, ErrorConditionT const&)> { typedef Req send_type; typedef Res recv_type; }; template -struct message_complete_traits&, MessagePointerT&, ErrorConditionT const&) const> { +struct message_complete_traits&, RecvMessagePointerT&, ErrorConditionT const&) const> { typedef Req send_type; typedef Res recv_type; }; @@ -74,13 +72,13 @@ struct CompleteHandler { void operator()( ConnectionContext& _rctx, - MessagePointerT<>& _rreq_msg_ptr, - MessagePointerT<>& _rres_msg_ptr, + SendMessagePointerT<>& _rreq_msg_ptr, + RecvMessagePointerT<>& _rres_msg_ptr, ErrorConditionT const& _err) { - MessagePointerT req_msg_ptr(solid::dynamic_pointer_cast(_rreq_msg_ptr)); - MessagePointerT res_msg_ptr(solid::dynamic_pointer_cast(_rres_msg_ptr)); - ErrorConditionT error(_err); + SendMessagePointerT req_msg_ptr(solid::dynamic_pointer_cast(std::move(_rreq_msg_ptr))); + RecvMessagePointerT res_msg_ptr(solid::dynamic_pointer_cast(std::move(_rres_msg_ptr))); + ErrorConditionT error(_err); if (!error && _rreq_msg_ptr && !req_msg_ptr) { error = error_service_bad_cast_request; @@ -99,12 +97,12 @@ class Deserializer { using PointerT = std::unique_ptr; virtual ~Deserializer(); - virtual ptrdiff_t run(ConnectionContext&, const char* _pdata, size_t _data_len, MessageHeader& _rmsghdr) = 0; - virtual ptrdiff_t run(ConnectionContext&, const char* _pdata, size_t _data_len, MessagePointerT<>& _rmsgptr) = 0; - virtual ptrdiff_t run(ConnectionContext&, const char* _pdata, size_t _data_len) = 0; - virtual ErrorConditionT error() const = 0; - virtual bool empty() const = 0; - virtual void clear() = 0; + virtual ptrdiff_t run(ConnectionContext&, const char* _pdata, size_t _data_len, MessageHeader& _rmsghdr) = 0; + virtual ptrdiff_t run(ConnectionContext&, const char* _pdata, size_t _data_len, RecvMessagePointerT<>& _rmsgptr) = 0; + virtual ptrdiff_t run(ConnectionContext&, const char* _pdata, size_t _data_len) = 0; + virtual ErrorConditionT error() const = 0; + virtual bool empty() const = 0; + virtual void clear() = 0; void link(PointerT& _ptr) { @@ -129,12 +127,12 @@ class Serializer { using PointerT = std::unique_ptr; virtual ~Serializer(); - virtual ptrdiff_t run(ConnectionContext&, char* _pdata, size_t _data_len, MessageHeader& _rmsghdr) = 0; - virtual ptrdiff_t run(ConnectionContext&, char* _pdata, size_t _data_len, MessagePointerT<>& _rmsgptr, const size_t _msg_type_idx = 0) = 0; - virtual ptrdiff_t run(ConnectionContext&, char* _pdata, size_t _data_len) = 0; - virtual ErrorConditionT error() const = 0; - virtual bool empty() const = 0; - virtual void clear() = 0; + virtual ptrdiff_t run(ConnectionContext&, char* _pdata, size_t _data_len, MessageHeader const& _rmsghdr) = 0; + virtual ptrdiff_t run(ConnectionContext&, char* _pdata, size_t _data_len, SendMessagePointerT<>& _rmsgptr, const size_t _msg_type_idx = 0) = 0; + virtual ptrdiff_t run(ConnectionContext&, char* _pdata, size_t _data_len) = 0; + virtual ErrorConditionT error() const = 0; + virtual bool empty() const = 0; + virtual void clear() = 0; void link(PointerT& _ptr) { @@ -162,7 +160,8 @@ class Protocol : NonCopyable { uint32_t version_minor_ = 0; public: - static constexpr size_t MaxPacketDataSize = 1024 * 64; + static constexpr size_t packet_header_size = 4; + static constexpr size_t max_packet_size = std::numeric_limits::max() - (std::numeric_limits::max() % packet_header_size); using PointerT = std::shared_ptr; @@ -188,12 +187,12 @@ class Protocol : NonCopyable { virtual size_t typeIndex(const Message* _pmsg) const = 0; // virtual const TypeStub& operator[](const size_t _idx) const = 0; - virtual void complete(const size_t _idx, ConnectionContext&, MessagePointerT<>&, MessagePointerT<>&, ErrorConditionT const&) const = 0; + virtual void complete(const size_t _idx, ConnectionContext&, SendMessagePointerT<>&, RecvMessagePointerT<>&, ErrorConditionT const&) const = 0; - virtual Serializer::PointerT createSerializer(const WriterConfiguration& _rconf) const = 0; - virtual Deserializer::PointerT createDeserializer(const ReaderConfiguration& _rconf) const = 0; + [[nodiscard]] virtual Serializer::PointerT createSerializer(const WriterConfiguration& _rconf) const = 0; + [[nodiscard]] virtual Deserializer::PointerT createDeserializer(const ReaderConfiguration& _rconf) const = 0; - virtual size_t minimumFreePacketDataSize() const = 0; + [[nodiscard]] virtual size_t minimumFreePacketDataSize() const = 0; void version(const uint32_t _major, const uint32_t _minor) { @@ -212,6 +211,4 @@ class Protocol : NonCopyable { } }; -} // namespace mprpc -} // namespace frame -} // namespace solid +} // namespace solid::frame::mprpc diff --git a/solid/frame/mprpc/mprpcprotocol_serialization_v3.hpp b/solid/frame/mprpc/mprpcprotocol_serialization_v3.hpp index 259b208d..5cc06a42 100644 --- a/solid/frame/mprpc/mprpcprotocol_serialization_v3.hpp +++ b/solid/frame/mprpc/mprpcprotocol_serialization_v3.hpp @@ -20,10 +20,7 @@ #include "solid/serialization/v3/serialization.hpp" #include "solid/system/error.hpp" -namespace solid { -namespace frame { -namespace mprpc { -namespace serialization_v3 { +namespace solid::frame::mprpc::serialization_v3 { template using SerializerTT = serialization::v3::binary::Serializer; @@ -47,13 +44,13 @@ class Serializer : public mprpc::Serializer { } private: - ptrdiff_t run(ConnectionContext& _rctx, char* _pdata, size_t _data_len, MessageHeader& _rmsghdr) override + ptrdiff_t run(ConnectionContext& _rctx, char* _pdata, size_t _data_len, MessageHeader const& _rmsghdr) override { return ser_.run( _pdata, static_cast(_data_len), [&_rmsghdr](SerializerT& _rs, ConnectionContext& _rctx) { _rs.add(_rmsghdr, _rctx, 0, "header"); }, _rctx); } - ptrdiff_t run(ConnectionContext& _rctx, char* _pdata, size_t _data_len, MessagePointerT<>& _rmsgptr, const size_t /*_msg_type_idx*/) override + ptrdiff_t run(ConnectionContext& _rctx, char* _pdata, size_t _data_len, SendMessagePointerT<>& _rmsgptr, const size_t /*_msg_type_idx*/) override { return ser_.run( _pdata, static_cast(_data_len), [&_rmsgptr](SerializerT& _rs, ConnectionContext& _rctx) { _rs.add(_rmsgptr, _rctx, 0, "message"); }, _rctx); @@ -98,7 +95,7 @@ class Deserializer : public mprpc::Deserializer { _pdata, static_cast(_data_len), [&_rmsghdr](DeserializerT& _rd, ConnectionContext& _rctx) mutable { _rd.add(_rmsghdr, _rctx, 0, "header"); }, _rctx); } - ptrdiff_t run(ConnectionContext& _rctx, const char* _pdata, size_t _data_len, MessagePointerT<>& _rmsgptr) override + ptrdiff_t run(ConnectionContext& _rctx, const char* _pdata, size_t _data_len, RecvMessagePointerT<>& _rmsgptr) override { return des_.run( _pdata, static_cast(_data_len), [&_rmsgptr](DeserializerT& _rd, ConnectionContext& _rctx) { _rd.add(_rmsgptr, _rctx, 0, "message"); }, _rctx); @@ -134,6 +131,11 @@ struct is_pair> : std::true_type { template class Protocol : public mprpc::Protocol { struct TypeData { + MessageCompleteFunctionT complete_fnc_; + + TypeData(const TypeData&) = default; + TypeData(TypeData&&) = default; + template TypeData(F&& _f) : complete_fnc_(std::forward(_f)) @@ -142,12 +144,10 @@ class Protocol : public mprpc::Protocol { TypeData() {} - void complete(ConnectionContext& _rctx, MessagePointerT<>& _p1, MessagePointerT<>& _p2, ErrorConditionT const& _e) const + void complete(ConnectionContext& _rctx, SendMessagePointerT<>& _p1, RecvMessagePointerT<>& _p2, ErrorConditionT const& _e) const { complete_fnc_(_rctx, _p1, _p2, _e); } - - MessageCompleteFunctionT complete_fnc_; }; using ThisT = Protocol; @@ -219,11 +219,7 @@ class Protocol : public mprpc::Protocol { auto create_lambda = [](auto& _rctx, auto& _rptr) { using PtrType = std::decay_t; using CtxType = std::decay_t; -#if defined(SOLID_MPRPC_USE_SHARED_PTR_MESSAGE) - if constexpr (solid::is_shared_ptr_v) { -#else - if constexpr (solid::is_intrusive_ptr_v) { -#endif + if constexpr (solid::is_mutable_intrusive_ptr_v) { _rptr = make_message(); if constexpr (std::is_same_v) { _rptr->header(_rctx); @@ -251,11 +247,8 @@ class Protocol : public mprpc::Protocol { auto create_lambda = [_create_fnc](auto& _rctx, auto& _rptr) { using PtrType = std::decay_t; using CtxType = std::decay_t; -#if defined(SOLID_MPRPC_USE_SHARED_PTR_MESSAGE) - if constexpr (solid::is_shared_ptr_v) { -#else - if constexpr (solid::is_intrusive_ptr_v) { -#endif + + if constexpr (solid::is_mutable_intrusive_ptr_v) { _create_fnc(_rctx, _rptr); if constexpr (std::is_same_v) { @@ -338,7 +331,7 @@ class Protocol : public mprpc::Protocol { return type_map_.index(_pmsg); } - void complete(const size_t _idx, ConnectionContext& _rctx, MessagePointerT<>& _rsent_msg_ptr, MessagePointerT<>& _rrecv_msg_ptr, ErrorConditionT const& _rerr) const override + void complete(const size_t _idx, ConnectionContext& _rctx, SendMessagePointerT<>& _rsent_msg_ptr, RecvMessagePointerT<>& _rrecv_msg_ptr, ErrorConditionT const& _rerr) const override { type_data_vec_[_idx].complete(_rctx, _rsent_msg_ptr, _rrecv_msg_ptr, _rerr); } @@ -361,7 +354,7 @@ class Protocol : public mprpc::Protocol { { } - size_t minimumFreePacketDataSize() const override + [[nodiscard]] size_t minimumFreePacketDataSize() const override { return 16; } @@ -384,7 +377,4 @@ auto create_protocol(MetadataFactory&& _metadata_factory, InitFunction _init_fnc return std::make_shared(_metadata_factory, _init_fnc); } -} // namespace serialization_v3 -} // namespace mprpc -} // namespace frame -} // namespace solid +} // namespace solid::frame::mprpc::serialization_v3 diff --git a/solid/frame/mprpc/mprpcrelayengine.hpp b/solid/frame/mprpc/mprpcrelayengine.hpp index d7a7c59e..22310979 100644 --- a/solid/frame/mprpc/mprpcrelayengine.hpp +++ b/solid/frame/mprpc/mprpcrelayengine.hpp @@ -14,10 +14,7 @@ #include "solid/system/error.hpp" #include "solid/system/pimpl.hpp" -namespace solid { -namespace frame { -namespace mprpc { -namespace relay { +namespace solid::frame::mprpc::relay { struct ConnectionStubBase { ActorIdT id_; @@ -98,7 +95,7 @@ class EngineCore : public RelayEngine { doExecute(f); } - ConnectionPrintStub plot(const ConnectionStubBase& _rcon) const + [[nodiscard]] ConnectionPrintStub plot(const ConnectionStubBase& _rcon) const { return ConnectionPrintStub(*this, _rcon); } @@ -108,7 +105,7 @@ class EngineCore : public RelayEngine { virtual size_t registerConnection(Proxy& _proxy, const uint32_t _group_id, const uint16_t _replica_id) = 0; private: - using ExecuteFunctionT = solid_function_t(void(Proxy&)); + using ExecuteFunctionT = SmallFunctionT; void doExecute(ExecuteFunctionT& _rfnc); @@ -158,7 +155,4 @@ class EngineCore : public RelayEngine { void doRegisterConnectionId(const ConnectionContext& _rconctx, const size_t _idx); }; -} // namespace relay -} // namespace mprpc -} // namespace frame -} // namespace solid +} // namespace solid::frame::mprpc::relay diff --git a/solid/frame/mprpc/mprpcservice.hpp b/solid/frame/mprpc/mprpcservice.hpp index 4b2e8155..7790fc47 100644 --- a/solid/frame/mprpc/mprpcservice.hpp +++ b/solid/frame/mprpc/mprpcservice.hpp @@ -9,7 +9,10 @@ // #pragma once +#include +#include #include +#include #include "solid/system/exception.hpp" #include "solid/system/statistic.hpp" @@ -43,7 +46,7 @@ class SocketStub; } // namespace openssl constexpr size_t event_small_size = 32; -using EventT = Event; +using EventT = Event; extern const Event<> pool_event_connect; extern const Event<> pool_event_disconnect; @@ -98,6 +101,7 @@ struct ServiceStatistic : solid::Statistic { std::atomic connection_send_posted_; std::atomic max_fetch_size_; std::atomic min_fetch_size_; + std::atomic_uint64_t max_optimize_duration_us_{0}; void fetchCount(const uint64_t _count, const bool _more) { @@ -164,6 +168,11 @@ struct ServiceStatistic : solid::Statistic { #endif } + void optimizeDuration(std::chrono::microseconds _us) + { + solid_statistic_max(max_optimize_duration_us_, static_cast(_us.count())); + } + ServiceStatistic(); std::ostream& print(std::ostream& _ros) const override; }; @@ -190,7 +199,7 @@ class RecipientUrl final { return false; } - bool hasURLNonEmpty() const + [[nodiscard]] bool hasURLNonEmpty() const { if (url_var_opt_.has_value()) { if (auto* psv = std::get_if(&url_var_opt_.value())) { @@ -200,7 +209,7 @@ class RecipientUrl final { return false; } - std::string_view url() const + [[nodiscard]] std::string_view url() const { if (url_var_opt_.has_value()) { if (auto* psv = std::get_if(&url_var_opt_.value())) { @@ -326,107 +335,107 @@ class Service : public frame::Service { const size_t _persistent_connection_count = 1); // send message using recipient name -------------------------------------- - template + template ErrorConditionT sendMessage( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - const MessageFlagsT& _flags = 0); + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + const MessageFlagsT& _flags = 0); - template + template ErrorConditionT sendMessage( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - RecipientId& _rrecipient_id, - const MessageFlagsT& _flags = 0); + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + RecipientId& _rrecipient_id, + const MessageFlagsT& _flags = 0); - template + template ErrorConditionT sendMessage( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - RecipientId& _rrecipient_id, - MessageId& _rmsg_id, - const MessageFlagsT& _flags = 0); + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + RecipientId& _rrecipient_id, + MessageId& _rmsg_id, + const MessageFlagsT& _flags = 0); // send message using connection uid ------------------------------------- - template + template ErrorConditionT sendMessage( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - MessageId& _rmsg_id, - const MessageFlagsT& _flags = 0); + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + MessageId& _rmsg_id, + const MessageFlagsT& _flags = 0); // send request using recipient name -------------------------------------- - template + template ErrorConditionT sendRequest( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - Fnc _complete_fnc, - const MessageFlagsT& _flags = 0); + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + Fnc _complete_fnc, + const MessageFlagsT& _flags = 0); - template + template ErrorConditionT sendRequest( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - Fnc _complete_fnc, - RecipientId& _rrecipient_id, - const MessageFlagsT& _flags = 0); + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + Fnc _complete_fnc, + RecipientId& _rrecipient_id, + const MessageFlagsT& _flags = 0); - template + template ErrorConditionT sendRequest( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - Fnc _complete_fnc, - RecipientId& _rrecipient_id, - MessageId& _rmsguid, - const MessageFlagsT& _flags = 0); + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + Fnc _complete_fnc, + RecipientId& _rrecipient_id, + MessageId& _rmsguid, + const MessageFlagsT& _flags = 0); // send message using connection uid ------------------------------------- - template + template ErrorConditionT sendResponse( - RecipientId const& _rrecipient_id, - MessagePointerT const& _rmsgptr, - const MessageFlagsT& _flags = 0); + RecipientId const& _rrecipient_id, + MsgPtr&& _rmsgptr, + const MessageFlagsT& _flags = 0); - template + template ErrorConditionT sendResponse( - RecipientId const& _rrecipient_id, - MessagePointerT const& _rmsgptr, - MessageId& _rmsg_id, - const MessageFlagsT& _flags = 0); + RecipientId const& _rrecipient_id, + MsgPtr&& _rmsgptr, + MessageId& _rmsg_id, + const MessageFlagsT& _flags = 0); // send message with complete using recipient name ------------------------ - template + template ErrorConditionT sendMessage( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - Fnc _complete_fnc, - const MessageFlagsT& _flags); + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + Fnc _complete_fnc, + const MessageFlagsT& _flags); - template + template ErrorConditionT sendMessage( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - Fnc _complete_fnc, - RecipientId& _rrecipient_id, - const MessageFlagsT& _flags); + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + Fnc _complete_fnc, + RecipientId& _rrecipient_id, + const MessageFlagsT& _flags); - template + template ErrorConditionT sendMessage( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - Fnc _complete_fnc, - RecipientId& _rrecipient_id, - MessageId& _rmsguid, - const MessageFlagsT& _flags); + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + Fnc _complete_fnc, + RecipientId& _rrecipient_id, + MessageId& _rmsguid, + const MessageFlagsT& _flags); // send message using ConnectionContext ---------------------------------- - template + template ErrorConditionT sendResponse( - ConnectionContext& _rctx, - MessagePointerT const& _rmsgptr, - const MessageFlagsT& _flags = 0); + ConnectionContext& _rctx, + MsgPtr&& _rmsgptr, + const MessageFlagsT& _flags = 0); //------------------------------------------------------------------------- ErrorConditionT sendRelay(const ActorIdT& _rconid, RelayData&& _urelmsg); ErrorConditionT sendRelayCancel(RelayData&& _urelmsg); @@ -560,7 +569,7 @@ class Service : public frame::Service { friend class Connection; friend class ClientConnection; friend class openssl::SocketStub; - friend struct ConnectionContext; + friend class ConnectionContext; Configuration const& configuration() const; ServiceStatistic& wstatistic(); @@ -616,14 +625,14 @@ class Service : public frame::Service { ErrorConditionT doSendMessage( const RecipientUrl& _recipient_url, - MessagePointerT<>& _rmsgptr, + SendMessagePointerT<>& _rmsgptr, MessageCompleteFunctionT& _rcomplete_fnc, RecipientId* _precipient_id_out, MessageId* _pmsg_id_out, const MessageFlagsT& _flags); ErrorConditionT doSendMessageUsingConnectionContext( const RecipientUrl& _recipient_url, - MessagePointerT<>& _rmsgptr, + SendMessagePointerT<>& _rmsgptr, MessageCompleteFunctionT& _rcomplete_fnc, RecipientId* _precipient_id_out, MessageId* _pmsg_id_out, @@ -650,106 +659,106 @@ class Service : public frame::Service { using ServiceT = frame::ServiceShell; //------------------------------------------------------------------------- -template +template ErrorConditionT Service::sendMessage( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - const MessageFlagsT& _flags) + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + const MessageFlagsT& _flags) { - auto msgptr(solid::static_pointer_cast(_rmsgptr)); + SendMessagePointerT<> msgptr(solid::static_pointer_cast(std::forward(std::forward(_rmsgptr)))); MessageCompleteFunctionT complete_handler; return doSendMessage(_recipient_url, msgptr, complete_handler, nullptr, nullptr, _flags); } //------------------------------------------------------------------------- -template +template ErrorConditionT Service::sendMessage( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - RecipientId& _rrecipient_id, - const MessageFlagsT& _flags) + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + RecipientId& _rrecipient_id, + const MessageFlagsT& _flags) { - auto msgptr(solid::static_pointer_cast(_rmsgptr)); + SendMessagePointerT<> msgptr(solid::static_pointer_cast(std::forward(_rmsgptr))); MessageCompleteFunctionT complete_handler; return doSendMessage(_recipient_url, msgptr, complete_handler, &_rrecipient_id, nullptr, _flags); } //------------------------------------------------------------------------- -template +template ErrorConditionT Service::sendMessage( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - RecipientId& _rrecipient_id, - MessageId& _rmsg_id, - const MessageFlagsT& _flags) + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + RecipientId& _rrecipient_id, + MessageId& _rmsg_id, + const MessageFlagsT& _flags) { - auto msgptr(solid::static_pointer_cast(_rmsgptr)); + SendMessagePointerT<> msgptr(solid::static_pointer_cast(std::forward(_rmsgptr))); MessageCompleteFunctionT complete_handler; return doSendMessage(_recipient_url, msgptr, complete_handler, &_rrecipient_id, &_rmsg_id, _flags); } //------------------------------------------------------------------------- -template +template ErrorConditionT Service::sendMessage( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - MessageId& _rmsg_id, - const MessageFlagsT& _flags) + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + MessageId& _rmsg_id, + const MessageFlagsT& _flags) { - auto msgptr(solid::static_pointer_cast(_rmsgptr)); + SendMessagePointerT<> msgptr(solid::static_pointer_cast(std::forward(_rmsgptr))); MessageCompleteFunctionT complete_handler; return doSendMessage(_recipient_url, msgptr, complete_handler, nullptr, &_rmsg_id, _flags); } //------------------------------------------------------------------------- // send request using recipient name -------------------------------------- -template +template ErrorConditionT Service::sendRequest( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - Fnc _complete_fnc, - const MessageFlagsT& _flags) + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + Fnc _complete_fnc, + const MessageFlagsT& _flags) { using CompleteHandlerT = CompleteHandler::send_type, typename message_complete_traits::recv_type>; - auto msgptr(solid::static_pointer_cast(_rmsgptr)); + SendMessagePointerT<> msgptr(solid::static_pointer_cast(std::forward(_rmsgptr))); CompleteHandlerT fnc(std::forward(_complete_fnc)); MessageCompleteFunctionT complete_handler(std::move(fnc)); return doSendMessage(_recipient_url, msgptr, complete_handler, nullptr, nullptr, _flags | MessageFlagsE::AwaitResponse); } //------------------------------------------------------------------------- -template +template ErrorConditionT Service::sendRequest( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - Fnc _complete_fnc, - RecipientId& _rrecipient_id, - const MessageFlagsT& _flags) + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + Fnc _complete_fnc, + RecipientId& _rrecipient_id, + const MessageFlagsT& _flags) { using CompleteHandlerT = CompleteHandler::send_type, typename message_complete_traits::recv_type>; - auto msgptr(solid::static_pointer_cast(_rmsgptr)); + SendMessagePointerT<> msgptr(solid::static_pointer_cast(std::forward(_rmsgptr))); CompleteHandlerT fnc(std::forward(_complete_fnc)); MessageCompleteFunctionT complete_handler(std::move(fnc)); return doSendMessage(_recipient_url, msgptr, complete_handler, &_rrecipient_id, nullptr, _flags | MessageFlagsE::AwaitResponse); } //------------------------------------------------------------------------- -template +template ErrorConditionT Service::sendRequest( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - Fnc _complete_fnc, - RecipientId& _rrecipient_id, - MessageId& _rmsguid, - const MessageFlagsT& _flags) + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + Fnc _complete_fnc, + RecipientId& _rrecipient_id, + MessageId& _rmsguid, + const MessageFlagsT& _flags) { using CompleteHandlerT = CompleteHandler::send_type, typename message_complete_traits::recv_type>; - auto msgptr(solid::static_pointer_cast(_rmsgptr)); + SendMessagePointerT<> msgptr(solid::static_pointer_cast(std::forward(_rmsgptr))); CompleteHandlerT fnc(std::forward(_complete_fnc)); MessageCompleteFunctionT complete_handler(std::move(fnc)); @@ -758,84 +767,84 @@ ErrorConditionT Service::sendRequest( //------------------------------------------------------------------------- // send response using recipient id --------------------------------------- -template +template ErrorConditionT Service::sendResponse( - RecipientId const& _rrecipient_id, - MessagePointerT const& _rmsgptr, - const MessageFlagsT& _flags) + RecipientId const& _rrecipient_id, + MsgPtr&& _rmsgptr, + const MessageFlagsT& _flags) { - auto msgptr(solid::static_pointer_cast(_rmsgptr)); + SendMessagePointerT<> msgptr(solid::static_pointer_cast(std::forward(_rmsgptr))); MessageCompleteFunctionT complete_handler; return doSendMessage(_rrecipient_id, msgptr, complete_handler, nullptr, nullptr, _flags | MessageFlagsE::Response); } //------------------------------------------------------------------------- -template +template ErrorConditionT Service::sendResponse( - RecipientId const& _rrecipient_id, - MessagePointerT const& _rmsgptr, - MessageId& _rmsg_id, - const MessageFlagsT& _flags) + RecipientId const& _rrecipient_id, + MsgPtr&& _rmsgptr, + MessageId& _rmsg_id, + const MessageFlagsT& _flags) { - auto msgptr(solid::static_pointer_cast(_rmsgptr)); + SendMessagePointerT<> msgptr(solid::static_pointer_cast(std::forward(_rmsgptr))); MessageCompleteFunctionT complete_handler; return doSendMessage(_rrecipient_id, msgptr, complete_handler, nullptr, &_rmsg_id, _flags | MessageFlagsE::Response); } //------------------------------------------------------------------------- // send message with complete using recipient name ------------------------ -template +template ErrorConditionT Service::sendMessage( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - Fnc _complete_fnc, - const MessageFlagsT& _flags) + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + Fnc _complete_fnc, + const MessageFlagsT& _flags) { using CompleteHandlerT = CompleteHandler::send_type, typename message_complete_traits::recv_type>; - auto msgptr(solid::static_pointer_cast(_rmsgptr)); + SendMessagePointerT<> msgptr(solid::static_pointer_cast(std::forward(_rmsgptr))); CompleteHandlerT fnc(std::forward(_complete_fnc)); MessageCompleteFunctionT complete_handler(std::move(fnc)); return doSendMessage(_recipient_url, msgptr, complete_handler, nullptr, nullptr, _flags); } //------------------------------------------------------------------------- -template +template ErrorConditionT Service::sendMessage( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - Fnc _complete_fnc, - RecipientId& _rrecipient_id, - const MessageFlagsT& _flags) + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + Fnc _complete_fnc, + RecipientId& _rrecipient_id, + const MessageFlagsT& _flags) { using CompleteHandlerT = CompleteHandler::send_type, typename message_complete_traits::recv_type>; - auto msgptr(solid::static_pointer_cast(_rmsgptr)); + SendMessagePointerT<> msgptr(solid::static_pointer_cast(std::forward(_rmsgptr))); CompleteHandlerT fnc(std::forward(_complete_fnc)); MessageCompleteFunctionT complete_handler(std::move(fnc)); return doSendMessage(_recipient_url, msgptr, complete_handler, &_rrecipient_id, nullptr, _flags); } //------------------------------------------------------------------------- -template +template ErrorConditionT Service::sendMessage( - const RecipientUrl& _recipient_url, - MessagePointerT const& _rmsgptr, - Fnc _complete_fnc, - RecipientId& _rrecipient_id, - MessageId& _rmsguid, - const MessageFlagsT& _flags) + const RecipientUrl& _recipient_url, + MsgPtr&& _rmsgptr, + Fnc _complete_fnc, + RecipientId& _rrecipient_id, + MessageId& _rmsguid, + const MessageFlagsT& _flags) { using CompleteHandlerT = CompleteHandler::send_type, typename message_complete_traits::recv_type>; - auto msgptr(solid::static_pointer_cast(_rmsgptr)); + auto msgptr(solid::static_pointer_cast(std::forward(_rmsgptr))); CompleteHandlerT fnc(std::forward(_complete_fnc)); MessageCompleteFunctionT complete_handler(std::move(fnc)); @@ -844,13 +853,13 @@ ErrorConditionT Service::sendMessage( //------------------------------------------------------------------------- // send message using ConnectionContext ---------------------------------- -template +template ErrorConditionT Service::sendResponse( - ConnectionContext& _rctx, - MessagePointerT const& _rmsgptr, - const MessageFlagsT& _flags) + ConnectionContext& _rctx, + MsgPtr&& _rmsgptr, + const MessageFlagsT& _flags) { - auto msgptr(solid::static_pointer_cast(_rmsgptr)); + SendMessagePointerT<> msgptr(solid::static_pointer_cast(std::forward(_rmsgptr))); MessageCompleteFunctionT complete_handler; return doSendMessage(_rctx, msgptr, complete_handler, nullptr, nullptr, _flags | MessageFlagsE::Response); } @@ -861,7 +870,7 @@ ErrorConditionT Service::forceCloseConnectionPool( RecipientId const& _rrecipient_id, F _f) { - auto fnc = [_f](ConnectionContext& _rctx, MessagePointerT<>& /*_rmsgptr*/, MessagePointerT<>&, ErrorConditionT const& /*_err*/) { + auto fnc = [_f](ConnectionContext& _rctx, SendMessagePointerT<>& /*_rmsgptr*/, RecvMessagePointerT<>&, ErrorConditionT const& /*_err*/) { _f(_rctx); }; @@ -874,7 +883,7 @@ ErrorConditionT Service::delayCloseConnectionPool( RecipientId const& _rrecipient_id, F _f) { - auto fnc = [_f](ConnectionContext& _rctx, MessagePointerT<>& /*_rmsgptr*/, MessagePointerT<>&, ErrorConditionT const& /*_err*/) { + auto fnc = [_f](ConnectionContext& _rctx, SendMessagePointerT<>& /*_rmsgptr*/, RecvMessagePointerT<>&, ErrorConditionT const& /*_err*/) { _f(_rctx); }; @@ -959,7 +968,7 @@ ErrorConditionT Service::connectionNotifyRecvSomeRawData( RecipientId const& _rrecipient_id, CompleteFnc _complete_fnc) { - ConnectionRecvRawDataCompleteFunctionT complete_fnc(std::move(_complete_fnc)); + ConnectionRecvRawDataCompleteFunctionT complete_fnc(std::move(_complete_fnc), AcceptBigT{}); return doConnectionNotifyRecvRawData(_rrecipient_id, std::move(complete_fnc)); } //------------------------------------------------------------------------- diff --git a/solid/frame/mprpc/mprpcsocketstub.hpp b/solid/frame/mprpc/mprpcsocketstub.hpp index 4b3df0b0..367cf5d2 100644 --- a/solid/frame/mprpc/mprpcsocketstub.hpp +++ b/solid/frame/mprpc/mprpcsocketstub.hpp @@ -19,7 +19,7 @@ namespace solid { namespace frame { namespace mprpc { -struct ConnectionContext; +class ConnectionContext; class SocketStub { public: @@ -73,7 +73,7 @@ class SocketStub { virtual bool hasPendingSend() const = 0; virtual bool sendAll( - frame::aio::ReactorContext& _rctx, OnSendF _pf, char* _buf, size_t _bufcp) + frame::aio::ReactorContext& _rctx, OnSendF _pf, char const* _buf, size_t _bufcp) = 0; virtual void prepareSocket( diff --git a/solid/frame/mprpc/mprpcsocketstub_openssl.hpp b/solid/frame/mprpc/mprpcsocketstub_openssl.hpp index d0dcf1e4..1940ac50 100644 --- a/solid/frame/mprpc/mprpcsocketstub_openssl.hpp +++ b/solid/frame/mprpc/mprpcsocketstub_openssl.hpp @@ -28,18 +28,15 @@ #include "solid/frame/mprpc/mprpcservice.hpp" -namespace solid { -namespace frame { -namespace mprpc { -namespace openssl { +namespace solid::frame::mprpc::openssl { using ContextT = frame::aio::openssl::Context; using StreamSocketT = frame::aio::Stream; -using ConnectionPrepareServerFunctionT = solid_function_t(unsigned long(frame::aio::ReactorContext&, ConnectionContext&, StreamSocketT&, ErrorConditionT&)); -using ConnectionPrepareClientFunctionT = solid_function_t(unsigned long(frame::aio::ReactorContext&, ConnectionContext&, StreamSocketT&, ErrorConditionT&)); -using ConnectionServerVerifyFunctionT = solid_function_t(bool(frame::aio::ReactorContext&, ConnectionContext&, StreamSocketT&, bool, frame::aio::openssl::VerifyContext&)); -using ConnectionClientVerifyFunctionT = solid_function_t(bool(frame::aio::ReactorContext&, ConnectionContext&, StreamSocketT&, bool, frame::aio::openssl::VerifyContext&)); +using ConnectionPrepareServerFunctionT = Function; +using ConnectionPrepareClientFunctionT = Function; +using ConnectionServerVerifyFunctionT = Function; +using ConnectionClientVerifyFunctionT = Function; struct ClientConfiguration { ClientConfiguration() @@ -113,8 +110,6 @@ class SocketStub final : public mprpc::SocketStub { } lambda(_pf, _revent); - // TODO: find solution for costly event copy - return sock.postSendAll(_rctx, _pbuf, _bufcp, lambda); } @@ -144,8 +139,6 @@ class SocketStub final : public mprpc::SocketStub { } lambda(_pf, _revent); - // TODO: find solution for costly event copy - return sock.postRecvSome(_rctx, _pbuf, _bufcp, lambda); } @@ -172,7 +165,7 @@ class SocketStub final : public mprpc::SocketStub { } bool sendAll( - frame::aio::ReactorContext& _rctx, OnSendF _pf, char* _buf, size_t _bufcp) override final + frame::aio::ReactorContext& _rctx, OnSendF _pf, char const* _buf, size_t _bufcp) override final { return sock.sendAll(_rctx, _buf, _bufcp, _pf); } @@ -244,8 +237,11 @@ class SocketStub final : public mprpc::SocketStub { inline SocketStubPtrT create_client_socket(mprpc::Configuration const& _rcfg, frame::aio::ActorProxy const& _rproxy, char* _emplace_buf) { - - if (sizeof(SocketStub) > static_cast(ConnectionValues::SocketEmplacementSize)) { +#ifdef SOLID_HAS_ASSERT + static_assert(sizeof(SocketStub) <= socket_emplace_size); + static_assert(alignof(SocketStub) <= socket_emplace_align); +#endif + if constexpr (sizeof(SocketStub) > socket_emplace_size and alignof(SocketStub) > socket_emplace_align) { return SocketStubPtrT(new SocketStub(_rproxy, const_cast(_rcfg.client.secure_any.cast())->context), SocketStub::delete_deleter); } else { return SocketStubPtrT(new (_emplace_buf) SocketStub(_rproxy, const_cast(_rcfg.client.secure_any.cast())->context), SocketStub::emplace_deleter); @@ -254,8 +250,12 @@ inline SocketStubPtrT create_client_socket(mprpc::Configuration const& _rcfg, fr inline SocketStubPtrT create_server_socket(mprpc::Configuration const& _rcfg, frame::aio::ActorProxy const& _rproxy, SocketDevice&& _usd, char* _emplace_buf) { +#ifdef SOLID_HAS_ASSERT + static_assert(sizeof(SocketStub) <= socket_emplace_size); + static_assert(alignof(SocketStub) <= socket_emplace_align); +#endif - if (sizeof(SocketStub) > static_cast(ConnectionValues::SocketEmplacementSize)) { + if constexpr (sizeof(SocketStub) > socket_emplace_size and alignof(SocketStub) > socket_emplace_align) { return SocketStubPtrT(new SocketStub(_rproxy, std::move(_usd), const_cast(_rcfg.server.secure_any.cast())->context), SocketStub::delete_deleter); } else { return SocketStubPtrT(new (_emplace_buf) SocketStub(_rproxy, std::move(_usd), const_cast(_rcfg.server.secure_any.cast())->context), SocketStub::emplace_deleter); @@ -321,7 +321,7 @@ inline void setup_client( { if (_rcfg.client.secure_any.empty()) { - _rcfg.client.secure_any = make_any(); + _rcfg.client.secure_any = ClientConfiguration{}; } _rcfg.client.connection_create_socket_fnc = &create_client_socket; @@ -347,7 +347,7 @@ inline void setup_server( { if (_rcfg.server.secure_any.empty()) { - _rcfg.server.secure_any = make_any(); + _rcfg.server.secure_any = ServerConfiguration{}; } _rcfg.server.connection_create_socket_fnc = &create_server_socket; @@ -362,7 +362,4 @@ inline void setup_server( rsecure_cfg.connection_verify_fnc = std::move(_verify_fnc); } -} // namespace openssl -} // namespace mprpc -} // namespace frame -} // namespace solid +} // namespace solid::frame::mprpc::openssl diff --git a/solid/frame/mprpc/mprpcsocketstub_plain.hpp b/solid/frame/mprpc/mprpcsocketstub_plain.hpp index 683ff256..9c890bc6 100644 --- a/solid/frame/mprpc/mprpcsocketstub_plain.hpp +++ b/solid/frame/mprpc/mprpcsocketstub_plain.hpp @@ -10,6 +10,7 @@ #pragma once +#include "solid/frame/mprpc/mprpcconfiguration.hpp" #include "solid/system/socketdevice.hpp" #include "solid/utility/event.hpp" @@ -18,10 +19,7 @@ #include "solid/frame/aio/aiostream.hpp" #include "solid/frame/mprpc/mprpcsocketstub.hpp" -namespace solid { -namespace frame { -namespace mprpc { -namespace plain { +namespace solid::frame::mprpc::plain { class SocketStub final : public mprpc::SocketStub { public: @@ -69,8 +67,6 @@ class SocketStub final : public mprpc::SocketStub { } lambda(_pf, _revent); - // TODO: find solution for costly event copy - return sock.postSendAll(_rctx, _pbuf, _bufcp, lambda); } @@ -100,8 +96,6 @@ class SocketStub final : public mprpc::SocketStub { } lambda(_pf, _revent); - // TODO: find solution for costly event copy - return sock.postRecvSome(_rctx, _pbuf, _bufcp, lambda); } @@ -128,7 +122,7 @@ class SocketStub final : public mprpc::SocketStub { } bool sendAll( - frame::aio::ReactorContext& _rctx, OnSendF _pf, char* _buf, size_t _bufcp) override final + frame::aio::ReactorContext& _rctx, OnSendF _pf, char const* _buf, size_t _bufcp) override final { return sock.sendAll(_rctx, _buf, _bufcp, _pf); } @@ -151,7 +145,11 @@ class SocketStub final : public mprpc::SocketStub { inline SocketStubPtrT create_client_socket(Configuration const& /*_rcfg*/, frame::aio::ActorProxy const& _rproxy, char* _emplace_buf) { - if (sizeof(SocketStub) > static_cast(ConnectionValues::SocketEmplacementSize)) { +#ifdef SOLID_HAS_ASSERT + static_assert(sizeof(SocketStub) <= socket_emplace_size); + static_assert(alignof(SocketStub) <= socket_emplace_align); +#endif + if constexpr (sizeof(SocketStub) > socket_emplace_size and alignof(SocketStub) > socket_emplace_align) { return SocketStubPtrT(new SocketStub(_rproxy), SocketStub::delete_deleter); } else { return SocketStubPtrT(new (_emplace_buf) SocketStub(_rproxy), SocketStub::emplace_deleter); @@ -160,15 +158,15 @@ inline SocketStubPtrT create_client_socket(Configuration const& /*_rcfg*/, frame inline SocketStubPtrT create_server_socket(Configuration const& /*_rcfg*/, frame::aio::ActorProxy const& _rproxy, SocketDevice&& _usd, char* _emplace_buf) { - - if (sizeof(SocketStub) > static_cast(ConnectionValues::SocketEmplacementSize)) { +#ifdef SOLID_HAS_ASSERT + static_assert(sizeof(SocketStub) <= socket_emplace_size); + static_assert(alignof(SocketStub) <= socket_emplace_align); +#endif + if constexpr (sizeof(SocketStub) > socket_emplace_size and alignof(SocketStub) > socket_emplace_align) { return SocketStubPtrT(new SocketStub(_rproxy, std::move(_usd)), SocketStub::delete_deleter); } else { return SocketStubPtrT(new (_emplace_buf) SocketStub(_rproxy, std::move(_usd)), SocketStub::emplace_deleter); } } -} // namespace plain -} // namespace mprpc -} // namespace frame -} // namespace solid +} // namespace solid::frame::mprpc::plain diff --git a/solid/frame/mprpc/src/mprpcconfiguration.cpp b/solid/frame/mprpc/src/mprpcconfiguration.cpp index a3a30d38..c1ad6f6f 100644 --- a/solid/frame/mprpc/src/mprpcconfiguration.cpp +++ b/solid/frame/mprpc/src/mprpcconfiguration.cpp @@ -40,14 +40,53 @@ std::ostream& operator<<(std::ostream& _ros, const RelayDataFlagsT& _flags) } namespace { -SharedBuffer default_allocate_recv_buffer(const uint32_t _cp) +constexpr size_t send_buffer_capacity = Protocol::max_packet_size; +constexpr size_t recv_buffer_capacity = (send_buffer_capacity * 2) + 64; + +struct BufferPoolConfiguration { + using IndexT = uint32_t; + + static constexpr IndexT capacity_count = 2; + + static constexpr IndexT dispatch(size_t const _requested_capacity) + { + if (_requested_capacity == send_buffer_capacity) { + return 0; + } else { + assert(_requested_capacity == recv_buffer_capacity); + return 1; + } + } + + static constexpr size_t capacity(IndexT const _index) + { + if (_index == 0) { + return send_buffer_capacity; + } + assert(_index == 1); + return recv_buffer_capacity; + } + + static constexpr size_t count(IndexT const) + { + return 16 * 1024; // same for any buffer + } +}; + +using BufferPoolT = BufferPool; + +MutableSharedBuffer default_allocate_recv_buffer(const uint32_t _cp) { - return BufferManager::make(_cp); + auto buf = BufferPoolT::create(_cp); + assert(buf.capacity() == _cp); + return buf; } -SharedBuffer default_allocate_send_buffer(const uint32_t _cp) +MutableSharedBuffer default_allocate_send_buffer(const uint32_t _cp) { - return make_shared_buffer(_cp); + auto buf = BufferPoolT::create(_cp); + assert(buf.capacity() == _cp); + return buf; } // void empty_reset_serializer_limits(ConnectionContext &, serialization::binary::Limits&){} @@ -188,11 +227,6 @@ bool RelayEngine::notifyConnection(Manager& _rm, const ActorIdT& _rrelay_uid, co //----------------------------------------------------------------------------- void Configuration::init() { - connection_recv_buffer_start_capacity_kb = 16; - connection_send_buffer_start_capacity_kb = 16; - - connection_recv_buffer_max_capacity_kb = connection_send_buffer_max_capacity_kb = 64; - connection_recv_buffer_allocate_fnc = &default_allocate_recv_buffer; connection_send_buffer_allocate_fnc = &default_allocate_send_buffer; @@ -300,22 +334,6 @@ void Configuration::prepare() pool_max_pending_connection_count = 1; } - if (connection_recv_buffer_max_capacity_kb > 64) { - connection_recv_buffer_max_capacity_kb = 64; - } - - if (connection_send_buffer_max_capacity_kb > 64) { - connection_send_buffer_max_capacity_kb = 64; - } - - if (connection_recv_buffer_start_capacity_kb > connection_recv_buffer_max_capacity_kb) { - connection_recv_buffer_start_capacity_kb = connection_recv_buffer_max_capacity_kb; - } - - if (connection_send_buffer_start_capacity_kb > connection_send_buffer_max_capacity_kb) { - connection_send_buffer_start_capacity_kb = connection_send_buffer_max_capacity_kb; - } - if (!server.hasSecureConfiguration()) { server.connection_start_secure = false; } @@ -366,14 +384,14 @@ void Configuration::createListenerDevice(SocketDevice& _rsd) const } //----------------------------------------------------------------------------- -SharedBuffer Configuration::allocateRecvBuffer() const +MutableSharedBuffer Configuration::allocateRecvBuffer() const { - return connection_recv_buffer_allocate_fnc(connection_recv_buffer_start_capacity_kb * 1024); + return connection_recv_buffer_allocate_fnc(recv_buffer_capacity); } //----------------------------------------------------------------------------- -SharedBuffer Configuration::allocateSendBuffer() const +MutableSharedBuffer Configuration::allocateSendBuffer() const { - return connection_send_buffer_allocate_fnc(connection_send_buffer_start_capacity_kb * 1024); + return connection_send_buffer_allocate_fnc(send_buffer_capacity); } //----------------------------------------------------------------------------- } // namespace mprpc diff --git a/solid/frame/mprpc/src/mprpcconnection.cpp b/solid/frame/mprpc/src/mprpcconnection.cpp index ae41df16..5f7ab8c2 100644 --- a/solid/frame/mprpc/src/mprpcconnection.cpp +++ b/solid/frame/mprpc/src/mprpcconnection.cpp @@ -8,17 +8,21 @@ // See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt. // #include "mprpcconnection.hpp" +#include "mprpcutility.hpp" #include "solid/frame/aio/aioreactorcontext.hpp" #include "solid/frame/manager.hpp" #include "solid/frame/mprpc/mprpcerror.hpp" +#include "solid/frame/mprpc/mprpcmessage.hpp" #include "solid/frame/mprpc/mprpcservice.hpp" #include "solid/utility/event.hpp" +#include +#include #include +#include #include +#include -namespace solid { -namespace frame { -namespace mprpc { +namespace solid::frame::mprpc { namespace { const LoggerT logger("solid::frame::mprpc::connection"); @@ -236,21 +240,14 @@ struct RecvRaw { //----------------------------------------------------------------------------- inline void Connection::doOptimizeRecvBuffer() { - const size_t remaining_size = recv_buf_.size() - cons_buf_off_; - if (remaining_size <= cons_buf_off_) { - memcpy(recv_buf_.data(), recv_buf_.data() + cons_buf_off_, remaining_size); - cons_buf_off_ = 0; - recv_buf_.resize(remaining_size); + if (recv_buf_.cempty()) [[likely]] { + recv_buf_.optimize(); + } else if ((recv_buf_.csize() + recv_buf_.msize()) < Protocol::max_packet_size) { + // not enough space in the recv_buf for a packet. + // solid_log(logger, Warning, this << " optimizing - " << recv_buf_.csize() << " " << recv_buf_.msize()); + recv_buf_.optimize(); } -} -//----------------------------------------------------------------------------- -inline void Connection::doOptimizeRecvBufferForced() -{ - const size_t remaining_size = recv_buf_.size() - cons_buf_off_; - - memmove(recv_buf_.data(), recv_buf_.data() + cons_buf_off_, remaining_size); - cons_buf_off_ = 0; - recv_buf_.resize(remaining_size); + assert(recv_buf_.msize()); } //----------------------------------------------------------------------------- Connection::Connection( @@ -301,11 +298,11 @@ void Connection::doPrepare(frame::aio::ReactorContext& _rctx) { Configuration const& config = service(_rctx).configuration(); - recv_buf_ = service(_rctx).configuration().allocateRecvBuffer(); - send_buf_ = service(_rctx).configuration().allocateSendBuffer(); + recv_buf_ = config.allocateRecvBuffer(); + send_buf_ = config.allocateSendBuffer(); recv_buf_count_ = 1; - msg_reader_.prepare(service(_rctx).configuration().reader); - msg_writer_.prepare(service(_rctx).configuration().writer); + msg_reader_.prepare(config.reader); + msg_writer_.prepare(config.writer); const auto crt_time = _rctx.steadyTime(); recv_keepalive_boundary_ = crt_time + config.server.connection_inactivity_keepalive_interval; } @@ -440,7 +437,7 @@ void Connection::doStop(frame::aio::ReactorContext& _rctx, const ErrorConditionT // no event get posted } else if (has_no_message) { // try handle the returned message if any - if (msg_bundle.message_ptr || !solid_function_empty(msg_bundle.complete_fnc)) { + if (msg_bundle.message_ptr || msg_bundle.complete_fnc) { doCompleteMessage(_rctx, pool_msg_id, msg_bundle, error_message_connection); } solid_log(logger, Info, this << ' ' << this->id() << " wait " << wait_duration.count()); @@ -509,7 +506,7 @@ void Connection::doContinueStopping( postStop(_rctx, std::move(lambda)); // no event get posted } else { - if (msg_bundle.message_ptr || !solid_function_empty(msg_bundle.complete_fnc)) { + if (msg_bundle.message_ptr || msg_bundle.complete_fnc) { doCompleteMessage(_rctx, pool_msg_id, msg_bundle, error_message_connection); } if (wait_duration != std::chrono::milliseconds(0)) { @@ -635,7 +632,7 @@ void Connection::onStopped( service(_rctx).connectionStop(conctx); - if (_rmsg_bundle.message_ptr || !solid_function_empty(_rmsg_bundle.complete_fnc)) { + if (_rmsg_bundle.message_ptr || _rmsg_bundle.complete_fnc) { doCompleteMessage(_rctx, _rpool_msg_id, _rmsg_bundle, error_message_connection); } @@ -815,7 +812,7 @@ void Connection::doHandleEventEnterActive(frame::aio::ReactorContext& _rctx, Eve if (!isStopping()) { // start receiving messages - this->postRecvSome(_rctx, recv_buf_.data(), recv_buf_.capacity()); + this->postRecvSome(_rctx, recv_buf_.mdata(), recv_buf_.msize()); if (rconfig.hasConnectionTimeoutRecv()) { timeout_recv_ = _rctx.nanoTime() + rconfig.connection_timeout_recv; @@ -877,7 +874,7 @@ void Connection::doHandleEventEnterPassive(frame::aio::ReactorContext& _rctx, Ev }); // start receiving messages - this->postRecvSome(_rctx, recv_buf_.data(), recv_buf_.capacity()); + this->postRecvSome(_rctx, recv_buf_.mdata(), recv_buf_.msize()); if (isServer() && config.server.hasConnectionTimeoutActive()) { timeout_active_ = _rctx.nanoTime() + config.server.connection_timeout_active; @@ -941,15 +938,15 @@ template return; } - if (!solid_function_empty(config.client.connection_on_secure_handshake_fnc)) { + if (config.client.connection_on_secure_handshake_fnc) { config.client.connection_on_secure_handshake_fnc(conctx); } if (!config.client.connection_start_secure) { solid_log(logger, Verbose, &rthis << ""); // we need the connection_on_secure_connect_fnc for advancing. - if (solid_function_empty(config.client.connection_on_secure_handshake_fnc)) { - rthis.doStop(_rctx, error_connection_invalid_state); // TODO: add new error + if (not config.client.connection_on_secure_handshake_fnc) { + rthis.doStop(_rctx, error_connection_invalid_state); } } else { rthis.flags_.set(FlagsE::Secure); @@ -994,14 +991,14 @@ template return; } - if (!solid_function_empty(config.server.connection_on_secure_handshake_fnc)) { + if (config.server.connection_on_secure_handshake_fnc) { config.server.connection_on_secure_handshake_fnc(conctx); } if (!config.server.connection_start_secure) { solid_log(logger, Verbose, &rthis << ""); // we need the connection_on_secure_accept_fnc for advancing. - if (solid_function_empty(config.server.connection_on_secure_handshake_fnc)) { + if (not config.server.connection_on_secure_handshake_fnc) { rthis.doStop(_rctx, error_connection_invalid_state); // TODO: add new error } } else { @@ -1047,17 +1044,13 @@ void Connection::doHandleEventSendRaw(frame::aio::ReactorContext& _rctx, EventBa solid_log(logger, Info, this << " datasize = " << pdata->data.size()); - size_t tocopy = send_buf_.capacity(); + size_t const tocopy = std::min(send_buf_.msize(), pdata->data.size()); - if (tocopy > pdata->data.size()) { - tocopy = pdata->data.size(); - } - - memcpy(send_buf_.data(), pdata->data.data(), tocopy); + memcpy(send_buf_.mdata(), pdata->data.data(), tocopy); if (tocopy != 0u) { pdata->offset = tocopy; - if (this->postSendAll(_rctx, send_buf_.data(), tocopy, _revent)) { + if (this->postSendAll(_rctx, send_buf_.mdata(), tocopy, _revent)) { pdata->complete_fnc(conctx, _rctx.error()); } } else { @@ -1073,39 +1066,34 @@ void Connection::doHandleEventRecvRaw(frame::aio::ReactorContext& _rctx, EventBa { RecvRaw* pdata = _revent.cast(); ConnectionContext conctx(_rctx, service(_rctx), *this); - size_t used_size = 0; + size_t consume_size = 0; solid_assert_log(pdata, logger); solid_log(logger, Info, this); if (this->isRawState() && pdata != nullptr) { - if (recv_buf_.size() == cons_buf_off_) { - if (this->postRecvSome(_rctx, recv_buf_.data(), recv_buf_.capacity(), _revent)) { + if (recv_buf_.csize() == 0U) { + if (this->postRecvSome(_rctx, recv_buf_.mdata(), recv_buf_.msize(), _revent)) { - pdata->complete_fnc(conctx, nullptr, used_size, _rctx.error()); + pdata->complete_fnc(conctx, nullptr, consume_size, _rctx.error()); } } else { - used_size = recv_buf_.size() - cons_buf_off_; + consume_size = recv_buf_.csize(); - pdata->complete_fnc(conctx, recv_buf_.data() + cons_buf_off_, used_size, _rctx.error()); + pdata->complete_fnc(conctx, recv_buf_.cdata(), consume_size, _rctx.error()); - if (used_size > (recv_buf_.size() - cons_buf_off_)) { - used_size = (recv_buf_.size() - cons_buf_off_); - } + consume_size = std::min(consume_size, recv_buf_.csize()); - cons_buf_off_ += used_size; + recv_buf_.consume(consume_size); - if (cons_buf_off_ == recv_buf_.size()) { - cons_buf_off_ = 0; - recv_buf_.resize(0); - } else { - solid_assert_log(cons_buf_off_ < recv_buf_.size(), logger); + if (recv_buf_.cempty()) { + recv_buf_.optimize(); } } } else if (pdata != nullptr) { - pdata->complete_fnc(conctx, nullptr, used_size, error_connection_invalid_state); + pdata->complete_fnc(conctx, nullptr, consume_size, error_connection_invalid_state); } } //----------------------------------------------------------------------------- @@ -1198,17 +1186,13 @@ template if (!_rctx.error()) { - size_t tocopy = pdata->data.size() - pdata->offset; + size_t const tocopy = std::min(pdata->data.size() - pdata->offset, rthis.send_buf_.msize()); - if (tocopy > rthis.send_buf_.capacity()) { - tocopy = rthis.send_buf_.capacity(); - } - - memcpy(rthis.send_buf_.data(), pdata->data.data() + pdata->offset, tocopy); + memcpy(rthis.send_buf_.mdata(), pdata->data.data() + pdata->offset, tocopy); if (tocopy != 0u) { pdata->offset += tocopy; - if (rthis.postSendAll(_rctx, rthis.send_buf_.data(), tocopy, _revent)) { + if (rthis.postSendAll(_rctx, rthis.send_buf_.mdata(), tocopy, _revent)) { pdata->complete_fnc(conctx, _rctx.error()); } } else { @@ -1232,17 +1216,16 @@ template if (pdata != nullptr) { - size_t used_size = _sz; + size_t consume_size = _sz; - pdata->complete_fnc(conctx, rthis.recv_buf_.data(), used_size, _rctx.error()); + pdata->complete_fnc(conctx, rthis.recv_buf_.cdata(), consume_size, _rctx.error()); - if (used_size > _sz) { - used_size = _sz; - } + consume_size = std::min(consume_size, _sz); - if (used_size < _sz) { - rthis.recv_buf_.resize(_sz); - rthis.cons_buf_off_ = used_size; + if (consume_size < _sz) { + rthis.recv_buf_.append(_sz); + rthis.recv_buf_.consume(consume_size); + rthis.recv_buf_.optimize(); } } } @@ -1250,11 +1233,11 @@ template template void Connection::doResetRecvBuffer(frame::aio::ReactorContext& _rctx, const uint8_t _request_buffer_ack_count, ErrorConditionT& _rerr) { - if (_request_buffer_ack_count == 0) { - + if (_request_buffer_ack_count == 0) [[likely]] { + return; } else if (recv_buf_.useCount() > 1) { solid_log(logger, Verbose, this << " buffer used for relay - try replace it. vec_size = " << recv_buf_vec_.size() << " count = " << recv_buf_count_); - SharedBuffer new_buf; + MutableSharedBuffer new_buf; if (!recv_buf_vec_.empty()) { new_buf = std::move(recv_buf_vec_.back()); recv_buf_vec_.pop_back(); @@ -1262,15 +1245,13 @@ void Connection::doResetRecvBuffer(frame::aio::ReactorContext& _rctx, const uint new_buf = service(_rctx).configuration().allocateRecvBuffer(); } else { recv_buf_.reset(); - _rerr = error_connection_too_many_recv_buffers; - cons_buf_off_ = 0; + _rerr = error_connection_too_many_recv_buffers; + solid_log(logger, Warning, this << " used all recv buffers"); + assert(false); return; } - const size_t cnssz = recv_buf_.size() - cons_buf_off_; - - memcpy(new_buf.data(), recv_buf_.data() + cons_buf_off_, cnssz); - cons_buf_off_ = 0; - new_buf.resize(cnssz); + memcpy(new_buf.mdata(), recv_buf_.cdata(), recv_buf_.csize()); + new_buf.append(recv_buf_.csize()); recv_buf_ = std::move(new_buf); } else { // tried to relay received messages/message parts - but all failed @@ -1305,7 +1286,7 @@ struct ConnectionReceiver : MessageReaderReceiver { { } - void receiveMessage(MessagePointerT<>& _rmsg_ptr, const size_t _msg_type_id) override + void receiveMessage(RecvMessagePointerT<>& _rmsg_ptr, const size_t _msg_type_id) override { rcon_.doCompleteMessage(rctx_, _rmsg_ptr, _msg_type_id); rcon_.flags_.set(Connection::FlagsE::PollPool); @@ -1362,9 +1343,7 @@ template ConnectionContext conctx(_rctx, rthis.service(_rctx), rthis); const Configuration& rconfig = rthis.service(_rctx).configuration(); unsigned repeatcnt = 4; - char* pbuf = nullptr; - size_t bufsz = 0; - const uint32_t recvbufcp = rthis.recv_buf_.capacity(); + auto& rrecvbuf = rthis.recv_buf_; typename Ctx::ReceiverT rcvr(rthis, _rctx, rconfig.reader, rconfig.protocol(), conctx); ErrorConditionT error; @@ -1373,15 +1352,15 @@ template rthis.service(_rctx).wstatistic().connectionRecvBufferSize(_sz, rthis.recv_buf_.capacity()); if (!_rctx.error()) { - rthis.recv_buf_.append(_sz); - pbuf = rthis.recv_buf_.data() + rthis.cons_buf_off_; - bufsz = rthis.recv_buf_.size() - rthis.cons_buf_off_; + rrecvbuf.append(_sz); rcvr.request_buffer_ack_count_ = 0; - rthis.cons_buf_off_ += rthis.msg_reader_.read(pbuf, bufsz, rcvr, error); + auto const consumed_size = rthis.msg_reader_.read(rrecvbuf.cdata(), rrecvbuf.csize(), rcvr, error); + + rrecvbuf.consume(consumed_size); - solid_log(logger, Verbose, &rthis << " consumed size " << rthis.cons_buf_off_ << " of " << bufsz); + solid_log(logger, Verbose, &rthis << " consumed size " << consumed_size << " remaining " << rrecvbuf.csize()); rthis.doResetRecvBuffer(_rctx, rcvr.request_buffer_ack_count_, error); @@ -1390,26 +1369,23 @@ template rthis.doStop(_rctx, error); return; } - - if (rthis.cons_buf_off_ < bufsz) { - rthis.doOptimizeRecvBufferForced(); - } } else { solid_log(logger, Info, &rthis << ' ' << rthis.id() << " receiving " << _rctx.error().message()); rthis.flags_.set(FlagsE::StopPeer); rthis.doStop(_rctx, _rctx.error(), _rctx.systemError()); return; } + --repeatcnt; + auto t_start = std::chrono::high_resolution_clock::now(); rthis.doOptimizeRecvBuffer(); + const auto duration = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - t_start); + rthis.service(_rctx) + .wstatistic() + .optimizeDuration(duration); + solid_check(rrecvbuf.msize()); - solid_assert_log(rthis.recv_buf_, logger); - - pbuf = rthis.recv_buf_.data() + rthis.recv_buf_.size(); - - bufsz = recvbufcp - rthis.recv_buf_.size(); - // solid_log(logger, Info, &rthis<<" buffer size "<(_rctx, pbuf, bufsz, _sz)); + } while (repeatcnt != 0U && !rthis.flags_.isSet(FlagsE::PauseRecv) && rthis.recvSome(_rctx, rrecvbuf.mdata(), rrecvbuf.msize(), _sz)); if (rconfig.hasConnectionTimeoutRecv()) { rthis.timeout_recv_ = _rctx.nanoTime() + rconfig.connection_timeout_recv; @@ -1418,7 +1394,7 @@ template } if (repeatcnt == 0 && !rthis.flags_.isSet(FlagsE::PauseRecv)) { - const bool rv = rthis.postRecvSome(_rctx, pbuf, bufsz); // fully asynchronous call + const bool rv = rthis.postRecvSome(_rctx, rthis.recv_buf_.mdata(), rthis.recv_buf_.msize()); // fully asynchronous call solid_assert_log(!rv, logger); (void)rv; } @@ -1468,7 +1444,7 @@ void Connection::doSend(frame::aio::ReactorContext& _rctx) write_flags.set(MessageWriter::WriteFlagsE::ShouldSendKeepAlive); } - WriteBuffer buffer{send_buf_.data(), send_buf_.capacity()}; + WriteBuffer buffer{send_buf_.mdata(), send_buf_.msize()}; error = msg_writer_.write( buffer, write_flags, ackd_buf_count_, cancel_remote_msg_vec_, send_relay_free_count_, sender); @@ -1476,7 +1452,9 @@ void Connection::doSend(frame::aio::ReactorContext& _rctx) flags_.reset(FlagsE::Keepalive); if (!error) { - service(_rctx).wstatistic().connectionSendBufferSize(buffer.size(), send_buf_.capacity()); + + service(_rctx).wstatistic().connectionSendBufferSize(buffer.size(), send_buf_.msize()); + if (!buffer.empty() && this->sendAll(_rctx, buffer.data(), buffer.size())) { sent_something = true; if (_rctx.error()) { @@ -1491,11 +1469,10 @@ void Connection::doSend(frame::aio::ReactorContext& _rctx) solid_assert(msg_writer_.isEmpty()); repeatcnt = 0; solid_statistic_inc(service(_rctx).wstatistic().connection_send_wait_count_); - break; } else { sent_something = true; - break; } + break; } else { break; } @@ -1596,8 +1573,8 @@ template //----------------------------------------------------------------------------- template struct ConnectionSenderResponse : ConnectionSender { - MessagePointerT<>& rresponse_ptr_; - bool request_found_ = false; + RecvMessagePointerT<>& rresponse_ptr_; + bool request_found_ = false; ConnectionSenderResponse( Connection& _rcon, @@ -1605,7 +1582,7 @@ struct ConnectionSenderResponse : ConnectionSender { WriterConfiguration const& _rconfig, Protocol const& _rproto, ConnectionContext& _rconctx, - MessagePointerT<>& _rresponse_ptr) + RecvMessagePointerT<>& _rresponse_ptr) : ConnectionSender(_rcon, _rctx, _rconfig, _rproto, _rconctx) , rresponse_ptr_(_rresponse_ptr) { @@ -1615,15 +1592,20 @@ struct ConnectionSenderResponse : ConnectionSender { { this->rcon_.updateContextOnCompleteMessage(this->context(), _rmsg_bundle, _rpool_msg_id, *rresponse_ptr_); - const bool must_clear_request = !rresponse_ptr_->isResponsePart(); // do not clear the request if the response is a partial one - - if (!solid_function_empty(_rmsg_bundle.complete_fnc)) { - solid_log(logger, Info, this); - _rmsg_bundle.complete_fnc(this->context(), _rmsg_bundle.message_ptr, rresponse_ptr_, this->err_); + const bool must_clear_request = !rresponse_ptr_->isResponsePart(); // do not clear the request if the response is a partial one + SendMessagePointerT<> send_msg_ptr; + if (must_clear_request) { + send_msg_ptr = std::move(_rmsg_bundle.message_ptr); + } else { + send_msg_ptr = _rmsg_bundle.message_ptr; + } + if (_rmsg_bundle.complete_fnc) { + solid_log(logger, Info, this << " clear_request = " << must_clear_request); + _rmsg_bundle.complete_fnc(this->context(), send_msg_ptr, rresponse_ptr_, this->err_); request_found_ = true; - } else if (_rmsg_bundle.message_ptr) { - solid_log(logger, Info, this << " " << _rmsg_bundle.message_type_id); - this->rproto_.complete(_rmsg_bundle.message_type_id, this->context(), _rmsg_bundle.message_ptr, rresponse_ptr_, this->err_); + } else if (send_msg_ptr) { + solid_log(logger, Info, this << " " << _rmsg_bundle.message_type_id << " clear_request = " << must_clear_request); + this->rproto_.complete(_rmsg_bundle.message_type_id, this->context(), send_msg_ptr, rresponse_ptr_, this->err_); this->request_found_ = true; } @@ -1641,7 +1623,7 @@ void Connection::updateContextOnCompleteMessage( } template -bool Connection::doCompleteMessage(frame::aio::ReactorContext& _rctx, MessagePointerT<>& _rresponse_ptr, const size_t _response_type_id) +bool Connection::doCompleteMessage(frame::aio::ReactorContext& _rctx, RecvMessagePointerT<>& _rresponse_ptr, const size_t _response_type_id) { ConnectionContext conctx(_rctx, service(_rctx), *this); const Configuration& rconfig = service(_rctx).configuration(); @@ -1672,15 +1654,15 @@ void Connection::doCompleteMessage( ErrorConditionT const& _rerror) { - ConnectionContext conctx(_rctx, service(_rctx), *this); - const Configuration& rconfig = service(_rctx).configuration(); - const Protocol& rproto = rconfig.protocol(); - MessagePointerT<> dummy_recv_msg_ptr; + ConnectionContext conctx(_rctx, service(_rctx), *this); + const Configuration& rconfig = service(_rctx).configuration(); + const Protocol& rproto = rconfig.protocol(); + RecvMessagePointerT<> dummy_recv_msg_ptr; conctx.message_flags_ = _rmsg_bundle.message_flags; conctx.message_id_ = _rpool_msg_id; - if (!solid_function_empty(_rmsg_bundle.complete_fnc)) { + if (_rmsg_bundle.complete_fnc) { solid_log(logger, Info, this); _rmsg_bundle.complete_fnc(conctx, _rmsg_bundle.message_ptr, dummy_recv_msg_ptr, _rerror); } else { @@ -1829,7 +1811,7 @@ bool Connection::recvSome(frame::aio::ReactorContext& _rctx, char* _buf, size_t } //----------------------------------------------------------------------------- template -bool Connection::sendAll(frame::aio::ReactorContext& _rctx, char* _buf, size_t _bufcp) +bool Connection::sendAll(frame::aio::ReactorContext& _rctx, char const* _buf, size_t _bufcp) { solid_check(!isStopping()); return sock_ptr_->sendAll(_rctx, Connection::onSend, _buf, _bufcp); @@ -1855,10 +1837,7 @@ void Connection::doResumeRead(frame::aio::ReactorContext& _rctx) if (flags_.isSet(FlagsE::PauseRecv)) { flags_.reset(FlagsE::PauseRecv); - const auto pbuf = recv_buf_.data() + recv_buf_.size(); - const auto bufsz = recv_buf_.capacity() - recv_buf_.size(); - - const bool rv = postRecvSome(_rctx, pbuf, bufsz); // fully asynchronous call + const bool rv = postRecvSome(_rctx, recv_buf_.mdata(), recv_buf_.msize()); // fully asynchronous call solid_assert_log(!rv, logger); (void)rv; @@ -2183,7 +2162,7 @@ struct RelayContext { void RelayConnection::tryPollRelayEngine(frame::aio::ReactorContext& _rctx, const Configuration& _rconfig, MessageWriter& _rmsgwriter) { if (shouldPollRelayEngine()) { - auto relay_poll_push_lambda = [this, &_rconfig, &_rmsgwriter]( + auto relay_poll_push_lambda = [&_rconfig, &_rmsgwriter]( RelayData*& _rprelay_data, const MessageId& _rengine_msg_id, MessageId& _rconn_msg_id, bool& _rmore) -> bool { @@ -2304,10 +2283,9 @@ void RelayConnection::doCancelRelayed( const Configuration& rconfig = configuration(_rctx); size_t ack_buf_cnt = 0; - const auto done_lambda = [this, &ack_buf_cnt](SharedBuffer& _rbuf) { - if (_rbuf.useCount() == 1) { + const auto done_lambda = [this, &ack_buf_cnt](SharedBufferView& _rbuf) { + if (returnRecvBuffer(std::move(_rbuf))) { ++ack_buf_cnt; - returnRecvBuffer(std::move(_rbuf)); } }; @@ -2324,14 +2302,15 @@ bool RelayConnection::doReceiveRelayStart( frame::aio::ReactorContext& _rctx, MessageHeader& _rmsghdr, const char* _pbeg, - size_t _sz, + size_t const _sz, MessageId& _rrelay_id, const bool _is_last, ErrorConditionT& _rerror) { Configuration const& config = configuration(_rctx); ConnectionContext conctx{_rctx, service(_rctx), *this}; - RelayData relmsg{recvBuffer(), _pbeg, _sz /*, this->uid(_rctx)*/, _is_last}; + RelayData relmsg{recvBufferView(_pbeg, _sz), _is_last}; + assert(relmsg.buffer_.cdata() == _pbeg and relmsg.buffer_.csize() == _sz); return config.relayEngine().relayStart(uid(_rctx), relayId(), _rmsghdr, std::move(relmsg), _rrelay_id, _rerror); } @@ -2339,14 +2318,15 @@ bool RelayConnection::doReceiveRelayStart( bool RelayConnection::doReceiveRelayBody( frame::aio::ReactorContext& _rctx, const char* _pbeg, - size_t _sz, + size_t const _sz, const MessageId& _rrelay_id, const bool _is_last, ErrorConditionT& _rerror) { Configuration const& config = configuration(_rctx); ConnectionContext conctx{_rctx, service(_rctx), *this}; - RelayData relmsg{recvBuffer(), _pbeg, _sz /*, this->uid(_rctx)*/, _is_last}; + RelayData relmsg{recvBufferView(_pbeg, _sz), _is_last}; + assert(relmsg.buffer_.cdata() == _pbeg and relmsg.buffer_.csize() == _sz); return config.relayEngine().relay(relayId(), std::move(relmsg), _rrelay_id, _rerror); } @@ -2355,14 +2335,15 @@ bool RelayConnection::doReceiveRelayResponse( frame::aio::ReactorContext& _rctx, MessageHeader& _rmsghdr, const char* _pbeg, - size_t _sz, + size_t const _sz, const MessageId& _rrelay_id, const bool _is_last, ErrorConditionT& _rerror) { Configuration const& config = configuration(_rctx); ConnectionContext conctx{_rctx, service(_rctx), *this}; - RelayData relmsg{recvBuffer(), _pbeg, _sz /*, this->uid(_rctx)*/, _is_last}; + RelayData relmsg{recvBufferView(_pbeg, _sz), _is_last}; + assert(relmsg.buffer_.cdata() == _pbeg and relmsg.buffer_.csize() == _sz); return config.relayEngine().relayResponse(relayId(), _rmsghdr, std::move(relmsg), _rrelay_id, _rerror); } @@ -2388,10 +2369,12 @@ void RelayConnection::doHandleEventRelayDone(frame::aio::ReactorContext& _rctx, Configuration const& config = configuration(_rctx); size_t ack_buf_cnt = 0; - const auto done_lambda = [this, &ack_buf_cnt](SharedBuffer& _rbuf) { + const auto done_lambda = [this, &ack_buf_cnt](SharedBufferView& _rbuf) { if (_rbuf.useCount() == 1) { + solid_log(logger, Info, this << " returnRecvBuffer " << _rbuf.useCount()); + } + if (returnRecvBuffer(std::move(_rbuf))) { ++ack_buf_cnt; - returnRecvBuffer(std::move(_rbuf)); } }; const auto cancel_lambda = [this](const MessageHeader& _rmsghdr) { @@ -2436,7 +2419,7 @@ Any<>& ConnectionContext::any() return rconnection_.any(); } //----------------------------------------------------------------------------- -MessagePointerT<> ConnectionContext::fetchRequest(Message const& _rmsg) const +SendMessagePointerT<> ConnectionContext::fetchRequest(Message const& _rmsg) const { return rconnection_.fetchRequest(_rmsg); } @@ -2550,6 +2533,4 @@ void Message::header(frame::mprpc::ConnectionContext& _rctx) header_ = std::move(*_rctx.pmessage_header_); } -} // namespace mprpc -} // namespace frame -} // namespace solid +} // namespace solid::frame::mprpc diff --git a/solid/frame/mprpc/src/mprpcconnection.hpp b/solid/frame/mprpc/src/mprpcconnection.hpp index 27bbb59a..fb0fe175 100644 --- a/solid/frame/mprpc/src/mprpcconnection.hpp +++ b/solid/frame/mprpc/src/mprpcconnection.hpp @@ -15,7 +15,6 @@ #include "solid/system/flags.hpp" #include "solid/utility/any.hpp" #include "solid/utility/event.hpp" -#include "solid/utility/queue.hpp" #include "solid/frame/aio/aioactor.hpp" #include "solid/frame/aio/aiotimer.hpp" @@ -26,14 +25,11 @@ #include "mprpcmessagereader.hpp" #include "mprpcmessagewriter.hpp" -namespace solid { -namespace frame { -namespace aio { +namespace solid::frame { -namespace openssl { +namespace aio::openssl { class Context; -} // namespace openssl -} // namespace aio +} // namespace aio::openssl namespace mprpc { @@ -42,12 +38,12 @@ class Service; struct ResolveMessage { AddressVectorT addrvec; - bool empty() const + [[nodiscard]] bool empty() const { return addrvec.empty(); } - SocketAddressInet const& currentAddress() const + [[nodiscard]] SocketAddressInet const& currentAddress() const { return addrvec.back(); } @@ -61,7 +57,7 @@ struct ResolveMessage { ResolveMessage(const ResolveMessage&) = delete; - ResolveMessage(ResolveMessage&& _urm) + ResolveMessage(ResolveMessage&& _urm) noexcept : addrvec(std::move(_urm.addrvec)) { } @@ -127,7 +123,7 @@ class Connection : public frame::aio::Actor { const UniqueId& relayId() const; void relayId(const UniqueId& _relay_id); - MessagePointerT<> fetchRequest(Message const& _rmsg) const; + SendMessagePointerT<> fetchRequest(Message const& _rmsg) const; ConnectionPoolId const& poolId() const; const std::string& poolName() const; @@ -200,9 +196,9 @@ class Connection : public frame::aio::Actor { void setFlag(const FlagsE _flag); void resetFlag(const FlagsE _flag); - const SharedBuffer& recvBuffer() const; + SharedBufferView recvBufferView(const char*, size_t) const; - void returnRecvBuffer(SharedBuffer&& _buf); + bool returnRecvBuffer(SharedBufferView&& _buf); void ackBufferCountAdd(uint8_t _val); @@ -269,7 +265,7 @@ class Connection : public frame::aio::Actor { template bool recvSome(frame::aio::ReactorContext& _rctx, char* _buf, size_t _bufcp, size_t& _sz); template - bool sendAll(frame::aio::ReactorContext& _rctx, char* _buf, size_t _bufcp); + bool sendAll(frame::aio::ReactorContext& _rctx, char const* _buf, size_t _bufcp); void prepareSocket(frame::aio::ReactorContext& _rctx); const NanoTime& minTimeout() const; @@ -277,7 +273,7 @@ class Connection : public frame::aio::Actor { ErrorConditionT pollServicePoolForUpdates(frame::aio::ReactorContext& _rctx, MessageId const& _rpool_msg_id); private: - friend struct ConnectionContext; + friend class ConnectionContext; friend class RelayEngine; friend class Service; @@ -316,7 +312,6 @@ class Connection : public frame::aio::Actor { EventBase& _revent); void doOptimizeRecvBuffer(); - void doOptimizeRecvBufferForced(); void doPrepare(frame::aio::ReactorContext& _rctx); void doUnprepare(frame::aio::ReactorContext& _rctx); template @@ -326,7 +321,7 @@ class Connection : public frame::aio::Actor { ResponseStateE doCheckResponseState(frame::aio::ReactorContext& _rctx, const MessageHeader& _rmsghdr, MessageId& _rrelay_id, const bool _erase_request); template bool doCompleteMessage( - frame::aio::ReactorContext& _rctx, MessagePointerT<>& _rresponse_ptr, const size_t _response_type_id); + frame::aio::ReactorContext& _rctx, RecvMessagePointerT<>& _rresponse_ptr, const size_t _response_type_id); void doCompleteMessage( solid::frame::aio::ReactorContext& _rctx, @@ -349,7 +344,7 @@ class Connection : public frame::aio::Actor { = frame::aio::SteadyTimer; using FlagsT = solid::Flags; using RequestIdVectorT = MessageWriter::RequestIdVectorT; - using RecvBufferVectorT = std::vector; + using RecvBufferVectorT = std::vector; template friend struct ConnectionReceiver; @@ -362,15 +357,14 @@ class Connection : public frame::aio::Actor { const std::string& rpool_name_; TimerT timer_; FlagsT flags_ = 0; - size_t cons_buf_off_ = 0; uint32_t recv_keepalive_count_ = 0; std::chrono::steady_clock::time_point recv_keepalive_boundary_ = std::chrono::steady_clock::time_point::min(); uint16_t recv_buf_count_ = 0; uint8_t send_relay_free_count_; uint8_t ackd_buf_count_ = 0; - SharedBuffer recv_buf_; + RingSharedBuffer recv_buf_; RecvBufferVectorT recv_buf_vec_; - SharedBuffer send_buf_; + MutableSharedBuffer send_buf_; MessageIdVectorT pending_message_vec_; MessageReader msg_reader_; MessageWriter msg_writer_; @@ -380,15 +374,15 @@ class Connection : public frame::aio::Actor { bool poll_pool_more_ = true; bool send_posted_ = false; Any<> any_data_; - char socket_emplace_buf_[static_cast(ConnectionValues::SocketEmplacementSize)] = {}; - SocketStubPtrT sock_ptr_; - NanoTime timeout_recv_ = NanoTime::max(); // client and server - NanoTime timeout_send_soft_ = NanoTime::max(); // client and server - NanoTime timeout_send_hard_ = NanoTime::max(); // client and server - NanoTime timeout_secure_ = NanoTime::max(); // server - NanoTime timeout_active_ = NanoTime::max(); // server - NanoTime timeout_keepalive_ = NanoTime::max(); // client - UniqueId relay_id_; + alignas(socket_emplace_align) char socket_emplace_buf_[socket_emplace_size] = {}; + SocketStubPtrT sock_ptr_; + NanoTime timeout_recv_ = NanoTime::max(); // client and server + NanoTime timeout_send_soft_ = NanoTime::max(); // client and server + NanoTime timeout_send_hard_ = NanoTime::max(); // client and server + NanoTime timeout_secure_ = NanoTime::max(); // server + NanoTime timeout_active_ = NanoTime::max(); // server + NanoTime timeout_keepalive_ = NanoTime::max(); // client + UniqueId relay_id_; }; //----------------------------------------------------------------------------- @@ -602,7 +596,7 @@ inline Any<>& Connection::any() return any_data_; } //----------------------------------------------------------------------------- -inline MessagePointerT<> Connection::fetchRequest(Message const& _rmsg) const +inline SendMessagePointerT<> Connection::fetchRequest(Message const& _rmsg) const { return msg_writer_.fetchRequest(_rmsg.requestId()); } @@ -666,14 +660,18 @@ inline void Connection::resetFlag(const FlagsE _flag) flags_.reset(_flag); } //----------------------------------------------------------------------------- -inline const SharedBuffer& Connection::recvBuffer() const +inline SharedBufferView Connection::recvBufferView(const char* _pbuf, size_t const _size) const { - return recv_buf_; + return recv_buf_.view(_pbuf - recv_buf_.data(), _size); } //----------------------------------------------------------------------------- -inline void Connection::returnRecvBuffer(SharedBuffer&& _buf) +inline bool Connection::returnRecvBuffer(SharedBufferView&& _buf) { - recv_buf_vec_.emplace_back(std::move(_buf)); + if (auto buf = _buf.collapse()) { + recv_buf_vec_.emplace_back(std::move(buf)); + return true; + } + return false; } //----------------------------------------------------------------------------- inline void Connection::ackBufferCountAdd(uint8_t _val) @@ -712,5 +710,4 @@ inline ErrorConditionT Connection::pollServicePoolForUpdates(frame::aio::Reactor } //----------------------------------------------------------------------------- } // namespace mprpc -} // namespace frame -} // namespace solid +} // namespace solid::frame diff --git a/solid/frame/mprpc/src/mprpcerror.cpp b/solid/frame/mprpc/src/mprpcerror.cpp index ef9727c1..5933e16a 100644 --- a/solid/frame/mprpc/src/mprpcerror.cpp +++ b/solid/frame/mprpc/src/mprpcerror.cpp @@ -11,9 +11,7 @@ #include "solid/frame/mprpc/mprpcerror.hpp" #include -namespace solid { -namespace frame { -namespace mprpc { +namespace solid::frame::mprpc { namespace { @@ -288,6 +286,4 @@ std::string ErrorCategory::message(int _ev) const /*extern*/ const ErrorConditionT error_service_connection_not_needed(ErrorServiceConnectionNotNeededE, category); /*extern*/ const ErrorConditionT error_service_connection_pool_count(ErrorServiceConnectionPoolCountE, category); -} // namespace mprpc -} // namespace frame -} // namespace solid +} // namespace solid::frame::mprpc diff --git a/solid/frame/mprpc/src/mprpcmessagereader.cpp b/solid/frame/mprpc/src/mprpcmessagereader.cpp index eeb45639..826d4c52 100644 --- a/solid/frame/mprpc/src/mprpcmessagereader.cpp +++ b/solid/frame/mprpc/src/mprpcmessagereader.cpp @@ -13,9 +13,12 @@ #include "solid/frame/mprpc/mprpccontext.hpp" #include "solid/frame/mprpc/mprpcerror.hpp" #include "solid/frame/mprpc/mprpcmessage.hpp" +#include "solid/frame/mprpc/mprpcprotocol.hpp" #include "solid/system/exception.hpp" #include "solid/system/log.hpp" +#include + namespace solid { namespace frame { namespace mprpc { @@ -49,7 +52,7 @@ size_t MessageReader::read( while (pbufpos != pbufend) { if (state_ == StateE::ReadPacketHead) { // try read the header - if ((pbufend - pbufpos) >= static_cast(PacketHeader::size_of_header)) { + if ((pbufend - pbufpos) >= static_cast(PacketHeader::header_size)) { state_ = StateE::ReadPacketBody; } else { break; @@ -60,6 +63,7 @@ size_t MessageReader::read( // try read the data const char* tmpbufpos = packet_header.load(pbufpos, _receiver.protocol()); if (!packet_header.isOk()) { + assert(false); _rerror = error_reader_invalid_packet_header; solid_log(logger, Error, _rerror.message()); break; @@ -187,7 +191,7 @@ void MessageReader::doConsumePacket( if (!_packet_header.isCompressed()) [[likely]] { doConsumePacketLoop(pbufpos, pbufend, _receiver, _rerror); } else { - char tmpbuf[Protocol::MaxPacketDataSize]; // decompress = TODO: try not to use so much stack + char tmpbuf[Protocol::max_packet_size]; // decompress = TODO: try not to use so much stack const size_t uncompressed_size = _receiver.configuration().decompress_fnc(tmpbuf, pbufpos, pbufend - pbufpos, _rerror); if (!_rerror) { @@ -303,7 +307,7 @@ bool MessageReader::doConsumeMessageBody( if ((_cmd & static_cast(PacketHeader::CommandE::EndMessageFlag)) != 0u) { if (rmsgstub.deserializer_ptr_->empty() && rmsgstub.message_ptr_) { // done parsing the message body - MessagePointerT<> msgptr{std::move(rmsgstub.message_ptr_)}; + RecvMessagePointerT<> msgptr{std::move(rmsgstub.message_ptr_)}; cache(rmsgstub.deserializer_ptr_); solid_log(logger, Verbose, "Clear Message " << _msgidx); rmsgstub.clear(); @@ -397,7 +401,7 @@ void MessageReader::doConsumeMessageRelayStart( const bool is_message_end = (_cmd & static_cast(PacketHeader::CommandE::EndMessageFlag)) != 0; solid_log(logger, Verbose, "msgidx = " << _msgidx << " message_size = " << _message_size << " is_message_end = " << is_message_end); - // TODO: + if (_receiver.receiveRelayStart(rmsgstub.message_header_, _pbufpos, _message_size, rmsgstub.relay_id, is_message_end, _rerror)) { rmsgstub.state_ = MessageStub::StateE::RelayBody; } else { diff --git a/solid/frame/mprpc/src/mprpcmessagereader.hpp b/solid/frame/mprpc/src/mprpcmessagereader.hpp index 61fde656..60639e5c 100644 --- a/solid/frame/mprpc/src/mprpcmessagereader.hpp +++ b/solid/frame/mprpc/src/mprpcmessagereader.hpp @@ -50,10 +50,10 @@ struct MessageReaderReceiver { virtual ~MessageReaderReceiver(); - virtual void receiveMessage(MessagePointerT<>&, const size_t /*_msg_type_id*/) = 0; - virtual void receiveKeepAlive() = 0; - virtual void receiveAckCount(uint8_t _count) = 0; - virtual void receiveCancelRequest(const RequestId&) = 0; + virtual void receiveMessage(RecvMessagePointerT<>&, const size_t /*_msg_type_id*/) = 0; + virtual void receiveKeepAlive() = 0; + virtual void receiveAckCount(uint8_t _count) = 0; + virtual void receiveCancelRequest(const RequestId&) = 0; virtual bool receiveRelayStart(MessageHeader& _rmsghdr, const char* _pbeg, size_t _sz, MessageId& _rrelay_id, const bool _is_last, ErrorConditionT& _rerror); virtual bool receiveRelayBody(const char* _pbeg, size_t _sz, const MessageId& _rrelay_id, const bool _is_last, ErrorConditionT& _rerror); virtual bool receiveRelayResponse(MessageHeader& _rmsghdr, const char* _pbeg, size_t _sz, const MessageId& _rrelay_id, const bool _is_last, ErrorConditionT& _rerror); @@ -82,7 +82,7 @@ class MessageReader { RelayResponse, }; - MessagePointerT<> message_ptr_; + RecvMessagePointerT<> message_ptr_; Deserializer::PointerT deserializer_ptr_; MessageHeader message_header_; size_t packet_count_ = 0; diff --git a/solid/frame/mprpc/src/mprpcmessagewriter.cpp b/solid/frame/mprpc/src/mprpcmessagewriter.cpp index 0dd4899c..3084938e 100644 --- a/solid/frame/mprpc/src/mprpcmessagewriter.cpp +++ b/solid/frame/mprpc/src/mprpcmessagewriter.cpp @@ -16,9 +16,7 @@ #include "solid/system/cassert.hpp" #include "solid/system/log.hpp" -namespace solid { -namespace frame { -namespace mprpc { +namespace solid::frame::mprpc { namespace { const LoggerT logger("solid::frame::mprpc::writer"); } @@ -192,8 +190,7 @@ bool MessageWriter::enqueue( MessageStub& rmsgstub(message_vec_[msgidx]); - if (_rprelay_data->pdata_ != nullptr) { - + if (_rprelay_data->buffer_) { solid_log(logger, Verbose, this << " " << msgidx << " relay_data.flags " << _rprelay_data->flags_ << ' ' << MessageWriterPrintPairT(*this, PrintInnerListsE)); if (_rprelay_data->isMessageBegin()) { @@ -202,8 +199,8 @@ bool MessageWriter::enqueue( } rmsgstub.prelay_data_ = _rprelay_data; - rmsgstub.prelay_pos_ = rmsgstub.prelay_data_->pdata_; - rmsgstub.relay_size_ = rmsgstub.prelay_data_->data_size_; + rmsgstub.prelay_pos_ = rmsgstub.prelay_data_->buffer_.cdata(); + rmsgstub.relay_size_ = rmsgstub.prelay_data_->buffer_.csize(); rmsgstub.pool_msg_id_ = _rengine_msg_id; _rprelay_data = nullptr; @@ -250,13 +247,13 @@ void MessageWriter::cancel( } } //----------------------------------------------------------------------------- -MessagePointerT<> MessageWriter::fetchRequest(MessageId const& _rmsguid) const +SendMessagePointerT<> MessageWriter::fetchRequest(MessageId const& _rmsguid) const { if (_rmsguid.isValid() && _rmsguid.index < message_vec_.size() && _rmsguid.unique == message_vec_[_rmsguid.index].unique_) { const MessageStub& rmsgstub = message_vec_[_rmsguid.index]; - return MessagePointerT<>(rmsgstub.msgbundle_.message_ptr); + return SendMessagePointerT<>(rmsgstub.msgbundle_.message_ptr); } - return MessagePointerT<>(); + return SendMessagePointerT<>(); } //----------------------------------------------------------------------------- ResponseStateE MessageWriter::checkResponseState(MessageId const& _rmsguid, MessageId& _rrelay_id, const bool _erase_request) @@ -419,11 +416,11 @@ ErrorConditionT MessageWriter::write( bool more = true; ErrorConditionT error; - while (more && freesz >= (PacketHeader::size_of_header + _rsender.protocol().minimumFreePacketDataSize())) { + while (more && freesz >= (PacketHeader::header_size + _rsender.protocol().minimumFreePacketDataSize())) { PacketHeader packet_header(PacketHeader::TypeE::Data, 0, 0); PacketOptions packet_options; - char* pbufdata = pbufpos + PacketHeader::size_of_header; + char* pbufdata = pbufpos + PacketHeader::header_size; size_t fillsz = doWritePacketData(pbufdata, pbufend, packet_options, _rackd_buf_count, _cancel_remote_msg_vec, _rrelay_free_count, _rsender, error); if (fillsz != 0u) { @@ -452,9 +449,9 @@ ErrorConditionT MessageWriter::write( more = false; // do not allow multiple packets per relay buffer } - solid_assert_log(static_cast(fillsz) < static_cast(0xffffUL), logger); + solid_assert_log(fillsz <= static_cast(PacketHeader::max_size), logger); - packet_header.size(static_cast(fillsz)); + packet_header.size(static_cast(fillsz)); pbufpos = packet_header.store(pbufpos, _rsender.protocol()); pbufpos = pbufdata + fillsz; @@ -1047,9 +1044,10 @@ void MessageWriter::forEveryMessagesNewerToOlder(VisitFunctionT const& _rvisit_f doUnprepareMessageStub(oldidx); } else { - msgidx = order_inner_list_.previousIndex(msgidx); } + } else { + msgidx = order_inner_list_.previousIndex(msgidx); } } // while } @@ -1128,6 +1126,4 @@ std::ostream& operator<<(std::ostream& _ros, std::pair; enum PrintWhat { PrintInnerListsE, @@ -193,7 +190,7 @@ class MessageWriter { void cancel(MessageId const& _rmsguid, MessageWriterSender& _rsender, const bool _force = false); - MessagePointerT<> fetchRequest(MessageId const& _rmsguid) const; + [[nodiscard]] SendMessagePointerT<> fetchRequest(MessageId const& _rmsguid) const; ResponseStateE checkResponseState(MessageId const& _rmsguid, MessageId& _rrelay_id, const bool _erase_request); @@ -399,6 +396,4 @@ inline bool MessageWriter::MessageStub::isSynchronous() const noexcept return Message::is_synchronous(msgbundle_.message_flags); } //----------------------------------------------------------------------------- -} // namespace mprpc -} // namespace frame -} // namespace solid +} // namespace solid::frame::mprpc diff --git a/solid/frame/mprpc/src/mprpcrelayengine.cpp b/solid/frame/mprpc/src/mprpcrelayengine.cpp index a4238ece..f438584b 100644 --- a/solid/frame/mprpc/src/mprpcrelayengine.cpp +++ b/solid/frame/mprpc/src/mprpcrelayengine.cpp @@ -21,10 +21,7 @@ using namespace std; -namespace solid { -namespace frame { -namespace mprpc { -namespace relay { +namespace solid::frame::mprpc::relay { //----------------------------------------------------------------------------- namespace { const LoggerT logger("solid::frame::mprpc::relay"); @@ -124,7 +121,7 @@ struct MessageStub : inner::Node { pback_->pnext_ = nullptr; } pback_->pmessage_header_ = &header_; - solid_log(logger, Verbose, "pushed relay_data " << pback_ << " size = " << pback_->data_size_ << " is_begin = " << pback_->isMessageBegin() << " is_end = " << pback_->isMessageEnd() << " is_last = " << pback_->isMessageLast()); + solid_log(logger, Verbose, "pushed relay_data " << pback_ << " size = " << pback_->buffer_.csize() << " is_begin = " << pback_->isMessageBegin() << " is_end = " << pback_->isMessageEnd() << " is_last = " << pback_->isMessageLast()); } RelayData* pop() @@ -550,7 +547,7 @@ bool EngineCore::doRelayStart( _rrelmsg.flags_.set(RelayDataFlagsE::First); _rrelmsg.message_flags_ = rmsg.header_.flags_; - solid_log(logger, Info, _rrelay_con_uid << " msgid = " << _rrelay_id << " size = " << _rrelmsg.data_size_ << " receiver_conidx " << rmsg.receiver_con_id_.index << " sender_conidx " << rmsg.sender_con_id_.index << " flags = " << _rrelmsg.flags_); + solid_log(logger, Info, _rrelay_con_uid << " msgid = " << _rrelay_id << " size = " << _rrelmsg.buffer_.csize() << " receiver_conidx " << rmsg.receiver_con_id_.index << " sender_conidx " << rmsg.sender_con_id_.index << " flags = " << _rrelmsg.flags_); solid_assert_log(rmsg.pfront_ == nullptr, logger); @@ -584,7 +581,7 @@ bool EngineCore::doRelay( const size_t msgidx = _rrelay_id.index; MessageStub& rmsg = impl_->msg_dq_[msgidx]; const bool is_msg_relay_data_queue_empty = (rmsg.pfront_ == nullptr); - size_t data_size = _rrelmsg.data_size_; + size_t data_size = _rrelmsg.buffer_.csize(); auto flags = rmsg.last_message_flags_; _rrelmsg.message_flags_ = rmsg.last_message_flags_; @@ -695,7 +692,7 @@ bool EngineCore::doRelayResponse( } } else if (rmsg.state_ == MessageStateE::Relay || rmsg.state_ == MessageStateE::WaitResponsePart) { const bool is_msg_relay_data_queue_empty = (rmsg.pfront_ == nullptr); - size_t data_size = _rrelmsg.data_size_; + size_t data_size = _rrelmsg.buffer_.csize(); rmsg.state_ = MessageStateE::Relay; @@ -1129,7 +1126,4 @@ void EngineCore::Proxy::registerConnectionId(const ConnectionContext& _rconctx, re_.doRegisterConnectionId(_rconctx, _idx); } //----------------------------------------------------------------------------- -} // namespace relay -} // namespace mprpc -} // namespace frame -} // namespace solid +} // namespace solid::frame::mprpc::relay diff --git a/solid/frame/mprpc/src/mprpcservice.cpp b/solid/frame/mprpc/src/mprpcservice.cpp index 4f629c7e..715e29e1 100644 --- a/solid/frame/mprpc/src/mprpcservice.cpp +++ b/solid/frame/mprpc/src/mprpcservice.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -46,9 +47,7 @@ using namespace std; -namespace solid { -namespace frame { -namespace mprpc { +namespace solid::frame::mprpc { namespace { const LoggerT logger("solid::frame::mprpc::service"); @@ -115,7 +114,7 @@ struct MessageStub : inner::Node { uint flags_; MessageStub( - MessagePointerT<>&& _rmsgptr, + SendMessagePointerT<>&& _rmsgptr, const size_t _msg_type_idx, MessageCompleteFunctionT& _rcomplete_fnc, ulong _msgflags, @@ -127,7 +126,7 @@ struct MessageStub : inner::Node { } MessageStub( - MessagePointerT<>&& _rmsgptr, + SendMessagePointerT<>&& _rmsgptr, const size_t _msg_type_idx, MessageCompleteFunctionT& _rcomplete_fnc, ulong _msgflags, @@ -297,12 +296,12 @@ struct ConnectionPoolStub : inner::Node& _rmsgptr, + SendMessagePointerT<>& _rmsgptr, const size_t _msg_type_idx, MessageCompleteFunctionT& _rcomplete_fnc, const MessageFlagsT& _flags, @@ -327,7 +326,7 @@ struct ConnectionPoolStub : inner::Node& _rmsgptr, + SendMessagePointerT<>& _rmsgptr, const size_t _msg_type_idx, MessageCompleteFunctionT& _rcomplete_fnc, const MessageFlagsT& _flags, @@ -352,7 +351,7 @@ struct ConnectionPoolStub : inner::Node& _rmsgptr, + SendMessagePointerT<>& _rmsgptr, const size_t _msg_type_idx, MessageCompleteFunctionT& _rcomplete_fnc, const MessageFlagsT& _flags, @@ -376,7 +375,7 @@ struct ConnectionPoolStub : inner::Node& _rmsgptr, + SendMessagePointerT<>& _rmsgptr, const size_t _msg_type_idx, MessageCompleteFunctionT& _rcomplete_fnc, const MessageFlagsT& _flags, @@ -636,8 +635,7 @@ struct Service::Data { NameMapT name_map_; ConnectionPoolDequeT pool_dq_; ConnectionPoolInnerListT pool_free_list_; - // std::string tmp_str_; - ServiceStatistic statistic_; + ServiceStatistic statistic_; Data(Service& _rsvc, Configuration&& _config) : rmutex_(_rsvc.mutex()) @@ -675,7 +673,7 @@ struct Service::Data { ErrorConditionT doSendMessageToConnection( Service& _rsvc, const RecipientId& _rrecipient_id_in, - MessagePointerT<>& _rmsgptr, + SendMessagePointerT<>& _rmsgptr, MessageCompleteFunctionT& _rcomplete_fnc, MessageId* _pmsg_id_out, MessageFlagsT _flags, @@ -755,7 +753,7 @@ struct Service::Data { bool doTryNotifyPoolWaitingConnection(Service& _rsvc, const size_t _pool_index); ErrorConditionT doSendMessageToPool( - Service& _rsvc, const ConnectionPoolId& _rpool_id, MessagePointerT<>& _rmsgptr, + Service& _rsvc, const ConnectionPoolId& _rpool_id, SendMessagePointerT<>& _rmsgptr, MessageCompleteFunctionT& _rcomplete_fnc, const size_t _msg_type_idx, const OptionalMessageRelayHeaderT& _relay, @@ -1033,7 +1031,7 @@ ErrorConditionT Service::Data::doLockPool( //----------------------------------------------------------------------------- ErrorConditionT Service::doSendMessageUsingConnectionContext( const RecipientUrl& _recipient_url, - MessagePointerT<>& _rmsgptr, + SendMessagePointerT<>& _rmsgptr, MessageCompleteFunctionT& _rcomplete_fnc, RecipientId* _precipient_id_out, MessageId* _pmsg_id_out, @@ -1073,7 +1071,7 @@ ErrorConditionT Service::doSendMessageUsingConnectionContext( //----------------------------------------------------------------------------- ErrorConditionT Service::doSendMessage( const RecipientUrl& _recipient_url, - MessagePointerT<>& _rmsgptr, + SendMessagePointerT<>& _rmsgptr, MessageCompleteFunctionT& _rcomplete_fnc, RecipientId* _precipient_id_out, MessageId* _pmsgid_out, @@ -1186,7 +1184,7 @@ ErrorConditionT Service::doSendMessage( ErrorConditionT Service::Data::doSendMessageToConnection( Service& _rsvc, const RecipientId& _rrecipient_id_in, - MessagePointerT<>& _rmsgptr, + SendMessagePointerT<>& _rmsgptr, MessageCompleteFunctionT& _rcomplete_fnc, MessageId* _pmsgid_out, MessageFlagsT _flags, @@ -1264,7 +1262,7 @@ ErrorConditionT Service::Data::doSendMessageToConnection( } //----------------------------------------------------------------------------- ErrorConditionT Service::Data::doSendMessageToPool( - Service& _rsvc, const ConnectionPoolId& _rpool_id, MessagePointerT<>& _rmsgptr, + Service& _rsvc, const ConnectionPoolId& _rpool_id, SendMessagePointerT<>& _rmsgptr, MessageCompleteFunctionT& _rcomplete_fnc, const size_t _msg_type_idx, const OptionalMessageRelayHeaderT& _relay, @@ -1632,9 +1630,9 @@ ErrorConditionT Service::doDelayCloseConnectionPool( } } - MessagePointerT<> empty_msg_ptr; - bool is_first; - const MessageId msgid = rpool.pushBackMessage(empty_msg_ptr, 0, _rcomplete_fnc, 0, {}, is_first); + SendMessagePointerT<> empty_msg_ptr; + bool is_first; + const MessageId msgid = rpool.pushBackMessage(empty_msg_ptr, 0, _rcomplete_fnc, 0, {}, is_first); (void)msgid; // notify all waiting connections about the new message @@ -1683,9 +1681,9 @@ ErrorConditionT Service::doForceCloseConnectionPool( } } - MessagePointerT<> empty_msg_ptr; - bool is_first; - const MessageId msgid = rpool.pushBackMessage(empty_msg_ptr, 0, _rcomplete_fnc, {MessageFlagsE::Synchronous}, {}, is_first); + SendMessagePointerT<> empty_msg_ptr; + bool is_first; + const MessageId msgid = rpool.pushBackMessage(empty_msg_ptr, 0, _rcomplete_fnc, {MessageFlagsE::Synchronous}, {}, is_first); (void)msgid; // no reason to cancel all messages - they'll be handled on connection stop. @@ -2002,7 +2000,7 @@ bool Service::connectionStopping( } else { retval = pimpl_->doMainConnectionStoppingPrepareCleanAll(rcon, _ractuid, _rwait_duration, _rmsg_id, _pmsg_bundle, _revent_context, _rerror); } - if (!was_disconnected && rpool.isDisconnected() && !solid_function_empty(rpool.on_event_fnc_)) { + if (!was_disconnected && rpool.isDisconnected() && rpool.on_event_fnc_) { ppool = &rpool; } } @@ -2196,7 +2194,7 @@ bool Service::Data::doMainConnectionStoppingCleanAll( solid_log(logger, Verbose, this << " pool " << pool_index << " set closing"); } - return true; // TODO: maybe we should return false + return true; } return false; } @@ -2372,7 +2370,7 @@ void Service::connectionStop(ConnectionContext& _rconctx) pool_lock.unlock(); // do not call callback under lock - if (!solid_function_empty(rpool.on_event_fnc_) && _rconctx.connection().isConnected()) { + if (rpool.on_event_fnc_ && _rconctx.connection().isConnected()) { rpool.on_event_fnc_(_rconctx, make_event(pool_event_category, PoolEvents::ConnectionStop), ErrorConditionT()); } @@ -2397,7 +2395,7 @@ void Service::connectionStop(ConnectionContext& _rconctx) rpool.clear(); } } - if (!solid_function_empty(on_event_fnc)) { + if (on_event_fnc) { on_event_fnc(_rconctx, make_event(pool_event_category, PoolEvents::PoolStop), ErrorConditionT()); } } @@ -2428,7 +2426,7 @@ bool Service::Data::doTryCreateNewConnectionForPool(Service& _rsvc, const size_t if (rpool.connect_addr_vec_.empty()) { - ResolveCompleteFunctionT cbk(OnRelsolveF(_rsvc.manager(), conuid, Connection::eventResolve())); + ResolveCompleteFunctionT cbk(OnRelsolveF(_rsvc.manager(), conuid, Connection::eventResolve()), AcceptBigT{}); config_.client.name_resolve_fnc(rpool.name_, cbk); @@ -2589,7 +2587,7 @@ ErrorConditionT Service::activateConnection(ConnectionContext& _rconctx, ActorId rpool.resetDisconnected(); - if (!solid_function_empty(rpool.on_event_fnc_)) { + if (rpool.on_event_fnc_) { pconpool = &rpool; } } @@ -2660,7 +2658,7 @@ void Service::onOutgoingConnectionStart(ConnectionContext& _rconctx) return; } - if (!solid_function_empty(rpool.on_event_fnc_)) { + if (rpool.on_event_fnc_) { ppool = &rpool; } } @@ -2844,9 +2842,8 @@ std::ostream& ServiceStatistic::print(std::ostream& _ros) const _ros << " 70:" << poll_pool_fetch_count_70_ << " 80:" << poll_pool_fetch_count_80_ << ']'; _ros << " max_fetch = " << max_fetch_size_; _ros << " min_fetch = " << min_fetch_size_; + _ros << " max_optimize_duration_us_ = " << max_optimize_duration_us_; return _ros; } //============================================================================= -} // namespace mprpc -} // namespace frame -} // namespace solid +} // namespace solid::frame::mprpc diff --git a/solid/frame/mprpc/src/mprpcutility.hpp b/solid/frame/mprpc/src/mprpcutility.hpp index 67201629..faee747f 100644 --- a/solid/frame/mprpc/src/mprpcutility.hpp +++ b/solid/frame/mprpc/src/mprpcutility.hpp @@ -10,15 +10,15 @@ #pragma once +#include "solid/frame/mprpc/mprpcprotocol.hpp" #include "solid/system/cassert.hpp" #include "solid/system/log.hpp" #include "solid/system/socketaddress.hpp" #include "solid/frame/mprpc/mprpcservice.hpp" +#include -namespace solid { -namespace frame { -namespace mprpc { +namespace solid::frame::mprpc { enum struct ResponseStateE { Wait, @@ -50,7 +50,8 @@ class PacketHeader { uint16_t size_; public: - static constexpr size_t size_of_header = 4; + static constexpr size_t header_size = 4; + static constexpr uint16_t max_size = Protocol::max_packet_size - header_size; enum struct TypeE : uint8_t { Data = 1, @@ -71,7 +72,6 @@ class PacketHeader { }; enum struct FlagE : uint8_t { - Size64KB = 1, // DO NOT CHANGE!! Compressed = 2, AckRequest = 4, }; @@ -81,6 +81,7 @@ class PacketHeader { const uint8_t _flags = 0, const uint16_t _size = 0) { + static_assert(Protocol::packet_header_size == header_size); reset(_type, _flags, _size); } @@ -94,18 +95,17 @@ class PacketHeader { size(_size); } - uint32_t size() const + [[nodiscard]] uint16_t size() const { - uint32_t sz = (flags_ & static_cast(FlagE::Size64KB)); - return (sz << 16) | size_; + return size_; } - uint8_t type() const + [[nodiscard]] uint8_t type() const { return type_; } - uint8_t flags() const + [[nodiscard]] uint8_t flags() const { return flags_; } @@ -119,22 +119,21 @@ class PacketHeader { flags_ = _flags /*& (0xff - Size64KBFlagE)*/; } - void size(uint32_t _sz) + void size(uint16_t const _sz) { - size_ = _sz & 0xffff; - flags_ |= ((_sz & (1 << 16)) >> 16); + size_ = _sz; } - bool isTypeKeepAlive() const + [[nodiscard]] bool isTypeKeepAlive() const { return type_ == static_cast(TypeE::KeepAlive); } - bool isCompressed() const + [[nodiscard]] bool isCompressed() const { - return flags_ & static_cast(FlagE::Compressed); + return (flags_ & static_cast(FlagE::Compressed)) != 0U; } - bool isOk() const + [[nodiscard]] bool isOk() const { switch (static_cast(type_)) { case TypeE::Data: @@ -144,7 +143,7 @@ class PacketHeader { return false; } - return size() <= Protocol::MaxPacketDataSize; + return size() <= max_size; } char* store(char* _pc, const Protocol& _rproto) const @@ -167,14 +166,14 @@ class PacketHeader { struct MessageBundle { size_t message_type_id = InvalidIndex(); MessageFlagsT message_flags = 0; - MessagePointerT<> message_ptr; + SendMessagePointerT<> message_ptr; MessageCompleteFunctionT complete_fnc; OptionalMessageRelayHeaderT message_relay_header_; MessageBundle() = default; MessageBundle( - MessagePointerT<>&& _rmsgptr, + SendMessagePointerT<>&& _rmsgptr, const size_t _msg_type_idx, const MessageFlagsT& _flags, MessageCompleteFunctionT& _complete_fnc, @@ -188,7 +187,7 @@ struct MessageBundle { } MessageBundle( - MessagePointerT<>&& _rmsgptr, + SendMessagePointerT<>&& _rmsgptr, const size_t _msg_type_idx, const MessageFlagsT& _flags, MessageCompleteFunctionT& _complete_fnc, @@ -202,7 +201,7 @@ struct MessageBundle { } MessageBundle( - MessagePointerT<>&& _rmsgptr, + SendMessagePointerT<>&& _rmsgptr, const size_t _msg_type_idx, const MessageFlagsT& _flags, MessageCompleteFunctionT& _complete_fnc) @@ -229,7 +228,7 @@ struct MessageBundle { message_flags = _rmsgbundle.message_flags; message_ptr = std::move(_rmsgbundle.message_ptr); message_relay_header_ = std::move(_rmsgbundle.message_relay_header_); - solid_function_clear(complete_fnc); + complete_fnc = nullptr; std::swap(complete_fnc, _rmsgbundle.complete_fnc); return *this; } @@ -240,10 +239,8 @@ struct MessageBundle { message_flags.reset(); message_ptr.reset(); message_relay_header_.reset(); - solid_function_clear(complete_fnc); + complete_fnc = nullptr; } }; -} // namespace mprpc -} // namespace frame -} // namespace solid +} // namespace solid::frame::mprpc diff --git a/solid/frame/mprpc/test/CMakeLists.txt b/solid/frame/mprpc/test/CMakeLists.txt index d66edb61..3cfe7478 100644 --- a/solid/frame/mprpc/test/CMakeLists.txt +++ b/solid/frame/mprpc/test/CMakeLists.txt @@ -56,6 +56,7 @@ if(OPENSSL_FOUND) set( mprpcClientServerTestSuite test_clientserver_basic.cpp + test_clientserver_pool.cpp test_clientserver_versioning.cpp test_clientserver_sendrequest.cpp test_clientserver_cancel_server.cpp @@ -128,6 +129,8 @@ if(OPENSSL_FOUND) add_test(NAME TestClientServerBasic_8B COMMAND test_mprpc_clientserver test_clientserver_basic 8 b) add_test(NAME TestClientServerBasic_8BC COMMAND test_mprpc_clientserver test_clientserver_basic 8 b c) + add_test(NAME TestClientServerPool_8 COMMAND test_mprpc_clientserver test_clientserver_pool 8) + add_test(NAME TestClientServerVersioning COMMAND test_mprpc_clientserver test_clientserver_versioning) add_test(NAME TestClientServerTopic COMMAND test_mprpc_clientserver test_clientserver_topic) @@ -205,7 +208,6 @@ if(OPENSSL_FOUND) PROPERTIES LABELS "mprpc clientserver" ) #============================================================================== - set( mprpcKeepAliveTestSuite test_keepalive_fail.cpp test_keepalive_success.cpp @@ -270,7 +272,6 @@ if(OPENSSL_FOUND) ) #============================================================================== - set( mprpcPoolTestSuite test_pool_basic.cpp test_pool_force_close.cpp @@ -317,7 +318,7 @@ if(OPENSSL_FOUND) ) #============================================================================== - + add_subdirectory(multiprotocol_basic) set( mprpcMultiProtocolTestSuite @@ -501,5 +502,4 @@ if(OPENSSL_FOUND) PROPERTIES LABELS "mprpc clientfrontback" ) #============================================================================== - endif(OPENSSL_FOUND) diff --git a/solid/frame/mprpc/test/multiprotocol_basic/alpha/client/alphaclient.cpp b/solid/frame/mprpc/test/multiprotocol_basic/alpha/client/alphaclient.cpp index 7c7705f3..8c8dc542 100644 --- a/solid/frame/mprpc/test/multiprotocol_basic/alpha/client/alphaclient.cpp +++ b/solid/frame/mprpc/test/multiprotocol_basic/alpha/client/alphaclient.cpp @@ -25,17 +25,17 @@ void client_connection_start(frame::mprpc::ConnectionContext& _rctx) template void complete_message( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror); + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, + frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror); template <> void complete_message( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, + frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, ""); solid_check(!_rerror); @@ -53,10 +53,10 @@ void complete_message( template <> void complete_message( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, + frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, ""); solid_check(!_rerror); @@ -74,10 +74,10 @@ void complete_message( template <> void complete_message( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, + frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, ""); solid_check(!_rerror); @@ -117,7 +117,7 @@ ErrorConditionT start( auto proto = frame::mprpc::serialization_v3::create_protocol( reflection::v1::metadata::factory, [](auto& _rmap) { - auto lambda = [&](const TypeIdT _id, const std::string_view _name, type_identity const& _rtype) { + auto lambda = [&](const TypeIdT _id, const std::string_view _name, type_identity const&) { _rmap.template registerMessage(_id, _name, complete_message); }; alpha_protocol::configure_protocol(lambda); @@ -139,7 +139,7 @@ ErrorConditionT start( _rctx.rwait_count += 3; err = mprpcclient_ptr->sendMessage( - {"localhost"}, frame::mprpc::make_message(100000UL, make_string(100000)), + {"localhost"}, frame::mprpc::make_message(100000U, make_string(100000)), {frame::mprpc::MessageFlagsE::AwaitResponse}); if (err) { return err; diff --git a/solid/frame/mprpc/test/multiprotocol_basic/alpha/server/alphaserver.cpp b/solid/frame/mprpc/test/multiprotocol_basic/alpha/server/alphaserver.cpp index b4f3fb50..70844899 100644 --- a/solid/frame/mprpc/test/multiprotocol_basic/alpha/server/alphaserver.cpp +++ b/solid/frame/mprpc/test/multiprotocol_basic/alpha/server/alphaserver.cpp @@ -9,10 +9,10 @@ namespace alpha_server { template <> void complete_message( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, + frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, ""); @@ -31,10 +31,10 @@ void complete_message( template <> void complete_message( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, + frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, ""); solid_check(!_rerror); @@ -51,10 +51,10 @@ void complete_message( template <> void complete_message( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, + frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, ""); solid_check(!_rerror); diff --git a/solid/frame/mprpc/test/multiprotocol_basic/alpha/server/alphaserver.hpp b/solid/frame/mprpc/test/multiprotocol_basic/alpha/server/alphaserver.hpp index 14adf529..d4c2e2cd 100644 --- a/solid/frame/mprpc/test/multiprotocol_basic/alpha/server/alphaserver.hpp +++ b/solid/frame/mprpc/test/multiprotocol_basic/alpha/server/alphaserver.hpp @@ -7,15 +7,15 @@ namespace alpha_server { template void complete_message( - solid::frame::mprpc::ConnectionContext& _rctx, - solid::frame::mprpc::MessagePointerT& _rsent_msg_ptr, - solid::frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - solid::ErrorConditionT const& _rerror); + solid::frame::mprpc::ConnectionContext& _rctx, + solid::frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, + solid::frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, + solid::ErrorConditionT const& _rerror); template void register_messages(Reg& _rmap) { - auto lambda = [&](const TypeIdT _id, const std::string_view _name, std::type_identity const& _rtype) { + auto lambda = [&](const TypeIdT _id, const std::string_view _name, std::type_identity const&) { _rmap.template registerMessage(_id, _name, complete_message); }; alpha_protocol::configure_protocol(lambda); diff --git a/solid/frame/mprpc/test/multiprotocol_basic/beta/client/betaclient.cpp b/solid/frame/mprpc/test/multiprotocol_basic/beta/client/betaclient.cpp index ed226df8..f4d740d9 100644 --- a/solid/frame/mprpc/test/multiprotocol_basic/beta/client/betaclient.cpp +++ b/solid/frame/mprpc/test/multiprotocol_basic/beta/client/betaclient.cpp @@ -22,10 +22,10 @@ void client_connection_start(frame::mprpc::ConnectionContext& _rctx) } void complete_message_first( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, + frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, ""); solid_check(!_rerror); @@ -42,10 +42,10 @@ void complete_message_first( } void complete_message_second( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, + frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, ""); solid_check(!_rerror); @@ -62,10 +62,10 @@ void complete_message_second( } void complete_message_third( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, + frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, ""); solid_check(!_rerror); @@ -105,7 +105,7 @@ ErrorConditionT start( auto proto = frame::mprpc::serialization_v3::create_protocol( reflection::v1::metadata::factory, [](auto& _rmap) { - auto lambda = [&](const TypeIdT _id, const std::string_view _name, type_identity const& _rtype) { + auto lambda = [&](const TypeIdT _id, const std::string_view _name, type_identity const&) { using TypeT = T; if constexpr (std::is_same_v) { _rmap.template registerMessage(_id, _name, complete_message_first); @@ -134,7 +134,7 @@ ErrorConditionT start( _rctx.rwait_count += 3; err = mprpcclient_ptr->sendMessage( - {"localhost"}, frame::mprpc::make_message(100000UL, make_string(100000)), + {"localhost"}, frame::mprpc::make_message(100000U, make_string(100000)), {frame::mprpc::MessageFlagsE::AwaitResponse}); if (err) { return err; diff --git a/solid/frame/mprpc/test/multiprotocol_basic/beta/server/betaserver.cpp b/solid/frame/mprpc/test/multiprotocol_basic/beta/server/betaserver.cpp index 5bd6bccc..0e6b5b4f 100644 --- a/solid/frame/mprpc/test/multiprotocol_basic/beta/server/betaserver.cpp +++ b/solid/frame/mprpc/test/multiprotocol_basic/beta/server/betaserver.cpp @@ -10,10 +10,10 @@ namespace beta_server { template <> void complete_message( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, + frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, ""); solid_check(!_rerror); @@ -33,10 +33,10 @@ void complete_message( template <> void complete_message( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, + frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, ""); solid_check(!_rerror); @@ -53,10 +53,10 @@ void complete_message( template <> void complete_message( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, + frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, ""); solid_check(!_rerror); diff --git a/solid/frame/mprpc/test/multiprotocol_basic/beta/server/betaserver.hpp b/solid/frame/mprpc/test/multiprotocol_basic/beta/server/betaserver.hpp index 73e28304..048342ea 100644 --- a/solid/frame/mprpc/test/multiprotocol_basic/beta/server/betaserver.hpp +++ b/solid/frame/mprpc/test/multiprotocol_basic/beta/server/betaserver.hpp @@ -7,15 +7,15 @@ namespace beta_server { template void complete_message( - solid::frame::mprpc::ConnectionContext& _rctx, - solid::frame::mprpc::MessagePointerT& _rsent_msg_ptr, - solid::frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - solid::ErrorConditionT const& _rerror); + solid::frame::mprpc::ConnectionContext& _rctx, + solid::frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, + solid::frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, + solid::ErrorConditionT const& _rerror); template void register_messages(Reg& _rmap) { - auto lambda = [&](const TypeIdT _id, const std::string_view _name, std::type_identity const& _rtype) { + auto lambda = [&](const TypeIdT _id, const std::string_view _name, std::type_identity const&) { _rmap.template registerMessage(_id, _name, complete_message); }; beta_protocol::configure_protocol(lambda); diff --git a/solid/frame/mprpc/test/multiprotocol_basic/gamma/client/gammaclient.cpp b/solid/frame/mprpc/test/multiprotocol_basic/gamma/client/gammaclient.cpp index 19566cae..2e697ea1 100644 --- a/solid/frame/mprpc/test/multiprotocol_basic/gamma/client/gammaclient.cpp +++ b/solid/frame/mprpc/test/multiprotocol_basic/gamma/client/gammaclient.cpp @@ -23,10 +23,10 @@ void client_connection_start(frame::mprpc::ConnectionContext& _rctx) template void complete_message( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, + frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, ""); solid_check(!_rerror); @@ -66,7 +66,7 @@ ErrorConditionT start( auto proto = frame::mprpc::serialization_v3::create_protocol( reflection::v1::metadata::factory, [](auto& _rmap) { - auto lambda = [&](const TypeIdT _id, const std::string_view _name, type_identity const& _rtype) { + auto lambda = [&](const TypeIdT _id, const std::string_view _name, type_identity const&) { _rmap.template registerMessage(_id, _name, complete_message); }; gamma_protocol::configure_protocol(lambda); @@ -88,7 +88,7 @@ ErrorConditionT start( _rctx.rwait_count += 3; err = mprpcclient_ptr->sendMessage( - {"localhost"}, frame::mprpc::make_message(100000UL, make_string(100000)), + {"localhost"}, frame::mprpc::make_message(100000U, make_string(100000)), {frame::mprpc::MessageFlagsE::AwaitResponse}); if (err) { return err; diff --git a/solid/frame/mprpc/test/multiprotocol_basic/gamma/server/gammaserver.hpp b/solid/frame/mprpc/test/multiprotocol_basic/gamma/server/gammaserver.hpp index 62c358ad..eaf8bbb1 100644 --- a/solid/frame/mprpc/test/multiprotocol_basic/gamma/server/gammaserver.hpp +++ b/solid/frame/mprpc/test/multiprotocol_basic/gamma/server/gammaserver.hpp @@ -10,10 +10,10 @@ namespace gamma_server { template void complete_message( - solid::frame::mprpc::ConnectionContext& _rctx, - solid::frame::mprpc::MessagePointerT& _rsent_msg_ptr, - solid::frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - solid::ErrorConditionT const& _rerror) + solid::frame::mprpc::ConnectionContext& _rctx, + solid::frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, + solid::frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, + solid::ErrorConditionT const& _rerror) { solid_dbg(solid::generic_logger, Info, ""); solid_check(!_rerror); @@ -31,7 +31,7 @@ void complete_message( template void register_messages(Reg& _rmap) { - auto lambda = [&](const TypeIdT _id, const std::string_view _name, std::type_identity const& _rtype) { + auto lambda = [&](const TypeIdT _id, const std::string_view _name, std::type_identity const&) { _rmap.template registerMessage(_id, _name, complete_message); }; gamma_protocol::configure_protocol(lambda); diff --git a/solid/frame/mprpc/test/test_clientfrontback_download.cpp b/solid/frame/mprpc/test/test_clientfrontback_download.cpp index 1bc1bd7b..deae91cf 100644 --- a/solid/frame/mprpc/test/test_clientfrontback_download.cpp +++ b/solid/frame/mprpc/test/test_clientfrontback_download.cpp @@ -35,7 +35,7 @@ using namespace solid; namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; LoggerT logger("test"); @@ -53,13 +53,11 @@ namespace front { struct Response; struct Request : frame::mprpc::Message { - string name_; - ofstream ofs_; - bool send_request_ = false; + string name_; + mutable ofstream ofs_; + mutable bool send_request_ = false; - Request() - { - } + Request() = default; Request(Response& _res); @@ -80,11 +78,11 @@ struct Request : frame::mprpc::Message { }; struct Response : frame::mprpc::Message { - uint32_t error_ = -1; - ostringstream oss_; - mutable istringstream iss_; - frame::mprpc::MessagePointerT req_ptr_; - frame::mprpc::RecipientId recipient_id_; + uint32_t error_ = -1; + ostringstream oss_; + mutable istringstream iss_; + mutable frame::mprpc::RecvMessagePointerT req_ptr_; + frame::mprpc::RecipientId recipient_id_; Response() : error_(0) @@ -124,8 +122,10 @@ struct Response : frame::mprpc::Message { } }; -using RequestPointerT = solid::frame::mprpc::MessagePointerT; -using ResponsePointerT = solid::frame::mprpc::MessagePointerT; +using SendRequestPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvRequestPointerT = solid::frame::mprpc::RecvMessagePointerT; +using SendResponsePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvResponsePointerT = solid::frame::mprpc::RecvMessagePointerT; Request::Request(Response& _res) : frame::mprpc::Message(_res) @@ -133,15 +133,15 @@ Request::Request(Response& _res) } void on_server_receive_first_request( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror); + frame::mprpc::ConnectionContext& _rctx, + SendRequestPointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror); void on_server_response( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "front: on message: " << _rsent_msg_ptr.get()); @@ -149,8 +149,8 @@ void on_server_response( void on_client_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "front: on message"); @@ -158,8 +158,8 @@ void on_client_request( void on_client_response( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "front: on message"); @@ -167,8 +167,8 @@ void on_client_response( void on_client_receive_response( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror); } // namespace front @@ -178,14 +178,12 @@ namespace back { struct Response; struct Request : frame::mprpc::Message { - string name_; - frame::mprpc::MessagePointerT res_ptr_; - frame::mprpc::RecipientId recipient_id_; - bool await_response_ = false; + string name_; + front::RecvResponsePointerT res_ptr_; + frame::mprpc::RecipientId recipient_id_; + mutable bool await_response_ = false; - Request() - { - } + Request() = default; Request(Response& _res); @@ -242,8 +240,10 @@ struct Response : frame::mprpc::Message { } }; -using RequestPointerT = solid::frame::mprpc::MessagePointerT; -using ResponsePointerT = solid::frame::mprpc::MessagePointerT; +using SendRequestPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvRequestPointerT = solid::frame::mprpc::RecvMessagePointerT; +using SendResponsePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvResponsePointerT = solid::frame::mprpc::RecvMessagePointerT; Request::Request(Response& _res) : frame::mprpc::Message(_res) @@ -252,14 +252,14 @@ Request::Request(Response& _res) void on_server_receive_first_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror); void on_server_response( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "back: on message"); @@ -267,8 +267,8 @@ void on_server_response( void on_client_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "back: on message"); @@ -276,8 +276,8 @@ void on_client_request( void on_client_response( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "back: on message"); @@ -527,7 +527,7 @@ int test_clientfrontback_download(int argc, char* argv[]) auto msg_ptr = frame::mprpc::make_message(f); msg_ptr->ofs_.open(string("client_storage/") + f); - mprpc_front_client.sendRequest({"localhost"}, msg_ptr, front::on_client_receive_response); + mprpc_front_client.sendRequest({"localhost"}, std::move(msg_ptr), front::on_client_receive_response); } auto fut = prom.get_future(); @@ -637,10 +637,10 @@ void check_files(const vector& _file_vec, const char* _path_prefix_clien namespace back { void on_client_receive_response( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror); + frame::mprpc::ConnectionContext& _rctx, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror); } // namespace back @@ -652,8 +652,8 @@ namespace front { void on_client_receive_response( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(_rrecv_msg_ptr); @@ -671,7 +671,7 @@ void on_client_receive_response( if (_rsent_msg_ptr->send_request_) { _rsent_msg_ptr->send_request_ = false; auto res_ptr = frame::mprpc::make_message(*_rrecv_msg_ptr); - auto err = _rctx.service().sendMessage(_rctx.recipientId(), res_ptr, {frame::mprpc::MessageFlagsE::Response}); + auto err = _rctx.service().sendMessage(_rctx.recipientId(), std::move(res_ptr), {frame::mprpc::MessageFlagsE::Response}); solid_log(logger, Verbose, "send response to: " << _rctx.recipientId() << " err: " << err.message()); } else { _rsent_msg_ptr->send_request_ = true; @@ -689,10 +689,10 @@ void on_client_receive_response( //----------------------------------------------------------------------------- void on_server_receive_request( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + front::SendResponsePointerT& _rsent_msg_ptr, + front::RecvRequestPointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_check(_rrecv_msg_ptr); solid_check(_rrecv_msg_ptr->name_.empty()); @@ -701,14 +701,14 @@ void on_server_receive_request( auto req_ptr = std::move(_rsent_msg_ptr->req_ptr_); - pmprpc_back_client->sendMessage(_rsent_msg_ptr->recipient_id_, req_ptr, {frame::mprpc::MessageFlagsE::Response}); + pmprpc_back_client->sendMessage(_rsent_msg_ptr->recipient_id_, std::move(req_ptr), {frame::mprpc::MessageFlagsE::Response}); } void on_server_receive_first_request( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + front::SendRequestPointerT& _rsent_msg_ptr, + front::RecvRequestPointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_check(_rrecv_msg_ptr); @@ -722,7 +722,7 @@ void on_server_receive_first_request( req_ptr->res_ptr_ = frame::mprpc::make_message(*_rrecv_msg_ptr); req_ptr->await_response_ = true; - pmprpc_back_client->sendRequest({"localhost"}, req_ptr, back::on_client_receive_response, flags); + pmprpc_back_client->sendRequest({"localhost"}, std::move(req_ptr), back::on_client_receive_response, flags); } } // namespace front @@ -730,14 +730,14 @@ void on_server_receive_first_request( namespace back { void on_client_receive_response( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + back::SendRequestPointerT& _rsent_msg_ptr, + back::RecvResponsePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "back: received response for: " << _rsent_msg_ptr->name_); - frame::mprpc::MessagePointerT res_ptr = frame::mprpc::make_message(); + auto res_ptr = frame::mprpc::make_message(); res_ptr->error_ = _rrecv_msg_ptr->error_; res_ptr->iss_.str(_rrecv_msg_ptr->oss_.str()); @@ -746,7 +746,7 @@ void on_client_receive_response( if (_rrecv_msg_ptr->isResponseLast()) { frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::AwaitResponse, frame::mprpc::MessageFlagsE::ResponseLast}; solid_log(logger, Verbose, "back: sent last response to front: " << res_ptr.get()); - pmprpc_front_server->sendMessage(_rsent_msg_ptr->recipient_id_, res_ptr, flags); + pmprpc_front_server->sendMessage(_rsent_msg_ptr->recipient_id_, std::move(res_ptr), flags); } else { if (_rsent_msg_ptr->await_response_) { frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::AwaitResponse, frame::mprpc::MessageFlagsE::ResponsePart}; @@ -754,12 +754,12 @@ void on_client_receive_response( res_ptr->recipient_id_ = _rctx.recipientId(); res_ptr->req_ptr_ = frame::mprpc::make_message(*_rrecv_msg_ptr); solid_log(logger, Verbose, "back: sent response part to front with wait: " << res_ptr.get()); - pmprpc_front_server->sendMessage(_rsent_msg_ptr->recipient_id_, res_ptr, front::on_server_receive_request, flags); + pmprpc_front_server->sendMessage(_rsent_msg_ptr->recipient_id_, std::move(res_ptr), front::on_server_receive_request, flags); } else { frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::ResponsePart}; _rsent_msg_ptr->await_response_ = true; solid_log(logger, Verbose, "back: sent response part to front without wait: " << res_ptr.get()); - pmprpc_front_server->sendMessage(_rsent_msg_ptr->recipient_id_, res_ptr, flags); + pmprpc_front_server->sendMessage(_rsent_msg_ptr->recipient_id_, std::move(res_ptr), flags); } } } @@ -769,8 +769,8 @@ void on_client_receive_response( //----------------------------------------------------------------------------- void on_server_receive_request( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(_rrecv_msg_ptr); @@ -780,26 +780,28 @@ void on_server_receive_request( frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::ResponsePart, frame::mprpc::MessageFlagsE::AwaitResponse}; _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, on_server_receive_request, flags); flags.reset(frame::mprpc::MessageFlagsE::AwaitResponse); - _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(_rsent_msg_ptr), flags); } else { solid_log(logger, Verbose, "Sending to " << _rctx.recipientId() << " last"); frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::ResponseLast}; - _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(_rsent_msg_ptr), flags); } } void on_server_receive_first_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { - string path = string("server_storage") + '/' + _rrecv_msg_ptr->name_; - - auto res_ptr = frame::mprpc::make_message(*_rrecv_msg_ptr); - - res_ptr->ifs_.open(path); + string path = string("server_storage") + '/' + _rrecv_msg_ptr->name_; + SendResponsePointerT res_ptr; + { + auto mut_res_ptr = frame::mprpc::make_message(*_rrecv_msg_ptr); + mut_res_ptr->ifs_.open(path); + res_ptr = std::move(mut_res_ptr); + } solid_check(res_ptr->ifs_, "failed open file: " << path); if (!res_ptr->ifs_.eof()) { @@ -809,12 +811,12 @@ void on_server_receive_first_request( auto error = _rctx.service().sendMessage(_rctx.recipientId(), res_ptr, on_server_receive_request, flags); solid_check(!error, "failed send message: " << error.message()); flags.reset(frame::mprpc::MessageFlagsE::AwaitResponse); - error = _rctx.service().sendMessage(_rctx.recipientId(), res_ptr, flags); + error = _rctx.service().sendMessage(_rctx.recipientId(), std::move(res_ptr), flags); solid_check(!error, "failed send message: " << error.message()); } else { solid_log(logger, Verbose, "Sending " << _rsent_msg_ptr->name_ << " to " << _rctx.recipientId() << " last"); frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::ResponseLast}; - _rctx.service().sendMessage(_rctx.recipientId(), res_ptr, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(res_ptr), flags); } } diff --git a/solid/frame/mprpc/test/test_clientfrontback_upload.cpp b/solid/frame/mprpc/test/test_clientfrontback_upload.cpp index c5ca7c38..dcf15f6f 100644 --- a/solid/frame/mprpc/test/test_clientfrontback_upload.cpp +++ b/solid/frame/mprpc/test/test_clientfrontback_upload.cpp @@ -43,7 +43,7 @@ frame::mprpc::ServiceT* pmprpc_front_server = nullptr; atomic expect_count(0); promise prom; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; namespace back { struct Request; @@ -52,13 +52,11 @@ struct Request; namespace front { struct Request : frame::mprpc::Message { - string name_; - mutable ifstream ifs_; - ostringstream oss_; + string name_; + mutable ifstream ifs_; + mutable ostringstream oss_; - Request() - { - } + Request() = default; Request(const string& _name) : name_(_name) @@ -93,13 +91,11 @@ struct Request : frame::mprpc::Message { }; struct Response : frame::mprpc::Message { - uint32_t error_ = -1; - frame::mprpc::RecipientId recipient_id_; - frame::mprpc::MessagePointerT req_ptr_; + uint32_t error_ = -1; + frame::mprpc::RecipientId recipient_id_; + mutable frame::mprpc::RecvMessagePointerT req_ptr_; - Response() - { - } + Response() = default; Response(Request& _req) : frame::mprpc::Message(_req) @@ -116,19 +112,21 @@ struct Response : frame::mprpc::Message { } }; -using RequestPointerT = solid::frame::mprpc::MessagePointerT; -using ResponsePointerT = solid::frame::mprpc::MessagePointerT; +using SendRequestPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvRequestPointerT = solid::frame::mprpc::RecvMessagePointerT; +using SendResponsePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvResponsePointerT = solid::frame::mprpc::RecvMessagePointerT; void on_server_receive_first_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror); void on_server_response( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "front: on message"); @@ -136,8 +134,8 @@ void on_server_response( void on_client_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "front: on message"); @@ -145,8 +143,8 @@ void on_client_request( void on_client_response( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "front: on message"); @@ -154,8 +152,8 @@ void on_client_response( void on_client_receive_first_response( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror); } // namespace front @@ -163,16 +161,14 @@ void on_client_receive_first_response( namespace back { struct Request : frame::mprpc::Message { - string name_; - mutable istringstream iss_; - ofstream ofs_; - ostringstream oss_; - frame::mprpc::RecipientId recipient_id_; - frame::mprpc::MessagePointerT res_ptr_; - - Request() - { - } + string name_; + mutable istringstream iss_; + ofstream ofs_; + ostringstream oss_; + frame::mprpc::RecipientId recipient_id_; + mutable front::RecvResponsePointerT res_ptr_; + + Request() = default; Request(const string& _name) : name_(_name) @@ -206,23 +202,22 @@ struct Request : frame::mprpc::Message { } }; -using RequestPointerT = solid::frame::mprpc::MessagePointerT; +using SendRequestPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvRequestPointerT = solid::frame::mprpc::RecvMessagePointerT; struct Response : frame::mprpc::Message { - uint32_t error_ = -1; - RequestPointerT req_ptr_; - bool send_response_ = false; + uint32_t error_ = -1; + RecvRequestPointerT req_ptr_; + mutable bool send_response_ = false; - Response() - { - } + Response() = default; Response(Request& _req) : frame::mprpc::Message(_req) { } - Response(RequestPointerT&& _req_ptr) + Response(RecvRequestPointerT&& _req_ptr) : frame::mprpc::Message(*_req_ptr) , req_ptr_(std::move(_req_ptr)) @@ -240,18 +235,19 @@ struct Response : frame::mprpc::Message { } }; -using ResponsePointerT = solid::frame::mprpc::MessagePointerT; +using SendResponsePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvResponsePointerT = solid::frame::mprpc::RecvMessagePointerT; void on_server_receive_first_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror); void on_server_response( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "back: on message"); @@ -259,8 +255,8 @@ void on_server_response( void on_client_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "back: on message"); @@ -268,8 +264,8 @@ void on_client_request( void on_client_response( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "back: on message"); @@ -518,7 +514,7 @@ int test_clientfrontback_upload(int argc, char* argv[]) auto msg_ptr = frame::mprpc::make_message(f); msg_ptr->ifs_.open(string("client_storage/") + f); - mprpc_front_client.sendRequest({"localhost"}, msg_ptr, front::on_client_receive_first_response); + mprpc_front_client.sendRequest({"localhost"}, std::move(msg_ptr), front::on_client_receive_first_response); } auto fut = prom.get_future(); @@ -628,16 +624,16 @@ void check_files(const vector& _file_vec, const char* _path_prefix_clien namespace back { void on_client_receive_response( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror); + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, + frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror); void on_client_receive_first_response( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror); + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, + frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror); } // namespace back namespace front { @@ -648,8 +644,8 @@ namespace front { void on_client_receive_last_response( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(_rrecv_msg_ptr); @@ -662,8 +658,8 @@ void on_client_receive_last_response( void on_client_receive_response( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(_rrecv_msg_ptr); @@ -675,33 +671,40 @@ void on_client_receive_response( frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::ResponsePart, frame::mprpc::MessageFlagsE::AwaitResponse}; _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, on_client_receive_response, flags); flags.reset(frame::mprpc::MessageFlagsE::AwaitResponse); - _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(_rsent_msg_ptr), flags); } else { solid_log(logger, Verbose, "front: sending " << _rsent_msg_ptr->name_ << " to " << _rctx.recipientId() << " last"); frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::ResponseLast, frame::mprpc::MessageFlagsE::AwaitResponse}; - _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, on_client_receive_last_response, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(_rsent_msg_ptr), on_client_receive_last_response, flags); } } void on_client_receive_first_response( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(_rrecv_msg_ptr); solid_check(_rrecv_msg_ptr->error_ == 0); - _rsent_msg_ptr->name_.clear(); - _rsent_msg_ptr->header(_rrecv_msg_ptr->header()); + { + auto sent_msg_ptr = _rsent_msg_ptr.collapse(); + solid_check(sent_msg_ptr); + solid_check(!_rsent_msg_ptr); + sent_msg_ptr->name_.clear(); + sent_msg_ptr->header(_rrecv_msg_ptr->header()); + + _rsent_msg_ptr = std::move(sent_msg_ptr); + } if (!_rsent_msg_ptr->ifs_.eof()) { solid_log(logger, Verbose, "front: sending " << _rsent_msg_ptr->name_ << " to " << _rctx.recipientId()); frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::ResponsePart, frame::mprpc::MessageFlagsE::AwaitResponse}; _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, on_client_receive_response, flags); flags.reset(frame::mprpc::MessageFlagsE::AwaitResponse); - _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(_rsent_msg_ptr), flags); } else { solid_log(logger, Verbose, "front: sending " << _rsent_msg_ptr->name_ << " to " << _rctx.recipientId() << " last"); frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::ResponseLast, frame::mprpc::MessageFlagsE::AwaitResponse}; @@ -714,15 +717,15 @@ void on_client_receive_first_response( //----------------------------------------------------------------------------- void on_server_receive_request( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + front::SendResponsePointerT& _rsent_msg_ptr, + front::RecvRequestPointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "front: received request for: " << _rsent_msg_ptr->req_ptr_->name_); if (!_rrecv_msg_ptr->isResponseLast()) { - frame::mprpc::MessagePointerT req_ptr = frame::mprpc::make_message(); + auto req_ptr = frame::mprpc::make_message(); req_ptr->header(_rsent_msg_ptr->req_ptr_->header()); req_ptr->iss_.str(_rrecv_msg_ptr->oss_.str()); @@ -731,32 +734,32 @@ void on_server_receive_request( req_ptr->recipient_id_ = _rctx.recipientId(); req_ptr->res_ptr_ = std::move(_rsent_msg_ptr->req_ptr_->res_ptr_); req_ptr->res_ptr_->header(_rrecv_msg_ptr->header()); - pmprpc_back_client->sendMessage(_rsent_msg_ptr->recipient_id_, req_ptr, back::on_client_receive_response, flags); + pmprpc_back_client->sendMessage(_rsent_msg_ptr->recipient_id_, std::move(req_ptr), back::on_client_receive_response, flags); solid_log(logger, Verbose, "front: forward request with wait response"); } else { frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::ResponsePart}; - pmprpc_back_client->sendMessage(_rsent_msg_ptr->recipient_id_, req_ptr, flags); + pmprpc_back_client->sendMessage(_rsent_msg_ptr->recipient_id_, std::move(req_ptr), flags); _rsent_msg_ptr->req_ptr_->res_ptr_ = frame::mprpc::make_message(); solid_log(logger, Verbose, "front: forward request without wait response"); } } else { solid_check(_rsent_msg_ptr->req_ptr_->res_ptr_); - frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::AwaitResponse, frame::mprpc::MessageFlagsE::ResponseLast}; - frame::mprpc::MessagePointerT req_ptr = std::move(_rsent_msg_ptr->req_ptr_); + frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::AwaitResponse, frame::mprpc::MessageFlagsE::ResponseLast}; + frame::mprpc::RecvMessagePointerT req_ptr = std::move(_rsent_msg_ptr->req_ptr_); req_ptr->res_ptr_->header(_rrecv_msg_ptr->header()); req_ptr->recipient_id_ = _rctx.recipientId(); - pmprpc_back_client->sendMessage(_rsent_msg_ptr->recipient_id_, req_ptr, back::on_client_receive_response, flags); + pmprpc_back_client->sendMessage(_rsent_msg_ptr->recipient_id_, std::move(req_ptr), back::on_client_receive_response, flags); solid_log(logger, Verbose, "front: forward last request with wait response"); } } // front server upload entry point - called only once at the begining of every file upload void on_server_receive_first_request( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + front::SendRequestPointerT& _rsent_msg_ptr, + front::RecvRequestPointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_check(_rrecv_msg_ptr); @@ -770,7 +773,7 @@ void on_server_receive_first_request( req_ptr->recipient_id_ = _rctx.recipientId(); req_ptr->res_ptr_ = frame::mprpc::make_message(*_rrecv_msg_ptr); - pmprpc_back_client->sendRequest({"localhost"}, req_ptr, back::on_client_receive_first_response, flags); + pmprpc_back_client->sendRequest({"localhost"}, std::move(req_ptr), back::on_client_receive_first_response, flags); } } // namespace front @@ -778,40 +781,44 @@ void on_server_receive_first_request( namespace back { void on_client_receive_first_response( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "back: received response on back client for: " << _rsent_msg_ptr->name_); - frame::mprpc::MessagePointerT res_ptr = std::move(_rsent_msg_ptr->res_ptr_); - frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::AwaitResponse, frame::mprpc::MessageFlagsE::Response}; + frame::mprpc::RecvMessagePointerT res_ptr = std::move(_rsent_msg_ptr->res_ptr_); + frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::AwaitResponse, frame::mprpc::MessageFlagsE::Response}; _rsent_msg_ptr->res_ptr_ = frame::mprpc::make_message(); res_ptr->error_ = _rrecv_msg_ptr->error_; res_ptr->recipient_id_ = _rctx.recipientId(); - res_ptr->req_ptr_ = std::move(_rsent_msg_ptr); + res_ptr->req_ptr_ = _rsent_msg_ptr.collapse(); + solid_check(!_rsent_msg_ptr); + solid_check(res_ptr->req_ptr_); res_ptr->req_ptr_->header(_rrecv_msg_ptr->header()); // forward the message to front client - pmprpc_front_server->sendMessage(res_ptr->req_ptr_->recipient_id_, res_ptr, front::on_server_receive_request, flags); + pmprpc_front_server->sendMessage(res_ptr->req_ptr_->recipient_id_, std::move(res_ptr), front::on_server_receive_request, flags); } void on_client_receive_response( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, - frame::mprpc::MessagePointerT& _rrecv_msg_ptr, - ErrorConditionT const& _rerror) + frame::mprpc::ConnectionContext& _rctx, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "back: received response on back client for: " << _rsent_msg_ptr->name_); - frame::mprpc::MessagePointerT res_ptr = std::move(_rsent_msg_ptr->res_ptr_); - frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::Response}; + frame::mprpc::RecvMessagePointerT res_ptr = std::move(_rsent_msg_ptr->res_ptr_); + frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::Response}; res_ptr->error_ = _rrecv_msg_ptr->error_; res_ptr->recipient_id_ = _rctx.recipientId(); - res_ptr->req_ptr_ = std::move(_rsent_msg_ptr); + res_ptr->req_ptr_ = _rsent_msg_ptr.collapse(); + solid_check(!_rsent_msg_ptr); + solid_check(res_ptr->req_ptr_); res_ptr->req_ptr_->header(_rrecv_msg_ptr->header()); // forward the message to front client - pmprpc_front_server->sendMessage(res_ptr->req_ptr_->recipient_id_, res_ptr, flags); + pmprpc_front_server->sendMessage(res_ptr->req_ptr_->recipient_id_, std::move(res_ptr), flags); } //----------------------------------------------------------------------------- @@ -819,8 +826,8 @@ void on_client_receive_response( //----------------------------------------------------------------------------- void on_server_receive_request( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { // the server will keep receiving new Requests @@ -836,7 +843,7 @@ void on_server_receive_request( _rsent_msg_ptr->send_response_ = false; auto res_ptr = frame::mprpc::make_message(*_rrecv_msg_ptr); res_ptr->error_ = 0; - auto err = _rctx.service().sendMessage(_rctx.recipientId(), res_ptr, {frame::mprpc::MessageFlagsE::Response}); + auto err = _rctx.service().sendMessage(_rctx.recipientId(), std::move(res_ptr), {frame::mprpc::MessageFlagsE::Response}); solid_log(logger, Verbose, "back: send response to: " << _rctx.recipientId() << " err: " << err.message()); } else { _rsent_msg_ptr->send_response_ = true; @@ -845,15 +852,15 @@ void on_server_receive_request( _rsent_msg_ptr->req_ptr_->ofs_.flush(); auto res_ptr = frame::mprpc::make_message(*_rrecv_msg_ptr); res_ptr->error_ = 0; - auto err = _rctx.service().sendMessage(_rctx.recipientId(), res_ptr, {frame::mprpc::MessageFlagsE::Response}); + auto err = _rctx.service().sendMessage(_rctx.recipientId(), std::move(res_ptr), {frame::mprpc::MessageFlagsE::Response}); solid_log(logger, Verbose, "back: send last response to: " << _rctx.recipientId() << " err: " << err.message()); } } void on_server_receive_first_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { string path = string("server_storage") + '/' + _rrecv_msg_ptr->name_; @@ -865,7 +872,7 @@ void on_server_receive_first_request( auto res_ptr = frame::mprpc::make_message(std::move(_rrecv_msg_ptr)); res_ptr->error_ = 0; const frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::AwaitResponse, frame::mprpc::MessageFlagsE::Response}; - _rctx.service().sendMessage(_rctx.recipientId(), res_ptr, on_server_receive_request, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(res_ptr), on_server_receive_request, flags); } } // namespace back diff --git a/solid/frame/mprpc/test/test_clientserver_basic.cpp b/solid/frame/mprpc/test/test_clientserver_basic.cpp index 2cde9458..babbcb14 100644 --- a/solid/frame/mprpc/test/test_clientserver_basic.cpp +++ b/solid/frame/mprpc/test/test_clientserver_basic.cpp @@ -39,7 +39,7 @@ struct InitStub { frame::mprpc::MessageFlagsT flags; }; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; InitStub initarray[] = { {100000, 0}, @@ -61,11 +61,11 @@ InitStub initarray[] = { std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -std::atomic crtwriteidx(0); -std::atomic crtreadidx(0); -std::atomic crtbackidx(0); -std::atomic crtackidx(0); -std::atomic writecount(0); +std::atomic crtwriteidx(0); +std::atomic crtreadidx(0); +std::atomic crtbackidx(0); +std::atomic crtackidx(0); +std::atomic writecount(0); size_t connection_count(0); bool running = true; @@ -83,6 +83,8 @@ size_t real_size(size_t _sz) } struct Message : frame::mprpc::Message { + static atomic_uint32_t create_count; + uint32_t idx; std::string str; mutable bool serialized; @@ -91,12 +93,14 @@ struct Message : frame::mprpc::Message { : idx(_idx) , serialized(false) { + ++create_count; solid_dbg(generic_logger, Info, "CREATE ---------------- " << this << " idx = " << idx); init(); } Message() : serialized(false) { + ++create_count; solid_dbg(generic_logger, Info, "CREATE ---------------- " << this); } ~Message() override @@ -153,7 +157,10 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +atomic_uint32_t Message::create_count{0}; + +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void client_connection_stop(frame::mprpc::ConnectionContext& _rctx) { @@ -188,7 +195,7 @@ void server_connection_start(frame::mprpc::ConnectionContext& _rctx) void client_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " " << crtbackidx << " " << writecount); @@ -223,7 +230,7 @@ void client_complete_message( void server_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& /*_rerror*/) { if (_rrecv_msg_ptr) { @@ -241,17 +248,19 @@ void server_complete_message( solid_check(_rctx.recipientId().isValidConnection(), "Connection id should not be invalid!"); - ErrorConditionT err = use_context_on_response ? _rctx.service().sendResponse(_rctx, _rrecv_msg_ptr) : _rctx.service().sendResponse(_rctx.recipientId(), _rrecv_msg_ptr); + ErrorConditionT err = use_context_on_response ? _rctx.service().sendResponse(_rctx, std::move(_rrecv_msg_ptr)) : _rctx.service().sendResponse(_rctx.recipientId(), std::move(_rrecv_msg_ptr)); solid_check(!err, "Connection id should not be invalid: " << err.message()); ++crtreadidx; solid_dbg(generic_logger, Info, crtreadidx); - if (crtwriteidx < writecount) { + if (crtwriteidx < writecount and pmprpcclient) { err = pmprpcclient->sendMessage( {""}, frame::mprpc::make_message(crtwriteidx++), initarray[crtwriteidx % initarraysize].flags | frame::mprpc::MessageFlagsE::AwaitResponse); solid_check(!err, "Connection id should not be invalid! " << err.message()); + } else { + solid_check(pmprpcclient, "pmprpcclient should not be nullptr"); } } if (_rsent_msg_ptr) { @@ -265,7 +274,7 @@ int test_clientserver_basic(int argc, char* argv[]) { solid::log_start(std::cerr, {".*:EWXS"}); - // solid::log_start(std::cerr, {"solid::frame::mprpc.*:EWX", "\\*:VIEWX"}); + // solid::log_start(std::cerr, {"solid::frame::mprpc.*:VIEWX", "\\*:VIEWX"}); size_t max_per_pool_connection_count = 1; @@ -450,6 +459,7 @@ int test_clientserver_basic(int argc, char* argv[]) std::cout << "Transfered size = " << (transfered_size * 2) / 1024 << "KB" << endl; std::cout << "Transfered count = " << transfered_count << endl; std::cout << "Connection count = " << connection_count << endl; + std::cout << "Message create count = " << Message::create_count << endl; return 0; } diff --git a/solid/frame/mprpc/test/test_clientserver_cancel_client.cpp b/solid/frame/mprpc/test/test_clientserver_cancel_client.cpp index 5e1be5a2..2cdc3d9e 100644 --- a/solid/frame/mprpc/test/test_clientserver_cancel_client.cpp +++ b/solid/frame/mprpc/test/test_clientserver_cancel_client.cpp @@ -44,7 +44,7 @@ struct InitStub { frame::mprpc::MessageFlagsT flags; }; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; // NOTE: if making more messages non-cancelable, please consider to change the value of expected_transfered_count @@ -73,8 +73,8 @@ typedef std::vector MessageIdVectorT; std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -std::atomic crtwriteidx(0); -std::atomic crtreadidx(0); +std::atomic crtwriteidx(0); +std::atomic crtreadidx(0); // std::atomic crtbackidx(0); // std::atomic crtackidx(0); std::atomic writecount(0); @@ -167,7 +167,8 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void client_connection_stop(frame::mprpc::ConnectionContext& _rctx) { @@ -192,7 +193,7 @@ void server_connection_start(frame::mprpc::ConnectionContext& _rctx) solid_dbg(generic_logger, Info, _rctx.recipientId()); } -void client_receive_message(frame::mprpc::ConnectionContext& _rctx, MessagePointerT& _rmsgptr) +void client_receive_message(frame::mprpc::ConnectionContext& _rctx, RecvMessagePointerT& _rmsgptr) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -202,7 +203,7 @@ void client_receive_message(frame::mprpc::ConnectionContext& _rctx, MessagePoint void client_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& /*_rsent_msg_ptr*/, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& /*_rsent_msg_ptr*/, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " error = " << _rerror.message()); @@ -211,7 +212,7 @@ void client_complete_message( } } -void server_receive_message(frame::mprpc::ConnectionContext& _rctx, MessagePointerT& _rmsgptr) +void server_receive_message(frame::mprpc::ConnectionContext& _rctx, RecvMessagePointerT& _rmsgptr) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " message id on sender " << _rmsgptr->senderRequestId()); @@ -235,13 +236,15 @@ void server_receive_message(frame::mprpc::ConnectionContext& _rctx, MessagePoint transfered_size += _rmsgptr->str.size(); ++transfered_count; - if (crtreadidx == 0) { + if (crtreadidx == 0 and pmprpcclient) { solid_dbg(generic_logger, Info, "canceling all messages"); lock_guard lock(mtx); for (auto& msguid : message_uid_vec) { solid_dbg(generic_logger, Info, "Cancel message: " << msguid); pmprpcclient->cancelMessage(recipient_id, msguid); } + } else { + solid_check(pmprpcclient, "pmprpcclient should not be nullptr"); } ++crtreadidx; @@ -255,7 +258,7 @@ void server_receive_message(frame::mprpc::ConnectionContext& _rctx, MessagePoint void server_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& /*_rsent_msg_ptr*/, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& /*_rsent_msg_ptr*/, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& /*_rerror*/) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -407,7 +410,7 @@ int test_clientserver_cancel_client(int argc, char* argv[]) frame::mprpc::MessageId msguid; ErrorConditionT err = mprpcclient.sendMessage( - {"localhost"}, frame::mprpc::MessagePointerT<>(frame::mprpc::make_message(crtwriteidx)), + {"localhost"}, frame::mprpc::make_message(crtwriteidx), recipient_id, msguid); diff --git a/solid/frame/mprpc/test/test_clientserver_cancel_server.cpp b/solid/frame/mprpc/test/test_clientserver_cancel_server.cpp index 76a52cd0..801d56b1 100644 --- a/solid/frame/mprpc/test/test_clientserver_cancel_server.cpp +++ b/solid/frame/mprpc/test/test_clientserver_cancel_server.cpp @@ -38,7 +38,7 @@ using SecureContextT = frame::aio::openssl::Context; namespace { -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -72,7 +72,7 @@ typedef std::vector MessageIdVectorT; std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -std::atomic crtwriteidx(0); +std::atomic crtwriteidx(0); std::atomic crtbackidx(0); std::atomic crtackidx(0); std::atomic writecount(0); @@ -162,7 +162,8 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void client_connection_stop(frame::mprpc::ConnectionContext& _rctx) { @@ -187,7 +188,7 @@ void server_connection_start(frame::mprpc::ConnectionContext& _rctx) solid_dbg(generic_logger, Info, _rctx.recipientId()); } -void client_receive_message(frame::mprpc::ConnectionContext& _rctx, MessagePointerT& _rmsgptr) +void client_receive_message(frame::mprpc::ConnectionContext& _rctx, RecvMessagePointerT& _rmsgptr) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -200,13 +201,15 @@ void client_receive_message(frame::mprpc::ConnectionContext& _rctx, MessagePoint transfered_size += _rmsgptr->str.size(); ++transfered_count; - if (crtbackidx == 0u) { + if (crtbackidx == 0u and pmprpcclient) { solid_dbg(generic_logger, Info, "canceling all messages"); lock_guard lock(mtx); for (const auto& msguid : message_uid_vec) { solid_dbg(generic_logger, Info, "Cancel message: " << msguid); pmprpcserver->cancelMessage(recipient_id, msguid); } + } else { + solid_check(pmprpcclient, "pmprpcclient should not be nullptr"); } ++crtbackidx; @@ -220,7 +223,7 @@ void client_receive_message(frame::mprpc::ConnectionContext& _rctx, MessagePoint void client_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -237,7 +240,7 @@ void client_complete_message( void server_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& /*_rsent_msg_ptr*/, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& /*_rsent_msg_ptr*/, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& /*_rerror*/) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -263,7 +266,7 @@ void server_complete_message( frame::mprpc::MessageId msguid; ErrorConditionT err = _rctx.service().sendMessage( - {recipient_id}, frame::mprpc::MessagePointerT<>(frame::mprpc::make_message(crtwriteidx)), + {recipient_id}, frame::mprpc::make_message(crtwriteidx), msguid); solid_check(!err, "Connection id should not be invalid! " << err.message()); @@ -416,7 +419,7 @@ int test_clientserver_cancel_server(int argc, char* argv[]) // Step 1. auto msgptr(frame::mprpc::make_message(0)); mprpcclient.sendMessage( - {"localhost"}, msgptr, + {"localhost"}, std::move(msgptr), initarray[0].flags); } diff --git a/solid/frame/mprpc/test/test_clientserver_delayed.cpp b/solid/frame/mprpc/test/test_clientserver_delayed.cpp index 736c2c33..3a29ba82 100644 --- a/solid/frame/mprpc/test/test_clientserver_delayed.cpp +++ b/solid/frame/mprpc/test/test_clientserver_delayed.cpp @@ -32,7 +32,7 @@ using AioSchedulerT = frame::Scheduler, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -150,7 +150,8 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void client_connection_stop(frame::mprpc::ConnectionContext& _rctx) { @@ -177,7 +178,7 @@ void server_connection_start(frame::mprpc::ConnectionContext& _rctx) void client_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -229,7 +230,7 @@ void client_complete_message( void server_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& /*_rerror*/) { if (_rrecv_msg_ptr) { @@ -247,7 +248,7 @@ void server_complete_message( if (_rctx.recipientId().isInvalidConnection()) { solid_throw("Connection id should not be invalid!"); } - ErrorConditionT err = _rctx.service().sendResponse(_rctx.recipientId(), _rrecv_msg_ptr); + ErrorConditionT err = _rctx.service().sendResponse(_rctx.recipientId(), std::move(_rrecv_msg_ptr)); solid_check(!err, "Connection id should not be invalid! " << err.message()); } @@ -357,24 +358,21 @@ int test_clientserver_delayed(int argc, char* argv[]) } } { - MessagePointerT msgptr(frame::mprpc::make_message(0)); err = mprpcclient.sendMessage( - {"localhost"}, msgptr); + {"localhost"}, frame::mprpc::make_message(0)); ++writecount; } { - MessagePointerT msgptr(frame::mprpc::make_message(1)); err = mprpcclient.sendMessage( - {"localhost"}, msgptr, {frame::mprpc::MessageFlagsE::OneShotSend}); + {"localhost"}, frame::mprpc::make_message(1), {frame::mprpc::MessageFlagsE::OneShotSend}); //++writecount; // this message should not be sent } { - MessagePointerT msgptr(frame::mprpc::make_message(2)); err = mprpcclient.sendMessage( - {"localhost"}, msgptr, {frame::mprpc::MessageFlagsE::AwaitResponse}); + {"localhost"}, frame::mprpc::make_message(2), {frame::mprpc::MessageFlagsE::AwaitResponse}); ++writecount; } diff --git a/solid/frame/mprpc/test/test_clientserver_download.cpp b/solid/frame/mprpc/test/test_clientserver_download.cpp index 90a8dd2e..c417564a 100644 --- a/solid/frame/mprpc/test/test_clientserver_download.cpp +++ b/solid/frame/mprpc/test/test_clientserver_download.cpp @@ -41,7 +41,7 @@ using SecureContextT = frame::aio::openssl::Context; namespace { LoggerT logger("test"); -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; atomic expect_count(0); promise prom; @@ -49,9 +49,9 @@ promise prom; struct Response; struct Request : frame::mprpc::Message { - string name_; - ofstream ofs_; - bool send_request_; + string name_; + mutable ofstream ofs_; // TODO: find a better solution + mutable bool send_request_; Request(Response& _rmsg); @@ -119,8 +119,10 @@ struct Response : frame::mprpc::Message { } }; -using RequestPointerT = solid::frame::mprpc::MessagePointerT; -using ResponsePointerT = solid::frame::mprpc::MessagePointerT; +using SendRequestPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvRequestPointerT = solid::frame::mprpc::RecvMessagePointerT; +using SendResponsePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvResponsePointerT = solid::frame::mprpc::RecvMessagePointerT; Request::Request(Response& _rmsg) : frame::mprpc::Message(_rmsg) @@ -130,8 +132,8 @@ Request::Request(Response& _rmsg) void on_client_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "on message"); @@ -139,8 +141,8 @@ void on_client_request( void on_client_response( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "on message"); @@ -148,20 +150,20 @@ void on_client_response( void on_client_receive_response( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror); void on_server_receive_first_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror); void on_server_response( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "on message"); @@ -324,7 +326,7 @@ int test_clientserver_download(int argc, char* argv[]) auto msg_ptr = frame::mprpc::make_message(f); msg_ptr->ofs_.open(string("client_storage/") + f); - mprpc_client.sendRequest({"localhost"}, msg_ptr, on_client_receive_response); + mprpc_client.sendRequest({"localhost"}, std::move(msg_ptr), on_client_receive_response); } auto fut = prom.get_future(); @@ -436,18 +438,18 @@ void check_files(const vector& _file_vec, const char* _path_prefix_clien void on_client_receive_response( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(_rrecv_msg_ptr); solid_check(_rrecv_msg_ptr->error_ == 0); - - string s = _rrecv_msg_ptr->oss_.str(); - _rsent_msg_ptr->ofs_.write(s.data(), s.size()); - - solid_log(logger, Verbose, "received response data of size: " << s.size()); + { + string s = _rrecv_msg_ptr->oss_.str(); + _rsent_msg_ptr->ofs_.write(s.data(), s.size()); + solid_log(logger, Verbose, "received response data of size: " << s.size()); + } frame::mprpc::MessageFlagsT flags; @@ -455,7 +457,7 @@ void on_client_receive_response( if (_rsent_msg_ptr->send_request_) { _rsent_msg_ptr->send_request_ = false; auto res_ptr = frame::mprpc::make_message(*_rrecv_msg_ptr); - auto err = _rctx.service().sendMessage(_rctx.recipientId(), res_ptr, {frame::mprpc::MessageFlagsE::Response}); + auto err = _rctx.service().sendMessage(_rctx.recipientId(), std::move(res_ptr), {frame::mprpc::MessageFlagsE::Response}); solid_log(logger, Verbose, "send response to: " << _rctx.recipientId() << " err: " << err.message()); } else { _rsent_msg_ptr->send_request_ = true; @@ -473,8 +475,8 @@ void on_client_receive_response( void on_server_receive_request( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(_rrecv_msg_ptr); @@ -484,18 +486,18 @@ void on_server_receive_request( frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::ResponsePart, frame::mprpc::MessageFlagsE::AwaitResponse}; _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, on_server_receive_request, flags); flags.reset(frame::mprpc::MessageFlagsE::AwaitResponse); - _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(_rsent_msg_ptr), flags); } else { solid_log(logger, Verbose, "Sending to " << _rctx.recipientId() << " last"); frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::ResponseLast}; - _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(_rsent_msg_ptr), flags); } } void on_server_receive_first_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { string path = string("server_storage") + '/' + _rrecv_msg_ptr->name_; @@ -507,17 +509,18 @@ void on_server_receive_first_request( solid_check(res_ptr->ifs_, "failed open file: " << path); if (!res_ptr->ifs_.eof()) { + SendResponsePointerT send_ptr{std::move(res_ptr)}; solid_log(logger, Verbose, "Sending " << _rrecv_msg_ptr->name_ << " to " << _rctx.recipientId()); frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::ResponsePart, frame::mprpc::MessageFlagsE::AwaitResponse}; - auto error = _rctx.service().sendMessage(_rctx.recipientId(), res_ptr, on_server_receive_request, flags); + auto error = _rctx.service().sendMessage(_rctx.recipientId(), send_ptr, on_server_receive_request, flags); solid_check(!error, "failed send message: " << error.message()); flags.reset(frame::mprpc::MessageFlagsE::AwaitResponse); - error = _rctx.service().sendMessage(_rctx.recipientId(), res_ptr, flags); + error = _rctx.service().sendMessage(_rctx.recipientId(), std::move(send_ptr), flags); solid_check(!error, "failed send message: " << error.message()); } else { solid_log(logger, Verbose, "Sending " << _rsent_msg_ptr->name_ << " to " << _rctx.recipientId() << " last"); frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::ResponseLast}; - _rctx.service().sendMessage(_rctx.recipientId(), res_ptr, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(res_ptr), flags); } } diff --git a/solid/frame/mprpc/test/test_clientserver_idempotent.cpp b/solid/frame/mprpc/test/test_clientserver_idempotent.cpp index b8762b17..94ec7e4b 100644 --- a/solid/frame/mprpc/test/test_clientserver_idempotent.cpp +++ b/solid/frame/mprpc/test/test_clientserver_idempotent.cpp @@ -33,7 +33,7 @@ using AioSchedulerT = frame::Scheduler, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -153,7 +153,8 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void client_connection_stop(frame::mprpc::ConnectionContext& _rctx) { @@ -188,7 +189,7 @@ void server_connection_start(frame::mprpc::ConnectionContext& _rctx) void client_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -235,7 +236,7 @@ void client_complete_message( void server_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& /*_rerror*/) { if (_rrecv_msg_ptr) { @@ -260,7 +261,7 @@ void server_complete_message( solid_throw("Connection id should not be invalid!"); } - ErrorConditionT err = _rctx.service().sendResponse(_rctx.recipientId(), _rrecv_msg_ptr); + ErrorConditionT err = _rctx.service().sendResponse(_rctx.recipientId(), std::move(_rrecv_msg_ptr)); solid_check(!(err && err != frame::mprpc::error_service_stopping), "sendResponse should not fail: " << err.message()); } @@ -409,7 +410,7 @@ int test_clientserver_idempotent(int argc, char* argv[]) pmprpcclient = &mprpcclient; - std::vector msg_vec{ + std::vector msg_vec{ frame::mprpc::make_message(0), frame::mprpc::make_message(1), frame::mprpc::make_message(2), diff --git a/solid/frame/mprpc/test/test_clientserver_noserver.cpp b/solid/frame/mprpc/test/test_clientserver_noserver.cpp index 7d9a6d8c..f7a85bde 100644 --- a/solid/frame/mprpc/test/test_clientserver_noserver.cpp +++ b/solid/frame/mprpc/test/test_clientserver_noserver.cpp @@ -33,7 +33,7 @@ using SecureContextT = frame::aio::openssl::Context; namespace { -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -137,7 +137,8 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void client_connection_stop(frame::mprpc::ConnectionContext& _rctx) { @@ -154,7 +155,7 @@ void client_connection_start(frame::mprpc::ConnectionContext& _rctx) void client_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -268,10 +269,8 @@ int test_clientserver_noserver(int argc, char* argv[]) frame::mprpc::RecipientId recipient_id; frame::mprpc::MessageId message_id; { - MessagePointerT msgptr(frame::mprpc::make_message(0)); - err = mprpcclient.sendMessage( - {"localhost"}, msgptr, + {"localhost"}, frame::mprpc::make_message(0), recipient_id, message_id, {frame::mprpc::MessageFlagsE::AwaitResponse}); solid_check(!err); diff --git a/solid/frame/mprpc/test/test_clientserver_oneshot.cpp b/solid/frame/mprpc/test/test_clientserver_oneshot.cpp index cc4e3291..a39665ec 100644 --- a/solid/frame/mprpc/test/test_clientserver_oneshot.cpp +++ b/solid/frame/mprpc/test/test_clientserver_oneshot.cpp @@ -32,7 +32,7 @@ namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -46,10 +46,7 @@ std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); std::atomic crtwriteidx(0); -// std::atomic crtreadidx(0); -// std::atomic crtbackidx(0); std::atomic crtackidx(0); -// std::atomic writecount(0); size_t connection_count(0); @@ -136,7 +133,8 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void client_connection_stop(frame::mprpc::ConnectionContext& _rctx) { @@ -155,7 +153,7 @@ void client_connection_start(frame::mprpc::ConnectionContext& _rctx) void client_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " " << _rerror.message()); @@ -270,10 +268,8 @@ int test_clientserver_oneshot(int argc, char* argv[]) frame::mprpc::RecipientId recipient_id; frame::mprpc::MessageId message_id; { - MessagePointerT msgptr(frame::mprpc::make_message(0)); - err = mprpcclient.sendMessage( - {"localhost"}, msgptr, + {"localhost"}, frame::mprpc::make_message(0), recipient_id, message_id, {frame::mprpc::MessageFlagsE::AwaitResponse, frame::mprpc::MessageFlagsE::OneShotSend}); solid_check(!err, "" << err.message()); diff --git a/solid/frame/mprpc/test/test_clientserver_pause_read.cpp b/solid/frame/mprpc/test/test_clientserver_pause_read.cpp index fd4eb4b0..0f12eb47 100644 --- a/solid/frame/mprpc/test/test_clientserver_pause_read.cpp +++ b/solid/frame/mprpc/test/test_clientserver_pause_read.cpp @@ -39,7 +39,7 @@ struct InitStub { frame::mprpc::MessageFlagsT flags; }; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; InitStub initarray[] = { {100000, 0}, @@ -61,10 +61,10 @@ InitStub initarray[] = { std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -std::atomic crtwriteidx(0); -std::atomic crtreadidx(0); -std::atomic crtbackidx(0); -std::atomic crtackidx(0); +std::atomic crtwriteidx(0); +std::atomic crtreadidx(0); +std::atomic crtbackidx(0); +std::atomic crtackidx(0); size_t connection_count(0); bool running = true; @@ -155,7 +155,8 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void client_connection_stop(frame::mprpc::ConnectionContext& _rctx) { @@ -190,7 +191,7 @@ void server_connection_start(frame::mprpc::ConnectionContext& _rctx) void client_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " " << crtbackidx << " " << crtwriteidx); @@ -225,7 +226,7 @@ void client_complete_message( void server_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& /*_rerror*/) { if (_rrecv_msg_ptr) { @@ -243,7 +244,7 @@ void server_complete_message( solid_check(_rctx.recipientId().isValidConnection(), "Connection id should not be invalid!"); - const auto err = _rctx.service().sendResponse(_rctx, _rrecv_msg_ptr); + const auto err = _rctx.service().sendResponse(_rctx, std::move(_rrecv_msg_ptr)); solid_check(!err, "Connection id should not be invalid: " << err.message()); @@ -422,8 +423,8 @@ int test_clientserver_pause_read(int argc, char* argv[]) pmprpcclient = &mprpcclient; while (true) { - auto msg_ptr = frame::mprpc::make_message(crtwriteidx); - const auto err = mprpcclient.sendMessage( + SendMessagePointerT msg_ptr = frame::mprpc::make_message(crtwriteidx); + const auto err = mprpcclient.sendMessage( {""}, msg_ptr, initarray[crtwriteidx % initarraysize].flags | frame::mprpc::MessageFlagsE::AwaitResponse); if (!err) { diff --git a/solid/frame/mprpc/test/test_clientserver_pool.cpp b/solid/frame/mprpc/test/test_clientserver_pool.cpp new file mode 100644 index 00000000..d55372c3 --- /dev/null +++ b/solid/frame/mprpc/test/test_clientserver_pool.cpp @@ -0,0 +1,485 @@ +#include +#include +#include +#include + +#include "solid/frame/mprpc/mprpcmessage.hpp" +#include "solid/frame/mprpc/mprpcsocketstub_openssl.hpp" + +#include "solid/frame/mprpc/mprpccompression_snappy.hpp" +#include "solid/frame/mprpc/mprpcconfiguration.hpp" +#include "solid/frame/mprpc/mprpcprotocol_serialization_v3.hpp" +#include "solid/frame/mprpc/mprpcservice.hpp" + +#include "solid/frame/manager.hpp" +#include "solid/frame/scheduler.hpp" +#include "solid/frame/service.hpp" + +#include "solid/frame/aio/aioactor.hpp" +#include "solid/frame/aio/aiolistener.hpp" +#include "solid/frame/aio/aioreactor.hpp" +#include "solid/frame/aio/aioresolver.hpp" +#include "solid/frame/aio/aiotimer.hpp" + +#include "solid/utility/threadpool.hpp" + +#include "solid/system/exception.hpp" + +#include "solid/system/log.hpp" + +using namespace std; +using namespace solid; + +using AioSchedulerT = frame::Scheduler>; +using SecureContextT = frame::aio::openssl::Context; + +namespace { + +struct InitStub { + size_t size; + frame::mprpc::MessageFlagsT flags; +}; + +using CallPoolT = ThreadPool, Function64T>; + +InitStub initarray[] = { + {100000, 0}, + {2000, 0}, + {4000, 0}, + {8000, 0}, + {16000, 0}, + {32000, 0}, + {64000, 0}, + {128000, 0}, + {256000, 0}, + {512000, 0}, + {1024000, 0}, + {2048000, 0}, + {4096000, 0}, + {8192000, 0}, + {16384000, 0}}; + +std::string pattern; +const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); + +std::atomic crtwriteidx(0); +std::atomic crtreadidx(0); +std::atomic crtbackidx(0); +std::atomic crtackidx(0); +std::atomic writecount(0); + +size_t connection_count(0); +bool running = true; +mutex mtx; +condition_variable cnd; +frame::mprpc::Service* pmprpcclient = nullptr; +std::atomic transfered_size(0); +std::atomic transfered_count(0); +bool use_context_on_response = false; + +size_t real_size(size_t _sz) +{ + // offset + (align - (offset mod align)) mod align + return _sz + ((sizeof(uint64_t) - (_sz % sizeof(uint64_t))) % sizeof(uint64_t)); +} + +struct Message final : frame::mprpc::Message, Poolable { + static atomic_uint32_t create_count; + + uint32_t idx; + std::string str; + mutable bool serialized; + + Message(uint32_t _idx) + : idx(_idx) + , serialized(false) + { + ++create_count; + solid_dbg(generic_logger, Info, "CREATE ---------------- " << this << " idx = " << idx); + init_start(); + } + Message() + : serialized(false) + { + ++create_count; + solid_dbg(generic_logger, Info, "CREATE ---------------- " << this); + } + ~Message() override + { + solid_dbg(generic_logger, Info, "DELETE ---------------- " << this); + + solid_assert(serialized || this->isBackOnSender()); + } + + SOLID_REFLECT_V1(_rr, _rthis, _rctx) + { + using ReflectorT = decay_t; + + _rr.add(_rthis.idx, _rctx, 0, "idx").add(_rthis.str, _rctx, 1, "str"); + + if constexpr (ReflectorT::is_const_reflector) { + _rthis.serialized = true; + } + } + + void init() + { + idx = 0; + str.clear(); + serialized = false; + clearHeader(); + } + + void init(uint32_t _idx) + { + idx = _idx; + str.clear(); + serialized = false; + init_start(); + clearHeader(); + } + + void init_start() + { + const size_t sz = real_size(initarray[idx % initarraysize].size); + str.resize(sz); + const size_t count = sz / sizeof(uint64_t); + uint64_t* pu = reinterpret_cast(const_cast(str.data())); + const uint64_t* pup = reinterpret_cast(pattern.data()); + const size_t pattern_size = pattern.size() / sizeof(uint64_t); + for (uint64_t i = 0; i < count; ++i) { + pu[i] = pup[(idx + i) % pattern_size]; // pattern[i % pattern.size()]; + } + } + + bool check() const + { + const size_t sz = real_size(initarray[idx % initarraysize].size); + solid_dbg(generic_logger, Info, "str.size = " << str.size() << " should be equal to " << sz); + if (sz != str.size()) { + return false; + } + // return true; + const size_t count = sz / sizeof(uint64_t); + const uint64_t* pu = reinterpret_cast(str.data()); + const uint64_t* pup = reinterpret_cast(pattern.data()); + const size_t pattern_size = pattern.size() / sizeof(uint64_t); + + for (uint64_t i = 0; i < count; ++i) { + if (pu[i] != pup[(i + idx) % pattern_size]) { + solid_throw("Message check failed."); + return false; + } + } + return true; + } +}; + +atomic_uint32_t Message::create_count{0}; + +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; + +void client_connection_stop(frame::mprpc::ConnectionContext& _rctx) +{ + solid_dbg(generic_logger, Info, _rctx.recipientId() << " error: " << _rctx.error().message()); + if (!running) { + ++connection_count; + } +} + +void client_connection_start(frame::mprpc::ConnectionContext& _rctx) +{ + solid_dbg(generic_logger, Info, _rctx.recipientId()); + auto lambda = [](frame::mprpc::ConnectionContext&, ErrorConditionT const& _rerror) { + solid_dbg(generic_logger, Info, "enter active error: " << _rerror.message()); + }; + _rctx.service().connectionNotifyEnterActiveState(_rctx.recipientId(), lambda); +} + +void server_connection_stop(frame::mprpc::ConnectionContext& _rctx) +{ + solid_dbg(generic_logger, Info, _rctx.recipientId() << " error: " << _rctx.error().message()); +} + +void server_connection_start(frame::mprpc::ConnectionContext& _rctx) +{ + solid_dbg(generic_logger, Info, _rctx.recipientId()); + auto lambda = [](frame::mprpc::ConnectionContext&, ErrorConditionT const& _rerror) { + solid_dbg(generic_logger, Info, "enter active error: " << _rerror.message()); + }; + _rctx.service().connectionNotifyEnterActiveState(_rctx.recipientId(), lambda); +} + +void client_complete_message( + frame::mprpc::ConnectionContext& _rctx, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) +{ + solid_dbg(generic_logger, Info, _rctx.recipientId() << " " << crtbackidx << " " << writecount); + + if (_rsent_msg_ptr) { + if (!_rerror) { + ++crtackidx; + } + } + if (_rrecv_msg_ptr) { + if (!_rrecv_msg_ptr->check()) { + solid_throw("Message check failed."); + } + + // cout<< _rmsgptr->str.size()<<'\n'; + transfered_size += _rrecv_msg_ptr->str.size(); + ++transfered_count; + + if (!_rrecv_msg_ptr->isBackOnSender()) { + solid_throw("Message not back on sender!."); + } + + ++crtbackidx; + + if (crtbackidx == writecount) { + lock_guard lock(mtx); + running = false; + cnd.notify_one(); + } + } +} + +void server_complete_message( + frame::mprpc::ConnectionContext& _rctx, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, + ErrorConditionT const& /*_rerror*/) +{ + if (_rrecv_msg_ptr) { + solid_dbg(generic_logger, Info, _rctx.recipientId() << " received message with id on sender " << _rrecv_msg_ptr->senderRequestId() << " " << crtreadidx << " " << writecount); + + if (!_rrecv_msg_ptr->check()) { + solid_throw("Message check failed."); + } + + if (!_rrecv_msg_ptr->isOnPeer()) { + solid_throw("Message not on peer!."); + } + + // send message back + + solid_check(_rctx.recipientId().isValidConnection(), "Connection id should not be invalid!"); + + ErrorConditionT err = use_context_on_response ? _rctx.service().sendResponse(_rctx, std::move(_rrecv_msg_ptr)) : _rctx.service().sendResponse(_rctx.recipientId(), std::move(_rrecv_msg_ptr)); + + solid_check(!err, "Connection id should not be invalid: " << err.message()); + + ++crtreadidx; + solid_dbg(generic_logger, Info, crtreadidx); + if (crtwriteidx < writecount and pmprpcclient) { + err = pmprpcclient->sendMessage( + {""}, frame::mprpc::make_pool_message(crtwriteidx++), + initarray[crtwriteidx % initarraysize].flags | frame::mprpc::MessageFlagsE::AwaitResponse); + solid_check(!err, "Connection id should not be invalid! " << err.message()); + } else { + solid_check(pmprpcclient, "pmprpcclient should not be nullptr"); + } + } + if (_rsent_msg_ptr) { + solid_dbg(generic_logger, Info, _rctx.recipientId() << " done sent message " << _rsent_msg_ptr.get()); + } +} + +} // namespace + +int test_clientserver_pool(int argc, char* argv[]) +{ + + solid::log_start(std::cerr, {".*:EWXS"}); + // solid::log_start(std::cerr, {"solid::frame::mprpc.*:VIEWX", "\\*:VIEWX"}); + + size_t max_per_pool_connection_count = 1; + + if (argc > 1) { + max_per_pool_connection_count = atoi(argv[1]); + if (max_per_pool_connection_count == 0) { + max_per_pool_connection_count = 1; + } + if (max_per_pool_connection_count > 100) { + max_per_pool_connection_count = 100; + } + } + + bool secure = false; + bool compress = false; + + if (argc > 2) { + if (*argv[2] == 's' || *argv[2] == 'S') { + secure = true; + } + if (*argv[2] == 'c' || *argv[2] == 'C') { + compress = true; + } + if (*argv[2] == 'b' || *argv[2] == 'B') { + secure = true; + compress = true; + } + } + + if (argc > 3) { + if (*argv[3] == 'c' || *argv[3] == 'C') { + use_context_on_response = true; + } + } + + for (int j = 0; j < 1; ++j) { + for (int i = 0; i < 127; ++i) { + int c = (i + j) % 127; + if (isprint(c) != 0 && isblank(c) == 0) { + pattern += static_cast(c); + } + } + } + + size_t sz = real_size(pattern.size()); + + if (sz > pattern.size()) { + pattern.resize(sz - sizeof(uint64_t)); + } else if (sz < pattern.size()) { + pattern.resize(sz); + } + + { + AioSchedulerT sch_client; + AioSchedulerT sch_server; + + frame::Manager m; + frame::mprpc::ServiceT mprpcserver(m); + frame::mprpc::ServiceT mprpcclient(m); + ErrorConditionT err; + CallPoolT cwp{{1, 100, 0}, [](const size_t) {}, [](const size_t) {}}; + frame::aio::Resolver resolver([&cwp](std::function&& _fnc) { cwp.pushOne(std::move(_fnc)); }); + + sch_client.start(1); + sch_server.start(1); + + std::string server_port; + + { // mprpc server initialization + auto proto = frame::mprpc::serialization_v3::create_protocol( + reflection::v1::metadata::factory, + [&](auto& _rmap) { + _rmap.template registerMessage(1, "Message", server_complete_message, [](auto&, auto& ptr) { + ptr = frame::mprpc::make_pool_message(); + }); + }); + frame::mprpc::Configuration cfg(sch_server, proto); + + // cfg.recv_buffer_capacity = 1024; + // cfg.send_buffer_capacity = 1024; + + cfg.connection_stop_fnc = &server_connection_stop; + cfg.server.connection_start_fnc = &server_connection_start; + + cfg.server.listener_address_str = "0.0.0.0:0"; + + if (secure) { + solid_dbg(generic_logger, Info, "Configure SSL server -------------------------------------"); + frame::mprpc::openssl::setup_server( + cfg, + [](frame::aio::openssl::Context& _rctx) -> ErrorCodeT { + _rctx.loadVerifyFile("echo-ca-cert.pem" /*"/etc/pki/tls/certs/ca-bundle.crt"*/); + _rctx.loadCertificateFile("echo-server-cert.pem"); + _rctx.loadPrivateKeyFile("echo-server-key.pem"); + return ErrorCodeT(); + }, + frame::mprpc::openssl::NameCheckSecureStart{"echo-client"}); + } + + if (compress) { + frame::mprpc::snappy::setup(cfg); + } + + { + frame::mprpc::ServiceStartStatus start_status; + mprpcserver.start(start_status, std::move(cfg)); + + std::ostringstream oss; + oss << start_status.listen_addr_vec_.back().port(); + server_port = oss.str(); + solid_dbg(generic_logger, Info, "server listens on: " << start_status.listen_addr_vec_.back()); + } + } + + { // mprpc client initialization + auto proto = frame::mprpc::serialization_v3::create_protocol( + reflection::v1::metadata::factory, + [&](auto& _rmap) { + _rmap.template registerMessage(1, "Message", client_complete_message); + }); + frame::mprpc::Configuration cfg(sch_client, proto); + + // cfg.recv_buffer_capacity = 1024; + // cfg.send_buffer_capacity = 1024; + + cfg.connection_stop_fnc = &client_connection_stop; + cfg.client.connection_start_fnc = &client_connection_start; + + cfg.pool_max_active_connection_count = max_per_pool_connection_count; + + cfg.client.name_resolve_fnc = frame::mprpc::InternetResolverF{resolver, server_port}; + + if (secure) { + solid_dbg(generic_logger, Info, "Configure SSL client ------------------------------------"); + frame::mprpc::openssl::setup_client( + cfg, + [](frame::aio::openssl::Context& _rctx) -> ErrorCodeT { + _rctx.loadVerifyFile("echo-ca-cert.pem" /*"/etc/pki/tls/certs/ca-bundle.crt"*/); + _rctx.loadCertificateFile("echo-client-cert.pem"); + _rctx.loadPrivateKeyFile("echo-client-key.pem"); + return ErrorCodeT(); + }, + frame::mprpc::openssl::NameCheckSecureStart{"echo-server"}); + } + + if (compress) { + frame::mprpc::snappy::setup(cfg); + } + + mprpcclient.start(std::move(cfg)); + } + + pmprpcclient = &mprpcclient; + + const size_t start_count = 10; + + writecount = initarraysize * 10; // start_count;// + + for (; crtwriteidx < start_count;) { + mprpcclient.sendMessage( + {""}, frame::mprpc::make_pool_message(crtwriteidx++), + initarray[crtwriteidx % initarraysize].flags | frame::mprpc::MessageFlagsE::AwaitResponse); + } + + unique_lock lock(mtx); + + if (!cnd.wait_for(lock, std::chrono::seconds(220), []() { return !running; })) { + solid_throw("Process is taking too long."); + } + + if (crtwriteidx != crtackidx) { + solid_throw("Not all messages were completed"); + } + + mprpcclient.stop(); + mprpcserver.stop(); + + solid_log(generic_logger, Statistic, "mprpcserver statistic: " << mprpcserver.statistic()); + solid_log(generic_logger, Statistic, "mprpcclient statistic: " << mprpcclient.statistic()); + } + + // exiting + + std::cout << "Transfered size = " << (transfered_size * 2) / 1024 << "KB" << endl; + std::cout << "Transfered count = " << transfered_count << endl; + std::cout << "Connection count = " << connection_count << endl; + std::cout << "Message create count = " << Message::create_count << endl; + + return 0; +} diff --git a/solid/frame/mprpc/test/test_clientserver_sendrequest.cpp b/solid/frame/mprpc/test/test_clientserver_sendrequest.cpp index c3e5b6ed..e73689d6 100644 --- a/solid/frame/mprpc/test/test_clientserver_sendrequest.cpp +++ b/solid/frame/mprpc/test/test_clientserver_sendrequest.cpp @@ -32,7 +32,7 @@ namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -59,11 +59,11 @@ InitStub initarray[] = { std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -std::atomic crtwriteidx(0); -std::atomic crtreadidx(0); -std::atomic crtbackidx(0); -std::atomic crtackidx(0); -std::atomic writecount(0); +std::atomic crtwriteidx(0); +std::atomic crtreadidx(0); +std::atomic crtbackidx(0); +std::atomic crtackidx(0); +std::atomic writecount(0); size_t connection_count(0); @@ -167,8 +167,10 @@ struct Response : frame::mprpc::Message { } }; -using RequestPointerT = solid::frame::mprpc::MessagePointerT; -using ResponsePointerT = solid::frame::mprpc::MessagePointerT; +using RequestPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvRequestPointerT = solid::frame::mprpc::RecvMessagePointerT; +using ResponsePointerT = solid::frame::mprpc::RecvMessagePointerT; +using SendResponsePointerT = solid::frame::mprpc::SendMessagePointerT; void client_connection_stop(frame::mprpc::ConnectionContext& _rctx) { @@ -218,7 +220,7 @@ void client_complete_request( void client_complete_response( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& /*_rsendmsgptr*/, + SendResponsePointerT& /*_rsendmsgptr*/, ResponsePointerT& /*_rrecvmsgptr*/, ErrorConditionT const& /*_rerr*/) { @@ -273,7 +275,7 @@ struct ResponseHandler { void server_complete_request( frame::mprpc::ConnectionContext& _rctx, RequestPointerT& _rsendmsgptr, - RequestPointerT& _rrecvmsgptr, + RecvRequestPointerT& _rrecvmsgptr, ErrorConditionT const& _rerr) { if (_rerr) { @@ -303,17 +305,17 @@ void server_complete_request( // send message back auto msgptr(frame::mprpc::make_message(*_rrecvmsgptr)); - _rctx.service().sendResponse(_rctx.recipientId(), msgptr); + _rctx.service().sendResponse(_rctx.recipientId(), std::move(msgptr)); ++crtreadidx; solid_dbg(generic_logger, Info, crtreadidx); - if (crtwriteidx < writecount) { + if (crtwriteidx < writecount and pmprpcclient) { auto msgptr(frame::mprpc::make_message(crtwriteidx)); ++crtwriteidx; pmprpcclient->sendRequest( - {"localhost"}, msgptr, + {"localhost"}, std::move(msgptr), // on_receive_response ResponseHandler() /*[](frame::mprpc::ConnectionContext &_rctx, ResponsePointerT &_rmsgptr, ErrorConditionT const &_rerr)->void{ @@ -321,12 +323,14 @@ void server_complete_request( }*/ , initarray[crtwriteidx % initarraysize].flags); + } else { + solid_check(pmprpcclient, "pmprpcclient should not be nullptr"); } } void server_complete_response( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsendmsgptr, + SendResponsePointerT& _rsendmsgptr, ResponsePointerT& _rrecvmsgptr, ErrorConditionT const& _rerr) { @@ -482,7 +486,7 @@ int test_clientserver_sendrequest(int argc, char* argv[]) auto msgptr(frame::mprpc::make_message(crtwriteidx)); ++crtwriteidx; mprpcclient.sendRequest( - {"localhost"}, msgptr, + {"localhost"}, std::move(msgptr), // ResponseHandler() []( diff --git a/solid/frame/mprpc/test/test_clientserver_split.cpp b/solid/frame/mprpc/test/test_clientserver_split.cpp index bdba9936..010e7d29 100644 --- a/solid/frame/mprpc/test/test_clientserver_split.cpp +++ b/solid/frame/mprpc/test/test_clientserver_split.cpp @@ -33,7 +33,7 @@ namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -60,11 +60,11 @@ InitStub initarray[] = { std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -std::atomic crtwriteidx(0); -std::atomic crtreadidx(0); -std::atomic crtbackidx(0); -std::atomic crtackidx(0); -std::atomic writecount(0); +std::atomic crtwriteidx(0); +std::atomic crtreadidx(0); +std::atomic crtbackidx(0); +std::atomic crtackidx(0); +std::atomic writecount(0); size_t connection_count(0); bool running = true; @@ -170,7 +170,8 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void client_connection_stop(frame::mprpc::ConnectionContext& _rctx) { @@ -205,7 +206,7 @@ void server_connection_start(frame::mprpc::ConnectionContext& _rctx) void client_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -251,7 +252,7 @@ void client_complete_message( void server_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& /*_rerror*/) { if (_rrecv_msg_ptr) { @@ -277,18 +278,20 @@ void server_complete_message( // - it must always arive last _rrecv_msg_ptr->str.clear(); } - err = _rctx.service().sendResponse(_rctx.recipientId(), _rrecv_msg_ptr, + err = _rctx.service().sendResponse(_rctx.recipientId(), std::move(_rrecv_msg_ptr), {frame::mprpc::MessageFlagsE::ResponseLast}); solid_check(!err, "Connection id should not be invalid: " << err.message()); ++crtreadidx; solid_dbg(generic_logger, Info, crtreadidx); - if (crtwriteidx < writecount) { + if (crtwriteidx < writecount and pmprpcclient) { err = pmprpcclient->sendMessage( {"localhost"}, frame::mprpc::make_message(crtwriteidx++), initarray[crtwriteidx % initarraysize].flags | frame::mprpc::MessageFlagsE::AwaitResponse); solid_check(!err, "Connection id should not be invalid! " << err.message()); + } else { + solid_check(pmprpcclient, "pmprpcclient should not be nullptr"); } } if (_rsent_msg_ptr) { diff --git a/solid/frame/mprpc/test/test_clientserver_stop.cpp b/solid/frame/mprpc/test/test_clientserver_stop.cpp index 71eb69ab..3fb45d5d 100644 --- a/solid/frame/mprpc/test/test_clientserver_stop.cpp +++ b/solid/frame/mprpc/test/test_clientserver_stop.cpp @@ -61,7 +61,7 @@ std::string TestErrorCategory::message(int _ev) const case 0: oss << "Success"; break; - case to_underlying(TestErrorE::Dummy): + case solid::to_underlying(TestErrorE::Dummy): oss << " Dummy"; break; default: @@ -71,14 +71,14 @@ std::string TestErrorCategory::message(int _ev) const return oss.str(); } -const ErrorConditionT error_test_dummy(to_underlying(TestErrorE::Dummy), test_category); +const ErrorConditionT error_test_dummy(solid::to_underlying(TestErrorE::Dummy), test_category); struct InitStub { size_t size; frame::mprpc::MessageFlagsT flags; }; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; InitStub initarray[] = { {100000, 0}, @@ -100,11 +100,11 @@ InitStub initarray[] = { std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -std::atomic crtwriteidx(0); -std::atomic crtreadidx(0); -std::atomic crtbackidx(0); -std::atomic crtackidx(0); -std::atomic writecount(0); +std::atomic crtwriteidx(0); +std::atomic crtreadidx(0); +std::atomic crtbackidx(0); +std::atomic crtackidx(0); +std::atomic writecount(0); size_t connection_count(0); bool running = true; @@ -192,7 +192,8 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void client_connection_stop(frame::mprpc::ConnectionContext& _rctx) { @@ -232,7 +233,7 @@ void server_connection_start(frame::mprpc::ConnectionContext& _rctx) void client_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " " << crtbackidx << " " << writecount); @@ -264,7 +265,7 @@ void client_complete_message( void server_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& /*_rerror*/) { if (_rrecv_msg_ptr) { @@ -276,7 +277,7 @@ void server_complete_message( solid_check(_rctx.recipientId().isValidConnection(), "Connection id should not be invalid!"); - ErrorConditionT err = use_context_on_response ? _rctx.service().sendResponse(_rctx, _rrecv_msg_ptr) : _rctx.service().sendResponse(_rctx.recipientId(), _rrecv_msg_ptr); + ErrorConditionT err = use_context_on_response ? _rctx.service().sendResponse(_rctx, std::move(_rrecv_msg_ptr)) : _rctx.service().sendResponse(_rctx.recipientId(), std::move(_rrecv_msg_ptr)); // solid_check(!err, "Connection id should not be invalid: " << err.message()); @@ -287,11 +288,13 @@ void server_complete_message( } solid_dbg(generic_logger, Info, crtreadidx << " " << crtwriteidx); - if (crtwriteidx < writecount) { + if (crtwriteidx < writecount and pmprpcclient) { err = pmprpcclient->sendMessage( {""}, frame::mprpc::make_message(crtwriteidx++), initarray[crtwriteidx % initarraysize].flags | frame::mprpc::MessageFlagsE::AwaitResponse | frame::mprpc::MessageFlagsE::Idempotent); solid_check(!err, "Connection id should not be invalid! " << err.message()); + } else { + solid_check(pmprpcclient, "pmprpcclient should not be nullptr"); } } if (_rsent_msg_ptr) { diff --git a/solid/frame/mprpc/test/test_clientserver_timeout_secure.cpp b/solid/frame/mprpc/test/test_clientserver_timeout_secure.cpp index 10307fbb..707fe61c 100644 --- a/solid/frame/mprpc/test/test_clientserver_timeout_secure.cpp +++ b/solid/frame/mprpc/test/test_clientserver_timeout_secure.cpp @@ -35,7 +35,7 @@ using namespace std::chrono_literals; namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; atomic wait_count{0}; bool running = true; @@ -96,8 +96,8 @@ void server_connection_stop(frame::mprpc::ConnectionContext& _rctx) } void server_complete_message( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, frame::mprpc::MessagePointerT& _rrecv_msg_ptr, + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& /*_rerror*/) { solid_check(false); diff --git a/solid/frame/mprpc/test/test_clientserver_topic.cpp b/solid/frame/mprpc/test/test_clientserver_topic.cpp index 237d2ec8..09a610a8 100644 --- a/solid/frame/mprpc/test/test_clientserver_topic.cpp +++ b/solid/frame/mprpc/test/test_clientserver_topic.cpp @@ -86,9 +86,9 @@ uint64_t microseconds_since_epoch() } struct Topic { - const size_t id_; - SynchContextT synch_ctx_; - uint64_t value_ = 0; + const size_t id_; + SynchContextT synch_ctx_; + atomic_uint64_t value_ = 0; Topic( const size_t _id, @@ -180,12 +180,10 @@ struct Response : frame::mprpc::Message { } }; -using CacheableRequestT = EnableCacheable; -using CacheableResponseT = EnableCacheable; -using RequestPointerT = solid::frame::mprpc::MessagePointerT; -using CesponsePointerT = solid::frame::mprpc::MessagePointerT; -using CacheableRequestPointerT = solid::frame::mprpc::MessagePointerT; -using CacheableResponsePointerT = solid::frame::mprpc::MessagePointerT; +using SendRequestPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvRequestPointerT = solid::frame::mprpc::RecvMessagePointerT; +using SendResponsePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvResponsePointerT = solid::frame::mprpc::RecvMessagePointerT; template auto lin_value(T _from, T _to, const size_t _index, const size_t _n) @@ -234,22 +232,22 @@ void server_connection_start(frame::mprpc::ConnectionContext& _rctx) void client_complete_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, CacheableResponsePointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror); void client_complete_response( frame::mprpc::ConnectionContext& _rctx, - CacheableResponsePointerT& _rsent_msg_ptr, CacheableResponsePointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror); void server_complete_response( frame::mprpc::ConnectionContext& _rctx, - CacheableResponsePointerT& _rsent_msg_ptr, CacheableResponsePointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& /*_rerror*/); void server_complete_request( frame::mprpc::ConnectionContext& _rctx, - CacheableRequestPointerT& _rsent_msg_ptr, CacheableRequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& /*_rerror*/); void multicast_run(CallPoolT& _work_pool); @@ -300,13 +298,6 @@ chrono::microseconds test_duration{chrono::seconds(1) DurationDqT duration_dq; #endif -auto create_message_ptr = [](auto& _rctx, auto& _rmsgptr) { - using PtrT = std::decay_t; - using ElemT = typename PtrT::element_type; - - _rmsgptr = ElemT::create(); -}; - //----------------------------------------------------------------------------- } // namespace @@ -345,10 +336,6 @@ int test_clientserver_topic(int argc, char* argv[]) sch_client.start([]() {set_current_thread_affinity();return true; }, []() {}, 1); sch_server.start([]() { set_current_thread_affinity(); - for(size_t i = 0; i < 2000; ++i){ - auto reply_ptr = frame::mprpc::make_message(); - reply_ptr->cache(); - } return true; }, []() {}, 2); { @@ -376,8 +363,8 @@ int test_clientserver_topic(int argc, char* argv[]) auto proto = frame::mprpc::serialization_v3::create_protocol( reflection::v1::metadata::factory, [&](auto& _rmap) { - _rmap.template registerMessage(1, "Request", server_complete_request, create_message_ptr); - _rmap.template registerMessage(2, "Response", server_complete_response, create_message_ptr); + _rmap.template registerMessage(1, "Request", server_complete_request); + _rmap.template registerMessage(2, "Response", server_complete_response); }); frame::mprpc::Configuration cfg(sch_server, proto); @@ -421,7 +408,7 @@ int test_clientserver_topic(int argc, char* argv[]) reflection::v1::metadata::factory, [&](auto& _rmap) { _rmap.template registerMessage(1, "Request", client_complete_request); - _rmap.template registerMessage(2, "Response", client_complete_response, create_message_ptr); + _rmap.template registerMessage(2, "Response", client_complete_response); }); frame::mprpc::Configuration cfg(sch_client, proto); @@ -483,9 +470,9 @@ int test_clientserver_topic(int argc, char* argv[]) solid_log(logger, Warning, "========== START sending messages =========="); - if (false) { + if (/* DISABLES CODE */ (false)) { const uint64_t startms = microseconds_since_epoch(); - for (size_t i = 0; i < message_count; ++i) { + for (uint32_t i = 0; i < message_count; ++i) { mprpcclient.sendMessage(client_id, frame::mprpc::make_message(i, microseconds_since_epoch()), {frame::mprpc::MessageFlagsE::AwaitResponse}); } solid_log(logger, Warning, "========== DONE sending messages ========== " << (microseconds_since_epoch() - startms) << "us"); @@ -495,7 +482,7 @@ int test_clientserver_topic(int argc, char* argv[]) const auto start = chrono::high_resolution_clock::now(); - for (size_t i = 0; i < message_count; ++i) { + for (uint32_t i = 0; i < message_count; ++i) { this_thread::sleep_until(start + chrono::microseconds(static_cast(lin_value(0.0, stop, i, message_count)))); mprpcclient.sendMessage(client_id, frame::mprpc::make_message(i, microseconds_since_epoch()), {frame::mprpc::MessageFlagsE::AwaitResponse}); } @@ -537,7 +524,7 @@ int test_clientserver_topic(int argc, char* argv[]) } } #endif - if (0) { + if (/* DISABLES CODE */ (false)) { ofstream ofs("trace.csv"); if (ofs) { for (const auto& t : trace_dq) { @@ -589,7 +576,7 @@ void multicast_run(CallPoolT& _work_pool) } void client_complete_response( frame::mprpc::ConnectionContext& _rctx, - CacheableResponsePointerT& _rsent_msg_ptr, CacheableResponsePointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(false); // should not be called @@ -597,7 +584,7 @@ void client_complete_response( void client_complete_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, CacheableResponsePointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(logger, Info, _rctx.recipientId()); @@ -627,14 +614,16 @@ void client_complete_request( ); #endif - cacheable_cache(std::move(_rrecv_msg_ptr)); + auto sent_msg_ptr = _rsent_msg_ptr.collapse(); + solid_check(sent_msg_ptr); + solid_check(!_rsent_msg_ptr); - _rsent_msg_ptr->time_point_ = now; - ++_rsent_msg_ptr->iteration_; + sent_msg_ptr->time_point_ = now; + ++sent_msg_ptr->iteration_; - if (_rsent_msg_ptr->iteration_ < per_message_loop_count) { - _rsent_msg_ptr->clearHeader(); - _rctx.service().sendMessage(client_id, std::move(_rsent_msg_ptr), {frame::mprpc::MessageFlagsE::AwaitResponse}); + if (sent_msg_ptr->iteration_ < per_message_loop_count) { + sent_msg_ptr->clearHeader(); + _rctx.service().sendMessage(client_id, std::move(sent_msg_ptr), {frame::mprpc::MessageFlagsE::AwaitResponse}); local_send_duration += (microseconds_since_epoch() - now); solid_statistic_inc(request_count); } else { @@ -651,18 +640,17 @@ void client_complete_request( void server_complete_response( frame::mprpc::ConnectionContext& _rctx, - CacheableResponsePointerT& _rsent_msg_ptr, CacheableResponsePointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& /*_rerror*/) { solid_check(_rsent_msg_ptr); solid_check(!_rrecv_msg_ptr); solid_dbg(logger, Info, _rctx.recipientId() << " done sent message " << _rsent_msg_ptr.get()); - cacheable_cache(std::move(_rsent_msg_ptr)); } void server_complete_request( frame::mprpc::ConnectionContext& _rctx, - CacheableRequestPointerT& _rsent_msg_ptr, CacheableRequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& /*_rerror*/) { solid_check(_rrecv_msg_ptr); @@ -671,28 +659,24 @@ void server_complete_request( solid_dbg(logger, Info, _rctx.recipientId()); auto& topic_ptr = local_worker_context_ptr->topic_vec_[_rrecv_msg_ptr->topic_id_ % local_worker_context_ptr->topic_vec_.size()]; - auto reply_ptr = CacheableResponseT::create(); + auto reply_ptr = frame::mprpc::make_message(); reply_ptr->receive_time_point_ = microseconds_since_epoch(); reply_ptr->header(_rrecv_msg_ptr->header()); - // cacheable_cache(std::move(_rrecv_msg_ptr)); - auto lambda = [topic_ptr, _rrecv_msg_ptr = std::move(_rrecv_msg_ptr), - &service = _rctx.service(), recipient_id = _rctx.recipientId(), reply_ptr = std::move(reply_ptr)]() { + &service = _rctx.service(), recipient_id = _rctx.recipientId(), reply_ptr = std::move(reply_ptr)]() mutable { ++topic_ptr->value_; reply_ptr->topic_value_ = topic_ptr->value_; reply_ptr->topic_context_ = local_thread_pool_context_ptr->value_; reply_ptr->time_point_ = microseconds_since_epoch(); - reply_ptr->cacheableAttach(std::move(_rrecv_msg_ptr)); - - service.sendResponse(recipient_id, reply_ptr); + service.sendResponse(recipient_id, std::move(reply_ptr)); }; static_assert(CallPoolT::is_small_one_type(), "Type not small"); - if (false) { + if (/* DISABLES CODE */ (false)) { std::lock_guard lock(trace_mtx); if (!trace_dq.empty()) { if (get<0>(trace_dq.back()) == _rctx.recipientId().connectionId().index) { diff --git a/solid/frame/mprpc/test/test_clientserver_upload.cpp b/solid/frame/mprpc/test/test_clientserver_upload.cpp index d9f2c694..45f059a5 100644 --- a/solid/frame/mprpc/test/test_clientserver_upload.cpp +++ b/solid/frame/mprpc/test/test_clientserver_upload.cpp @@ -32,7 +32,7 @@ using namespace std; using namespace solid; namespace { -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; @@ -47,9 +47,7 @@ struct Request : frame::mprpc::Message { ofstream ofs_; ostringstream oss_; - Request() - { - } + Request() = default; Request(const string& _name) : name_(_name) @@ -82,23 +80,23 @@ struct Request : frame::mprpc::Message { } } }; -using RequestPointerT = solid::frame::mprpc::MessagePointerT; + +using SendRequestPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvRequestPointerT = solid::frame::mprpc::RecvMessagePointerT; struct Response : frame::mprpc::Message { - uint32_t error_ = -1; - RequestPointerT req_ptr_; - bool send_response_ = false; + uint32_t error_ = -1; + RecvRequestPointerT req_ptr_; + mutable bool send_response_ = false; // TODO: find a better solution - Response() - { - } + Response() = default; Response(Request& _req) : frame::mprpc::Message(_req) { } - Response(RequestPointerT&& _req_ptr) + Response(RecvRequestPointerT&& _req_ptr) : frame::mprpc::Message(*_req_ptr) , req_ptr_(std::move(_req_ptr)) @@ -116,12 +114,13 @@ struct Response : frame::mprpc::Message { } }; -using ResponsePointerT = solid::frame::mprpc::MessagePointerT; +using SendResponsePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvResponsePointerT = solid::frame::mprpc::RecvMessagePointerT; void on_client_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "on message"); @@ -129,8 +128,8 @@ void on_client_request( void on_client_response( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "on message"); @@ -138,20 +137,20 @@ void on_client_response( void on_client_receive_first_response( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror); void on_server_receive_first_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror); void on_server_response( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "on message"); @@ -314,7 +313,7 @@ int test_clientserver_upload(int argc, char* argv[]) auto msg_ptr = frame::mprpc::make_message(f); msg_ptr->ifs_.open(string("client_storage/") + f); - mprpc_client.sendRequest({"localhost"}, msg_ptr, on_client_receive_first_response); + mprpc_client.sendRequest({"localhost"}, std::move(msg_ptr), on_client_receive_first_response); } auto fut = prom.get_future(); @@ -426,8 +425,8 @@ void check_files(const vector& _file_vec, const char* _path_prefix_clien void on_client_receive_last_response( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(_rrecv_msg_ptr); @@ -439,40 +438,49 @@ void on_client_receive_last_response( } void on_client_receive_response( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(_rrecv_msg_ptr); - solid_check(_rrecv_msg_ptr->error_ == 0); + // auto sent_msg_ptr = _rsent_msg_ptr.collapse(); + // solid_check(sent_msg_ptr); + // solid_check(!_rsent_msg_ptr); + // sent_msg_ptr->header(_rrecv_msg_ptr->header()); + if (!_rsent_msg_ptr->ifs_.eof()) { solid_log(logger, Verbose, "Sending " << _rsent_msg_ptr->name_ << " to " << _rctx.recipientId()); frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::ResponsePart, frame::mprpc::MessageFlagsE::AwaitResponse}; _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, on_client_receive_response, flags); flags.reset(frame::mprpc::MessageFlagsE::AwaitResponse); - _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(_rsent_msg_ptr), flags); } else { solid_log(logger, Verbose, "Sending " << _rsent_msg_ptr->name_ << " to " << _rctx.recipientId() << " last"); frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::ResponseLast, frame::mprpc::MessageFlagsE::AwaitResponse}; - _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, on_client_receive_last_response, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(_rsent_msg_ptr), on_client_receive_last_response, flags); } } void on_client_receive_first_response( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(_rrecv_msg_ptr); - + solid_check(_rsent_msg_ptr); solid_check(_rrecv_msg_ptr->error_ == 0); + { + auto sent_msg_ptr = _rsent_msg_ptr.collapse(); + solid_check(sent_msg_ptr); + solid_check(!_rsent_msg_ptr); + sent_msg_ptr->name_.clear(); + sent_msg_ptr->header(_rrecv_msg_ptr->header()); - _rsent_msg_ptr->name_.clear(); - _rsent_msg_ptr->header(_rrecv_msg_ptr->header()); - + _rsent_msg_ptr = std::move(sent_msg_ptr); + } frame::mprpc::MessageFlagsT flags; if (!_rsent_msg_ptr->ifs_.eof()) { @@ -480,11 +488,11 @@ void on_client_receive_first_response( frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::ResponsePart, frame::mprpc::MessageFlagsE::AwaitResponse}; _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, on_client_receive_response, flags); flags.reset(frame::mprpc::MessageFlagsE::AwaitResponse); - _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(_rsent_msg_ptr), flags); } else { solid_log(logger, Verbose, "Sending " << _rsent_msg_ptr->name_ << " to " << _rctx.recipientId() << " last"); frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::ResponseLast, frame::mprpc::MessageFlagsE::AwaitResponse}; - _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, on_client_receive_last_response, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(_rsent_msg_ptr), on_client_receive_last_response, flags); } } //----------------------------------------------------------------------------- @@ -492,8 +500,8 @@ void on_client_receive_first_response( //----------------------------------------------------------------------------- void on_server_receive_request( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { // the server will keep receiving new Requests @@ -506,10 +514,9 @@ void on_server_receive_request( if (!_rrecv_msg_ptr->isResponseLast()) { if (_rsent_msg_ptr->send_response_) { - _rsent_msg_ptr->send_response_ = false; - auto res_ptr = frame::mprpc::make_message(*_rrecv_msg_ptr); - res_ptr->error_ = 0; - auto err = _rctx.service().sendMessage(_rctx.recipientId(), res_ptr, {frame::mprpc::MessageFlagsE::Response}); + auto res_ptr = frame::mprpc::make_message(*_rrecv_msg_ptr); + res_ptr->error_ = 0; + auto err = _rctx.service().sendMessage(_rctx.recipientId(), std::move(res_ptr), {frame::mprpc::MessageFlagsE::Response}); solid_log(logger, Verbose, "send response to: " << _rctx.recipientId() << " err: " << err.message()); } else { _rsent_msg_ptr->send_response_ = true; @@ -518,15 +525,15 @@ void on_server_receive_request( _rsent_msg_ptr->req_ptr_->ofs_.flush(); auto res_ptr = frame::mprpc::make_message(*_rrecv_msg_ptr); res_ptr->error_ = 0; - auto err = _rctx.service().sendMessage(_rctx.recipientId(), res_ptr, {frame::mprpc::MessageFlagsE::Response}); + auto err = _rctx.service().sendMessage(_rctx.recipientId(), std::move(res_ptr), {frame::mprpc::MessageFlagsE::Response}); solid_log(logger, Verbose, "send last response to: " << _rctx.recipientId() << " err: " << err.message()); } } void on_server_receive_first_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { string path = string("server_storage") + '/' + _rrecv_msg_ptr->name_; @@ -538,7 +545,7 @@ void on_server_receive_first_request( auto res_ptr = frame::mprpc::make_message(std::move(_rrecv_msg_ptr)); res_ptr->error_ = 0; const frame::mprpc::MessageFlagsT flags{frame::mprpc::MessageFlagsE::AwaitResponse, frame::mprpc::MessageFlagsE::Response}; - _rctx.service().sendMessage(_rctx.recipientId(), res_ptr, on_server_receive_request, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(res_ptr), on_server_receive_request, flags); } } // namespace diff --git a/solid/frame/mprpc/test/test_clientserver_upload_single.cpp b/solid/frame/mprpc/test/test_clientserver_upload_single.cpp index f7feed29..4de01a63 100644 --- a/solid/frame/mprpc/test/test_clientserver_upload_single.cpp +++ b/solid/frame/mprpc/test/test_clientserver_upload_single.cpp @@ -38,7 +38,7 @@ using namespace solid; namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; LoggerT logger("test"); @@ -51,9 +51,7 @@ struct Request : frame::mprpc::Message { ofstream ofs_; ostringstream oss_; - Request() - { - } + Request() = default; Request(const string& _name) : name_(_name) @@ -87,23 +85,22 @@ struct Request : frame::mprpc::Message { } }; -using RequestPointerT = solid::frame::mprpc::MessagePointerT; +using SendRequestPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvRequestPointerT = solid::frame::mprpc::RecvMessagePointerT; struct Response : frame::mprpc::Message { - uint32_t error_ = -1; - RequestPointerT req_ptr_; - bool send_response_ = false; + uint32_t error_ = -1; + RecvRequestPointerT req_ptr_; + mutable bool send_response_ = false; // TODO: find a better solution - Response() - { - } + Response() = default; Response(Request& _req) : frame::mprpc::Message(_req) { } - Response(RequestPointerT&& _req_ptr) + Response(RecvRequestPointerT&& _req_ptr) : frame::mprpc::Message(*_req_ptr) , req_ptr_(std::move(_req_ptr)) , send_response_(false) @@ -120,12 +117,13 @@ struct Response : frame::mprpc::Message { } }; -using ResponsePointerT = solid::frame::mprpc::MessagePointerT; +using SendResponsePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvResponsePointerT = solid::frame::mprpc::RecvMessagePointerT; void on_client_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "on message"); @@ -133,8 +131,8 @@ void on_client_request( void on_client_response( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "on message"); @@ -142,20 +140,20 @@ void on_client_response( void on_client_first_response( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror); void on_server_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror); void on_server_response( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_log(logger, Verbose, "on message"); @@ -318,7 +316,7 @@ int test_clientserver_upload_single(int argc, char* argv[]) auto msg_ptr = frame::mprpc::make_message(f); msg_ptr->ifs_.open(string("client_storage/") + f); - mprpc_client.sendRequest({"localhost"}, msg_ptr, on_client_first_response); + mprpc_client.sendRequest({"localhost"}, std::move(msg_ptr), on_client_first_response); } auto fut = prom.get_future(); @@ -429,14 +427,14 @@ void check_files(const vector& _file_vec, const char* _path_prefix_clien //----------------------------------------------------------------------------- void on_client_continue_response( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror); void on_client_continue( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { @@ -446,18 +444,18 @@ void on_client_continue( solid_log(logger, Verbose, "Sending data to " << _rctx.recipientId() << " expect response"); flags.set(frame::mprpc::MessageFlagsE::ResponsePart); flags.set(frame::mprpc::MessageFlagsE::AwaitResponse); - _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, on_client_continue_response, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(_rsent_msg_ptr), on_client_continue_response, flags); } else { solid_log(logger, Verbose, "Sending data to " << _rctx.recipientId() << " expect response"); flags.set(frame::mprpc::MessageFlagsE::ResponseLast); - _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(_rsent_msg_ptr), flags); } } void on_client_continue_response( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(_rrecv_msg_ptr); @@ -468,37 +466,40 @@ void on_client_continue_response( if (!_rsent_msg_ptr->ifs_.eof()) { solid_log(logger, Verbose, "Sending " << _rsent_msg_ptr->name_ << " to " << _rctx.recipientId() << " expect no response"); flags.set(frame::mprpc::MessageFlagsE::ResponsePart); - _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, on_client_continue, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(_rsent_msg_ptr), on_client_continue, flags); } else { solid_log(logger, Verbose, "Sending " << _rsent_msg_ptr->name_ << " to " << _rctx.recipientId() << " last"); flags.set(frame::mprpc::MessageFlagsE::ResponseLast); - _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(_rsent_msg_ptr), flags); } } void on_client_first_response( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - ResponsePointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(_rrecv_msg_ptr); - + solid_check(_rsent_msg_ptr); solid_check(_rrecv_msg_ptr->error_ == 0); - _rsent_msg_ptr->name_.clear(); - _rsent_msg_ptr->header(_rrecv_msg_ptr->header()); + auto sent_msg_ptr = _rsent_msg_ptr.collapse(); + solid_check(sent_msg_ptr); + solid_check(!_rsent_msg_ptr); + sent_msg_ptr->name_.clear(); + sent_msg_ptr->header(_rrecv_msg_ptr->header()); frame::mprpc::MessageFlagsT flags; - if (!_rsent_msg_ptr->ifs_.eof()) { + if (!sent_msg_ptr->ifs_.eof()) { solid_log(logger, Verbose, "Sending " << _rsent_msg_ptr->name_ << " to " << _rctx.recipientId() << " expect no response"); flags.set(frame::mprpc::MessageFlagsE::ResponsePart); - _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, on_client_continue, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(sent_msg_ptr), on_client_continue, flags); } else { solid_log(logger, Verbose, "Sending " << _rsent_msg_ptr->name_ << " to " << _rctx.recipientId() << " last"); flags.set(frame::mprpc::MessageFlagsE::ResponseLast); - _rctx.service().sendMessage(_rctx.recipientId(), _rsent_msg_ptr, flags); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(sent_msg_ptr), flags); } } //----------------------------------------------------------------------------- @@ -506,8 +507,8 @@ void on_client_first_response( //----------------------------------------------------------------------------- void on_server_chunk( frame::mprpc::ConnectionContext& _rctx, - ResponsePointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendResponsePointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { // the server will keep receiving new Requests @@ -523,7 +524,7 @@ void on_server_chunk( _rsent_msg_ptr->send_response_ = false; auto res_ptr = frame::mprpc::make_message(*_rrecv_msg_ptr); res_ptr->error_ = 0; - auto err = _rctx.service().sendMessage(_rctx.recipientId(), res_ptr, {frame::mprpc::MessageFlagsE::Response}); + auto err = _rctx.service().sendMessage(_rctx.recipientId(), std::move(res_ptr), {frame::mprpc::MessageFlagsE::Response}); solid_log(logger, Verbose, "send response to: " << _rctx.recipientId() << " err: " << err.message()); } else { _rsent_msg_ptr->send_response_ = true; @@ -538,8 +539,8 @@ void on_server_chunk( void on_server_request( frame::mprpc::ConnectionContext& _rctx, - RequestPointerT& _rsent_msg_ptr, - RequestPointerT& _rrecv_msg_ptr, + SendRequestPointerT& _rsent_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { string path = string("server_storage") + '/' + _rrecv_msg_ptr->name_; @@ -550,7 +551,7 @@ void on_server_request( _rrecv_msg_ptr->ofs_.write(s.data(), s.size()); auto res_ptr = frame::mprpc::make_message(std::move(_rrecv_msg_ptr)); res_ptr->error_ = 0; - _rctx.service().sendMessage(_rctx.recipientId(), res_ptr, on_server_chunk, {frame::mprpc::MessageFlagsE::AwaitResponse, frame::mprpc::MessageFlagsE::Response}); + _rctx.service().sendMessage(_rctx.recipientId(), std::move(res_ptr), on_server_chunk, {frame::mprpc::MessageFlagsE::AwaitResponse, frame::mprpc::MessageFlagsE::Response}); } } // namespace diff --git a/solid/frame/mprpc/test/test_clientserver_versioning.cpp b/solid/frame/mprpc/test/test_clientserver_versioning.cpp index d4871f5b..9e8e3503 100644 --- a/solid/frame/mprpc/test/test_clientserver_versioning.cpp +++ b/solid/frame/mprpc/test/test_clientserver_versioning.cpp @@ -39,7 +39,7 @@ namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; const solid::LoggerT logger("test"); @@ -112,8 +112,8 @@ namespace { template void complete_message( frame::mprpc::ConnectionContext& /*_rctx*/, - frame::mprpc::MessagePointerT& /*_rsent_msg_ptr*/, - frame::mprpc::MessagePointerT& /*_rrecv_msg_ptr*/, + frame::mprpc::SendMessagePointerT& /*_rsent_msg_ptr*/, + frame::mprpc::RecvMessagePointerT& /*_rrecv_msg_ptr*/, ErrorConditionT const& /*_rerror*/) { // catch all messages @@ -123,17 +123,17 @@ void complete_message( namespace v1 { using namespace versioning::v1; -using RequestPointerT = solid::frame::mprpc::MessagePointerT; -using ResponsePointerT = solid::frame::mprpc::MessagePointerT; -using InitRequestPointerT = solid::frame::mprpc::MessagePointerT; -using InitResponsePointerT = solid::frame::mprpc::MessagePointerT; +using RequestPointerT = solid::frame::mprpc::SendMessagePointerT; +using ResponsePointerT = solid::frame::mprpc::RecvMessagePointerT; +using InitRequestPointerT = solid::frame::mprpc::SendMessagePointerT; +using InitResponsePointerT = solid::frame::mprpc::RecvMessagePointerT; void configure_service(frame::mprpc::ServiceT& _rsvc, AioSchedulerT& _rsch, frame::aio::Resolver& _rrsv, const string& _server_port) { auto proto = frame::mprpc::serialization_v3::create_protocol( reflection::v1::metadata::factory, [&](auto& _rmap) { - auto lambda = [&](const uint8_t _id, const std::string_view _name, const type_identity& _rtype) { + auto lambda = [&](const uint8_t _id, const std::string_view _name, const type_identity&) { _rmap.template registerMessage(_id, _name, complete_message); }; configure_protocol(lambda); @@ -160,7 +160,7 @@ void configure_service(frame::mprpc::ServiceT& _rsvc, AioSchedulerT& _rsch, fram } }; _rctx.any() = std::make_tuple(version); - _rctx.service().sendRequest(_rctx.recipientId(), req_ptr, lambda); + _rctx.service().sendRequest(_rctx.recipientId(), std::move(req_ptr), lambda); }; cfg.client.connection_start_fnc = std::move(connection_start_lambda); cfg.client.connection_start_state = frame::mprpc::ConnectionState::Passive; @@ -171,7 +171,7 @@ void send_request(frame::mprpc::ServiceT& _rsvc) { auto req_ptr = frame::mprpc::make_message(); _rsvc.sendRequest( - {"localhost"}, req_ptr, + {"localhost"}, std::move(req_ptr), []( frame::mprpc::ConnectionContext& _rctx, RequestPointerT& _rreqmsgptr, @@ -193,17 +193,17 @@ void send_request(frame::mprpc::ServiceT& _rsvc) namespace v2 { using namespace versioning::v2; -using RequestPointerT = solid::frame::mprpc::MessagePointerT; -using ResponsePointerT = solid::frame::mprpc::MessagePointerT; -using InitRequestPointerT = solid::frame::mprpc::MessagePointerT; -using InitResponsePointerT = solid::frame::mprpc::MessagePointerT; +using RequestPointerT = solid::frame::mprpc::SendMessagePointerT; +using ResponsePointerT = solid::frame::mprpc::RecvMessagePointerT; +using InitRequestPointerT = solid::frame::mprpc::SendMessagePointerT; +using InitResponsePointerT = solid::frame::mprpc::RecvMessagePointerT; void configure_service(frame::mprpc::ServiceT& _rsvc, AioSchedulerT& _rsch, frame::aio::Resolver& _rrsv, const string& _server_port) { auto proto = frame::mprpc::serialization_v3::create_protocol( reflection::v1::metadata::factory, [&](auto& _rmap) { - auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const& _rtype) { + auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const&) { _rmap.template registerMessage(_id, _name, complete_message); }; configure_protocol(lambda); @@ -230,7 +230,7 @@ void configure_service(frame::mprpc::ServiceT& _rsvc, AioSchedulerT& _rsch, fram } }; _rctx.any() = std::make_tuple(version); - _rctx.service().sendRequest(_rctx.recipientId(), req_ptr, lambda); + _rctx.service().sendRequest(_rctx.recipientId(), std::move(req_ptr), lambda); }; cfg.client.connection_start_fnc = std::move(connection_start_lambda); cfg.client.connection_start_state = frame::mprpc::ConnectionState::Passive; @@ -242,7 +242,7 @@ void send_request(frame::mprpc::ServiceT& _rsvc) auto req_ptr = frame::mprpc::make_message(); req_ptr->value_ = 11; _rsvc.sendRequest( - {"localhost"}, req_ptr, + {"localhost"}, std::move(req_ptr), []( frame::mprpc::ConnectionContext& _rctx, RequestPointerT& _rreqmsgptr, @@ -266,18 +266,20 @@ void send_request(frame::mprpc::ServiceT& _rsvc) namespace v3 { using namespace versioning::v3; -using RequestPointerT = solid::frame::mprpc::MessagePointerT; -using ResponsePointerT = solid::frame::mprpc::MessagePointerT; -using Response2PointerT = solid::frame::mprpc::MessagePointerT; -using InitRequestPointerT = solid::frame::mprpc::MessagePointerT; -using InitResponsePointerT = solid::frame::mprpc::MessagePointerT; +using RequestPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvRequestPointerT = solid::frame::mprpc::RecvMessagePointerT; +using ResponsePointerT = solid::frame::mprpc::RecvMessagePointerT; +using Response2PointerT = solid::frame::mprpc::RecvMessagePointerT; +using SendInitRequestPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvInitRequestPointerT = solid::frame::mprpc::RecvMessagePointerT; +using InitResponsePointerT = solid::frame::mprpc::RecvMessagePointerT; void configure_service(frame::mprpc::ServiceT& _rsvc, AioSchedulerT& _rsch, frame::aio::Resolver& _rrsv, const string& _server_port) { auto proto = frame::mprpc::serialization_v3::create_protocol( reflection::v1::metadata::factory, [&](auto& _rmap) { - auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const& _rtype) { + auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const&) { _rmap.template registerMessage(_id, _name, complete_message); }; configure_protocol(lambda); @@ -290,7 +292,7 @@ void configure_service(frame::mprpc::ServiceT& _rsvc, AioSchedulerT& _rsch, fram auto req_ptr = frame::mprpc::make_message(); auto lambda = []( frame::mprpc::ConnectionContext& _rctx, - InitRequestPointerT& _rsent_msg_ptr, + SendInitRequestPointerT& _rsent_msg_ptr, InitResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { if (_rrecv_msg_ptr) { @@ -304,7 +306,7 @@ void configure_service(frame::mprpc::ServiceT& _rsvc, AioSchedulerT& _rsch, fram }; _rctx.any() = std::make_tuple(version); - _rctx.service().sendRequest(_rctx.recipientId(), req_ptr, lambda); + _rctx.service().sendRequest(_rctx.recipientId(), std::move(req_ptr), lambda); }; cfg.client.connection_start_fnc = std::move(connection_start_lambda); cfg.client.connection_start_state = frame::mprpc::ConnectionState::Passive; @@ -316,7 +318,7 @@ void send_request(frame::mprpc::ServiceT& _rsvc) auto req_ptr = frame::mprpc::make_message(); req_ptr->values_ = "test"; _rsvc.sendRequest( - {"localhost"}, req_ptr, + {"localhost"}, std::move(req_ptr), []( frame::mprpc::ConnectionContext& _rctx, RequestPointerT& _rreqmsgptr, @@ -340,17 +342,18 @@ void send_request(frame::mprpc::ServiceT& _rsvc) namespace v4 { using namespace versioning::v4; -using InitRequestPointerT = solid::frame::mprpc::MessagePointerT; -using InitResponsePointerT = solid::frame::mprpc::MessagePointerT; -using Request2PointerT = solid::frame::mprpc::MessagePointerT; -using Response2PointerT = solid::frame::mprpc::MessagePointerT; +using SendInitRequestPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvInitRequestPointerT = solid::frame::mprpc::RecvMessagePointerT; +using InitResponsePointerT = solid::frame::mprpc::RecvMessagePointerT; +using Request2PointerT = solid::frame::mprpc::SendMessagePointerT; +using Response2PointerT = solid::frame::mprpc::RecvMessagePointerT; void configure_service(frame::mprpc::ServiceT& _rsvc, AioSchedulerT& _rsch, frame::aio::Resolver& _rrsv, const string& _server_port) { auto proto = frame::mprpc::serialization_v3::create_protocol( reflection::v1::metadata::factory, [&](auto& _rmap) { - auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const& _rtype) { + auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const&) { _rmap.template registerMessage(_id, _name, complete_message); }; configure_protocol(lambda); @@ -364,7 +367,7 @@ void configure_service(frame::mprpc::ServiceT& _rsvc, AioSchedulerT& _rsch, fram auto req_ptr = frame::mprpc::make_message(); auto lambda = []( frame::mprpc::ConnectionContext& _rctx, - InitRequestPointerT& _rsent_msg_ptr, + SendInitRequestPointerT& _rsent_msg_ptr, InitResponsePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { if (_rrecv_msg_ptr) { @@ -379,7 +382,7 @@ void configure_service(frame::mprpc::ServiceT& _rsvc, AioSchedulerT& _rsch, fram } }; _rctx.any() = std::make_tuple(version); - _rctx.service().sendRequest(_rctx.recipientId(), req_ptr, lambda); + _rctx.service().sendRequest(_rctx.recipientId(), std::move(req_ptr), lambda); }; cfg.client.connection_start_fnc = std::move(connection_start_lambda); cfg.client.connection_start_state = frame::mprpc::ConnectionState::Passive; @@ -390,7 +393,7 @@ void send_request(frame::mprpc::ServiceT& _rsvc) { auto req_ptr = frame::mprpc::make_message(); _rsvc.sendRequest( - {"localhost"}, req_ptr, + {"localhost"}, std::move(req_ptr), []( frame::mprpc::ConnectionContext& _rctx, Request2PointerT& _rreqmsgptr, @@ -416,15 +419,15 @@ using namespace versioning::v3; template void complete_message( frame::mprpc::ConnectionContext& /*_rctx*/, - frame::mprpc::MessagePointerT& /*_rsent_msg_ptr*/, - frame::mprpc::MessagePointerT& /*_rrecv_msg_ptr*/, + frame::mprpc::SendMessagePointerT& /*_rsent_msg_ptr*/, + frame::mprpc::RecvMessagePointerT& /*_rrecv_msg_ptr*/, ErrorConditionT const& /*_rerror*/); template <> void complete_message( frame::mprpc::ConnectionContext& _rctx, - InitRequestPointerT& /*_rsent_msg_ptr*/, - InitRequestPointerT& _rrecv_msg_ptr, + SendInitRequestPointerT& /*_rsent_msg_ptr*/, + RecvInitRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& /*_rerror*/) { solid_log(logger, Info, "Init request: peer [" << _rrecv_msg_ptr->version_.version_ << ']'); @@ -439,13 +442,13 @@ void complete_message( auto lambda = [response_ptr = std::move(res_ptr)](frame::mprpc::ConnectionContext& _rctx, ErrorConditionT const& _rerror) mutable { solid_check(!_rerror, "error activating connection: " << _rerror.message()); - _rctx.service().sendResponse(_rctx.recipientId(), response_ptr); + _rctx.service().sendResponse(_rctx.recipientId(), std::move(response_ptr)); }; - _rctx.service().connectionNotifyEnterActiveState(_rctx.recipientId(), lambda); + _rctx.service().connectionNotifyEnterActiveState(_rctx.recipientId(), std::move(lambda)); } else { res_ptr->error_ = 1; res_ptr->message_ = "unsupported version"; - _rctx.service().sendResponse(_rctx.recipientId(), res_ptr); + _rctx.service().sendResponse(_rctx.recipientId(), std::move(res_ptr)); _rctx.service().delayCloseConnectionPool(_rctx.recipientId(), [](frame::mprpc::ConnectionContext& /*_rctx*/) {}); } } @@ -454,31 +457,31 @@ template <> void complete_message( frame::mprpc::ConnectionContext& _rctx, RequestPointerT& /*_rsent_msg_ptr*/, - RequestPointerT& _rrecv_msg_ptr, + RecvRequestPointerT& _rrecv_msg_ptr, ErrorConditionT const& /*_rerror*/) { if (_rctx.any().get_if()->version_ == 2) { // need to send back Response2 auto res_ptr = frame::mprpc::make_message(*_rrecv_msg_ptr); - res_ptr->error_ = _rrecv_msg_ptr->values_.size(); - _rctx.service().sendResponse(_rctx.recipientId(), res_ptr); + res_ptr->error_ = static_cast(_rrecv_msg_ptr->values_.size()); + _rctx.service().sendResponse(_rctx.recipientId(), std::move(res_ptr)); } else if (_rctx.any().get_if()->request_ == 1) { auto res_ptr = frame::mprpc::make_message(*_rrecv_msg_ptr); res_ptr->error_ = 10; - _rctx.service().sendResponse(_rctx.recipientId(), res_ptr); + _rctx.service().sendResponse(_rctx.recipientId(), std::move(res_ptr)); } else if (_rctx.any().get_if()->request_ == 2) { auto res_ptr = frame::mprpc::make_message(*_rrecv_msg_ptr); res_ptr->error_ = _rrecv_msg_ptr->valuei_; - _rctx.service().sendResponse(_rctx.recipientId(), res_ptr); + _rctx.service().sendResponse(_rctx.recipientId(), std::move(res_ptr)); } } template void complete_message( frame::mprpc::ConnectionContext& /*_rctx*/, - frame::mprpc::MessagePointerT& /*_rsent_msg_ptr*/, - frame::mprpc::MessagePointerT& /*_rrecv_msg_ptr*/, + frame::mprpc::SendMessagePointerT& /*_rsent_msg_ptr*/, + frame::mprpc::RecvMessagePointerT& /*_rrecv_msg_ptr*/, ErrorConditionT const& /*_rerror*/) { // catch all @@ -489,7 +492,7 @@ string configure_service(frame::mprpc::ServiceT& _rsvc, AioSchedulerT& _rsch) auto proto = frame::mprpc::serialization_v3::create_protocol( reflection::v1::metadata::factory, [&](auto& _rmap) { - auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const& _rtype) { + auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const&) { _rmap.template registerMessage(_id, _name, complete_message); }; configure_protocol(lambda); diff --git a/solid/frame/mprpc/test/test_connection_close.cpp b/solid/frame/mprpc/test/test_connection_close.cpp index 28c2eeb5..96129af6 100644 --- a/solid/frame/mprpc/test/test_connection_close.cpp +++ b/solid/frame/mprpc/test/test_connection_close.cpp @@ -32,7 +32,7 @@ using namespace solid; namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -132,7 +132,8 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; struct Logout : frame::mprpc::Message { SOLID_REFLECT_V1(_rr, _rthis, _rctx) @@ -180,7 +181,7 @@ void server_connection_start(frame::mprpc::ConnectionContext& _rctx) void client_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -201,12 +202,14 @@ void client_complete_message( solid_throw("Message not back on sender!."); } - { + if (pmprpcclient) { auto msgptr(frame::mprpc::make_message()); pmprpcclient->sendMessage( - _rctx.recipientId(), msgptr, + _rctx.recipientId(), std::move(msgptr), {frame::mprpc::MessageFlagsE::AwaitResponse}); + } else { + solid_check(pmprpcclient, "pmprpcclient should not be nullptr"); } client_received_message = true; @@ -214,8 +217,8 @@ void client_complete_message( } void client_complete_logout( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, frame::mprpc::MessagePointerT& _rrecv_msg_ptr, + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(!_rerror); @@ -226,7 +229,7 @@ void client_complete_logout( void server_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { if (_rrecv_msg_ptr.get()) { @@ -254,8 +257,8 @@ void server_complete_message( } void server_complete_logout( - frame::mprpc::ConnectionContext& _rctx, - frame::mprpc::MessagePointerT& _rsent_msg_ptr, frame::mprpc::MessagePointerT& _rrecv_msg_ptr, + frame::mprpc::ConnectionContext& _rctx, + frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { if (_rrecv_msg_ptr.get()) { @@ -383,9 +386,9 @@ int test_connection_close(int argc, char* argv[]) pmprpcclient = &mprpcclient; { - MessagePointerT msgptr(frame::mprpc::make_message(0)); + auto msgptr(frame::mprpc::make_message(0)); mprpcclient.sendMessage( - {"localhost"}, msgptr, + {"localhost"}, std::move(msgptr), initarray[0].flags | frame::mprpc::MessageFlagsE::AwaitResponse); } diff --git a/solid/frame/mprpc/test/test_keepalive_fail.cpp b/solid/frame/mprpc/test/test_keepalive_fail.cpp index 96d66056..e1a24a02 100644 --- a/solid/frame/mprpc/test/test_keepalive_fail.cpp +++ b/solid/frame/mprpc/test/test_keepalive_fail.cpp @@ -35,7 +35,7 @@ namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -62,11 +62,11 @@ InitStub initarray[] = { std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -std::atomic crtwriteidx(0); -std::atomic crtreadidx(0); -std::atomic crtbackidx(0); -std::atomic crtackidx(0); -std::atomic writecount(0); +std::atomic crtwriteidx(0); +std::atomic crtreadidx(0); +std::atomic crtbackidx(0); +std::atomic crtackidx(0); +std::atomic writecount(0); size_t connection_count(0); @@ -147,7 +147,8 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void client_connection_stop(frame::mprpc::ConnectionContext& _rctx) { @@ -192,7 +193,7 @@ void server_connection_start(frame::mprpc::ConnectionContext& _rctx) solid_dbg(generic_logger, Info, _rctx.recipientId()); } -void client_receive_message(frame::mprpc::ConnectionContext& _rctx, MessagePointerT& _rmsgptr) +void client_receive_message(frame::mprpc::ConnectionContext& _rctx, RecvMessagePointerT& _rmsgptr) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -219,7 +220,7 @@ void client_receive_message(frame::mprpc::ConnectionContext& _rctx, MessagePoint void client_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -234,7 +235,7 @@ void client_complete_message( } } -void server_receive_message(frame::mprpc::ConnectionContext& _rctx, MessagePointerT& _rmsgptr) +void server_receive_message(frame::mprpc::ConnectionContext& _rctx, RecvMessagePointerT& _rmsgptr) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " message id on sender " << _rmsgptr->senderRequestId()); if (!_rmsgptr->check()) { @@ -246,22 +247,24 @@ void server_receive_message(frame::mprpc::ConnectionContext& _rctx, MessagePoint } // send message back - _rctx.service().sendResponse(_rctx.recipientId(), _rmsgptr); + _rctx.service().sendResponse(_rctx.recipientId(), std::move(_rmsgptr)); ++crtreadidx; solid_dbg(generic_logger, Info, crtreadidx); - if (crtwriteidx < writecount) { - MessagePointerT msgptr(frame::mprpc::make_message(crtwriteidx)); + if (crtwriteidx < writecount and pmprpcclient) { + auto msgptr(frame::mprpc::make_message(crtwriteidx)); ++crtwriteidx; pmprpcclient->sendMessage( - {"localhost"}, msgptr, + {"localhost"}, std::move(msgptr), initarray[crtwriteidx % initarraysize].flags | frame::mprpc::MessageFlagsE::AwaitResponse); + } else { + solid_check(pmprpcclient, "pointer should not be nullptr"); } } void server_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -388,10 +391,10 @@ int test_keepalive_fail(int argc, char* argv[]) writecount = 1; { - MessagePointerT msgptr(frame::mprpc::make_message(crtwriteidx)); + auto msgptr(frame::mprpc::make_message(crtwriteidx)); ++crtwriteidx; mprpcclient.sendMessage( - {"localhost"}, msgptr, + {"localhost"}, std::move(msgptr), initarray[crtwriteidx % initarraysize].flags | frame::mprpc::MessageFlagsE::AwaitResponse); } diff --git a/solid/frame/mprpc/test/test_keepalive_success.cpp b/solid/frame/mprpc/test/test_keepalive_success.cpp index d610dc06..1cb324cb 100644 --- a/solid/frame/mprpc/test/test_keepalive_success.cpp +++ b/solid/frame/mprpc/test/test_keepalive_success.cpp @@ -34,7 +34,7 @@ namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -61,7 +61,7 @@ InitStub initarray[] = { std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -std::atomic crtwriteidx(0); +std::atomic crtwriteidx(0); // std::atomic crtreadidx(0); std::atomic crtbackidx(0); std::atomic crtackidx(0); @@ -146,7 +146,8 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void client_connection_stop(frame::mprpc::ConnectionContext& _rctx) { @@ -171,7 +172,7 @@ void server_connection_start(frame::mprpc::ConnectionContext& _rctx) solid_dbg(generic_logger, Info, _rctx.recipientId()); } -void client_receive_message(frame::mprpc::ConnectionContext& _rctx, MessagePointerT& _rmsgptr) +void client_receive_message(frame::mprpc::ConnectionContext& _rctx, RecvMessagePointerT& _rmsgptr) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -199,7 +200,7 @@ void client_receive_message(frame::mprpc::ConnectionContext& _rctx, MessagePoint void client_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -214,7 +215,7 @@ void client_complete_message( } } -void server_receive_message(frame::mprpc::ConnectionContext& _rctx, MessagePointerT& _rmsgptr) +void server_receive_message(frame::mprpc::ConnectionContext& _rctx, RecvMessagePointerT& _rmsgptr) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " message id on sender " << _rmsgptr->senderRequestId()); if (!_rmsgptr->check()) { @@ -226,7 +227,7 @@ void server_receive_message(frame::mprpc::ConnectionContext& _rctx, MessagePoint } // send message back - _rctx.service().sendResponse(_rctx.recipientId(), _rmsgptr); + _rctx.service().sendResponse(_rctx.recipientId(), std::move(_rmsgptr)); /* ++crtreadidx; solid_dbg(generic_logger, Info, crtreadidx); @@ -242,7 +243,7 @@ void server_receive_message(frame::mprpc::ConnectionContext& _rctx, MessagePoint void server_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -364,10 +365,10 @@ int test_keepalive_success(int argc, char* argv[]) writecount = 2; { - MessagePointerT msgptr(frame::mprpc::make_message(crtwriteidx)); + auto msgptr(frame::mprpc::make_message(crtwriteidx)); ++crtwriteidx; mprpcclient.sendMessage( - {"localhost"}, msgptr, + {"localhost"}, std::move(msgptr), initarray[crtwriteidx % initarraysize].flags | frame::mprpc::MessageFlagsE::AwaitResponse); } solid_dbg(generic_logger, Info, "before sleep"); @@ -376,10 +377,10 @@ int test_keepalive_success(int argc, char* argv[]) solid_dbg(generic_logger, Info, "after sleep"); { - MessagePointerT msgptr(frame::mprpc::make_message(crtwriteidx)); + auto msgptr(frame::mprpc::make_message(crtwriteidx)); ++crtwriteidx; mprpcclient.sendMessage( - {"localhost"}, msgptr, + {"localhost"}, std::move(msgptr), initarray[crtwriteidx % initarraysize].flags | frame::mprpc::MessageFlagsE::AwaitResponse); } diff --git a/solid/frame/mprpc/test/test_multiprotocol_basic.cpp b/solid/frame/mprpc/test/test_multiprotocol_basic.cpp index 3209c490..f31eb101 100644 --- a/solid/frame/mprpc/test/test_multiprotocol_basic.cpp +++ b/solid/frame/mprpc/test/test_multiprotocol_basic.cpp @@ -41,7 +41,7 @@ using namespace solid; typedef frame::aio::openssl::Context SecureContextT; namespace { -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; std::atomic wait_count(0); mutex mtx; diff --git a/solid/frame/mprpc/test/test_pool_basic.cpp b/solid/frame/mprpc/test/test_pool_basic.cpp index 1034b0eb..6a992248 100644 --- a/solid/frame/mprpc/test/test_pool_basic.cpp +++ b/solid/frame/mprpc/test/test_pool_basic.cpp @@ -33,7 +33,7 @@ namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -60,11 +60,11 @@ InitStub initarray[] = { std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -std::atomic crtwriteidx(0); -std::atomic crtreadidx(0); -std::atomic crtbackidx(0); -std::atomic crtackidx(0); -std::atomic writecount(0); +std::atomic crtwriteidx(0); +std::atomic crtreadidx(0); +std::atomic crtbackidx(0); +std::atomic crtackidx(0); +std::atomic writecount(0); size_t connection_count(0); bool running = true; @@ -152,7 +152,8 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void client_connection_stop(frame::mprpc::ConnectionContext& _rctx) { @@ -187,7 +188,7 @@ void server_connection_start(frame::mprpc::ConnectionContext& _rctx) void client_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -222,7 +223,7 @@ void client_complete_message( void server_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { if (_rrecv_msg_ptr) { @@ -246,11 +247,13 @@ void server_complete_message( ++crtreadidx; solid_dbg(generic_logger, Info, crtreadidx); - if (crtwriteidx < writecount) { + if (crtwriteidx < writecount and pmprpcclient) { err = pmprpcclient->sendMessage( client_id, frame::mprpc::make_message(crtwriteidx++), initarray[crtwriteidx % initarraysize].flags | frame::mprpc::MessageFlagsE::AwaitResponse); solid_check(!err, "Connection id should not be invalid! " << err.message()); + } else { + solid_check(pmprpcclient, "pmprpcclient should not be nullptr"); } } if (_rsent_msg_ptr) { diff --git a/solid/frame/mprpc/test/test_pool_delay_close.cpp b/solid/frame/mprpc/test/test_pool_delay_close.cpp index 638eed8a..17238e68 100644 --- a/solid/frame/mprpc/test/test_pool_delay_close.cpp +++ b/solid/frame/mprpc/test/test_pool_delay_close.cpp @@ -31,7 +31,7 @@ using namespace solid; namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -150,7 +150,8 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void client_connection_stop(frame::mprpc::ConnectionContext& _rctx) { @@ -177,7 +178,7 @@ void server_connection_start(frame::mprpc::ConnectionContext& _rctx) void client_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " error: " << _rerror.message()); @@ -218,7 +219,7 @@ void client_complete_message( void server_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { if (_rrecv_msg_ptr.get()) { @@ -356,14 +357,14 @@ int test_pool_delay_close(int argc, char* argv[]) writecount = start_count; // { - std::vector msg_vec; + std::vector msg_vec; - for (size_t i = 0; i < start_count; ++i) { - msg_vec.push_back(MessagePointerT(frame::mprpc::make_message(i))); + for (uint32_t i = 0; i < start_count; ++i) { + msg_vec.push_back(frame::mprpc::make_message(i)); } { - std::vector::iterator it = msg_vec.begin(); + auto it = msg_vec.begin(); { ++crtwriteidx; @@ -399,9 +400,9 @@ int test_pool_delay_close(int argc, char* argv[]) }); { - MessagePointerT msgptr(frame::mprpc::make_message(0)); + auto msgptr(frame::mprpc::make_message(0)); ErrorConditionT err = pmprpcclient->sendMessage( - recipinet_id, msgptr, + recipinet_id, std::move(msgptr), {frame::mprpc::MessageFlagsE::AwaitResponse}); solid_dbg(generic_logger, Info, "send message error message: " << err.message()); solid_check(err); diff --git a/solid/frame/mprpc/test/test_pool_force_close.cpp b/solid/frame/mprpc/test/test_pool_force_close.cpp index 733b02d1..201dc877 100644 --- a/solid/frame/mprpc/test/test_pool_force_close.cpp +++ b/solid/frame/mprpc/test/test_pool_force_close.cpp @@ -32,7 +32,7 @@ namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -116,7 +116,7 @@ struct Message : frame::mprpc::Message { if (_rthis.isOnPeer()) { ++crtreadidx; solid_dbg(generic_logger, Info, crtreadidx); - if (crtreadidx == 1) { + if (crtreadidx == 1 and pmprpcclient) { pmprpcclient->forceCloseConnectionPool( recipinet_id, @@ -126,6 +126,8 @@ struct Message : frame::mprpc::Message { running = false; cnd.notify_one(); }); + } else { + solid_check(pmprpcclient, "pmprpcclient should not be nullptr"); } } } @@ -167,7 +169,8 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void client_connection_stop(frame::mprpc::ConnectionContext& _rctx) { @@ -194,7 +197,7 @@ void server_connection_start(frame::mprpc::ConnectionContext& _rctx) void client_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " error: " << _rerror.message()); @@ -208,7 +211,7 @@ void client_complete_message( void server_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(false); @@ -325,14 +328,14 @@ int test_pool_force_close(int argc, char* argv[]) writecount = start_count; // { - std::vector msg_vec; - ErrorConditionT err; + std::vector msg_vec; + ErrorConditionT err; - for (size_t i = 0; i < start_count; ++i) { - msg_vec.push_back(MessagePointerT(frame::mprpc::make_message(i))); + for (uint32_t i = 0; i < start_count; ++i) { + msg_vec.push_back(frame::mprpc::make_message(i)); } { - std::vector::iterator it = msg_vec.begin(); + auto it = msg_vec.begin(); { ++crtwriteidx; diff --git a/solid/frame/mprpc/test/test_protocol_basic.cpp b/solid/frame/mprpc/test/test_protocol_basic.cpp index 7cc0070f..d9b643c3 100644 --- a/solid/frame/mprpc/test/test_protocol_basic.cpp +++ b/solid/frame/mprpc/test/test_protocol_basic.cpp @@ -48,7 +48,7 @@ InitStub initarray[] = { std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -size_t crtwriteidx = 0; +uint32_t crtwriteidx = 0; uint32_t crtreadidx = 0; size_t writecount = 0; @@ -114,12 +114,13 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rmessage_ptr, - MessagePointerT& _rresponse_ptr, + SendMessagePointerT& _rmessage_ptr, + RecvMessagePointerT& _rresponse_ptr, ErrorConditionT const& _rerr); struct Context { @@ -144,15 +145,15 @@ frame::mprpc::ConnectionContext& mprpcconctx(frame::mprpc::TestEntryway::createC void complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rmessage_ptr, - MessagePointerT& _rresponse_ptr, + SendMessagePointerT& _rmessage_ptr, + RecvMessagePointerT& _rresponse_ptr, ErrorConditionT const& _rerr) { if (_rerr) { solid_throw("Message complete with error"); } if (_rmessage_ptr.get()) { - solid_dbg(generic_logger, Info, static_cast(_rmessage_ptr.get())->idx); + solid_dbg(generic_logger, Info, static_cast(_rmessage_ptr.get())->idx); } if (_rresponse_ptr.get()) { @@ -199,17 +200,17 @@ struct Receiver : frame::mprpc::MessageReaderReceiver { { } - void fillRequestVector(size_t _m = 10) + void fillRequestVector(uint32_t const _m = 10) { - for (size_t i = 0; i < _m; ++i) { + for (uint32_t i = 0; i < _m; ++i) { reqvec.push_back(frame::mprpc::RequestId(i, i)); } } - void receiveMessage(frame::mprpc::MessagePointerT<>& _rresponse_ptr, const size_t _msg_type_id) override + void receiveMessage(frame::mprpc::RecvMessagePointerT<>& _rresponse_ptr, const size_t _msg_type_id) override { - frame::mprpc::MessagePointerT<> message_ptr; - ErrorConditionT error; + frame::mprpc::SendMessagePointerT<> message_ptr; + ErrorConditionT error; rprotocol_.complete(_msg_type_id, mprpcconctx, message_ptr, _rresponse_ptr, error); } @@ -255,8 +256,8 @@ struct Sender : frame::mprpc::MessageWriterSender { ErrorConditionT completeMessage(frame::mprpc::MessageBundle& _rmsgbundle, frame::mprpc::MessageId const& /*_rmsgid*/) override { solid_dbg(generic_logger, Info, "writer complete message"); - frame::mprpc::MessagePointerT<> response_ptr; - ErrorConditionT error; + frame::mprpc::RecvMessagePointerT<> response_ptr; + ErrorConditionT error; rprotocol_.complete(_rmsgbundle.message_type_id, mprpcconctx, _rmsgbundle.message_ptr, response_ptr, error); return ErrorConditionT(); } @@ -316,7 +317,7 @@ int test_protocol_basic(int argc, char* argv[]) frame::mprpc::MessageId pool_msg_id; msgbundle.message_flags = initarray[crtwriteidx % initarraysize].flags; - msgbundle.message_ptr = MessagePointerT(frame::mprpc::make_message(crtwriteidx)); + msgbundle.message_ptr = SendMessagePointerT(frame::mprpc::make_message(crtwriteidx)); msgbundle.message_type_id = ctx.mprpcprotocol->typeIndex(msgbundle.message_ptr.get()); const bool rv = mprpcmsgwriter.enqueue( diff --git a/solid/frame/mprpc/test/test_protocol_cancel.cpp b/solid/frame/mprpc/test/test_protocol_cancel.cpp index 2b95d01d..f2f75196 100644 --- a/solid/frame/mprpc/test/test_protocol_cancel.cpp +++ b/solid/frame/mprpc/test/test_protocol_cancel.cpp @@ -104,12 +104,13 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rmessage_ptr, - MessagePointerT& _rresponse_ptr, + SendMessagePointerT& _rmessage_ptr, + RecvMessagePointerT& _rresponse_ptr, ErrorConditionT const& _rerr); struct Context { @@ -153,35 +154,35 @@ struct Sender : frame::mprpc::MessageWriterSender { ErrorConditionT completeMessage(frame::mprpc::MessageBundle& _rmsgbundle, frame::mprpc::MessageId const& /*_rmsgid*/) override { solid_dbg(generic_logger, Info, "writer complete message"); - frame::mprpc::MessagePointerT<> response_ptr; - ErrorConditionT error; + frame::mprpc::RecvMessagePointerT<> response_ptr; + ErrorConditionT error; rprotocol_.complete(_rmsgbundle.message_type_id, mprpcconctx, _rmsgbundle.message_ptr, response_ptr, error); return ErrorConditionT(); } bool cancelMessage(frame::mprpc::MessageBundle& _rmsgbundle, frame::mprpc::MessageId const& /*_rmsgid*/) override { - solid_dbg(generic_logger, Info, "Cancel message " << static_cast(*_rmsgbundle.message_ptr).str.size()); + solid_dbg(generic_logger, Info, "Cancel message " << static_cast(*_rmsgbundle.message_ptr).str.size()); return true; } }; void complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rmessage_ptr, - MessagePointerT& _rresponse_ptr, + SendMessagePointerT& _rmessage_ptr, + RecvMessagePointerT& _rresponse_ptr, ErrorConditionT const& _rerr) { if (_rerr && _rerr != frame::mprpc::error_message_canceled) { solid_throw("Message complete with error"); } if (_rmessage_ptr.get()) { - size_t idx = static_cast(*_rmessage_ptr).idx; + size_t idx = static_cast(*_rmessage_ptr).idx; if (crtreadidx) { // not the first message solid_check((!_rerr && !initarray[idx % initarraysize].cancel) || (initarray[idx % initarraysize].cancel && _rerr == frame::mprpc::error_message_canceled)); } - solid_dbg(generic_logger, Info, static_cast(*_rmessage_ptr).str.size() << ' ' << _rerr.message()); + solid_dbg(generic_logger, Info, static_cast(*_rmessage_ptr).str.size() << ' ' << _rerr.message()); } if (_rresponse_ptr.get()) { if (!static_cast(*_rresponse_ptr).check()) { @@ -229,10 +230,10 @@ struct Receiver : frame::mprpc::MessageReaderReceiver { } } - void receiveMessage(frame::mprpc::MessagePointerT<>& _rresponse_ptr, const size_t _msg_type_id) override + void receiveMessage(frame::mprpc::RecvMessagePointerT<>& _rresponse_ptr, const size_t _msg_type_id) override { - frame::mprpc::MessagePointerT<> message_ptr; - ErrorConditionT error; + frame::mprpc::SendMessagePointerT<> message_ptr; + ErrorConditionT error; rprotocol_.complete(_msg_type_id, mprpcconctx, message_ptr, _rresponse_ptr, error); } @@ -311,7 +312,7 @@ int test_protocol_cancel(int argc, char* argv[]) frame::mprpc::MessageId pool_msg_id; msgbundle.message_flags = initarray[crtwriteidx % initarraysize].flags; - msgbundle.message_ptr = MessagePointerT(frame::mprpc::make_message(crtwriteidx)); + msgbundle.message_ptr = SendMessagePointerT(frame::mprpc::make_message(crtwriteidx)); msgbundle.message_type_id = ctx.mprpcprotocol->typeIndex(msgbundle.message_ptr.get()); bool rv = mprpcmsgwriter.enqueue( diff --git a/solid/frame/mprpc/test/test_protocol_synchronous.cpp b/solid/frame/mprpc/test/test_protocol_synchronous.cpp index 5ca9192e..56b4e6eb 100644 --- a/solid/frame/mprpc/test/test_protocol_synchronous.cpp +++ b/solid/frame/mprpc/test/test_protocol_synchronous.cpp @@ -32,9 +32,9 @@ InitStub initarray[] = { std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -size_t crtwriteidx = 0; -size_t crtreadidx = 0; -size_t writecount = 0; +uint32_t crtwriteidx = 0; +uint32_t crtreadidx = 0; +size_t writecount = 0; size_t real_size(size_t _sz) { @@ -98,12 +98,13 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rmessage_ptr, - MessagePointerT& _rresponse_ptr, + SendMessagePointerT& _rmessage_ptr, + RecvMessagePointerT& _rresponse_ptr, ErrorConditionT const& _rerr); struct Context { @@ -128,15 +129,15 @@ frame::mprpc::ConnectionContext& mprpcconctx(frame::mprpc::TestEntryway::createC void complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rmessage_ptr, - MessagePointerT& _rresponse_ptr, + SendMessagePointerT& _rmessage_ptr, + RecvMessagePointerT& _rresponse_ptr, ErrorConditionT const& _rerr) { if (_rerr) { solid_throw("Message complete with error"); } if (_rmessage_ptr.get()) { - solid_dbg(generic_logger, Info, static_cast(_rmessage_ptr.get())->idx); + solid_dbg(generic_logger, Info, static_cast(_rmessage_ptr.get())->idx); } if (_rresponse_ptr.get()) { @@ -157,7 +158,7 @@ void complete_message( frame::mprpc::MessageId pool_msg_id; msgbundle.message_flags = initarray[crtwriteidx % initarraysize].flags; - msgbundle.message_ptr = MessagePointerT(frame::mprpc::make_message(crtwriteidx)); + msgbundle.message_ptr = SendMessagePointerT(frame::mprpc::make_message(crtwriteidx)); msgbundle.message_type_id = ctx.mprpcprotocol->typeIndex(msgbundle.message_ptr.get()); const bool rv = ctx.mprpcmsgwriter->enqueue( @@ -187,15 +188,15 @@ struct Receiver : frame::mprpc::MessageReaderReceiver { void fillRequestVector(size_t _m = 10) { - for (size_t i = 0; i < _m; ++i) { + for (uint32_t i = 0; i < _m; ++i) { reqvec.push_back(frame::mprpc::RequestId(i, i)); } } - void receiveMessage(frame::mprpc::MessagePointerT<>& _rresponse_ptr, const size_t _msg_type_id) override + void receiveMessage(frame::mprpc::RecvMessagePointerT<>& _rresponse_ptr, const size_t _msg_type_id) override { - frame::mprpc::MessagePointerT<> message_ptr; - ErrorConditionT error; + frame::mprpc::SendMessagePointerT<> message_ptr; + ErrorConditionT error; rprotocol_.complete(_msg_type_id, mprpcconctx, message_ptr, _rresponse_ptr, error); } @@ -241,8 +242,8 @@ struct Sender : frame::mprpc::MessageWriterSender { ErrorConditionT completeMessage(frame::mprpc::MessageBundle& _rmsgbundle, frame::mprpc::MessageId const& /*_rmsgid*/) override { solid_dbg(generic_logger, Info, "writer complete message"); - frame::mprpc::MessagePointerT<> response_ptr; - ErrorConditionT error; + frame::mprpc::RecvMessagePointerT<> response_ptr; + ErrorConditionT error; rprotocol_.complete(_rmsgbundle.message_type_id, mprpcconctx, _rmsgbundle.message_ptr, response_ptr, error); return ErrorConditionT(); } @@ -302,7 +303,7 @@ int test_protocol_synchronous(int argc, char* argv[]) frame::mprpc::MessageId pool_msg_id; msgbundle.message_flags = initarray[crtwriteidx % initarraysize].flags; - msgbundle.message_ptr = MessagePointerT(frame::mprpc::make_message(crtwriteidx)); + msgbundle.message_ptr = SendMessagePointerT(frame::mprpc::make_message(crtwriteidx)); msgbundle.message_type_id = ctx.mprpcprotocol->typeIndex(msgbundle.message_ptr.get()); bool rv = mprpcmsgwriter.enqueue( diff --git a/solid/frame/mprpc/test/test_raw_basic.cpp b/solid/frame/mprpc/test/test_raw_basic.cpp index 150fde3a..24081ca2 100644 --- a/solid/frame/mprpc/test/test_raw_basic.cpp +++ b/solid/frame/mprpc/test/test_raw_basic.cpp @@ -30,7 +30,7 @@ using namespace solid; namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -57,11 +57,11 @@ InitStub initarray[] = { std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -std::atomic crtwriteidx(0); -std::atomic crtreadidx(0); -std::atomic crtbackidx(0); -std::atomic crtackidx(0); -std::atomic writecount(0); +std::atomic crtwriteidx(0); +std::atomic crtreadidx(0); +std::atomic crtbackidx(0); +std::atomic crtackidx(0); +std::atomic writecount(0); size_t connection_count(0); @@ -155,7 +155,8 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void client_connection_stop(frame::mprpc::ConnectionContext& _rctx) { @@ -249,7 +250,7 @@ void server_connection_start(frame::mprpc::ConnectionContext& _rctx) void client_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -284,7 +285,7 @@ void client_complete_message( void server_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { if (_rrecv_msg_ptr) { @@ -425,10 +426,10 @@ int test_raw_basic(int argc, char* argv[]) writecount = 10; // initarraysize * 10;//start_count;// for (; crtwriteidx < start_count;) { - MessagePointerT msgptr(frame::mprpc::make_message(crtwriteidx)); + auto msgptr(frame::mprpc::make_message(crtwriteidx)); ++crtwriteidx; mprpcclient.sendMessage( - {"localhost"}, msgptr, + {"localhost"}, std::move(msgptr), initarray[crtwriteidx % initarraysize].flags | frame::mprpc::MessageFlagsE::AwaitResponse); } diff --git a/solid/frame/mprpc/test/test_raw_proxy.cpp b/solid/frame/mprpc/test/test_raw_proxy.cpp index 956a8594..f34e6ee2 100644 --- a/solid/frame/mprpc/test/test_raw_proxy.cpp +++ b/solid/frame/mprpc/test/test_raw_proxy.cpp @@ -29,7 +29,7 @@ using namespace solid; namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -56,11 +56,11 @@ InitStub initarray[] = { std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -std::atomic crtwriteidx(0); -std::atomic crtreadidx(0); -std::atomic crtbackidx(0); -std::atomic crtackidx(0); -std::atomic writecount(0); +std::atomic crtwriteidx(0); +std::atomic crtreadidx(0); +std::atomic crtbackidx(0); +std::atomic crtackidx(0); +std::atomic writecount(0); size_t connection_count(0); @@ -154,7 +154,8 @@ struct Message : frame::mprpc::Message { } }; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; void client_connection_stop(frame::mprpc::ConnectionContext& _rctx) { @@ -249,7 +250,7 @@ void server_connection_start(frame::mprpc::ConnectionContext& _rctx) void client_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -284,7 +285,7 @@ void client_complete_message( void server_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { if (_rrecv_msg_ptr) { @@ -425,10 +426,10 @@ int test_raw_proxy(int argc, char* argv[]) writecount = 10; // initarraysize * 10;//start_count;// for (; crtwriteidx < start_count;) { - MessagePointerT msgptr(frame::mprpc::make_message(crtwriteidx)); + auto msgptr(frame::mprpc::make_message(crtwriteidx)); ++crtwriteidx; mprpcclient.sendMessage( - {"localhost"}, msgptr, + {"localhost"}, std::move(msgptr), initarray[crtwriteidx % initarraysize].flags | frame::mprpc::MessageFlagsE::AwaitResponse); } diff --git a/solid/frame/mprpc/test/test_relay_basic.cpp b/solid/frame/mprpc/test/test_relay_basic.cpp index ba04ef15..1425c5c7 100644 --- a/solid/frame/mprpc/test/test_relay_basic.cpp +++ b/solid/frame/mprpc/test/test_relay_basic.cpp @@ -34,7 +34,7 @@ using namespace solid; namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -66,12 +66,12 @@ InitStub initarray[] = { std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -std::atomic crtwriteidx(0); -std::atomic crtreadidx(0); -std::atomic crtbackidx(0); -std::atomic crtackidx(0); -std::atomic writecount(0); -std::atomic connection_count(0); +std::atomic crtwriteidx(0); +std::atomic crtreadidx(0); +std::atomic crtbackidx(0); +std::atomic crtackidx(0); +std::atomic writecount(0); +std::atomic connection_count(0); std::atomic running = true; mutex mtx; @@ -187,8 +187,11 @@ struct Message : frame::mprpc::Message { } }; -using RegisterPointerT = solid::frame::mprpc::MessagePointerT; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendRegisterPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvRegisterPointerT = solid::frame::mprpc::RecvMessagePointerT; + +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; //----------------------------------------------------------------------------- // PeerA @@ -209,7 +212,7 @@ void peera_connection_stop(frame::mprpc::ConnectionContext& _rctx) void peera_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " error: " << _rerror.message()); @@ -262,7 +265,7 @@ void peerb_connection_stop(frame::mprpc::ConnectionContext& _rctx) void peerb_complete_register( frame::mprpc::ConnectionContext& _rctx, - RegisterPointerT& _rsent_msg_ptr, RegisterPointerT& _rrecv_msg_ptr, + SendRegisterPointerT& _rsent_msg_ptr, RecvRegisterPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -280,7 +283,7 @@ void peerb_complete_register( void peerb_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { if (_rrecv_msg_ptr) { @@ -411,8 +414,8 @@ int test_relay_basic(int argc, char* argv[]) auto con_register = [&relay_engine, test_ptr = std::move(test_ptr)]( frame::mprpc::ConnectionContext& _rctx, - RegisterPointerT& _rsent_msg_ptr, - RegisterPointerT& _rrecv_msg_ptr, + SendRegisterPointerT& _rsent_msg_ptr, + RecvRegisterPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) mutable { solid_check(!_rerror); solid_check(*test_ptr == "test", ""); @@ -573,6 +576,9 @@ int test_relay_basic(int argc, char* argv[]) solid_throw("Not all messages were completed"); } + cout << " mprpcrelay statistics: " << mprpcrelay.statistic() << endl; + cout << " mprpcpeera statistics: " << mprpcpeera.statistic() << endl; + cout << " mprpcpeerb statistics: " << mprpcpeerb.statistic() << endl; // m.stop(); } diff --git a/solid/frame/mprpc/test/test_relay_cancel_request.cpp b/solid/frame/mprpc/test/test_relay_cancel_request.cpp index 8121b0e3..b10eb8e6 100644 --- a/solid/frame/mprpc/test/test_relay_cancel_request.cpp +++ b/solid/frame/mprpc/test/test_relay_cancel_request.cpp @@ -34,7 +34,7 @@ using namespace solid; namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -69,7 +69,7 @@ using MessageIdVectorT = std::deque; std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -std::atomic crtwriteidx(0); +std::atomic crtwriteidx(0); std::atomic writecount(0); std::atomic created_count(0); std::atomic cancelable_created_count(0); @@ -235,8 +235,12 @@ struct Message : frame::mprpc::Message { return true; } }; -using RegisterPointerT = solid::frame::mprpc::MessagePointerT; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; + +using SendRegisterPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvRegisterPointerT = solid::frame::mprpc::RecvMessagePointerT; + +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; //----------------------------------------------------------------------------- // PeerA @@ -257,7 +261,7 @@ void peera_connection_stop(frame::mprpc::ConnectionContext& _rctx) void peera_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " error: " << _rerror.message()); @@ -308,7 +312,7 @@ void peerb_connection_stop(frame::mprpc::ConnectionContext& _rctx) void peerb_complete_register( frame::mprpc::ConnectionContext& _rctx, - RegisterPointerT& _rsent_msg_ptr, RegisterPointerT& _rrecv_msg_ptr, + SendRegisterPointerT& _rsent_msg_ptr, RecvRegisterPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -326,7 +330,7 @@ void peerb_complete_register( void peerb_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { if (_rrecv_msg_ptr) { @@ -462,8 +466,8 @@ int test_relay_cancel_request(int argc, char* argv[]) }; auto con_register = [&relay_engine]( frame::mprpc::ConnectionContext& _rctx, - RegisterPointerT& _rsent_msg_ptr, - RegisterPointerT& _rrecv_msg_ptr, + SendRegisterPointerT& _rsent_msg_ptr, + RecvRegisterPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(!_rerror); if (_rrecv_msg_ptr) { diff --git a/solid/frame/mprpc/test/test_relay_cancel_response.cpp b/solid/frame/mprpc/test/test_relay_cancel_response.cpp index ac11fc2a..e32f21ad 100644 --- a/solid/frame/mprpc/test/test_relay_cancel_response.cpp +++ b/solid/frame/mprpc/test/test_relay_cancel_response.cpp @@ -34,7 +34,7 @@ using namespace solid; namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -69,7 +69,7 @@ using MessageIdVectorT = std::deque; std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -std::atomic crtwriteidx(0); +std::atomic crtwriteidx(0); std::atomic writecount(0); std::atomic created_count(0); std::atomic cancelable_created_count(0); @@ -234,8 +234,11 @@ struct Message : frame::mprpc::Message { } }; -using RegisterPointerT = solid::frame::mprpc::MessagePointerT; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendRegisterPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvRegisterPointerT = solid::frame::mprpc::RecvMessagePointerT; + +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; //----------------------------------------------------------------------------- // PeerA @@ -256,7 +259,7 @@ void peera_connection_stop(frame::mprpc::ConnectionContext& _rctx) void peera_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " error: " << _rerror.message()); @@ -304,7 +307,7 @@ void peerb_connection_stop(frame::mprpc::ConnectionContext& _rctx) void peerb_complete_register( frame::mprpc::ConnectionContext& _rctx, - RegisterPointerT& _rsent_msg_ptr, RegisterPointerT& _rrecv_msg_ptr, + SendRegisterPointerT& _rsent_msg_ptr, RecvRegisterPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -322,7 +325,7 @@ void peerb_complete_register( void peerb_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { if (_rrecv_msg_ptr) { @@ -455,8 +458,8 @@ int test_relay_cancel_response(int argc, char* argv[]) }; auto con_register = [&relay_engine]( frame::mprpc::ConnectionContext& _rctx, - RegisterPointerT& _rsent_msg_ptr, - RegisterPointerT& _rrecv_msg_ptr, + SendRegisterPointerT& _rsent_msg_ptr, + RecvRegisterPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(!_rerror); if (_rrecv_msg_ptr) { diff --git a/solid/frame/mprpc/test/test_relay_close_request.cpp b/solid/frame/mprpc/test/test_relay_close_request.cpp index 39a7d7b5..4b5dff07 100644 --- a/solid/frame/mprpc/test/test_relay_close_request.cpp +++ b/solid/frame/mprpc/test/test_relay_close_request.cpp @@ -36,7 +36,7 @@ using namespace solid; namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -55,7 +55,7 @@ using MessageIdVectorT = std::deque; std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -std::atomic crtwriteidx(0); +std::atomic crtwriteidx(0); std::atomic writecount(0); std::atomic created_count(0); std::atomic canceled_count(0); @@ -221,9 +221,11 @@ struct Message : frame::mprpc::Message { } }; -using RegisterPointerT = solid::frame::mprpc::MessagePointerT; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendRegisterPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvRegisterPointerT = solid::frame::mprpc::RecvMessagePointerT; +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; //----------------------------------------------------------------------------- // PeerA //----------------------------------------------------------------------------- @@ -243,7 +245,7 @@ void peera_connection_stop(frame::mprpc::ConnectionContext& _rctx) void peera_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " error: " << _rerror.message()); @@ -276,7 +278,7 @@ void peerb_connection_stop(frame::mprpc::ConnectionContext& _rctx) void peerb_complete_register( frame::mprpc::ConnectionContext& _rctx, - RegisterPointerT& _rsent_msg_ptr, RegisterPointerT& _rrecv_msg_ptr, + SendRegisterPointerT& _rsent_msg_ptr, RecvRegisterPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -294,7 +296,7 @@ void peerb_complete_register( void peerb_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { if (_rrecv_msg_ptr) { @@ -415,8 +417,8 @@ int test_relay_close_request(int argc, char* argv[]) }; auto con_register = [&relay_engine]( frame::mprpc::ConnectionContext& _rctx, - RegisterPointerT& _rsent_msg_ptr, - RegisterPointerT& _rrecv_msg_ptr, + SendRegisterPointerT& _rsent_msg_ptr, + RecvRegisterPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(!_rerror); if (_rrecv_msg_ptr) { diff --git a/solid/frame/mprpc/test/test_relay_close_response.cpp b/solid/frame/mprpc/test/test_relay_close_response.cpp index 3fb4b160..b4fb6390 100644 --- a/solid/frame/mprpc/test/test_relay_close_response.cpp +++ b/solid/frame/mprpc/test/test_relay_close_response.cpp @@ -36,7 +36,7 @@ using namespace solid; namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -55,7 +55,7 @@ using MessageIdVectorT = std::deque; std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -std::atomic crtwriteidx(0); +std::atomic crtwriteidx(0); std::atomic writecount(0); std::atomic created_count(0); std::atomic canceled_count(0); @@ -217,8 +217,11 @@ struct Message : frame::mprpc::Message { } }; -using RegisterPointerT = solid::frame::mprpc::MessagePointerT; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendRegisterPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvRegisterPointerT = solid::frame::mprpc::RecvMessagePointerT; + +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; //----------------------------------------------------------------------------- // PeerA @@ -239,7 +242,7 @@ void peera_connection_stop(frame::mprpc::ConnectionContext& _rctx) void peera_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " error: " << _rerror.message()); @@ -277,7 +280,7 @@ void peerb_connection_stop(frame::mprpc::ConnectionContext& _rctx) void peerb_complete_register( frame::mprpc::ConnectionContext& _rctx, - RegisterPointerT& _rsent_msg_ptr, RegisterPointerT& _rrecv_msg_ptr, + SendRegisterPointerT& _rsent_msg_ptr, RecvRegisterPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -295,7 +298,7 @@ void peerb_complete_register( void peerb_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { if (_rrecv_msg_ptr) { @@ -415,8 +418,8 @@ int test_relay_close_response(int argc, char* argv[]) }; auto con_register = [&relay_engine]( frame::mprpc::ConnectionContext& _rctx, - RegisterPointerT& _rsent_msg_ptr, - RegisterPointerT& _rrecv_msg_ptr, + SendRegisterPointerT& _rsent_msg_ptr, + RecvRegisterPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(!_rerror); if (_rrecv_msg_ptr) { diff --git a/solid/frame/mprpc/test/test_relay_detect_close.cpp b/solid/frame/mprpc/test/test_relay_detect_close.cpp index 66f14b1f..df007b20 100644 --- a/solid/frame/mprpc/test/test_relay_detect_close.cpp +++ b/solid/frame/mprpc/test/test_relay_detect_close.cpp @@ -36,7 +36,7 @@ using namespace solid; namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; bool running = true; mutex mtx; @@ -104,8 +104,11 @@ struct Message : frame::mprpc::Message { } }; -using RegisterPointerT = solid::frame::mprpc::MessagePointerT; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendRegisterPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvRegisterPointerT = solid::frame::mprpc::RecvMessagePointerT; + +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; //----------------------------------------------------------------------------- // PeerA @@ -123,7 +126,7 @@ void peera_connection_stop(frame::mprpc::ConnectionContext& _rctx) void peera_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " error: " << _rerror.message()); @@ -136,12 +139,10 @@ void peera_complete_message( } void peera_complete_detect_close( - frame::mprpc::ConnectionContext& _rctx, - solid::frame::mprpc::MessagePointerT& _rsent_msg_ptr, solid::frame::mprpc::MessagePointerT& _rrecv_msg_ptr, + frame::mprpc::ConnectionContext& _rctx, + solid::frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, solid::frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { - static size_t call_count = 0; - ++call_count; solid_dbg(generic_logger, Info, _rctx.recipientId() << " error: " << _rerror.message()); if (_rrecv_msg_ptr) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " peera received DetectCloseMessage " << _rrecv_msg_ptr->idx); @@ -172,7 +173,7 @@ void peerb_connection_stop(frame::mprpc::ConnectionContext& _rctx) void peerb_complete_register( frame::mprpc::ConnectionContext& _rctx, - RegisterPointerT& _rsent_msg_ptr, RegisterPointerT& _rrecv_msg_ptr, + SendRegisterPointerT& _rsent_msg_ptr, RecvRegisterPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -190,7 +191,7 @@ void peerb_complete_register( void peerb_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { if (_rrecv_msg_ptr) { @@ -226,8 +227,8 @@ void peerb_complete_message( } void peerb_complete_detect_close( - frame::mprpc::ConnectionContext& _rctx, - solid::frame::mprpc::MessagePointerT& _rsent_msg_ptr, solid::frame::mprpc::MessagePointerT& _rrecv_msg_ptr, + frame::mprpc::ConnectionContext& _rctx, + solid::frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, solid::frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { if (_rrecv_msg_ptr) { @@ -284,8 +285,8 @@ int test_relay_detect_close(int argc, char* argv[]) }; auto con_register = [&relay_engine]( frame::mprpc::ConnectionContext& _rctx, - RegisterPointerT& _rsent_msg_ptr, - RegisterPointerT& _rrecv_msg_ptr, + SendRegisterPointerT& _rsent_msg_ptr, + RecvRegisterPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(!_rerror); if (_rrecv_msg_ptr) { diff --git a/solid/frame/mprpc/test/test_relay_detect_close_while_response.cpp b/solid/frame/mprpc/test/test_relay_detect_close_while_response.cpp index c80982cd..95de03f5 100644 --- a/solid/frame/mprpc/test/test_relay_detect_close_while_response.cpp +++ b/solid/frame/mprpc/test/test_relay_detect_close_while_response.cpp @@ -36,7 +36,7 @@ using namespace solid; namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; bool running = true; mutex mtx; @@ -150,8 +150,11 @@ struct Message : frame::mprpc::Message { } }; -using RegisterPointerT = solid::frame::mprpc::MessagePointerT; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendRegisterPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvRegisterPointerT = solid::frame::mprpc::RecvMessagePointerT; + +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; //----------------------------------------------------------------------------- // PeerA @@ -169,7 +172,7 @@ void peera_connection_stop(frame::mprpc::ConnectionContext& _rctx) void peera_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " error: " << _rerror.message()); @@ -178,12 +181,10 @@ void peera_complete_message( } void peera_complete_detect_close( - frame::mprpc::ConnectionContext& _rctx, - solid::frame::mprpc::MessagePointerT& _rsent_msg_ptr, solid::frame::mprpc::MessagePointerT& _rrecv_msg_ptr, + frame::mprpc::ConnectionContext& _rctx, + solid::frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, solid::frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { - static size_t call_count = 0; - ++call_count; solid_dbg(generic_logger, Info, _rctx.recipientId() << " error: " << _rerror.message()); if (_rrecv_msg_ptr) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " peera received DetectCloseMessage " << _rrecv_msg_ptr->idx); @@ -215,7 +216,7 @@ void peerb_connection_stop(frame::mprpc::ConnectionContext& _rctx) void peerb_complete_register( frame::mprpc::ConnectionContext& _rctx, - RegisterPointerT& _rsent_msg_ptr, RegisterPointerT& _rrecv_msg_ptr, + SendRegisterPointerT& _rsent_msg_ptr, RecvRegisterPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -233,7 +234,7 @@ void peerb_complete_register( void peerb_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { if (_rrecv_msg_ptr) { @@ -265,8 +266,8 @@ void peerb_complete_message( } void peerb_complete_detect_close( - frame::mprpc::ConnectionContext& _rctx, - solid::frame::mprpc::MessagePointerT& _rsent_msg_ptr, solid::frame::mprpc::MessagePointerT& _rrecv_msg_ptr, + frame::mprpc::ConnectionContext& _rctx, + solid::frame::mprpc::SendMessagePointerT& _rsent_msg_ptr, solid::frame::mprpc::RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { if (_rrecv_msg_ptr) { @@ -323,8 +324,8 @@ int test_relay_detect_close_while_response(int argc, char* argv[]) }; auto con_register = [&relay_engine]( frame::mprpc::ConnectionContext& _rctx, - RegisterPointerT& _rsent_msg_ptr, - RegisterPointerT& _rrecv_msg_ptr, + SendRegisterPointerT& _rsent_msg_ptr, + RecvRegisterPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(!_rerror); if (_rrecv_msg_ptr) { diff --git a/solid/frame/mprpc/test/test_relay_disabled.cpp b/solid/frame/mprpc/test/test_relay_disabled.cpp index 31710c16..b1b66d11 100644 --- a/solid/frame/mprpc/test/test_relay_disabled.cpp +++ b/solid/frame/mprpc/test/test_relay_disabled.cpp @@ -32,7 +32,7 @@ using namespace solid; namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -64,11 +64,11 @@ InitStub initarray[] = { std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -std::atomic crtwriteidx(0); -std::atomic crtreadidx(0); -std::atomic crtbackidx(0); -std::atomic crtackidx(0); -std::atomic writecount(0); +std::atomic crtwriteidx(0); +std::atomic crtreadidx(0); +std::atomic crtbackidx(0); +std::atomic crtackidx(0); +std::atomic writecount(0); size_t connection_count(0); @@ -185,8 +185,12 @@ struct Message : frame::mprpc::Message { return true; } }; -using RegisterPointerT = solid::frame::mprpc::MessagePointerT; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; + +using SendRegisterPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvRegisterPointerT = solid::frame::mprpc::RecvMessagePointerT; + +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; //----------------------------------------------------------------------------- // PeerA @@ -208,7 +212,7 @@ void peera_connection_stop(frame::mprpc::ConnectionContext& _rctx) void peera_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " error: " << _rerror.message()); @@ -246,7 +250,7 @@ void peerb_connection_stop(frame::mprpc::ConnectionContext& _rctx) void peerb_complete_register( frame::mprpc::ConnectionContext& _rctx, - RegisterPointerT& _rsent_msg_ptr, RegisterPointerT& _rrecv_msg_ptr, + SendRegisterPointerT& _rsent_msg_ptr, RecvRegisterPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -264,7 +268,7 @@ void peerb_complete_register( void peerb_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { if (_rrecv_msg_ptr) { @@ -375,8 +379,8 @@ int test_relay_disabled(int argc, char* argv[]) auto con_stop = [](frame::mprpc::ConnectionContext& _rctx) {}; auto con_register = []( frame::mprpc::ConnectionContext& _rctx, - RegisterPointerT& _rsent_msg_ptr, - RegisterPointerT& _rrecv_msg_ptr, + SendRegisterPointerT& _rsent_msg_ptr, + RecvRegisterPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { }; diff --git a/solid/frame/mprpc/test/test_relay_split.cpp b/solid/frame/mprpc/test/test_relay_split.cpp index d159c37c..6ca4d981 100644 --- a/solid/frame/mprpc/test/test_relay_split.cpp +++ b/solid/frame/mprpc/test/test_relay_split.cpp @@ -33,7 +33,7 @@ using namespace solid; namespace { using AioSchedulerT = frame::Scheduler>; using SecureContextT = frame::aio::openssl::Context; -using CallPoolT = ThreadPool, Function>; +using CallPoolT = ThreadPool, Function64T>; struct InitStub { size_t size; @@ -65,12 +65,12 @@ InitStub initarray[] = { std::string pattern; const size_t initarraysize = sizeof(initarray) / sizeof(InitStub); -std::atomic crtwriteidx(0); -std::atomic crtreadidx(0); -std::atomic crtbackidx(0); -std::atomic crtackidx(0); -std::atomic writecount(0); -std::atomic connection_count(0); +std::atomic crtwriteidx(0); +std::atomic crtreadidx(0); +std::atomic crtbackidx(0); +std::atomic crtackidx(0); +std::atomic writecount(0); +std::atomic connection_count(0); std::atomic running = true; mutex mtx; @@ -204,9 +204,12 @@ struct Message : frame::mprpc::Message { return true; } }; -using RegisterPointerT = solid::frame::mprpc::MessagePointerT; -using MessagePointerT = solid::frame::mprpc::MessagePointerT; +using SendRegisterPointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvRegisterPointerT = solid::frame::mprpc::RecvMessagePointerT; + +using SendMessagePointerT = solid::frame::mprpc::SendMessagePointerT; +using RecvMessagePointerT = solid::frame::mprpc::RecvMessagePointerT; //----------------------------------------------------------------------------- // PeerA //----------------------------------------------------------------------------- @@ -226,7 +229,7 @@ void peera_connection_stop(frame::mprpc::ConnectionContext& _rctx) void peera_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId() << " error: " << _rerror.message()); @@ -292,7 +295,7 @@ void peerb_connection_stop(frame::mprpc::ConnectionContext& _rctx) void peerb_complete_register( frame::mprpc::ConnectionContext& _rctx, - RegisterPointerT& _rsent_msg_ptr, RegisterPointerT& _rrecv_msg_ptr, + SendRegisterPointerT& _rsent_msg_ptr, RecvRegisterPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_dbg(generic_logger, Info, _rctx.recipientId()); @@ -310,7 +313,7 @@ void peerb_complete_register( void peerb_complete_message( frame::mprpc::ConnectionContext& _rctx, - MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + SendMessagePointerT& _rsent_msg_ptr, RecvMessagePointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { if (_rrecv_msg_ptr) { @@ -336,7 +339,7 @@ void peerb_complete_message( // - it must always arive last //_rrecv_msg_ptr->str.clear(); } - err = _rctx.service().sendResponse(_rctx.recipientId(), _rrecv_msg_ptr, + err = _rctx.service().sendResponse(_rctx.recipientId(), std::move(_rrecv_msg_ptr), {frame::mprpc::MessageFlagsE::ResponseLast}); solid_check(!err, "Connection id should not be invalid! " << err.message()); @@ -440,8 +443,8 @@ int test_relay_split(int argc, char* argv[]) auto con_register = [&relay_engine, test_ptr = std::move(test_ptr)]( frame::mprpc::ConnectionContext& _rctx, - RegisterPointerT& _rsent_msg_ptr, - RegisterPointerT& _rrecv_msg_ptr, + SendRegisterPointerT& _rsent_msg_ptr, + RecvRegisterPointerT& _rrecv_msg_ptr, ErrorConditionT const& _rerror) { solid_check(!_rerror); solid_check(*test_ptr == "test", ""); diff --git a/solid/frame/reactor.hpp b/solid/frame/reactor.hpp index 2b1c34c3..5d2ecdc2 100644 --- a/solid/frame/reactor.hpp +++ b/solid/frame/reactor.hpp @@ -15,6 +15,7 @@ #include "solid/system/log.hpp" #include "solid/system/pimpl.hpp" #include "solid/utility/event.hpp" +#include "solid/utility/function.hpp" #include "solid/utility/queue.hpp" #include @@ -110,7 +111,7 @@ class Reactor : public frame::ReactorBase { public: using StatisticT = ReactorStatistic; - using EventFunctionT = solid_function_t(void(ReactorContext&, EventBase&&)); + using EventFunctionT = SmallFunctionT; bool start(); void stop() override; @@ -532,7 +533,7 @@ class Reactor : public impl::Reactor { }; constexpr size_t reactor_default_event_small_size = std::max(sizeof(Function), sizeof(std::function)); -using ReactorEventT = Event; +using ReactorEventT = Event; using ReactorT = Reactor; } // namespace frame diff --git a/solid/frame/reactorbase.hpp b/solid/frame/reactorbase.hpp index 6a3be829..64497887 100644 --- a/solid/frame/reactorbase.hpp +++ b/solid/frame/reactorbase.hpp @@ -56,10 +56,11 @@ inline constexpr static auto computeCounter(const IndexT _index, const size_t _c return (_index / _capacity) & std::numeric_limits::max(); } -struct WakeStubBase { +class WakeStubBase { AtomicCounterT produce_count_{0}; AtomicCounterT consume_count_{static_cast(-1)}; +public: template void waitWhilePush(Statistic& _rstats, const AtomicCounterValueT _count, const size_t _spin_count = 1) noexcept { @@ -80,7 +81,6 @@ struct WakeStubBase { void notifyWhilePush() noexcept { ++consume_count_; - std::atomic_notify_all(&consume_count_); } void notifyWhilePop() noexcept diff --git a/solid/frame/schedulerbase.hpp b/solid/frame/schedulerbase.hpp index 678a31a2..50a3f2e3 100644 --- a/solid/frame/schedulerbase.hpp +++ b/solid/frame/schedulerbase.hpp @@ -24,8 +24,7 @@ class Service; class ReactorBase; class ActorBase; -// typedef FunctorReference ScheduleFunctorT; -typedef solid_function_t(bool(ReactorBase&)) ScheduleFunctionT; +using ScheduleFunctionT = solid::SmallFunctionT; //! A base class for all schedulers class SchedulerBase : NonCopyable { @@ -35,8 +34,8 @@ class SchedulerBase : NonCopyable { protected: typedef bool (*CreateWorkerF)(SchedulerBase& _rsch, const size_t, std::thread& _rthr, const size_t _wake_capacity); - typedef solid_function_t(bool()) ThreadEnterFunctionT; - typedef solid_function_t(void()) ThreadExitFunctionT; + using ThreadEnterFunctionT = solid::Function; + using ThreadExitFunctionT = solid::Function; void doStart( CreateWorkerF _pf, diff --git a/solid/frame/sharedstore.hpp b/solid/frame/sharedstore.hpp index 33e955ef..e33d9aae 100644 --- a/solid/frame/sharedstore.hpp +++ b/solid/frame/sharedstore.hpp @@ -545,7 +545,7 @@ class Store : public StoreBase { } private: - typedef solid_function_t(void(ControllerT&, PointerT&, ErrorCodeT const&)) FunctionT; + using FunctionT = Function; struct WaitStub { WaitStub() diff --git a/solid/frame/src/reactor.cpp b/solid/frame/src/reactor.cpp index 10b25ac3..e747dffe 100644 --- a/solid/frame/src/reactor.cpp +++ b/solid/frame/src/reactor.cpp @@ -95,7 +95,6 @@ struct ActorStub { } }; -constexpr size_t min_event_capacity = 32; constexpr size_t max_event_capacity = 1024 * 64; using UniqueIdVectorT = std::vector; diff --git a/solid/frame/src/schedulerbase.cpp b/solid/frame/src/schedulerbase.cpp index f0653bba..e2255efc 100644 --- a/solid/frame/src/schedulerbase.cpp +++ b/solid/frame/src/schedulerbase.cpp @@ -185,15 +185,15 @@ void SchedulerBase::doStart( pimpl_->reactor_vec_.resize(_reactorcnt); - if (!solid_function_empty(_renter_fnc)) { - solid_function_clear(pimpl_->thread_enter_fnc_); + if (_renter_fnc) { + pimpl_->thread_enter_fnc_ = nullptr; std::swap(pimpl_->thread_enter_fnc_, _renter_fnc); } else { pimpl_->thread_enter_fnc_ = &dummy_thread_enter; } - if (!solid_function_empty(_rexit_fnc)) { - solid_function_clear(pimpl_->thread_exit_fnc_); + if (_rexit_fnc) { + pimpl_->thread_exit_fnc_ = nullptr; std::swap(pimpl_->thread_exit_fnc_, _rexit_fnc); } else { pimpl_->thread_exit_fnc_ = &dummy_thread_exit; diff --git a/solid/frame/timer.hpp b/solid/frame/timer.hpp index caa6c628..64bddf22 100644 --- a/solid/frame/timer.hpp +++ b/solid/frame/timer.hpp @@ -17,8 +17,7 @@ #include "reactorcontext.hpp" #include "solid/frame/error.hpp" -namespace solid { -namespace frame { +namespace solid::frame { struct ActorProxy; class ReactorContext; @@ -42,7 +41,7 @@ class SteadyTimer : public CompletionHandler { break; case ReactorEventE::Clear: rthis.doClear(_rctx); - rthis.function_ = &on_dummy; + rthis.function_ = on_dummy; break; default: solid_assert_log(false, generic_logger); @@ -52,7 +51,7 @@ class SteadyTimer : public CompletionHandler { { } - typedef solid_function_t(void(ReactorContext&)) FunctionT; + using FunctionT = SmallFunctionT; FunctionT function_; size_t storeidx_; @@ -71,9 +70,9 @@ class SteadyTimer : public CompletionHandler { this->deactivate(false); } - bool hasPending() const + bool hasPending() const noexcept { - return !solid_function_empty(function_); + return function_.has_value(); } template @@ -98,7 +97,7 @@ class SteadyTimer : public CompletionHandler { void cancel(ReactorContext& _rctx) { - if (!solid_function_empty(function_)) { + if (function_) { remTimer(_rctx, storeidx_); error(_rctx, error_timer_cancel); doExec(_rctx); @@ -118,11 +117,10 @@ class SteadyTimer : public CompletionHandler { } void doClear(ReactorContext& _rctx) { - solid_function_clear(function_); + function_ = nullptr; remTimer(_rctx, storeidx_); storeidx_ = InvalidIndex(); } }; -} // namespace frame -} // namespace solid +} // namespace solid::frame diff --git a/solid/reflection/v1/dispatch.hpp b/solid/reflection/v1/dispatch.hpp index 162d9311..dc05e82d 100644 --- a/solid/reflection/v1/dispatch.hpp +++ b/solid/reflection/v1/dispatch.hpp @@ -43,7 +43,7 @@ constexpr TypeGroupE type_group() { if constexpr (solid::is_shared_ptr_v) { return TypeGroupE::SharedPtr; - } else if constexpr (solid::is_intrusive_ptr_v) { + } else if constexpr (solid::is_intrusive_ptr_v || solid::is_const_intrusive_ptr_v || solid::is_mutable_intrusive_ptr_v) { return TypeGroupE::IntrusivePtr; } else if constexpr (solid::is_unique_ptr_v) { return TypeGroupE::UniquePtr; diff --git a/solid/reflection/v1/metadata.hpp b/solid/reflection/v1/metadata.hpp index 0644db52..9d5ab863 100644 --- a/solid/reflection/v1/metadata.hpp +++ b/solid/reflection/v1/metadata.hpp @@ -239,7 +239,7 @@ struct Variant { template Variant& operator=(T&& _rv) { - var_ = std::move(_rv); + var_ = std::forward(_rv); return *this; } @@ -286,18 +286,12 @@ struct Variant { } }; -template -inline constexpr size_t array_size(const T (&arr)[S]) -{ - return S; -} - inline constexpr auto factory = [](const auto& _rt, auto& _rctx, const TypeMapBase* _ptype_map) -> auto { using rem_ref_value_t = typename std::remove_reference::type; using value_t = std::decay_t; if constexpr (std::is_enum_v) { return Enum{}; - } else if constexpr (is_shared_ptr_v || is_unique_ptr_v || is_intrusive_ptr_v) { + } else if constexpr (is_shared_ptr_v || is_unique_ptr_v || is_intrusive_ptr_v || is_const_intrusive_ptr_v || is_mutable_intrusive_ptr_v) { return Pointer{_ptype_map}; } else if constexpr (std::is_signed_v) { return SignedInteger{std::numeric_limits::min(), std::numeric_limits::max()}; diff --git a/solid/reflection/v1/reflection.hpp b/solid/reflection/v1/reflection.hpp index 2f2f21aa..7f2367e7 100644 --- a/solid/reflection/v1/reflection.hpp +++ b/solid/reflection/v1/reflection.hpp @@ -15,6 +15,7 @@ #include "solid/reflection/v1/reflector.hpp" #include "solid/reflection/v1/typetraits.hpp" +#ifndef __cpp_explicit_this_parameter #define SOLID_REFLECT_V1(reflector, rthis, context) \ template \ void solidReflectV1(Reflector& _rr, Context& _rctx) const \ @@ -28,11 +29,13 @@ } \ template \ static void solidReflectV1(Reflector& reflector, T& rthis, Context& context) - -namespace solid { -namespace reflection { +#else +#define SOLID_REFLECT_V1(reflector, rthis, context) \ + template \ + void solidReflectV1(this T& rthis, Reflector& reflector, Context& context) +#endif +namespace solid::reflection { using namespace v1; -} // namespace reflection -} // namespace solid +} // namespace solid::reflection diff --git a/solid/reflection/v1/typemap.hpp b/solid/reflection/v1/typemap.hpp index ea93df88..82e4872a 100644 --- a/solid/reflection/v1/typemap.hpp +++ b/solid/reflection/v1/typemap.hpp @@ -21,6 +21,7 @@ #include "solid/system/cassert.hpp" #include "solid/system/exception.hpp" #include "solid/utility/common.hpp" +#include "solid/utility/typetraits.hpp" namespace solid { namespace reflection { @@ -46,17 +47,11 @@ class TypeMapBase : NonCopyable { using ReverseCastFunctionT = std::function; struct CastStub { - template - CastStub(SF _sf, UF _uf, IF _if, RF _rf) - : shared_fnc_(_sf) - , unique_fnc_(_uf) - , intrusive_fnc_(_if) - , reverse_fnc_(_rf) - { - } CastFunctionT shared_fnc_; CastFunctionT unique_fnc_; CastFunctionT intrusive_fnc_; + CastFunctionT const_intrusive_fnc_; + CastFunctionT mutable_intrusive_fnc_; ReverseCastFunctionT reverse_fnc_; }; using TypeIndexPairT = std::pair; @@ -76,6 +71,8 @@ class TypeMapBase : NonCopyable { CreateFunctionT create_shared_fnc_; CreateFunctionT create_unique_fnc_; CreateFunctionT create_intrusive_fnc_; + CreateFunctionT create_const_intrusive_fnc_; + CreateFunctionT create_mutable_intrusive_fnc_; }; using ReflectorVectorT = std::vector; struct TypeStub { @@ -320,7 +317,7 @@ class TypeMapBase : NonCopyable { { const size_t reflector_index = reflectorIndex(); solid_assert(reflector_index != solid::InvalidIndex()); - static_assert(solid::is_shared_ptr_v || solid::is_unique_ptr_v || solid::is_intrusive_ptr_v); + static_assert(solid::is_shared_ptr_v || solid::is_unique_ptr_v || solid::is_intrusive_ptr_v || solid::is_const_intrusive_ptr_v || solid::is_mutable_intrusive_ptr_v); solid_assert(_category < category_vec_.size()); _rptr.reset(); @@ -347,8 +344,13 @@ class TypeMapBase : NonCopyable { } else if constexpr (solid::is_unique_ptr_v) { // unique_ptr static_assert(std::is_same_v>, "Only unique with default deleter is supported"); rtypestub.reflector_vec_[reflector_index].create_unique_fnc_(&_rctx, &_rptr, rcaststub.unique_fnc_); - } else { + } else if constexpr (solid::is_intrusive_ptr_v) { rtypestub.reflector_vec_[reflector_index].create_intrusive_fnc_(&_rctx, &_rptr, rcaststub.intrusive_fnc_); + } else if constexpr (solid::is_const_intrusive_ptr_v) { + rtypestub.reflector_vec_[reflector_index].create_const_intrusive_fnc_(&_rctx, &_rptr, rcaststub.const_intrusive_fnc_); + } else { + static_assert(solid::is_mutable_intrusive_ptr_v); + rtypestub.reflector_vec_[reflector_index].create_mutable_intrusive_fnc_(&_rctx, &_rptr, rcaststub.mutable_intrusive_fnc_); } rtypestub.reflector_vec_[reflector_index].reflect_fnc_(&_rreflector, _rptr.get(), &_rctx, rcaststub.reverse_fnc_); @@ -494,20 +496,20 @@ class TypeMap : public TypeMapBase { rref.add(rval, rctx, 0, ""); } }; - type_vec_[_type_index].reflector_vec_[_index].create_shared_fnc_ = [_create_f](void* _pctx, void* _pptr, const CastFunctionT& _cast) { + type_vec_[_type_index].reflector_vec_[_index].create_shared_fnc_ = [=](void* _pctx, void* _pptr, const CastFunctionT& _cast) { typename Ref::ContextT& rctx = *reinterpret_cast(_pctx); std::shared_ptr ptr; _create_f(rctx, ptr); _cast(_pptr, &ptr); }; - type_vec_[_type_index].reflector_vec_[_index].create_unique_fnc_ = [_create_f](void* _pctx, void* _pptr, const CastFunctionT& _cast) { + type_vec_[_type_index].reflector_vec_[_index].create_unique_fnc_ = [=](void* _pctx, void* _pptr, const CastFunctionT& _cast) { typename Ref::ContextT& rctx = *reinterpret_cast(_pctx); std::unique_ptr ptr; _create_f(rctx, ptr); _cast(_pptr, &ptr); }; - type_vec_[_type_index].reflector_vec_[_index].create_intrusive_fnc_ = [_create_f](void* _pctx, void* _pptr, const CastFunctionT& _cast) { + type_vec_[_type_index].reflector_vec_[_index].create_intrusive_fnc_ = [=](void* _pctx, void* _pptr, const CastFunctionT& _cast) { if constexpr (std::is_base_of_v) { typename Ref::ContextT& rctx = *reinterpret_cast(_pctx); solid::IntrusivePtr ptr; @@ -516,6 +518,24 @@ class TypeMap : public TypeMapBase { } }; + type_vec_[_type_index].reflector_vec_[_index].create_const_intrusive_fnc_ = [=](void* _pctx, void* _pptr, const CastFunctionT& _cast) { + if constexpr (std::is_base_of_v) { + typename Ref::ContextT& rctx = *reinterpret_cast(_pctx); + solid::ConstIntrusivePtr ptr; + _create_f(rctx, ptr); + _cast(_pptr, &ptr); + } + }; + + type_vec_[_type_index].reflector_vec_[_index].create_mutable_intrusive_fnc_ = [=](void* _pctx, void* _pptr, const CastFunctionT& _cast) { + if constexpr (std::is_base_of_v) { + typename Ref::ContextT& rctx = *reinterpret_cast(_pctx); + solid::MutableIntrusivePtr ptr; + _create_f(rctx, ptr); + _cast(_pptr, &ptr); + } + }; + if constexpr (!is_empty_pack::value) { doInitTypeReflect(_create_f, _type_index, _index + 1); } @@ -530,7 +550,8 @@ class TypeMap : public TypeMapBase { const size_t _base_cast_index = 0) { solid_check(type_index_map_.find(std::type_index(typeid(T))) == type_index_map_.end(), "Type " << typeid(T).name() << " already registered"); - const size_t index = type_vec_.size(); + const size_t index = type_vec_.size(); + type_index_map_[std::type_index(typeid(T))] = std::make_tuple(index, _category, _id); if (category_vec_.size() <= _category) { category_vec_.resize(_category + 1); @@ -558,7 +579,6 @@ class TypeMap : public TypeMapBase { const size_t cast_index = cast_vec_.size(); cast_map_[std::make_pair(std::type_index(typeid(T)), std::type_index(typeid(B)))] = cast_index; - cast_vec_.emplace_back( [](void* _pto, void* _pfrom) { std::shared_ptr& rto = *reinterpret_cast*>(_pto); @@ -572,11 +592,28 @@ class TypeMap : public TypeMapBase { }, [](void* _pto, void* _pfrom) { if constexpr (std::is_base_of_v && std::is_base_of_v) { + solid::IntrusivePtr& rto = *reinterpret_cast*>(_pto); solid::IntrusivePtr& rfrom = *reinterpret_cast*>(_pfrom); rto = std::move(rfrom); } }, + [](void* _pto, void* _pfrom) { + if constexpr (std::is_base_of_v && std::is_base_of_v) { + + solid::ConstIntrusivePtr& rto = *reinterpret_cast*>(_pto); + solid::ConstIntrusivePtr& rfrom = *reinterpret_cast*>(_pfrom); + rto = std::move(rfrom); + } + }, + [](void* _pto, void* _pfrom) { + if constexpr (std::is_base_of_v && std::is_base_of_v) { + + solid::MutableIntrusivePtr& rto = *reinterpret_cast*>(_pto); + solid::MutableIntrusivePtr& rfrom = *reinterpret_cast*>(_pfrom); + rto = std::move(rfrom); + } + }, [](const void* _pfrom) { return static_cast(reinterpret_cast(_pfrom)); }); diff --git a/solid/serialization/v3/binarydeserializer.hpp b/solid/serialization/v3/binarydeserializer.hpp index 7edd9b8d..4b0ff7cd 100644 --- a/solid/serialization/v3/binarydeserializer.hpp +++ b/solid/serialization/v3/binarydeserializer.hpp @@ -19,6 +19,7 @@ #include "solid/system/cassert.hpp" #include "solid/system/convertors.hpp" #include "solid/system/exception.hpp" +#include "solid/utility/common.hpp" #include "solid/utility/function.hpp" namespace solid { @@ -31,7 +32,7 @@ class DeserializerBase : public Base { typedef ReturnE (*CallbackT)(DeserializerBase&, Runnable&, void*); - using FunctionT = solid_function_t(ReturnE(DeserializerBase&, Runnable&, void*), 64); + using FunctionT = SmallFunction128T; using FunctionPtrT = std::unique_ptr; struct Runnable { @@ -73,7 +74,7 @@ class DeserializerBase : public Base { , size_(0) , data_(0) , name_(_name) - , fnc_ptr_(std::make_unique(std::move(_f))) + , fnc_ptr_(std::make_unique(std::move(_f), AcceptBigT{})) , limit_(0) { } @@ -116,7 +117,7 @@ class DeserializerBase : public Base { public: std::istream& run(std::istream& _ris, void* _pctx = nullptr); - ptrdiff_t run(const char* _pbeg, unsigned _sz, void* _pctx = nullptr); + ptrdiff_t run(const char* _pbeg, size_t _sz, void* _pctx = nullptr); void clear(); @@ -1028,14 +1029,14 @@ class Deserializer : public DeserializerBase { } template - ptrdiff_t run(const char* _pbeg, unsigned _sz, F _f, ContextT& _rctx) + ptrdiff_t run(const char* _pbeg, size_t _sz, F _f, ContextT& _rctx) { doPrepareRun(_pbeg, _sz); _f(*this, _rctx); return doRun(&_rctx); } - ptrdiff_t run(const char* _pbeg, unsigned _sz, ContextT& _rctx) + ptrdiff_t run(const char* _pbeg, size_t _sz, ContextT& _rctx) { return DeserializerBase::run(_pbeg, _sz, &_rctx); } @@ -1088,11 +1089,9 @@ class Deserializer : public DeserializerBase { } } - template >*/> -#if 1 + template requires( - !std::is_base_of_v && !std::is_floating_point_v || (std::is_pointer_v && (is_shared_ptr_v || is_unique_ptr_v || is_intrusive_ptr_v))) -#endif + (!std::is_base_of_v && !std::is_floating_point_v) || (std::is_pointer_v && (is_shared_ptr_v || is_unique_ptr_v || is_intrusive_ptr_v || is_mutable_intrusive_ptr_v))) void addDispatch(const Meta& _meta, T& _rt, ContextT& _rctx, const size_t _id, const char* const _name) { if constexpr (std::is_base_of_v) { @@ -1104,7 +1103,7 @@ class Deserializer : public DeserializerBase { addBasicCompacted(_rt.value_, _name); } else if constexpr (is_bitset_v) { addBitset(_rt, _name); - } else if constexpr (is_shared_ptr_v || is_unique_ptr_v || is_intrusive_ptr_v) { + } else if constexpr (is_shared_ptr_v || is_unique_ptr_v || is_intrusive_ptr_v || is_mutable_intrusive_ptr_v) { const auto* ptypemap = _meta.map(); solid_assert(ptypemap != nullptr); add(type_id_, _rctx, 1, "type_id"); diff --git a/solid/serialization/v3/binaryserializer.hpp b/solid/serialization/v3/binaryserializer.hpp index 0148a362..16302526 100644 --- a/solid/serialization/v3/binaryserializer.hpp +++ b/solid/serialization/v3/binaryserializer.hpp @@ -37,7 +37,7 @@ class SerializerBase : public Base { typedef ReturnE (*CallbackT)(SerializerBase&, Runnable&, void*); - using FunctionT = solid_function_t(ReturnE(SerializerBase&, Runnable&, void*), 64); + using FunctionT = SmallFunction128T; using FunctionPtrT = std::unique_ptr; struct Runnable { @@ -101,7 +101,7 @@ class SerializerBase : public Base { static constexpr bool is_const_reflector = true; std::ostream& run(std::ostream& _ros, void* _pctx = nullptr); - ptrdiff_t run(char* _pbeg, unsigned _sz, void* _pctx = nullptr); + ptrdiff_t run(char* _pbeg, size_t _sz, void* _pctx = nullptr); void clear(); @@ -545,7 +545,7 @@ class SerializerBase : public Base { } protected: - void doPrepareRun(char* _pbeg, unsigned _sz) + void doPrepareRun(char* _pbeg, size_t const _sz) { pbeg_ = _pbeg; pend_ = _pbeg + _sz; @@ -913,7 +913,7 @@ class Serializer : public SerializerBase { template requires( - !std::is_base_of_v && !std::is_floating_point_v || (std::is_pointer_v && (is_shared_ptr_v || is_unique_ptr_v || is_intrusive_ptr_v))) + (!std::is_base_of_v && !std::is_floating_point_v) || (std::is_pointer_v && (is_shared_ptr_v || is_unique_ptr_v || is_intrusive_ptr_v || is_const_intrusive_ptr_v))) void addDispatch(const Meta& _meta, const T& _rt, ContextT& _rctx, const size_t _id, const char* const _name) { @@ -927,7 +927,7 @@ class Serializer : public SerializerBase { addBasicCompacted(_rt.value_, _name); } else if constexpr (is_bitset_v) { addBitset(_rt, _name); - } else if constexpr (is_shared_ptr_v || is_unique_ptr_v || is_intrusive_ptr_v) { + } else if constexpr (is_shared_ptr_v || is_unique_ptr_v || is_intrusive_ptr_v || is_const_intrusive_ptr_v) { const auto* ptypemap = _meta.map(); solid_assert(ptypemap != nullptr); const auto index_tuple = ptypemap->id(_rt.get()); diff --git a/solid/serialization/v3/src/binarydeserializer.cpp b/solid/serialization/v3/src/binarydeserializer.cpp index 91269a2c..89932aa4 100644 --- a/solid/serialization/v3/src/binarydeserializer.cpp +++ b/solid/serialization/v3/src/binarydeserializer.cpp @@ -43,7 +43,7 @@ std::istream& DeserializerBase::run(std::istream& _ris, void* /*_pctx*/) return _ris; } -ptrdiff_t DeserializerBase::run(const char* _pbeg, unsigned _sz, void* _pctx) +ptrdiff_t DeserializerBase::run(const char* _pbeg, size_t const _sz, void* _pctx) { doPrepareRun(_pbeg, _sz); return doRun(_pctx); diff --git a/solid/serialization/v3/src/binaryserializer.cpp b/solid/serialization/v3/src/binaryserializer.cpp index 02697e2a..47c4131d 100644 --- a/solid/serialization/v3/src/binaryserializer.cpp +++ b/solid/serialization/v3/src/binaryserializer.cpp @@ -41,7 +41,7 @@ std::ostream& SerializerBase::run(std::ostream& _ros, void* _pctx) return _ros; } -ptrdiff_t SerializerBase::run(char* _pbeg, unsigned _sz, void* _pctx) +ptrdiff_t SerializerBase::run(char* _pbeg, size_t const _sz, void* _pctx) { doPrepareRun(_pbeg, _sz); return doRun(_pctx); diff --git a/solid/serialization/v3/test/test_binary.cpp b/solid/serialization/v3/test/test_binary.cpp index d8221b66..4dbcbb64 100644 --- a/solid/serialization/v3/test/test_binary.cpp +++ b/solid/serialization/v3/test/test_binary.cpp @@ -75,9 +75,9 @@ class Test { uint32_t blob64_sz = 0; char blob64[sizeof(uint64_t)]; - std::ostringstream oss; - std::istringstream iss; - string* pstr = nullptr; + std::ostringstream oss; + std::istringstream iss; + [[maybe_unused]] string* pstr = nullptr; void populate(bool _b) { diff --git a/solid/serialization/v3/test/test_container.cpp b/solid/serialization/v3/test/test_container.cpp index e2f67a8c..265f88f8 100644 --- a/solid/serialization/v3/test/test_container.cpp +++ b/solid/serialization/v3/test/test_container.cpp @@ -232,7 +232,7 @@ void Test::init() } } - v32 = str.size(); + v32 = static_cast(str.size()); for (size_t i = 0; i < 100; ++i) { sa[i] = kv_array[i % kv_array_size].second; diff --git a/solid/system/configuration_impl.hpp.in b/solid/system/configuration_impl.hpp.in index 9ec992ff..04eb9fba 100644 --- a/solid/system/configuration_impl.hpp.in +++ b/solid/system/configuration_impl.hpp.in @@ -26,6 +26,4 @@ #cmakedefine SOLID_USE_GCC_BSWAP -#cmakedefine SOLID_FRAME_AIO_REACTOR_USE_SPINLOCK - -#cmakedefine SOLID_MPRPC_USE_SHARED_PTR_MESSAGE +#cmakedefine SOLID_FRAME_AIO_REACTOR_USE_SPINLOCK \ No newline at end of file diff --git a/solid/system/exception.hpp b/solid/system/exception.hpp index 65d73846..3cfac574 100644 --- a/solid/system/exception.hpp +++ b/solid/system/exception.hpp @@ -87,48 +87,30 @@ class RuntimeError : public std::runtime_error { __FILE__, __LINE__, SOLID_FUNCTION_NAME) #define solid_check_error(a, c) \ - (solid_likely(a) ? static_cast(0) : solid_throw_error(c)); + if (not(a)) [[unlikely]] \ + solid_throw_error(c); -// adapted from https://github.com/Microsoft/GSL/blob/master/include/gsl/gsl_assert -#if defined(__clang__) || defined(__GNUC__) -#define solid_likely(x) __builtin_expect(!!(x), 1) -#define solid_unlikely(x) __builtin_expect(!!(x), 0) -#else -#define solid_likely(x) (!!(x)) -#define solid_unlikely(x) (!(x)) -#endif - -#define solid_check1(a) \ - (solid_likely(a) ? static_cast(0) : solid_throw("(" #a ") check failed")); +#define solid_check1(a) \ + if (!(a)) [[unlikely]] { \ + solid_throw("(" #a ") check failed"); \ + } -#define solid_check2(a, msg) \ - (solid_likely(a) ? static_cast(0) : solid_throw("(" #a ") check failed: " << msg)); +#define solid_check2(a, msg) \ + if (!(a)) [[unlikely]] { \ + solid_throw("(" #a ") check failed: " << msg); \ + } #define solid_check_log2(a, l) \ - if (solid_likely(a)) { \ - } else { \ + if (!(a)) [[unlikely]] { \ solid_throw_log(l, "(" #a ") check failed"); \ } #define solid_check_log3(a, l, msg) \ - if (solid_likely(a)) { \ - } else { \ + if (!(a)) [[unlikely]] { \ solid_throw_log(l, "(" #a ") check failed: " << msg); \ } // adapted from: https://stackoverflow.com/questions/9183993/msvc-variadic-macro-expansion/9338429#9338429 -#if 1 #define solid_check(...) SOLID_CALL_OVERLOAD(solid_check, __VA_ARGS__) #define solid_check_log(...) SOLID_CALL_OVERLOAD(solid_check_log, __VA_ARGS__) -#else -#define GET_3RD_ARG(arg1, arg2, arg3, ...) arg3 - -#define solid_check_MACRO_CHOOSER(...) \ - GET_3RD_ARG(__VA_ARGS__, solid_check2, \ - solid_check1) - -#define solid_check(...) \ - solid_check_MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__) -#endif - } // namespace solid diff --git a/solid/system/nanotime.hpp b/solid/system/nanotime.hpp index cc138aec..b2b2b3eb 100644 --- a/solid/system/nanotime.hpp +++ b/solid/system/nanotime.hpp @@ -62,7 +62,7 @@ struct NanoTime : public timespec { explicit operator bool() const noexcept { - return tv_sec == 0 && tv_nsec == 0; + return tv_sec != 0 or tv_nsec != 0; } template diff --git a/solid/system/pimpl.hpp b/solid/system/pimpl.hpp index 7a8489f6..3b80f0b1 100644 --- a/solid/system/pimpl.hpp +++ b/solid/system/pimpl.hpp @@ -11,6 +11,7 @@ #pragma once #include +#include #include namespace solid { @@ -28,7 +29,7 @@ class Pimpl { Pimpl(Args&&... args) { static_assert(sizeof(T) <= Cp && alignof(T) <= Align); -#if __cpp_static_assert >= 202306L +#if __cpp_static_assert > 202306L // Not real C++ yet (std::format should be constexpr to work): static_assert(sizeof(T) <= Cp, std::format("Increase the capacity! Expected {}, got {}", sizeof(T), Cp)); #else diff --git a/solid/system/socketaddress.hpp b/solid/system/socketaddress.hpp index ce515cba..c1013d01 100644 --- a/solid/system/socketaddress.hpp +++ b/solid/system/socketaddress.hpp @@ -47,7 +47,7 @@ struct ResolveIterator { int protocol() const; size_t size() const; sockaddr* sockAddr() const; - operator bool() const; + operator bool() const; ResolveIterator& operator++(); bool operator==(const ResolveIterator& _rrit) const; @@ -233,7 +233,7 @@ struct SocketAddress { const socklen_t& size() const; const sockaddr* sockAddr() const; - operator const sockaddr*() const; + operator const sockaddr*() const; bool operator<(const SocketAddress& _raddr) const; bool operator==(const SocketAddress& _raddr) const; @@ -253,7 +253,7 @@ struct SocketAddress { private: friend class SocketDevice; - operator sockaddr*(); + operator sockaddr*(); sockaddr* sockAddr(); AddrUnion d; socklen_t sz; @@ -292,7 +292,7 @@ struct SocketAddressInet { const socklen_t& size() const; const sockaddr* sockAddr() const; - operator const sockaddr*() const; + operator const sockaddr*() const; bool toBinary(DataArray4T& _bin, uint16_t& _port) const; bool toBinary(DataArray6T& _bin, uint16_t& _port) const; @@ -315,7 +315,7 @@ struct SocketAddressInet { private: friend class SocketDevice; - operator sockaddr*(); + operator sockaddr*(); sockaddr* sockAddr(); AddrUnion d; socklen_t sz; @@ -375,7 +375,7 @@ struct SocketAddressInet4 { private: friend class SocketDevice; - operator sockaddr*(); + operator sockaddr*(); sockaddr* sockAddr(); AddrUnion d; }; @@ -409,7 +409,7 @@ struct SocketAddressInet6 { socklen_t size() const; const sockaddr* sockAddr() const; - operator const sockaddr*() const; + operator const sockaddr*() const; void toBinary(DataArrayT& _bin, uint16_t& _port) const; @@ -430,7 +430,7 @@ struct SocketAddressInet6 { private: friend class SocketDevice; - operator sockaddr*(); + operator sockaddr*(); sockaddr* sockAddr(); AddrUnion d; }; @@ -477,7 +477,7 @@ struct SocketAddressLocal { const socklen_t& size() const; const sockaddr* sockAddr() const; - operator const sockaddr*() const; + operator const sockaddr*() const; bool operator<(const SocketAddressLocal& _raddr) const; bool operator==(const SocketAddressLocal& _raddr) const; @@ -491,7 +491,7 @@ struct SocketAddressLocal { private: friend class SocketDevice; - operator sockaddr*(); + operator sockaddr*(); sockaddr* sockAddr(); AddrUnion d; socklen_t sz = 0; diff --git a/solid/system/socketinfo.hpp b/solid/system/socketinfo.hpp index 7bbd94bb..72aa4eb2 100644 --- a/solid/system/socketinfo.hpp +++ b/solid/system/socketinfo.hpp @@ -10,6 +10,8 @@ #pragma once +#include "solid/system/common.hpp" + #ifdef SOLID_ON_WINDOWS #ifndef WIN32_LEAN_AND_MEAN @@ -18,6 +20,7 @@ #ifndef VC_EXTRALEAN #define VC_EXTRALEAN #endif + #ifndef NOMINMAX #define NOMINMAX #endif diff --git a/solid/system/spinlock.hpp b/solid/system/spinlock.hpp index 37fc0f9c..f95fc527 100644 --- a/solid/system/spinlock.hpp +++ b/solid/system/spinlock.hpp @@ -10,6 +10,7 @@ #pragma once #include "solid/system/common.hpp" +#include "solid/system/exception.hpp" #if (defined(__i386__) || defined(__x86_64__)) && defined(__clang__) #include diff --git a/solid/utility/CMakeLists.txt b/solid/utility/CMakeLists.txt index 50aa7b0a..ec09977c 100644 --- a/solid/utility/CMakeLists.txt +++ b/solid/utility/CMakeLists.txt @@ -11,6 +11,7 @@ set(Sources set(Headers algorithm.hpp any.hpp + anyimpl.hpp common.hpp event.hpp innerlist.hpp @@ -26,7 +27,6 @@ set(Headers super.hpp sharedbuffer.hpp threadpool.hpp - cacheable.hpp cast.hpp intrusiveptr.hpp collapse.hpp diff --git a/solid/utility/any.hpp b/solid/utility/any.hpp index 6eb02c89..8a6336a6 100644 --- a/solid/utility/any.hpp +++ b/solid/utility/any.hpp @@ -9,7 +9,6 @@ // #pragma once - #include #include #include @@ -18,228 +17,213 @@ #include "solid/system/exception.hpp" #include "solid/system/log.hpp" +#include "solid/utility/anyimpl.hpp" #include "solid/utility/common.hpp" #include "solid/utility/typetraits.hpp" namespace solid { -inline constexpr size_t any_default_data_size = 3 * sizeof(void*); -inline constexpr size_t any_size_from_sizeof(const size_t _sizeof) -{ - return _sizeof - sizeof(void*); -} -template -inline constexpr const T& any_max(const T& a, const T& b) +template + requires(std::popcount(Align) == 1) +constexpr size_t any_size_to_small_size() { - return (a < b) ? b : a; + constexpr size_t max = std::max(sizeof(std::uintptr_t), Align); + static_assert(Size >= max, "size must be greater than sizeof(std::uintptr_t)"); + return Size - max; } -template + +constexpr size_t any_default_size = any_size_to_small_size<32>(); +constexpr size_t any_default_align = sizeof(std::uintptr_t); + +template < + size_t SmallSize = any_default_size, + size_t SmallAlign = any_default_align, + StoreOption Option = StoreOption::AcceptBig> + requires(SmallSize > 0 and SmallSize >= SmallAlign + and (SmallSize % SmallAlign == 0) and std::popcount(SmallAlign) == 1) class Any; template struct is_any; -template -struct is_any> : std::true_type { +template +struct is_any> : std::true_type { }; template struct is_any : std::false_type { }; +template +inline constexpr bool is_any_v = is_any::value; + namespace any_impl { -enum struct RepresentationE : uintptr_t { - None = 0, - Small, - Big, -}; -constexpr uintptr_t representation_mask = 3; -constexpr uintptr_t representation_and_flags_mask = representation_mask; struct SmallRTTI; +struct BigRTTI; -struct BigRTTI { - using DestroyFncT = void(void*); - using CopyFncT = RepresentationE(const void*, void*, const size_t, const SmallRTTI*&, void*&, const BigRTTI*&); - using MoveFncT = RepresentationE(void*, void*, const size_t, const SmallRTTI*&, void*&, const BigRTTI*&); - using GetIfFncT = const void*(const std::type_index&, const void*); +struct BaseRTTI { + using DestroyFncT = void(void*) noexcept; + using CopyFncT = uintptr_t(const void*, void*, size_t, size_t, void*&); + using MoveFncT = uintptr_t(void*, void*, size_t, size_t, void*&); + using GetIfFncT = const void*(const std::type_index&, const void*); + using GetTypeInfoT = std::type_info const*() noexcept; - template - static void destroy(void* const _what) noexcept + CopyFncT& copy_fnc_; + MoveFncT& move_fnc_; + GetIfFncT& get_if_fnc_; + GetTypeInfoT& get_type_info_fnc_; + const bool is_copyable_; + const bool is_movable_; + const bool is_tuple_; + + static BaseRTTI const& get(uintptr_t const _rtti) noexcept { - //::delete static_cast(_what); - std::destroy_at(std::launder(static_cast(_what))); + return *reinterpret_cast(_rtti & reversed_representation_and_flags_mask); } +}; + +struct BigRTTI : BaseRTTI { + + DestroyFncT& destroy_fnc_; template - static void* move(void* const _from) + static void destroy(void* const _what) noexcept { - return ::new T(std::move(*static_cast(_from))); + ::delete static_cast(_what); } - DestroyFncT* pdestroy_fnc_; - CopyFncT* pcopy_fnc_; - MoveFncT* pmove_fnc_; - GetIfFncT* pget_if_fnc_; - const bool is_copyable_; - const bool is_movable_; - const bool is_tuple_; + static BigRTTI const& get(uintptr_t const _rtti) noexcept + { + return *reinterpret_cast(_rtti & reversed_representation_and_flags_mask); + } }; -struct SmallRTTI { - using DestroyFncT = void(void*) noexcept; - using CopyFncT = RepresentationE(const void*, void*, const size_t, const SmallRTTI*&, void*&, const BigRTTI*&); - using MoveFncT = RepresentationE(void*, void*, const size_t, const SmallRTTI*&, void*&, const BigRTTI*&); - using GetIfFncT = const void*(const std::type_index&, const void*); +struct SmallRTTI : BaseRTTI { + + DestroyFncT* pdestroy_fnc_; template static void destroy(void* const _what) noexcept { - static_cast(_what)->~T(); + std::destroy_at(std::launder(static_cast(_what))); } - static void dummy_destroy(void* const _what) noexcept + + static SmallRTTI const& get(uintptr_t const _rtti) noexcept { + return *reinterpret_cast(_rtti & reversed_representation_and_flags_mask); } - DestroyFncT* pdestroy_fnc_; - CopyFncT* pcopy_fnc_; - MoveFncT* pmove_fnc_; - GetIfFncT* pget_if_fnc_; - const bool is_copyable_; - const bool is_movable_; - const bool is_tuple_; }; template -RepresentationE do_copy( - const void* _pfrom, - void* _pto_small, const size_t _small_cap, const SmallRTTI*& _rpsmall_rtti, - void*& _rpto_big, const BigRTTI*& _rpbig_rtti); +uintptr_t do_copy( + const void*, + void*, size_t, size_t, + void*&); template -RepresentationE do_move( - void* _pfrom, - void* _pto_small, const size_t _small_cap, const SmallRTTI*& _rpsmall_rtti, - void*& _rpto_big, const BigRTTI*& _rpbig_rtti); +uintptr_t do_move( + void*, + void*, size_t, size_t, + void*&); template -RepresentationE do_move_big( - void* _pfrom, - void* _pto_small, const size_t _small_cap, const SmallRTTI*& _rpsmall_rtti, - void*& _rpto_big, const BigRTTI*& _rpbig_rtti); +uintptr_t do_move_big( + void*, + void*, size_t, size_t, + void*&); template -const void* do_get_if(const std::type_index& _type_index, const void* _pdata); +const void* do_get_if(const std::type_index&, const void*); + +template +std::type_info const* get_type_info() noexcept; template inline constexpr BigRTTI big_rtti = { - &BigRTTI::destroy, &do_copy, &do_move_big, &do_get_if, std::is_copy_constructible_v, std::is_move_constructible_v, is_specialization_v}; + {do_copy, + do_move_big, + do_get_if, + get_type_info, + std::is_copy_constructible_v, + std::is_move_constructible_v, + is_specialization_v}, + BigRTTI::destroy}; template inline constexpr SmallRTTI small_rtti = { - &SmallRTTI::destroy, &do_copy, &do_move, &do_get_if, std::is_copy_constructible_v, std::is_move_constructible_v, is_specialization_v}; - -inline RepresentationE do_dummy_copy( - const void* _pfrom, - void* _pto_small, const size_t _small_cap, const SmallRTTI*& _rpsmall_rtti, - void*& _rpto_big, const BigRTTI*& _rpbig_rtti) -{ - return RepresentationE::None; -} - -inline RepresentationE do_dummy_move( - void* _pfrom, - void* _pto_small, const size_t _small_cap, const SmallRTTI*& _rpsmall_rtti, - void*& _rpto_big, const BigRTTI*& _rpbig_rtti) -{ - return RepresentationE::None; -} - -inline const void* do_dummy_get_if(const std::type_index& _type_index, const void* _pdata) -{ - return nullptr; -} - -inline constexpr SmallRTTI dummy_small_rtti = { - &SmallRTTI::dummy_destroy, &do_dummy_copy, &do_dummy_move, &do_dummy_get_if, false, false, false}; + {do_copy, + do_move, + do_get_if, + get_type_info, + std::is_copy_constructible_v, + std::is_move_constructible_v, + is_specialization_v}, + std::is_trivially_copyable_v ? nullptr : &SmallRTTI::destroy}; template -RepresentationE do_copy( +uintptr_t do_copy( const void* _pfrom, - void* _pto_small, const size_t _small_cap, const SmallRTTI*& _rpsmall_rtti, - void*& _rpto_big, const BigRTTI*& _rpbig_rtti) + void* _pto_small, const size_t _small_cap, const size_t _small_align, + void*& _rpto_big) { - if constexpr (alignof(T) <= alignof(max_align_t) && std::is_copy_constructible_v) { - if (sizeof(T) <= _small_cap) { + if constexpr (std::is_copy_constructible_v) { + if (sizeof(T) <= _small_cap and alignof(T) <= _small_align) { T& rdst = *static_cast(_pto_small); const T& rsrc = *static_cast(_pfrom); - ::new (const_cast(static_cast(std::addressof(rdst)))) T(rsrc); - _rpsmall_rtti = &small_rtti; - return RepresentationE::Small; + ::new (std::addressof(rdst)) T(rsrc); + return representation(&small_rtti, RepresentationE::Small); } else { - _rpto_big = ::new T(*static_cast(_pfrom)); - _rpbig_rtti = &big_rtti; - return RepresentationE::Big; + _rpto_big = ::new T(*static_cast(_pfrom)); + return representation(&big_rtti, RepresentationE::Big); } - } else if constexpr (std::is_trivially_constructible_v || std::is_copy_constructible_v) { - _rpto_big = ::new T(*static_cast(_pfrom)); - _rpbig_rtti = &big_rtti; - return RepresentationE::Big; } else { solid_throw("Any: contained value not copyable"); - return RepresentationE::None; + return 0; } } template -RepresentationE do_move( +uintptr_t do_move( void* _pfrom, - void* _pto_small, const size_t _small_cap, const SmallRTTI*& _rpsmall_rtti, - void*& _rpto_big, const BigRTTI*& _rpbig_rtti) + void* _pto_small, const size_t _small_cap, const size_t _small_align, + void*& _rpto_big) { - if constexpr (alignof(T) <= alignof(max_align_t) && std::is_move_constructible_v) { - if (sizeof(T) <= _small_cap) { + if constexpr (std::is_move_constructible_v) { + if (sizeof(T) <= _small_cap and alignof(T) <= _small_align) { T& rdst = *static_cast(_pto_small); T& rsrc = *static_cast(_pfrom); - ::new (const_cast(static_cast(std::addressof(rdst)))) T{std::move(rsrc)}; - _rpsmall_rtti = &small_rtti; - return RepresentationE::Small; + ::new (std::addressof(rdst)) T{std::move(rsrc)}; + return representation(&small_rtti, RepresentationE::Small); } else { - _rpto_big = ::new T{std::move(*static_cast(_pfrom))}; - _rpbig_rtti = &big_rtti; - return RepresentationE::Big; + _rpto_big = ::new T{std::move(*static_cast(_pfrom))}; + return representation(&big_rtti, RepresentationE::Big); } - } else if constexpr (std::is_move_constructible_v) { - _rpto_big = ::new T{std::move(*static_cast(_pfrom))}; - _rpbig_rtti = &big_rtti; - return RepresentationE::Big; } else { solid_throw("Any: contained value not movable"); - return RepresentationE::None; + return 0; } } template -RepresentationE do_move_big( +uintptr_t do_move_big( void* _pfrom, - void* _pto_small, const size_t _small_cap, const SmallRTTI*& _rpsmall_rtti, - void*& _rpto_big, const BigRTTI*& _rpbig_rtti) + void* _pto_small, const size_t _small_cap, const size_t _small_align, + void*& _rpto_big) { - if constexpr (alignof(T) <= alignof(max_align_t) && std::is_move_constructible_v) { - if (sizeof(T) <= _small_cap) { + if constexpr (std::is_move_constructible_v) { + if (sizeof(T) <= _small_cap and alignof(T) <= _small_align) { T& rdst = *static_cast(_pto_small); T& rsrc = *static_cast(_pfrom); - ::new (const_cast(static_cast(std::addressof(rdst)))) T{std::move(rsrc)}; - _rpsmall_rtti = &small_rtti; - return RepresentationE::Small; + ::new (std::addressof(rdst)) T{std::move(rsrc)}; + return representation(&small_rtti, RepresentationE::Small); } else { - _rpto_big = static_cast(_pfrom); //::new T{ std::move(*static_cast(_pfrom)) }; - _rpbig_rtti = &big_rtti; - return RepresentationE::Big; + _rpto_big = static_cast(_pfrom); + return representation(&big_rtti, RepresentationE::Big); } } else { - _rpto_big = static_cast(_pfrom); //::new T{ std::move(*static_cast(_pfrom)) }; - _rpbig_rtti = &big_rtti; - return RepresentationE::Big; + _rpto_big = static_cast(_pfrom); + return representation(&big_rtti, RepresentationE::Big); } } @@ -266,82 +250,70 @@ const void* do_get_if(const std::type_index& _type_index, const void* _pdata) return nullptr; } -constexpr size_t compute_small_capacity(const size_t _req_capacity) +template +std::type_info const* get_type_info() noexcept { - const size_t end_capacity = sizeof(uintptr_t) + sizeof(void*); - const size_t req_capacity = any_max(_req_capacity, any_max(end_capacity, sizeof(max_align_t)) - end_capacity); - const size_t tot_capacity = padded_size(req_capacity + sizeof(uintptr_t) + sizeof(void*), alignof(max_align_t)); - - return tot_capacity - end_capacity; + return &typeid(T); } } // namespace any_impl -template +template + requires(SmallSize > 0 and SmallSize >= SmallAlign + and (SmallSize % SmallAlign == 0) and std::popcount(SmallAlign) == 1) class Any { - static constexpr size_t small_capacity = any_impl::compute_small_capacity(any_max(sizeof(void*) * 3, DataSize)); - static constexpr size_t big_padding = small_capacity - sizeof(void*); struct Small { - unsigned char data_[small_capacity]; - const any_impl::SmallRTTI* prtti_; + alignas(SmallAlign) unsigned char data_[SmallSize]; }; struct Big { - unsigned char padding_[big_padding]; - void* ptr_; - const any_impl::BigRTTI* prtti_; - }; - - struct Storage { - union { - Small small_; - Big big_; - }; - uintptr_t type_data_; + void* pdata_; }; + uintptr_t rtti_ = 0; union { - Storage storage_{}; - max_align_t dummy_; + Small small_; + Big big_; }; - template + + template + requires(S > 0 and S >= A + and (S % A == 0) and std::popcount(A) == 1) friend class Any; private: - any_impl::RepresentationE representation() const noexcept + [[nodiscard]] const std::type_info* typeInfo() const noexcept { - return static_cast(storage_.type_data_ & any_impl::representation_and_flags_mask); + auto const rtti = rtti_; + if (rtti) [[likely]] { + return any_impl::BaseRTTI::get(rtti).get_type_info_fnc_(); + } + return nullptr; } - void representation(const any_impl::RepresentationE _repr) noexcept - { - storage_.type_data_ &= (~any_impl::representation_and_flags_mask); - storage_.type_data_ |= static_cast(_repr); - } +public: + using ThisT = Any; - const std::type_info* typeInfo() const noexcept + static constexpr size_t smallCapacity() { - return reinterpret_cast(storage_.type_data_ & ~any_impl::representation_and_flags_mask); + return SmallSize; } -public: - using ThisT = Any; - - static constexpr size_t smallCapacity() + static constexpr size_t smallAlign() { - return small_capacity; + return SmallAlign; } template static constexpr bool is_small_type() { - return alignof(T) <= alignof(max_align_t) && sizeof(T) <= small_capacity; + return alignof(T) <= smallAlign() && sizeof(T) <= smallCapacity(); } constexpr Any() noexcept { - storage_.type_data_ = 0; + rtti_ = 0; } Any(const ThisT& _other) @@ -349,8 +321,8 @@ class Any { doCopyFrom(_other); } - template - Any(const Any& _other) + template + Any(const Any& _other) { doCopyFrom(_other); } @@ -360,39 +332,36 @@ class Any { doMoveFrom(_other); } - template - Any(Any&& _other) noexcept + template + Any(Any&& _other) noexcept { doMoveFrom(_other); } - template >>, std::negation, std::in_place_type_t>> /*, - std::is_copy_constructible>*/ - >, - int> - = 0> - Any(T&& _rvalue) + template + Any(T&& _rvalue, std::integral_constant = store_option_dispatch()) + requires(not is_any_v> and not is_specialization_v, std::in_place_type_t>) { + using ValueT = std::decay_t; + static_assert(Opt == StoreOption::AcceptBig or is_small_type(), "Value not small. Construct by using AcceptBigT{} or assign using .emplace()"); doEmplace>(std::forward(_rvalue)); } - template , Args...> /*, std::is_copy_constructible>*/>, - int> - = 0> - explicit Any(std::in_place_type_t, Args&&... _args) + template + explicit Any(std::in_place_type_t, Args&&... _args, std::integral_constant = store_option_dispatch()) + requires(std::is_constructible_v, Args...>) { + using ValueT = std::decay_t; + static_assert(Opt == StoreOption::AcceptBig or is_small_type(), "Value not small. Construct by using AcceptBigT{} or assign using .emplace()"); doEmplace>(std::forward(_args)...); } - template , std::initializer_list&, Args...>, - std::is_copy_constructible>>, - int> - = 0> - explicit Any(std::in_place_type_t, std::initializer_list _ilist, Args&&... _args) + template + explicit Any(std::in_place_type_t, std::initializer_list _ilist, Args&&... _args, std::integral_constant = store_option_dispatch()) + requires(std::is_constructible_v, std::initializer_list&, Args...> and std::is_copy_constructible_v>) { + using ValueT = std::decay_t; + static_assert(Opt == StoreOption::AcceptBig or is_small_type(), "Value not small. Construct by using AcceptBigT{} or assign using .emplace()"); doEmplace>(_ilist, std::forward(_args)...); } @@ -414,75 +383,80 @@ class Any { return *this; } - template - ThisT& operator=(const Any& _other) + template + ThisT& operator=(const Any& _other) { *this = ThisT{_other}; return *this; } - template - ThisT& operator=(Any&& _other) noexcept + template + ThisT& operator=(Any&& _other) noexcept { reset(); doMoveFrom(_other); return *this; } - template >>, std::is_copy_constructible>>, int> = 0> + template ThisT& operator=(T&& _rvalue) + requires(not is_any_v> and std::is_copy_constructible_v>) { *this = ThisT{std::forward(_rvalue)}; return *this; } +#if 0 + template + ThisT& emplace(T&& _rvalue) + { + *this = ThisT{std::forward(_rvalue), AcceptBigT{}}; + return *this; + } - template , Args...>>, - int> - = 0> - std::decay_t& emplace(Args&&... _args) + template + ThisT& emplace(Args&&... _args) + requires(std::is_constructible_v, Args...>) { - reset(); - return doEmplace>(std::forward(_args)...); + *this = ThisT{std::in_place_type_t{}, std::forward(_args)..., AcceptBigT{}}; + return *this; } - template , std::initializer_list&, Args...> /*, - is_copy_constructible>*/ - >, - int> - = 0> - std::decay_t& emplace(std::initializer_list _ilist, Args&&... _args) + template + ThisT& emplace(std::initializer_list _ilist, Args&&... _args) + requires(std::is_constructible_v, std::initializer_list&, Args...>) { - reset(); - return doEmplace>(_ilist, std::forward(_args)...); + *this = ThisT{std::in_place_type_t{}, _ilist, std::forward(_args)..., AcceptBigT{}}; + return *this; } - +#endif void reset() noexcept { - switch (representation()) { - case any_impl::RepresentationE::Small: - storage_.small_.prtti_->pdestroy_fnc_(&storage_.small_.data_); - break; - case any_impl::RepresentationE::Big: - storage_.big_.prtti_->pdestroy_fnc_(storage_.big_.ptr_); - break; + auto const rtti = rtti_; + switch (any_impl::representation(rtti)) { + [[likely]] case any_impl::RepresentationE::Small: { + auto& rrtti = any_impl::SmallRTTI::get(rtti); + if (rrtti.pdestroy_fnc_) { + rrtti.pdestroy_fnc_(small_.data_); + } + } break; + case any_impl::RepresentationE::Big: { + any_impl::BigRTTI::get(rtti).destroy_fnc_(big_.pdata_); + } break; case any_impl::RepresentationE::None: default: break; } - storage_.type_data_ = 0; + rtti_ = 0u; } - template - void swap(Any& _other) noexcept + template + void swap(Any& _other) noexcept { _other = std::exchange(*this, std::move(_other)); } - bool has_value() const noexcept + [[nodiscard]] bool has_value() const noexcept { - return storage_.type_data_ != 0; + return rtti_ != 0u; } explicit operator bool() const noexcept @@ -490,12 +464,12 @@ class Any { return has_value(); } - bool empty() const noexcept + [[nodiscard]] bool empty() const noexcept { return !has_value(); } - const std::type_info& type() const noexcept + [[nodiscard]] const std::type_info& type() const noexcept { const std::type_info* const pinfo = typeInfo(); return pinfo ? *pinfo : typeid(void); @@ -510,9 +484,9 @@ class Any { } if constexpr (is_small_type()) { - return reinterpret_cast(&storage_.small_.data_); + return reinterpret_cast(&small_.data_); } else { - return static_cast(storage_.big_.ptr_); + return static_cast(big_.pdata_); } } @@ -525,14 +499,12 @@ class Any { template const T* get_if() const noexcept { - switch (representation()) { - case any_impl::RepresentationE::Small: - return static_cast(storage_.small_.prtti_->pget_if_fnc_(std::type_index(typeid(T)), &storage_.small_.data_)); - case any_impl::RepresentationE::Big: - return static_cast(storage_.big_.prtti_->pget_if_fnc_(std::type_index(typeid(T)), storage_.big_.ptr_)); - default: - return nullptr; + auto const rtti = rtti_; + if (rtti) [[likely]] { + void const* pdata = any_impl::representation(rtti) == any_impl::RepresentationE::Small ? small_.data_ : big_.pdata_; + return static_cast(any_impl::BaseRTTI::get(rtti).get_if_fnc_(std::type_index(typeid(T)), pdata)); } + return nullptr; } template @@ -541,95 +513,88 @@ class Any { return const_cast(static_cast(this)->get_if()); } - bool is_movable() const + [[nodiscard]] bool is_movable() const { - if (is_small()) { - return storage_.small_.prtti_->is_movable_; - } else if (is_big()) { - return storage_.big_.prtti_->is_movable_; + auto const rtti = rtti_; + if (rtti) [[likely]] { + return any_impl::BaseRTTI::get(rtti).is_movable_; } return true; } - bool is_copyable() const + [[nodiscard]] bool is_copyable() const { - if (is_small()) { - return storage_.small_.prtti_->is_copyable_; - } else if (is_big()) { - return storage_.big_.prtti_->is_copyable_; + auto const rtti = rtti_; + if (rtti) [[likely]] { + return any_impl::BaseRTTI::get(rtti).is_copyable_; } return true; } - bool is_tuple() const + [[nodiscard]] bool is_tuple() const { - if (is_small()) { - return storage_.small_.prtti_->is_tuple_; - } else if (is_big()) { - return storage_.big_.prtti_->is_tuple_; + auto const rtti = rtti_; + if (rtti) [[likely]] { + return any_impl::BaseRTTI::get(rtti).is_tuple_; } return false; } - bool is_small() const + [[nodiscard]] bool is_small() const { - return representation() == any_impl::RepresentationE::Small; + return any_impl::representation(rtti_) == any_impl::RepresentationE::Small; } - bool is_big() const + + [[nodiscard]] bool is_big() const { - return representation() == any_impl::RepresentationE::Big; + return any_impl::representation(rtti_) == any_impl::RepresentationE::Big; } private: - template - void doMoveFrom(Any& _other) + template + void doMoveFrom(Any& _other) { - storage_.type_data_ = _other.storage_.type_data_; - representation(any_impl::RepresentationE::None); - switch (_other.representation()) { + auto const rtti = _other.rtti_; + + switch (any_impl::representation(rtti)) { case any_impl::RepresentationE::Small: { - const auto repr = _other.storage_.small_.prtti_->pmove_fnc_( - _other.storage_.small_.data_, - storage_.small_.data_, small_capacity, storage_.small_.prtti_, - storage_.big_.ptr_, storage_.big_.prtti_); - representation(repr); + rtti_ = any_impl::BaseRTTI::get(rtti).move_fnc_( + _other.small_.data_, + small_.data_, smallCapacity(), smallAlign(), + big_.pdata_); _other.reset(); } break; case any_impl::RepresentationE::Big: { - const auto repr = _other.storage_.big_.prtti_->pmove_fnc_( - _other.storage_.big_.ptr_, - storage_.small_.data_, small_capacity, storage_.small_.prtti_, - storage_.big_.ptr_, storage_.big_.prtti_); - representation(repr); - if (repr == any_impl::RepresentationE::Big) { - _other.storage_.type_data_ = 0; - } else { - _other.reset(); + rtti_ = any_impl::BaseRTTI::get(rtti).move_fnc_( + _other.big_.pdata_, + small_.data_, smallCapacity(), smallAlign(), + big_.pdata_); + if (is_big()) { + _other.rtti_ = 0u; } + _other.reset(); } break; default: break; } } - template - void doCopyFrom(const Any& _other) + template + void doCopyFrom(const Any& _other) { - storage_.type_data_ = _other.storage_.type_data_; - representation(any_impl::RepresentationE::None); - switch (_other.representation()) { + auto const rtti = _other.rtti_; + + switch (any_impl::representation(rtti)) { case any_impl::RepresentationE::Small: { - const auto repr = _other.storage_.small_.prtti_->pcopy_fnc_( - _other.storage_.small_.data_, - storage_.small_.data_, small_capacity, storage_.small_.prtti_, - storage_.big_.ptr_, storage_.big_.prtti_); - representation(repr); + rtti_ = any_impl::BaseRTTI::get(rtti).copy_fnc_( + _other.small_.data_, + small_.data_, smallCapacity(), smallAlign(), + big_.pdata_); } break; case any_impl::RepresentationE::Big: { - const auto repr = _other.storage_.big_.prtti_->pcopy_fnc_( - _other.storage_.big_.ptr_, - storage_.small_.data_, small_capacity, storage_.small_.prtti_, - storage_.big_.ptr_, storage_.big_.prtti_); - representation(repr); + rtti_ = any_impl::BaseRTTI::get(rtti).copy_fnc_( + _other.big_.pdata_, + small_.data_, smallCapacity(), smallAlign(), + big_.pdata_); } break; default: break; @@ -640,20 +605,14 @@ class Any { T& doEmplace(Args&&... _args) { if constexpr (is_small_type()) { - auto& rval = reinterpret_cast(storage_.small_.data_); - - ::new (const_cast(static_cast(std::addressof(rval)))) T{std::forward(_args)...}; - storage_.small_.prtti_ = &any_impl::small_rtti; - storage_.type_data_ = reinterpret_cast(&typeid(T)); - representation(any_impl::RepresentationE::Small); - + auto& rval = reinterpret_cast(small_.data_); + ::new (std::addressof(rval)) T{std::forward(_args)...}; + rtti_ = representation(&any_impl::small_rtti, any_impl::RepresentationE::Small); return rval; } else { - T* const ptr = ::new T(std::forward(_args)...); - storage_.big_.ptr_ = ptr; - storage_.big_.prtti_ = &any_impl::big_rtti; - storage_.type_data_ = reinterpret_cast(&typeid(T)); - representation(any_impl::RepresentationE::Big); + T* const ptr = ::new T(std::forward(_args)...); + big_.pdata_ = ptr; + rtti_ = representation(&any_impl::big_rtti, any_impl::RepresentationE::Big); return *ptr; } } @@ -661,22 +620,28 @@ class Any { //----------------------------------------------------------------------------- -template -inline void swap(Any& _a1, Any& _a2) noexcept +template +inline void swap(Any& _a1, Any& _a2) noexcept { _a1.swap(_a2); } -template -Any make_any(Args&&... _args) -{ - return Any{std::in_place_type, std::forward(_args)...}; -} -template -Any make_any(std::initializer_list _ilist, Args&&... _args) -{ - return Any{std::in_place_type, _ilist, std::forward(_args)...}; -} +using Any64T = Any()>; +using Any96T = Any()>; +using Any128T = Any()>; +using Any256T = Any()>; + +using SmallAnyT = Any; +using SmallAny64T = Any(), any_default_align, StoreOption::RejectBig>; +using SmallAny96T = Any(), any_default_align, StoreOption::RejectBig>; +using SmallAny128T = Any(), any_default_align, StoreOption::RejectBig>; +using SmallAny256T = Any(), any_default_align, StoreOption::RejectBig>; + +static_assert(sizeof(Any<>) == 32); +static_assert(sizeof(Any64T) == 64); +static_assert(sizeof(Any96T) == 96); +static_assert(sizeof(Any128T) == 128); +static_assert(sizeof(Any256T) == 256); //----------------------------------------------------------------------------- diff --git a/solid/utility/anyimpl.hpp b/solid/utility/anyimpl.hpp new file mode 100644 index 00000000..cbb693a2 --- /dev/null +++ b/solid/utility/anyimpl.hpp @@ -0,0 +1,41 @@ +// solid/utility/anyimpl.hpp +// +// Copyright (c) 2025 Valentin Palade (vipalade @ gmail . com) +// +// This file is part of SolidFrame framework. +// +// 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. +// + +#pragma once + +#include "solid/utility/common.hpp" + +namespace solid::any_impl { + +enum struct RepresentationE : uintptr_t { + None = 0, + Small, + Big, +}; +constexpr uintptr_t representation_mask = 3; +constexpr uintptr_t representation_and_flags_mask = representation_mask; +constexpr uintptr_t reversed_representation_and_flags_mask = ~representation_mask; + +inline RepresentationE representation(uintptr_t const _rtti) noexcept +{ + return static_cast(_rtti & representation_mask); +} + +inline uintptr_t representation(uintptr_t const _rtti, RepresentationE const _repr) noexcept +{ + return (_rtti & (~representation_and_flags_mask)) | to_underlying(_repr); +} + +inline uintptr_t representation(void const* _rtti, RepresentationE const _repr) noexcept +{ + return (reinterpret_cast(_rtti) & (~representation_and_flags_mask)) | to_underlying(_repr); +} + +} // namespace solid::any_impl \ No newline at end of file diff --git a/solid/utility/cacheable.hpp b/solid/utility/cacheable.hpp deleted file mode 100644 index 448857c7..00000000 --- a/solid/utility/cacheable.hpp +++ /dev/null @@ -1,241 +0,0 @@ -// solid/utility/cacheable.hpp -// -// Copyright (c) 2023 Valentin Palade (vipalade @ gmail . com) -// -// This file is part of SolidFrame framework. -// -// 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. -// - -#include "solid/utility/cast.hpp" -#include "solid/utility/intrusiveptr.hpp" -#include "solid/utility/stack.hpp" - -namespace solid { - -class Cacheable { -protected: - virtual void doCache() {} - virtual void cacheableClear() {} - -public: - virtual ~Cacheable() {} -}; - -class SharedCacheable : public Cacheable, public std::enable_shared_from_this { - - template - friend class EnableCacheable; - - std::shared_ptr next_; - - void doAttach(std::shared_ptr&& _other) - { - if (_other) { - _other->next_ = std::move(next_); - next_ = std::move(_other); - } - } - -public: - void cache() - { - auto next = std::move(next_); - cacheableClear(); - doCache(); - while (next) { - auto tmp = std::move(next->next_); - next->cacheableClear(); - next->doCache(); - std::swap(next, tmp); - } - } - - template - void cacheableAttach(const std::shared_ptr& _other) - { - doAttach(std::static_pointer_cast(_other)); - } - - template - void cacheableAttach(std::shared_ptr&& _other) - { - doAttach(std::static_pointer_cast(std::move(_other))); - } -}; - -class IntrusiveCacheable : public Cacheable, public IntrusiveThreadSafeBase { - - template - friend class EnableCacheable; - - IntrusivePtr next_; - - void doAttach(IntrusivePtr&& _other) - { - if (_other) { - _other->next_ = std::move(next_); - next_ = std::move(_other); - } - } - -public: - void cache() - { - auto next = std::move(next_); - cacheableClear(); - doCache(); - while (next) { - auto tmp = std::move(next->next_); - next->cacheableClear(); - next->doCache(); - std::swap(next, tmp); - } - } - - template - void cacheableAttach(const IntrusivePtr& _other) - { - doAttach(static_pointer_cast(_other)); - } - - template - void cacheableAttach(IntrusivePtr&& _other) - { - doAttach(static_pointer_cast(std::move(_other))); - } -}; - -#ifdef __cpp_concepts -template -concept SharedCacheableDerived = std::is_base_of_v; - -template -#else -template -#endif -void cacheable_cache(std::shared_ptr&& _what_ptr) -{ - if (_what_ptr) [[likely]] { - _what_ptr->cache(); - _what_ptr.reset(); - } -} - -#ifdef __cpp_concepts -template -concept IntrusiveCacheableDerived = std::is_base_of_v; - -template -#else -template -#endif -void cacheable_cache(IntrusivePtr&& _what_ptr) -{ - if (_what_ptr) [[likely]] { - _what_ptr->cache(); - _what_ptr.reset(); - } -} - -class ThreadLocalCache; - -template -class EnableCacheable : public What { - using ThisT = EnableCacheable; - -public: - static auto create() - { - if constexpr (std::is_base_of_v) { - auto ret = static_pointer_cast(Cache::template load_ip()); - if (!ret) [[unlikely]] { - ret = make_intrusive(); - } - return ret; - } else { - static_assert(std::is_base_of_v, "Type must be derived from SharedCacheable"); - auto p{Cache::template load_sp()}; - auto ret = std::static_pointer_cast(std::move(p)); - if (!ret) [[unlikely]] { - ret = std::make_shared(); - } - return ret; - } - } - - template - EnableCacheable(Args&&... _args) - : What(std::forward(_args)...) - { - } - -private: - void doCache() override - { - if constexpr (std::is_base_of_v) { - Cache::store(IntrusivePtr(static_cast(this), true)); - } else { - static_assert(std::is_base_of_v, "Type must be derived from SharedCacheable"); - Cache::store(std::static_pointer_cast(this->shared_from_this())); - } - } -}; - -class ThreadLocalCache { - template - static auto& local_stack_sp() - { - static thread_local Stack> stack; - return stack; - } - - template - static auto& local_stack_ip() - { - static thread_local Stack> stack; - return stack; - } - -public: - template - static void store(std::shared_ptr&& _what) - { - local_stack_sp().push(std::move(_what)); - } - - template - static void store(IntrusivePtr&& _what) - { - local_stack_ip().push(std::move(_what)); - } - - template - static auto load_sp() - { - auto& ls = local_stack_sp(); - if (!ls.empty()) { - auto ret = std::move(ls.top()); - ls.pop(); - return ret; - } else { - return std::shared_ptr{}; - } - } - - template - static auto load_ip() - { - auto& ls = local_stack_ip(); - if (!ls.empty()) { - auto ret = std::move(ls.top()); - ls.pop(); - return ret; - } else { - return IntrusivePtr{}; - } - } -}; - -} // namespace solid diff --git a/solid/utility/cast.hpp b/solid/utility/cast.hpp index 85695ced..ee56009e 100644 --- a/solid/utility/cast.hpp +++ b/solid/utility/cast.hpp @@ -9,7 +9,6 @@ // #pragma once -#include "solid/utility/innerlist.hpp" #include namespace solid { diff --git a/solid/utility/common.hpp b/solid/utility/common.hpp index deeb38b3..527af0fa 100644 --- a/solid/utility/common.hpp +++ b/solid/utility/common.hpp @@ -11,6 +11,8 @@ #pragma once #include "solid/system/common.hpp" +#include +#include #include #ifdef __cpp_lib_bitops #include @@ -293,4 +295,51 @@ class Padded : public Base { #endif +template +struct AlignedStorage { + static constexpr size_t size() + { + return sizeof(T); + } + + alignas(T) std::byte data_[size()]; + + std::byte* data() + { + return data_; + } + + std::byte const* data() const + { + return data_; + } + + T* cast() + { + return std::launder(reinterpret_cast(data())); + } + T const* cast() const + { + return std::launder(reinterpret_cast(data())); + } +}; + +enum class StoreOption : uint8_t { + AcceptBig, + RejectBig +}; + +using AcceptBigT = std::integral_constant; +using RejectBigT = std::integral_constant; + +template +constexpr auto store_option_dispatch() +{ + if constexpr (Option == StoreOption::AcceptBig) { + return AcceptBigT{}; + } else { + return RejectBigT{}; + } +} + } // namespace solid diff --git a/solid/utility/event.hpp b/solid/utility/event.hpp index eddf6e8e..69741c52 100644 --- a/solid/utility/event.hpp +++ b/solid/utility/event.hpp @@ -9,6 +9,8 @@ // #pragma once +#include +// #define SOLID_THROW_ON_BIG_EVENT #include #include @@ -42,12 +44,8 @@ class EventBase { const EventCategoryBase* pcategory_; uintptr_t id_; - uintptr_t type_data_ = 0; - union { - const any_impl::SmallRTTI* psmall_; - const any_impl::BigRTTI* pbig_; - } rtti_; - void* pdata_ = nullptr; + uintptr_t rtti_ = 0u; + void* pdata_ = nullptr; public: std::ostream& print(std::ostream& _ros) const; @@ -56,24 +54,28 @@ class EventBase { void resetData() { - switch (representation()) { - case any_impl::RepresentationE::Small: - rtti_.psmall_->pdestroy_fnc_(pdata_); - break; - case any_impl::RepresentationE::Big: - rtti_.pbig_->pdestroy_fnc_(pdata_); - break; + auto const rtti = rtti_; + switch (any_impl::representation(rtti)) { + [[likely]] case any_impl::RepresentationE::Small: { + auto& rrtti = any_impl::SmallRTTI::get(rtti); + if (rrtti.pdestroy_fnc_) { + rrtti.pdestroy_fnc_(pdata_); + } + } break; + case any_impl::RepresentationE::Big: { + any_impl::BigRTTI::get(rtti).destroy_fnc_(pdata_); + } break; case any_impl::RepresentationE::None: default: break; } - pdata_ = nullptr; - type_data_ = 0; + rtti_ = 0u; + pdata_ = nullptr; } bool hasData() const noexcept { - return type_data_ != 0; + return rtti_ == 0u; } bool operator==(const EventBase& _rother) const; @@ -85,12 +87,6 @@ class EventBase { return !empty(); } - const std::type_info& type() const noexcept - { - const std::type_info* const pinfo = typeInfo(); - return pinfo ? *pinfo : typeid(void); - } - template const T* cast() const noexcept { @@ -111,14 +107,11 @@ class EventBase { template const T* get_if() const noexcept { - switch (representation()) { - case any_impl::RepresentationE::Small: - return static_cast(rtti_.psmall_->pget_if_fnc_(std::type_index(typeid(T)), pdata_)); - case any_impl::RepresentationE::Big: - return static_cast(rtti_.pbig_->pget_if_fnc_(std::type_index(typeid(T)), pdata_)); - default: - return nullptr; + auto const rtti = rtti_; + if (rtti) [[likely]] { + return static_cast(any_impl::BaseRTTI::get(rtti).get_if_fnc_(std::type_index(typeid(T)), pdata_)); } + return nullptr; } template @@ -129,40 +122,37 @@ class EventBase { bool is_movable() const { - if (is_small()) { - return rtti_.psmall_->is_movable_; - } else if (is_big()) { - return rtti_.pbig_->is_movable_; + auto const rtti = rtti_; + if (rtti) [[likely]] { + return any_impl::BaseRTTI::get(rtti).is_movable_; } return true; } bool is_copyable() const { - if (is_small()) { - return rtti_.psmall_->is_copyable_; - } else if (is_big()) { - return rtti_.pbig_->is_copyable_; + auto const rtti = rtti_; + if (rtti) [[likely]] { + return any_impl::BaseRTTI::get(rtti).is_copyable_; } return true; } bool is_tuple() const { - if (is_small()) { - return rtti_.psmall_->is_tuple_; - } else if (is_big()) { - return rtti_.pbig_->is_tuple_; + auto const rtti = rtti_; + if (rtti) [[likely]] { + return any_impl::BaseRTTI::get(rtti).is_tuple_; } return false; } bool is_small() const { - return representation() == any_impl::RepresentationE::Small; + return any_impl::representation(rtti_) == any_impl::RepresentationE::Small; } bool is_big() const { - return representation() == any_impl::RepresentationE::Big; + return any_impl::representation(rtti_) == any_impl::RepresentationE::Big; } protected: @@ -173,14 +163,13 @@ class EventBase { , id_(_id) { - rtti_.psmall_ = &any_impl::dummy_small_rtti; } EventBase(const EventBase& _other) : pcategory_(_other.pcategory_) , id_(_other.id_) { - rtti_.psmall_ = _other.rtti_.psmall_; + rtti_ = _other.rtti_; } ~EventBase() @@ -188,20 +177,22 @@ class EventBase { reset(); } - any_impl::RepresentationE representation() const noexcept - { - return static_cast(type_data_ & any_impl::representation_and_flags_mask); - } - - void representation(const any_impl::RepresentationE _repr) noexcept + const std::type_info* typeInfo() const noexcept { - type_data_ &= (~any_impl::representation_and_flags_mask); - type_data_ |= static_cast(_repr); + auto const rtti = rtti_; + if (rtti) [[likely]] { + return any_impl::BaseRTTI::get(rtti).get_type_info_fnc_(); + } + return nullptr; } - const std::type_info* typeInfo() const noexcept + const std::type_info& type() const noexcept { - return reinterpret_cast(type_data_ & ~any_impl::representation_and_flags_mask); + auto const rtti = rtti_; + if (rtti) [[likely]] { + return *any_impl::BaseRTTI::get(rtti).get_type_info_fnc_(); + } + return typeid(void); } void reset(const EventBase& _other) @@ -211,82 +202,57 @@ class EventBase { resetData(); } - void doMoveFrom(void* _psmall_data, const size_t _small_capacity, EventBase& _other) + void doMoveFrom(void* _psmall_data, const size_t _small_capacity, const size_t _small_align, EventBase& _other) { - type_data_ = _other.type_data_; - pdata_ = _psmall_data; - representation(any_impl::RepresentationE::None); - switch (_other.representation()) { - case any_impl::RepresentationE::Small: { - const auto repr = _other.rtti_.psmall_->pmove_fnc_( - _other.pdata_, - _psmall_data, _small_capacity, rtti_.psmall_, - pdata_, rtti_.pbig_); - representation(repr); - _other.reset(); - } break; - case any_impl::RepresentationE::Big: { - const auto repr = _other.rtti_.pbig_->pmove_fnc_( + pdata_ = _psmall_data; + + auto const rtti = _other.rtti_; + + if (rtti) [[likely]] { + rtti_ = any_impl::BaseRTTI::get(rtti).move_fnc_( _other.pdata_, - _psmall_data, _small_capacity, rtti_.psmall_, - pdata_, rtti_.pbig_); - representation(repr); - if (repr == any_impl::RepresentationE::Big) { - _other.type_data_ = 0; - } else { - _other.reset(); + _psmall_data, _small_capacity, _small_align, + pdata_); + + if (is_big()) { + _other.rtti_ = 0u; } - } break; - default: - break; + _other.reset(); } } - void doCopyFrom(void* _psmall_data, const size_t _small_capacity, const EventBase& _other) + void doCopyFrom(void* _psmall_data, const size_t _small_capacity, const size_t _small_align, const EventBase& _other) { - type_data_ = _other.type_data_; - pdata_ = _psmall_data; - representation(any_impl::RepresentationE::None); - switch (_other.representation()) { - case any_impl::RepresentationE::Small: { - const auto repr = _other.rtti_.psmall_->pcopy_fnc_( - _other.pdata_, - _psmall_data, _small_capacity, rtti_.psmall_, - pdata_, rtti_.pbig_); - representation(repr); - } break; - case any_impl::RepresentationE::Big: { - const auto repr = _other.rtti_.pbig_->pcopy_fnc_( + pdata_ = _psmall_data; + + auto const rtti = _other.rtti_; + + if (rtti) [[likely]] { + rtti_ = any_impl::BaseRTTI::get(rtti).copy_fnc_( _other.pdata_, - _psmall_data, _small_capacity, rtti_.psmall_, - pdata_, rtti_.pbig_); - representation(repr); - } break; - default: - break; + _psmall_data, _small_capacity, _small_align, + pdata_); } } template - T& doEmplaceSmall(void* _psmall_data, const size_t _small_capacity, Args&&... _args) + T& doEmplaceSmall(void* _psmall_data, Args&&... _args) { - auto* pdata = ::new (_psmall_data) T{std::forward(_args)...}; - pdata_ = _psmall_data; - rtti_.psmall_ = &any_impl::small_rtti; - type_data_ = reinterpret_cast(&typeid(T)); - representation(any_impl::RepresentationE::Small); - + auto* pdata = ::new (_psmall_data) T{std::forward(_args)...}; + pdata_ = _psmall_data; + rtti_ = any_impl::representation(&any_impl::small_rtti, any_impl::RepresentationE::Small); return *pdata; } template T& doEmplaceBig(Args&&... _args) { +#if defined(SOLID_THROW_ON_BIG_EVENT) + solid_throw("Big Event"); +#endif T* const ptr = ::new T(std::forward(_args)...); pdata_ = ptr; - rtti_.pbig_ = &any_impl::big_rtti; - type_data_ = reinterpret_cast(&typeid(T)); - representation(any_impl::RepresentationE::Big); + rtti_ = representation(&any_impl::big_rtti, any_impl::RepresentationE::Big); return *ptr; } }; @@ -299,7 +265,7 @@ std::ostream& operator<<(std::ostream& _ros, EventBase const& _re); class EventCategoryBase { public: - const std::string& name() const + [[nodiscard]] const std::string& name() const { return name_; } @@ -312,14 +278,14 @@ class EventCategoryBase { virtual ~EventCategoryBase() {} - uintptr_t eventId(const EventBase& _revt) const + [[nodiscard]] uintptr_t eventId(const EventBase& _revt) const { return _revt.id_; } private: friend class EventBase; - virtual std::string_view eventName(const EventBase& _revt) const = 0; + [[nodiscard]] virtual std::string_view eventName(const EventBase& _revt) const = 0; private: const std::string name_; @@ -400,14 +366,18 @@ inline EventCategory category{ //----------------------------------------------------------------------------- // Event<> //----------------------------------------------------------------------------- -template +template < + size_t SmallSize = 0, + size_t SmallAlign = SmallSize == 0 ? 0 : sizeof(uintptr_t), + StoreOption Option = StoreOption::AcceptBig> + requires((SmallSize == 0 and SmallAlign == 0) or (SmallSize > 0 and SmallSize >= SmallAlign and (SmallSize % SmallAlign == 0) and std::popcount(SmallAlign) == 1)) class Event; template struct is_event; -template -struct is_event> : std::true_type { +template +struct is_event> : std::true_type { }; template <> @@ -418,8 +388,11 @@ template struct is_event : std::false_type { }; +template +inline constexpr bool is_event_v = is_event::value; + template <> -class Event<0> : public EventBase { +class Event<0, 0, StoreOption::AcceptBig> : public EventBase { public: using ThisT = Event<0>; @@ -428,6 +401,11 @@ class Event<0> : public EventBase { return 0; } + static constexpr size_t smallAlign() + { + return 0; + } + template static constexpr bool is_small_type() { @@ -452,26 +430,28 @@ class Event<0> : public EventBase { } }; -template +template + requires((SmallSize == 0 and SmallAlign == 0) or (SmallSize > 0 and SmallSize >= SmallAlign and (SmallSize % SmallAlign == 0) and std::popcount(SmallAlign) == 1)) class Event : public EventBase { - static constexpr size_t small_capacity = any_impl::compute_small_capacity(any_max(sizeof(void*), SmallSize)); - union { - unsigned char data_[small_capacity]; - max_align_t dummy_; - }; + alignas(SmallAlign) unsigned char data_[SmallSize]; public: - using ThisT = Event; + using ThisT = Event; static constexpr size_t smallCapacity() { - return small_capacity; + return SmallSize; + } + + static constexpr size_t smallAlign() + { + return SmallAlign; } template static constexpr bool is_small_type() { - return alignof(T) <= alignof(max_align_t) && sizeof(T) <= small_capacity; + return alignof(T) <= smallAlign() && sizeof(T) <= smallCapacity(); } Event() @@ -482,129 +462,136 @@ class Event : public EventBase { Event(const ThisT& _other) : EventBase(_other) { - doCopyFrom(data_, small_capacity, _other); + doCopyFrom(data_, smallCapacity(), smallAlign(), _other); } - template - Event(const Event& _other) + template + Event(const Event& _other) : EventBase(_other) { - doCopyFrom(data_, small_capacity, _other); + doCopyFrom(data_, smallCapacity(), smallAlign(), _other); } Event(ThisT&& _other) : EventBase(_other) { - doMoveFrom(data_, small_capacity, _other); + doMoveFrom(data_, smallCapacity(), smallAlign(), _other); } - template - Event(Event&& _other) + template + Event(Event&& _other) : EventBase(_other) { - doMoveFrom(data_, small_capacity, _other); + doMoveFrom(data_, smallCapacity(), smallAlign(), _other); } - template >>, std::negation, std::in_place_type_t>>>, int> = 0> - Event(const Evs _ev, T&& _rvalue) + template + Event( + const Evs _ev, T&& _rvalue, + std::integral_constant = store_option_dispatch()) + requires(not is_event_v> and not is_specialization_v, std::in_place_type_t>) : EventBase(category, to_underlying(_ev)) { - - if constexpr (is_small_type()) { - auto& rval = reinterpret_cast(data_); - doEmplaceSmall>(const_cast(static_cast(std::addressof(rval))), small_capacity, std::forward(_rvalue)); + using ValueT = std::decay_t; + static_assert(Opt == StoreOption::AcceptBig or is_small_type(), "Value not small. Construct by using AcceptBigT{} or assign using .emplace()"); + if constexpr (is_small_type()) { + auto& rval = reinterpret_cast(data_); + doEmplaceSmall(std::addressof(rval), std::forward(_rvalue)); } else { - doEmplaceBig>(std::forward(_rvalue)); + doEmplaceBig(std::forward<>(_rvalue)); } } - template >>, std::negation, std::in_place_type_t>>>, int> = 0> - Event(const EventCategoryBase& _category, const Evs _ev, T&& _rvalue) + template + Event(const EventCategoryBase& _category, const Evs _ev, + T&& _rvalue, std::integral_constant = store_option_dispatch()) + requires(not is_event_v> and not is_specialization_v, std::in_place_type_t>) : EventBase(_category, to_underlying(_ev)) { - - if constexpr (is_small_type()) { - auto& rval = reinterpret_cast(data_); - doEmplaceSmall>(const_cast(static_cast(std::addressof(rval))), small_capacity, std::forward(_rvalue)); + using ValueT = std::decay_t; + static_assert(Opt == StoreOption::AcceptBig or is_small_type(), "Value not small. Construct by using AcceptBigT{} or assign using .emplace()"); + if constexpr (is_small_type()) { + auto& rval = reinterpret_cast(data_); + doEmplaceSmall(std::addressof(rval), std::forward(_rvalue)); } else { - doEmplaceBig>(std::forward(_rvalue)); + doEmplaceBig(std::forward(_rvalue)); } } - template , Args...>>, - int> - = 0> - explicit Event(const Evs _ev, std::in_place_type_t, Args&&... _args) + template + explicit Event(const Evs _ev, std::in_place_type_t, Args&&... _args, + std::integral_constant = store_option_dispatch()) + requires(std::is_constructible_v, Args...>) : EventBase(category, to_underlying(_ev)) { - if constexpr (is_small_type()) { - auto& rval = reinterpret_cast(data_); - doEmplaceSmall>(const_cast(static_cast(std::addressof(rval))), small_capacity, std::forward(_args)...); + using ValueT = std::decay_t; + static_assert(Opt == StoreOption::AcceptBig or is_small_type(), "Value not small. Construct by using AcceptBigT{} or assign using .emplace()"); + if constexpr (is_small_type()) { + auto& rval = reinterpret_cast(data_); + doEmplaceSmall(std::addressof(rval), std::forward(_args)...); } else { - doEmplaceBig>(std::forward(_args)...); + doEmplaceBig(std::forward(_args)...); } } - template , Args...>>, - int> - = 0> - explicit Event(const EventCategoryBase& _category, const Evs _ev, std::in_place_type_t, Args&&... _args) + template + explicit Event(const EventCategoryBase& _category, const Evs _ev, std::in_place_type_t, + Args&&... _args, std::integral_constant = store_option_dispatch()) + requires(std::is_constructible_v, Args...>) : EventBase(_category, to_underlying(_ev)) { - if constexpr (is_small_type()) { - auto& rval = reinterpret_cast(data_); - doEmplaceSmall>(const_cast(static_cast(std::addressof(rval))), small_capacity, std::forward(_args)...); + using ValueT = std::decay_t; + static_assert(Opt == StoreOption::AcceptBig or is_small_type(), "Value not small. Construct by using AcceptBigT{} or assign using .emplace()"); + if constexpr (is_small_type()) { + auto& rval = reinterpret_cast(data_); + doEmplaceSmall(std::addressof(rval), std::forward(_args)...); } else { - doEmplaceBig>(std::forward(_args)...); + doEmplaceBig(std::forward(_args)...); } } - template , std::initializer_list&, Args...>, - std::is_copy_constructible>>, - int> - = 0> - explicit Event(const Evs _ev, std::in_place_type_t, std::initializer_list _ilist, Args&&... _args) + template + explicit Event(const Evs _ev, std::in_place_type_t, std::initializer_list _ilist, + Args&&... _args, std::integral_constant = store_option_dispatch()) + requires(std::is_constructible_v, std::initializer_list&, Args...> and std::is_copy_constructible_v>) : EventBase(category, to_underlying(_ev)) { - if constexpr (is_small_type()) { - auto& rval = reinterpret_cast(data_); - doEmplaceSmall>(const_cast(static_cast(std::addressof(rval))), small_capacity, _ilist, std::forward(_args)...); + using ValueT = std::decay_t; + static_assert(Opt == StoreOption::AcceptBig or is_small_type(), "Value not small. Construct by using AcceptBigT{} or assign using .emplace()"); + if constexpr (is_small_type()) { + auto& rval = reinterpret_cast(data_); + doEmplaceSmall(std::addressof(rval), _ilist, std::forward(_args)...); } else { - doEmplaceBig>(_ilist, std::forward(_args)...); + doEmplaceBig(_ilist, std::forward(_args)...); } } - template , std::initializer_list&, Args...>, - std::is_copy_constructible>>, - int> - = 0> - explicit Event(const EventCategoryBase& _category, const Evs _ev, std::in_place_type_t, std::initializer_list _ilist, Args&&... _args) + template + explicit Event(const EventCategoryBase& _category, const Evs _ev, std::in_place_type_t, + std::initializer_list _ilist, Args&&... _args, std::integral_constant = store_option_dispatch()) + requires(std::is_constructible_v, std::initializer_list&, Args...> and std::is_copy_constructible_v>) : EventBase(_category, to_underlying(_ev)) { - if constexpr (is_small_type()) { - auto& rval = reinterpret_cast(data_); - doEmplaceSmall>(const_cast(static_cast(std::addressof(rval))), small_capacity, _ilist, std::forward(_args)...); + using ValueT = std::decay_t; + static_assert(Opt == StoreOption::AcceptBig or is_small_type(), "Value not small. Construct by using AcceptBigT{} or assign using .emplace()"); + if constexpr (is_small_type()) { + auto& rval = reinterpret_cast(data_); + doEmplaceSmall(std::addressof(rval), _ilist, std::forward(_args)...); } else { - doEmplaceBig>(_ilist, std::forward(_args)...); + doEmplaceBig(_ilist, std::forward(_args)...); } } Event(const EventBase& _other) : EventBase(_other) { - doCopyFrom(data_, small_capacity, _other); + doCopyFrom(data_, smallCapacity(), smallAlign(), _other); } Event(EventBase&& _other) noexcept : EventBase(_other) { - doMoveFrom(data_, small_capacity, _other); + doMoveFrom(data_, smallCapacity(), smallAlign(), _other); } ThisT& operator=(const ThisT& _other) @@ -616,78 +603,100 @@ class Event : public EventBase { ThisT& operator=(ThisT&& _other) noexcept { reset(_other); - doMoveFrom(data_, small_capacity, _other); + doMoveFrom(data_, smallCapacity(), smallAlign(), _other); return *this; } - template - ThisT& operator=(const Event& _other) + template + ThisT& operator=(const Event& _other) { *this = ThisT{_other}; return *this; } - template - ThisT& operator=(Event&& _other) noexcept + template + ThisT& operator=(Event&& _other) noexcept { reset(_other); - doMoveFrom(data_, small_capacity, _other); + doMoveFrom(data_, smallCapacity(), smallAlign(), _other); return *this; } - template >>, std::is_copy_constructible>>, int> = 0> + template ThisT& operator=(T&& _rvalue) + requires(not is_event_v> and std::is_copy_constructible_v>) { + using ValueT = std::decay_t; + static_assert(is_small_type(), "Value not small. Construct by using AcceptBigT{} or assign using .emplace()"); + resetData(); - if constexpr (is_small_type()) { + if constexpr (is_small_type()) { auto& rval = reinterpret_cast(data_); - doEmplaceSmall>(const_cast(static_cast(std::addressof(rval))), small_capacity, std::forward(_rvalue)); + doEmplaceSmall(std::addressof(rval), std::forward(_rvalue)); } else { - doEmplaceBig>(std::forward(_rvalue)); + doEmplaceBig(std::forward(_rvalue)); } return *this; } - template , Args...>>, - int> - = 0> - std::decay_t& emplace(Args&&... _args) + template + ThisT& emplace(T&& _rvalue) + requires(not is_event_v> and std::is_copy_constructible_v>) { + using ValueT = std::decay_t; resetData(); - if constexpr (is_small_type()) { + + if constexpr (is_small_type()) { auto& rval = reinterpret_cast(data_); - return doEmplaceSmall>(const_cast(static_cast(std::addressof(rval))), small_capacity, std::forward(_args)...); + doEmplaceSmall(std::addressof(rval), std::forward(_rvalue)); } else { - return doEmplaceBig>(std::forward(_args)...); + doEmplaceBig(std::forward(_rvalue)); } + return *this; } - template , std::initializer_list&, Args...>>, int> = 0> - std::decay_t& emplace(std::initializer_list _ilist, Args&&... _args) + + template + ThisT& emplace(Args&&... _args) + requires(std::is_constructible_v, Args...>) { resetData(); - if constexpr (is_small_type()) { - auto& rval = reinterpret_cast(data_); - return doEmplaceSmall>(const_cast(static_cast(std::addressof(rval))), small_capacity, _ilist, std::forward(_args)...); + using ValueT = std::decay_t; + if constexpr (is_small_type()) { + auto& rval = reinterpret_cast(data_); + doEmplaceSmall(std::addressof(rval), std::forward(_args)...); } else { - return doEmplaceBig>(_ilist, std::forward(_args)...); + doEmplaceBig(std::forward(_args)...); } + return *this; + } + + template + ThisT& emplace(std::initializer_list _ilist, Args&&... _args) + requires(std::is_constructible_v, std::initializer_list&, Args...>) + { + resetData(); + using ValueT = std::decay_t; + if constexpr (is_small_type()) { + auto& rval = reinterpret_cast(data_); + doEmplaceSmall(std::addressof(rval), _ilist, std::forward(_args)...); + } else { + doEmplaceBig(_ilist, std::forward(_args)...); + } + return *this; } ThisT& operator=(const EventBase& _other) { reset(_other); - doCopyFrom(data_, small_capacity, _other); + doCopyFrom(data_, smallCapacity(), smallAlign(), _other); return *this; } ThisT& operator=(EventBase&& _other) { reset(_other); - doMoveFrom(data_, small_capacity, _other); + doMoveFrom(data_, smallCapacity(), smallAlign(), _other); return *this; } }; @@ -695,50 +704,58 @@ class Event : public EventBase { //----------------------------------------------------------------------------- // make_event //----------------------------------------------------------------------------- -template , int> = 0> -inline Event<> make_event(const Events _id) +template +auto make_event(const Events _id) + requires(std::is_enum_v) { return Event<>(_id); } -template , int> = 0> -inline Event<> make_event(const EventCategoryBase& _category, const Events _id) +template +auto make_event(const EventCategoryBase& _category, const Events _id) + requires(std::is_enum_v) { return Event<>(_category, _id); } -template , int> = 0> -inline Event)> make_event(const Events _id, T&& _data) +template +auto make_event(const Events _id, T&& _data) + requires(std::is_enum_v) { - return Event)>(_id, std::forward(_data)); + return Event), alignof(std::decay_t), StoreOption::RejectBig>(_id, std::forward(_data)); } -template , int> = 0> -Event)> make_event(const Events _id, Args&&... _args) +template +auto make_event(const Events _id, Args&&... _args) + requires(std::is_enum_v) { - return Event)>{_id, std::in_place_type, std::forward(_args)...}; + return Event), alignof(std::decay_t), StoreOption::RejectBig>{_id, std::in_place_type, std::forward(_args)...}; } -template , int> = 0> -Event)> make_event(const Events _id, std::initializer_list _ilist, Args&&... _args) +template +auto make_event(const Events _id, std::initializer_list _ilist, Args&&... _args) + requires(std::is_enum_v) { - return Event)>{_id, std::in_place_type, _ilist, std::forward(_args)...}; + return Event), alignof(std::decay_t), StoreOption::RejectBig>{_id, std::in_place_type, _ilist, std::forward(_args)...}; } -template , int> = 0> -inline Event)> make_event(const EventCategoryBase& _category, const Events _id, T&& _data) +template +auto make_event(const EventCategoryBase& _category, const Events _id, T&& _data) + requires(std::is_enum_v) { - return Event)>(_category, _id, std::forward(_data)); + return Event), alignof(std::decay_t), StoreOption::RejectBig>(_category, _id, std::forward(_data)); } -template , int> = 0> -Event)> make_event(const EventCategoryBase& _category, const Events _id, Args&&... _args) +template +auto make_event(const EventCategoryBase& _category, const Events _id, Args&&... _args) + requires(std::is_enum_v) { - return Event)>{_category, _id, std::in_place_type, std::forward(_args)...}; + return Event), alignof(std::decay_t), StoreOption::RejectBig>{_category, _id, std::in_place_type, std::forward(_args)...}; } -template , int> = 0> -Event)> make_event(const EventCategoryBase& _category, const Events _id, std::initializer_list _ilist, Args&&... _args) +template +auto make_event(const EventCategoryBase& _category, const Events _id, std::initializer_list _ilist, Args&&... _args) + requires(std::is_enum_v) { - return Event)>{_category, _id, std::in_place_type, _ilist, std::forward(_args)...}; + return Event), alignof(std::decay_t), StoreOption::RejectBig>{_category, _id, std::in_place_type, _ilist, std::forward(_args)...}; } //----------------------------------------------------------------------------- @@ -787,8 +804,7 @@ class EventHandlerBase { template class EventHandler : protected EventHandlerBase { public: - // using FunctionT = solid_function_t(RetVal(Event&, Args...)); - using FunctionT = std::function; + using FunctionT = Function; private: using FunctionVectorT = std::vector; diff --git a/solid/utility/function.hpp b/solid/utility/function.hpp index 9771d989..8d4af328 100644 --- a/solid/utility/function.hpp +++ b/solid/utility/function.hpp @@ -9,65 +9,88 @@ // #pragma once +// #define SOLID_THROW_ON_BIG_FUNCTION + #include #include +#include #include +#include +#include +#include #include -#include #include #include "solid/system/exception.hpp" #include "solid/system/log.hpp" +#include "solid/utility/anyimpl.hpp" #include "solid/utility/common.hpp" #include "solid/utility/typetraits.hpp" namespace solid { -inline constexpr size_t function_default_data_size = 3 * sizeof(void*); -inline constexpr size_t function_size_from_sizeof(const size_t _sizeof) -{ - return _sizeof - sizeof(void*); -} -template -inline constexpr const T& function_max(const T& a, const T& b) +template + requires(std::popcount(Align) == 1) +constexpr size_t function_size_to_small_size() { - return (a < b) ? b : a; + constexpr size_t max = std::max(sizeof(std::uintptr_t), Align); + static_assert(Size >= max, "size must be greater than sizeof(std::uintptr_t)"); + return Size - max; } -template + +constexpr size_t function_default_size = function_size_to_small_size<32>(); +constexpr size_t function_default_align = alignof(std::uintptr_t); + +template + requires(SmallSize > 0 and SmallSize >= SmallAlign + and (SmallSize % SmallAlign == 0) and std::popcount(SmallAlign) == 1) class Function; // undefined template struct is_function; -template -struct is_function> : std::true_type { +template +struct is_function> : std::true_type { }; template struct is_function : std::false_type { }; +template +inline constexpr bool is_function_v = is_function::value; + namespace fnc_impl { -enum struct RepresentationE : uintptr_t { - None = 0, - Small, - Big, -}; -constexpr uintptr_t representation_mask = 3; -constexpr uintptr_t representation_and_flags_mask = representation_mask /* + (3 << 2)*/; -template -struct SmallRTTI; +using any_impl::representation; +using any_impl::RepresentationE; +using any_impl::reversed_representation_and_flags_mask; template -struct BigRTTI { - using BigRTTIT = BigRTTI; - using SmallRTTIT = SmallRTTI; +struct BaseRTTI { + using CopyFncT = uintptr_t(const void*, void*, size_t, size_t, void*&); + using MoveFncT = uintptr_t(void*, void*, size_t, size_t, void*&); + using InvokeFncT = R(void*, ArgTypes&&...); - using DestroyFncT = void(void*); - using CopyFncT = RepresentationE(const void*, void*, const size_t, const SmallRTTIT*&, void*&, const BigRTTIT*&); - using MoveFncT = RepresentationE(void*, void*, const size_t, const SmallRTTIT*&, void*&, const BigRTTIT*&); - using InvokeFncT = R(const void*, ArgTypes&&...); + InvokeFncT& invoke_fnc_; + CopyFncT& copy_fnc_; + MoveFncT& move_fnc_; + const bool is_copyable_; + const bool is_movable_; + + static BaseRTTI const& get(uintptr_t const _rtti) noexcept + { + return *reinterpret_cast(_rtti & reversed_representation_and_flags_mask); + } +}; + +template +struct BigRTTI : BaseRTTI { + using DestroyFncT = void(void*) noexcept; + DestroyFncT& destroy_fnc_; template static void destroy(void* const _what) noexcept @@ -75,226 +98,199 @@ struct BigRTTI { ::delete static_cast(_what); } - InvokeFncT* pinvoke_fnc_; - DestroyFncT* pdestroy_fnc_; - CopyFncT* pcopy_fnc_; - MoveFncT* pmove_fnc_; - const bool is_copyable_; - const bool is_movable_; + static BigRTTI const& get(uintptr_t const _rtti) noexcept + { + return *reinterpret_cast(_rtti & reversed_representation_and_flags_mask); + } }; template -struct SmallRTTI { - using BigRTTIT = BigRTTI; - using SmallRTTIT = SmallRTTI; +struct SmallRTTI : BaseRTTI { using DestroyFncT = void(void*) noexcept; - using CopyFncT = RepresentationE(const void*, void*, const size_t, const SmallRTTIT*&, void*&, const BigRTTIT*&); - using MoveFncT = RepresentationE(void*, void*, const size_t, const SmallRTTIT*&, void*&, const BigRTTIT*&); - using InvokeFncT = R(const void*, ArgTypes&&...); + + DestroyFncT* pdestroy_fnc_; template static void destroy(void* const _what) noexcept { - static_cast(_what)->~T(); + std::destroy_at(std::launder(static_cast(_what))); } - InvokeFncT* pinvoke_fnc_; - DestroyFncT* pdestroy_fnc_; - CopyFncT* pcopy_fnc_; - MoveFncT* pmove_fnc_; - const bool is_copyable_; - const bool is_movable_; + static SmallRTTI const& get(uintptr_t const _rtti) noexcept + { + return *reinterpret_cast(_rtti & reversed_representation_and_flags_mask); + } }; template -R do_invoke(const void* _pvalue, ArgTypes&&... _args) +R do_invoke(void* _pvalue, ArgTypes&&... _args) { - return std::invoke(*const_cast(static_cast(_pvalue)), std::forward(_args)...); + T* pfun = reinterpret_cast(_pvalue); + return std::invoke(*pfun, static_cast(_args)... /* std::forward(_args)... */); } template -RepresentationE do_copy( - const void* _pfrom, - void* _pto_small, const size_t _small_cap, const SmallRTTI*& _rpsmall_rtti, - void*& _rpto_big, const BigRTTI*& _rpbig_rtti); +uintptr_t do_copy( + const void*, + void*, size_t, size_t, + void*&); template -RepresentationE do_move( - void* _pfrom, - void* _pto_small, const size_t _small_cap, const SmallRTTI*& _rpsmall_rtti, - void*& _rpto_big, const BigRTTI*& _rpbig_rtti); +uintptr_t do_move( + void*, + void*, size_t, size_t, + void*&); template -RepresentationE do_move_big( - void* _pfrom, - void* _pto_small, const size_t _small_cap, const SmallRTTI*& _rpsmall_rtti, - void*& _rpto_big, const BigRTTI*& _rpbig_rtti); +uintptr_t do_move_big( + void*, + void*, size_t, size_t, + void*&); template inline constexpr BigRTTI big_rtti = { - &do_invoke, - &BigRTTI::template destroy, &do_copy, &do_move_big, - std::is_copy_constructible_v, std::is_move_constructible_v}; + {do_invoke, + do_copy, + do_move_big, + std::is_copy_constructible_v, + std::is_move_constructible_v}, + BigRTTI::template destroy, +}; template inline constexpr SmallRTTI small_rtti = { - &do_invoke, - &SmallRTTI::template destroy, &do_copy, &do_move, - std::is_copy_constructible_v, std::is_move_constructible_v}; + {do_invoke, + do_copy, + do_move, + std::is_copy_constructible_v, + std::is_move_constructible_v}, + std::is_trivially_copyable_v ? nullptr : &SmallRTTI::template destroy, +}; template -RepresentationE do_copy( +uintptr_t do_copy( const void* _pfrom, - void* _pto_small, const size_t _small_cap, const SmallRTTI*& _rpsmall_rtti, - void*& _rpto_big, const BigRTTI*& _rpbig_rtti) + void* _pto_small, const size_t _small_cap, const size_t _small_align, + void*& _rpto_big) { - if constexpr (alignof(T) <= alignof(max_align_t) && std::is_copy_constructible_v) { - if (sizeof(T) <= _small_cap) { + if constexpr (std::is_copy_constructible_v) { + if (sizeof(T) <= _small_cap and alignof(T) <= _small_align) { T& rdst = *static_cast(_pto_small); const T& rsrc = *static_cast(_pfrom); - ::new (const_cast(static_cast(std::addressof(rdst)))) T(rsrc); - _rpsmall_rtti = &small_rtti; - return RepresentationE::Small; + ::new (std::addressof(rdst)) T(rsrc); + return representation(&small_rtti, RepresentationE::Small); } else { - _rpto_big = ::new T(*static_cast(_pfrom)); - _rpbig_rtti = &big_rtti; - return RepresentationE::Big; +#if defined(SOLID_THROW_ON_BIG_FUNCTION) + solid_throw("Big Function"); +#endif + _rpto_big = ::new T(*static_cast(_pfrom)); + return representation(&big_rtti, RepresentationE::Big); } - } else if constexpr (std::is_trivially_constructible_v || std::is_copy_constructible_v) { - _rpto_big = ::new T(*static_cast(_pfrom)); - _rpbig_rtti = &big_rtti; - return RepresentationE::Big; } else { solid_throw("Function: contained value not copyable"); - return RepresentationE::None; + return 0; } } template -RepresentationE do_move( +uintptr_t do_move( void* _pfrom, - void* _pto_small, const size_t _small_cap, const SmallRTTI*& _rpsmall_rtti, - void*& _rpto_big, const BigRTTI*& _rpbig_rtti) + void* _pto_small, const size_t _small_cap, const size_t _small_align, + void*& _rpto_big) { - if constexpr (alignof(T) <= alignof(max_align_t) && std::is_move_constructible_v) { - if (sizeof(T) <= _small_cap) { + if constexpr (std::is_move_constructible_v) { + if (sizeof(T) <= _small_cap and alignof(T) <= _small_align) { T& rdst = *static_cast(_pto_small); T& rsrc = *static_cast(_pfrom); - ::new (const_cast(static_cast(std::addressof(rdst)))) T{std::move(rsrc)}; - _rpsmall_rtti = &small_rtti; - return RepresentationE::Small; + ::new (std::addressof(rdst)) T{std::move(rsrc)}; + return representation(&small_rtti, RepresentationE::Small); } else { - _rpto_big = ::new T{std::move(*static_cast(_pfrom))}; - _rpbig_rtti = &big_rtti; - return RepresentationE::Big; +#if defined(SOLID_THROW_ON_BIG_FUNCTION) + solid_throw("Big Function"); +#endif + _rpto_big = ::new T{std::move(*static_cast(_pfrom))}; + return representation(&big_rtti, RepresentationE::Big); } - } else if constexpr (std::is_move_constructible_v) { - _rpto_big = ::new T{std::move(*static_cast(_pfrom))}; - _rpbig_rtti = &big_rtti; - return RepresentationE::Big; } else { solid_throw("Function: contained value not movable"); - return RepresentationE::None; + return 0u; } } template -RepresentationE do_move_big( +uintptr_t do_move_big( void* _pfrom, - void* _pto_small, const size_t _small_cap, const SmallRTTI*& _rpsmall_rtti, - void*& _rpto_big, const BigRTTI*& _rpbig_rtti) + void* _pto_small, const size_t _small_cap, const size_t _small_align, + void*& _rpto_big) { - if constexpr (alignof(T) <= alignof(max_align_t) && std::is_move_constructible_v) { - if (sizeof(T) <= _small_cap) { + if constexpr (std::is_move_constructible_v) { + if (sizeof(T) <= _small_cap and alignof(T) <= _small_align) { T& rdst = *static_cast(_pto_small); T& rsrc = *static_cast(_pfrom); - ::new (const_cast(static_cast(std::addressof(rdst)))) T{std::move(rsrc)}; - _rpsmall_rtti = &small_rtti; - return RepresentationE::Small; + ::new (std::addressof(rdst)) T{std::move(rsrc)}; + return representation(&small_rtti, RepresentationE::Small); } else { - _rpto_big = static_cast(_pfrom); //::new T{ std::move(*static_cast(_pfrom)) }; - _rpbig_rtti = &big_rtti; - return RepresentationE::Big; + _rpto_big = static_cast(_pfrom); + return representation(&big_rtti, RepresentationE::Big); } } else { - _rpto_big = static_cast(_pfrom); //::new T{ std::move(*static_cast(_pfrom)) }; - _rpbig_rtti = &big_rtti; - return RepresentationE::Big; + _rpto_big = static_cast(_pfrom); + return representation(&big_rtti, RepresentationE::Big); } } -constexpr size_t compute_small_capacity(const size_t _req_capacity) -{ - const size_t end_capacity = sizeof(uintptr_t) + sizeof(void*); - const size_t req_capacity = function_max(_req_capacity, function_max(end_capacity, sizeof(max_align_t)) - end_capacity); - const size_t tot_capacity = padded_size(req_capacity + sizeof(uintptr_t) + sizeof(void*), alignof(max_align_t)); - - return tot_capacity - end_capacity; -} } // namespace fnc_impl -template -class Function { - static constexpr size_t small_capacity = fnc_impl::compute_small_capacity(function_max(sizeof(void*) * 3, DataSize)); - static constexpr size_t big_padding = small_capacity - sizeof(void*); +template + requires(SmallSize > 0 and SmallSize >= SmallAlign + and (SmallSize % SmallAlign == 0) and std::popcount(SmallAlign) == 1) +class Function { + using BaseRTTI_T = fnc_impl::BaseRTTI; struct Small { - unsigned char data_[small_capacity]; - const fnc_impl::SmallRTTI* prtti_; + using RTTI_T = fnc_impl::SmallRTTI; + alignas(SmallAlign) mutable unsigned char data_[SmallSize]; }; struct Big { - unsigned char padding_[big_padding]; - void* ptr_; - const fnc_impl::BigRTTI* prtti_; + using RTTI_T = fnc_impl::BigRTTI; + mutable void* ptr_; }; struct Storage { + uintptr_t rtti_ = 0; union { Small small_; Big big_; }; - uintptr_t type_data_; }; - // static_assert(sizeof(_Storage_t) == _Any_trivial_space_size + sizeof(void*)); - // static_assert(is_standard_layout_v<_Storage_t>); - union { - Storage storage_{}; - max_align_t dummy_; - }; - template + Storage storage_{}; + + template + requires(S > 0 and S >= A + and (S % A == 0) and std::popcount(A) == 1) friend class Function; -private: - fnc_impl::RepresentationE representation() const noexcept - { - return static_cast(storage_.type_data_ & fnc_impl::representation_and_flags_mask); - } +public: + using ThisT = Function; - void representation(const fnc_impl::RepresentationE _repr) noexcept + static constexpr size_t smallCapacity() { - storage_.type_data_ &= (~fnc_impl::representation_and_flags_mask); - storage_.type_data_ |= static_cast(_repr); + return SmallSize; } - const std::type_info* typeInfo() const noexcept + static constexpr size_t smallAlign() { - return reinterpret_cast(storage_.type_data_ & ~fnc_impl::representation_and_flags_mask); + return SmallAlign; } -public: - using ThisT = Function; - template static constexpr bool is_small_type() { - return alignof(T) <= alignof(max_align_t) && sizeof(T) <= small_capacity; - } - - static constexpr size_t smallCapacity() - { - return small_capacity; + return alignof(T) <= smallAlign() && sizeof(T) <= smallCapacity(); } Function() noexcept = default; @@ -306,8 +302,8 @@ class Function { doCopyFrom(_other); } - template - Function(const Function& _other) + template + Function(const Function& _other) { doCopyFrom(_other); } @@ -317,35 +313,49 @@ class Function { doMoveFrom(_other); } - template - Function(Function&& _other) noexcept + template + Function(Function&& _other) noexcept { doMoveFrom(_other); } - template >>, std::negation, std::in_place_type_t>> /*, - std::is_copy_constructible>*/ - >, - int> - = 0> - Function(const T& _value) - { - doEmplace>(std::move(_value)); - } - - template >>, std::negation, std::in_place_type_t>> /*, - std::is_copy_constructible>*/ - >, - int> - = 0> - Function(T&& _rvalue) + template + Function(T&& _fun, std::integral_constant = store_option_dispatch()) + requires(not is_function_v> and not is_specialization_v, std::in_place_type_t>) { - doEmplace>(std::forward(_rvalue)); + using FncT = std::decay_t; + static_assert(Opt == StoreOption::AcceptBig or is_small_type(), "Function not small. Construct by using AcceptBigT{} or assign using .emplace()"); + if constexpr (is_small_type()) { + storage_.rtti_ = fnc_impl::representation(&fnc_impl::small_rtti, fnc_impl::RepresentationE::Small); + auto& rval = reinterpret_cast(storage_.small_.data_); + std::construct_at(std::addressof(rval), std::forward(_fun)); + } else { +#if defined(SOLID_THROW_ON_BIG_FUNCTION) + solid_throw("Big Function"); +#endif + FncT* const ptr = ::new FncT(std::forward(_fun)); + storage_.big_.ptr_ = ptr; + storage_.rtti_ = fnc_impl::representation(&fnc_impl::big_rtti, fnc_impl::RepresentationE::Big); + } } ~Function() noexcept { - reset(); + auto const rtti = storage_.rtti_; + switch (fnc_impl::representation(rtti)) { + [[likely]] case fnc_impl::RepresentationE::Small: + if (auto* pf = Small::RTTI_T::get(rtti).pdestroy_fnc_) { + (*pf)(storage_.small_.data_); + } + break; + case fnc_impl::RepresentationE::Big: + Big::RTTI_T::get(rtti).destroy_fnc_(storage_.big_.ptr_); + break; + case fnc_impl::RepresentationE::None: + [[fallthrough]]; + default: + break; + } } ThisT& operator=(const ThisT& _other) @@ -361,66 +371,76 @@ class Function { return *this; } - template - ThisT& operator=(const Function& _other) + template + ThisT& operator=(const Function& _other) { *this = ThisT{_other}; return *this; } - template - ThisT& operator=(Function&& _other) noexcept + template + ThisT& operator=(Function&& _other) noexcept { reset(); doMoveFrom(_other); return *this; } - template >>, std::is_copy_constructible>>, int> = 0> + template ThisT& operator=(T&& _rvalue) { *this = ThisT{std::forward(_rvalue)}; return *this; } + template + ThisT& emplace(T&& _rvalue) + { + *this = ThisT{std::forward(_rvalue), AcceptBigT{}}; + return *this; + } + void reset() noexcept { - switch (representation()) { - case fnc_impl::RepresentationE::Small: - storage_.small_.prtti_->pdestroy_fnc_(&storage_.small_.data_); + auto const rtti = storage_.rtti_; + switch (fnc_impl::representation(rtti)) { + [[likely]] case fnc_impl::RepresentationE::Small: + if (auto* pfnc = Small::RTTI_T::get(rtti).pdestroy_fnc_) { + (*pfnc)(storage_.small_.data_); + } break; case fnc_impl::RepresentationE::Big: - storage_.big_.prtti_->pdestroy_fnc_(storage_.big_.ptr_); + Big::RTTI_T::get(rtti).destroy_fnc_(storage_.big_.ptr_); break; case fnc_impl::RepresentationE::None: + [[fallthrough]]; default: break; } - storage_.type_data_ = 0; + storage_.rtti_ = 0; } R operator()(ArgTypes... _args) const { - if (has_value()) { - if (is_small()) { - return storage_.small_.prtti_->pinvoke_fnc_(&storage_.small_.data_, std::forward(_args)...); - } else { - return storage_.big_.prtti_->pinvoke_fnc_(storage_.big_.ptr_, std::forward(_args)...); - } + auto const rtti = storage_.rtti_; + if (auto const repr = fnc_impl::representation(rtti); repr == fnc_impl::RepresentationE::Small) [[likely]] { + return Small::RTTI_T::get(rtti).invoke_fnc_(storage_.small_.data_, static_cast(_args)...); + } else if (repr == fnc_impl::RepresentationE::Big) { + return Big::RTTI_T::get(rtti).invoke_fnc_(storage_.big_.ptr_, static_cast(_args)...); } else { throw std::bad_function_call(); } } - template - void swap(Function& _other) noexcept + template + void swap(Function& _other) noexcept { _other = std::exchange(*this, std::move(_other)); } bool has_value() const noexcept { - return storage_.type_data_ != 0; + return storage_.rtti_ != 0; } bool empty() const noexcept { @@ -432,123 +452,118 @@ class Function { return has_value(); } - const std::type_info& type() const noexcept - { - const std::type_info* const pinfo = typeInfo(); - return pinfo ? *pinfo : typeid(void); - } - bool is_movable() const { - if (is_small()) { - return storage_.small_.prtti_->is_movable_; - } else if (is_big()) { - return storage_.big_.prtti_->is_copyable_; + auto const rtti = storage_.rtti_; + if (rtti) [[likely]] { + return BaseRTTI_T::get(rtti).is_movable_; } return true; } bool is_copyable() const { - if (is_small()) { - return storage_.small_.prtti_->is_copyable_; - } else if (is_big()) { - return storage_.big_.prtti_->is_copyable_; + auto const rtti = storage_.rtti_; + if (rtti) [[likely]] { + return BaseRTTI_T::get(rtti).is_copyable_; } return true; } - bool is_small() const + [[nodiscard]] bool is_small() const { - return representation() == fnc_impl::RepresentationE::Small; + return fnc_impl::representation(storage_.rtti_) == fnc_impl::RepresentationE::Small; } - bool is_big() const + + [[nodiscard]] bool is_big() const { - return representation() == fnc_impl::RepresentationE::Big; + return fnc_impl::representation(storage_.rtti_) == fnc_impl::RepresentationE::Big; } private: - template - void doMoveFrom(Function& _other) + template + void doMoveFrom(Function& _other) { - storage_.type_data_ = _other.storage_.type_data_; - representation(fnc_impl::RepresentationE::None); - switch (_other.representation()) { + storage_.rtti_ = 0u; + switch (fnc_impl::representation(_other.storage_.rtti_)) { case fnc_impl::RepresentationE::Small: { - const auto repr = _other.storage_.small_.prtti_->pmove_fnc_( - _other.storage_.small_.data_, - storage_.small_.data_, small_capacity, storage_.small_.prtti_, - storage_.big_.ptr_, storage_.big_.prtti_); - representation(repr); + storage_.rtti_ = Small::RTTI_T::get(_other.storage_.rtti_).move_fnc_(_other.storage_.small_.data_, storage_.small_.data_, smallCapacity(), smallAlign(), storage_.big_.ptr_); + _other.reset(); } break; case fnc_impl::RepresentationE::Big: { - const auto repr = _other.storage_.big_.prtti_->pmove_fnc_( - _other.storage_.big_.ptr_, - storage_.small_.data_, small_capacity, storage_.small_.prtti_, - storage_.big_.ptr_, storage_.big_.prtti_); - representation(repr); - if (repr == fnc_impl::RepresentationE::Big) { - _other.storage_.type_data_ = 0; + storage_.rtti_ = Big::RTTI_T::get(_other.storage_.rtti_).move_fnc_(_other.storage_.big_.ptr_, storage_.small_.data_, smallCapacity(), smallAlign(), storage_.big_.ptr_); + if (is_big()) { + _other.storage_.rtti_ = 0u; } + _other.reset(); } break; default: break; } } - template - void doCopyFrom(const Function& _other) + template + void doCopyFrom(const Function& _other) { - storage_.type_data_ = _other.storage_.type_data_; - representation(fnc_impl::RepresentationE::None); - switch (_other.representation()) { + storage_.rtti_ = 0u; + switch (fnc_impl::representation(_other.storage_.rtti_)) { case fnc_impl::RepresentationE::Small: { - const auto repr = _other.storage_.small_.prtti_->pcopy_fnc_( - _other.storage_.small_.data_, - storage_.small_.data_, small_capacity, storage_.small_.prtti_, - storage_.big_.ptr_, storage_.big_.prtti_); - representation(repr); + storage_.rtti_ = Small::RTTI_T::get(_other.storage_.rtti_).copy_fnc_(_other.storage_.small_.data_, storage_.small_.data_, smallCapacity(), smallAlign(), storage_.big_.ptr_); } break; case fnc_impl::RepresentationE::Big: { - const auto repr = _other.storage_.big_.prtti_->pcopy_fnc_( - _other.storage_.big_.ptr_, - storage_.small_.data_, small_capacity, storage_.small_.prtti_, - storage_.big_.ptr_, storage_.big_.prtti_); - representation(repr); + storage_.rtti_ = Big::RTTI_T::get(_other.storage_.rtti_).copy_fnc_(_other.storage_.big_.ptr_, storage_.small_.data_, smallCapacity(), smallAlign(), storage_.big_.ptr_); } break; default: break; } } - template - T& doEmplace(Args&&... _args) + template + void doEmplace(Fnc _fun) { - if constexpr (is_small_type()) { - auto& rval = reinterpret_cast(storage_.small_.data_); - - ::new (const_cast(static_cast(std::addressof(rval)))) T{std::forward(_args)...}; - storage_.small_.prtti_ = &fnc_impl::small_rtti; - storage_.type_data_ = reinterpret_cast(&typeid(T)); - representation(fnc_impl::RepresentationE::Small); - - return rval; + using FncT = std::decay_t; + if constexpr (is_small_type()) { + storage_.rtti_ = representation(&fnc_impl::small_rtti, fnc_impl::RepresentationE::Small); + auto& rval = reinterpret_cast(storage_.small_.data_); + std::construct_at(std::addressof(rval), std::move(_fun)); + // new (&rval) FncT(std::move(_fun)); } else { - T* const ptr = ::new T(std::forward(_args)...); - storage_.big_.ptr_ = ptr; - storage_.big_.prtti_ = &fnc_impl::big_rtti; - storage_.type_data_ = reinterpret_cast(&typeid(T)); - representation(fnc_impl::RepresentationE::Big); - return *ptr; +#if defined(SOLID_THROW_ON_BIG_FUNCTION) + solid_throw("Big Function"); +#endif + FncT* const ptr = ::new FncT(std::move(_fun)); + storage_.big_.ptr_ = ptr; + storage_.rtti_ = representation(&fnc_impl::big_rtti, fnc_impl::RepresentationE::Big); } } }; //----------------------------------------------------------------------------- +template +using Function64T = Function()>; +template +using Function96T = Function()>; +template +using Function128T = Function()>; +template +using Function256T = Function()>; + +template +using SmallFunctionT = Function; +template +using SmallFunction64T = Function(), function_default_align, StoreOption::RejectBig>; +template +using SmallFunction96T = Function(), function_default_align, StoreOption::RejectBig>; +template +using SmallFunction128T = Function(), function_default_align, StoreOption::RejectBig>; +template +using SmallFunction256T = Function(), function_default_align, StoreOption::RejectBig>; //----------------------------------------------------------------------------- } // namespace solid +#if 0 + #ifdef SOLID_USE_STD_FUNCTION #define solid_function_t(...) std::function<__VA_ARGS__> @@ -561,3 +576,4 @@ class Function { #define solid_function_empty(f) (!f) #define solid_function_clear(f) (f = nullptr) +#endif \ No newline at end of file diff --git a/solid/utility/intrusiveptr.hpp b/solid/utility/intrusiveptr.hpp index 3204a8b9..4a05f109 100644 --- a/solid/utility/intrusiveptr.hpp +++ b/solid/utility/intrusiveptr.hpp @@ -8,9 +8,12 @@ // See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt. // #pragma once - +#include "solid/utility/poolable.hpp" #include +#include #include +#include +#include namespace solid { @@ -18,7 +21,7 @@ struct IntrusiveThreadSafePolicy; class IntrusiveThreadSafeBase { friend struct IntrusiveThreadSafePolicy; - mutable std::atomic_size_t use_count_{0}; + mutable std::atomic_size_t use_count_{1}; protected: auto useCount() const @@ -115,9 +118,35 @@ class IntrusivePtrBase { protected: T* ptr_ = nullptr; -protected: IntrusivePtrBase() = default; + IntrusivePtrBase(T* _ptr) + : ptr_(_ptr) + { + assert(ptr_ == nullptr or intrusive_ptr_use_count(*ptr_) == 1U); + } + + IntrusivePtrBase(T* _ptr, const bool _do_acquire) + : ptr_(_ptr) + { + if (_ptr && _do_acquire) { + intrusive_ptr_acquire(*_ptr); + } + } + + IntrusivePtrBase(T* _ptr, const std::true_type) + : ptr_(_ptr) + { + if (_ptr) { + intrusive_ptr_acquire(*_ptr); + } + } + + IntrusivePtrBase(T* _ptr, const std::false_type) + : ptr_(_ptr) + { + } + IntrusivePtrBase(const IntrusivePtrBase& _other) : ptr_(_other.ptr_) { @@ -126,7 +155,7 @@ class IntrusivePtrBase { } } - IntrusivePtrBase(IntrusivePtrBase&& _other) + IntrusivePtrBase(IntrusivePtrBase&& _other) noexcept : ptr_(_other.detach()) { } @@ -142,7 +171,7 @@ class IntrusivePtrBase { template IntrusivePtrBase(IntrusivePtrBase&& _other) - : ptr_(static_cast(_other.detach())) + : ptr_(static_cast(_other.detach())) { } @@ -174,22 +203,6 @@ class IntrusivePtrBase { IntrusivePtrBase{std::move(_other)}.swap(*this); } - IntrusivePtrBase(T* _ptr) - : ptr_(_ptr) - { - if (_ptr) { - intrusive_ptr_acquire(*_ptr); - } - } - - IntrusivePtrBase(T* _ptr, const bool _do_acquire) - : ptr_(_ptr) - { - if (_ptr && _do_acquire) { - intrusive_ptr_acquire(*_ptr); - } - } - T* detach() noexcept { T* ret = ptr_; @@ -204,6 +217,9 @@ class IntrusivePtrBase { _other.ptr_ = tmp; } + template