From 46de8ae67dd623ed60deab8ae44da402358ad59e Mon Sep 17 00:00:00 2001 From: Valentin Palade Date: Mon, 25 Nov 2024 14:46:13 +0200 Subject: [PATCH 01/14] fix warnings --- solid/frame/aio/aiolistener.hpp | 19 +++++------ solid/frame/aio/src/aiolistener.cpp | 34 +++++++++---------- solid/frame/mprpc/src/mprpclistener.cpp | 12 +++---- solid/frame/mprpc/src/mprpclistener.hpp | 4 +-- solid/frame/mprpc/src/mprpcmessagereader.cpp | 2 +- solid/frame/mprpc/src/mprpcservice.cpp | 4 +-- .../mprpc/test/test_clientserver_topic.cpp | 4 +-- solid/frame/mprpc/test/test_relay_basic.cpp | 4 +-- .../mprpc/test/test_relay_cancel_request.cpp | 4 +-- .../mprpc/test/test_relay_cancel_response.cpp | 4 +-- .../mprpc/test/test_relay_close_request.cpp | 4 +-- .../mprpc/test/test_relay_close_response.cpp | 4 +-- .../mprpc/test/test_relay_detect_close.cpp | 4 +-- ...test_relay_detect_close_while_response.cpp | 4 +-- .../frame/mprpc/test/test_relay_disabled.cpp | 4 +-- solid/frame/mprpc/test/test_relay_split.cpp | 4 +-- solid/utility/test/test_threadpool_batch.cpp | 2 +- 17 files changed, 58 insertions(+), 59 deletions(-) diff --git a/solid/frame/aio/aiolistener.hpp b/solid/frame/aio/aiolistener.hpp index ff613f8b..15f7b953 100644 --- a/solid/frame/aio/aiolistener.hpp +++ b/solid/frame/aio/aiolistener.hpp @@ -31,12 +31,16 @@ 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; + FunctionT f_; + SocketBase s_; + public: Listener( ActorProxy const& _ract, SocketDevice&& _rsd) : CompletionHandler(_ract, Listener::on_init_completion) - , s(std::move(_rsd)) + , s_(std::move(_rsd)) { } @@ -55,8 +59,8 @@ class Listener : public CompletionHandler { template bool postAccept(ReactorContext& _rctx, F&& _f) { - if (solid_function_empty(f)) { - f = std::forward(_f); + if (solid_function_empty(f_)) { + f_ = std::forward(_f); doPostAccept(_rctx); return false; } else { @@ -70,13 +74,13 @@ class Listener : public CompletionHandler { template bool accept(ReactorContext& _rctx, F&& _f, SocketDevice& _rsd) { - if (solid_function_empty(f)) { + if (solid_function_empty(f_)) { contextBind(_rctx); if (this->doTryAccept(_rctx, _rsd)) { return true; } - f = std::forward(_f); + f_ = std::forward(_f); return false; } else { error(_rctx, error_already); @@ -89,11 +93,6 @@ class Listener : public CompletionHandler { bool doTryAccept(ReactorContext& _rctx, SocketDevice& _rsd); void doAccept(ReactorContext& _rctx, solid::SocketDevice& _rsd); void doClear(ReactorContext& _rctx); - -private: - typedef solid_function_t(void(ReactorContext&, SocketDevice&)) FunctionT; - FunctionT f; - SocketBase s; }; } // namespace aio diff --git a/solid/frame/aio/src/aiolistener.cpp b/solid/frame/aio/src/aiolistener.cpp index e199f043..63ed5b8e 100644 --- a/solid/frame/aio/src/aiolistener.cpp +++ b/solid/frame/aio/src/aiolistener.cpp @@ -27,7 +27,7 @@ const LoggerT logger("solid::frame::aio"); // rthis.completionCallback(on_dummy_completion); rthis.completionCallback(&on_completion); // rthis.contextBind(_rctx); - rthis.s.initAccept(_rctx); + rthis.s_.initAccept(_rctx); } /*static*/ void Listener::on_completion(CompletionHandler& _rch, ReactorContext& _rctx) @@ -36,11 +36,11 @@ const LoggerT logger("solid::frame::aio"); switch (rthis.reactorEvent(_rctx)) { case ReactorEventE::Recv: - if (!solid_function_empty(rthis.f)) { + if (!solid_function_empty(rthis.f_)) { SocketDevice sd; FunctionT tmpf; - std::swap(tmpf, rthis.f); - solid_assert_log(solid_function_empty(rthis.f), logger); + std::swap(tmpf, rthis.f_); + solid_assert_log(solid_function_empty(rthis.f_), logger); rthis.doAccept(_rctx, sd); tmpf(_rctx, sd); @@ -48,10 +48,10 @@ const LoggerT logger("solid::frame::aio"); break; case ReactorEventE::Error: case ReactorEventE::Hangup: - if (!solid_function_empty(rthis.f)) { + if (!solid_function_empty(rthis.f_)) { SocketDevice sd; FunctionT tmpf; - std::swap(tmpf, rthis.f); + std::swap(tmpf, rthis.f_); rthis.error(_rctx, error_listener_hangup); @@ -72,9 +72,9 @@ const LoggerT logger("solid::frame::aio"); Listener& rthis = *pthis; SocketDevice sd; - if (!solid_function_empty(rthis.f) && rthis.doTryAccept(_rctx, sd)) { + if (!solid_function_empty(rthis.f_) && rthis.doTryAccept(_rctx, sd)) { FunctionT tmpf; - std::swap(tmpf, rthis.f); + std::swap(tmpf, rthis.f_); tmpf(_rctx, sd); } } @@ -85,14 +85,14 @@ const LoggerT logger("solid::frame::aio"); SocketDevice Listener::reset(ReactorContext& _rctx, SocketDevice&& _rnewdev) { - if (s.device()) { - remDevice(_rctx, s.device()); + if (s_.device()) { + remDevice(_rctx, s_.device()); } contextBind(_rctx); - SocketDevice tmpsd = s.resetAccept(_rctx, std::move(_rnewdev)); - if (s.device()) { + SocketDevice tmpsd = s_.resetAccept(_rctx, std::move(_rnewdev)); + if (s_.device()) { completionCallback(&on_completion); } return tmpsd; @@ -106,7 +106,7 @@ void Listener::doPostAccept(ReactorContext& _rctx) bool Listener::doTryAccept(ReactorContext& _rctx, SocketDevice& _rsd) { bool can_retry; - ErrorCodeT err = s.accept(_rctx, _rsd, can_retry); + ErrorCodeT err = s_.accept(_rctx, _rsd, can_retry); if (!err) { } else if (can_retry) { @@ -121,7 +121,7 @@ bool Listener::doTryAccept(ReactorContext& _rctx, SocketDevice& _rsd) void Listener::doAccept(ReactorContext& _rctx, SocketDevice& _rsd) { bool can_retry; - ErrorCodeT err = s.accept(_rctx, _rsd, can_retry); + ErrorCodeT err = s_.accept(_rctx, _rsd, can_retry); if (!err) { } else if (can_retry) { @@ -134,9 +134,9 @@ void Listener::doAccept(ReactorContext& _rctx, SocketDevice& _rsd) void Listener::doClear(ReactorContext& _rctx) { - solid_function_clear(f); - remDevice(_rctx, s.device()); - f = &on_dummy; + solid_function_clear(f_); + remDevice(_rctx, s_.device()); + f_ = &on_dummy; } } // namespace aio diff --git a/solid/frame/mprpc/src/mprpclistener.cpp b/solid/frame/mprpc/src/mprpclistener.cpp index 0186b184..2e63ccad 100644 --- a/solid/frame/mprpc/src/mprpclistener.cpp +++ b/solid/frame/mprpc/src/mprpclistener.cpp @@ -22,8 +22,8 @@ const LoggerT logger("solid::frame::mprpc::listener"); Listener::Listener( SocketDevice& _rsd) - : sock(this->proxy(), std::move(_rsd)) - , timer(this->proxy()) + : sock_(this->proxy(), std::move(_rsd)) + , timer_(this->proxy()) { solid_log(logger, Info, this); } @@ -42,7 +42,7 @@ inline Service& Listener::service(frame::aio::ReactorContext& _rctx) solid_log(logger, Info, "event = " << _uevent); if ( _uevent == generic_event || _uevent == generic_event) { - sock.postAccept( + sock_.postAccept( _rctx, [this](frame::aio::ReactorContext& _rctx, SocketDevice& _rsd) { onAccept(_rctx, _rsd); }); } else if (_uevent == generic_event) { @@ -64,17 +64,17 @@ void Listener::onAccept(frame::aio::ReactorContext& _rctx, SocketDevice& _rsd) postStop(_rctx); } else { solid_log(logger, Info, "listen error" << _rctx.error().message()); - timer.waitFor( + timer_.waitFor( _rctx, std::chrono::seconds(10), [this](frame::aio::ReactorContext& _rctx) { onEvent(_rctx, make_event(GenericEventE::Timer)); }); break; } --repeatcnt; } while ( - repeatcnt != 0u && sock.accept(_rctx, [this](frame::aio::ReactorContext& _rctx, SocketDevice& _rsd) { onAccept(_rctx, _rsd); }, _rsd)); + repeatcnt != 0u && sock_.accept(_rctx, [this](frame::aio::ReactorContext& _rctx, SocketDevice& _rsd) { onAccept(_rctx, _rsd); }, _rsd)); if (repeatcnt == 0u) { - sock.postAccept( + sock_.postAccept( _rctx, [this](frame::aio::ReactorContext& _rctx, SocketDevice& _rsd) { onAccept(_rctx, _rsd); }); // fully asynchronous call } diff --git a/solid/frame/mprpc/src/mprpclistener.hpp b/solid/frame/mprpc/src/mprpclistener.hpp index c910c662..51ba8d2c 100644 --- a/solid/frame/mprpc/src/mprpclistener.hpp +++ b/solid/frame/mprpc/src/mprpclistener.hpp @@ -49,8 +49,8 @@ class Listener final : public frame::aio::Actor { typedef frame::aio::Listener ListenerSocketT; typedef frame::aio::SteadyTimer TimerT; - ListenerSocketT sock; - TimerT timer; + ListenerSocketT sock_; + TimerT timer_; }; } // namespace mprpc diff --git a/solid/frame/mprpc/src/mprpcmessagereader.cpp b/solid/frame/mprpc/src/mprpcmessagereader.cpp index a61be0bf..69b2ab7b 100644 --- a/solid/frame/mprpc/src/mprpcmessagereader.cpp +++ b/solid/frame/mprpc/src/mprpcmessagereader.cpp @@ -49,7 +49,7 @@ size_t MessageReader::read( while (pbufpos != pbufend) { if (state_ == StateE::ReadPacketHead) { // try read the header - if ((pbufend - pbufpos) >= PacketHeader::size_of_header) { + if ((pbufend - pbufpos) >= static_cast(PacketHeader::size_of_header)) { state_ = StateE::ReadPacketBody; } else { break; diff --git a/solid/frame/mprpc/src/mprpcservice.cpp b/solid/frame/mprpc/src/mprpcservice.cpp index 56d6e5b1..4f629c7e 100644 --- a/solid/frame/mprpc/src/mprpcservice.cpp +++ b/solid/frame/mprpc/src/mprpcservice.cpp @@ -2604,8 +2604,6 @@ void Service::acceptIncomingConnection(SocketDevice& _rsd) { solid_log(logger, Verbose, this); - configuration().server.socket_device_setup_fnc(_rsd); - size_t pool_index; { lock_guard lock(pimpl_->rmutex_); @@ -2618,6 +2616,8 @@ void Service::acceptIncomingConnection(SocketDevice& _rsd) } } + configuration().server.socket_device_setup_fnc(_rsd); + { lock_guard pool_lock(pimpl_->poolMutex(pool_index)); ConnectionPoolStub& rpool(pimpl_->pool_dq_[pool_index]); diff --git a/solid/frame/mprpc/test/test_clientserver_topic.cpp b/solid/frame/mprpc/test/test_clientserver_topic.cpp index c29bb8bf..237d2ec8 100644 --- a/solid/frame/mprpc/test/test_clientserver_topic.cpp +++ b/solid/frame/mprpc/test/test_clientserver_topic.cpp @@ -291,10 +291,10 @@ size_t max_per_pool_connection_count = std::atomic client_connection_count{0}; std::promise client_connection_promise; std::promise promise; -std::atomic_bool running = true; -bool cache_local_messages = false; +std::atomic_bool running = true; thread_local unique_ptr local_thread_pool_context_ptr; chrono::microseconds test_duration{chrono::seconds(1)}; +// bool cache_local_messages = false; #ifdef TRACE_DURATION DurationDqT duration_dq; diff --git a/solid/frame/mprpc/test/test_relay_basic.cpp b/solid/frame/mprpc/test/test_relay_basic.cpp index 8582aa53..ba04ef15 100644 --- a/solid/frame/mprpc/test/test_relay_basic.cpp +++ b/solid/frame/mprpc/test/test_relay_basic.cpp @@ -93,8 +93,8 @@ struct Register : frame::mprpc::Message { uint16_t replica_id_ = 0; Register(const uint32_t _group_id, uint32_t _err = 0) - : group_id_(_group_id) - , err_(_err) + : err_(_err) + , group_id_(_group_id) { solid_dbg(generic_logger, Info, "CREATE ---------------- " << this); } diff --git a/solid/frame/mprpc/test/test_relay_cancel_request.cpp b/solid/frame/mprpc/test/test_relay_cancel_request.cpp index c0c48f6a..8121b0e3 100644 --- a/solid/frame/mprpc/test/test_relay_cancel_request.cpp +++ b/solid/frame/mprpc/test/test_relay_cancel_request.cpp @@ -115,8 +115,8 @@ struct Register : frame::mprpc::Message { uint16_t replica_id_ = 0; Register(const uint32_t _group_id, uint32_t _err = 0) - : group_id_(_group_id) - , err_(_err) + : err_(_err) + , group_id_(_group_id) { solid_dbg(generic_logger, Info, "CREATE ---------------- " << this); } diff --git a/solid/frame/mprpc/test/test_relay_cancel_response.cpp b/solid/frame/mprpc/test/test_relay_cancel_response.cpp index d61feaa7..ac11fc2a 100644 --- a/solid/frame/mprpc/test/test_relay_cancel_response.cpp +++ b/solid/frame/mprpc/test/test_relay_cancel_response.cpp @@ -116,8 +116,8 @@ struct Register : frame::mprpc::Message { uint16_t replica_id_ = 0; Register(const uint32_t _group_id, uint32_t _err = 0) - : group_id_(_group_id) - , err_(_err) + : err_(_err) + , group_id_(_group_id) { solid_dbg(generic_logger, Info, "CREATE ---------------- " << this); } diff --git a/solid/frame/mprpc/test/test_relay_close_request.cpp b/solid/frame/mprpc/test/test_relay_close_request.cpp index 505363aa..39a7d7b5 100644 --- a/solid/frame/mprpc/test/test_relay_close_request.cpp +++ b/solid/frame/mprpc/test/test_relay_close_request.cpp @@ -99,8 +99,8 @@ struct Register : frame::mprpc::Message { uint16_t replica_id_ = 0; Register(const uint32_t _group_id, uint32_t _err = 0) - : group_id_(_group_id) - , err_(_err) + : err_(_err) + , group_id_(_group_id) { solid_dbg(generic_logger, Info, "CREATE ---------------- " << this); } diff --git a/solid/frame/mprpc/test/test_relay_close_response.cpp b/solid/frame/mprpc/test/test_relay_close_response.cpp index 84db8c9a..3fb4b160 100644 --- a/solid/frame/mprpc/test/test_relay_close_response.cpp +++ b/solid/frame/mprpc/test/test_relay_close_response.cpp @@ -102,8 +102,8 @@ struct Register : frame::mprpc::Message { uint16_t replica_id_ = 0; Register(const uint32_t _group_id, uint32_t _err = 0) - : group_id_(_group_id) - , err_(_err) + : err_(_err) + , group_id_(_group_id) { solid_dbg(generic_logger, Info, "CREATE ---------------- " << this); } diff --git a/solid/frame/mprpc/test/test_relay_detect_close.cpp b/solid/frame/mprpc/test/test_relay_detect_close.cpp index 1c2bc749..66f14b1f 100644 --- a/solid/frame/mprpc/test/test_relay_detect_close.cpp +++ b/solid/frame/mprpc/test/test_relay_detect_close.cpp @@ -55,8 +55,8 @@ struct Register : frame::mprpc::Message { uint16_t replica_id_ = 0; Register(const uint32_t _group_id, uint32_t _err = 0) - : group_id_(_group_id) - , err_(_err) + : err_(_err) + , group_id_(_group_id) { solid_dbg(generic_logger, Info, "CREATE ---------------- " << this); } 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 048b53ab..c80982cd 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 @@ -83,8 +83,8 @@ struct Register : frame::mprpc::Message { uint16_t replica_id_ = 0; Register(const uint32_t _group_id, uint32_t _err = 0) - : group_id_(_group_id) - , err_(_err) + : err_(_err) + , group_id_(_group_id) { solid_dbg(generic_logger, Info, "CREATE ---------------- " << this); } diff --git a/solid/frame/mprpc/test/test_relay_disabled.cpp b/solid/frame/mprpc/test/test_relay_disabled.cpp index 88c53b01..31710c16 100644 --- a/solid/frame/mprpc/test/test_relay_disabled.cpp +++ b/solid/frame/mprpc/test/test_relay_disabled.cpp @@ -92,8 +92,8 @@ struct Register : frame::mprpc::Message { uint16_t replica_id_ = 0; Register(const uint32_t _group_id, uint32_t _err = 0) - : group_id_(_group_id) - , err_(_err) + : err_(_err) + , group_id_(_group_id) { solid_dbg(generic_logger, Info, "CREATE ---------------- " << this); } diff --git a/solid/frame/mprpc/test/test_relay_split.cpp b/solid/frame/mprpc/test/test_relay_split.cpp index b08b143b..79056234 100644 --- a/solid/frame/mprpc/test/test_relay_split.cpp +++ b/solid/frame/mprpc/test/test_relay_split.cpp @@ -92,8 +92,8 @@ struct Register : frame::mprpc::Message { uint16_t replica_id_ = 0; Register(const uint32_t _group_id, uint32_t _err = 0) - : group_id_(_group_id) - , err_(_err) + : err_(_err) + , group_id_(_group_id) { solid_dbg(generic_logger, Info, "CREATE ---------------- " << this); } diff --git a/solid/utility/test/test_threadpool_batch.cpp b/solid/utility/test/test_threadpool_batch.cpp index c51195fa..976e7fb9 100644 --- a/solid/utility/test/test_threadpool_batch.cpp +++ b/solid/utility/test/test_threadpool_batch.cpp @@ -100,7 +100,7 @@ int test_threadpool_batch(int argc, char* argv[]) solid::log_start(std::cerr, {".*:EWXS", "test:VIEWS"}); int wait_seconds = 500; size_t entry_count = 300; - size_t repeat_count = 1000000; + // size_t repeat_count = 1000000; solid_log(logger, Verbose, "capacity " << capacity << " reminder " << (std::numeric_limits::max() % capacity)); { vector cnt_vec(capacity, 0); From 50c1309de783eded8241fdefac84961c98f79103 Mon Sep 17 00:00:00 2001 From: Valentin Palade Date: Wed, 11 Dec 2024 00:14:28 +0200 Subject: [PATCH 02/14] aio: fixes - mprpc: fixes and support for ConnectionContext::stop --- CMakeLists.txt | 33 ++++ JOURNAL.md | 5 + configure | 8 +- solid/frame/aio/aiostream.hpp | 9 +- solid/frame/mprpc/mprpccontext.hpp | 58 +++--- solid/frame/mprpc/mprpcmessage.hpp | 8 +- solid/frame/mprpc/mprpcsocketstub.hpp | 2 + solid/frame/mprpc/mprpcsocketstub_openssl.hpp | 5 + solid/frame/mprpc/mprpcsocketstub_plain.hpp | 13 +- solid/frame/mprpc/src/mprpcconnection.cpp | 187 +++++++++++++----- solid/frame/mprpc/src/mprpcconnection.hpp | 25 ++- solid/frame/mprpc/src/mprpcmessagereader.cpp | 4 +- solid/frame/mprpc/src/mprpcmessagewriter.cpp | 30 +-- solid/frame/mprpc/test/CMakeLists.txt | 1 + .../frame/mprpc/test/test_protocol_common.hpp | 11 +- solid/serialization/v3/binarydeserializer.hpp | 4 +- 16 files changed, 295 insertions(+), 108 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e5cfd43..7aef8a16 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,9 +58,11 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) #----------------------------------------------------------------- set(EXTERNAL_DIR "" CACHE PATH "External dependencies directory") +set(FORTIFY "ON" CACHE BOOL "Fortify C++") message("Install directory: \"${CMAKE_INSTALL_PREFIX}\"") message("External directory: \"${EXTERNAL_DIR}\"") +message("Fortify: \"${FORTIFY}\"") list(APPEND CMAKE_PREFIX_PATH ${EXTERNAL_PATH}) @@ -278,6 +280,37 @@ if(NOT ON_FOUND) message(FATAL_ERROR "\r\n === Unsupported system - please contact project owner ===\r\n") endif(NOT ON_FOUND) + +if(FORTIFY AND (SOLID_ON_LINUX OR SOLID_ON_FREEBSD OR SOLID_ON_DARWIN)) + message("Fortifying C++") + include(CheckCXXSymbolExists) + if(cxx_std_20 IN_LIST CMAKE_CXX_COMPILE_FEATURES) + set(header version) + else() + set(header ciso646) + endif() + + check_cxx_symbol_exists(_LIBCPP_VERSION ${header} LIBCPP) + if(LIBCPP) + # Logic for libc++ + endif() + + check_cxx_symbol_exists(__GLIBCXX__ ${header} GLIBCXX) + if(GLIBCXX) + # Logic for libstdc++ + + add_compile_options( + #-fpie -Wl,-pie + #-fpic -shared + "$<$:SHELL: -D_FORTIFY_SOURCE=2 -D_GLIBCXX_ASSERTIONS -pipe -fasynchronous-unwind-tables -fexceptions -fstack-clash-protection -fcf-protection -Wl,-z,relro>" + "$<$:SHELL: -Wall -O2 -D_FORTIFY_SOURCE=2 -D_GLIBCXX_ASSERTIONS -pipe -fasynchronous-unwind-tables -fexceptions -fstack-clash-protection -fcf-protection -Wl,-z,relro>" + "$<$:SHELL: -Wall -D_FORTIFY_SOURCE=2 -D_GLIBCXX_ASSERTIONS -pipe -fasynchronous-unwind-tables -fexceptions -fstack-clash-protection -fcf-protection -Wl,-z,relro>" + "$<$:>" + ) + + endif() +endif() + #----------------------------------------------------------------- # Find external libraries #----------------------------------------------------------------- diff --git a/JOURNAL.md b/JOURNAL.md index e974b6c1..55cb6f64 100644 --- a/JOURNAL.md +++ b/JOURNAL.md @@ -1,4 +1,9 @@ +## 20241210 + * aio: stream fix not call doTrySend or doTryRecv after disconnect + * mprpc: do not reset timer on onSend with error if connection already stopping + * mprpc: add support for ConnectionContext::stop() for stopping the connection + ## 20241116 * mprpc::Connection fix too many keep alive messages diff --git a/configure b/configure index 058dd844..c3b0c920 100755 --- a/configure +++ b/configure @@ -101,6 +101,7 @@ INSTALL_PREFIX= EXTRA_COMPILE_OPTIONS= EXTRA_LINK_OPTIONS= ARCHITECTURE= +FORTIFY="OFF" #echo "$@" pass_arg_count=0 @@ -175,6 +176,9 @@ do shift TEST_SITE="$1" ;; + --fortify) + FORTIFY="ON" + ;; *) HELP="yes" ;; @@ -256,7 +260,7 @@ for param in "$@"; do done echo -echo -ne "./configure -f $FOLDER_NAME -F \"$FOLDER_PATH\" -b \"$BUILD_TYPE\" -g \"$GENERATOR\" -e \"$EXTERNAL_DIR\" \"$@\" \"$SRC_PATH\"\r\n" > configure.txt +echo -ne "./configure -f $FOLDER_NAME -F \"$FOLDER_PATH\" -b \"$BUILD_TYPE\" -g \"$GENERATOR\" -e \"$EXTERNAL_DIR\" \"$@\" \"$SRC_PATH\" \"$FORTIFY\" \r\n" > configure.txt if [ "$GENERATOR" = "" ]; then echo "Using cmake's default generator" @@ -272,7 +276,7 @@ else echo "Using architecture $ARCHITECTURE - ${ARC[@]}" fi -exec cmake "${GEN[@]}" "${ARC[@]}" -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DEXTERNAL_DIR:PATH="$EXTERNAL_DIR" -DEXTRA_COMPILE_OPTIONS:STRING="$EXTRA_COMPILE_OPTIONS" -DEXTRA_LINK_OPTIONS:STRING="$EXTRA_LINK_OPTIONS" -DCMAKE_INSTALL_PREFIX="$INSTALL_PREFIX" "$@" "$SRC_PATH" +exec cmake "${GEN[@]}" "${ARC[@]}" -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DEXTERNAL_DIR:PATH="$EXTERNAL_DIR" -DEXTRA_COMPILE_OPTIONS:STRING="$EXTRA_COMPILE_OPTIONS" -DEXTRA_LINK_OPTIONS:STRING="$EXTRA_LINK_OPTIONS" -DCMAKE_INSTALL_PREFIX="$INSTALL_PREFIX" -DFORTIFY:BOOL=$FORTIFY "$@" "$SRC_PATH" echo "Done!" diff --git a/solid/frame/aio/aiostream.hpp b/solid/frame/aio/aiostream.hpp index 56a94a74..d33c8651 100644 --- a/solid/frame/aio/aiostream.hpp +++ b/solid/frame/aio/aiostream.hpp @@ -103,7 +103,7 @@ class Stream : public CompletionHandler { void operator()(ThisT& _rthis, ReactorContext& _rctx) { - if (_rthis.doTryRecv(_rctx)) { + if (_rctx.systemError() || _rthis.doTryRecv(_rctx)) { const size_t recv_sz = _rthis.recv_buf_sz; F tmp{std::forward(f)}; _rthis.doClearRecv(_rctx); @@ -123,7 +123,7 @@ class Stream : public CompletionHandler { void operator()(ThisT& _rthis, ReactorContext& _rctx) { - while (_rthis.doTrySend(_rctx)) { + while (_rctx.systemError() || _rthis.doTrySend(_rctx)) { if (_rthis.send_buf_sz == _rthis.send_buf_cp) { F tmp{std::forward(f)}; _rthis.doClearSend(_rctx); @@ -412,6 +412,11 @@ class Stream : public CompletionHandler { return true; } + void cancelRecv(ReactorContext& _rctx) + { + doClearRecv(_rctx); + } + template bool postSendAll(ReactorContext& _rctx, const char* _buf, size_t _bufcp, F&& _f) { diff --git a/solid/frame/mprpc/mprpccontext.hpp b/solid/frame/mprpc/mprpccontext.hpp index 7955681f..d2e54aef 100644 --- a/solid/frame/mprpc/mprpccontext.hpp +++ b/solid/frame/mprpc/mprpccontext.hpp @@ -60,19 +60,29 @@ struct ConnectionProxy { Connection& connection(frame::aio::ReactorContext& _rctx) const; }; -struct ConnectionContext : NonCopyable { +class ConnectionContext : NonCopyable { + frame::aio::ReactorContext& rreactor_context_; + Service& rservice_; + Connection& rconnection_; + MessageHeader* pmessage_header_{nullptr}; + MessageFlagsT message_flags_{0}; + RequestId request_id_; + MessageId message_id_; + MessageRelayHeader* pmessage_relay_header_{nullptr}; // we cannot make it const - serializer constraint +public: ConnectionContext( frame::aio::ReactorContext& _rctx, const ConnectionProxy& _rccs) - : rservice(_rccs.service(_rctx)) - , rconnection(_rccs.connection(_rctx)) - , message_flags(0) + : rreactor_context_(_rctx) + , rservice_(_rccs.service(_rctx)) + , rconnection_(_rccs.connection(_rctx)) + , message_flags_(0) { } Service& service() const { - return rservice; + return rservice_; } Configuration const& configuration() const; @@ -92,12 +102,12 @@ struct ConnectionContext : NonCopyable { const MessageFlagsT& messageFlags() const { - return message_flags; + return message_flags_; } MessageId const& localMessageId() const { - return message_id; + return message_id_; } MessagePointerT<> fetchRequest(Message const& _rmsg) const; @@ -108,11 +118,16 @@ struct ConnectionContext : NonCopyable { const ErrorConditionT& error() const; const ErrorCodeT& systemError() const; + void stop(const ErrorConditionT& _err); + + void pauseRead(); + void resumeRead(); + private: // not used for now RequestId const& requestId() const { - return request_id; + return request_id_; } void relayId(const UniqueId& _relay_id) const; @@ -131,27 +146,26 @@ struct ConnectionContext : NonCopyable { template friend struct ConnectionSenderResponse; - Service& rservice; - Connection& rconnection; - MessageHeader* pmessage_header{nullptr}; - MessageFlagsT message_flags{0}; - RequestId request_id; - MessageId message_id; - MessageRelayHeader* pmessage_relay_header_{nullptr}; // we cannot make it const - serializer constraint - ConnectionContext( - Service& _rsrv, Connection& _rcon) - : rservice(_rsrv) - , rconnection(_rcon) + frame::aio::ReactorContext& _rctx, + Service& _rsvc, + Connection& _rcon) + : rreactor_context_(_rctx) + , rservice_(_rsvc) + , rconnection_(_rcon) { } - ConnectionContext(ConnectionContext const&); - ConnectionContext& operator=(ConnectionContext const&); + ConnectionContext(ConnectionContext const&) = delete; + ConnectionContext& operator=(ConnectionContext const&) = delete; Connection& connection() { - return rconnection; + return rconnection_; + } + auto& reactorContext() + { + return rreactor_context_; } }; diff --git a/solid/frame/mprpc/mprpcmessage.hpp b/solid/frame/mprpc/mprpcmessage.hpp index 69a5da83..ef46b29e 100644 --- a/solid/frame/mprpc/mprpcmessage.hpp +++ b/solid/frame/mprpc/mprpcmessage.hpp @@ -125,13 +125,13 @@ struct MessageHeader { SOLID_REFLECT_V1(_rr, _rthis, _rctx) { if constexpr (std::decay_t::is_const_reflector) { - const MessageFlagsValueT tmp = _rctx.message_flags.toUnderlyingType(); + const MessageFlagsValueT tmp = _rctx.message_flags_.toUnderlyingType(); _rr.add(tmp, _rctx, 1, "flags"); - _rr.add(_rctx.request_id.index, _rctx, 2, "sender_request_index"); - _rr.add(_rctx.request_id.unique, _rctx, 3, "sender_request_unique"); + _rr.add(_rctx.request_id_.index, _rctx, 2, "sender_request_index"); + _rr.add(_rctx.request_id_.unique, _rctx, 3, "sender_request_unique"); _rr.add(_rthis.sender_request_id_.index, _rctx, 4, "recipient_request_index"); _rr.add(_rthis.sender_request_id_.unique, _rctx, 5, "recipient_request_unique"); - if (_rctx.message_flags.has(MessageFlagsE::Relayed)) { + if (_rctx.message_flags_.has(MessageFlagsE::Relayed)) { _rr.add(_rthis.relay_, _rctx, 6, "relay"); } } else { diff --git a/solid/frame/mprpc/mprpcsocketstub.hpp b/solid/frame/mprpc/mprpcsocketstub.hpp index 7cbeee7c..4b3df0b0 100644 --- a/solid/frame/mprpc/mprpcsocketstub.hpp +++ b/solid/frame/mprpc/mprpcsocketstub.hpp @@ -80,6 +80,8 @@ class SocketStub { frame::aio::ReactorContext& _rctx) = 0; + virtual void cancelRecv(frame::aio::ReactorContext& _rctx) = 0; + virtual bool secureAccept( frame::aio::ReactorContext& _rctx, ConnectionContext& _rconctx, OnSecureAcceptF _pf, ErrorConditionT& _rerror); virtual bool secureConnect( diff --git a/solid/frame/mprpc/mprpcsocketstub_openssl.hpp b/solid/frame/mprpc/mprpcsocketstub_openssl.hpp index 02e0961e..d0dcf1e4 100644 --- a/solid/frame/mprpc/mprpcsocketstub_openssl.hpp +++ b/solid/frame/mprpc/mprpcsocketstub_openssl.hpp @@ -233,6 +233,11 @@ class SocketStub final : public mprpc::SocketStub { return sock; } + void cancelRecv(frame::aio::ReactorContext& _rctx) override + { + sock.cancelRecv(_rctx); + } + private: StreamSocketT sock; }; diff --git a/solid/frame/mprpc/mprpcsocketstub_plain.hpp b/solid/frame/mprpc/mprpcsocketstub_plain.hpp index 9c86aa4b..683ff256 100644 --- a/solid/frame/mprpc/mprpcsocketstub_plain.hpp +++ b/solid/frame/mprpc/mprpcsocketstub_plain.hpp @@ -53,8 +53,8 @@ class SocketStub final : public mprpc::SocketStub { frame::aio::ReactorContext& _rctx, OnSendAllRawF _pf, const char* _pbuf, size_t _bufcp, EventBase& _revent) override final { struct Closure { - OnSendAllRawF pf; - EventT event; + const OnSendAllRawF pf; + EventT event; Closure(OnSendAllRawF _pf, EventBase const& _revent) : pf(_pf) @@ -84,8 +84,8 @@ class SocketStub final : public mprpc::SocketStub { frame::aio::ReactorContext& _rctx, OnRecvSomeRawF _pf, char* _pbuf, size_t _bufcp, EventBase& _revent) override final { struct Closure { - OnRecvSomeRawF pf; - EventT event; + const OnRecvSomeRawF pf; + EventT event; Closure(OnRecvSomeRawF _pf, EventBase const& _revent) : pf(_pf) @@ -138,6 +138,11 @@ class SocketStub final : public mprpc::SocketStub { { } + void cancelRecv(frame::aio::ReactorContext& _rctx) override + { + sock.cancelRecv(_rctx); + } + private: using StreamSocketT = frame::aio::Stream; diff --git a/solid/frame/mprpc/src/mprpcconnection.cpp b/solid/frame/mprpc/src/mprpcconnection.cpp index df1747af..ae41df16 100644 --- a/solid/frame/mprpc/src/mprpcconnection.cpp +++ b/solid/frame/mprpc/src/mprpcconnection.cpp @@ -321,7 +321,7 @@ template void Connection::doStart(frame::aio::ReactorContext& _rctx, const bool _is_incoming) { - ConnectionContext conctx(service(_rctx), *this); + ConnectionContext conctx(_rctx, service(_rctx), *this); Configuration const& config = service(_rctx).configuration(); doPrepare(_rctx); @@ -413,7 +413,7 @@ void Connection::doStop(frame::aio::ReactorContext& _rctx, const ErrorConditionT flags_.set(FlagsE::Stopping); - ConnectionContext conctx(service(_rctx), *this); + ConnectionContext conctx(_rctx, service(_rctx), *this); ErrorConditionT tmp_error(error()); ActorIdT actuid(uid(_rctx)); std::chrono::milliseconds wait_duration = std::chrono::milliseconds(0); @@ -488,7 +488,7 @@ void Connection::doContinueStopping( MessageBundle msg_bundle; MessageId pool_msg_id; EventT event(_revent); - ConnectionContext conctx(service(_rctx), *this); + ConnectionContext conctx(_rctx, service(_rctx), *this); const bool can_stop = service(_rctx).connectionStopping(conctx, actuid, wait_duration, pool_msg_id, &msg_bundle, event, tmp_error); solid_log(logger, Info, this << ' ' << this->id() << ' ' << can_stop); @@ -580,7 +580,7 @@ void Connection::doCompleteAllMessages( if (has_any_message) { solid_log(logger, Info, this); // complete msg_writer messages - ConnectionContext conctx(service(_rctx), *this); + ConnectionContext conctx(_rctx, service(_rctx), *this); Configuration const& rconfig = service(_rctx).configuration(); typename Ctx::SenderT sender(*this, _rctx, rconfig.writer, rconfig.protocol(), conctx, error_message_connection); @@ -631,7 +631,7 @@ void Connection::onStopped( { ActorIdT actuid(uid(_rctx)); - ConnectionContext conctx(service(_rctx), *this); + ConnectionContext conctx(_rctx, service(_rctx), *this); service(_rctx).connectionStop(conctx); @@ -645,7 +645,7 @@ void Connection::onStopped( //----------------------------------------------------------------------------- void Connection::doHandleEventGeneric(frame::aio::ReactorContext& _rctx, EventBase& _revent) { - ConnectionContext conctx(service(_rctx), *this); + ConnectionContext conctx(_rctx, service(_rctx), *this); configuration(_rctx).connection_on_event_fnc(conctx, _revent); } //----------------------------------------------------------------------------- @@ -746,7 +746,7 @@ void Connection::doHandleEventCancelConnMessage(frame::aio::ReactorContext& _rct solid_assert_log(pmsgid, logger); if (pmsgid != nullptr) { - ConnectionContext conctx(service(_rctx), *this); + ConnectionContext conctx(_rctx, service(_rctx), *this); Configuration const& rconfig = service(_rctx).configuration(); typename Ctx::SenderT sender(*this, _rctx, rconfig.writer, rconfig.protocol(), conctx, error_message_canceled); msg_writer_.cancel(*pmsgid, sender); @@ -789,7 +789,7 @@ void Connection::doHandleEventEnterActive(frame::aio::ReactorContext& _rctx, Eve solid_log(logger, Info, this); - ConnectionContext conctx(service(_rctx), *this); + ConnectionContext conctx(_rctx, service(_rctx), *this); Configuration const& rconfig = service(_rctx).configuration(); EnterActive* pdata = _revent.cast(); @@ -853,7 +853,7 @@ void Connection::doHandleEventEnterPassive(frame::aio::ReactorContext& _rctx, Ev { Configuration const& config = service(_rctx).configuration(); EnterPassive* pdata = _revent.cast(); - ConnectionContext conctx(service(_rctx), *this); + ConnectionContext conctx(_rctx, service(_rctx), *this); if (!isStopping()) { if (this->isRawState()) { flags_.reset(FlagsE::Raw); @@ -893,7 +893,7 @@ void Connection::doHandleEventStartSecure(frame::aio::ReactorContext& _rctx, Eve { solid_log(logger, Verbose, this << ""); Configuration const& config = service(_rctx).configuration(); - ConnectionContext conctx(service(_rctx), *this); + ConnectionContext conctx(_rctx, service(_rctx), *this); if (!isStopping()) { if ((isServer() && config.server.hasSecureConfiguration()) || ((!isServer()) && config.client.hasSecureConfiguration())) { ErrorConditionT error; @@ -932,7 +932,7 @@ template /*static*/ void Connection::onSecureConnect(frame::aio::ReactorContext& _rctx) { Connection& rthis = static_cast(_rctx.actor()); - ConnectionContext conctx(rthis.service(_rctx), rthis); + ConnectionContext conctx(_rctx, rthis.service(_rctx), rthis); Configuration const& config = rthis.service(_rctx).configuration(); if (_rctx.error()) { @@ -985,7 +985,7 @@ template /*static*/ void Connection::onSecureAccept(frame::aio::ReactorContext& _rctx) { Connection& rthis = static_cast(_rctx.actor()); - ConnectionContext conctx(rthis.service(_rctx), rthis); + ConnectionContext conctx(_rctx, rthis.service(_rctx), rthis); Configuration const& config = rthis.service(_rctx).configuration(); if (_rctx.error()) { @@ -1039,7 +1039,7 @@ template void Connection::doHandleEventSendRaw(frame::aio::ReactorContext& _rctx, EventBase& _revent) { SendRaw* pdata = _revent.cast(); - ConnectionContext conctx(service(_rctx), *this); + ConnectionContext conctx(_rctx, service(_rctx), *this); solid_assert_log(pdata, logger); @@ -1072,7 +1072,7 @@ void Connection::doHandleEventSendRaw(frame::aio::ReactorContext& _rctx, EventBa void Connection::doHandleEventRecvRaw(frame::aio::ReactorContext& _rctx, EventBase& _revent) { RecvRaw* pdata = _revent.cast(); - ConnectionContext conctx(service(_rctx), *this); + ConnectionContext conctx(_rctx, service(_rctx), *this); size_t used_size = 0; solid_assert_log(pdata, logger); @@ -1111,7 +1111,7 @@ void Connection::doHandleEventRecvRaw(frame::aio::ReactorContext& _rctx, EventBa //----------------------------------------------------------------------------- void Connection::doHandleEventPost(frame::aio::ReactorContext& _rctx, EventBase& _revent) { - ConnectionContext conctx(service(_rctx), *this); + ConnectionContext conctx(_rctx, service(_rctx), *this); ConnectionPostCompleteFunctionT* pdata = _revent.cast(); solid_check(pdata != nullptr); (*pdata)(conctx); @@ -1167,7 +1167,7 @@ template if (crt_time >= rthis.timeout_send_soft_) { solid_log(logger, Info, &rthis << " " << rthis.flags_.toString() << " send soft timeout = " << rthis.timeout_send_soft_ << " crt_time = " << crt_time); - ConnectionContext conctx(rthis.service(_rctx), rthis); + ConnectionContext conctx(_rctx, rthis.service(_rctx), rthis); rthis.timeout_send_soft_ = NanoTime::max(); rconfig.connection_on_send_timeout_soft_(conctx); } @@ -1190,7 +1190,7 @@ template Connection& rthis = static_cast(_rctx.actor()); SendRaw* pdata = _revent.cast(); - ConnectionContext conctx(rthis.service(_rctx), rthis); + ConnectionContext conctx(_rctx, rthis.service(_rctx), rthis); solid_assert_log(pdata, logger); @@ -1226,7 +1226,7 @@ template Connection& rthis = static_cast(_rctx.actor()); RecvRaw* pdata = _revent.cast(); - ConnectionContext conctx(rthis.service(_rctx), rthis); + ConnectionContext conctx(_rctx, rthis.service(_rctx), rthis); solid_assert_log(pdata, logger); @@ -1359,7 +1359,7 @@ template /*static*/ void Connection::onRecv(frame::aio::ReactorContext& _rctx, size_t _sz) { Connection& rthis = static_cast(_rctx.actor()); - ConnectionContext conctx(rthis.service(_rctx), rthis); + ConnectionContext conctx(_rctx, rthis.service(_rctx), rthis); const Configuration& rconfig = rthis.service(_rctx).configuration(); unsigned repeatcnt = 4; char* pbuf = nullptr; @@ -1409,7 +1409,7 @@ template 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, pbuf, bufsz, _sz)); if (rconfig.hasConnectionTimeoutRecv()) { rthis.timeout_recv_ = _rctx.nanoTime() + rconfig.connection_timeout_recv; @@ -1417,8 +1417,8 @@ template rthis.doResetTimer(_rctx); } - if (repeatcnt == 0) { - bool rv = rthis.postRecvSome(_rctx, pbuf, bufsz); // fully asynchronous call + if (repeatcnt == 0 && !rthis.flags_.isSet(FlagsE::PauseRecv)) { + const bool rv = rthis.postRecvSome(_rctx, pbuf, bufsz); // fully asynchronous call solid_assert_log(!rv, logger); (void)rv; } @@ -1437,7 +1437,7 @@ void Connection::doSend(frame::aio::ReactorContext& _rctx) } ErrorConditionT error; const Configuration& rconfig = service(_rctx).configuration(); - ConnectionContext conctx(service(_rctx), *this); + ConnectionContext conctx(_rctx, service(_rctx), *this); // we do a pollPoolForUpdates here because we want to be able to // receive a force pool close, even though we are waiting for send. @@ -1571,7 +1571,7 @@ template } rthis.doResetTimer(_rctx); rthis.doSend(_rctx); - } else { + } else if (!rthis.isStopping()) { solid_log(logger, Error, &rthis << ' ' << rthis.id() << " sending [" << _rctx.error().message() << "][" << _rctx.systemError().message() << ']'); rthis.timeout_send_soft_ = rthis.timeout_send_hard_ = NanoTime::max(); @@ -1635,15 +1635,15 @@ void Connection::updateContextOnCompleteMessage( ConnectionContext& _rconctx, MessageBundle& _rmsg_bundle, MessageId const& _rpool_msg_id, const Message& _rmsg) const { - _rconctx.message_flags = _rmsg_bundle.message_flags; - _rconctx.request_id = _rmsg.requestId(); - _rconctx.message_id = _rpool_msg_id; + _rconctx.message_flags_ = _rmsg_bundle.message_flags; + _rconctx.request_id_ = _rmsg.requestId(); + _rconctx.message_id_ = _rpool_msg_id; } template bool Connection::doCompleteMessage(frame::aio::ReactorContext& _rctx, MessagePointerT<>& _rresponse_ptr, const size_t _response_type_id) { - ConnectionContext conctx(service(_rctx), *this); + ConnectionContext conctx(_rctx, service(_rctx), *this); const Configuration& rconfig = service(_rctx).configuration(); const Protocol& rproto = rconfig.protocol(); ErrorConditionT error; @@ -1672,13 +1672,13 @@ void Connection::doCompleteMessage( ErrorConditionT const& _rerror) { - ConnectionContext conctx(service(_rctx), *this); + ConnectionContext conctx(_rctx, service(_rctx), *this); const Configuration& rconfig = service(_rctx).configuration(); const Protocol& rproto = rconfig.protocol(); MessagePointerT<> dummy_recv_msg_ptr; - conctx.message_flags = _rmsg_bundle.message_flags; - conctx.message_id = _rpool_msg_id; + conctx.message_flags_ = _rmsg_bundle.message_flags; + conctx.message_id_ = _rpool_msg_id; if (!solid_function_empty(_rmsg_bundle.complete_fnc)) { solid_log(logger, Info, this); @@ -1766,7 +1766,7 @@ void Connection::doCompleteCancelRequest(frame::aio::ReactorContext& _rctx, cons MessageId msgid(_reqid); MessageBundle msg_bundle; MessageId pool_msg_id; - ConnectionContext conctx(service(_rctx), *this); + ConnectionContext conctx(_rctx, service(_rctx), *this); Configuration const& rconfig = service(_rctx).configuration(); typename Ctx::SenderT sender(*this, _rctx, rconfig.writer, rconfig.protocol(), conctx, error_message_canceled_peer); @@ -1831,6 +1831,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) { + solid_check(!isStopping()); return sock_ptr_->sendAll(_rctx, Connection::onSend, _buf, _bufcp); } //----------------------------------------------------------------------------- @@ -1838,6 +1839,32 @@ void Connection::prepareSocket(frame::aio::ReactorContext& _rctx) { sock_ptr_->prepareSocket(_rctx); } +//----------------------------------------------------------------------------- +template +void Connection::doPauseRead(frame::aio::ReactorContext& _rctx) +{ + if (!flags_.isSet(FlagsE::PauseRecv)) { + flags_.set(FlagsE::PauseRecv); + sock_ptr_->cancelRecv(_rctx); + } +} +//----------------------------------------------------------------------------- +template +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 + + solid_assert_log(!rv, logger); + (void)rv; + } +} +//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // ClientConnection @@ -1963,6 +1990,21 @@ void ClientConnection::doHandleEventResolve( } } //----------------------------------------------------------------------------- +void ClientConnection::stop(frame::aio::ReactorContext& _rctx, const ErrorConditionT& _rerr) +{ + doStop(_rctx, _rerr); +} +//----------------------------------------------------------------------------- +void ClientConnection::pauseRead(frame::aio::ReactorContext& _rctx) +{ + doPauseRead(_rctx); +} +//----------------------------------------------------------------------------- +void ClientConnection::resumeRead(frame::aio::ReactorContext& _rctx) +{ + doResumeRead(_rctx); +} +//----------------------------------------------------------------------------- // ServerConnection //----------------------------------------------------------------------------- struct ServerContext { @@ -2049,7 +2091,21 @@ void ServerConnection::onEvent(frame::aio::ReactorContext& _rctx, EventBase&& _u solid_log(logger, Verbose, this << ' ' << this->id() << " " << _uevent); event_handler.handle(_uevent, *this, _rctx); } - +//----------------------------------------------------------------------------- +void ServerConnection::stop(frame::aio::ReactorContext& _rctx, const ErrorConditionT& _rerr) +{ + doStop(_rctx, _rerr); +} +//----------------------------------------------------------------------------- +void ServerConnection::pauseRead(frame::aio::ReactorContext& _rctx) +{ + doPauseRead(_rctx); +} +//----------------------------------------------------------------------------- +void ServerConnection::resumeRead(frame::aio::ReactorContext& _rctx) +{ + doResumeRead(_rctx); +} //----------------------------------------------------------------------------- // RelayConnection //----------------------------------------------------------------------------- @@ -2274,7 +2330,7 @@ bool RelayConnection::doReceiveRelayStart( ErrorConditionT& _rerror) { Configuration const& config = configuration(_rctx); - ConnectionContext conctx{service(_rctx), *this}; + ConnectionContext conctx{_rctx, service(_rctx), *this}; RelayData relmsg{recvBuffer(), _pbeg, _sz /*, this->uid(_rctx)*/, _is_last}; return config.relayEngine().relayStart(uid(_rctx), relayId(), _rmsghdr, std::move(relmsg), _rrelay_id, _rerror); @@ -2289,7 +2345,7 @@ bool RelayConnection::doReceiveRelayBody( ErrorConditionT& _rerror) { Configuration const& config = configuration(_rctx); - ConnectionContext conctx{service(_rctx), *this}; + ConnectionContext conctx{_rctx, service(_rctx), *this}; RelayData relmsg{recvBuffer(), _pbeg, _sz /*, this->uid(_rctx)*/, _is_last}; return config.relayEngine().relay(relayId(), std::move(relmsg), _rrelay_id, _rerror); @@ -2305,7 +2361,7 @@ bool RelayConnection::doReceiveRelayResponse( ErrorConditionT& _rerror) { Configuration const& config = configuration(_rctx); - ConnectionContext conctx{service(_rctx), *this}; + ConnectionContext conctx{_rctx, service(_rctx), *this}; RelayData relmsg{recvBuffer(), _pbeg, _sz /*, this->uid(_rctx)*/, _is_last}; return config.relayEngine().relayResponse(relayId(), _rmsghdr, std::move(relmsg), _rrelay_id, _rerror); @@ -2357,73 +2413,102 @@ void RelayConnection::doHandleEventRelayDone(frame::aio::ReactorContext& _rctx, } } } - +//----------------------------------------------------------------------------- +void RelayConnection::stop(frame::aio::ReactorContext& _rctx, const ErrorConditionT& _rerr) +{ + doStop(_rctx, _rerr); +} +//----------------------------------------------------------------------------- +void RelayConnection::pauseRead(frame::aio::ReactorContext& _rctx) +{ + doPauseRead(_rctx); +} +//----------------------------------------------------------------------------- +void RelayConnection::resumeRead(frame::aio::ReactorContext& _rctx) +{ + doResumeRead(_rctx); +} //----------------------------------------------------------------------------- // ConnectionContext //----------------------------------------------------------------------------- Any<>& ConnectionContext::any() { - return rconnection.any(); + return rconnection_.any(); } //----------------------------------------------------------------------------- MessagePointerT<> ConnectionContext::fetchRequest(Message const& _rmsg) const { - return rconnection.fetchRequest(_rmsg); + return rconnection_.fetchRequest(_rmsg); } //----------------------------------------------------------------------------- RecipientId ConnectionContext::recipientId() const { - return RecipientId(rconnection.poolId(), rservice.manager().id(rconnection)); + return RecipientId(rconnection_.poolId(), rservice_.manager().id(rconnection_)); } //----------------------------------------------------------------------------- ActorIdT ConnectionContext::connectionId() const { - return rservice.manager().id(rconnection); + return rservice_.manager().id(rconnection_); } //----------------------------------------------------------------------------- const UniqueId& ConnectionContext::relayId() const { - return rconnection.relayId(); + return rconnection_.relayId(); } //----------------------------------------------------------------------------- void ConnectionContext::relayId(const UniqueId& _relay_id) const { - rconnection.relayId(_relay_id); + rconnection_.relayId(_relay_id); } //----------------------------------------------------------------------------- const std::string& ConnectionContext::recipientName() const { - return rconnection.poolName(); + return rconnection_.poolName(); } //----------------------------------------------------------------------------- SocketDevice const& ConnectionContext::device() const { - return rconnection.device(); + return rconnection_.device(); } //----------------------------------------------------------------------------- bool ConnectionContext::isConnectionActive() const { - return rconnection.isActiveState(); + return rconnection_.isActiveState(); } //----------------------------------------------------------------------------- bool ConnectionContext::isConnectionServer() const { - return rconnection.isServer(); + return rconnection_.isServer(); } //----------------------------------------------------------------------------- const ErrorConditionT& ConnectionContext::error() const { - return rconnection.error(); + return rconnection_.error(); } //----------------------------------------------------------------------------- const ErrorCodeT& ConnectionContext::systemError() const { - return rconnection.systemError(); + return rconnection_.systemError(); } //----------------------------------------------------------------------------- Configuration const& ConnectionContext::configuration() const { - return rservice.configuration(); + return rservice_.configuration(); +} +//----------------------------------------------------------------------------- +void ConnectionContext::stop(const ErrorConditionT& _err) +{ + rconnection_.stop(reactorContext(), _err); +} +//----------------------------------------------------------------------------- +void ConnectionContext::pauseRead() +{ + rconnection_.pauseRead(reactorContext()); +} +//----------------------------------------------------------------------------- +void ConnectionContext::resumeRead() +{ + rconnection_.resumeRead(reactorContext()); } //----------------------------------------------------------------------------- // SocketStub @@ -2462,7 +2547,7 @@ Connection& ConnectionProxy::connection(frame::aio::ReactorContext& _rctx) const void Message::header(frame::mprpc::ConnectionContext& _rctx) { - header_ = std::move(*_rctx.pmessage_header); + header_ = std::move(*_rctx.pmessage_header_); } } // namespace mprpc diff --git a/solid/frame/mprpc/src/mprpcconnection.hpp b/solid/frame/mprpc/src/mprpcconnection.hpp index 4a5f3410..adacab0c 100644 --- a/solid/frame/mprpc/src/mprpcconnection.hpp +++ b/solid/frame/mprpc/src/mprpcconnection.hpp @@ -191,6 +191,7 @@ class Connection : public frame::aio::Actor { Raw, InPoolWaitQueue, Connected, // once set - the flag should not be reset. Is used by pool for restarting + PauseRecv, LastFlag, }; @@ -255,6 +256,11 @@ class Connection : public frame::aio::Actor { template bool connect(frame::aio::ReactorContext& _rctx, const SocketAddressInet& _raddr); + template + void doPauseRead(frame::aio::ReactorContext& _rctx); + template + void doResumeRead(frame::aio::ReactorContext& _rctx); + private: bool postSendAll(frame::aio::ReactorContext& _rctx, const char* _pbuf, size_t _bufcp, EventBase& _revent); template @@ -334,8 +340,13 @@ class Connection : public frame::aio::Actor { template void doCompleteCancelRequest(frame::aio::ReactorContext& _rctx, const RequestId& _reqid); + virtual void stop(frame::aio::ReactorContext& _rctx, const ErrorConditionT& _rerr) = 0; + virtual void pauseRead(frame::aio::ReactorContext& _rctx) = 0; + virtual void resumeRead(frame::aio::ReactorContext& _rctx) = 0; + private: - using TimerT = frame::aio::SteadyTimer; + using TimerT + = frame::aio::SteadyTimer; using FlagsT = solid::Flags; using RequestIdVectorT = MessageWriter::RequestIdVectorT; using RecvBufferVectorT = std::vector; @@ -398,6 +409,10 @@ class ClientConnection final : public Connection { void onEvent(frame::aio::ReactorContext& _rctx, EventBase&& _uevent) override; void doHandleEventResolve(frame::aio::ReactorContext& _rctx, EventBase& _revent); + + void stop(frame::aio::ReactorContext& _rctx, const ErrorConditionT& _rerr) override; + void pauseRead(frame::aio::ReactorContext& _rctx) override; + void resumeRead(frame::aio::ReactorContext& _rctx) override; }; //----------------------------------------------------------------------------- @@ -417,6 +432,10 @@ class ServerConnection final : public Connection { private: void onEvent(frame::aio::ReactorContext& _rctx, EventBase&& _uevent) override; + + void stop(frame::aio::ReactorContext& _rctx, const ErrorConditionT& _rerr) override; + void pauseRead(frame::aio::ReactorContext& _rctx) override; + void resumeRead(frame::aio::ReactorContext& _rctx) override; }; //----------------------------------------------------------------------------- @@ -481,6 +500,10 @@ class RelayConnection final : public Connection { void doHandleEventRelayNew(frame::aio::ReactorContext& _rctx, EventBase& _revent); void doHandleEventRelayDone(frame::aio::ReactorContext& _rctx, EventBase& _revent); + + void stop(frame::aio::ReactorContext& _rctx, const ErrorConditionT& _rerr) override; + void pauseRead(frame::aio::ReactorContext& _rctx) override; + void resumeRead(frame::aio::ReactorContext& _rctx) override; }; //----------------------------------------------------------------------------- diff --git a/solid/frame/mprpc/src/mprpcmessagereader.cpp b/solid/frame/mprpc/src/mprpcmessagereader.cpp index 69b2ab7b..eeb45639 100644 --- a/solid/frame/mprpc/src/mprpcmessagereader.cpp +++ b/solid/frame/mprpc/src/mprpcmessagereader.cpp @@ -216,7 +216,7 @@ bool MessageReader::doConsumeMessageHeader( _pbufpos = _receiver.protocol().loadValue(_pbufpos, _message_size); solid_log(logger, Verbose, "msgidx = " << _msgidx << " message_size = " << _message_size); if (_message_size <= static_cast(_pbufend - _pbufpos)) { - _receiver.context().pmessage_header = &rmsgstub.message_header_; + _receiver.context().pmessage_header_ = &rmsgstub.message_header_; const ptrdiff_t rv = rmsgstub.state_ == MessageStub::StateE::ReadHeadStart ? rmsgstub.deserializer_ptr_->run(_receiver.context(), _pbufpos, _message_size, rmsgstub.message_header_) : rmsgstub.deserializer_ptr_->run(_receiver.context(), _pbufpos, _message_size); @@ -290,7 +290,7 @@ bool MessageReader::doConsumeMessageBody( if (_message_size <= static_cast(_pbufend - _pbufpos)) { - _receiver.context().pmessage_header = &rmsgstub.message_header_; + _receiver.context().pmessage_header_ = &rmsgstub.message_header_; const ptrdiff_t rv = rmsgstub.state_ == MessageStub::StateE::ReadBodyStart ? rmsgstub.deserializer_ptr_->run(_receiver.context(), _pbufpos, _message_size, rmsgstub.message_ptr_) : rmsgstub.deserializer_ptr_->run(_receiver.context(), _pbufpos, _message_size); diff --git a/solid/frame/mprpc/src/mprpcmessagewriter.cpp b/solid/frame/mprpc/src/mprpcmessagewriter.cpp index 48d8f6d1..0dd4899c 100644 --- a/solid/frame/mprpc/src/mprpcmessagewriter.cpp +++ b/solid/frame/mprpc/src/mprpcmessagewriter.cpp @@ -672,16 +672,16 @@ char* MessageWriter::doWriteMessageHead( MessageStub& rmsgstub = message_vec_[_msgidx]; rmsgstub.msgbundle_.message_flags = Message::update_state_flags(Message::clear_state_flags(rmsgstub.msgbundle_.message_flags) | Message::state_flags(rmsgstub.msgbundle_.message_ptr->flags())); - _rsender.context().request_id.index = static_cast(_msgidx + 1); - _rsender.context().request_id.unique = rmsgstub.unique_; - _rsender.context().message_flags = rmsgstub.msgbundle_.message_flags; + _rsender.context().request_id_.index = static_cast(_msgidx + 1); + _rsender.context().request_id_.unique = rmsgstub.unique_; + _rsender.context().message_flags_ = rmsgstub.msgbundle_.message_flags; if (rmsgstub.msgbundle_.message_relay_header_.has_value()) { // solid_assert_log(_rsender.context().message_flags.isSet(MessageFlagsE::Relayed), logger, ""<(_msgidx + 1); - _rsender.context().request_id.unique = rmsgstub.unique_; - _rsender.context().message_flags = rmsgstub.msgbundle_.message_flags; + _rsender.context().request_id_.index = static_cast(_msgidx + 1); + _rsender.context().request_id_.unique = rmsgstub.unique_; + _rsender.context().message_flags_ = rmsgstub.msgbundle_.message_flags; if (rmsgstub.msgbundle_.message_relay_header_.has_value()) { - _rsender.context().message_flags.set(MessageFlagsE::Relayed); + _rsender.context().message_flags_.set(MessageFlagsE::Relayed); _rsender.context().pmessage_relay_header_ = &rmsgstub.msgbundle_.message_relay_header_.value(); } else { - _rsender.context().message_flags.reset(MessageFlagsE::Relayed); + _rsender.context().message_flags_.reset(MessageFlagsE::Relayed); _rsender.context().pmessage_relay_header_ = nullptr; } @@ -788,10 +788,10 @@ char* MessageWriter::doWriteRelayedHead( MessageStub& rmsgstub = message_vec_[_msgidx]; - _rsender.context().request_id.index = static_cast(_msgidx + 1); - _rsender.context().request_id.unique = rmsgstub.unique_; - _rsender.context().message_flags = rmsgstub.prelay_data_->pmessage_header_->flags_; - _rsender.context().message_flags.set(MessageFlagsE::Relayed); + _rsender.context().request_id_.index = static_cast(_msgidx + 1); + _rsender.context().request_id_.unique = rmsgstub.unique_; + _rsender.context().message_flags_ = rmsgstub.prelay_data_->pmessage_header_->flags_; + _rsender.context().message_flags_.set(MessageFlagsE::Relayed); _rsender.context().pmessage_relay_header_ = &rmsgstub.prelay_data_->pmessage_header_->relay_; const ptrdiff_t rv = rmsgstub.state_ == MessageStub::StateE::RelayedHeadStart ? rmsgstub.serializer_ptr_->run(_rsender.context(), _pbufpos, _pbufend - _pbufpos, *rmsgstub.prelay_data_->pmessage_header_) : rmsgstub.serializer_ptr_->run(_rsender.context(), _pbufpos, _pbufend - _pbufpos); @@ -982,7 +982,7 @@ void MessageWriter::doTryCompleteMessageAfterSerialization( MessageStub& rmsgstub(message_vec_[_msgidx]); RequestId requid(static_cast(_msgidx), rmsgstub.unique_); - solid_log(logger, Info, this << " done serializing message " << requid << ". Message id sent to client " << _rsender.context().request_id); + solid_log(logger, Info, this << " done serializing message " << requid << ". Message id sent to client " << _rsender.context().request_id_); cache(rmsgstub.serializer_ptr_); diff --git a/solid/frame/mprpc/test/CMakeLists.txt b/solid/frame/mprpc/test/CMakeLists.txt index 9948da86..12ad21cd 100644 --- a/solid/frame/mprpc/test/CMakeLists.txt +++ b/solid/frame/mprpc/test/CMakeLists.txt @@ -70,6 +70,7 @@ if(OPENSSL_FOUND) test_clientserver_download.cpp test_clientserver_timeout_secure.cpp test_clientserver_topic.cpp + test_clientserver_stop.cpp ) if(SOLID_ON_WINDOWS) diff --git a/solid/frame/mprpc/test/test_protocol_common.hpp b/solid/frame/mprpc/test/test_protocol_common.hpp index a1631bdc..36958983 100644 --- a/solid/frame/mprpc/test/test_protocol_common.hpp +++ b/solid/frame/mprpc/test/test_protocol_common.hpp @@ -15,9 +15,10 @@ class TestEntryway { public: static ConnectionContext& createContext() { - Connection& rcon = *createConnection(); - Service& rsvc = *createService(); - static ConnectionContext conctx(rsvc, rcon); + Connection& rcon = *createConnection(); + Service& rsvc = *createService(); + frame::aio::ReactorContext& rctx = *createReactorContex(); + static ConnectionContext conctx(rctx, rsvc, rcon); return conctx; } static Connection* createConnection() @@ -28,6 +29,10 @@ class TestEntryway { { return nullptr; } + static frame::aio::ReactorContext* createReactorContex() + { + return nullptr; + } }; } /*namespace mprpc*/ diff --git a/solid/serialization/v3/binarydeserializer.hpp b/solid/serialization/v3/binarydeserializer.hpp index 6ce837fd..01e7e4ab 100644 --- a/solid/serialization/v3/binarydeserializer.hpp +++ b/solid/serialization/v3/binarydeserializer.hpp @@ -185,7 +185,7 @@ class DeserializerBase : public Base { } template - inline void addBinaryCArray(T (&_ra)[Sz], const uint64_t _limit, const char* _name) + inline void addCBinaryArray(T (&_ra)[Sz], const uint64_t _limit, const char* _name) { solid_log(logger, Info, _name); addBasicCompacted(data_.u64_, _name); @@ -1150,7 +1150,7 @@ class Deserializer : public DeserializerBase { } } else if constexpr (std::is_array_v) { static_assert(std::is_arithmetic_v>, "C style arrays of other than arithmetic type, not supported"); - addBinaryCArray(_rt, _meta.max_size_, _name); + addCBinaryArray(_rt, _meta.max_size_, _name); } else if constexpr (is_container_v) { addContainer(*this, _rt, _meta.max_size_, _rctx, _name); } else { From 646d1f93ddfcef1b022e38bbdb3ae81f34454eae Mon Sep 17 00:00:00 2001 From: Valentin Palade Date: Sat, 14 Dec 2024 20:00:57 +0200 Subject: [PATCH 03/14] mprpc: clientserver pause resume basic test --- solid/frame/mprpc/test/CMakeLists.txt | 1 + .../test/test_clientserver_pause_read.cpp | 482 +++++++++++++++++ .../mprpc/test/test_clientserver_stop.cpp | 499 ++++++++++++++++++ 3 files changed, 982 insertions(+) create mode 100644 solid/frame/mprpc/test/test_clientserver_pause_read.cpp create mode 100644 solid/frame/mprpc/test/test_clientserver_stop.cpp diff --git a/solid/frame/mprpc/test/CMakeLists.txt b/solid/frame/mprpc/test/CMakeLists.txt index 12ad21cd..d8407c3b 100644 --- a/solid/frame/mprpc/test/CMakeLists.txt +++ b/solid/frame/mprpc/test/CMakeLists.txt @@ -71,6 +71,7 @@ if(OPENSSL_FOUND) test_clientserver_timeout_secure.cpp test_clientserver_topic.cpp test_clientserver_stop.cpp + test_clientserver_pause_read.cpp ) if(SOLID_ON_WINDOWS) diff --git a/solid/frame/mprpc/test/test_clientserver_pause_read.cpp b/solid/frame/mprpc/test/test_clientserver_pause_read.cpp new file mode 100644 index 00000000..fc91b1b9 --- /dev/null +++ b/solid/frame/mprpc/test/test_clientserver_pause_read.cpp @@ -0,0 +1,482 @@ +#include +#include +#include +#include + +#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, Function>; + +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); + +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; +frame::mprpc::RecipientId server_connection_id; +bool server_connection_paused = 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 : frame::mprpc::Message { + uint32_t idx; + std::string str; + mutable bool serialized; + + Message(uint32_t _idx) + : idx(_idx) + , serialized(false) + { + solid_dbg(generic_logger, Info, "CREATE ---------------- " << this << " idx = " << idx); + init(); + } + Message() + : serialized(false) + { + 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() + { + 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; + } +}; + +using MessagePointerT = solid::frame::mprpc::MessagePointerT; + +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, + MessagePointerT& _rsent_msg_ptr, MessagePointerT& _rrecv_msg_ptr, + ErrorConditionT const& _rerror) +{ + solid_dbg(generic_logger, Info, _rctx.recipientId() << " " << crtbackidx << " " << crtwriteidx); + + 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 == crtwriteidx) { + lock_guard lock(mtx); + running = false; + cnd.notify_one(); + } + } +} + +void server_complete_message( + frame::mprpc::ConnectionContext& _rctx, + MessagePointerT& _rsent_msg_ptr, MessagePointerT& _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 << " " << crtwriteidx); + + 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!"); + + const auto err = _rctx.service().sendResponse(_rctx, _rrecv_msg_ptr); + + solid_check(!err, "Connection id should not be invalid: " << err.message()); + + ++crtreadidx; + + if (crtreadidx == 2) { + _rctx.pauseRead(); + lock_guard lock(mtx); + server_connection_paused = true; + server_connection_id = _rctx.recipientId(); + cnd.notify_one(); + } + } + if (_rsent_msg_ptr) { + solid_dbg(generic_logger, Info, _rctx.recipientId() << " done sent message " << _rsent_msg_ptr.get()); + } +} + +} // namespace + +int test_clientserver_pause_read(int argc, char* argv[]) +{ + + solid::log_start(std::cerr, {".*:EWXS"}); + // solid::log_start(std::cerr, {"solid::frame::mprpc.*:EWX", "\\*: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); + }); + 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 = 1; // NOTE: currently the test only works with one connection per pool + + 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; + + while (true) { + auto msg_ptr = frame::mprpc::make_message(crtwriteidx); + const auto err = mprpcclient.sendMessage( + {""}, msg_ptr, + initarray[crtwriteidx % initarraysize].flags | frame::mprpc::MessageFlagsE::AwaitResponse); + if (!err) { + ++crtwriteidx; + solid_check(crtwriteidx < 100000); + } else { + msg_ptr->serialized = true; // prevent crash + break; + } + } + + cout << "Sent " << crtwriteidx << " messages" << endl; + + this_thread::sleep_for(chrono::seconds(5)); + + cout << "Current read idx after sleep: " << crtreadidx << endl; + + solid_check(crtwriteidx > crtreadidx); + + unique_lock lock(mtx); + + // make sure server connection was paused + if (!cnd.wait_for(lock, std::chrono::seconds(10), []() { return server_connection_paused; })) { + solid_throw("Server connection still not paused."); + } + + mprpcserver.connectionPost(server_connection_id, [](frame::mprpc::ConnectionContext& _rctx) { + _rctx.resumeRead(); + cout << "Server connection " << _rctx.recipientId() << " resumed." << endl; + }); + + 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: crtwriteidx = " << crtwriteidx << " crtackidx = " << crtackidx); + } + + 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; + + return 0; +} diff --git a/solid/frame/mprpc/test/test_clientserver_stop.cpp b/solid/frame/mprpc/test/test_clientserver_stop.cpp new file mode 100644 index 00000000..71eb69ab --- /dev/null +++ b/solid/frame/mprpc/test/test_clientserver_stop.cpp @@ -0,0 +1,499 @@ +#include +#include +#include +#include + +#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" +#ifndef SOLID_ON_WINDOWS +#include +#endif + +using namespace std; +using namespace solid; + +using AioSchedulerT = frame::Scheduler>; +using SecureContextT = frame::aio::openssl::Context; + +namespace { + +enum struct TestErrorE : int { + Dummy = 1 +}; +class TestErrorCategory : public ErrorCategoryT { +public: + const char* name() const noexcept override + { + return "test"; + } + std::string message(int _ev) const override; +}; + +const TestErrorCategory test_category; + +std::string TestErrorCategory::message(int _ev) const +{ + std::ostringstream oss; + + oss << "(" << name() << ":" << _ev << "): "; + + switch (_ev) { + case 0: + oss << "Success"; + break; + case to_underlying(TestErrorE::Dummy): + oss << " Dummy"; + break; + default: + oss << " Unknown [" << _ev << "]"; + break; + }; + return oss.str(); +} + +const ErrorConditionT error_test_dummy(to_underlying(TestErrorE::Dummy), test_category); + +struct InitStub { + size_t size; + frame::mprpc::MessageFlagsT flags; +}; + +using CallPoolT = ThreadPool, Function>; + +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 : frame::mprpc::Message { + uint32_t idx; + std::string str; + mutable bool serialized; + + Message(uint32_t _idx) + : idx(_idx) + , serialized(false) + { + solid_dbg(generic_logger, Info, "CREATE ---------------- " << this << " idx = " << idx); + init(); + } + Message() + : serialized(false) + { + 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() + { + 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; + } +}; + +using MessagePointerT = solid::frame::mprpc::MessagePointerT; + +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, Error, _rctx.recipientId()); + auto lambda = [](frame::mprpc::ConnectionContext&, ErrorConditionT const& _rerror) { + solid_dbg(generic_logger, Error, "enter active error: " << _rerror.message()); + }; + _rctx.service().connectionNotifyEnterActiveState(_rctx.recipientId(), lambda); +} + +void server_connection_stop(frame::mprpc::ConnectionContext& _rctx) +{ + solid_dbg(generic_logger, Error, _rctx.recipientId() << " error: " << _rctx.error().message()); + static bool b{true}; + if (b) { + solid_check(_rctx.error() == error_test_dummy); + b = false; + } +} + +void server_connection_start(frame::mprpc::ConnectionContext& _rctx) +{ + solid_dbg(generic_logger, Error, _rctx.recipientId()); + auto lambda = [](frame::mprpc::ConnectionContext&, ErrorConditionT const& _rerror) { + solid_dbg(generic_logger, Error, "enter active error: " << _rerror.message()); + }; + _rctx.service().connectionNotifyEnterActiveState(_rctx.recipientId(), lambda); +} + +void client_complete_message( + frame::mprpc::ConnectionContext& _rctx, + MessagePointerT& _rsent_msg_ptr, MessagePointerT& _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) { + solid_check(_rrecv_msg_ptr->check(), "Message check failed."); + + // cout<< _rmsgptr->str.size()<<'\n'; + transfered_size += _rrecv_msg_ptr->str.size(); + ++transfered_count; + + solid_check(_rrecv_msg_ptr->isBackOnSender(), "Message not back on sender!."); + + ++crtbackidx; + + if (crtbackidx == writecount) { + solid_dbg(generic_logger, Error, _rctx.recipientId() << " " << crtbackidx << " " << writecount); + lock_guard lock(mtx); + running = false; + cnd.notify_one(); + } + } +} + +void server_complete_message( + frame::mprpc::ConnectionContext& _rctx, + MessagePointerT& _rsent_msg_ptr, MessagePointerT& _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); + + solid_check(_rrecv_msg_ptr->check(), "Message check failed."); + solid_check(_rrecv_msg_ptr->isOnPeer(), "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, _rrecv_msg_ptr) : _rctx.service().sendResponse(_rctx.recipientId(), _rrecv_msg_ptr); + + // solid_check(!err, "Connection id should not be invalid: " << err.message()); + + ++crtreadidx; + + if ((crtreadidx % 30) == 0) { + _rctx.stop(error_test_dummy); + } + + solid_dbg(generic_logger, Info, crtreadidx << " " << crtwriteidx); + if (crtwriteidx < writecount) { + 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()); + } + } + if (_rsent_msg_ptr) { + solid_dbg(generic_logger, Info, _rctx.recipientId() << " done sent message " << _rsent_msg_ptr.get()); + } +} + +} // namespace + +int test_clientserver_stop(int argc, char* argv[]) +{ + +#ifndef SOLID_ON_WINDOWS + // signal(SIGINT, term_handler); /* Die on SIGTERM */ + signal(SIGPIPE, SIG_IGN); +#endif + solid::log_start(std::cerr, {".*:EWXS"}); + // solid::log_start(std::cerr, {"solid::frame::mprpc::connection.*:EWX", ".*:EWXS", "\\*:EWX"}); + + 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); + }); + 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_message(crtwriteidx++), + initarray[crtwriteidx % initarraysize].flags | frame::mprpc::MessageFlagsE::AwaitResponse | frame::mprpc::MessageFlagsE::Idempotent); + } + + 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; + + return 0; +} From 01160f923b98b55afc16e9969650fe5d8ce688d9 Mon Sep 17 00:00:00 2001 From: Valentin Palade Date: Mon, 16 Dec 2024 15:32:03 +0200 Subject: [PATCH 04/14] mprpc: fixes --- JOURNAL.md | 2 ++ solid/frame/mprpc/test/CMakeLists.txt | 6 +++++- solid/frame/mprpc/test/test_clientfrontback_download.cpp | 5 +++-- solid/frame/mprpc/test/test_clientfrontback_upload.cpp | 5 +++-- solid/frame/mprpc/test/test_clientserver_download.cpp | 5 +++-- solid/frame/mprpc/test/test_clientserver_pause_read.cpp | 2 -- solid/frame/mprpc/test/test_clientserver_upload.cpp | 5 +++-- solid/frame/mprpc/test/test_clientserver_upload_single.cpp | 5 +++-- solid/utility/test/test_threadpool_batch.cpp | 3 ++- 9 files changed, 24 insertions(+), 14 deletions(-) diff --git a/JOURNAL.md b/JOURNAL.md index 55cb6f64..bdf7cc92 100644 --- a/JOURNAL.md +++ b/JOURNAL.md @@ -1,3 +1,5 @@ +## 20241214 + * mprpc: add support for ConnectionContext::pauseRead and Connection::Context::resumeRead ## 20241210 * aio: stream fix not call doTrySend or doTryRecv after disconnect diff --git a/solid/frame/mprpc/test/CMakeLists.txt b/solid/frame/mprpc/test/CMakeLists.txt index d8407c3b..d66edb61 100644 --- a/solid/frame/mprpc/test/CMakeLists.txt +++ b/solid/frame/mprpc/test/CMakeLists.txt @@ -153,6 +153,8 @@ if(OPENSSL_FOUND) add_test(NAME TestClientServerTimeoutSecureS COMMAND test_mprpc_clientserver test_clientserver_timeout_secure 10 s) add_test(NAME TestClientServerTimeoutSecureP COMMAND test_mprpc_clientserver test_clientserver_timeout_secure 10 p) add_test(NAME TestClientServerTimeoutSecureA COMMAND test_mprpc_clientserver test_clientserver_timeout_secure 10 a) + add_test(NAME TestClientServerStop COMMAND test_mprpc_clientserver test_clientserver_stop) + add_test(NAME TestClientServerPauseRead COMMAND test_mprpc_clientserver test_clientserver_pause_read) set_tests_properties( TestClientServerBasic_1 @@ -197,7 +199,9 @@ if(OPENSSL_FOUND) TestClientServerDownload TestClientServerTimeoutSecureS TestClientServerTimeoutSecureP - TestClientServerTimeoutSecureA + TestClientServerTimeoutSecureA + TestClientServerStop + TestClientServerPauseRead PROPERTIES LABELS "mprpc clientserver" ) #============================================================================== diff --git a/solid/frame/mprpc/test/test_clientfrontback_download.cpp b/solid/frame/mprpc/test/test_clientfrontback_download.cpp index 425d9e9f..1bc1bd7b 100644 --- a/solid/frame/mprpc/test/test_clientfrontback_download.cpp +++ b/solid/frame/mprpc/test/test_clientfrontback_download.cpp @@ -334,8 +334,9 @@ int test_clientfrontback_download(int argc, char* argv[]) increment_size = make_number(argv[3]); } - system("rm -rf client_storage"); - system("rm -rf server_storage"); + auto rv = system("rm -rf client_storage"); + rv = system("rm -rf server_storage"); + (void)rv; Directory::create("client_storage"); Directory::create("server_storage"); diff --git a/solid/frame/mprpc/test/test_clientfrontback_upload.cpp b/solid/frame/mprpc/test/test_clientfrontback_upload.cpp index 040da66c..c5ca7c38 100644 --- a/solid/frame/mprpc/test/test_clientfrontback_upload.cpp +++ b/solid/frame/mprpc/test/test_clientfrontback_upload.cpp @@ -326,8 +326,9 @@ int test_clientfrontback_upload(int argc, char* argv[]) increment_size = make_number(argv[3]); } - system("rm -rf client_storage"); - system("rm -rf server_storage"); + auto rv = system("rm -rf client_storage"); + rv = system("rm -rf server_storage"); + (void)rv; Directory::create("client_storage"); Directory::create("server_storage"); diff --git a/solid/frame/mprpc/test/test_clientserver_download.cpp b/solid/frame/mprpc/test/test_clientserver_download.cpp index b9fc7688..90a8dd2e 100644 --- a/solid/frame/mprpc/test/test_clientserver_download.cpp +++ b/solid/frame/mprpc/test/test_clientserver_download.cpp @@ -216,8 +216,9 @@ int test_clientserver_download(int argc, char* argv[]) increment_size = make_number(argv[3]); } - system("rm -rf client_storage"); - system("rm -rf server_storage"); + auto rv = system("rm -rf client_storage"); + rv = system("rm -rf server_storage"); + (void)rv; Directory::create("client_storage"); Directory::create("server_storage"); diff --git a/solid/frame/mprpc/test/test_clientserver_pause_read.cpp b/solid/frame/mprpc/test/test_clientserver_pause_read.cpp index fc91b1b9..fd4eb4b0 100644 --- a/solid/frame/mprpc/test/test_clientserver_pause_read.cpp +++ b/solid/frame/mprpc/test/test_clientserver_pause_read.cpp @@ -421,8 +421,6 @@ int test_clientserver_pause_read(int argc, char* argv[]) pmprpcclient = &mprpcclient; - const size_t start_count = 10; - while (true) { auto msg_ptr = frame::mprpc::make_message(crtwriteidx); const auto err = mprpcclient.sendMessage( diff --git a/solid/frame/mprpc/test/test_clientserver_upload.cpp b/solid/frame/mprpc/test/test_clientserver_upload.cpp index e41f5aa7..d9f2c694 100644 --- a/solid/frame/mprpc/test/test_clientserver_upload.cpp +++ b/solid/frame/mprpc/test/test_clientserver_upload.cpp @@ -206,8 +206,9 @@ int test_clientserver_upload(int argc, char* argv[]) increment_size = make_number(argv[3]); } - system("rm -rf client_storage"); - system("rm -rf server_storage"); + auto rv = system("rm -rf client_storage"); + rv = system("rm -rf server_storage"); + (void)rv; Directory::create("client_storage"); Directory::create("server_storage"); diff --git a/solid/frame/mprpc/test/test_clientserver_upload_single.cpp b/solid/frame/mprpc/test/test_clientserver_upload_single.cpp index ba62ed5a..f7feed29 100644 --- a/solid/frame/mprpc/test/test_clientserver_upload_single.cpp +++ b/solid/frame/mprpc/test/test_clientserver_upload_single.cpp @@ -210,8 +210,9 @@ int test_clientserver_upload_single(int argc, char* argv[]) increment_size = make_number(argv[3]); } - system("rm -rf client_storage"); - system("rm -rf server_storage"); + auto rv = system("rm -rf client_storage"); + rv = system("rm -rf server_storage"); + (void)rv; Directory::create("client_storage"); Directory::create("server_storage"); diff --git a/solid/utility/test/test_threadpool_batch.cpp b/solid/utility/test/test_threadpool_batch.cpp index 976e7fb9..febf1faf 100644 --- a/solid/utility/test/test_threadpool_batch.cpp +++ b/solid/utility/test/test_threadpool_batch.cpp @@ -48,7 +48,7 @@ constexpr size_t thread_count = 10; #ifdef SOLID_ON_LINUX vector isolcpus = {/*3, 4, 5, 6,*/ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; - +#if 0 void set_current_thread_affinity() { if (std::thread::hardware_concurrency() < (thread_count + isolcpus[0])) { @@ -64,6 +64,7 @@ void set_current_thread_affinity() // solid_check(rc == 0); (void)rc; } +#endif #else void set_current_thread_affinity() { From d17771ddb9fcd2d21b668a476a76aa14a92a790f Mon Sep 17 00:00:00 2001 From: Valentin Palade Date: Tue, 17 Dec 2024 22:03:28 +0200 Subject: [PATCH 05/14] fix some warnings --- solid/frame/aio/openssl/src/aiosecuresocket.cpp | 3 ++- solid/frame/aio/test/test_echo_tcp_stress.cpp | 2 ++ solid/frame/mprpc/test/test_clientserver_split.cpp | 3 +++ solid/frame/mprpc/test/test_protocol_basic.cpp | 6 ++++-- solid/frame/mprpc/test/test_protocol_synchronous.cpp | 3 ++- solid/frame/mprpc/test/test_relay_split.cpp | 4 ++++ solid/frame/src/manager.cpp | 3 +-- solid/system/test/test_exception.cpp | 1 + 8 files changed, 19 insertions(+), 6 deletions(-) diff --git a/solid/frame/aio/openssl/src/aiosecuresocket.cpp b/solid/frame/aio/openssl/src/aiosecuresocket.cpp index e05c7faf..cd87f2b2 100644 --- a/solid/frame/aio/openssl/src/aiosecuresocket.cpp +++ b/solid/frame/aio/openssl/src/aiosecuresocket.cpp @@ -446,8 +446,9 @@ Socket::Socket( pssl = SSL_new(_rctx.pctx); ::SSL_set_mode(pssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); if (device()) { - int rv = SSL_set_fd(pssl, device().descriptor()); + const int rv = SSL_set_fd(pssl, device().descriptor()); solid_assert_log(rv != 0, logger); + (void)rv; } } diff --git a/solid/frame/aio/test/test_echo_tcp_stress.cpp b/solid/frame/aio/test/test_echo_tcp_stress.cpp index 4bb35974..bab2dbfc 100644 --- a/solid/frame/aio/test/test_echo_tcp_stress.cpp +++ b/solid/frame/aio/test/test_echo_tcp_stress.cpp @@ -193,6 +193,7 @@ class SecureConnection final : public Connection { { SecureConnection& rthis = static_cast(_rctx.actor()); solid_dbg(generic_logger, Info, &rthis << " " << _preverified); + (void)rthis; return _preverified; } @@ -365,6 +366,7 @@ class SecureConnection final : public Connection { { SecureConnection& rthis = static_cast(_rctx.actor()); solid_dbg(generic_logger, Info, &rthis << " " << _preverified); + (void)rthis; return _preverified; } diff --git a/solid/frame/mprpc/test/test_clientserver_split.cpp b/solid/frame/mprpc/test/test_clientserver_split.cpp index 64e59bc0..bdba9936 100644 --- a/solid/frame/mprpc/test/test_clientserver_split.cpp +++ b/solid/frame/mprpc/test/test_clientserver_split.cpp @@ -228,6 +228,9 @@ void client_complete_message( const auto cnt = _rsent_msg_ptr->response_count; solid_dbg(generic_logger, Info, "response_cout = " << cnt << "/" << _rsent_msg_ptr->splitCount() << " is_rsp = " << is_response << " is_rsp_part = " << is_response_part << " is_rsp_last = " << is_response_last); + (void)is_response; + (void)is_response_part; + (void)is_response_last; transfered_size += _rrecv_msg_ptr->str.size(); ++transfered_count; diff --git a/solid/frame/mprpc/test/test_protocol_basic.cpp b/solid/frame/mprpc/test/test_protocol_basic.cpp index 210c6deb..7cc0070f 100644 --- a/solid/frame/mprpc/test/test_protocol_basic.cpp +++ b/solid/frame/mprpc/test/test_protocol_basic.cpp @@ -173,11 +173,12 @@ void complete_message( msgbundle.message_ptr = frame::mprpc::make_message(crtwriteidx); msgbundle.message_type_id = ctx.mprpcprotocol->typeIndex(msgbundle.message_ptr.get()); - bool rv = ctx.mprpcmsgwriter->enqueue( + const bool rv = ctx.mprpcmsgwriter->enqueue( *ctx.mprpcwriterconfig, msgbundle, pool_msg_id, writer_msg_id); solid_dbg(generic_logger, Info, "enqueue rv = " << rv << " writer_msg_id = " << writer_msg_id); solid_dbg(generic_logger, Info, frame::mprpc::MessageWriterPrintPairT(*ctx.mprpcmsgwriter, frame::mprpc::MessageWriter::PrintInnerListsE)); + (void)rv; ++crtwriteidx; } } @@ -318,10 +319,11 @@ int test_protocol_basic(int argc, char* argv[]) msgbundle.message_ptr = MessagePointerT(frame::mprpc::make_message(crtwriteidx)); msgbundle.message_type_id = ctx.mprpcprotocol->typeIndex(msgbundle.message_ptr.get()); - bool rv = mprpcmsgwriter.enqueue( + const bool rv = mprpcmsgwriter.enqueue( mprpcwriterconfig, msgbundle, pool_msg_id, writer_msg_id); solid_dbg(generic_logger, Info, "enqueue rv = " << rv << " writer_msg_id = " << writer_msg_id); solid_dbg(generic_logger, Info, frame::mprpc::MessageWriterPrintPairT(mprpcmsgwriter, frame::mprpc::MessageWriter::PrintInnerListsE)); + (void)rv; } { diff --git a/solid/frame/mprpc/test/test_protocol_synchronous.cpp b/solid/frame/mprpc/test/test_protocol_synchronous.cpp index 7729e699..5ca9192e 100644 --- a/solid/frame/mprpc/test/test_protocol_synchronous.cpp +++ b/solid/frame/mprpc/test/test_protocol_synchronous.cpp @@ -160,11 +160,12 @@ void complete_message( msgbundle.message_ptr = MessagePointerT(frame::mprpc::make_message(crtwriteidx)); msgbundle.message_type_id = ctx.mprpcprotocol->typeIndex(msgbundle.message_ptr.get()); - bool rv = ctx.mprpcmsgwriter->enqueue( + const bool rv = ctx.mprpcmsgwriter->enqueue( *ctx.mprpcwriterconfig, msgbundle, pool_msg_id, writer_msg_id); solid_dbg(generic_logger, Info, "enqueue rv = " << rv << " writer_msg_id = " << writer_msg_id); solid_dbg(generic_logger, Info, frame::mprpc::MessageWriterPrintPairT(*ctx.mprpcmsgwriter, frame::mprpc::MessageWriter::PrintInnerListsE)); + (void)rv; ++crtwriteidx; } } diff --git a/solid/frame/mprpc/test/test_relay_split.cpp b/solid/frame/mprpc/test/test_relay_split.cpp index 79056234..6c8a367e 100644 --- a/solid/frame/mprpc/test/test_relay_split.cpp +++ b/solid/frame/mprpc/test/test_relay_split.cpp @@ -251,6 +251,10 @@ void peera_complete_message( solid_dbg(generic_logger, Info, _rctx.recipientId() << " received message with id on sender " << _rrecv_msg_ptr->senderRequestId() << " datasz = " << _rrecv_msg_ptr->str.size()); + (void)is_response; + (void)is_response_part; + (void)is_response_last; + transfered_size += _rrecv_msg_ptr->str.size(); ++transfered_count; diff --git a/solid/frame/src/manager.cpp b/solid/frame/src/manager.cpp index df57df94..e859ce91 100644 --- a/solid/frame/src/manager.cpp +++ b/solid/frame/src/manager.cpp @@ -840,8 +840,7 @@ ActorIdT Manager::id(const ActorBase& _ractor) const // std::lock_guard actor_lock{pimpl_->actorMutex(actor_index)}; const ActorStub& ras = rchunk[actor_index % pimpl_->actor_chunk_size_]; - const ActorBase* pactor = ras.pactor_; - solid_assert_log(pactor == &_ractor, frame_logger); + solid_assert_log(ras.pactor_ == &_ractor, frame_logger); retval = ActorIdT(actor_index, ras.unique_); } return retval; diff --git a/solid/system/test/test_exception.cpp b/solid/system/test/test_exception.cpp index 65948cb5..3fc4aa26 100644 --- a/solid/system/test/test_exception.cpp +++ b/solid/system/test/test_exception.cpp @@ -83,6 +83,7 @@ int test_exception(int argc, char* argv[]) } solid_assert_log(is_ok, solid::generic_logger); + (void)is_ok; return 0; } From a3a8d32690dfea009901c0f535168b6e7a1b2f7f Mon Sep 17 00:00:00 2001 From: Valentin Palade Date: Tue, 24 Dec 2024 16:44:19 +0200 Subject: [PATCH 06/14] fix build on intel macos --- cmake/check.config.cmake | 4 ++++ cmake/check/stringstream_view.cpp | 11 +++++++++++ solid/system/log.hpp | 5 ++++- solid/utility/src/utility.cpp | 2 +- 4 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 cmake/check/stringstream_view.cpp diff --git a/cmake/check.config.cmake b/cmake/check.config.cmake index 39f78fe1..3dee8132 100644 --- a/cmake/check.config.cmake +++ b/cmake/check.config.cmake @@ -49,5 +49,9 @@ file (READ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/check/pthread_spinlock.cpp" source CHECK_CXX_SOURCE_COMPILES("${source_code}" SOLID_USE_PTHREAD_SPINLOCK) +file (READ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/check/stringstream_view.cpp" source_code) + +CHECK_CXX_SOURCE_COMPILES("${source_code}" SOLID_USE_STRINGSTREAM_VIEW) + #TODO: #set(SOLID_FRAME_AIO_REACTOR_USE_SPINLOCK TRUE) \ No newline at end of file diff --git a/cmake/check/stringstream_view.cpp b/cmake/check/stringstream_view.cpp new file mode 100644 index 00000000..35835794 --- /dev/null +++ b/cmake/check/stringstream_view.cpp @@ -0,0 +1,11 @@ +#include +#include +using namespace std; + +int main() +{ + ostringstream oss; + oss << "test"; + cout << oss.view() << endl; + return 0; +} \ No newline at end of file diff --git a/solid/system/log.hpp b/solid/system/log.hpp index 72e73d9b..6d563795 100644 --- a/solid/system/log.hpp +++ b/solid/system/log.hpp @@ -95,6 +95,7 @@ class LogLineStream : public OChunkedStream, public LogLineBase { } }; +#ifdef SOLID_USE_STRINGSTREAM_VIEW class LogLineStringStream : public std::ostringstream, public LogLineBase { public: std::ostream& writeTo(std::ostream& _ros) const override @@ -102,11 +103,13 @@ class LogLineStringStream : public std::ostringstream, public LogLineBase { const auto view = this->view(); return _ros.write(view.data(), view.size()); } + size_t size() const override { - return this->std::ostringstream::view().size(); + this->std::ostringstream::view().size(); } }; +#endif } // namespace impl diff --git a/solid/utility/src/utility.cpp b/solid/utility/src/utility.cpp index 1253f051..303edb96 100644 --- a/solid/utility/src/utility.cpp +++ b/solid/utility/src/utility.cpp @@ -201,7 +201,7 @@ std::ostream& ThreadPoolStatistic::print(std::ostream& _ros) const _ros << " push_one_latency_max_us = " << push_one_latency_max_us_.load(std::memory_order_relaxed); _ros << " push_one_latency_min_us = " << push_one_latency_min_us_.load(std::memory_order_relaxed); const auto sum_ones = push_one_count_[0].load(std::memory_order_relaxed) + push_one_count_[1].load(std::memory_order_relaxed); - _ros << " push_one_latency_avg_us = " << sum_ones ? push_one_latency_sum_us_.load(std::memory_order_relaxed) / sum_ones : 0; + _ros << " push_one_latency_avg_us = " << (sum_ones ? push_one_latency_sum_us_.load(std::memory_order_relaxed) / sum_ones : 0); return _ros; } void ThreadPoolStatistic::clear() {} From 8d4ead077cf1297a4ce33b00b86810b278bb6d1b Mon Sep 17 00:00:00 2001 From: Valentin Palade Date: Mon, 30 Dec 2024 15:06:40 +0200 Subject: [PATCH 07/14] mprpc: configuration fixed size recv and send buffers --- solid/frame/mprpc/src/mprpcconfiguration.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/solid/frame/mprpc/src/mprpcconfiguration.cpp b/solid/frame/mprpc/src/mprpcconfiguration.cpp index 348c5488..bff022ef 100644 --- a/solid/frame/mprpc/src/mprpcconfiguration.cpp +++ b/solid/frame/mprpc/src/mprpcconfiguration.cpp @@ -218,8 +218,8 @@ bool RelayEngine::notifyConnection(Manager& _rm, const ActorIdT& _rrelay_uid, co //----------------------------------------------------------------------------- void Configuration::init() { - connection_recv_buffer_start_capacity_kb = static_cast(memory_page_size() / 1024); - connection_send_buffer_start_capacity_kb = static_cast(memory_page_size() / 1024); + 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; From 01f5e947478171b60a6faa53ecdae830b5de2959 Mon Sep 17 00:00:00 2001 From: Valentin Palade Date: Fri, 3 Jan 2025 11:49:21 +0200 Subject: [PATCH 08/14] fix cacheable nrvo --- solid/utility/cacheable.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/solid/utility/cacheable.hpp b/solid/utility/cacheable.hpp index f0c6fabb..aaeb892b 100644 --- a/solid/utility/cacheable.hpp +++ b/solid/utility/cacheable.hpp @@ -215,12 +215,12 @@ class ThreadLocalCache { static auto load_sp() { auto& ls = local_stack_sp(); - if (ls.empty()) { - return std::shared_ptr{}; - } else { + if (!ls.empty()) { auto ret = std::move(ls.top()); ls.pop(); return ret; + } else { + return std::shared_ptr{}; } } @@ -228,12 +228,12 @@ class ThreadLocalCache { static auto load_ip() { auto& ls = local_stack_ip(); - if (ls.empty()) { - return IntrusivePtr{}; - } else { - auto ret(std::move(ls.top())); + if (!ls.empty()) { + auto ret = std::move(ls.top()); ls.pop(); return ret; + } else { + return IntrusivePtr{}; } } }; From c3a6c4f580735d19c646febe592e6451cfece6ba Mon Sep 17 00:00:00 2001 From: Valentin Palade Date: Mon, 6 Jan 2025 15:29:12 +0200 Subject: [PATCH 09/14] using std::variant in example_threadpool --- JOURNAL.md | 3 + .../utility/threadpool/example_threadpool.cpp | 128 ++++++++++++++++-- 2 files changed, 117 insertions(+), 14 deletions(-) diff --git a/JOURNAL.md b/JOURNAL.md index bdf7cc92..f28f3129 100644 --- a/JOURNAL.md +++ b/JOURNAL.md @@ -1,3 +1,6 @@ +## 20250106 + * use std::variant in example_threadpool + ## 20241214 * mprpc: add support for ConnectionContext::pauseRead and Connection::Context::resumeRead diff --git a/examples/utility/threadpool/example_threadpool.cpp b/examples/utility/threadpool/example_threadpool.cpp index d0d5f62c..c550559e 100644 --- a/examples/utility/threadpool/example_threadpool.cpp +++ b/examples/utility/threadpool/example_threadpool.cpp @@ -1,6 +1,6 @@ -// example_ThreadPool.cpp +// example_threadpool.cpp // -// Copyright (c) 2007, 2008, 2018 Valentin Palade (vipalade @ gmail . com) +// Copyright (c) 2007, 2008, 2018, 2025 Valentin Palade (vipalade @ gmail . com) // // This file is part of SolidFrame framework. // @@ -9,26 +9,126 @@ // #include "solid/system/log.hpp" #include "solid/utility/threadpool.hpp" +#include #include -#include - +#include +#include +#include using namespace std; using namespace solid; +namespace { +Logger logger{"test"}; +} // namespace + +struct First { + uint64_t v1_; + + First(uint64_t _v) + : v1_(_v) + { + } +}; + +struct Second { + uint64_t v1_; + uint64_t v2_; + + Second(uint64_t _v) + : v1_(_v) + , v2_(_v) + { + } +}; + +struct Third { + uint64_t v1_; + uint64_t v2_; + uint64_t v3_; + + Third(uint64_t _v) + : v1_(_v) + , v2_(_v) + , v3_(_v) + { + } +}; + +using VariantT = std::variant>; + +using ThreadPoolT = ThreadPool; + +struct Context { + mutex mtx_; +}; + +void handle(First& _rv, Context& _rctx) +{ + lock_guard lock(_rctx.mtx_); + solid_log(logger, Info, "Handle First"); +} + +void handle(Second& _rv, Context& _rctx) +{ + lock_guard lock(_rctx.mtx_); + solid_log(logger, Info, "Handle Second"); +} + +void handle(Third& _rv, Context& _rctx) +{ + lock_guard lock(_rctx.mtx_); + solid_log(logger, Info, "Handle Third"); +} + +void handle(string& _rv, Context& _rctx) +{ + lock_guard lock(_rctx.mtx_); + solid_log(logger, Info, "Handle string " << _rv); +} + +void handle(unique_ptr& _rv, Context& _rctx) +{ + lock_guard lock(_rctx.mtx_); + solid_log(logger, Info, "Handle unique_ptr"); +} + int main(int argc, char* argv[]) { - solid::log_start(std::cerr, {".*:VIEW"}); + solid::log_start(std::cerr, {".*:EW", "test:VIEW"}); + + Context ctx; + + ThreadPoolT tp{ + {4}, + [](size_t, Context&) {}, + [](size_t, Context&) {}, + [](VariantT& _var, Context& _rctx) { + std::visit([&_rctx](auto& _rv) { handle(_rv, _rctx); }, _var); + }, + [](size_t, Context&) { - ThreadPool wp{ - {1, 100, 0}, [](const size_t) {}, [](const size_t) {}, - [](int _v) { - solid_log(generic_logger, Info, "v = " << _v); - std::this_thread::sleep_for(std::chrono::milliseconds(_v * 10)); }, - [](const size_t) {}}; + ref(ctx)}; - for (int i(0); i < 100; ++i) { - wp.pushOne(i); + for (size_t i = 0; i < 100; ++i) { + switch (i % variant_size_v) { + case 0: + tp.pushOne(to_string(i)); + break; + case 1: + tp.pushOne(First(i)); + break; + case 2: + tp.pushOne(Second(i)); + break; + case 3: + tp.pushOne(Third(i)); + break; + case 4: + tp.pushOne(make_unique(i)); + break; + default: + assert(false); + } } - return 0; } From 92a07ab48112b0d789907c63f2c2e8095655944a Mon Sep 17 00:00:00 2001 From: Valentin Palade Date: Mon, 6 Jan 2025 18:08:20 +0200 Subject: [PATCH 10/14] TypeToType -> std::type_identity --- JOURNAL.md | 1 + prerequisites/build | 2 +- solid/frame/mprpc/mprpcprotocol.hpp | 2 +- .../alpha/alphamessages.hpp | 6 +-- .../alpha/client/alphaclient.cpp | 5 +- .../alpha/server/alphaserver.hpp | 5 +- .../multiprotocol_basic/beta/betamessages.hpp | 6 +-- .../beta/client/betaclient.cpp | 4 +- .../beta/server/betaserver.hpp | 5 +- .../gamma/client/gammaclient.cpp | 5 +- .../gamma/gammamessages.hpp | 6 +-- .../gamma/server/gammaserver.hpp | 5 +- .../test/test_clientserver_versioning.cpp | 25 ++++------ .../test/test_clientserver_versioning_v1.hpp | 8 +-- .../test/test_clientserver_versioning_v2.hpp | 8 +-- .../test/test_clientserver_versioning_v3.hpp | 10 ++-- .../test/test_clientserver_versioning_v4.hpp | 12 ++--- solid/frame/mprpc/test/test_relay_split.cpp | 2 +- solid/reflection/v1/enummap.hpp | 2 +- .../v1/test/test_reflection_basic.cpp | 4 +- .../v1/test/test_reflection_ostream.cpp | 4 +- solid/serialization/v3/binarybasic.hpp | 10 ++-- tutorials/mprpc_echo/README.md | 8 +-- tutorials/mprpc_echo/mprpc_echo_client.cpp | 5 +- .../mprpc_echo/mprpc_echo_client_pool.cpp | 5 +- tutorials/mprpc_echo/mprpc_echo_messages.hpp | 2 +- tutorials/mprpc_echo/mprpc_echo_server.cpp | 5 +- tutorials/mprpc_file/README.md | 12 ++--- tutorials/mprpc_file/mprpc_file_client.cpp | 5 +- tutorials/mprpc_file/mprpc_file_messages.hpp | 8 +-- tutorials/mprpc_file/mprpc_file_server.cpp | 5 +- tutorials/mprpc_request/README.md | 8 +-- .../mprpc_request/mprpc_request_client.cpp | 5 +- .../mprpc_request/mprpc_request_messages.hpp | 4 +- .../mprpc_request/mprpc_request_server.cpp | 5 +- tutorials/mprpc_request_ssl/README.md | 50 +++++++++---------- .../mprpc_request_client.cpp | 4 +- .../mprpc_request_messages.hpp | 18 +++---- .../mprpc_request_server.cpp | 4 +- 39 files changed, 137 insertions(+), 153 deletions(-) diff --git a/JOURNAL.md b/JOURNAL.md index f28f3129..2e32b4cd 100644 --- a/JOURNAL.md +++ b/JOURNAL.md @@ -1,5 +1,6 @@ ## 20250106 * use std::variant in example_threadpool + * TypeToType -> std::type_identity ## 20241214 * mprpc: add support for ConnectionContext::pauseRead and Connection::Context::resumeRead diff --git a/prerequisites/build b/prerequisites/build index 55ee48c3..9b666289 100755 --- a/prerequisites/build +++ b/prerequisites/build @@ -24,7 +24,7 @@ printUsage() echo } -OPENSSL_ADDR="https://www.openssl.org/source/openssl-3.1.2.tar.gz" +OPENSSL_ADDR="https://github.com/openssl/openssl/releases/download/openssl-3.4.0/openssl-3.4.0.tar.gz" SYSTEM= BIT64= diff --git a/solid/frame/mprpc/mprpcprotocol.hpp b/solid/frame/mprpc/mprpcprotocol.hpp index ad8b408c..6cec470f 100644 --- a/solid/frame/mprpc/mprpcprotocol.hpp +++ b/solid/frame/mprpc/mprpcprotocol.hpp @@ -21,7 +21,7 @@ namespace solid { namespace frame { namespace mprpc { -struct ConnectionContext; +class ConnectionContext; template struct message_complete_traits; diff --git a/solid/frame/mprpc/test/multiprotocol_basic/alpha/alphamessages.hpp b/solid/frame/mprpc/test/multiprotocol_basic/alpha/alphamessages.hpp index e64ffc41..7d7c3071 100644 --- a/solid/frame/mprpc/test/multiprotocol_basic/alpha/alphamessages.hpp +++ b/solid/frame/mprpc/test/multiprotocol_basic/alpha/alphamessages.hpp @@ -62,9 +62,9 @@ struct ThirdMessage : solid::frame::mprpc::Message { template inline void configure_protocol(Reg _rreg) { - _rreg({0, 1}, "FirstMessage", solid::TypeToType()); - _rreg({0, 2}, "SecondMessage", solid::TypeToType()); - _rreg({0, 3}, "ThirdMessage", solid::TypeToType()); + _rreg({0, 1}, "FirstMessage", std::type_identity()); + _rreg({0, 2}, "SecondMessage", std::type_identity()); + _rreg({0, 3}, "ThirdMessage", std::type_identity()); } } // namespace alpha_protocol 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 08e010da..7c7705f3 100644 --- a/solid/frame/mprpc/test/multiprotocol_basic/alpha/client/alphaclient.cpp +++ b/solid/frame/mprpc/test/multiprotocol_basic/alpha/client/alphaclient.cpp @@ -117,9 +117,8 @@ 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, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; - _rmap.template registerMessage(_id, _name, complete_message); + auto lambda = [&](const TypeIdT _id, const std::string_view _name, type_identity const& _rtype) { + _rmap.template registerMessage(_id, _name, complete_message); }; alpha_protocol::configure_protocol(lambda); }); 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 a63245ca..14adf529 100644 --- a/solid/frame/mprpc/test/multiprotocol_basic/alpha/server/alphaserver.hpp +++ b/solid/frame/mprpc/test/multiprotocol_basic/alpha/server/alphaserver.hpp @@ -15,9 +15,8 @@ void complete_message( template void register_messages(Reg& _rmap) { - auto lambda = [&](const TypeIdT _id, const std::string_view _name, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; - _rmap.template registerMessage(_id, _name, complete_message); + auto lambda = [&](const TypeIdT _id, const std::string_view _name, std::type_identity const& _rtype) { + _rmap.template registerMessage(_id, _name, complete_message); }; alpha_protocol::configure_protocol(lambda); } diff --git a/solid/frame/mprpc/test/multiprotocol_basic/beta/betamessages.hpp b/solid/frame/mprpc/test/multiprotocol_basic/beta/betamessages.hpp index 0ede19bc..65f800b4 100644 --- a/solid/frame/mprpc/test/multiprotocol_basic/beta/betamessages.hpp +++ b/solid/frame/mprpc/test/multiprotocol_basic/beta/betamessages.hpp @@ -75,9 +75,9 @@ struct SecondMessage : solid::frame::mprpc::Message { template inline void configure_protocol(Reg _rreg) { - _rreg({1, 1}, "FirstMessage", solid::TypeToType()); - _rreg({1, 2}, "SecondMessage", solid::TypeToType()); - _rreg({1, 3}, "ThirdMessage", solid::TypeToType()); + _rreg({1, 1}, "FirstMessage", std::type_identity()); + _rreg({1, 2}, "SecondMessage", std::type_identity()); + _rreg({1, 3}, "ThirdMessage", std::type_identity()); } } // namespace beta_protocol 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 2fd7f107..ed226df8 100644 --- a/solid/frame/mprpc/test/multiprotocol_basic/beta/client/betaclient.cpp +++ b/solid/frame/mprpc/test/multiprotocol_basic/beta/client/betaclient.cpp @@ -105,8 +105,8 @@ 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, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; + auto lambda = [&](const TypeIdT _id, const std::string_view _name, type_identity const& _rtype) { + using TypeT = T; if constexpr (std::is_same_v) { _rmap.template registerMessage(_id, _name, complete_message_first); } else if constexpr (std::is_same_v) { 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 d9d543c7..73e28304 100644 --- a/solid/frame/mprpc/test/multiprotocol_basic/beta/server/betaserver.hpp +++ b/solid/frame/mprpc/test/multiprotocol_basic/beta/server/betaserver.hpp @@ -15,9 +15,8 @@ void complete_message( template void register_messages(Reg& _rmap) { - auto lambda = [&](const TypeIdT _id, const std::string_view _name, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; - _rmap.template registerMessage(_id, _name, complete_message); + auto lambda = [&](const TypeIdT _id, const std::string_view _name, std::type_identity const& _rtype) { + _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 bd7b1d7e..19566cae 100644 --- a/solid/frame/mprpc/test/multiprotocol_basic/gamma/client/gammaclient.cpp +++ b/solid/frame/mprpc/test/multiprotocol_basic/gamma/client/gammaclient.cpp @@ -66,9 +66,8 @@ 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, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; - _rmap.template registerMessage(_id, _name, complete_message); + auto lambda = [&](const TypeIdT _id, const std::string_view _name, type_identity const& _rtype) { + _rmap.template registerMessage(_id, _name, complete_message); }; gamma_protocol::configure_protocol(lambda); }); diff --git a/solid/frame/mprpc/test/multiprotocol_basic/gamma/gammamessages.hpp b/solid/frame/mprpc/test/multiprotocol_basic/gamma/gammamessages.hpp index e77bc68a..a4a848df 100644 --- a/solid/frame/mprpc/test/multiprotocol_basic/gamma/gammamessages.hpp +++ b/solid/frame/mprpc/test/multiprotocol_basic/gamma/gammamessages.hpp @@ -61,8 +61,8 @@ struct ThirdMessage : solid::frame::mprpc::Message { template inline void configure_protocol(Reg _rreg) { - _rreg({2, 1}, "FirstMessage", solid::TypeToType()); - _rreg({2, 2}, "SecondMessage", solid::TypeToType()); - _rreg({2, 3}, "ThirdMessage", solid::TypeToType()); + _rreg({2, 1}, "FirstMessage", std::type_identity()); + _rreg({2, 2}, "SecondMessage", std::type_identity()); + _rreg({2, 3}, "ThirdMessage", std::type_identity()); } } // namespace gamma_protocol 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 e537aea3..62c358ad 100644 --- a/solid/frame/mprpc/test/multiprotocol_basic/gamma/server/gammaserver.hpp +++ b/solid/frame/mprpc/test/multiprotocol_basic/gamma/server/gammaserver.hpp @@ -31,9 +31,8 @@ void complete_message( template void register_messages(Reg& _rmap) { - auto lambda = [&](const TypeIdT _id, const std::string_view _name, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; - _rmap.template registerMessage(_id, _name, complete_message); + auto lambda = [&](const TypeIdT _id, const std::string_view _name, std::type_identity const& _rtype) { + _rmap.template registerMessage(_id, _name, complete_message); }; gamma_protocol::configure_protocol(lambda); } diff --git a/solid/frame/mprpc/test/test_clientserver_versioning.cpp b/solid/frame/mprpc/test/test_clientserver_versioning.cpp index 1f1372c9..d4871f5b 100644 --- a/solid/frame/mprpc/test/test_clientserver_versioning.cpp +++ b/solid/frame/mprpc/test/test_clientserver_versioning.cpp @@ -133,9 +133,8 @@ void configure_service(frame::mprpc::ServiceT& _rsvc, AioSchedulerT& _rsch, fram 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, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; - _rmap.template registerMessage(_id, _name, complete_message); + auto lambda = [&](const uint8_t _id, const std::string_view _name, const type_identity& _rtype) { + _rmap.template registerMessage(_id, _name, complete_message); }; configure_protocol(lambda); }); @@ -204,9 +203,8 @@ void configure_service(frame::mprpc::ServiceT& _rsvc, AioSchedulerT& _rsch, fram 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, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; - _rmap.template registerMessage(_id, _name, complete_message); + auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const& _rtype) { + _rmap.template registerMessage(_id, _name, complete_message); }; configure_protocol(lambda); }); @@ -279,9 +277,8 @@ void configure_service(frame::mprpc::ServiceT& _rsvc, AioSchedulerT& _rsch, fram 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, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; - _rmap.template registerMessage(_id, _name, complete_message); + auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const& _rtype) { + _rmap.template registerMessage(_id, _name, complete_message); }; configure_protocol(lambda); }); @@ -353,9 +350,8 @@ void configure_service(frame::mprpc::ServiceT& _rsvc, AioSchedulerT& _rsch, fram 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, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; - _rmap.template registerMessage(_id, _name, complete_message); + auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const& _rtype) { + _rmap.template registerMessage(_id, _name, complete_message); }; configure_protocol(lambda); }); @@ -493,9 +489,8 @@ 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, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; - _rmap.template registerMessage(_id, _name, complete_message); + auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const& _rtype) { + _rmap.template registerMessage(_id, _name, complete_message); }; configure_protocol(lambda); }); diff --git a/solid/frame/mprpc/test/test_clientserver_versioning_v1.hpp b/solid/frame/mprpc/test/test_clientserver_versioning_v1.hpp index 9a866b03..6f0c17ef 100644 --- a/solid/frame/mprpc/test/test_clientserver_versioning_v1.hpp +++ b/solid/frame/mprpc/test/test_clientserver_versioning_v1.hpp @@ -108,10 +108,10 @@ struct Response : solid::frame::mprpc::Message { template inline void configure_protocol(Reg _rreg) { - _rreg(1, "InitRequest", solid::TypeToType()); - _rreg(2, "InitResponse", solid::TypeToType()); - _rreg(4, "Request", solid::TypeToType()); - _rreg(5, "Response", solid::TypeToType()); + _rreg(1, "InitRequest", std::type_identity{}); + _rreg(2, "InitResponse", std::type_identity{}); + _rreg(4, "Request", std::type_identity{}); + _rreg(5, "Response", std::type_identity{}); } } // namespace v1 diff --git a/solid/frame/mprpc/test/test_clientserver_versioning_v2.hpp b/solid/frame/mprpc/test/test_clientserver_versioning_v2.hpp index 60ee827b..6f54f637 100644 --- a/solid/frame/mprpc/test/test_clientserver_versioning_v2.hpp +++ b/solid/frame/mprpc/test/test_clientserver_versioning_v2.hpp @@ -116,10 +116,10 @@ struct Response : solid::frame::mprpc::Message { template inline void configure_protocol(Reg _rreg) { - _rreg(1, "InitRequest", solid::TypeToType()); - _rreg(2, "InitResponse", solid::TypeToType()); - _rreg(4, "Request", solid::TypeToType()); - _rreg(5, "Response", solid::TypeToType()); + _rreg(1, "InitRequest", std::type_identity()); + _rreg(2, "InitResponse", std::type_identity()); + _rreg(4, "Request", std::type_identity()); + _rreg(5, "Response", std::type_identity()); } } // namespace v2 diff --git a/solid/frame/mprpc/test/test_clientserver_versioning_v3.hpp b/solid/frame/mprpc/test/test_clientserver_versioning_v3.hpp index c4c51143..72f626e6 100644 --- a/solid/frame/mprpc/test/test_clientserver_versioning_v3.hpp +++ b/solid/frame/mprpc/test/test_clientserver_versioning_v3.hpp @@ -139,11 +139,11 @@ struct Response2 : solid::frame::mprpc::Message { template inline void configure_protocol(Reg _rreg) { - _rreg(1, "InitRequest", solid::TypeToType()); - _rreg(2, "InitResponse", solid::TypeToType()); - _rreg(4, "Request", solid::TypeToType()); - _rreg(5, "Response", solid::TypeToType()); - _rreg(6, "Response2", solid::TypeToType()); + _rreg(1, "InitRequest", std::type_identity()); + _rreg(2, "InitResponse", std::type_identity()); + _rreg(4, "Request", std::type_identity()); + _rreg(5, "Response", std::type_identity()); + _rreg(6, "Response2", std::type_identity()); } } // namespace v3 diff --git a/solid/frame/mprpc/test/test_clientserver_versioning_v4.hpp b/solid/frame/mprpc/test/test_clientserver_versioning_v4.hpp index fc42f46e..7109084b 100644 --- a/solid/frame/mprpc/test/test_clientserver_versioning_v4.hpp +++ b/solid/frame/mprpc/test/test_clientserver_versioning_v4.hpp @@ -120,12 +120,12 @@ struct Response2 : solid::frame::mprpc::Message { template inline void configure_protocol(Reg _rreg) { - _rreg(1, "InitRequest", solid::TypeToType()); - _rreg(2, "InitResponse", solid::TypeToType()); - //_rreg(4, "Request", solid::TypeToType()); - //_rreg(5, "Response", solid::TypeToType()); - _rreg(6, "Response2", solid::TypeToType()); - _rreg(7, "Request2", solid::TypeToType()); + _rreg(1, "InitRequest", std::type_identity()); + _rreg(2, "InitResponse", std::type_identity()); + //_rreg(4, "Request", std::type_identity()); + //_rreg(5, "Response", std::type_identity()); + _rreg(6, "Response2", std::type_identity()); + _rreg(7, "Request2", std::type_identity()); } } // namespace v4 diff --git a/solid/frame/mprpc/test/test_relay_split.cpp b/solid/frame/mprpc/test/test_relay_split.cpp index 6c8a367e..d159c37c 100644 --- a/solid/frame/mprpc/test/test_relay_split.cpp +++ b/solid/frame/mprpc/test/test_relay_split.cpp @@ -254,7 +254,7 @@ void peera_complete_message( (void)is_response; (void)is_response_part; (void)is_response_last; - + transfered_size += _rrecv_msg_ptr->str.size(); ++transfered_count; diff --git a/solid/reflection/v1/enummap.hpp b/solid/reflection/v1/enummap.hpp index 74300e7a..258a7119 100644 --- a/solid/reflection/v1/enummap.hpp +++ b/solid/reflection/v1/enummap.hpp @@ -33,7 +33,7 @@ class EnumMap : NonCopyable { using InitListT = std::initializer_list>; template - EnumMap(TypeToType _t, InitListT _init_list) + EnumMap(std::type_identity _t, InitListT _init_list) { static_assert(std::is_enum_v, "T must be an enum"); diff --git a/solid/reflection/v1/test/test_reflection_basic.cpp b/solid/reflection/v1/test/test_reflection_basic.cpp index 60be85a3..73006fc6 100644 --- a/solid/reflection/v1/test/test_reflection_basic.cpp +++ b/solid/reflection/v1/test/test_reflection_basic.cpp @@ -35,9 +35,9 @@ enum UserStatus { }; // const EnumMap figure_enum_map = {{Zero, "zero"}, {One, "one"}}; -const reflection::EnumMap figure_enum_map{TypeToType(), {{Zero, "Zero"}, {One, "One"}, {Two, "Two"}, {Three, "Three"}, {Four, "Four"}, {Five, "Five"}, {Six, "Six"}, {Seven, "Seven"}, {Eight, "Eight"}, {Nine, "Nine"}}}; +const reflection::EnumMap figure_enum_map{std::type_identity(), {{Zero, "Zero"}, {One, "One"}, {Two, "Two"}, {Three, "Three"}, {Four, "Four"}, {Five, "Five"}, {Six, "Six"}, {Seven, "Seven"}, {Eight, "Eight"}, {Nine, "Nine"}}}; -const reflection::EnumMap user_status_map = {TypeToType(), {{StatusMarriedE, "Married"}, {StatusSingleE, "Single"}, {StatusRelationE, "Relation"}}}; +const reflection::EnumMap user_status_map = {std::type_identity(), {{StatusMarriedE, "Married"}, {StatusSingleE, "Single"}, {StatusRelationE, "Relation"}}}; struct Fruit { virtual ~Fruit() {} diff --git a/solid/reflection/v1/test/test_reflection_ostream.cpp b/solid/reflection/v1/test/test_reflection_ostream.cpp index 40f8dfb4..18d895b8 100644 --- a/solid/reflection/v1/test/test_reflection_ostream.cpp +++ b/solid/reflection/v1/test/test_reflection_ostream.cpp @@ -36,9 +36,9 @@ enum UserStatus { }; // const EnumMap figure_enum_map = {{Zero, "zero"}, {One, "one"}}; -const reflection::EnumMap figure_enum_map{TypeToType(), {{Zero, "Zero"}, {One, "One"}, {Two, "Two"}, {Three, "Three"}, {Four, "Four"}, {Five, "Five"}, {Six, "Six"}, {Seven, "Seven"}, {Eight, "Eight"}, {Nine, "Nine"}}}; +const reflection::EnumMap figure_enum_map{std::type_identity(), {{Zero, "Zero"}, {One, "One"}, {Two, "Two"}, {Three, "Three"}, {Four, "Four"}, {Five, "Five"}, {Six, "Six"}, {Seven, "Seven"}, {Eight, "Eight"}, {Nine, "Nine"}}}; -const reflection::EnumMap user_status_map = {TypeToType(), {{StatusMarriedE, "Married"}, {StatusSingleE, "Single"}, {StatusRelationE, "Relation"}}}; +const reflection::EnumMap user_status_map = {std::type_identity(), {{StatusMarriedE, "Married"}, {StatusSingleE, "Single"}, {StatusRelationE, "Relation"}}}; struct Fruit { virtual ~Fruit() {} diff --git a/solid/serialization/v3/binarybasic.hpp b/solid/serialization/v3/binarybasic.hpp index 6d228e69..369efa59 100644 --- a/solid/serialization/v3/binarybasic.hpp +++ b/solid/serialization/v3/binarybasic.hpp @@ -22,7 +22,7 @@ namespace v3 { namespace binary { namespace impl { -inline char* store(char* _pd, const uint8_t _val, TypeToType _ff) +inline char* store(char* _pd, const uint8_t _val, std::type_identity _ff) { uint8_t* pd = reinterpret_cast(_pd); *pd = _val; @@ -34,7 +34,7 @@ union Convert16 { uint8_t bytes_[sizeof(uint16_t)]; }; -inline char* store(char* _pd, const uint16_t _val, TypeToType _ff) +inline char* store(char* _pd, const uint16_t _val, std::type_identity _ff) { uint8_t* pd = reinterpret_cast(_pd); Convert16 c; @@ -54,7 +54,7 @@ union Convert32 { uint8_t bytes_[sizeof(uint32_t)]; }; -inline char* store(char* _pd, const uint32_t _val, TypeToType _ff) +inline char* store(char* _pd, const uint32_t _val, std::type_identity _ff) { uint8_t* pd = reinterpret_cast(_pd); Convert32 c; @@ -78,7 +78,7 @@ union Convert64 { uint8_t bytes_[sizeof(uint64_t)]; }; -inline char* store(char* _pd, const uint64_t _val, TypeToType _ff) +inline char* store(char* _pd, const uint64_t _val, std::type_identity _ff) { uint8_t* pd = reinterpret_cast(_pd); Convert64 c; @@ -121,7 +121,7 @@ union BytesConvertor { template inline char* store(char* _pd, const T _v) { - return impl::store(_pd, _v, TypeToType()); + return impl::store(_pd, _v, std::type_identity()); } inline const char* load(const char* _ps, uint8_t& _val) diff --git a/tutorials/mprpc_echo/README.md b/tutorials/mprpc_echo/README.md index 09a601e8..94f7941a 100644 --- a/tutorials/mprpc_echo/README.md +++ b/tutorials/mprpc_echo/README.md @@ -67,7 +67,7 @@ inline void protocol_setup(R _r, ProtocolT& _rproto) { _rproto.null(static_cast(0)); - _r(_rproto, solid::TypeToType(), 1); + _r(_rproto, std::type_identity(), 1); } }//namespace ipc_echo @@ -96,7 +96,7 @@ inline void protocol_setup(Stub _s, ProtocolT& _rproto) { _rproto.null(static_cast(0)); - _s(_rproto, solid::TypeToType(), 1); + _s(_rproto, std::type_identity(), 1); } ``` @@ -194,7 +194,7 @@ void complete_message( } struct MessageSetup { - void operator()(ipc_echo::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_echo::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_echo::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_echo::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerMessage(complete_message, _rtid); } @@ -342,7 +342,7 @@ void complete_message( } struct MessageSetup { - void operator()(ipc_echo::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_echo::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_echo::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_echo::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerMessage(complete_message, _rtid); } diff --git a/tutorials/mprpc_echo/mprpc_echo_client.cpp b/tutorials/mprpc_echo/mprpc_echo_client.cpp index bcf66fda..e87a274a 100644 --- a/tutorials/mprpc_echo/mprpc_echo_client.cpp +++ b/tutorials/mprpc_echo/mprpc_echo_client.cpp @@ -83,9 +83,8 @@ int main(int argc, char* argv[]) 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, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; - _rmap.template registerMessage(_id, _name, rpc_echo_client::complete_message); + auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const& _rtype) { + _rmap.template registerMessage(_id, _name, rpc_echo_client::complete_message); }; rpc_echo::configure_protocol(lambda); }); diff --git a/tutorials/mprpc_echo/mprpc_echo_client_pool.cpp b/tutorials/mprpc_echo/mprpc_echo_client_pool.cpp index 15bca936..df50ec71 100644 --- a/tutorials/mprpc_echo/mprpc_echo_client_pool.cpp +++ b/tutorials/mprpc_echo/mprpc_echo_client_pool.cpp @@ -87,9 +87,8 @@ int main(int argc, char* argv[]) 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, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; - _rmap.template registerMessage(_id, _name, rpc_echo_client::complete_message); + auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const& _rtype) { + _rmap.template registerMessage(_id, _name, rpc_echo_client::complete_message); }; rpc_echo::configure_protocol(lambda); }); diff --git a/tutorials/mprpc_echo/mprpc_echo_messages.hpp b/tutorials/mprpc_echo/mprpc_echo_messages.hpp index 7ca669a2..be8b83d5 100644 --- a/tutorials/mprpc_echo/mprpc_echo_messages.hpp +++ b/tutorials/mprpc_echo/mprpc_echo_messages.hpp @@ -26,7 +26,7 @@ struct Message : solid::frame::mprpc::Message { template inline void configure_protocol(Reg _rreg) { - _rreg(1, "Message", solid::TypeToType()); + _rreg(1, "Message", std::type_identity()); } } // namespace rpc_echo diff --git a/tutorials/mprpc_echo/mprpc_echo_server.cpp b/tutorials/mprpc_echo/mprpc_echo_server.cpp index 53f43b0e..dd776a37 100644 --- a/tutorials/mprpc_echo/mprpc_echo_server.cpp +++ b/tutorials/mprpc_echo/mprpc_echo_server.cpp @@ -83,9 +83,8 @@ int main(int argc, char* argv[]) 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, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; - _rmap.template registerMessage(_id, _name, rpc_echo_server::complete_message); + auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const& _rtype) { + _rmap.template registerMessage(_id, _name, rpc_echo_server::complete_message); }; rpc_echo::configure_protocol(lambda); }); diff --git a/tutorials/mprpc_file/README.md b/tutorials/mprpc_file/README.md index 0b6fe2c8..568a516f 100644 --- a/tutorials/mprpc_file/README.md +++ b/tutorials/mprpc_file/README.md @@ -243,10 +243,10 @@ inline void protocol_setup(R _r, ProtocolT& _rproto) { _rproto.null(static_cast(0)); - _r(_rproto, solid::TypeToType(), 1); - _r(_rproto, solid::TypeToType(), 2); - _r(_rproto, solid::TypeToType(), 3); - _r(_rproto, solid::TypeToType(), 4); + _r(_rproto, std::type_identity(), 1); + _r(_rproto, std::type_identity(), 2); + _r(_rproto, std::type_identity(), 3); + _r(_rproto, std::type_identity(), 4); } ``` @@ -313,7 +313,7 @@ void complete_message( struct MessageSetup { template - void operator()(ipc_file::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_file::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_file::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_file::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerMessage(complete_message, _rtid); } @@ -585,7 +585,7 @@ void complete_message( struct MessageSetup { template - void operator()(ipc_file::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_file::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_file::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_file::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerMessage(complete_message, _rtid); } diff --git a/tutorials/mprpc_file/mprpc_file_client.cpp b/tutorials/mprpc_file/mprpc_file_client.cpp index 4c201080..b5d7d7fe 100644 --- a/tutorials/mprpc_file/mprpc_file_client.cpp +++ b/tutorials/mprpc_file/mprpc_file_client.cpp @@ -90,9 +90,8 @@ int main(int argc, char* argv[]) 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, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; - _rmap.template registerMessage(_id, _name, rpc_file_client::complete_message); + auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const& _rtype) { + _rmap.template registerMessage(_id, _name, rpc_file_client::complete_message); }; rpc_file::configure_protocol(lambda); }); diff --git a/tutorials/mprpc_file/mprpc_file_messages.hpp b/tutorials/mprpc_file/mprpc_file_messages.hpp index c15d9184..fdd77689 100644 --- a/tutorials/mprpc_file/mprpc_file_messages.hpp +++ b/tutorials/mprpc_file/mprpc_file_messages.hpp @@ -135,10 +135,10 @@ struct FileResponse : solid::frame::mprpc::Message { template inline void configure_protocol(Reg _rreg) { - _rreg(1, "ListRequest", solid::TypeToType()); - _rreg(2, "ListResponse", solid::TypeToType()); - _rreg(3, "FileRequest", solid::TypeToType()); - _rreg(4, "FileResponse", solid::TypeToType()); + _rreg(1, "ListRequest", std::type_identity()); + _rreg(2, "ListResponse", std::type_identity()); + _rreg(3, "FileRequest", std::type_identity()); + _rreg(4, "FileResponse", std::type_identity()); } } // namespace rpc_file diff --git a/tutorials/mprpc_file/mprpc_file_server.cpp b/tutorials/mprpc_file/mprpc_file_server.cpp index 6326e627..cd63f23e 100644 --- a/tutorials/mprpc_file/mprpc_file_server.cpp +++ b/tutorials/mprpc_file/mprpc_file_server.cpp @@ -157,9 +157,8 @@ int main(int argc, char* argv[]) 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, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; - _rmap.template registerMessage(_id, _name, rpc_file_server::complete_message); + auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const& _rtype) { + _rmap.template registerMessage(_id, _name, rpc_file_server::complete_message); }; rpc_file::configure_protocol(lambda); }); diff --git a/tutorials/mprpc_request/README.md b/tutorials/mprpc_request/README.md index c928ba8c..0301799e 100644 --- a/tutorials/mprpc_request/README.md +++ b/tutorials/mprpc_request/README.md @@ -128,8 +128,8 @@ inline void protocol_setup(R _r, ProtocolT& _rproto) { _rproto.null(ProtocolT::TypeIdT(0)); - _r(_rproto, solid::TypeToType(), 1); - _r(_rproto, solid::TypeToType(), 2); + _r(_rproto, std::type_identity(), 1); + _r(_rproto, std::type_identity(), 2); } }//namespace ipc_request @@ -206,7 +206,7 @@ void complete_message( struct MessageSetup { template - void operator()(ipc_request::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_request::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerMessage(complete_message, _rtid); } @@ -373,7 +373,7 @@ void complete_message( struct MessageSetup { template - void operator()(ipc_request::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_request::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerMessage(complete_message, _rtid); } diff --git a/tutorials/mprpc_request/mprpc_request_client.cpp b/tutorials/mprpc_request/mprpc_request_client.cpp index 3767e842..40dfc6a2 100644 --- a/tutorials/mprpc_request/mprpc_request_client.cpp +++ b/tutorials/mprpc_request/mprpc_request_client.cpp @@ -88,9 +88,8 @@ int main(int argc, char* argv[]) 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, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; - _rmap.template registerMessage(_id, _name, rpc_request_client::complete_message); + auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const& _rtype) { + _rmap.template registerMessage(_id, _name, rpc_request_client::complete_message); }; rpc_request::configure_protocol(lambda); }); diff --git a/tutorials/mprpc_request/mprpc_request_messages.hpp b/tutorials/mprpc_request/mprpc_request_messages.hpp index 285678a0..b8a37be5 100644 --- a/tutorials/mprpc_request/mprpc_request_messages.hpp +++ b/tutorials/mprpc_request/mprpc_request_messages.hpp @@ -71,8 +71,8 @@ struct Response : solid::frame::mprpc::Message { template inline void configure_protocol(Reg _rreg) { - _rreg(1, "Request", solid::TypeToType()); - _rreg(2, "Response", solid::TypeToType()); + _rreg(1, "Request", std::type_identity()); + _rreg(2, "Response", std::type_identity()); } } // namespace rpc_request diff --git a/tutorials/mprpc_request/mprpc_request_server.cpp b/tutorials/mprpc_request/mprpc_request_server.cpp index 5f0af569..99684fad 100644 --- a/tutorials/mprpc_request/mprpc_request_server.cpp +++ b/tutorials/mprpc_request/mprpc_request_server.cpp @@ -158,9 +158,8 @@ int main(int argc, char* argv[]) 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, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; - _rmap.template registerMessage(_id, _name, rpc_request_server::complete_message); + auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const& _rtype) { + _rmap.template registerMessage(_id, _name, rpc_request_server::complete_message); }; rpc_request::configure_protocol(lambda); }); diff --git a/tutorials/mprpc_request_ssl/README.md b/tutorials/mprpc_request_ssl/README.md index 1b2063f8..0d4c1a63 100644 --- a/tutorials/mprpc_request_ssl/README.md +++ b/tutorials/mprpc_request_ssl/README.md @@ -291,15 +291,15 @@ inline void protocol_setup(R _r, ProtocolT& _rproto) { _rproto.null(ProtocolT::TypeIdT(0)); - _r(_rproto, solid::TypeToType(), 1); - _r(_rproto, solid::TypeToType(), 2); - _r(_rproto, solid::TypeToType(), 3); - _r(_rproto, solid::TypeToType(), 4); - _r(_rproto, solid::TypeToType(), 5); - _r(_rproto, solid::TypeToType(), 6); - _r(_rproto, solid::TypeToType(), 7); - _r(_rproto, solid::TypeToType(), 8); - _r(_rproto, solid::TypeToType(), 9); + _r(_rproto, std::type_identity(), 1); + _r(_rproto, std::type_identity(), 2); + _r(_rproto, std::type_identity(), 3); + _r(_rproto, std::type_identity(), 4); + _r(_rproto, std::type_identity(), 5); + _r(_rproto, std::type_identity(), 6); + _r(_rproto, std::type_identity(), 7); + _r(_rproto, std::type_identity(), 8); + _r(_rproto, std::type_identity(), 9); } ``` @@ -324,43 +324,43 @@ void complete_message( struct MessageSetup { - void operator()(ipc_request::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_request::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerType(_rtid); } - void operator()(ipc_request::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_request::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerType(_rtid); } - void operator()(ipc_request::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_request::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerType(_rtid); } - void operator()(ipc_request::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_request::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerType(_rtid); } - void operator()(ipc_request::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_request::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerType(_rtid); } - void operator()(ipc_request::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_request::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerType(_rtid); } - void operator()(ipc_request::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_request::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerType(_rtid); } template - void operator()(ipc_request::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_request::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerMessage(complete_message, _rtid); } @@ -457,50 +457,50 @@ but now, ipc_request_server::MessageSetup is a little more complex: ```C++ struct MessageSetup { - void operator()(ipc_request::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_request::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerType(_rtid); _rprotocol.registerCast(); } - void operator()(ipc_request::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_request::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerType(_rtid); _rprotocol.registerCast(); } - void operator()(ipc_request::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_request::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerType(_rtid); _rprotocol.registerCast(); } - void operator()(ipc_request::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_request::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerType(_rtid); _rprotocol.registerCast(); } - void operator()(ipc_request::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_request::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerType(_rtid); _rprotocol.registerCast(); } - void operator()(ipc_request::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_request::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerType(_rtid); _rprotocol.registerCast(); } - void operator()(ipc_request::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_request::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerType(_rtid); _rprotocol.registerCast(); } template - void operator()(ipc_request::ProtocolT& _rprotocol, TypeToType _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) + void operator()(ipc_request::ProtocolT& _rprotocol, std::type_identity _t2t, const ipc_request::ProtocolT::TypeIdT& _rtid) { _rprotocol.registerMessage(complete_message, _rtid); } diff --git a/tutorials/mprpc_request_ssl/mprpc_request_client.cpp b/tutorials/mprpc_request_ssl/mprpc_request_client.cpp index 717d426b..76390e18 100644 --- a/tutorials/mprpc_request_ssl/mprpc_request_client.cpp +++ b/tutorials/mprpc_request_ssl/mprpc_request_client.cpp @@ -104,8 +104,8 @@ int main(int argc, char* argv[]) 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, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; + auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const& _rtype) { + using TypeT = T; if constexpr (std::is_base_of_v) { _rmap.template registerType(_id, _name); diff --git a/tutorials/mprpc_request_ssl/mprpc_request_messages.hpp b/tutorials/mprpc_request_ssl/mprpc_request_messages.hpp index aaf8e7a4..a9702185 100644 --- a/tutorials/mprpc_request_ssl/mprpc_request_messages.hpp +++ b/tutorials/mprpc_request_ssl/mprpc_request_messages.hpp @@ -316,15 +316,15 @@ struct Response : solid::frame::mprpc::Message { template inline void configure_protocol(Reg _rreg) { - _rreg(1, "Request", solid::TypeToType()); - _rreg(2, "Response", solid::TypeToType()); - _rreg(3, "RequestKeyAnd", solid::TypeToType()); - _rreg(4, "RequestKeyOr", solid::TypeToType()); - _rreg(5, "RequestKeyAndList", solid::TypeToType()); - _rreg(6, "RequestKeyOrList", solid::TypeToType()); - _rreg(7, "RequestKeyUserIdRegex", solid::TypeToType()); - _rreg(8, "RequestKeyEmailRegex", solid::TypeToType()); - _rreg(9, "RequestKeyYearLess", solid::TypeToType()); + _rreg(1, "Request", std::type_identity()); + _rreg(2, "Response", std::type_identity()); + _rreg(3, "RequestKeyAnd", std::type_identity()); + _rreg(4, "RequestKeyOr", std::type_identity()); + _rreg(5, "RequestKeyAndList", std::type_identity()); + _rreg(6, "RequestKeyOrList", std::type_identity()); + _rreg(7, "RequestKeyUserIdRegex", std::type_identity()); + _rreg(8, "RequestKeyEmailRegex", std::type_identity()); + _rreg(9, "RequestKeyYearLess", std::type_identity()); } } // namespace rpc_request diff --git a/tutorials/mprpc_request_ssl/mprpc_request_server.cpp b/tutorials/mprpc_request_ssl/mprpc_request_server.cpp index e16cdb3e..ef439a3f 100644 --- a/tutorials/mprpc_request_ssl/mprpc_request_server.cpp +++ b/tutorials/mprpc_request_ssl/mprpc_request_server.cpp @@ -326,8 +326,8 @@ int main(int argc, char* argv[]) 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, auto const& _rtype) { - using TypeT = typename std::decay_t::TypeT; + auto lambda = [&](const uint8_t _id, const std::string_view _name, type_identity const& _rtype) { + using TypeT = T; if constexpr (std::is_base_of_v) { _rmap.template registerType(_id, _name); From 9561549b8b46bd6fb493a1a3484b3bad6a75900c Mon Sep 17 00:00:00 2001 From: Valentin Palade Date: Thu, 9 Jan 2025 15:42:39 +0200 Subject: [PATCH 11/14] improvements and fixes on reflection --- JOURNAL.md | 3 + solid/reflection/v1/enummap.hpp | 46 +++++----- solid/reflection/v1/metadata.hpp | 19 ----- solid/reflection/v1/ostreamreflection.hpp | 2 +- solid/reflection/v1/reflector.hpp | 26 ++---- .../v1/test/test_reflection_basic.cpp | 18 ++-- .../v1/test/test_reflection_ostream.cpp | 15 ++-- solid/serialization/v3/test/test_binary.cpp | 85 ++++++++++++------- 8 files changed, 108 insertions(+), 106 deletions(-) diff --git a/JOURNAL.md b/JOURNAL.md index 2e32b4cd..120fbd05 100644 --- a/JOURNAL.md +++ b/JOURNAL.md @@ -1,3 +1,6 @@ +## 20250109 + * improvements and fixes on reflection + ## 20250106 * use std::variant in example_threadpool * TypeToType -> std::type_identity diff --git a/solid/reflection/v1/enummap.hpp b/solid/reflection/v1/enummap.hpp index 258a7119..3b30d1fc 100644 --- a/solid/reflection/v1/enummap.hpp +++ b/solid/reflection/v1/enummap.hpp @@ -11,62 +11,68 @@ #pragma once #include +#include #include #include #include +#include "solid/system/exception.hpp" #include "solid/utility/common.hpp" namespace solid { namespace reflection { namespace v1 { +template class EnumMap : NonCopyable { - using DirectMapT = std::unordered_map; - using ReverseMapT = std::unordered_map; + static_assert(std::is_enum_v, "T must be an enum"); + + using DirectMapT = std::unordered_map; + using ReverseMapT = std::unordered_map; DirectMapT direct_map_; ReverseMapT reverse_map_; public: - template - using InitListT = std::initializer_list>; + using EnumT = T; + using InitListT = std::initializer_list>; - template - EnumMap(std::type_identity _t, InitListT _init_list) + EnumMap(InitListT _init_list) { - static_assert(std::is_enum_v, "T must be an enum"); - for (const auto& item : _init_list) { - direct_map_.emplace(static_cast(to_underlying(item.first)), item.second); - reverse_map_.emplace(item.second, static_cast(to_underlying(item.first))); + const auto p = direct_map_.emplace(item.first, item.second); + solid_check(p.second, "Enum with the same value already exists"); + reverse_map_.emplace(p.first->second, item.first); } } - template - const char* get(const T _key) const + std::string_view get(const EnumT _key) const { - static_assert(std::is_enum_v, "T must be an enum"); - const auto it = direct_map_.find(static_cast(to_underlying(_key))); + const auto it = direct_map_.find(_key); if (it != direct_map_.end()) { - return it->second.data(); + return it->second; } else { - return nullptr; + return {}; } } - template - T get(std::string_view _name) const + std::optional get(std::string_view _name) const { - static_assert(std::is_enum_v, "T must be an enum"); const auto it = reverse_map_.find(_name); if (it != reverse_map_.end()) { return it->second; } else { - return nullptr; + return {}; } } }; +template +extern EnumMap enum_map_v; + +#define enummap_instance(V) \ + template <> \ + reflection::EnumMap solid::reflection::v1::enum_map_v + } // namespace v1 } // namespace reflection } // namespace solid diff --git a/solid/reflection/v1/metadata.hpp b/solid/reflection/v1/metadata.hpp index f7a609aa..0644db52 100644 --- a/solid/reflection/v1/metadata.hpp +++ b/solid/reflection/v1/metadata.hpp @@ -25,25 +25,6 @@ struct Generic { }; struct Enum { - const EnumMap* pmap_ = nullptr; - - Enum() {} - - Enum(const EnumMap& _rmap) - : pmap_(&_rmap) - { - } - - auto& map(const EnumMap& _rmap) - { - pmap_ = &_rmap; - return *this; - } - - const EnumMap* map() const - { - return pmap_; - } }; struct Pointer { diff --git a/solid/reflection/v1/ostreamreflection.hpp b/solid/reflection/v1/ostreamreflection.hpp index fab87d0c..7c7dfd23 100644 --- a/solid/reflection/v1/ostreamreflection.hpp +++ b/solid/reflection/v1/ostreamreflection.hpp @@ -65,7 +65,7 @@ struct OStreamVisitor { case tg::Enum: { auto& renum_node = *_rnode.template as(); rostream_ << _name << '(' << _index << ") = "; - renum_node.print(rostream_, _rmeta.enumeration()->map()); + renum_node.print(rostream_); rostream_ << eol_; } break; case tg::Structure: diff --git a/solid/reflection/v1/reflector.hpp b/solid/reflection/v1/reflector.hpp index 020fde50..e4b7a4f5 100644 --- a/solid/reflection/v1/reflector.hpp +++ b/solid/reflection/v1/reflector.hpp @@ -69,7 +69,6 @@ class BaseNode { virtual void doVisit(Reflector& /*_rreflector*/, const TypeMapBase*, ContextT& /*_rctx*/) = 0; virtual void doVisit(Reflector& /*_rreflector*/, const TypeMapBase*, ContextT& /*_rctx*/) const = 0; virtual std::ostream& print(std::ostream& _ros) const = 0; - virtual std::ostream& print(std::ostream& _ros, const EnumMap* /*_penum_map*/) const = 0; virtual void reset(const std::string_view _name, const TypeMapBase* _ptype_map, ContextT& /*_rctx*/) = 0; virtual std::ostream& ostream() = 0; virtual std::istream& istream() const = 0; @@ -162,7 +161,7 @@ class GroupNode : public BaseNode { } public: - std::ostream& print(std::ostream& _ros, const EnumMap* /*_penum_map*/) const override = 0; + std::ostream& print(std::ostream& _ros) const override = 0; }; template @@ -392,7 +391,7 @@ class Node : public GroupNode>()> { } } else if constexpr (type_group() == TypeGroupE::Container) { size_t i = 0; - for (auto& item : ref_) { + for (typename ValueT::const_reference item : ref_) { _rreflector.add(item, _rctx, i, ""); ++i; } @@ -412,7 +411,7 @@ class Node : public GroupNode>()> { } } else if constexpr (type_group() == TypeGroupE::Container) { size_t i = 0; - for (auto& item : ref_) { + for (typename ValueT::const_reference item : ref_) { _rreflector.add(item, _rctx, i, ""); ++i; } @@ -464,26 +463,17 @@ class Node : public GroupNode>()> { { if constexpr (type_group() == TypeGroupE::Basic || type_group() == TypeGroupE::Bitset) { _ros << ref_; - } - return _ros; - } - - std::ostream& print(std::ostream& _ros, const EnumMap* _penum_map) const override - { - if constexpr (type_group() == TypeGroupE::Enum) { - if (_penum_map) { - const char* name = _penum_map->get(ref_); - if (name != nullptr) { - _ros << name; - } else { - _ros << to_underlying(ref_); - } + } else if constexpr (type_group() == TypeGroupE::Enum) { + const auto name = enum_map_v.get(ref_); + if (!name.empty()) { + _ros << name; } else { _ros << to_underlying(ref_); } } return _ros; } + bool isNull() const override { if constexpr (type_group() == TypeGroupE::SharedPtr || type_group() == TypeGroupE::UniquePtr) { diff --git a/solid/reflection/v1/test/test_reflection_basic.cpp b/solid/reflection/v1/test/test_reflection_basic.cpp index 73006fc6..42aa5765 100644 --- a/solid/reflection/v1/test/test_reflection_basic.cpp +++ b/solid/reflection/v1/test/test_reflection_basic.cpp @@ -33,12 +33,12 @@ enum UserStatus { StatusSingleE, StatusRelationE, }; +} // namespace -// const EnumMap figure_enum_map = {{Zero, "zero"}, {One, "one"}}; -const reflection::EnumMap figure_enum_map{std::type_identity(), {{Zero, "Zero"}, {One, "One"}, {Two, "Two"}, {Three, "Three"}, {Four, "Four"}, {Five, "Five"}, {Six, "Six"}, {Seven, "Seven"}, {Eight, "Eight"}, {Nine, "Nine"}}}; - -const reflection::EnumMap user_status_map = {std::type_identity(), {{StatusMarriedE, "Married"}, {StatusSingleE, "Single"}, {StatusRelationE, "Relation"}}}; +enummap_instance(FigureE){{{Zero, "Zero"}, {One, "One"}, {Two, "Two"}, {Three, "Three"}, {Four, "Four"}, {Five, "Five"}, {Six, "Six"}, {Seven, "Seven"}, {Eight, "Eight"}, {Nine, "Nine"}}}; +enummap_instance(UserStatus){{{StatusMarriedE, "Married"}, {StatusSingleE, "Single"}, {StatusRelationE, "Relation"}}}; +namespace { struct Fruit { virtual ~Fruit() {} virtual void print(ostream& _ros) = 0; @@ -186,7 +186,7 @@ struct Test { { _rr.add([&_rthis](Reflector& _rr, Context& _rctx) { _rr(_rctx, 1, _rthis.id_, "id", _rthis.name_, "name", _rthis.ip_vec_, "ip_vec"); - _rr.add(_rthis.figure_, _rctx, 4, "figure", [](auto& _rmeta) { _rmeta.map(figure_enum_map); }); + _rr.add(_rthis.figure_, _rctx, 4, "figure"); _rr.add(reflection::compacted{_rthis.comp_id_}, _rctx, 5, "comp_id"); }, _rctx); @@ -215,19 +215,19 @@ struct Test { _rr.add(_rthis.user_vec_, _rctx, 1, "user_vec"); _rr.add(_rthis.services_, _rctx, 2, "services"); _rr.add(_rthis.vegetable_ptr_, _rctx, 4, "vegetable"); - _rr.add(_rthis.fruit_ptr_, _rctx, 5, "fruit", [](auto& _rmeta) { _rmeta.map(*pfruits_map); }); + _rr.add(_rthis.fruit_ptr_, _rctx, 5, "fruit"); _rr.add(_rthis.guid_ptr_, _rctx, 6, "guid"); _rr.add(_rthis.veg_tuple_, _rctx, 7, "veg_tuple"); if constexpr (!ReflectorT::is_const_reflector) { auto progress_lambda = [](Context& _rctx, std::ostream& _ris, uint64_t _len, const bool _done, const size_t _index, const char* _name) { // NOTE: here you can use context.any()for actual implementation }; - _rr.add(_rthis.ofs_, _rctx, 8, "stream", [&progress_lambda](auto _rmeta) { _rmeta.progressFunction(progress_lambda); }); + _rr.add(_rthis.ofs_, _rctx, 8, "stream", [&progress_lambda](auto& _rmeta) { _rmeta.progressFunction(progress_lambda); }); } else { auto progress_lambda = [](Context& _rctx, std::istream& _ris, uint64_t _len, const bool _done, const size_t _index, const char* _name) { // NOTE: here you can use context.any()for actual implementation }; - _rr.add(_rthis.ifs_, _rctx, 8, "stream", [&progress_lambda](auto _rmeta) { _rmeta.progressFunction(progress_lambda); }); + _rr.add(_rthis.ifs_, _rctx, 8, "stream", [&progress_lambda](auto& _rmeta) { _rmeta.progressFunction(progress_lambda); }); } } }; @@ -273,7 +273,7 @@ struct OStreamVisitor { case tg::Enum: { auto& renum_node = *_rnode.template as(); rostream_ << _name << '(' << _index << ") = "; - renum_node.print(rostream_, _rmeta.enumeration()->map()); + renum_node.print(rostream_); rostream_ << endl; } break; case tg::Structure: diff --git a/solid/reflection/v1/test/test_reflection_ostream.cpp b/solid/reflection/v1/test/test_reflection_ostream.cpp index 18d895b8..8fcb22e2 100644 --- a/solid/reflection/v1/test/test_reflection_ostream.cpp +++ b/solid/reflection/v1/test/test_reflection_ostream.cpp @@ -34,12 +34,15 @@ enum UserStatus { StatusSingleE, StatusRelationE, }; +} // namespace -// const EnumMap figure_enum_map = {{Zero, "zero"}, {One, "one"}}; -const reflection::EnumMap figure_enum_map{std::type_identity(), {{Zero, "Zero"}, {One, "One"}, {Two, "Two"}, {Three, "Three"}, {Four, "Four"}, {Five, "Five"}, {Six, "Six"}, {Seven, "Seven"}, {Eight, "Eight"}, {Nine, "Nine"}}}; +// template <> +// reflection::EnumMap solid::reflection::v1::enum_map_v +enummap_instance(FigureE){{{Zero, "Zero"}, {One, "One"}, {Two, "Two"}, {Three, "Three"}, {Four, "Four"}, {Five, "Five"}, {Six, "Six"}, {Seven, "Seven"}, {Eight, "Eight"}, {Nine, "Nine"}}}; -const reflection::EnumMap user_status_map = {std::type_identity(), {{StatusMarriedE, "Married"}, {StatusSingleE, "Single"}, {StatusRelationE, "Relation"}}}; +enummap_instance(UserStatus){{{StatusMarriedE, "Married"}, {StatusSingleE, "Single"}, {StatusRelationE, "Relation"}}}; +namespace { struct Fruit { virtual ~Fruit() {} virtual void print(ostream& _ros) = 0; @@ -188,7 +191,7 @@ struct Test { _rr.add(_rthis.id_, _rctx, 1, "id"); _rr.add(_rthis.name_, _rctx, 2, "name"); _rr.add(_rthis.ip_vec_, _rctx, 3, "ip_vec"); - _rr.add(_rthis.figure_, _rctx, 4, "figure", [](auto& _rmeta) { _rmeta.map(figure_enum_map); }); + _rr.add(_rthis.figure_, _rctx, 4, "figure"); }, _rctx); } @@ -223,12 +226,12 @@ struct Test { auto progress_lambda = [](Context& _rctx, std::ostream& _ris, uint64_t _len, const bool _done, const size_t _index, const char* _name) { // NOTE: here you can use context.any()for actual implementation }; - _rr.add(_rthis.ofs_, _rctx, 8, "stream", [&progress_lambda](auto _rmeta) { _rmeta.progressFunction(progress_lambda); }); + _rr.add(_rthis.ofs_, _rctx, 8, "stream", [&progress_lambda](auto& _rmeta) { _rmeta.progressFunction(progress_lambda); }); } else { auto progress_lambda = [](Context& _rctx, std::istream& _ris, uint64_t _len, const bool _done, const size_t _index, const char* _name) { // NOTE: here you can use context.any()for actual implementation }; - _rr.add(_rthis.ifs_, _rctx, 8, "stream", [&progress_lambda](auto _rmeta) { _rmeta.progressFunction(progress_lambda); }); + _rr.add(_rthis.ifs_, _rctx, 8, "stream", [&progress_lambda](auto& _rmeta) { _rmeta.progressFunction(progress_lambda); }); } } }; diff --git a/solid/serialization/v3/test/test_binary.cpp b/solid/serialization/v3/test/test_binary.cpp index 58d3ad63..32d901d0 100644 --- a/solid/serialization/v3/test/test_binary.cpp +++ b/solid/serialization/v3/test/test_binary.cpp @@ -52,28 +52,28 @@ struct Context { class Test { static constexpr size_t BlobCapacity = 40 * 1024; - string p; - bool b = false; - vector v; - deque d; - map m; - set s; - unordered_map um; - unordered_set us; - A a; - vector vb; - bitset<20> bs; - vector vc; - array a1; - array a2; - array a3; - uint16_t a2_sz = 0; - uint32_t blob_sz = 0; - char blob[BlobCapacity]; - uint32_t blob32_sz = 0; - char blob32[sizeof(uint32_t)]; - uint32_t blob64_sz = 0; - char blob64[sizeof(uint64_t)]; + string p; + bool b = false; + vector v; + deque d; + map m; + set s; + map um; + set us; + A a; + vector vb; + bitset<20> bs; + vector vc; + array a1; + array a2; + array a3; + uint16_t a2_sz = 0; + uint32_t blob_sz = 0; + char blob[BlobCapacity]; + uint32_t blob32_sz = 0; + char blob32[sizeof(uint32_t)]; + uint32_t blob64_sz = 0; + char blob64[sizeof(uint64_t)]; std::ostringstream oss; @@ -280,8 +280,7 @@ class Test { int test_binary(int argc, char* argv[]) { - solid::log_start(std::cerr, {".*:EWX"}); - // solid::log_start(argv[0], {".*:VIEW"}, true, 2, 1024 * 1024); + solid::log_start(std::cerr, {".*:EWX", "\\*:VIEWX"}); std::string input_file_path; std::string output_file_path; @@ -345,9 +344,10 @@ int test_binary(int argc, char* argv[]) std::shared_ptr sp1; std::unique_ptr up1; ContextT ctx; - ostringstream oss; + ostringstream ossbin; + string txt; - if (choice != 'l') { + if (choice == 's' || choice == 'v') { SerializerT ser{reflection::metadata::factory, key_type_map}; ofstream ofs; @@ -355,7 +355,7 @@ int test_binary(int argc, char* argv[]) ofs.open(archive_path, ios_base::out | ios_base::binary); } - ostream& ros = ofs.is_open() ? static_cast(std::ref(ofs)) : static_cast(std::ref(oss)); + ostream& ros = ofs.is_open() ? static_cast(std::ref(ofs)) : static_cast(std::ref(ossbin)); ser.run( ros, @@ -365,11 +365,16 @@ int test_binary(int argc, char* argv[]) ctx); solid_check(!ser.error(), "check failed: " << ser.error().message()); + ostringstream osstxt; + osstxt << reflection::oreflect>(reflection::metadata::factory, t, ctx, &key_type_map, "", " "); + solid_log(generic_logger, Info, "t refected: [" << reflection::oreflect>(reflection::metadata::factory, t, ctx, &key_type_map, "", " ") << "]"); + txt = osstxt.str(); + solid_check(!txt.empty()); } - if (choice != 's') { + if (choice == 'l' || choice == 'v') { - solid_dbg(generic_logger, Info, "oss.str.size = " << oss.str().size()); + solid_dbg(generic_logger, Info, "oss.str.size = " << ossbin.str().size()); ifstream ifs; @@ -378,10 +383,9 @@ int test_binary(int argc, char* argv[]) solid_assert(ifs.is_open()); } - istringstream iss(oss.str()); + istringstream iss(ossbin.str()); DeserializerT des{reflection::metadata::factory, key_type_map}; - - istream& ris = ifs.is_open() ? static_cast(std::ref(ifs)) : static_cast(std::ref(iss)); + istream& ris = ifs.is_open() ? static_cast(std::ref(ifs)) : static_cast(std::ref(iss)); Test t_c; std::shared_ptr tp_c; @@ -393,7 +397,7 @@ int test_binary(int argc, char* argv[]) des.run( ris, - [&t_c, &tp_c, &tup_c, &sp1_c, &up1_c](decltype(des)& des, ContextT& ctx) { + [&t_c, &tp_c, &tup_c, &sp1_c, &up1_c](auto& des, ContextT& ctx) { des.add(t_c, ctx, 1, "t").add(tp_c, ctx, 2, "tp_c").add(tup_c, ctx, 3, "tup_c").add(sp1_c, ctx, 4, "sp1").add(up1_c, ctx, 5, "up1"); }, ctx); @@ -405,6 +409,21 @@ int test_binary(int argc, char* argv[]) solid_check(*tup == *tup_c, "check failed"); solid_check(!sp1_c, "check failed"); solid_check(!up1_c, "check failed"); + + if (!txt.empty()) { + ostringstream osstxt; + osstxt << reflection::oreflect>(reflection::metadata::factory, t_c, ctx, &key_type_map, "", " "); + solid_log(generic_logger, Info, "t_c refected: [" << reflection::oreflect>(reflection::metadata::factory, t_c, ctx, &key_type_map, "", " ") << "]"); + string ctxt = osstxt.str(); + solid_check(!ctxt.empty()); + solid_check(ctxt.size() == txt.size()); +#if 0 + for (size_t i = 0; i < txt.size(); ++i) { + solid_check(txt[i] == ctxt[i], "failed for index " << i << " out of " << txt.size()); + } +#endif + solid_check(txt == ctxt); + } } } return 0; From fee809f9f4a550fb8017d14bd79eabd24afea25e Mon Sep 17 00:00:00 2001 From: Valentin Palade Date: Thu, 9 Jan 2025 21:31:35 +0200 Subject: [PATCH 12/14] reflection: handle VectorBool separately --- solid/reflection/v1/dispatch.hpp | 3 ++ solid/reflection/v1/ostreamreflection.hpp | 8 ++++ solid/reflection/v1/reflector.hpp | 49 +++++++++++++++++++++-- solid/utility/typetraits.hpp | 11 +++++ 4 files changed, 67 insertions(+), 4 deletions(-) diff --git a/solid/reflection/v1/dispatch.hpp b/solid/reflection/v1/dispatch.hpp index 719d59de..adde8129 100644 --- a/solid/reflection/v1/dispatch.hpp +++ b/solid/reflection/v1/dispatch.hpp @@ -26,6 +26,7 @@ enum struct TypeGroupE { Basic, Structure, Container, + VectorBool, Array, Bitset, Enum, @@ -57,6 +58,8 @@ constexpr TypeGroupE type_group() return TypeGroupE::Enum; if constexpr (is_bitset_v) return TypeGroupE::Bitset; + else if constexpr (is_std_vector_bool_v) + return TypeGroupE::VectorBool; else if constexpr (solid::is_container_v) return TypeGroupE::Container; else if constexpr (std::is_array::value || solid::is_std_array_v) diff --git a/solid/reflection/v1/ostreamreflection.hpp b/solid/reflection/v1/ostreamreflection.hpp index 7c7dfd23..d5d03779 100644 --- a/solid/reflection/v1/ostreamreflection.hpp +++ b/solid/reflection/v1/ostreamreflection.hpp @@ -84,6 +84,14 @@ struct OStreamVisitor { indent(); rostream_ << "]" << eol_; break; + case tg::VectorBool: + rostream_ << _name << '(' << _index << ") = [" << eol_; + ++indent_count_; + _rnode.template as()->for_each(std::ref(*this), _rctx); + --indent_count_; + indent(); + rostream_ << "]" << eol_; + break; case tg::Array: rostream_ << _name << '(' << _index << ") = [" << eol_; ++indent_count_; diff --git a/solid/reflection/v1/reflector.hpp b/solid/reflection/v1/reflector.hpp index e4b7a4f5..6efce384 100644 --- a/solid/reflection/v1/reflector.hpp +++ b/solid/reflection/v1/reflector.hpp @@ -122,6 +122,33 @@ class GroupNode : public BaseNode { } }; +template +class GroupNode : public BaseNode { +protected: + using ContextT = typename Reflector::ContextT; + using BaseT = BaseNode; + + GroupNode(Reflector& _rreflector, const std::type_info* const _ptype_info) + : BaseT(_rreflector, TypeGroupE::VectorBool, _ptype_info) + { + } + +public: + template + void for_each(DispatchFunction _dispatch_function, ContextT& _rctx) + { + Reflector new_reflector{this->rreflector_.metadataFactory(), _dispatch_function}; + this->doForEach(new_reflector, _rctx); + } + + template + void for_each(DispatchFunction _dispatch_function, ContextT& _rctx) const + { + Reflector new_reflector{this->rreflector_.metadataFactory(), _dispatch_function}; + this->doForEach(new_reflector, _rctx); + } +}; + template class GroupNode : public BaseNode { protected: @@ -391,10 +418,17 @@ class Node : public GroupNode>()> { } } else if constexpr (type_group() == TypeGroupE::Container) { size_t i = 0; - for (typename ValueT::const_reference item : ref_) { + for (auto& item : ref_) { _rreflector.add(item, _rctx, i, ""); ++i; } + } else if constexpr (type_group() == TypeGroupE::VectorBool) { + size_t i = 0; + for (auto item : ref_) { + const bool b = item; + _rreflector.add(b, _rctx, i, ""); + ++i; + } } else if constexpr (type_group() == TypeGroupE::Structure) { solidReflectV1(_rreflector, ref_, _rctx); } else if constexpr (type_group() == TypeGroupE::Tuple) { @@ -411,10 +445,17 @@ class Node : public GroupNode>()> { } } else if constexpr (type_group() == TypeGroupE::Container) { size_t i = 0; - for (typename ValueT::const_reference item : ref_) { + for (auto& item : ref_) { _rreflector.add(item, _rctx, i, ""); ++i; } + } else if constexpr (type_group() == TypeGroupE::VectorBool) { + size_t i = 0; + for (auto item : ref_) { + const bool b = item; + _rreflector.add(b, _rctx, i, ""); + ++i; + } } else if constexpr (type_group() == TypeGroupE::Structure) { solidReflectV1(_rreflector, ref_, _rctx); } else if constexpr (type_group() == TypeGroupE::Tuple) { @@ -427,7 +468,7 @@ class Node : public GroupNode>()> { if constexpr (type_group() == TypeGroupE::SharedPtr || type_group() == TypeGroupE::UniquePtr || type_group() == TypeGroupE::IntrusivePtr) { solid_check(ref_); if constexpr ( - type_group() == TypeGroupE::Basic || type_group() == TypeGroupE::Container || type_group() == TypeGroupE::Enum || type_group() == TypeGroupE::Bitset) { + type_group() == TypeGroupE::Basic || type_group() == TypeGroupE::Container || type_group() == TypeGroupE::Enum || type_group() == TypeGroupE::Bitset || type_group() == TypeGroupE::VectorBool) { _rreflector.add(*ref_, _rctx, 0, ""); } else { solid_check(_ptype_map != nullptr); @@ -441,7 +482,7 @@ class Node : public GroupNode>()> { if constexpr (type_group() == TypeGroupE::SharedPtr || type_group() == TypeGroupE::UniquePtr || type_group() == TypeGroupE::IntrusivePtr) { solid_check(ref_); if constexpr ( - type_group() == TypeGroupE::Basic || type_group() == TypeGroupE::Container || type_group() == TypeGroupE::Enum || type_group() == TypeGroupE::Bitset) { + type_group() == TypeGroupE::Basic || type_group() == TypeGroupE::Container || type_group() == TypeGroupE::Enum || type_group() == TypeGroupE::Bitset || type_group() == TypeGroupE::VectorBool) { _rreflector.add(*ref_, _rctx, 0, ""); } else { solid_check(_ptype_map != nullptr); diff --git a/solid/utility/typetraits.hpp b/solid/utility/typetraits.hpp index c6530510..c2942af2 100644 --- a/solid/utility/typetraits.hpp +++ b/solid/utility/typetraits.hpp @@ -163,6 +163,17 @@ struct is_std_vector> : std::true_type { template inline constexpr bool is_std_vector_v = is_std_vector::value; +template +struct is_std_vector_bool : std::false_type { +}; + +template +struct is_std_vector_bool> : std::true_type { +}; + +template +inline constexpr bool is_std_vector_bool_v = is_std_vector_bool::value; + template using element_type_t = std::remove_reference_t()))>; From 2a42460fd71a6c435fa62bd584bcc0afb3f5a169 Mon Sep 17 00:00:00 2001 From: Valentin Palade Date: Wed, 15 Jan 2025 09:59:52 +0200 Subject: [PATCH 13/14] small fixes in threadpool and function --- solid/utility/function.hpp | 2 +- solid/utility/threadpool.hpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/solid/utility/function.hpp b/solid/utility/function.hpp index fb3b7bf0..9771d989 100644 --- a/solid/utility/function.hpp +++ b/solid/utility/function.hpp @@ -165,7 +165,7 @@ RepresentationE do_copy( _rpbig_rtti = &big_rtti; return RepresentationE::Big; } else { - solid_throw("Any: contained value not copyable"); + solid_throw("Function: contained value not copyable"); return RepresentationE::None; } } diff --git a/solid/utility/threadpool.hpp b/solid/utility/threadpool.hpp index 4f2d8d72..b001565a 100644 --- a/solid/utility/threadpool.hpp +++ b/solid/utility/threadpool.hpp @@ -342,7 +342,7 @@ class TaskList { void push(Task&& _task, const uint64_t _all_id, const uint64_t _id) { - size_t index = -1; + size_t index = InvalidIndex{}; if (!free_tasks_.empty()) { index = free_tasks_.backIndex(); free_tasks_.popBack(); @@ -448,7 +448,7 @@ class ThreadPool : NonCopyable { struct OneStub { AtomicCounterT produce_count_{0}; - AtomicCounterT consume_count_{static_cast(-1)}; + AtomicCounterT consume_count_{std::numeric_limits::max()}; std::uint8_t event_ = {to_underlying(EventE::Fill)}; TaskData* data_ptr_ = nullptr; ContextStub* pcontext_ = nullptr; @@ -556,7 +556,7 @@ class ThreadPool : NonCopyable { struct AllStub { AtomicCounterT produce_count_{0}; - AtomicCounterT consume_count_{static_cast(-1)}; + AtomicCounterT consume_count_{std::numeric_limits::max()}; std::atomic_uint32_t use_count_ = {0}; std::atomic_uint64_t id_ = {0}; TaskData* data_ptr_ = nullptr; From 81936932c59153587c18d3588e83579267b3477d Mon Sep 17 00:00:00 2001 From: Valentin Palade Date: Sun, 19 Jan 2025 14:58:15 +0200 Subject: [PATCH 14/14] version 12.2 --- CMakeLists.txt | 2 +- JOURNAL.md | 3 +++ RELEASES.md | 9 +++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7aef8a16..e95116c2 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.1) +project (SolidFrame VERSION 12.2) message("SolidFrame version: ${PROJECT_VERSION} - ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") #----------------------------------------------------------------- diff --git a/JOURNAL.md b/JOURNAL.md index 120fbd05..14b1807e 100644 --- a/JOURNAL.md +++ b/JOURNAL.md @@ -1,3 +1,6 @@ +## 20250119 + * release 12.2 + ## 20250109 * improvements and fixes on reflection diff --git a/RELEASES.md b/RELEASES.md index 7f2feb0e..659f5ba1 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,5 +1,14 @@ # SolidFrame Releases +## Version 12.2 + * improvements and fixes on reflection + * use std::variant in example_threadpool + * TypeToType -> std::type_identity + * mprpc: add support for ConnectionContext::pauseRead and Connection::Context::resumeRead + * aio: stream fix not call doTrySend or doTryRecv after disconnect + * mprpc: do not reset timer on onSend with error if connection already stopping + * mprpc: add support for ConnectionContext::stop() for stopping the connection + ## Version 12.1 * Coverity fixes