From 3cd54fbe1e28cc9991fcf9403ae92beac8b4520e Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Fri, 13 Oct 2023 17:03:21 +0500 Subject: [PATCH 01/37] Add handler submodule --- include/FlameIDE/CMakeLists.txt | 1 + src/CMakeLists.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/include/FlameIDE/CMakeLists.txt b/include/FlameIDE/CMakeLists.txt index 2c05b3a4..44168890 100644 --- a/include/FlameIDE/CMakeLists.txt +++ b/include/FlameIDE/CMakeLists.txt @@ -8,6 +8,7 @@ set(HEADER_MODULES ${FLAME_INCLUDE_SUBMODLUES_PATH}/Common ${FLAME_INCLUDE_SUBMODLUES_PATH}/Constants ${FLAME_INCLUDE_SUBMODLUES_PATH}/Crypto + ${FLAME_INCLUDE_SUBMODLUES_PATH}/Handler ${FLAME_INCLUDE_SUBMODLUES_PATH}/Os ${FLAME_INCLUDE_SUBMODLUES_PATH}/Others # ${FLAME_INCLUDE_SUBMODLUES_PATH}/Streams diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a6842898..74f16177 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,6 +5,7 @@ set(SOURCE_MODULES ${FLAME_SOURCE_SUBMODLUES_PATH}/Bus ${FLAME_SOURCE_SUBMODLUES_PATH}/Common ${FLAME_SOURCE_SUBMODLUES_PATH}/Crypto + ${FLAME_SOURCE_SUBMODLUES_PATH}/Handler ${FLAME_SOURCE_SUBMODLUES_PATH}/Os # ${FLAME_SOURCE_SUBMODLUES_PATH}/Streams ${FLAME_SOURCE_SUBMODLUES_PATH}/Ubjson From 5f2e5e38c566c57f5374c1dfa0bc7921f31e0eeb Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Sun, 24 Dec 2023 21:41:49 +0500 Subject: [PATCH 02/37] Add Expected class to Common. Fix 'Utils' -> 'UtilsTest' --- include/FlameIDE/Common/PrimitiveTypes.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/FlameIDE/Common/PrimitiveTypes.hpp b/include/FlameIDE/Common/PrimitiveTypes.hpp index d7261745..7f29eb1c 100644 --- a/include/FlameIDE/Common/PrimitiveTypes.hpp +++ b/include/FlameIDE/Common/PrimitiveTypes.hpp @@ -23,7 +23,6 @@ using long_t = ::int64_t; using float_t = float; using double_t = double; using ldouble_t = long double; - using ptrint_t = ::intptr_t; using ptruint_t = ::uintptr_t; From 5f5993b6658a7981a24a319075217518c5423ec0 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Mon, 25 Dec 2023 02:39:10 +0500 Subject: [PATCH 03/37] Add implementation of network hadler --- include/FlameIDE/Handler/CMakeLists.txt | 8 + .../FlameIDE/Handler/Network/CMakeLists.txt | 20 + include/FlameIDE/Handler/Network/Handler.hpp | 154 ++++++ .../FlameIDE/Handler/Network/Headers.cmake | 3 + include/FlameIDE/Os/Network/NetworkBase.hpp | 6 +- include/FlameIDE/Os/Network/TcpClient.hpp | 3 +- include/FlameIDE/Os/Network/TcpServer.hpp | 2 +- include/FlameIDE/Os/Network/UdpClient.hpp | 2 + include/FlameIDE/Os/Network/UdpServer.hpp | 2 + src/Handler/CMakeLists.txt | 8 + src/Handler/Network/CMakeLists.txt | 32 ++ src/Handler/Network/CommunicationHandle.cpp | 30 ++ src/Handler/Network/Config.cmake | 48 ++ src/Handler/Network/Functions.hpp | 65 +++ src/Handler/Network/Handler.cpp | 126 +++++ src/Handler/Network/Headers.cmake | 15 + src/Handler/Network/Internal.cpp | 438 ++++++++++++++++++ src/Handler/Network/Internal.hpp | 44 ++ src/Handler/Network/ServerHandle.cpp | 18 + src/Handler/Network/Sources.cmake | 9 + src/Handler/Network/Tcp.cpp | 78 ++++ src/Handler/Network/Tcp.hpp | 73 +++ src/Handler/Network/TcpClient.hpp | 58 +++ src/Handler/Network/TcpConfig.hpp | 42 ++ src/Handler/Network/TcpServer.hpp | 67 +++ src/Handler/Network/TcpTypes.hpp | 48 ++ src/Handler/Network/Udp.cpp | 78 ++++ src/Handler/Network/Udp.hpp | 52 +++ src/Handler/Network/UdpClient.hpp | 45 ++ src/Handler/Network/UdpConfig.hpp | 42 ++ src/Handler/Network/UdpServer.hpp | 47 ++ src/Handler/Network/UdpTypes.hpp | 47 ++ src/Handler/Network/Worker.cpp | 58 +++ src/Handler/Network/Worker.hpp | 62 +++ src/Handler/Tests/CMakeLists.txt | 113 +++++ src/Handler/Tests/Network/CMakeLists.txt | 29 ++ src/Handler/Tests/Network/HandlerTest.cpp | 20 + src/Handler/Tests/Network/HandlerTest.hpp | 24 + src/Handler/Tests/Network/Headers.cmake | 5 + src/Handler/Tests/Network/InternalTest.cpp | 20 + src/Handler/Tests/Network/InternalTest.hpp | 24 + src/Handler/Tests/Network/Sources.cmake | 12 + src/Handler/Tests/Network/TcpTest.cpp | 52 +++ src/Handler/Tests/Network/TcpTest.hpp | 28 ++ src/Handler/Tests/Network/UdpTest.cpp | 52 +++ src/Handler/Tests/Network/UdpTest.hpp | 28 ++ src/Handler/Tests/Network/WorkerTest.cpp | 20 + src/Handler/Tests/Network/WorkerTest.hpp | 24 + src/Handler/Tests/Sources.cmake | 5 + src/Handler/Tests/TestAggregator.cpp | 23 + src/Handler/Tests/TestAggregator.hpp | 20 + src/Handler/Tests/main.cpp | 6 + tests/CMakeLists.txt | 1 + 53 files changed, 2332 insertions(+), 4 deletions(-) create mode 100644 include/FlameIDE/Handler/CMakeLists.txt create mode 100644 include/FlameIDE/Handler/Network/CMakeLists.txt create mode 100644 include/FlameIDE/Handler/Network/Handler.hpp create mode 100644 include/FlameIDE/Handler/Network/Headers.cmake create mode 100644 src/Handler/CMakeLists.txt create mode 100644 src/Handler/Network/CMakeLists.txt create mode 100644 src/Handler/Network/CommunicationHandle.cpp create mode 100644 src/Handler/Network/Config.cmake create mode 100644 src/Handler/Network/Functions.hpp create mode 100644 src/Handler/Network/Handler.cpp create mode 100644 src/Handler/Network/Headers.cmake create mode 100644 src/Handler/Network/Internal.cpp create mode 100644 src/Handler/Network/Internal.hpp create mode 100644 src/Handler/Network/ServerHandle.cpp create mode 100644 src/Handler/Network/Sources.cmake create mode 100644 src/Handler/Network/Tcp.cpp create mode 100644 src/Handler/Network/Tcp.hpp create mode 100644 src/Handler/Network/TcpClient.hpp create mode 100644 src/Handler/Network/TcpConfig.hpp create mode 100644 src/Handler/Network/TcpServer.hpp create mode 100644 src/Handler/Network/TcpTypes.hpp create mode 100644 src/Handler/Network/Udp.cpp create mode 100644 src/Handler/Network/Udp.hpp create mode 100644 src/Handler/Network/UdpClient.hpp create mode 100644 src/Handler/Network/UdpConfig.hpp create mode 100644 src/Handler/Network/UdpServer.hpp create mode 100644 src/Handler/Network/UdpTypes.hpp create mode 100644 src/Handler/Network/Worker.cpp create mode 100644 src/Handler/Network/Worker.hpp create mode 100644 src/Handler/Tests/CMakeLists.txt create mode 100644 src/Handler/Tests/Network/CMakeLists.txt create mode 100644 src/Handler/Tests/Network/HandlerTest.cpp create mode 100644 src/Handler/Tests/Network/HandlerTest.hpp create mode 100644 src/Handler/Tests/Network/Headers.cmake create mode 100644 src/Handler/Tests/Network/InternalTest.cpp create mode 100644 src/Handler/Tests/Network/InternalTest.hpp create mode 100644 src/Handler/Tests/Network/Sources.cmake create mode 100644 src/Handler/Tests/Network/TcpTest.cpp create mode 100644 src/Handler/Tests/Network/TcpTest.hpp create mode 100644 src/Handler/Tests/Network/UdpTest.cpp create mode 100644 src/Handler/Tests/Network/UdpTest.hpp create mode 100644 src/Handler/Tests/Network/WorkerTest.cpp create mode 100644 src/Handler/Tests/Network/WorkerTest.hpp create mode 100644 src/Handler/Tests/Sources.cmake create mode 100644 src/Handler/Tests/TestAggregator.cpp create mode 100644 src/Handler/Tests/TestAggregator.hpp create mode 100644 src/Handler/Tests/main.cpp diff --git a/include/FlameIDE/Handler/CMakeLists.txt b/include/FlameIDE/Handler/CMakeLists.txt new file mode 100644 index 00000000..eda5ebe0 --- /dev/null +++ b/include/FlameIDE/Handler/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.14) + +set(SOURCE_MODULES + ${CMAKE_CURRENT_LIST_DIR}/Network +) +foreach(module ${SOURCE_MODULES}) + add_subdirectory(${module}) +endforeach() diff --git a/include/FlameIDE/Handler/Network/CMakeLists.txt b/include/FlameIDE/Handler/Network/CMakeLists.txt new file mode 100644 index 00000000..38a8684f --- /dev/null +++ b/include/FlameIDE/Handler/Network/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.14) + +set(NAME "Handler.Network") +set(NAME_ALIAS "Handler::Network") +set(LIBRARY_ALIAS_NAME ${FLAME_NAMESPACE}::${NAME_ALIAS}::Headers) +set(DEPENDENCY_LIST + ${FLAME_NAMESPACE}::Common::Headers + ${FLAME_NAMESPACE}::Os::Headers + ${FLAME_NAMESPACE}::Templates::Headers +) + +get_sources(FILE_LIST) +flame_header_library( + NAME "${NAME}" + LIBRARY_ALIAS_NAME "${LIBRARY_ALIAS_NAME}" + HEADER_LIST "${FILE_LIST}" + DEPENDENCY_TARGET_LIST "${DEPENDENCY_LIST}" + INCLUDE_PATHS "${FLAME_INCLUDE_PATH}" + INSTALL_SUBDIR "${FLAME_NAMESPACE}/${NAME}" +) diff --git a/include/FlameIDE/Handler/Network/Handler.hpp b/include/FlameIDE/Handler/Network/Handler.hpp new file mode 100644 index 00000000..f6940278 --- /dev/null +++ b/include/FlameIDE/Handler/Network/Handler.hpp @@ -0,0 +1,154 @@ +#ifndef FLAMEIDE_OS_NETWORK_HANDLER_HPP +#define FLAMEIDE_OS_NETWORK_HANDLER_HPP + +#include +#include + +#include +#include +#include + +namespace flame_ide +{namespace os +{namespace network +{ + +class NetworkBase; + +class UdpServer; +class UdpClient; + +class TcpServer; +class TcpClient; + +}}} // namespace flame_ide::os::network + +namespace flame_ide +{namespace handler +{namespace network +{ + +/// +/// @brief The Handler class +/// +class Handler +{ +public: + class Internal; + +public: + class ServerHandle; + class CommunicationHandle; + +public: + Handler() noexcept; + Handler(const Handler &) noexcept = delete; + Handler(Handler &&handler) noexcept; + + ~Handler() noexcept; + + Handler &operator=(const Handler &) noexcept = delete; + Handler &operator=(Handler &&handler) noexcept; + + ServerHandle push(os::network::UdpServer &&server) noexcept; + CommunicationHandle push(os::network::UdpClient &&client) noexcept; + + ServerHandle push(os::network::TcpServer &&server) noexcept; + CommunicationHandle push(os::network::TcpClient &&client) noexcept; + + os::Status pop(const ServerHandle &, os::network::UdpServer &server) noexcept; + os::Status pop(const CommunicationHandle &, os::network::UdpClient &client) noexcept; + + os::Status pop(const ServerHandle &, os::network::TcpServer &server) noexcept; + os::Status pop(const CommunicationHandle &, os::network::TcpClient &client) noexcept; + + os::Status start() noexcept; + os::Status stop() noexcept; + +private: + Internal *internal = nullptr; +}; + +}}} // namespace flame_ide::handler::network + +// Handler::ServerHandle +namespace flame_ide +{namespace handler +{namespace network +{ + +class Handler::ServerHandle +{ +public: + ServerHandle() noexcept = default; + ServerHandle(ServerHandle &&) noexcept = default; + ~ServerHandle() noexcept = default; + + ServerHandle &operator=(const ServerHandle &) noexcept = default; + ServerHandle &operator=(ServerHandle &&) noexcept = default; + + operator bool() const noexcept; + + Handler::CommunicationHandle getCommunicationHandle() noexcept; + +private: + friend class Handler::Internal; + +private: + using CallbackGetCommunicationHandle = Handler::CommunicationHandle (*)(void *); + +private: + void *data = nullptr; + CallbackGetCommunicationHandle callbackGetCommunicationHandle = nullptr; +}; + +}}} // namespace flame_ide::handler::network + +// Handler::CommunicationHandle +namespace flame_ide +{namespace handler +{namespace network +{ + +class Handler::CommunicationHandle +{ +public: + CommunicationHandle() noexcept = default; + CommunicationHandle(CommunicationHandle &&) noexcept = default; + ~CommunicationHandle() noexcept = default; + + CommunicationHandle &operator=(CommunicationHandle &&) noexcept = default; + + operator bool() const noexcept; + + Types::ssize_t bytesToRead() const noexcept; + + Types::ssize_t receive(flame_ide::templates::Range) noexcept; + Types::ssize_t send(flame_ide::templates::Range) noexcept; + +private: + friend class Handler::Internal; + friend class Handler::ServerHandle; + +private: + static constexpr Types::size_t OBJECT_SIZE = 64; + + using Object = templates::Object; + using CallbackBytesToRead = Types::ssize_t (*)(const Object *); + using CallbackReceive = Types::ssize_t (*)( + Object *, flame_ide::templates::Range + ); + using CallbackSend = Types::ssize_t (*)( + Object *, flame_ide::templates::Range + ); + +private: + Object object; + CallbackBytesToRead callbackBytesToRead = nullptr; + CallbackReceive callbackReceive = nullptr; + CallbackSend callbackSend = nullptr; +}; + +}}} // namespace flame_ide::handler::network + +#endif // FLAMEIDE_OS_NETWORK_HANDLER_HPP diff --git a/include/FlameIDE/Handler/Network/Headers.cmake b/include/FlameIDE/Handler/Network/Headers.cmake new file mode 100644 index 00000000..ac4c9f15 --- /dev/null +++ b/include/FlameIDE/Handler/Network/Headers.cmake @@ -0,0 +1,3 @@ +set (HEADER_LIST + ${CMAKE_CURRENT_SOURCE_DIR}/Handler.hpp +) diff --git a/include/FlameIDE/Os/Network/NetworkBase.hpp b/include/FlameIDE/Os/Network/NetworkBase.hpp index 7b5c5ecc..5c9fb20c 100644 --- a/include/FlameIDE/Os/Network/NetworkBase.hpp +++ b/include/FlameIDE/Os/Network/NetworkBase.hpp @@ -3,6 +3,7 @@ #include #include +#include #include @@ -38,6 +39,7 @@ class NetworkBase: public NonCopy static const NativeCallbacks &callbacks() noexcept; protected: + NetworkBase() noexcept = default; NetworkBase(Socket socket) noexcept; NetworkBase(NetworkBase &&base) noexcept; @@ -54,10 +56,10 @@ class NetworkBase: public NonCopy static Types::int_t checkStatus(Status status) noexcept; protected: - Socket socket; + Socket socket = SOCKET_INVALID; private: - Status status = 0; + Status status = STATUS_SUCCESS; }; }}} // namespace flame_ide::os::network diff --git a/include/FlameIDE/Os/Network/TcpClient.hpp b/include/FlameIDE/Os/Network/TcpClient.hpp index 76a0cb59..1c0d74a9 100644 --- a/include/FlameIDE/Os/Network/TcpClient.hpp +++ b/include/FlameIDE/Os/Network/TcpClient.hpp @@ -18,7 +18,8 @@ class TcpClient final: public NetworkBase struct NativeCallbacks; public: - TcpClient() noexcept = delete; + TcpClient() noexcept : NetworkBase() {} + TcpClient(const TcpClient &) noexcept = delete; TcpClient(TcpClient &&client) noexcept; diff --git a/include/FlameIDE/Os/Network/TcpServer.hpp b/include/FlameIDE/Os/Network/TcpServer.hpp index f8f8a641..ef792e0d 100644 --- a/include/FlameIDE/Os/Network/TcpServer.hpp +++ b/include/FlameIDE/Os/Network/TcpServer.hpp @@ -21,7 +21,7 @@ class TcpServer final: public NetworkBase struct NativeCallbacks; public: - TcpServer() noexcept = delete; + TcpServer() noexcept : NetworkBase() {} TcpServer(const TcpServer &tcpServer) noexcept = delete; TcpServer(TcpServer &&tcpServer) noexcept; diff --git a/include/FlameIDE/Os/Network/UdpClient.hpp b/include/FlameIDE/Os/Network/UdpClient.hpp index 48874c9a..e2c4ba51 100644 --- a/include/FlameIDE/Os/Network/UdpClient.hpp +++ b/include/FlameIDE/Os/Network/UdpClient.hpp @@ -18,6 +18,8 @@ class UdpClient final: public NetworkBase struct NativeCallbacks; public: + UdpClient() noexcept : NetworkBase() {} + UdpClient(UdpClient &&udpClient) noexcept; UdpClient(Ipv4 ip) noexcept; diff --git a/include/FlameIDE/Os/Network/UdpServer.hpp b/include/FlameIDE/Os/Network/UdpServer.hpp index 6f83ac9d..de030e5b 100644 --- a/include/FlameIDE/Os/Network/UdpServer.hpp +++ b/include/FlameIDE/Os/Network/UdpServer.hpp @@ -19,6 +19,8 @@ class UdpServer final: public NetworkBase struct NativeCallbacks; public: + UdpServer() noexcept : NetworkBase() {} + UdpServer(UdpServer &&udpServer) noexcept; UdpServer(Ipv4::Port port) noexcept; ~UdpServer() noexcept = default; diff --git a/src/Handler/CMakeLists.txt b/src/Handler/CMakeLists.txt new file mode 100644 index 00000000..eda5ebe0 --- /dev/null +++ b/src/Handler/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.14) + +set(SOURCE_MODULES + ${CMAKE_CURRENT_LIST_DIR}/Network +) +foreach(module ${SOURCE_MODULES}) + add_subdirectory(${module}) +endforeach() diff --git a/src/Handler/Network/CMakeLists.txt b/src/Handler/Network/CMakeLists.txt new file mode 100644 index 00000000..bff07354 --- /dev/null +++ b/src/Handler/Network/CMakeLists.txt @@ -0,0 +1,32 @@ +cmake_minimum_required(VERSION 3.14) + +set(NAME Handler.Network) +set(NAME_ALIAS Handler::Network) +set(INCLUDE_PATHS ${FLAME_INCLUDE_PATH}) + +set(DEPENDENCY_HEADER_TARGETS + ${FLAME_NAMESPACE}::Handler::Network::Headers +) +set(DEPENDENCY_TARGETS_FOR_STATIC + "${FLAME_NAMESPACE}::Os::Static" +) +set(DEPENDENCY_TARGETS_FOR_SHARED + "${FLAME_NAMESPACE}::Os::Shared" +) + +get_sources(FILE_LIST) +flame_compile_library( + NAME "${NAME}" + SOURCE_LIST "${FILE_LIST}" + INCLUDE_PATHS "${INCLUDE_PATHS}" "${GENERATED_INCLUDE_PATH}" + DEPENDENCY_HEADER_TARGETS "${DEPENDENCY_HEADER_TARGETS}" + DEPENDENCY_TARGETS_FOR_STATIC "${DEPENDENCY_TARGETS_FOR_STATIC}" + DEPENDENCY_TARGETS_FOR_SHARED "${DEPENDENCY_TARGETS_FOR_SHARED}" + OBJECT_ALIAS_NAME + "${FLAME_NAMESPACE}::${NAME_ALIAS}::Object" + INDEPENDENT_OBJECT_ALIAS_NAME + "${FLAME_NAMESPACE}::${NAME_ALIAS}::Object::Independ" + + NO_RTTI + NO_EXCEPTIONS +) diff --git a/src/Handler/Network/CommunicationHandle.cpp b/src/Handler/Network/CommunicationHandle.cpp new file mode 100644 index 00000000..8d6f9639 --- /dev/null +++ b/src/Handler/Network/CommunicationHandle.cpp @@ -0,0 +1,30 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{ + +Handler::CommunicationHandle::operator bool() const noexcept +{ + return object && callbackBytesToRead && callbackReceive && callbackSend; +} + +Types::ssize_t Handler::CommunicationHandle::bytesToRead() const noexcept +{ + return callbackBytesToRead(&object); +} + +Types::ssize_t +Handler::CommunicationHandle::receive(templates::Range bytes) noexcept +{ + return callbackReceive(&object, bytes); +} + +Types::ssize_t +Handler::CommunicationHandle::send(templates::Range bytes) noexcept +{ + return callbackSend(&object, bytes); +} + +}}} // namespace flame_ide::handler::network diff --git a/src/Handler/Network/Config.cmake b/src/Handler/Network/Config.cmake new file mode 100644 index 00000000..515b4a76 --- /dev/null +++ b/src/Handler/Network/Config.cmake @@ -0,0 +1,48 @@ +cmake_minimum_required(VERSION 3.14) + +# Udp + +set(UDP_MESSAGE_SIZE_KB 32) + +set(UDP_SERVERS 8) +set(UDP_SERVER_INPUT_QUEUE_SIZE 32) +set(UDP_SERVER_OUTPUT_QUEUE_SIZE 32) + +set(UDP_CLIENTS 16) +set(UDP_CLIENT_INPUT_QUEUE_SIZE 32) +set(UDP_CLIENT_OUTPUT_QUEUE_SIZE 32) + +# Tcp + +set(TCP_SERVERS 8) +set(TCP_SERVER_INPUT_BUFFER_KB 64) +set(TCP_SERVER_OUTPUT_BUFFER_KB 64) + +set(TCP_CLIENTS 16) +set(TCP_CLIENT_INPUT_BUFFER_KB 64) +set(TCP_CLIENT_OUTPUT_BUFFER_KB 64) + +# Common + +set(NUMBER_OF_WORKERS 2) + +# Add defines + +set(HANDLER_NETWORK_DEFINES + "HANDLER_NETWORK_UDP_SERVERS=${UDP_SERVERS}" + "HANDLER_NETWORK_UDP_CLIENTS=${UDP_CLIENTS}" + "HANDLER_NETWORK_UDP_MESSAGE_SIZE_KB=${UDP_MESSAGE_SIZE_KB}" + "HANDLER_NETWORK_UDP_SERVER_INPUT_QUEUE_SIZE=${UDP_SERVER_INPUT_QUEUE_SIZE}" + "HANDLER_NETWORK_UDP_SERVER_OUTPUT_QUEUE_SIZE=${UDP_SERVER_OUTPUT_QUEUE_SIZE}" + "HANDLER_NETWORK_UDP_CLIENT_INPUT_QUEUE_SIZE=${UDP_CLIENT_INPUT_QUEUE_SIZE}" + "HANDLER_NETWORK_UDP_CLIENT_OUTPUT_QUEUE_SIZE=${UDP_CLIENT_OUTPUT_QUEUE_SIZE}" + + "HANDLER_NETWORK_TCP_SERVERS=${TCP_SERVERS}" + "HANDLER_NETWORK_TCP_CLIENTS=${TCP_CLIENTS}" + "HANDLER_NETWORK_TCP_SERVER_INPUT_BUFFER_KB=${TCP_SERVER_INPUT_BUFFER_KB}" + "HANDLER_NETWORK_TCP_SERVER_OUTPUT_BUFFER_KB=${TCP_SERVER_OUTPUT_BUFFER_KB}" + "HANDLER_NETWORK_TCP_CLIENT_INPUT_BUFFER_KB=${TCP_CLIENT_INPUT_BUFFER_KB}" + "HANDLER_NETWORK_TCP_CLIENT_OUTPUT_BUFFER_KB=${TCP_CLIENT_OUTPUT_BUFFER_KB}" + + "HANDLER_NETWORK_NUMBER_OF_WORKERS=${NUMBER_OF_WORKERS}" +) diff --git a/src/Handler/Network/Functions.hpp b/src/Handler/Network/Functions.hpp new file mode 100644 index 00000000..e6320fb1 --- /dev/null +++ b/src/Handler/Network/Functions.hpp @@ -0,0 +1,65 @@ +#ifndef HANDLERINTERNALFUNCTIONS_HPP +#define HANDLERINTERNALFUNCTIONS_HPP + +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{ + +template +inline bool initPointer(Pointer &pointer, os::threads::Spin &spin) noexcept +{ + os::threads::Locker lock{ spin }; + if (!pointer) + pointer = Pointer{}; + return pointer; +} + +template +inline auto *pushData(Pointer &pointer, os::threads::Spin &spin + , LambdaCheck &&check, LambdaAssign &&assignTo) noexcept +{ + using DataPointer = flame_ide::RemoveAllTypebegin())>; + using Data = flame_ide::RemoveAllTypebegin()))>; + + os::threads::Locker lock{ spin }; + Data *data = nullptr; + for (DataPointer &i : *pointer) + { + if (check(*i)) + continue; + + data = i.pointer(); + break; + } + assignTo(*data); + return data; +} + +template< + typename Pointer, typename Data, typename LambdaCheck + , typename LambdaReturn +> +inline auto popData(Pointer &pointer, os::threads::Spin &spin, Data &data + , LambdaCheck &&check, LambdaReturn &&returnData) noexcept +{ + using DataPointer = flame_ide::RemoveAllTypebegin())>; + using ReturnData = decltype(returnData(*data)); + + os::threads::Locker lock{ spin }; + for (DataPointer &i : *pointer) + { + if (!check(*data, *i)) + continue; + + return returnData(*i); + } + return ReturnData{}; +} + +}}} // namespace flame_ide::handler::network + +#endif // HANDLERINTERNALFUNCTIONS_HPP diff --git a/src/Handler/Network/Handler.cpp b/src/Handler/Network/Handler.cpp new file mode 100644 index 00000000..2b724873 --- /dev/null +++ b/src/Handler/Network/Handler.cpp @@ -0,0 +1,126 @@ +#include + +#include + +#include + +// private functions +namespace flame_ide +{namespace handler +{namespace network +{ +namespace // anonymous +{ + +Handler::Internal *makeInternal() noexcept; +void destroyInternal(Handler::Internal *&internal) noexcept; + +} // namespace anonymous +}}} // namespace flame_ide::handler::network + +// Handler +namespace flame_ide +{namespace handler +{namespace network +{ + +Handler::Handler() noexcept : internal{ makeInternal() } +{} + +Handler::Handler(Handler &&handler) noexcept +{ + operator=(flame_ide::move(handler)); +} + +Handler::~Handler() noexcept +{ + stop(); + + if (!internal) + return; + + destroyInternal(internal); +} + +Handler &Handler::operator=(Handler &&handler) noexcept +{ + internal = handler.internal; + handler.internal = nullptr; + + return *this; +} + +Handler::ServerHandle Handler::push(os::network::UdpServer &&server) noexcept +{ + return internal->push(flame_ide::move(server)); +} + +Handler::CommunicationHandle Handler::push(os::network::UdpClient &&client) noexcept +{ + return internal->push(flame_ide::move(client)); +} + +Handler::ServerHandle Handler::push(os::network::TcpServer &&server) noexcept +{ + return internal->push(flame_ide::move(server)); +} + +Handler::CommunicationHandle Handler::push(os::network::TcpClient &&client) noexcept +{ + return internal->push(flame_ide::move(client)); +} + +os::Status Handler::pop(const ServerHandle &, os::network::UdpServer &/*server*/) noexcept +{ + return os::STATUS_FAILED; +} + +os::Status Handler::pop(const CommunicationHandle &, os::network::UdpClient &/*client*/) noexcept +{ + return os::STATUS_FAILED; +} + +os::Status Handler::pop(const ServerHandle &, os::network::TcpServer &/*server*/) noexcept +{ + return os::STATUS_FAILED; +} + +os::Status Handler::pop(const CommunicationHandle &, os::network::TcpClient &/*client*/) noexcept +{ + return os::STATUS_FAILED; +} + +os::Status Handler::start() noexcept +{ + return os::STATUS_FAILED; +} + +os::Status Handler::stop() noexcept +{ + return os::STATUS_FAILED; +} + +}}} // namespace flame_ide::handler::network + +// private functions +namespace flame_ide +{namespace handler +{namespace network +{ +namespace // anonymous +{ + +using InternalAllocator = templates::allocator::ObjectAllocator; + +Handler::Internal *makeInternal() noexcept +{ + return InternalAllocator{}.construct(); +} + +void destroyInternal(Handler::Internal *&internal) noexcept +{ + InternalAllocator{}.destroy(internal); +} + +} // namespace anonymous +}}} // namespace flame_ide::os::network diff --git a/src/Handler/Network/Headers.cmake b/src/Handler/Network/Headers.cmake new file mode 100644 index 00000000..1b2f9ce4 --- /dev/null +++ b/src/Handler/Network/Headers.cmake @@ -0,0 +1,15 @@ +set (HEADER_LIST + ${CMAKE_CURRENT_SOURCE_DIR}/Functions.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Internal.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Tcp.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/TcpClient.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/TcpConfig.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/TcpServer.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/TcpTypes.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Udp.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/UdpClient.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/UdpConfig.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/UdpServer.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/UdpTypes.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Worker.hpp +) diff --git a/src/Handler/Network/Internal.cpp b/src/Handler/Network/Internal.cpp new file mode 100644 index 00000000..d7390689 --- /dev/null +++ b/src/Handler/Network/Internal.cpp @@ -0,0 +1,438 @@ +#include +#include + +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ +namespace // anonymous +{ + +struct ServerCommunicationData +{ + os::network::UdpServer::WithClient client; + Server::Message *message; + Server::ActualOutput *output; +}; + +struct ClientCommunicationData +{ + os::network::UdpClient *client; + Server::Message *message; + Server::ActualOutput *output; +}; + +} // namespace anonymous +}}}} // namespace flame_ide::os::network::udp + +// private callbacks for UDP - difinition +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace callbacks +{ +namespace // anonymous +{ + +// client + +// TODO +//Types::ssize_t clientBytesToRead(void *data) noexcept; + +// TODO +//Types::ssize_t clientReceive(void *data, templates::Range) noexcept; + +// TODO +//Types::ssize_t clientSend(void *data, templates::Range) noexcept; + +// server + +Types::ssize_t serverBytesToRead(const udp::ServerCommunicationData *message) noexcept; + +Types::ssize_t serverReceive( + udp::ServerCommunicationData *message, templates::Range range +) noexcept; + +Types::ssize_t serverSend( + udp::ServerCommunicationData *data, templates::Range +) noexcept; + +} // namespace anonymous +}}}}} // namespace flame_ide::os::network::udp::callbacks + +// private callbacks for TCP - difinition +namespace flame_ide +{namespace os +{namespace network +{namespace tcp +{namespace callbacks +{ +namespace // anonymous +{ + +// client + +// TODO +//Types::ssize_t clientBytesToRead(void *data) noexcept; + +// TODO +//Types::ssize_t clientReceive(void *data, templates::Range) noexcept; + +// TODO +//Types::ssize_t clientSend(void *data, templates::Range) noexcept; + +// server + +// TODO +//Types::ssize_t serverBytesToRead(void *data) noexcept; + +// TODO +//Types::ssize_t serverReceive(void *data, templates::Range) noexcept; + +// TODO +//Types::ssize_t serverSend(void *data, templates::Range) noexcept; + +} // namespace anonymous +}}}}} // namespace flame_ide::os::network::udp::callbacks + +// Handler::Internal implementation +namespace flame_ide +{namespace handler +{namespace network +{ + +Handler::Internal::Internal() noexcept +{ +// for (auto &i : workers) +// { +// i.set(udp, tcp); +// } +} + +Handler::Internal::~Internal() = default; + +Handler::ServerHandle Handler::Internal::push(os::network::UdpServer &&server) noexcept +{ + udp::Server *data = udp.push(flame_ide::move(server)); + if (!data) + return ServerHandle{}; + + ServerHandle handle; + handle.data = data; + handle.callbackGetCommunicationHandle = getUdpServerHandleCallback(); + return handle; +} + +Handler::CommunicationHandle Handler::Internal::push(os::network::UdpClient &&client) noexcept +{ + udp::Client *data = udp.push(flame_ide::move(client)); + if (!data) + return CommunicationHandle{}; + + Handler::CommunicationHandle handle; +// handle.data[0] = nullptr; // ? +// handle.data[1] = nullptr; // ? +// handle.callbackBytesToRead = udp::callbacks::clientBytesToRead; +// handle.callbackReceive = udp::callbacks::clientReceive; +// handle.callbackSend = udp::callbacks::clientSend; + return handle; +} + +Handler::ServerHandle Handler::Internal::push(os::network::TcpServer &&server) noexcept +{ + if (!tcp.servers) + tcp.servers = decltype(tcp.servers){}; + + tcp::Server *data = nullptr; + for (auto &i : *tcp.servers) + { + if (i->server) + continue; + data = i.pointer(); + break; + } + if (!data) + return {}; + data->server = flame_ide::move(server); + + Handler::ServerHandle handle; + { + static auto callbackGetCommunicationHandle = [](void *data) + -> Handler::CommunicationHandle + { + if (!data) + return {}; + + Handler::CommunicationHandle handle; +// handle.data[0] = nullptr; // ? +// handle.data[1] = nullptr; // ? +// handle.callbackBytesToRead = tcp::callbacks::serverBytesToRead; +// handle.callbackReceive = tcp::callbacks::serverReceive; +// handle.callbackSend = tcp::callbacks::serverSend; + return handle; + }; + handle.callbackGetCommunicationHandle = callbackGetCommunicationHandle; + } + return handle; +} + +Handler::CommunicationHandle Handler::Internal::push(os::network::TcpClient &&/*client*/) noexcept +{ + if (!tcp.clients) + tcp.clients = decltype(tcp.clients){}; + +// tcp::Client *data = nullptr; +// for (auto &i : tcp.clients) +// { +// if (i.client) +// continue; +// data = &i; +// break; +// } +// if (!data) +// return {}; +// data->client = flame_ide::move(client); + + Handler::CommunicationHandle handle; +// handle.data[0] = nullptr; // ? +// handle.data[1] = nullptr; // ? +// handle.callbackBytesToRead = tcp::callbacks::clientBytesToRead; +// handle.callbackReceive = tcp::callbacks::clientReceive; +// handle.callbackSend = tcp::callbacks::clientSend; + return handle; +} + +// private + +Handler::ServerHandle::CallbackGetCommunicationHandle +Handler::Internal::getUdpServerHandleCallback() const noexcept +{ + using CallbackGetUdpCommunicationHandle = + Handler::CommunicationHandle (*)(udp::Server *); + using CallbackGetCommunicationHandle = + Handler::ServerHandle::CallbackGetCommunicationHandle; + + using CallbackBytesToRead = Handler::CommunicationHandle::CallbackBytesToRead; + using CallbackReceive = Handler::CommunicationHandle::CallbackReceive; + using CallbackSend = Handler::CommunicationHandle::CallbackSend; + + static auto callbackGetCommunicationHandle = [](udp::Server *data) + -> Handler::CommunicationHandle + { + if (!data) + return Handler::CommunicationHandle{}; + + udp::Server::Message *inputMessage = nullptr; + { + auto &input = data->input; + os::threads::Locker inputLocker{ input.spin }; + + if (input.first == input.last) + return Handler::CommunicationHandle{}; + + { + auto *message = input.first->pointer(); + os::threads::Locker messageLocker{ message->spin }; + // TODO: а точно ли сообщение готово? + + inputMessage = message; + inputMessage->state = udp::MessageState::PROCESSING; + } + ++input.first; + } + + Handler::CommunicationHandle handle; + handle.object = udp::ServerCommunicationData{ + inputMessage->client, inputMessage, &data->output + }; + handle.callbackBytesToRead = reinterpret_cast( + udp::callbacks::serverBytesToRead + ); + handle.callbackReceive = reinterpret_cast( + udp::callbacks::serverReceive + ); + handle.callbackSend = reinterpret_cast( + udp::callbacks::serverSend + ); + return handle; + }; + + CallbackGetUdpCommunicationHandle callback = callbackGetCommunicationHandle; + return reinterpret_cast(callback); +} + + +}}} // namespace flame_ide::os::network + +// private callbacks for UDP - implementation +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace callbacks +{ +namespace // anonymous +{ + +// client + +// TODO +//Types::ssize_t clientBytesToRead(void */*data*/) noexcept +//{ +// return os::STATUS_FAILED; +//} + +// TODO +//Types::ssize_t clientReceive(void */*data*/, templates::Range) noexcept +//{ +// return os::STATUS_FAILED; +//} + +// TODO +//Types::ssize_t clientSend(void */*data*/, templates::Range) noexcept +//{ +// return os::STATUS_FAILED; +//} + +// server + +Types::ssize_t serverBytesToRead(const udp::ServerCommunicationData *data) noexcept +{ + if (!data || !data->message) + return os::STATUS_FAILED; + + os::threads::Locker{ data->message->spin }; + + return data->message->size; +} + +Types::ssize_t +serverReceive( + udp::ServerCommunicationData *data, templates::Range range +) noexcept +{ + if (!data || !data->message) + return os::STATUS_FAILED; + + Types::ssize_t numberToRead = 0; + auto &message = *data->message; + { + os::threads::Locker{ message.spin }; + + const Types::ssize_t rangeSize = range.end() - range.begin(); + const Types::ssize_t messageSize = message.size; + const Types::ssize_t toRead = (rangeSize < messageSize) + ? rangeSize + : messageSize; + + auto begin = range.begin(); + for (Types::ssize_t i = 0; i < toRead; ++i, ++begin) + { + *begin = message.bytes[i]; + } + message.size = 0; + message.client = decltype(message.client){}; + message.state = MessageState::EMPTY; + + numberToRead = toRead; + } + return numberToRead; +} + +Types::ssize_t +serverSend( + udp::ServerCommunicationData *data, templates::Range range +) noexcept +{ + if (!data || !data->output) + return os::STATUS_FAILED; + + auto &output = *data->output; + Server::Message *message = nullptr; + { + os::threads::Locker locker{ output.spin }; + message = output.last->pointer(); + { + os::threads::Locker locker{ message->spin }; + message->state = MessageState::PROCESSING; + } + ++output.last; + } + + const Types::ssize_t rangeSize = range.end() - range.begin(); + { + os::threads::Locker locker{ message->spin }; + message->size = rangeSize; + message->client = data->client; + + auto begin = range.begin(); + for (Types::ssize_t i = 0; i < rangeSize; ++i, ++begin) + { + message->bytes[i] = *begin; + } + + message->state = MessageState::READY; + } + return rangeSize; +} + +} // namespace anonymous +}}}}} // namespace flame_ide::os::network::udp::callbacks + +// private callbacks for TCP - implementation +namespace flame_ide +{namespace os +{namespace network +{namespace tcp +{namespace callbacks +{ +namespace // anonymous +{ + +// client + +// TODO +//Types::ssize_t clientBytesToRead(void */*data*/) noexcept +//{ +// return os::STATUS_FAILED; +//} + +// TODO +//Types::ssize_t clientReceive(void */*data*/, templates::Range) noexcept +//{ +// return os::STATUS_FAILED; +//} + +// TODO +//Types::ssize_t clientSend(void */*data*/, templates::Range) noexcept +//{ +// return os::STATUS_FAILED; +//} + +// server + +// TODO +//Types::ssize_t serverBytesToRead(void */*data*/) noexcept +//{ +// return os::STATUS_FAILED; +//} + +// TODO +//Types::ssize_t serverReceive(void */*data*/, templates::Range) noexcept +//{ +// return os::STATUS_FAILED; +//} + +// TODO +//Types::ssize_t serverSend(void */*data*/, templates::Range) noexcept +//{ +// return os::STATUS_FAILED; +//} + +} // namespace anonymous +}}}}} // namespace flame_ide::os::network::udp::callbacks diff --git a/src/Handler/Network/Internal.hpp b/src/Handler/Network/Internal.hpp new file mode 100644 index 00000000..89fa9481 --- /dev/null +++ b/src/Handler/Network/Internal.hpp @@ -0,0 +1,44 @@ +#ifndef HANDLERINTERNAL_HPP +#define HANDLERINTERNAL_HPP + +#include + +#include +#include + +#include +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{ + +class Handler::Internal +{ +public: + Internal() noexcept; + ~Internal() noexcept; + + Handler::ServerHandle push(os::network::UdpServer &&server) noexcept; + Handler::CommunicationHandle push(os::network::UdpClient &&client) noexcept; + + Handler::ServerHandle push(os::network::TcpServer &&server) noexcept; + Handler::CommunicationHandle push(os::network::TcpClient &&client) noexcept; + +private: + Handler::ServerHandle::CallbackGetCommunicationHandle + getUdpServerHandleCallback() const noexcept; + +private: + udp::Udp udp; + tcp::Tcp tcp; + Workers workers; + + os::async::network::Registrar registration; +}; + +}}} // namespace flame_ide::handler::network + +#endif // HANDLERINTERNAL_HPP diff --git a/src/Handler/Network/ServerHandle.cpp b/src/Handler/Network/ServerHandle.cpp new file mode 100644 index 00000000..6e44e835 --- /dev/null +++ b/src/Handler/Network/ServerHandle.cpp @@ -0,0 +1,18 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{ + +Handler::ServerHandle::operator bool() const noexcept +{ + return data && callbackGetCommunicationHandle; +} + +Handler::CommunicationHandle Handler::ServerHandle::getCommunicationHandle() noexcept +{ + return callbackGetCommunicationHandle(data); +} + +}}} // namespace flame_ide::handler::network diff --git a/src/Handler/Network/Sources.cmake b/src/Handler/Network/Sources.cmake new file mode 100644 index 00000000..46e3e35a --- /dev/null +++ b/src/Handler/Network/Sources.cmake @@ -0,0 +1,9 @@ +set (SOURCE_LIST + ${CMAKE_CURRENT_SOURCE_DIR}/CommunicationHandle.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Handler.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Internal.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ServerHandle.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Tcp.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Udp.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Worker.cpp +) diff --git a/src/Handler/Network/Tcp.cpp b/src/Handler/Network/Tcp.cpp new file mode 100644 index 00000000..68d0392f --- /dev/null +++ b/src/Handler/Network/Tcp.cpp @@ -0,0 +1,78 @@ +#include +#include + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tcp +{ + +Server *Tcp::push(os::network::TcpServer &&server) noexcept +{ + if (!initPointer(servers, serversSpin)) + return nullptr; + + return pushData(servers, serversSpin + , /* check = */ [](const Server &i) -> const auto & + { + return i.server; + } + , /* assignTo = */ [&server](Server &handle) + { + handle.server = flame_ide::move(server); + } + ); +} + +os::network::TcpServer Tcp::pop(Server *server) noexcept +{ + if (!server) + return {}; + + return popData(servers, serversSpin, server + , /* check = */ [](const Server &input, const Server &internal) -> bool + { + if (!(input.server) || !(internal.server)) + return false; + + return input.server->native().descriptor + == internal.server->native().descriptor; + } + , /* returnData = */ [](Server &internal) -> os::network::TcpServer + { + os::network::TcpServer server = flame_ide::move(*internal.server); + return server; + } + ); +} + +Client *Tcp::push(os::network::TcpClient &&/*client*/) noexcept +{ +// if (!initPointer(clients, clientsSpin)) + return nullptr; + +// return assignData(clients, clientsSpin +// , /* check = */ [](const Client &i) -> const auto & +// { +// return i.client; +// } +// , /* assignTo = */ [&client](Client &handle) +// { +// handle.client = flame_ide::move(client); +// } +// ); +} + +os::network::TcpClient Tcp::pop(Client */*client*/) noexcept +{ +// if (!client) + return {}; +// if (!isPointer(clients, clientsSpin)) +// return; +// +// flame_ide::unused(client); +} + +}}}} // namespace flame_ide::handler::network::tcp diff --git a/src/Handler/Network/Tcp.hpp b/src/Handler/Network/Tcp.hpp new file mode 100644 index 00000000..d5de158c --- /dev/null +++ b/src/Handler/Network/Tcp.hpp @@ -0,0 +1,73 @@ +#ifndef HANDLERINTERNALTCP_HPP +#define HANDLERINTERNALTCP_HPP + +#include +#include + +#include +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tcp +{ + +// WARNING: using UniquePointer because malloc doen't work with big sizes +using Servers = ChooseType< + Constants::NUMBER_OF_SERVERS != 0 + , templates::StaticArray< + templates::UniquePointer, Constants::NUMBER_OF_SERVERS + > + , ::flame_ide::Empty +>::Type; + +// WARNING: using UniquePointer because malloc doen't work with big sizes +using Clients = ::flame_ide::ChooseType< + Constants::NUMBER_OF_CLIENTS != 0 + , templates::StaticArray< + templates::UniquePointer, Constants::NUMBER_OF_CLIENTS + > + , ::flame_ide::Empty +>::Type; + +using SocketDescriptors = ChooseType< + Constants::NUMBER_OF_SOCKETS != 0 + , templates::StaticArray< + os::SocketDescriptor, Constants::NUMBER_OF_SOCKETS + > + , ::flame_ide::Empty +>::Type; + +// WARNING: using UniquePointer because malloc doen't work with big sizes +using AcceptedConnections = templates::StaticArray< + templates::UniquePointer + , Constants::NUMBER_OF_SERVERS_CONNECTIONS +>; + +struct Tcp +{ +public: + Server *push(os::network::TcpServer &&server) noexcept; + os::network::TcpServer pop(Server *server) noexcept; + + Client *push(os::network::TcpClient &&client) noexcept; + os::network::TcpClient pop(Client *client) noexcept; + +public: + templates::UniquePointer servers = decltype(servers)::makeEmpty(); + templates::UniquePointer acceptedConnctions + /* = decltype(acceptedConnctions)::makeEmpty()*/; + + templates::UniquePointer clients/* = decltype(clients)::makeEmpty()*/; + SocketDescriptors socketDescriptors; + + os::threads::Spin serversSpin; + os::threads::Spin acceptedConnctionsSpin; + os::threads::Spin clientsSpin; +}; + +}}}} // namespace flame_ide::handler::network::tcp + +#endif // HANDLERINTERNALTCP_HPP diff --git a/src/Handler/Network/TcpClient.hpp b/src/Handler/Network/TcpClient.hpp new file mode 100644 index 00000000..8e586670 --- /dev/null +++ b/src/Handler/Network/TcpClient.hpp @@ -0,0 +1,58 @@ +#ifndef HANDLERINTERNALTCPCLIENT_HPP +#define HANDLERINTERNALTCPCLIENT_HPP + +#include +#include +#include + +#include + +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tcp +{ + +class Client +{ +public: + static_assert( + Constants::CLIENT_INPUT_BUFFER_SIZE != 0 + , "Input buffer size for TCP clients is 0" + ); + static_assert( + Constants::CLIENT_OUTPUT_BUFFER_SIZE != 0 + , "Output buffer size for TCP clients is 0" + ); + +public: + using Optional = ::flame_ide::templates::Optional; + + using InputBuffer = ::flame_ide::templates::CircularArray< + ::flame_ide::byte_t, Constants::CLIENT_INPUT_BUFFER_SIZE + >; + using OutputBuffer = ::flame_ide::templates::CircularArray< + ::flame_ide::byte_t, Constants::CLIENT_OUTPUT_BUFFER_SIZE + >; + using TempBuffer = ::flame_ide::templates::Array< + ::flame_ide::byte_t + , ( + Constants::CLIENT_INPUT_BUFFER_SIZE + > Constants::CLIENT_OUTPUT_BUFFER_SIZE + ) ? Constants::CLIENT_INPUT_BUFFER_SIZE : Constants::CLIENT_OUTPUT_BUFFER_SIZE + >; + +public: + templates::UniquePointer input; + templates::UniquePointer output; + templates::UniquePointer tmp; + + Optional client; +}; + +}}}} // namespace flame_ide::handler::network::tcp + +#endif // HANDLERINTERNALTCPCLIENT_HPP diff --git a/src/Handler/Network/TcpConfig.hpp b/src/Handler/Network/TcpConfig.hpp new file mode 100644 index 00000000..c95657df --- /dev/null +++ b/src/Handler/Network/TcpConfig.hpp @@ -0,0 +1,42 @@ +#ifndef HANDLERINTERNALTCPCONFIG_HPP +#define HANDLERINTERNALTCPCONFIG_HPP + +#include +#include +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tcp +{ + +struct Constants: ::flame_ide::NonCreational +{ + static constexpr Types::size_t NUMBER_OF_SERVERS = + generated::network::Config::TCP_SERVERS; + static constexpr Types::size_t NUMBER_OF_SERVERS_CONNECTIONS = + generated::network::Config::TCP_SERVER_BACKLOG; + + static constexpr Types::size_t NUMBER_OF_CLIENTS = + generated::network::Config::TCP_CLIENTS; + + static constexpr Types::size_t SERVER_INPUT_BUFFER_SIZE = + generated::network::Config::TCP_SERVER_INPUT_BUFFER_SIZE; + static constexpr Types::size_t SERVER_OUTPUT_BUFFER_SIZE = + generated::network::Config::TCP_SERVER_OUTPUT_BUFFER_SIZE; + + static constexpr Types::size_t CLIENT_INPUT_BUFFER_SIZE = + generated::network::Config::TCP_CLIENT_INPUT_BUFFER_SIZE; + static constexpr Types::size_t CLIENT_OUTPUT_BUFFER_SIZE = + generated::network::Config::TCP_CLIENT_OUTPUT_BUFFER_SIZE; + + static constexpr Types::size_t NUMBER_OF_SOCKETS = + Constants::NUMBER_OF_SERVERS * (1 + Constants::NUMBER_OF_SERVERS_CONNECTIONS) + + Constants::NUMBER_OF_CLIENTS; +}; + +}}}} // namespace flame_ide::handler::network::tcp + +#endif // HANDLERINTERNALTCPCONFIG_HPP diff --git a/src/Handler/Network/TcpServer.hpp b/src/Handler/Network/TcpServer.hpp new file mode 100644 index 00000000..40d00c92 --- /dev/null +++ b/src/Handler/Network/TcpServer.hpp @@ -0,0 +1,67 @@ +#ifndef HANDLERINTERNALTCPSERVER_HPP +#define HANDLERINTERNALTCPSERVER_HPP + +#include +#include +#include + +#include + +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tcp +{ + +class Server +{ +public: + static_assert( + Constants::SERVER_INPUT_BUFFER_SIZE != 0 + , "Input buffer size for TCP servers is 0" + ); + static_assert( + Constants::SERVER_OUTPUT_BUFFER_SIZE != 0 + , "Output buffer size for TCP servers is 0" + ); + static_assert( + Constants::NUMBER_OF_SERVERS_CONNECTIONS != 0 + , "TCP server's backlog is 0" + ); + +public: + using InputBuffer = Buffer; + using OutputBuffer = Buffer; + using TempBuffer = TemporaryBuffer< + Constants::SERVER_INPUT_BUFFER_SIZE, Constants::SERVER_OUTPUT_BUFFER_SIZE + >; + + using Optional = templates::Optional; + using OptionalConnection = templates::Optional< + flame_ide::os::network::TcpServer::WithClient + >; + +public: + struct Connection + { + templates::UniquePointer input; + templates::UniquePointer output; + templates::UniquePointer tmp; + + OptionalConnection client; + }; + using Connections = ::flame_ide::templates::StaticArray< + Connection, Constants::NUMBER_OF_SERVERS_CONNECTIONS + >; + +public: + Optional server; + Connections connections; +}; + +}}}} // namespace flame_ide::handler::network::tcp + +#endif // HANDLERINTERNALTCPSERVER_HPP diff --git a/src/Handler/Network/TcpTypes.hpp b/src/Handler/Network/TcpTypes.hpp new file mode 100644 index 00000000..8ffa93e7 --- /dev/null +++ b/src/Handler/Network/TcpTypes.hpp @@ -0,0 +1,48 @@ +#ifndef HANDLERINTERNALTCPTYPES_HPP +#define HANDLERINTERNALTCPTYPES_HPP + +#include +#include +#include + +#include +#include + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tcp +{ + +template +using Buffer = templates::CircularArray; + +template +using TemporaryBuffer = templates::Array< + byte_t + , ChooseType< + (BUFFER_SIZE1 > BUFFER_SIZE2) + , IntegralConstant + , IntegralConstant + >::Type::VALUE +>; + +struct AcceptedConnection +{ + constexpr AcceptedConnection() = default; + constexpr bool operator==(AcceptedConnection connection) const noexcept + { + return server == connection.server && client == connection.client; + } + + os::SocketAddressIn address = {}; + os::SocketDescriptor server = os::SOCKET_INVALID.descriptor; + os::SocketDescriptor client = os::SOCKET_INVALID.descriptor; + +}; + +}}}} // namespace flame_ide::handler::network::tcp + +#endif // HANDLERINTERNALTCPTYPES_HPP diff --git a/src/Handler/Network/Udp.cpp b/src/Handler/Network/Udp.cpp new file mode 100644 index 00000000..6c2b85b8 --- /dev/null +++ b/src/Handler/Network/Udp.cpp @@ -0,0 +1,78 @@ +#include +#include + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +Server *Udp::push(os::network::UdpServer &&server) noexcept +{ + if (!initPointer(servers, serversSpin)) + return nullptr; + + return pushData(servers, serversSpin + , /* check = */ [](const Server &i) -> bool + { + return (i.server); + } + , /* assignTo = */ [&server](Server &handle) + { + handle.server = flame_ide::move(server); + } + ); +} + +os::network::UdpServer Udp::pop(Server *server) noexcept +{ + if (!server) + return {}; + + return popData(servers, serversSpin, server + , /* check = */ [](const Server &input, const Server &internal) -> bool + { + if (!(input.server) || !(internal.server)) + return false; + + return input.server->native().descriptor + == internal.server->native().descriptor; + } + , /* returnData = */ [](Server &internal) -> os::network::UdpServer + { + os::network::UdpServer server = flame_ide::move(*internal.server); + return server; + } + ); +} + +Client *Udp::push(os::network::UdpClient &&/*client*/) noexcept +{ +// if (!initPointer(clients, clientsSpin)) + return nullptr; + +// return pushData(clients, clientsSpin +// , /* check = */ [](const Client &i) -> const auto & +// { +// return i.client; +// } +// , /* assignTo = */ [&client](Client &handle) +// { +// handle.client = flame_ide::move(client); +// } +// ); +} + +os::network::UdpClient Udp::pop(Client *client) noexcept +{ + if (!client) + return {}; + + return {}; + +// flame_ide::unused(client); +} + +}}}} // namespace flame_ide::handler::network::udp diff --git a/src/Handler/Network/Udp.hpp b/src/Handler/Network/Udp.hpp new file mode 100644 index 00000000..c6b3d512 --- /dev/null +++ b/src/Handler/Network/Udp.hpp @@ -0,0 +1,52 @@ +#ifndef HANDLERINTERNALUDP_HPP +#define HANDLERINTERNALUDP_HPP + +#include +#include + +#include +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +// WARNING: using UniquePointer because malloc doen't work with big sizes +using Servers = ::flame_ide::templates::StaticArray< + templates::UniquePointer, Constants::NUMBER_OF_SERVERS +>; + +// WARNING: using UniquePointer because malloc doen't work with big sizes +using Clients = ::flame_ide::templates::StaticArray< + templates::UniquePointer, Constants::NUMBER_OF_CLIENTS +>; + +using SocketDescriptors = ::flame_ide::templates::StaticArray< + ::flame_ide::os::SocketDescriptor + , Constants::NUMBER_OF_SERVERS + Constants::NUMBER_OF_CLIENTS +>; + +class Udp +{ +public: + Server *push(os::network::UdpServer &&server) noexcept; + os::network::UdpServer pop(Server *server) noexcept; + + Client *push(os::network::UdpClient &&client) noexcept; + os::network::UdpClient pop(Client *client) noexcept; + +public: + templates::UniquePointer servers = decltype(servers)::makeEmpty(); + templates::UniquePointer clients/* = decltype(clients)::makeEmpty()*/; + SocketDescriptors socketDescriptors; + + os::threads::Spin serversSpin; + os::threads::Spin clientsSpin; +}; + +}}}} // namespace flame_ide::handler::network::udp + +#endif // HANDLERINTERNALUDP_HPP diff --git a/src/Handler/Network/UdpClient.hpp b/src/Handler/Network/UdpClient.hpp new file mode 100644 index 00000000..b2d003bd --- /dev/null +++ b/src/Handler/Network/UdpClient.hpp @@ -0,0 +1,45 @@ +#ifndef HANDLERINTERNALUDPCLIENT_HPP +#define HANDLERINTERNALUDPCLIENT_HPP + +#include +#include + +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +class Client +{ +public: + struct Message + { + ::flame_ide::templates::StaticArray< + ::flame_ide::byte_t, Constants::MESSAGE_SIZE + > bytes; + Types::ssize_t size = 0; + MessageState state = MessageState::EMPTY; + mutable os::threads::Spin spin; + }; + +public: + using Optional = ::flame_ide::templates::Optional< + ::flame_ide::os::network::UdpClient + >; + + using ActualInput = ActualData; + using ActualOutput = ActualData; + +public: + Optional client; + ActualInput input; + ActualOutput output; +}; + +}}}} // namespace flame_ide::handler::network::udp + +#endif // HANDLERINTERNALUDPCLIENT_HPP diff --git a/src/Handler/Network/UdpConfig.hpp b/src/Handler/Network/UdpConfig.hpp new file mode 100644 index 00000000..faa7e414 --- /dev/null +++ b/src/Handler/Network/UdpConfig.hpp @@ -0,0 +1,42 @@ +#ifndef HANDLERINTERNALUDPCONFIG_HPP +#define HANDLERINTERNALUDPCONFIG_HPP + +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +struct Constants: ::flame_ide::NonCreational +{ + static constexpr Types::size_t NUMBER_OF_SERVERS = + generated::network::Config::UDP_SERVERS; + static constexpr Types::size_t NUMBER_OF_CLIENTS = + generated::network::Config::UDP_CLIENTS; + + static constexpr Types::size_t MESSAGE_SIZE = + generated::network::Config::UDP_MESSAGE_SIZE; + + static constexpr Types::size_t SERVER_INPUT_QUEUE_SIZE = + generated::network::Config::UDP_SERVER_INPUT_QUEUE_SIZE; + static constexpr Types::size_t SERVER_OUTPUT_QUEUE_SIZE = + generated::network::Config::UDP_SERVER_OUTPUT_QUEUE_SIZE; + + static constexpr Types::size_t CLIENT_INPUT_QUEUE_SIZE = + generated::network::Config::UDP_CLIENT_INPUT_QUEUE_SIZE; + static constexpr Types::size_t CLIENT_OUTPUT_QUEUE_SIZE = + generated::network::Config::UDP_CLIENT_OUTPUT_QUEUE_SIZE; + +private: + static_assert( + MESSAGE_SIZE < ::flame_ide::Constants::MAX_UDP_IPV4_MESSAGE_SIZE + , "UDP IPv4 message is too big. Max size is 65507" + ); +}; + +}}}} // namespace flame_ide::handler::network::udp + +#endif // HANDLERINTERNALUDPCONFIG_HPP diff --git a/src/Handler/Network/UdpServer.hpp b/src/Handler/Network/UdpServer.hpp new file mode 100644 index 00000000..65e14c50 --- /dev/null +++ b/src/Handler/Network/UdpServer.hpp @@ -0,0 +1,47 @@ +#ifndef HANDLERINTERNALUDPSERVER_HPP +#define HANDLERINTERNALUDPSERVER_HPP + +#include +#include + +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +class Server +{ +public: + struct Message + { + mutable os::threads::Spin spin; + + Types::ssize_t size = 0; + flame_ide::os::network::UdpServer::WithClient client; + flame_ide::templates::StaticArray< + flame_ide::byte_t, Constants::MESSAGE_SIZE + > bytes; + MessageState state = MessageState::EMPTY; + }; + +public: + using Optional = flame_ide::templates::Optional< + flame_ide::os::network::UdpServer + >; + + using ActualInput = ActualData; + using ActualOutput = ActualData; + +public: + Optional server; + ActualInput input; + ActualOutput output; +}; + +}}}} // namespace flame_ide::handler::network::udp + +#endif // HANDLERINTERNALUDPSERVER_HPP diff --git a/src/Handler/Network/UdpTypes.hpp b/src/Handler/Network/UdpTypes.hpp new file mode 100644 index 00000000..a7e1fe38 --- /dev/null +++ b/src/Handler/Network/UdpTypes.hpp @@ -0,0 +1,47 @@ +#ifndef HANDLERINTERNALUDPTYPES_HPP +#define HANDLERINTERNALUDPTYPES_HPP + +#include + +#include +#include +#include + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +enum class MessageState +{ + EMPTY + , PROCESSING + , READY +}; + +template +struct ActualData +{ + using Messages = flame_ide::templates::StaticArray< + flame_ide::templates::UniquePointer, SIZE + >; + using MessagesCircularIterator = + flame_ide::templates::defaults::CircularForwardIterator< + typename Messages::Iterator + >; + + Messages messages; + MessagesCircularIterator first = MessagesCircularIterator{ + messages.begin() + , templates::makeRange(messages.begin(), messages.end()) + }; + MessagesCircularIterator last = first; + mutable os::threads::Spin spin; +}; + +}}}} // namespace flame_ide::handler::network::udp + +#endif // HANDLERINTERNALUDPTYPES_HPP diff --git a/src/Handler/Network/Worker.cpp b/src/Handler/Network/Worker.cpp new file mode 100644 index 00000000..655de304 --- /dev/null +++ b/src/Handler/Network/Worker.cpp @@ -0,0 +1,58 @@ +#include + +#include + +namespace flame_ide +{namespace handler +{namespace network +{ + +void Worker::init(os::threads::ConditionVariable &initCondvar) noexcept +{ + condvar = &initCondvar; +} + +void Worker::body() noexcept +{ + while (!condvar->tryWait()) + {} +} + +}}} // namespace flame_ide::handler::network + +namespace flame_ide +{namespace handler +{namespace network +{ + +Workers::Workers() noexcept +{ + flame_ide::templates::foreachChangable( + workers + , [this](Worker &i) { i.init(condvar); } + ); +} + +Workers::~Workers() noexcept +{ + stop(); +} + +void Workers::start() +{ + flame_ide::templates::foreachChangable( + workers + , [](Worker &i) { i.run(); } + ); +} + +void Workers::stop() +{ + condvar.notify(); + flame_ide::templates::foreachChangable( + workers + , [](Worker &i) { i.join(); } + ); +} + +}}} // namespace flame_ide::handler::network diff --git a/src/Handler/Network/Worker.hpp b/src/Handler/Network/Worker.hpp new file mode 100644 index 00000000..b96b1aa5 --- /dev/null +++ b/src/Handler/Network/Worker.hpp @@ -0,0 +1,62 @@ +#ifndef WORKER_HPP +#define WORKER_HPP + +#include + +#include +#include +#include + +#include + +namespace flame_ide +{namespace handler +{namespace network +{ + +class Worker: public os::threads::ThreadCrtp +{ + using Parent = os::threads::ThreadCrtp; + friend Parent; + +public: // + void init(os::threads::ConditionVariable &initCondvar) noexcept; + +private: // os::threads::ThreadCrtp + void body() noexcept; + +private: + os::threads::ConditionVariable *condvar = nullptr; +}; + +}}} // namespace flame_ide::handler::network + +namespace flame_ide +{namespace handler +{namespace network +{ + +class Workers +{ +public: + Workers() noexcept; + ~Workers() noexcept; + + void start(); + void stop(); + +private: + void join() noexcept; + +private: + os::threads::Mutex mutex; + os::threads::ConditionVariable condvar{ mutex }; + + templates::StaticArray< + Worker, generated::network::Config::HANDLER_NUMBER_OF_WORKERS + > workers; +}; + +}}} // namespace flame_ide::handler::network + +#endif // WORKER_HPP diff --git a/src/Handler/Tests/CMakeLists.txt b/src/Handler/Tests/CMakeLists.txt new file mode 100644 index 00000000..6ab2f3c1 --- /dev/null +++ b/src/Handler/Tests/CMakeLists.txt @@ -0,0 +1,113 @@ +cmake_minimum_required(VERSION 3.14) + +if(NOT FLAME_TESTING) + return() +endif() + +set(NAME "Handler.Tests") +set(NAME_ALIAS "Handler::Tests") +set(INCLUDE_PATHS + ${FLAME_INCLUDE_PATH} + ${FLAME_INCLUDE_TEST_PATH} +) +get_sources(FILE_LIST) +list(FILTER FILE_LIST EXCLUDE REGEX "main.cpp") + +set(DEPENDENCY_HEADER_TARGETS + # "${FLAME_NAMESPACE}::Handler::Headers" + "${FLAME_NAMESPACE}::Handler::Network::Headers" +) + +set(STATIC_ALIAS_NAME "${FLAME_NAMESPACE}::${NAME_ALIAS}::Static") +set(SHARED_ALIAS_NAME "${FLAME_NAMESPACE}::${NAME_ALIAS}::Shared") + +set(DEPEND_OBJECTS + "${FLAME_NAMESPACE}::Handler::Network::Test::Object" +) +set(INDEPEND_OBJECTS + "${FLAME_NAMESPACE}::Handler::Network::Test::Object::Independ" +) + +set(MAIN_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp") +if(FLAME_MAKE_STATIC) + set(MAKE_STATIC MAKE_STATIC) + flame_compile_binary( + NAME "${NAME}.static" + SOURCE_LIST "${MAIN_SOURCE}" + #INSTALL_PATH + INCLUDE_PATHS "${INCLUDE_PATHS}" + #HEADER_LIST + #COMMPILE_FLAGS + #LINK_FLAGS" + DEPENDENCY_TARGET_LIST "${STATIC_ALIAS_NAME}" + DEFINES "${SHARED_LIBRARY_DIR_DEFINE}" + + NO_RTTI + EXCEPTIONS + + TEST + TEST_ARGUMENTS "" + ) +endif() +if(FLAME_MAKE_SHARED) + set(MAKE_SHARED MAKE_SHARED) + flame_compile_binary( + NAME "${NAME}.shared" + SOURCE_LIST "${MAIN_SOURCE}" + #INSTALL_PATH + INCLUDE_PATHS "${INCLUDE_PATHS}" + #HEADER_LIST + #COMMPILE_FLAGS" + #LINK_FLAGS" + DEPENDENCY_TARGET_LIST "${STATIC_ALIAS_NAME}" + DEFINES "${SHARED_LIBRARY_DIR_DEFINE}" + + NO_RTTI + EXCEPTIONS + + TEST + TEST_ARGUMENTS "" + ) +endif() + +set(DEPENDENCY_TARGETS_FOR_STATIC +# "${FLAME_NAMESPACE}::Handler::Static" + "${FLAME_NAMESPACE}::Handler::Network::Object" + "${FLAME_NAMESPACE}::Os::Static" + "${DEPEND_OBJECTS}" +) +set(DEPENDENCY_TARGETS_FOR_SHARED +# "${FLAME_NAMESPACE}::Handler::Shared" + "${FLAME_NAMESPACE}::Handler::Network::Object::Independ" + "${FLAME_NAMESPACE}::Os::Shared" + "${INDEPEND_OBJECTS}" +) +flame_compile_library( + NAME "${NAME}" + SOURCE_LIST "${FILE_LIST}" + INCLUDE_PATHS "${INCLUDE_PATHS}" + DEPENDENCY_HEADER_TARGETS "${DEPENDENCY_HEADER_TARGETS}" + DEPENDENCY_TARGETS_FOR_STATIC "${DEPENDENCY_TARGETS_FOR_STATIC}" + DEPENDENCY_TARGETS_FOR_SHARED "${DEPENDENCY_TARGETS_FOR_SHARED}" + OBJECT_ALIAS_NAME + "${FLAME_NAMESPACE}::${NAME_ALIAS}::Object" + INDEPENDENT_OBJECT_ALIAS_NAME + "${FLAME_NAMESPACE}::${NAME_ALIAS}::Object::Independ" + STATIC_ALIAS_NAME "${STATIC_ALIAS_NAME}" + SHARED_ALIAS_NAME "${SHARED_ALIAS_NAME}" + + DEFINES "${SHARED_LIBRARY_DIR_DEFINE}" + + NO_RTTI + EXCEPTIONS + + ${MAKE_STATIC} + ${MAKE_SHARED} +) + +set(SOURCE_MODULES + ${CMAKE_CURRENT_LIST_DIR}/Network +) +foreach(module ${SOURCE_MODULES}) + add_subdirectory(${module}) +endforeach() diff --git a/src/Handler/Tests/Network/CMakeLists.txt b/src/Handler/Tests/Network/CMakeLists.txt new file mode 100644 index 00000000..a4c087fd --- /dev/null +++ b/src/Handler/Tests/Network/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.14) + +if(NOT FLAME_TESTING) + return() +endif() + +set(NAME "Handler.Network.Test") +set(NAME_ALIAS "Handler::Network::Test") + +get_sources(FILE_LIST) + +set(DEPENDENCY_HEADER_TARGETS + "${FLAME_NAMESPACE}::Handler::Network::Headers" +) + +flame_compile_library( + NAME "${NAME}" + SOURCE_LIST "${FILE_LIST}" + INCLUDE_PATHS "${INCLUDE_PATHS}" "${CMAKE_BINARY_DIR}/generated/include" + DEPENDENCY_HEADER_TARGETS "${DEPENDENCY_HEADER_TARGETS}" + + OBJECT_ALIAS_NAME + "${FLAME_NAMESPACE}::${NAME_ALIAS}::Object" + INDEPENDENT_OBJECT_ALIAS_NAME + "${FLAME_NAMESPACE}::${NAME_ALIAS}::Object::Independ" + + NO_RTTI + EXCEPTIONS +) diff --git a/src/Handler/Tests/Network/HandlerTest.cpp b/src/Handler/Tests/Network/HandlerTest.cpp new file mode 100644 index 00000000..eaf22e97 --- /dev/null +++ b/src/Handler/Tests/Network/HandlerTest.cpp @@ -0,0 +1,20 @@ +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +HandlerTest::HandlerTest() : ::AbstractTest("Handler") +{} + +HandlerTest::~HandlerTest() = default; + +int HandlerTest::vStart() +{ + return ResultType::SUCCESS; +} + +}}}} // namespace flame_ide::handler::network::tests diff --git a/src/Handler/Tests/Network/HandlerTest.hpp b/src/Handler/Tests/Network/HandlerTest.hpp new file mode 100644 index 00000000..a67fa3d5 --- /dev/null +++ b/src/Handler/Tests/Network/HandlerTest.hpp @@ -0,0 +1,24 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_HANDLERTEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_HANDLERTEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +class HandlerTest: public ::AbstractTest +{ +public: + HandlerTest(); + virtual ~HandlerTest(); + +private: + virtual int vStart(); +}; + +}}}} // namespace flame_ide::handler::network::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_HANDLERTEST_HPP diff --git a/src/Handler/Tests/Network/Headers.cmake b/src/Handler/Tests/Network/Headers.cmake new file mode 100644 index 00000000..0c46a4da --- /dev/null +++ b/src/Handler/Tests/Network/Headers.cmake @@ -0,0 +1,5 @@ +set (HEADER_LIST + ${CMAKE_CURRENT_SOURCE_DIR}/InternalTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/TcpTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/UdpTest.hpp +) diff --git a/src/Handler/Tests/Network/InternalTest.cpp b/src/Handler/Tests/Network/InternalTest.cpp new file mode 100644 index 00000000..424ea0b5 --- /dev/null +++ b/src/Handler/Tests/Network/InternalTest.cpp @@ -0,0 +1,20 @@ +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +InternalTest::InternalTest() : ::AbstractTest("Internal") +{} + +InternalTest::~InternalTest() = default; + +int InternalTest::vStart() +{ + return ResultType::SUCCESS; +} + +}}}} // namespace flame_ide::handler::network::tests diff --git a/src/Handler/Tests/Network/InternalTest.hpp b/src/Handler/Tests/Network/InternalTest.hpp new file mode 100644 index 00000000..a1e66e8d --- /dev/null +++ b/src/Handler/Tests/Network/InternalTest.hpp @@ -0,0 +1,24 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_INTERNALTEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_INTERNALTEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +class InternalTest: public ::AbstractTest +{ +public: + InternalTest(); + virtual ~InternalTest(); + +private: + virtual int vStart(); +}; + +}}}} // namespace flame_ide::handler::network::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_INTERNALTEST_HPP diff --git a/src/Handler/Tests/Network/Sources.cmake b/src/Handler/Tests/Network/Sources.cmake new file mode 100644 index 00000000..971e7bf9 --- /dev/null +++ b/src/Handler/Tests/Network/Sources.cmake @@ -0,0 +1,12 @@ +set (SOURCE_LIST + ${CMAKE_CURRENT_SOURCE_DIR}/HandlerTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/HandlerTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/InternalTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/InternalTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/TcpTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/TcpTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/UdpTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/UdpTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/WorkerTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/WorkerTest.hpp +) diff --git a/src/Handler/Tests/Network/TcpTest.cpp b/src/Handler/Tests/Network/TcpTest.cpp new file mode 100644 index 00000000..cf5d6d83 --- /dev/null +++ b/src/Handler/Tests/Network/TcpTest.cpp @@ -0,0 +1,52 @@ +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +TcpTest::TcpTest() : ::AbstractTest("Tcp") +{} + +TcpTest::~TcpTest() = default; + +int TcpTest::vStart() +{ + CHECK_RESULT_SUCCESS(doTestCase( + "initialization" + , [this]() { return init(); } + + )); + CHECK_RESULT_SUCCESS(doTestCase( + "server push-pop" + , [this]() { return serverPushPop(); } + + )); + return ResultType::SUCCESS; +} + +int TcpTest::init() +{ + tcp::Tcp tcp; + return ResultType::SUCCESS; +} + +int TcpTest::serverPushPop() +{ + tcp::Tcp tcp; + os::network::TcpServer server{ 65001 }; + + const os::Socket expectedSocket = server.native(); + + auto handle = tcp.push(flame_ide::move(server)); + IN_CASE_CHECK(handle != nullptr); + + auto resultServer = tcp.pop(handle); + IN_CASE_CHECK(expectedSocket.descriptor == resultServer.native().descriptor); + + return ResultType::SUCCESS; +} + +}}}} // namespace flame_ide::handler::network::tests diff --git a/src/Handler/Tests/Network/TcpTest.hpp b/src/Handler/Tests/Network/TcpTest.hpp new file mode 100644 index 00000000..104e9097 --- /dev/null +++ b/src/Handler/Tests/Network/TcpTest.hpp @@ -0,0 +1,28 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_TCPTEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_TCPTEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +class TcpTest: public ::AbstractTest +{ +public: + TcpTest(); + virtual ~TcpTest(); + +private: + virtual int vStart(); + +private: + int init(); + int serverPushPop(); +}; + +}}}} // namespace flame_ide::handler::network::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_TCPTEST_HPP diff --git a/src/Handler/Tests/Network/UdpTest.cpp b/src/Handler/Tests/Network/UdpTest.cpp new file mode 100644 index 00000000..0e356da0 --- /dev/null +++ b/src/Handler/Tests/Network/UdpTest.cpp @@ -0,0 +1,52 @@ +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +UdpTest::UdpTest() : ::AbstractTest("Udp") +{} + +UdpTest::~UdpTest() = default; + +int UdpTest::vStart() +{ + CHECK_RESULT_SUCCESS(doTestCase( + "initialization" + , [this]() { return init(); } + + )); + CHECK_RESULT_SUCCESS(doTestCase( + "server push-pop" + , [this]() { return serverPushPop(); } + + )); + return ResultType::SUCCESS; +} + +int UdpTest::init() +{ + udp::Udp udp; + return ResultType::SUCCESS; +} + +int UdpTest::serverPushPop() +{ + udp::Udp udp; + os::network::UdpServer server{ 65001 }; + + const os::Socket expectedSocket = server.native(); + + auto handle = udp.push(flame_ide::move(server)); + IN_CASE_CHECK(handle != nullptr); + + auto resultServer = udp.pop(handle); + IN_CASE_CHECK(expectedSocket.descriptor == resultServer.native().descriptor); + + return ResultType::SUCCESS; +} + +}}}} // namespace flame_ide::handler::network::tests diff --git a/src/Handler/Tests/Network/UdpTest.hpp b/src/Handler/Tests/Network/UdpTest.hpp new file mode 100644 index 00000000..8583bcb3 --- /dev/null +++ b/src/Handler/Tests/Network/UdpTest.hpp @@ -0,0 +1,28 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_UDPTEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_UDPTEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +class UdpTest: public ::AbstractTest +{ +public: + UdpTest(); + virtual ~UdpTest(); + +private: + virtual int vStart(); + +private: + int init(); + int serverPushPop(); +}; + +}}}} // namespace flame_ide::handler::network::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_UDPTEST_HPP diff --git a/src/Handler/Tests/Network/WorkerTest.cpp b/src/Handler/Tests/Network/WorkerTest.cpp new file mode 100644 index 00000000..a3dded3b --- /dev/null +++ b/src/Handler/Tests/Network/WorkerTest.cpp @@ -0,0 +1,20 @@ +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +WorkerTest::WorkerTest() : ::AbstractTest("Worker") +{} + +WorkerTest::~WorkerTest() = default; + +int WorkerTest::vStart() +{ + return ResultType::SUCCESS; +} + +}}}} // namespace flame_ide::handler::network::tests diff --git a/src/Handler/Tests/Network/WorkerTest.hpp b/src/Handler/Tests/Network/WorkerTest.hpp new file mode 100644 index 00000000..d7a96e1a --- /dev/null +++ b/src/Handler/Tests/Network/WorkerTest.hpp @@ -0,0 +1,24 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_WORKERTEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_WORKERTEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +class WorkerTest: public ::AbstractTest +{ +public: + WorkerTest(); + virtual ~WorkerTest(); + +private: + virtual int vStart(); +}; + +}}}} // namespace flame_ide::handler::network::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_WORKERTEST_HPP diff --git a/src/Handler/Tests/Sources.cmake b/src/Handler/Tests/Sources.cmake new file mode 100644 index 00000000..c7f678a7 --- /dev/null +++ b/src/Handler/Tests/Sources.cmake @@ -0,0 +1,5 @@ +set (SOURCE_LIST + ${CMAKE_CURRENT_SOURCE_DIR}/TestAggregator.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/TestAggregator.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp +) diff --git a/src/Handler/Tests/TestAggregator.cpp b/src/Handler/Tests/TestAggregator.cpp new file mode 100644 index 00000000..68146c29 --- /dev/null +++ b/src/Handler/Tests/TestAggregator.cpp @@ -0,0 +1,23 @@ +#include + +#include +#include +#include +#include +#include + +namespace flame_ide +{namespace handler +{namespace tests +{ + +TestAggregator::TestAggregator() : ::TestAggregator("Handler") +{ + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); +} + +}}} // namespace flame_ide::handler::tests diff --git a/src/Handler/Tests/TestAggregator.hpp b/src/Handler/Tests/TestAggregator.hpp new file mode 100644 index 00000000..4921a684 --- /dev/null +++ b/src/Handler/Tests/TestAggregator.hpp @@ -0,0 +1,20 @@ +#ifndef FLAMEIDE_SRC_HANDLER_TESTS_TESTAGGREGATOR_HPP +#define FLAMEIDE_SRC_HANDLER_TESTS_TESTAGGREGATOR_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace tests +{ + +class TestAggregator: public ::TestAggregator +{ +public: + TestAggregator(); + virtual ~TestAggregator() = default; +}; + +}}} // namespace flame_ide::handler::tests + +#endif // FLAMEIDE_SRC_HANDLER_TESTS_TESTAGGREGATOR_HPP diff --git a/src/Handler/Tests/main.cpp b/src/Handler/Tests/main.cpp new file mode 100644 index 00000000..9f7d3bd8 --- /dev/null +++ b/src/Handler/Tests/main.cpp @@ -0,0 +1,6 @@ +#include + +int main() +{ + return flame_ide::handler::tests::TestAggregator().start(); +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 080a255e..b2e06ca9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -11,6 +11,7 @@ set(TEST_MODULES ${FLAME_SOURCE_SUBMODLUES_PATH}/Common/Tests ${FLAME_SOURCE_SUBMODLUES_PATH}/Os/Tests ${FLAME_SOURCE_SUBMODLUES_PATH}/Crypto/Pkcs11/Tests + ${FLAME_SOURCE_SUBMODLUES_PATH}/Handler/Tests ) foreach(module ${TEST_MODULES}) From 56e49c1972efd73a474b4c3718369ce66a19e0cb Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Tue, 17 Sep 2024 04:18:12 +0500 Subject: [PATCH 04/37] Move files and fix headers --- include/FlameIDE/Handler/Network/Handler.hpp | 116 +++-- src/Handler/Network/CMakeLists.txt | 24 + src/Handler/Network/CommunicationHandle.cpp | 8 +- src/Handler/Network/Handler.cpp | 36 +- src/Handler/Network/Headers.cmake | 10 - src/Handler/Network/Internal.cpp | 432 ++---------------- src/Handler/Network/Internal.hpp | 93 +++- src/Handler/Network/ServerHandle.cpp | 6 +- src/Handler/Network/Sources.cmake | 2 - src/Handler/Network/Tcp/CMakeLists.txt | 24 + .../Network/{TcpClient.hpp => Tcp/Client.hpp} | 8 +- .../Network/{TcpConfig.hpp => Tcp/Config.hpp} | 0 src/Handler/Network/Tcp/Headers.cmake | 8 + src/Handler/Network/Tcp/InternalData.cpp | 50 ++ src/Handler/Network/Tcp/InternalData.hpp | 38 ++ .../Network/{TcpServer.hpp => Tcp/Server.hpp} | 8 +- src/Handler/Network/Tcp/Sources.cmake | 4 + src/Handler/Network/{ => Tcp}/Tcp.cpp | 2 +- src/Handler/Network/{ => Tcp}/Tcp.hpp | 6 +- .../Network/{TcpTypes.hpp => Tcp/Types.hpp} | 0 src/Handler/Network/Udp/CMakeLists.txt | 24 + .../Network/{UdpClient.hpp => Udp/Client.hpp} | 4 +- .../Network/{UdpConfig.hpp => Udp/Config.hpp} | 0 src/Handler/Network/Udp/Headers.cmake | 8 + src/Handler/Network/Udp/InternalData.cpp | 114 +++++ src/Handler/Network/Udp/InternalData.hpp | 61 +++ .../Network/{UdpServer.hpp => Udp/Server.hpp} | 4 +- src/Handler/Network/Udp/Sources.cmake | 4 + .../Network/{UdpTypes.hpp => Udp/Types.hpp} | 0 src/Handler/Network/{ => Udp}/Udp.cpp | 2 +- src/Handler/Network/{ => Udp}/Udp.hpp | 6 +- src/Handler/Network/Worker.cpp | 28 +- src/Handler/Network/Worker.hpp | 17 +- src/Handler/Tests/CMakeLists.txt | 6 +- src/Handler/Tests/Network/TcpTest.cpp | 2 +- src/Handler/Tests/Network/UdpTest.cpp | 2 +- 36 files changed, 639 insertions(+), 518 deletions(-) create mode 100644 src/Handler/Network/Tcp/CMakeLists.txt rename src/Handler/Network/{TcpClient.hpp => Tcp/Client.hpp} (92%) rename src/Handler/Network/{TcpConfig.hpp => Tcp/Config.hpp} (100%) create mode 100644 src/Handler/Network/Tcp/Headers.cmake create mode 100644 src/Handler/Network/Tcp/InternalData.cpp create mode 100644 src/Handler/Network/Tcp/InternalData.hpp rename src/Handler/Network/{TcpServer.hpp => Tcp/Server.hpp} (92%) create mode 100644 src/Handler/Network/Tcp/Sources.cmake rename src/Handler/Network/{ => Tcp}/Tcp.cpp (96%) rename src/Handler/Network/{ => Tcp}/Tcp.hpp (91%) rename src/Handler/Network/{TcpTypes.hpp => Tcp/Types.hpp} (100%) create mode 100644 src/Handler/Network/Udp/CMakeLists.txt rename src/Handler/Network/{UdpClient.hpp => Udp/Client.hpp} (88%) rename src/Handler/Network/{UdpConfig.hpp => Udp/Config.hpp} (100%) create mode 100644 src/Handler/Network/Udp/Headers.cmake create mode 100644 src/Handler/Network/Udp/InternalData.cpp create mode 100644 src/Handler/Network/Udp/InternalData.hpp rename src/Handler/Network/{UdpServer.hpp => Udp/Server.hpp} (88%) create mode 100644 src/Handler/Network/Udp/Sources.cmake rename src/Handler/Network/{UdpTypes.hpp => Udp/Types.hpp} (100%) rename src/Handler/Network/{ => Udp}/Udp.cpp (96%) rename src/Handler/Network/{ => Udp}/Udp.hpp (88%) diff --git a/include/FlameIDE/Handler/Network/Handler.hpp b/include/FlameIDE/Handler/Network/Handler.hpp index f6940278..cd7265e2 100644 --- a/include/FlameIDE/Handler/Network/Handler.hpp +++ b/include/FlameIDE/Handler/Network/Handler.hpp @@ -1,7 +1,7 @@ #ifndef FLAMEIDE_OS_NETWORK_HANDLER_HPP #define FLAMEIDE_OS_NETWORK_HANDLER_HPP -#include +#include #include #include @@ -13,8 +13,6 @@ namespace flame_ide {namespace network { -class NetworkBase; - class UdpServer; class UdpClient; @@ -35,34 +33,78 @@ class Handler { public: class Internal; + class Tcp; + class Udp; public: class ServerHandle; - class CommunicationHandle; + class SessionHandle; + + using ExpectedServerHandle = Expected; + using ExpectedSessionHandle = Expected; + + using ExpectedUdpServer = Expected; + using ExpectedUdpClient = Expected; + + using ExpectedTcpServer = Expected; + using ExpectedTcpClient = Expected; public: Handler() noexcept; Handler(const Handler &) noexcept = delete; Handler(Handler &&handler) noexcept; - ~Handler() noexcept; Handler &operator=(const Handler &) noexcept = delete; - Handler &operator=(Handler &&handler) noexcept; - - ServerHandle push(os::network::UdpServer &&server) noexcept; - CommunicationHandle push(os::network::UdpClient &&client) noexcept; - ServerHandle push(os::network::TcpServer &&server) noexcept; - CommunicationHandle push(os::network::TcpClient &&client) noexcept; - - os::Status pop(const ServerHandle &, os::network::UdpServer &server) noexcept; - os::Status pop(const CommunicationHandle &, os::network::UdpClient &client) noexcept; - - os::Status pop(const ServerHandle &, os::network::TcpServer &server) noexcept; - os::Status pop(const CommunicationHandle &, os::network::TcpClient &client) noexcept; + Handler &operator=(Handler &&handler) noexcept; + /// @brief pushUdp + /// @param server + /// @return + ExpectedServerHandle pushUdp(os::network::UdpServer &&server) noexcept; + + /// @brief pushUdp + /// @param client + /// @return + ExpectedSessionHandle pushUdp(os::network::UdpClient &&client) noexcept; + + /// @brief pushTcp + /// @param server + /// @return + ExpectedServerHandle pushTcp(os::network::TcpServer &&server) noexcept; + + /// @brief pushTcp + /// @param client + /// @return + ExpectedSessionHandle pushTcp(os::network::TcpClient &&client) noexcept; + + /// @brief pop + /// @param server + /// @return + ExpectedUdpServer popUdp(ServerHandle &handle) noexcept; + + /// @brief pop + /// @param client + /// @return + ExpectedUdpClient popUdp(SessionHandle &handle) noexcept; + + /// @brief pop + /// @param server + /// @return + ExpectedTcpServer popTcp(ServerHandle &handle) noexcept; + + /// @brief pop + /// @param client + /// @return + ExpectedTcpClient popTcp(SessionHandle &handle) noexcept; + + /// @brief start + /// @return os::Status start() noexcept; + + /// @brief stop + /// @return os::Status stop() noexcept; private: @@ -89,45 +131,65 @@ class Handler::ServerHandle operator bool() const noexcept; - Handler::CommunicationHandle getCommunicationHandle() noexcept; + /// + /// @brief getSessionHandle + /// @return + /// + Handler::SessionHandle getSessionHandle() noexcept; private: friend class Handler::Internal; + friend class Handler::Udp; + friend class Handler::Tcp; -private: - using CallbackGetCommunicationHandle = Handler::CommunicationHandle (*)(void *); + using CallbackGetSessionHandle = Handler::SessionHandle (*)(void *); private: void *data = nullptr; - CallbackGetCommunicationHandle callbackGetCommunicationHandle = nullptr; + CallbackGetSessionHandle callbackGetSessionHandle = nullptr; }; }}} // namespace flame_ide::handler::network -// Handler::CommunicationHandle +// Handler::SessionHandle namespace flame_ide {namespace handler {namespace network { -class Handler::CommunicationHandle +class Handler::SessionHandle { public: - CommunicationHandle() noexcept = default; - CommunicationHandle(CommunicationHandle &&) noexcept = default; - ~CommunicationHandle() noexcept = default; + SessionHandle() noexcept = default; + SessionHandle(SessionHandle &&) noexcept = default; + ~SessionHandle() noexcept = default; - CommunicationHandle &operator=(CommunicationHandle &&) noexcept = default; + SessionHandle &operator=(SessionHandle &&) noexcept = default; operator bool() const noexcept; + /// + /// @brief bytesToRead + /// @return + /// Types::ssize_t bytesToRead() const noexcept; + /// + /// @brief receive + /// @return + /// Types::ssize_t receive(flame_ide::templates::Range) noexcept; + + /// + /// @brief send + /// @return + /// Types::ssize_t send(flame_ide::templates::Range) noexcept; private: friend class Handler::Internal; + friend class Handler::Udp; + friend class Handler::Tcp; friend class Handler::ServerHandle; private: diff --git a/src/Handler/Network/CMakeLists.txt b/src/Handler/Network/CMakeLists.txt index bff07354..765598f1 100644 --- a/src/Handler/Network/CMakeLists.txt +++ b/src/Handler/Network/CMakeLists.txt @@ -8,12 +8,23 @@ set(DEPENDENCY_HEADER_TARGETS ${FLAME_NAMESPACE}::Handler::Network::Headers ) set(DEPENDENCY_TARGETS_FOR_STATIC + "${FLAME_NAMESPACE}::${NAME_ALIAS}::Udp::Object" + "${FLAME_NAMESPACE}::${NAME_ALIAS}::Tcp::Object" "${FLAME_NAMESPACE}::Os::Static" ) set(DEPENDENCY_TARGETS_FOR_SHARED + "${FLAME_NAMESPACE}::${NAME_ALIAS}::Udp::Object::Independ" + "${FLAME_NAMESPACE}::${NAME_ALIAS}::Tcp::Object::Independ" "${FLAME_NAMESPACE}::Os::Shared" ) +if(FLAME_MAKE_STATIC) + set(MAKE_STATIC MAKE_STATIC) +endif() +if(FLAME_MAKE_SHARED) + set(MAKE_SHARED MAKE_SHARED) +endif() + get_sources(FILE_LIST) flame_compile_library( NAME "${NAME}" @@ -26,7 +37,20 @@ flame_compile_library( "${FLAME_NAMESPACE}::${NAME_ALIAS}::Object" INDEPENDENT_OBJECT_ALIAS_NAME "${FLAME_NAMESPACE}::${NAME_ALIAS}::Object::Independ" + STATIC_ALIAS_NAME "${FLAME_NAMESPACE}::${NAME_ALIAS}::Static" + SHARED_ALIAS_NAME "${FLAME_NAMESPACE}::${NAME_ALIAS}::Shared" NO_RTTI NO_EXCEPTIONS + + ${MAKE_STATIC} + ${MAKE_SHARED} +) + +set(SOURCE_MODULES + ${CMAKE_CURRENT_LIST_DIR}/Udp + ${CMAKE_CURRENT_LIST_DIR}/Tcp ) +foreach(module ${SOURCE_MODULES}) + add_subdirectory(${module}) +endforeach() diff --git a/src/Handler/Network/CommunicationHandle.cpp b/src/Handler/Network/CommunicationHandle.cpp index 8d6f9639..89f04e08 100644 --- a/src/Handler/Network/CommunicationHandle.cpp +++ b/src/Handler/Network/CommunicationHandle.cpp @@ -5,24 +5,24 @@ namespace flame_ide {namespace network { -Handler::CommunicationHandle::operator bool() const noexcept +Handler::SessionHandle::operator bool() const noexcept { return object && callbackBytesToRead && callbackReceive && callbackSend; } -Types::ssize_t Handler::CommunicationHandle::bytesToRead() const noexcept +Types::ssize_t Handler::SessionHandle::bytesToRead() const noexcept { return callbackBytesToRead(&object); } Types::ssize_t -Handler::CommunicationHandle::receive(templates::Range bytes) noexcept +Handler::SessionHandle::receive(templates::Range bytes) noexcept { return callbackReceive(&object, bytes); } Types::ssize_t -Handler::CommunicationHandle::send(templates::Range bytes) noexcept +Handler::SessionHandle::send(templates::Range bytes) noexcept { return callbackSend(&object, bytes); } diff --git a/src/Handler/Network/Handler.cpp b/src/Handler/Network/Handler.cpp index 2b724873..a192e8e5 100644 --- a/src/Handler/Network/Handler.cpp +++ b/src/Handler/Network/Handler.cpp @@ -50,54 +50,54 @@ Handler &Handler::operator=(Handler &&handler) noexcept return *this; } -Handler::ServerHandle Handler::push(os::network::UdpServer &&server) noexcept +Handler::ExpectedServerHandle Handler::pushUdp(os::network::UdpServer &&server) noexcept { - return internal->push(flame_ide::move(server)); + return internal->udp().push(flame_ide::move(server)); } -Handler::CommunicationHandle Handler::push(os::network::UdpClient &&client) noexcept +Handler::ExpectedSessionHandle Handler::pushUdp(os::network::UdpClient &&client) noexcept { - return internal->push(flame_ide::move(client)); + return internal->udp().push(flame_ide::move(client)); } -Handler::ServerHandle Handler::push(os::network::TcpServer &&server) noexcept +Handler::ExpectedServerHandle Handler::pushTcp(os::network::TcpServer &&server) noexcept { - return internal->push(flame_ide::move(server)); + return internal->tcp().push(flame_ide::move(server)); } -Handler::CommunicationHandle Handler::push(os::network::TcpClient &&client) noexcept +Handler::ExpectedSessionHandle Handler::pushTcp(os::network::TcpClient &&client) noexcept { - return internal->push(flame_ide::move(client)); + return internal->tcp().push(flame_ide::move(client)); } -os::Status Handler::pop(const ServerHandle &, os::network::UdpServer &/*server*/) noexcept +Handler::ExpectedUdpServer Handler::popUdp(ServerHandle &handle) noexcept { - return os::STATUS_FAILED; + return internal->udp().pop(handle); } -os::Status Handler::pop(const CommunicationHandle &, os::network::UdpClient &/*client*/) noexcept +Handler::ExpectedUdpClient Handler::popUdp(SessionHandle &handle) noexcept { - return os::STATUS_FAILED; + return internal->udp().pop(handle); } -os::Status Handler::pop(const ServerHandle &, os::network::TcpServer &/*server*/) noexcept +Handler::ExpectedTcpServer Handler::popTcp(ServerHandle &handle) noexcept { - return os::STATUS_FAILED; + return internal->tcp().pop(handle); } -os::Status Handler::pop(const CommunicationHandle &, os::network::TcpClient &/*client*/) noexcept +Handler::ExpectedTcpClient Handler::popTcp(SessionHandle &handle) noexcept { - return os::STATUS_FAILED; + return internal->tcp().pop(handle); } os::Status Handler::start() noexcept { - return os::STATUS_FAILED; + return internal->start(); } os::Status Handler::stop() noexcept { - return os::STATUS_FAILED; + return internal->stop(); } }}} // namespace flame_ide::handler::network diff --git a/src/Handler/Network/Headers.cmake b/src/Handler/Network/Headers.cmake index 1b2f9ce4..addd311d 100644 --- a/src/Handler/Network/Headers.cmake +++ b/src/Handler/Network/Headers.cmake @@ -1,15 +1,5 @@ set (HEADER_LIST ${CMAKE_CURRENT_SOURCE_DIR}/Functions.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Internal.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/Tcp.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/TcpClient.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/TcpConfig.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/TcpServer.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/TcpTypes.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/Udp.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/UdpClient.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/UdpConfig.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/UdpServer.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/UdpTypes.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Worker.hpp ) diff --git a/src/Handler/Network/Internal.cpp b/src/Handler/Network/Internal.cpp index d7390689..23e4accb 100644 --- a/src/Handler/Network/Internal.cpp +++ b/src/Handler/Network/Internal.cpp @@ -1,5 +1,6 @@ #include -#include +#include +#include #include #include @@ -7,432 +8,91 @@ namespace flame_ide {namespace handler {namespace network -{namespace udp { -namespace // anonymous -{ - -struct ServerCommunicationData -{ - os::network::UdpServer::WithClient client; - Server::Message *message; - Server::ActualOutput *output; -}; -struct ClientCommunicationData -{ - os::network::UdpClient *client; - Server::Message *message; - Server::ActualOutput *output; -}; - -} // namespace anonymous -}}}} // namespace flame_ide::os::network::udp +// Hanler::Udp -// private callbacks for UDP - difinition -namespace flame_ide -{namespace handler -{namespace network -{namespace udp -{namespace callbacks -{ -namespace // anonymous +Handler::ExpectedServerHandle Handler::Udp::push(os::network::UdpServer &&server) noexcept { + flame_ide::unused(server); + return { os::STATUS_FAILED }; +} -// client - -// TODO -//Types::ssize_t clientBytesToRead(void *data) noexcept; - -// TODO -//Types::ssize_t clientReceive(void *data, templates::Range) noexcept; - -// TODO -//Types::ssize_t clientSend(void *data, templates::Range) noexcept; - -// server - -Types::ssize_t serverBytesToRead(const udp::ServerCommunicationData *message) noexcept; - -Types::ssize_t serverReceive( - udp::ServerCommunicationData *message, templates::Range range -) noexcept; - -Types::ssize_t serverSend( - udp::ServerCommunicationData *data, templates::Range -) noexcept; - -} // namespace anonymous -}}}}} // namespace flame_ide::os::network::udp::callbacks - -// private callbacks for TCP - difinition -namespace flame_ide -{namespace os -{namespace network -{namespace tcp -{namespace callbacks +Handler::ExpectedSessionHandle Handler::Udp::push(os::network::UdpClient &&client) noexcept { -namespace // anonymous -{ - -// client - -// TODO -//Types::ssize_t clientBytesToRead(void *data) noexcept; - -// TODO -//Types::ssize_t clientReceive(void *data, templates::Range) noexcept; - -// TODO -//Types::ssize_t clientSend(void *data, templates::Range) noexcept; - -// server - -// TODO -//Types::ssize_t serverBytesToRead(void *data) noexcept; - -// TODO -//Types::ssize_t serverReceive(void *data, templates::Range) noexcept; - -// TODO -//Types::ssize_t serverSend(void *data, templates::Range) noexcept; - -} // namespace anonymous -}}}}} // namespace flame_ide::os::network::udp::callbacks + flame_ide::unused(client); + return { os::STATUS_FAILED }; +} -// Handler::Internal implementation -namespace flame_ide -{namespace handler -{namespace network +Handler::ExpectedUdpServer Handler::Udp::pop(Handler::ServerHandle &handle) { + flame_ide::unused(handle); + return { os::STATUS_FAILED }; +} -Handler::Internal::Internal() noexcept +Handler::ExpectedUdpClient Handler::Udp::pop(Handler::SessionHandle &handle) { -// for (auto &i : workers) -// { -// i.set(udp, tcp); -// } + flame_ide::unused(handle); + return { os::STATUS_FAILED }; } -Handler::Internal::~Internal() = default; +// Handler::Tcp -Handler::ServerHandle Handler::Internal::push(os::network::UdpServer &&server) noexcept +Handler::ExpectedServerHandle Handler::Tcp::push(os::network::TcpServer &&server) noexcept { - udp::Server *data = udp.push(flame_ide::move(server)); - if (!data) - return ServerHandle{}; - - ServerHandle handle; - handle.data = data; - handle.callbackGetCommunicationHandle = getUdpServerHandleCallback(); - return handle; + flame_ide::unused(server); + return { os::STATUS_FAILED }; } -Handler::CommunicationHandle Handler::Internal::push(os::network::UdpClient &&client) noexcept +Handler::ExpectedSessionHandle Handler::Tcp::push(os::network::TcpClient &&client) noexcept { - udp::Client *data = udp.push(flame_ide::move(client)); - if (!data) - return CommunicationHandle{}; - - Handler::CommunicationHandle handle; -// handle.data[0] = nullptr; // ? -// handle.data[1] = nullptr; // ? -// handle.callbackBytesToRead = udp::callbacks::clientBytesToRead; -// handle.callbackReceive = udp::callbacks::clientReceive; -// handle.callbackSend = udp::callbacks::clientSend; - return handle; + flame_ide::unused(client); + return { os::STATUS_FAILED }; } -Handler::ServerHandle Handler::Internal::push(os::network::TcpServer &&server) noexcept +Handler::ExpectedTcpServer Handler::Tcp::pop(Handler::ServerHandle &handle) { - if (!tcp.servers) - tcp.servers = decltype(tcp.servers){}; - - tcp::Server *data = nullptr; - for (auto &i : *tcp.servers) - { - if (i->server) - continue; - data = i.pointer(); - break; - } - if (!data) - return {}; - data->server = flame_ide::move(server); - - Handler::ServerHandle handle; - { - static auto callbackGetCommunicationHandle = [](void *data) - -> Handler::CommunicationHandle - { - if (!data) - return {}; - - Handler::CommunicationHandle handle; -// handle.data[0] = nullptr; // ? -// handle.data[1] = nullptr; // ? -// handle.callbackBytesToRead = tcp::callbacks::serverBytesToRead; -// handle.callbackReceive = tcp::callbacks::serverReceive; -// handle.callbackSend = tcp::callbacks::serverSend; - return handle; - }; - handle.callbackGetCommunicationHandle = callbackGetCommunicationHandle; - } - return handle; + flame_ide::unused(handle); + return { os::STATUS_FAILED }; } -Handler::CommunicationHandle Handler::Internal::push(os::network::TcpClient &&/*client*/) noexcept +Handler::ExpectedTcpClient Handler::Tcp::pop(Handler::SessionHandle &handle) { - if (!tcp.clients) - tcp.clients = decltype(tcp.clients){}; - -// tcp::Client *data = nullptr; -// for (auto &i : tcp.clients) -// { -// if (i.client) -// continue; -// data = &i; -// break; -// } -// if (!data) -// return {}; -// data->client = flame_ide::move(client); - - Handler::CommunicationHandle handle; -// handle.data[0] = nullptr; // ? -// handle.data[1] = nullptr; // ? -// handle.callbackBytesToRead = tcp::callbacks::clientBytesToRead; -// handle.callbackReceive = tcp::callbacks::clientReceive; -// handle.callbackSend = tcp::callbacks::clientSend; - return handle; + flame_ide::unused(handle); + return { os::STATUS_FAILED }; } -// private +}}} // namespace flame_ide::handler::network -Handler::ServerHandle::CallbackGetCommunicationHandle -Handler::Internal::getUdpServerHandleCallback() const noexcept -{ - using CallbackGetUdpCommunicationHandle = - Handler::CommunicationHandle (*)(udp::Server *); - using CallbackGetCommunicationHandle = - Handler::ServerHandle::CallbackGetCommunicationHandle; - - using CallbackBytesToRead = Handler::CommunicationHandle::CallbackBytesToRead; - using CallbackReceive = Handler::CommunicationHandle::CallbackReceive; - using CallbackSend = Handler::CommunicationHandle::CallbackSend; - - static auto callbackGetCommunicationHandle = [](udp::Server *data) - -> Handler::CommunicationHandle - { - if (!data) - return Handler::CommunicationHandle{}; - - udp::Server::Message *inputMessage = nullptr; - { - auto &input = data->input; - os::threads::Locker inputLocker{ input.spin }; - - if (input.first == input.last) - return Handler::CommunicationHandle{}; - - { - auto *message = input.first->pointer(); - os::threads::Locker messageLocker{ message->spin }; - // TODO: а точно ли сообщение готово? - - inputMessage = message; - inputMessage->state = udp::MessageState::PROCESSING; - } - ++input.first; - } - - Handler::CommunicationHandle handle; - handle.object = udp::ServerCommunicationData{ - inputMessage->client, inputMessage, &data->output - }; - handle.callbackBytesToRead = reinterpret_cast( - udp::callbacks::serverBytesToRead - ); - handle.callbackReceive = reinterpret_cast( - udp::callbacks::serverReceive - ); - handle.callbackSend = reinterpret_cast( - udp::callbacks::serverSend - ); - return handle; - }; - - CallbackGetUdpCommunicationHandle callback = callbackGetCommunicationHandle; - return reinterpret_cast(callback); -} - - -}}} // namespace flame_ide::os::network - -// private callbacks for UDP - implementation +// Handler::Internal implementation namespace flame_ide {namespace handler {namespace network -{namespace udp -{namespace callbacks { -namespace // anonymous -{ - -// client - -// TODO -//Types::ssize_t clientBytesToRead(void */*data*/) noexcept -//{ -// return os::STATUS_FAILED; -//} -// TODO -//Types::ssize_t clientReceive(void */*data*/, templates::Range) noexcept -//{ -// return os::STATUS_FAILED; -//} - -// TODO -//Types::ssize_t clientSend(void */*data*/, templates::Range) noexcept -//{ -// return os::STATUS_FAILED; -//} +Handler::Internal::Internal() noexcept +{} -// server +Handler::Internal::~Internal() = default; -Types::ssize_t serverBytesToRead(const udp::ServerCommunicationData *data) noexcept +Handler::Udp &Handler::Internal::udp() noexcept { - if (!data || !data->message) - return os::STATUS_FAILED; - - os::threads::Locker{ data->message->spin }; - - return data->message->size; + return udpData; } -Types::ssize_t -serverReceive( - udp::ServerCommunicationData *data, templates::Range range -) noexcept +Handler::Tcp &Handler::Internal::tcp() noexcept { - if (!data || !data->message) - return os::STATUS_FAILED; - - Types::ssize_t numberToRead = 0; - auto &message = *data->message; - { - os::threads::Locker{ message.spin }; - - const Types::ssize_t rangeSize = range.end() - range.begin(); - const Types::ssize_t messageSize = message.size; - const Types::ssize_t toRead = (rangeSize < messageSize) - ? rangeSize - : messageSize; - - auto begin = range.begin(); - for (Types::ssize_t i = 0; i < toRead; ++i, ++begin) - { - *begin = message.bytes[i]; - } - message.size = 0; - message.client = decltype(message.client){}; - message.state = MessageState::EMPTY; - - numberToRead = toRead; - } - return numberToRead; + return tcpData; } -Types::ssize_t -serverSend( - udp::ServerCommunicationData *data, templates::Range range -) noexcept +os::Status Handler::Internal::start() noexcept { - if (!data || !data->output) - return os::STATUS_FAILED; - - auto &output = *data->output; - Server::Message *message = nullptr; - { - os::threads::Locker locker{ output.spin }; - message = output.last->pointer(); - { - os::threads::Locker locker{ message->spin }; - message->state = MessageState::PROCESSING; - } - ++output.last; - } - - const Types::ssize_t rangeSize = range.end() - range.begin(); - { - os::threads::Locker locker{ message->spin }; - message->size = rangeSize; - message->client = data->client; - - auto begin = range.begin(); - for (Types::ssize_t i = 0; i < rangeSize; ++i, ++begin) - { - message->bytes[i] = *begin; - } - - message->state = MessageState::READY; - } - return rangeSize; + return workers.start(); } -} // namespace anonymous -}}}}} // namespace flame_ide::os::network::udp::callbacks - -// private callbacks for TCP - implementation -namespace flame_ide -{namespace os -{namespace network -{namespace tcp -{namespace callbacks +os::Status Handler::Internal::stop() noexcept { -namespace // anonymous -{ - -// client - -// TODO -//Types::ssize_t clientBytesToRead(void */*data*/) noexcept -//{ -// return os::STATUS_FAILED; -//} - -// TODO -//Types::ssize_t clientReceive(void */*data*/, templates::Range) noexcept -//{ -// return os::STATUS_FAILED; -//} - -// TODO -//Types::ssize_t clientSend(void */*data*/, templates::Range) noexcept -//{ -// return os::STATUS_FAILED; -//} - -// server - -// TODO -//Types::ssize_t serverBytesToRead(void */*data*/) noexcept -//{ -// return os::STATUS_FAILED; -//} - -// TODO -//Types::ssize_t serverReceive(void */*data*/, templates::Range) noexcept -//{ -// return os::STATUS_FAILED; -//} - -// TODO -//Types::ssize_t serverSend(void */*data*/, templates::Range) noexcept -//{ -// return os::STATUS_FAILED; -//} + return workers.stop(); +} -} // namespace anonymous -}}}}} // namespace flame_ide::os::network::udp::callbacks +}}} // namespace flame_ide::os::network diff --git a/src/Handler/Network/Internal.hpp b/src/Handler/Network/Internal.hpp index 89fa9481..e137b8dd 100644 --- a/src/Handler/Network/Internal.hpp +++ b/src/Handler/Network/Internal.hpp @@ -6,8 +6,8 @@ #include #include -#include -#include +#include +#include #include namespace flame_ide @@ -15,28 +15,95 @@ namespace flame_ide {namespace network { +class Handler::Udp +{ +public: + using CallbackGetSessionHandle = Handler::ServerHandle::CallbackGetSessionHandle; + +public: + // TODO + Handler::ExpectedServerHandle push(os::network::UdpServer &&server) noexcept; + // TODO + Handler::ExpectedSessionHandle push(os::network::UdpClient &&client) noexcept; + + // TODO + Handler::ExpectedUdpServer pop(Handler::ServerHandle &handle); + // TODO + Handler::ExpectedUdpClient pop(Handler::SessionHandle &handle); + + /// @brief serverHandleCallback + /// @return + // TODO + CallbackGetSessionHandle serverHandleCallback() const noexcept; + +private: + udp::Udp udp; +}; + +class Handler::Tcp +{ +public: + using CallbackGetSessionHandle = Handler::ServerHandle::CallbackGetSessionHandle; + +public: + // TODO + Handler::ExpectedServerHandle push(os::network::TcpServer &&server) noexcept; + // TODO + Handler::ExpectedSessionHandle push(os::network::TcpClient &&client) noexcept; + + // TODO + Handler::ExpectedTcpServer pop(Handler::ServerHandle &handle); + // TODO + Handler::ExpectedTcpClient pop(Handler::SessionHandle &handle); + + /// @brief serverHandleCallback + /// @return + // TODO + CallbackGetSessionHandle serverHandleCallback() const noexcept; + +private: + tcp::Tcp tcp; +}; + +}}} // namespace flame_ide::handler::network + +namespace flame_ide +{namespace handler +{namespace network +{ + class Handler::Internal { public: Internal() noexcept; ~Internal() noexcept; - Handler::ServerHandle push(os::network::UdpServer &&server) noexcept; - Handler::CommunicationHandle push(os::network::UdpClient &&client) noexcept; + /// @brief pushUdp + /// @param server + /// @return + Udp &udp() noexcept; - Handler::ServerHandle push(os::network::TcpServer &&server) noexcept; - Handler::CommunicationHandle push(os::network::TcpClient &&client) noexcept; + /// @brief pushUdp + /// @param server + /// @return + Tcp &tcp() noexcept; -private: - Handler::ServerHandle::CallbackGetCommunicationHandle - getUdpServerHandleCallback() const noexcept; + /// @brief start + /// @return + // TODO + os::Status start() noexcept; + + /// @brief stop + /// @return + // TODO + os::Status stop() noexcept; private: - udp::Udp udp; - tcp::Tcp tcp; - Workers workers; + Handler::Udp udpData; ///< + Handler::Tcp tcpData; ///< + Workers workers; ///< - os::async::network::Registrar registration; + os::async::network::Registrar registration; ///< }; }}} // namespace flame_ide::handler::network diff --git a/src/Handler/Network/ServerHandle.cpp b/src/Handler/Network/ServerHandle.cpp index 6e44e835..381e1746 100644 --- a/src/Handler/Network/ServerHandle.cpp +++ b/src/Handler/Network/ServerHandle.cpp @@ -7,12 +7,12 @@ namespace flame_ide Handler::ServerHandle::operator bool() const noexcept { - return data && callbackGetCommunicationHandle; + return data && callbackGetSessionHandle; } -Handler::CommunicationHandle Handler::ServerHandle::getCommunicationHandle() noexcept +Handler::SessionHandle Handler::ServerHandle::getSessionHandle() noexcept { - return callbackGetCommunicationHandle(data); + return callbackGetSessionHandle(data); } }}} // namespace flame_ide::handler::network diff --git a/src/Handler/Network/Sources.cmake b/src/Handler/Network/Sources.cmake index 46e3e35a..570fb26b 100644 --- a/src/Handler/Network/Sources.cmake +++ b/src/Handler/Network/Sources.cmake @@ -3,7 +3,5 @@ set (SOURCE_LIST ${CMAKE_CURRENT_SOURCE_DIR}/Handler.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Internal.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ServerHandle.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Tcp.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Udp.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Worker.cpp ) diff --git a/src/Handler/Network/Tcp/CMakeLists.txt b/src/Handler/Network/Tcp/CMakeLists.txt new file mode 100644 index 00000000..23621c92 --- /dev/null +++ b/src/Handler/Network/Tcp/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.14) + +set(NAME Handler.Network.Tcp) +set(NAME_ALIAS Handler::Network::Tcp) +set(INCLUDE_PATHS ${FLAME_INCLUDE_PATH}) + +set(DEPENDENCY_HEADER_TARGETS + ${FLAME_NAMESPACE}::Os::Network::Headers +) + +get_sources(FILE_LIST) +flame_compile_library( + NAME "${NAME}" + SOURCE_LIST "${FILE_LIST}" + INCLUDE_PATHS "${INCLUDE_PATHS}" "${GENERATED_INCLUDE_PATH}" + DEPENDENCY_HEADER_TARGETS "${DEPENDENCY_HEADER_TARGETS}" + OBJECT_ALIAS_NAME + "${FLAME_NAMESPACE}::${NAME_ALIAS}::Object" + INDEPENDENT_OBJECT_ALIAS_NAME + "${FLAME_NAMESPACE}::${NAME_ALIAS}::Object::Independ" + + NO_RTTI + NO_EXCEPTIONS +) diff --git a/src/Handler/Network/TcpClient.hpp b/src/Handler/Network/Tcp/Client.hpp similarity index 92% rename from src/Handler/Network/TcpClient.hpp rename to src/Handler/Network/Tcp/Client.hpp index 8e586670..007b7e66 100644 --- a/src/Handler/Network/TcpClient.hpp +++ b/src/Handler/Network/Tcp/Client.hpp @@ -1,14 +1,14 @@ #ifndef HANDLERINTERNALTCPCLIENT_HPP #define HANDLERINTERNALTCPCLIENT_HPP +#include + #include #include #include -#include - -#include -#include +#include +#include namespace flame_ide {namespace handler diff --git a/src/Handler/Network/TcpConfig.hpp b/src/Handler/Network/Tcp/Config.hpp similarity index 100% rename from src/Handler/Network/TcpConfig.hpp rename to src/Handler/Network/Tcp/Config.hpp diff --git a/src/Handler/Network/Tcp/Headers.cmake b/src/Handler/Network/Tcp/Headers.cmake new file mode 100644 index 00000000..8db2e245 --- /dev/null +++ b/src/Handler/Network/Tcp/Headers.cmake @@ -0,0 +1,8 @@ +set (HEADER_LIST + ${CMAKE_CURRENT_SOURCE_DIR}/Client.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Config.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/InternalData.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Server.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Tcp.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Types.hpp +) diff --git a/src/Handler/Network/Tcp/InternalData.cpp b/src/Handler/Network/Tcp/InternalData.cpp new file mode 100644 index 00000000..ebe14443 --- /dev/null +++ b/src/Handler/Network/Tcp/InternalData.cpp @@ -0,0 +1,50 @@ +#include + +namespace flame_ide +{namespace os +{namespace network +{namespace tcp +{namespace callbacks +{ + +// client + +// TODO +Types::ssize_t clientBytesToRead(void */*data*/) noexcept +{ + return os::STATUS_FAILED; +} + +// TODO +Types::ssize_t clientReceive(void */*data*/, templates::Range) noexcept +{ + return os::STATUS_FAILED; +} + +// TODO +Types::ssize_t clientSend(void */*data*/, templates::Range) noexcept +{ + return os::STATUS_FAILED; +} + +// server + +// TODO +Types::ssize_t serverBytesToRead(void */*data*/) noexcept +{ + return os::STATUS_FAILED; +} + +// TODO +Types::ssize_t serverReceive(void */*data*/, templates::Range) noexcept +{ + return os::STATUS_FAILED; +} + +// TODO +Types::ssize_t serverSend(void */*data*/, templates::Range) noexcept +{ + return os::STATUS_FAILED; +} + +}}}}} // namespace flame_ide::os::network::udp::callbacks diff --git a/src/Handler/Network/Tcp/InternalData.hpp b/src/Handler/Network/Tcp/InternalData.hpp new file mode 100644 index 00000000..db335595 --- /dev/null +++ b/src/Handler/Network/Tcp/InternalData.hpp @@ -0,0 +1,38 @@ +#ifndef HANDLERINTERNALTCPDATA_HPP +#define HANDLERINTERNALTCPDATA_HPP + +#include +#include + +namespace flame_ide +{namespace os +{namespace network +{namespace tcp +{namespace callbacks +{ + +// client + +// TODO +Types::ssize_t clientBytesToRead(void *data) noexcept; + +// TODO +Types::ssize_t clientReceive(void *data, templates::Range) noexcept; + +// TODO +Types::ssize_t clientSend(void *data, templates::Range) noexcept; + +// server + +// TODO +Types::ssize_t serverBytesToRead(void *data) noexcept; + +// TODO +Types::ssize_t serverReceive(void *data, templates::Range) noexcept; + +// TODO +Types::ssize_t serverSend(void *data, templates::Range) noexcept; + +}}}}} // namespace flame_ide::os::network::udp::callbacks + +#endif // HANDLERINTERNALTCPDATA_HPP diff --git a/src/Handler/Network/TcpServer.hpp b/src/Handler/Network/Tcp/Server.hpp similarity index 92% rename from src/Handler/Network/TcpServer.hpp rename to src/Handler/Network/Tcp/Server.hpp index 40d00c92..259b315b 100644 --- a/src/Handler/Network/TcpServer.hpp +++ b/src/Handler/Network/Tcp/Server.hpp @@ -1,14 +1,14 @@ #ifndef HANDLERINTERNALTCPSERVER_HPP #define HANDLERINTERNALTCPSERVER_HPP +#include + #include #include #include -#include - -#include -#include +#include +#include namespace flame_ide {namespace handler diff --git a/src/Handler/Network/Tcp/Sources.cmake b/src/Handler/Network/Tcp/Sources.cmake new file mode 100644 index 00000000..8d926f36 --- /dev/null +++ b/src/Handler/Network/Tcp/Sources.cmake @@ -0,0 +1,4 @@ +set (SOURCE_LIST + ${CMAKE_CURRENT_SOURCE_DIR}/InternalData.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Tcp.cpp +) diff --git a/src/Handler/Network/Tcp.cpp b/src/Handler/Network/Tcp/Tcp.cpp similarity index 96% rename from src/Handler/Network/Tcp.cpp rename to src/Handler/Network/Tcp/Tcp.cpp index 68d0392f..0e2d483f 100644 --- a/src/Handler/Network/Tcp.cpp +++ b/src/Handler/Network/Tcp/Tcp.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include diff --git a/src/Handler/Network/Tcp.hpp b/src/Handler/Network/Tcp/Tcp.hpp similarity index 91% rename from src/Handler/Network/Tcp.hpp rename to src/Handler/Network/Tcp/Tcp.hpp index d5de158c..a7d0893a 100644 --- a/src/Handler/Network/Tcp.hpp +++ b/src/Handler/Network/Tcp/Tcp.hpp @@ -4,9 +4,9 @@ #include #include -#include -#include -#include +#include +#include +#include namespace flame_ide {namespace handler diff --git a/src/Handler/Network/TcpTypes.hpp b/src/Handler/Network/Tcp/Types.hpp similarity index 100% rename from src/Handler/Network/TcpTypes.hpp rename to src/Handler/Network/Tcp/Types.hpp diff --git a/src/Handler/Network/Udp/CMakeLists.txt b/src/Handler/Network/Udp/CMakeLists.txt new file mode 100644 index 00000000..ccf01bc7 --- /dev/null +++ b/src/Handler/Network/Udp/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.14) + +set(NAME Handler.Network.Udp) +set(NAME_ALIAS Handler::Network::Udp) +set(INCLUDE_PATHS ${FLAME_INCLUDE_PATH}) + +set(DEPENDENCY_HEADER_TARGETS + ${FLAME_NAMESPACE}::Os::Network::Headers +) + +get_sources(FILE_LIST) +flame_compile_library( + NAME "${NAME}" + SOURCE_LIST "${FILE_LIST}" + INCLUDE_PATHS "${INCLUDE_PATHS}" "${GENERATED_INCLUDE_PATH}" + DEPENDENCY_HEADER_TARGETS "${DEPENDENCY_HEADER_TARGETS}" + OBJECT_ALIAS_NAME + "${FLAME_NAMESPACE}::${NAME_ALIAS}::Object" + INDEPENDENT_OBJECT_ALIAS_NAME + "${FLAME_NAMESPACE}::${NAME_ALIAS}::Object::Independ" + + NO_RTTI + NO_EXCEPTIONS +) diff --git a/src/Handler/Network/UdpClient.hpp b/src/Handler/Network/Udp/Client.hpp similarity index 88% rename from src/Handler/Network/UdpClient.hpp rename to src/Handler/Network/Udp/Client.hpp index b2d003bd..3292500c 100644 --- a/src/Handler/Network/UdpClient.hpp +++ b/src/Handler/Network/Udp/Client.hpp @@ -1,8 +1,8 @@ #ifndef HANDLERINTERNALUDPCLIENT_HPP #define HANDLERINTERNALUDPCLIENT_HPP -#include -#include +#include +#include #include #include diff --git a/src/Handler/Network/UdpConfig.hpp b/src/Handler/Network/Udp/Config.hpp similarity index 100% rename from src/Handler/Network/UdpConfig.hpp rename to src/Handler/Network/Udp/Config.hpp diff --git a/src/Handler/Network/Udp/Headers.cmake b/src/Handler/Network/Udp/Headers.cmake new file mode 100644 index 00000000..001d000a --- /dev/null +++ b/src/Handler/Network/Udp/Headers.cmake @@ -0,0 +1,8 @@ +set (HEADER_LIST + ${CMAKE_CURRENT_SOURCE_DIR}/Client.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Config.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/InternalData.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Server.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Types.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Udp.hpp +) diff --git a/src/Handler/Network/Udp/InternalData.cpp b/src/Handler/Network/Udp/InternalData.cpp new file mode 100644 index 00000000..4f8a7796 --- /dev/null +++ b/src/Handler/Network/Udp/InternalData.cpp @@ -0,0 +1,114 @@ +#include + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace callbacks +{ + +// client + +// TODO +Types::ssize_t clientBytesToRead(void */*data*/) noexcept +{ + return os::STATUS_FAILED; +} + +// TODO +Types::ssize_t clientReceive(void */*data*/, templates::Range) noexcept +{ + return os::STATUS_FAILED; +} + +// TODO +Types::ssize_t clientSend(void */*data*/, templates::Range) noexcept +{ + return os::STATUS_FAILED; +} + +// server + +Types::ssize_t serverBytesToRead(const udp::ServerCommunicationData *data) noexcept +{ + if (!data || !data->message) + return os::STATUS_FAILED; + + os::threads::Locker{ data->message->spin }; + + return data->message->size; +} + +Types::ssize_t +serverReceive( + udp::ServerCommunicationData *data, templates::Range range +) noexcept +{ + if (!data || !data->message) + return os::STATUS_FAILED; + + Types::ssize_t numberToRead = 0; + auto &message = *data->message; + { + os::threads::Locker{ message.spin }; + + const Types::ssize_t rangeSize = range.end() - range.begin(); + const Types::ssize_t messageSize = message.size; + const Types::ssize_t toRead = (rangeSize < messageSize) + ? rangeSize + : messageSize; + + auto begin = range.begin(); + for (Types::ssize_t i = 0; i < toRead; ++i, ++begin) + { + *begin = message.bytes[i]; + } + message.size = 0; + message.client = decltype(message.client){}; + message.state = MessageState::EMPTY; + + numberToRead = toRead; + } + return numberToRead; +} + +Types::ssize_t +serverSend( + udp::ServerCommunicationData *data, templates::Range range +) noexcept +{ + if (!data || !data->output) + return os::STATUS_FAILED; + + auto &output = *data->output; + Server::Message *message = nullptr; + { + os::threads::Locker locker{ output.spin }; + message = output.last->pointer(); + { + os::threads::Locker locker{ message->spin }; + message->state = MessageState::PROCESSING; + } + ++output.last; + } + + const Types::ssize_t rangeSize = range.end() - range.begin(); + { + os::threads::Locker locker{ message->spin }; + message->size = rangeSize; + message->client = data->client; + + auto begin = range.begin(); + for (Types::ssize_t i = 0; i < rangeSize; ++i, ++begin) + { + message->bytes[i] = *begin; + } + + message->state = MessageState::READY; + } + return rangeSize; +} + +}}}}} // namespace flame_ide::os::network::udp::callbacks diff --git a/src/Handler/Network/Udp/InternalData.hpp b/src/Handler/Network/Udp/InternalData.hpp new file mode 100644 index 00000000..c5876728 --- /dev/null +++ b/src/Handler/Network/Udp/InternalData.hpp @@ -0,0 +1,61 @@ +#ifndef HANDLERINTERNALUDPDATA_HPP +#define HANDLERINTERNALUDPDATA_HPP + +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +struct ServerCommunicationData +{ + os::network::UdpServer::WithClient client; + Server::Message *message; + Server::ActualOutput *output; +}; + +struct ClientCommunicationData +{ + os::network::UdpClient *client; + Server::Message *message; + Server::ActualOutput *output; +}; + +}}}} // namespace flame_ide::os::network::udp + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace callbacks +{ + +// client + +// TODO +Types::ssize_t clientBytesToRead(void *data) noexcept; + +// TODO +Types::ssize_t clientReceive(void *data, templates::Range) noexcept; + +// TODO +Types::ssize_t clientSend(void *data, templates::Range) noexcept; + +// server + +Types::ssize_t serverBytesToRead(const udp::ServerCommunicationData *message) noexcept; + +Types::ssize_t serverReceive( + udp::ServerCommunicationData *message, templates::Range range +) noexcept; + +Types::ssize_t serverSend( + udp::ServerCommunicationData *data, templates::Range +) noexcept; + +}}}}} // namespace flame_ide::os::network::udp::callbacks + +#endif // HANDLERINTERNALUDPDATA_HPP diff --git a/src/Handler/Network/UdpServer.hpp b/src/Handler/Network/Udp/Server.hpp similarity index 88% rename from src/Handler/Network/UdpServer.hpp rename to src/Handler/Network/Udp/Server.hpp index 65e14c50..a92ea331 100644 --- a/src/Handler/Network/UdpServer.hpp +++ b/src/Handler/Network/Udp/Server.hpp @@ -1,8 +1,8 @@ #ifndef HANDLERINTERNALUDPSERVER_HPP #define HANDLERINTERNALUDPSERVER_HPP -#include -#include +#include +#include #include #include diff --git a/src/Handler/Network/Udp/Sources.cmake b/src/Handler/Network/Udp/Sources.cmake new file mode 100644 index 00000000..75f77690 --- /dev/null +++ b/src/Handler/Network/Udp/Sources.cmake @@ -0,0 +1,4 @@ +set (SOURCE_LIST + ${CMAKE_CURRENT_SOURCE_DIR}/InternalData.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Udp.cpp +) diff --git a/src/Handler/Network/UdpTypes.hpp b/src/Handler/Network/Udp/Types.hpp similarity index 100% rename from src/Handler/Network/UdpTypes.hpp rename to src/Handler/Network/Udp/Types.hpp diff --git a/src/Handler/Network/Udp.cpp b/src/Handler/Network/Udp/Udp.cpp similarity index 96% rename from src/Handler/Network/Udp.cpp rename to src/Handler/Network/Udp/Udp.cpp index 6c2b85b8..598313b7 100644 --- a/src/Handler/Network/Udp.cpp +++ b/src/Handler/Network/Udp/Udp.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include diff --git a/src/Handler/Network/Udp.hpp b/src/Handler/Network/Udp/Udp.hpp similarity index 88% rename from src/Handler/Network/Udp.hpp rename to src/Handler/Network/Udp/Udp.hpp index c6b3d512..d7e9940f 100644 --- a/src/Handler/Network/Udp.hpp +++ b/src/Handler/Network/Udp/Udp.hpp @@ -4,9 +4,9 @@ #include #include -#include -#include -#include +#include +#include +#include namespace flame_ide {namespace handler diff --git a/src/Handler/Network/Worker.cpp b/src/Handler/Network/Worker.cpp index 655de304..d70cc3f8 100644 --- a/src/Handler/Network/Worker.cpp +++ b/src/Handler/Network/Worker.cpp @@ -7,14 +7,14 @@ namespace flame_ide {namespace network { -void Worker::init(os::threads::ConditionVariable &initCondvar) noexcept +void Worker::notify() { - condvar = &initCondvar; + condvar.notify(); } void Worker::body() noexcept { - while (!condvar->tryWait()) + while (!condvar.tryWait()) {} } @@ -26,33 +26,21 @@ namespace flame_ide { Workers::Workers() noexcept -{ - flame_ide::templates::foreachChangable( - workers - , [this](Worker &i) { i.init(condvar); } - ); -} +{} Workers::~Workers() noexcept { stop(); } -void Workers::start() +os::Status Workers::start() { - flame_ide::templates::foreachChangable( - workers - , [](Worker &i) { i.run(); } - ); + return os::STATUS_FAILED; } -void Workers::stop() +os::Status Workers::stop() { - condvar.notify(); - flame_ide::templates::foreachChangable( - workers - , [](Worker &i) { i.join(); } - ); + return os::STATUS_FAILED; } }}} // namespace flame_ide::handler::network diff --git a/src/Handler/Network/Worker.hpp b/src/Handler/Network/Worker.hpp index b96b1aa5..ba8e1ff0 100644 --- a/src/Handler/Network/Worker.hpp +++ b/src/Handler/Network/Worker.hpp @@ -19,14 +19,16 @@ class Worker: public os::threads::ThreadCrtp using Parent = os::threads::ThreadCrtp; friend Parent; -public: // - void init(os::threads::ConditionVariable &initCondvar) noexcept; +public: + void notify(); -private: // os::threads::ThreadCrtp +private: + // os::threads::ThreadCrtp void body() noexcept; private: - os::threads::ConditionVariable *condvar = nullptr; + os::threads::Mutex mutex; + os::threads::ConditionVariable condvar{ mutex }; }; }}} // namespace flame_ide::handler::network @@ -42,16 +44,13 @@ class Workers Workers() noexcept; ~Workers() noexcept; - void start(); - void stop(); + os::Status start(); + os::Status stop(); private: void join() noexcept; private: - os::threads::Mutex mutex; - os::threads::ConditionVariable condvar{ mutex }; - templates::StaticArray< Worker, generated::network::Config::HANDLER_NUMBER_OF_WORKERS > workers; diff --git a/src/Handler/Tests/CMakeLists.txt b/src/Handler/Tests/CMakeLists.txt index 6ab2f3c1..bee5ba08 100644 --- a/src/Handler/Tests/CMakeLists.txt +++ b/src/Handler/Tests/CMakeLists.txt @@ -71,14 +71,12 @@ if(FLAME_MAKE_SHARED) endif() set(DEPENDENCY_TARGETS_FOR_STATIC -# "${FLAME_NAMESPACE}::Handler::Static" - "${FLAME_NAMESPACE}::Handler::Network::Object" + "${FLAME_NAMESPACE}::Handler::Network::Static" "${FLAME_NAMESPACE}::Os::Static" "${DEPEND_OBJECTS}" ) set(DEPENDENCY_TARGETS_FOR_SHARED -# "${FLAME_NAMESPACE}::Handler::Shared" - "${FLAME_NAMESPACE}::Handler::Network::Object::Independ" + "${FLAME_NAMESPACE}::Handler::Network::Shared" "${FLAME_NAMESPACE}::Os::Shared" "${INDEPEND_OBJECTS}" ) diff --git a/src/Handler/Tests/Network/TcpTest.cpp b/src/Handler/Tests/Network/TcpTest.cpp index cf5d6d83..b450c439 100644 --- a/src/Handler/Tests/Network/TcpTest.cpp +++ b/src/Handler/Tests/Network/TcpTest.cpp @@ -1,5 +1,5 @@ #include -#include +#include namespace flame_ide {namespace handler diff --git a/src/Handler/Tests/Network/UdpTest.cpp b/src/Handler/Tests/Network/UdpTest.cpp index 0e356da0..f88f9633 100644 --- a/src/Handler/Tests/Network/UdpTest.cpp +++ b/src/Handler/Tests/Network/UdpTest.cpp @@ -1,5 +1,5 @@ #include -#include +#include namespace flame_ide {namespace handler From b4dcbe51bbbcb394bad131bd2c3425073566bc58 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Tue, 17 Sep 2024 20:12:05 +0500 Subject: [PATCH 05/37] Add 'Common/TypeMapper' with tests --- include/FlameIDE/Common/Traits/Functional.hpp | 38 +++++++++++++++ src/Common/Tests/FunctionalTraitTest.cpp | 47 +++++++++++++++++++ src/Common/Tests/FunctionalTraitTest.hpp | 26 ++++++++++ src/Common/Tests/Sources.cmake | 2 + src/Common/Tests/TestAggregator.cpp | 2 + 5 files changed, 115 insertions(+) create mode 100644 src/Common/Tests/FunctionalTraitTest.cpp create mode 100644 src/Common/Tests/FunctionalTraitTest.hpp diff --git a/include/FlameIDE/Common/Traits/Functional.hpp b/include/FlameIDE/Common/Traits/Functional.hpp index 635df965..f81efc7b 100644 --- a/include/FlameIDE/Common/Traits/Functional.hpp +++ b/include/FlameIDE/Common/Traits/Functional.hpp @@ -342,6 +342,44 @@ struct DoSomeByIndex {} }; +/// +/// @brief The TypeMappingTrait class +/// @tparam T1 +/// @tparam T2 +/// +template +struct TypeMappingTrait +{ + using Type1 = T1; + using Type2 = T2; +}; + +/// +/// @brief The TypeMapper class +/// @tparam T +/// @tparam TypeMappingTrait +/// @tparam ENABLE_STATIC_ASSERT +/// +template +struct TypeMapper +{ + using Type = typename ChooseType< + ComparingTypes::VALUE + , typename TypeMappingTrait::Type2 + , typename ChooseType< + ComparingTypes::VALUE + , typename TypeMappingTrait::Type1 + , Empty + >::Type + >::Type; + + static_assert( + !ENABLE_STATIC_ASSERT + || ComparingTypes::VALUE == FalseType::VALUE + , "Type does not include in chosen TypeMatchingTrait" + ); +}; + } #endif // FLAMEIDE_COMMON_TRAITS_FUCTIONAL_HPP diff --git a/src/Common/Tests/FunctionalTraitTest.cpp b/src/Common/Tests/FunctionalTraitTest.cpp new file mode 100644 index 00000000..be993767 --- /dev/null +++ b/src/Common/Tests/FunctionalTraitTest.cpp @@ -0,0 +1,47 @@ +#include + +#include + +namespace flame_ide +{namespace common +{namespace tests +{ + +FunctionalTraitTest::FunctionalTraitTest() noexcept : ::AbstractTest{ "FunctionalTrait" } +{} + +FunctionalTraitTest::~FunctionalTraitTest() noexcept = default; + +int FunctionalTraitTest::vStart() +{ + CHECK_RESULT_SUCCESS(doTestCase( + "TypeMapper" + , [this] { return typeMapper(); } + )); + return ResultType::SUCCESS; +} + +int FunctionalTraitTest::typeMapper() +{ + using T1 = long long; + using T2 = unsigned long long; + using T3 = double; + using TestTypeMatchingTrait = TypeMappingTrait; + + using T2Result = TypeMapper::Type; + using T1Result = TypeMapper::Type; + // using T3Result = TypeMapper::Type; // static assert + using T3Result = TypeMapper::Type; + + const bool t1ComparationResult = ComparingTypes::VALUE; + const bool t2ComparationResult = ComparingTypes::VALUE; + const bool t3ComparationResult = ComparingTypes::VALUE; + + IN_CASE_CHECK(t1ComparationResult == true); + IN_CASE_CHECK(t2ComparationResult == true); + IN_CASE_CHECK(t3ComparationResult == true); + + return ResultType::SUCCESS; +} + +}}} // namespace flame_ide::common::tests diff --git a/src/Common/Tests/FunctionalTraitTest.hpp b/src/Common/Tests/FunctionalTraitTest.hpp new file mode 100644 index 00000000..02efde71 --- /dev/null +++ b/src/Common/Tests/FunctionalTraitTest.hpp @@ -0,0 +1,26 @@ +#ifndef FLAMEIDE_COMMON_TESTS_FUNCTIONALTRAITTEST_HPP +#define FLAMEIDE_COMMON_TESTS_FUNCTIONALTRAITTEST_HPP + +#include + +namespace flame_ide +{namespace common +{namespace tests +{ + +class FunctionalTraitTest: public ::AbstractTest +{ +public: + FunctionalTraitTest() noexcept; + ~FunctionalTraitTest() noexcept override; + +private: + int vStart() override; + +private: + int typeMapper(); +}; + +}}} // namespace flame_ide::common::tests + +#endif // FLAMEIDE_COMMON_TESTS_FUNCTIONALTRAITTEST_HPP diff --git a/src/Common/Tests/Sources.cmake b/src/Common/Tests/Sources.cmake index 3e585535..1c26f64a 100644 --- a/src/Common/Tests/Sources.cmake +++ b/src/Common/Tests/Sources.cmake @@ -1,6 +1,8 @@ set (SOURCE_LIST ${CMAKE_CURRENT_SOURCE_DIR}/ExpectedTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ExpectedTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/FunctionalTraitTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/FunctionalTraitTest.hpp ${CMAKE_CURRENT_SOURCE_DIR}/TestAggregator.cpp ${CMAKE_CURRENT_SOURCE_DIR}/TestAggregator.hpp ${CMAKE_CURRENT_SOURCE_DIR}/UtilsTest.cpp diff --git a/src/Common/Tests/TestAggregator.cpp b/src/Common/Tests/TestAggregator.cpp index eef69d18..6d36a9f9 100644 --- a/src/Common/Tests/TestAggregator.cpp +++ b/src/Common/Tests/TestAggregator.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include @@ -14,6 +15,7 @@ TestAggregator::TestAggregator() : ::TestAggregator("Common") pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); } }}} // namespace flame_ide::common::tests From fa971dd60118ea8190981f72a2284152a785da47 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Mon, 23 Sep 2024 05:43:11 +0500 Subject: [PATCH 06/37] Redesign UDP part of Hanler --- src/Handler/Network/Handler.cpp | 49 +++++++- src/Handler/Network/Internal.cpp | 11 ++ src/Handler/Network/Internal.hpp | 4 + src/Handler/Network/Udp/Client.hpp | 37 +++--- src/Handler/Network/Udp/Endpoint.hpp | 127 ++++++++++++++++++++ src/Handler/Network/Udp/Headers.cmake | 1 + src/Handler/Network/Udp/InternalData.cpp | 45 ++++---- src/Handler/Network/Udp/InternalData.hpp | 26 ++--- src/Handler/Network/Udp/Server.hpp | 42 +++---- src/Handler/Network/Udp/Types.hpp | 121 ++++++++++++++++++++ src/Handler/Network/Udp/Udp.cpp | 96 +++++++++------- src/Handler/Network/Udp/Udp.hpp | 140 ++++++++++++++++++----- 12 files changed, 545 insertions(+), 154 deletions(-) create mode 100644 src/Handler/Network/Udp/Endpoint.hpp diff --git a/src/Handler/Network/Handler.cpp b/src/Handler/Network/Handler.cpp index a192e8e5..86de31d5 100644 --- a/src/Handler/Network/Handler.cpp +++ b/src/Handler/Network/Handler.cpp @@ -1,5 +1,6 @@ #include +#include #include #include @@ -52,22 +53,62 @@ Handler &Handler::operator=(Handler &&handler) noexcept Handler::ExpectedServerHandle Handler::pushUdp(os::network::UdpServer &&server) noexcept { - return internal->udp().push(flame_ide::move(server)); + const auto descriptor = server.native().descriptor; + + auto result = internal->udp().push(flame_ide::move(server)); + flame_ide::makeConstReferenceWrapper(result)->ifResult( + [descriptor, this](const auto &) + { + internal->registrar().pushUdpServer(descriptor); + } + ); + + return result; } Handler::ExpectedSessionHandle Handler::pushUdp(os::network::UdpClient &&client) noexcept { - return internal->udp().push(flame_ide::move(client)); + const auto descriptor = client.native().descriptor; + + auto result = internal->udp().push(flame_ide::move(client)); + flame_ide::makeConstReferenceWrapper(result)->ifResult( + [descriptor, this](const auto &) + { + internal->registrar().pushUdpServer(descriptor); + } + ); + + return result; } Handler::ExpectedServerHandle Handler::pushTcp(os::network::TcpServer &&server) noexcept { - return internal->tcp().push(flame_ide::move(server)); + const auto descriptor = server.native().descriptor; + + auto result = internal->tcp().push(flame_ide::move(server)); + flame_ide::makeConstReferenceWrapper(result)->ifResult( + [descriptor, this](const auto &) + { + internal->registrar().pushUdpServer(descriptor); + } + ); + + return result; } Handler::ExpectedSessionHandle Handler::pushTcp(os::network::TcpClient &&client) noexcept { - return internal->tcp().push(flame_ide::move(client)); + const auto descriptor = client.native().descriptor; + + auto result = internal->tcp().push(flame_ide::move(client)); + flame_ide::makeConstReferenceWrapper(result)->ifResult( + [descriptor, this](const auto &) + { + internal->registrar().pushUdpServer(descriptor); + } + ); + + return result; } Handler::ExpectedUdpServer Handler::popUdp(ServerHandle &handle) noexcept diff --git a/src/Handler/Network/Internal.cpp b/src/Handler/Network/Internal.cpp index 23e4accb..e9aa35f5 100644 --- a/src/Handler/Network/Internal.cpp +++ b/src/Handler/Network/Internal.cpp @@ -15,12 +15,18 @@ namespace flame_ide Handler::ExpectedServerHandle Handler::Udp::push(os::network::UdpServer &&server) noexcept { flame_ide::unused(server); + + udp::Server *udpServer = udp.push(move(server)); + flame_ide::unused(udpServer); return { os::STATUS_FAILED }; } Handler::ExpectedSessionHandle Handler::Udp::push(os::network::UdpClient &&client) noexcept { flame_ide::unused(client); + + udp::Client *udpClient = udp.push(move(client)); + flame_ide::unused(udpClient); return { os::STATUS_FAILED }; } @@ -85,6 +91,11 @@ Handler::Tcp &Handler::Internal::tcp() noexcept return tcpData; } +os::async::network::Registrar &Handler::Internal::registrar() noexcept +{ + return registration; +} + os::Status Handler::Internal::start() noexcept { return workers.start(); diff --git a/src/Handler/Network/Internal.hpp b/src/Handler/Network/Internal.hpp index e137b8dd..1762ac71 100644 --- a/src/Handler/Network/Internal.hpp +++ b/src/Handler/Network/Internal.hpp @@ -88,6 +88,10 @@ class Handler::Internal /// @return Tcp &tcp() noexcept; + /// @brief registrar + /// @return + os::async::network::Registrar ®istrar() noexcept; + /// @brief start /// @return // TODO diff --git a/src/Handler/Network/Udp/Client.hpp b/src/Handler/Network/Udp/Client.hpp index 3292500c..068605cb 100644 --- a/src/Handler/Network/Udp/Client.hpp +++ b/src/Handler/Network/Udp/Client.hpp @@ -1,7 +1,6 @@ #ifndef HANDLERINTERNALUDPCLIENT_HPP #define HANDLERINTERNALUDPCLIENT_HPP -#include #include #include @@ -13,31 +12,25 @@ namespace flame_ide {namespace udp { -class Client +struct ClientMessage: public Message +{}; +using ClientEndpoint = Endpoint< + ::flame_ide::os::network::UdpClient, ClientMessage + , Constants::CLIENT_INPUT_QUEUE_SIZE, Constants::CLIENT_OUTPUT_QUEUE_SIZE +>; + +class Client: public ClientEndpoint { public: - struct Message + inline ClientEndpoint::Optional &client() noexcept { - ::flame_ide::templates::StaticArray< - ::flame_ide::byte_t, Constants::MESSAGE_SIZE - > bytes; - Types::ssize_t size = 0; - MessageState state = MessageState::EMPTY; - mutable os::threads::Spin spin; - }; - -public: - using Optional = ::flame_ide::templates::Optional< - ::flame_ide::os::network::UdpClient - >; + return this->osEndpoint; + } - using ActualInput = ActualData; - using ActualOutput = ActualData; - -public: - Optional client; - ActualInput input; - ActualOutput output; + inline const ClientEndpoint::Optional &client() const noexcept + { + return this->osEndpoint; + } }; }}}} // namespace flame_ide::handler::network::udp diff --git a/src/Handler/Network/Udp/Endpoint.hpp b/src/Handler/Network/Udp/Endpoint.hpp new file mode 100644 index 00000000..bb880362 --- /dev/null +++ b/src/Handler/Network/Udp/Endpoint.hpp @@ -0,0 +1,127 @@ +#ifndef HANDLERINTERNALUDPENDPOINT_HPP +#define HANDLERINTERNALUDPENDPOINT_HPP + +#include +#include + +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +// Container data + +// WARNING: using UniquePointer because malloc doen't work with big sizes +using Servers = ::flame_ide::templates::StaticArray< + templates::UniquePointer, Constants::NUMBER_OF_SERVERS +>; + +// WARNING: using UniquePointer because malloc doen't work with big sizes +using Clients = ::flame_ide::templates::StaticArray< + templates::UniquePointer, Constants::NUMBER_OF_CLIENTS +>; + +using SocketDescriptors = ::flame_ide::templates::StaticArray< + ::flame_ide::os::SocketDescriptor + , Constants::NUMBER_OF_SERVERS + Constants::NUMBER_OF_CLIENTS +>; + +template +struct HandlerEndpointUdpData +{ + templates::UniquePointer container = decltype(container)::makeEmpty(); + os::threads::Spin spin; +}; + +// Matching traits + +using ServerMatchingTrait = ::flame_ide::TypeMappingTrait< + os::network::UdpServer, Server +>; +using ClientMatchingTrait = ::flame_ide::TypeMappingTrait< + os::network::UdpClient, Client +>; + +using ServerDataMatchingTrait = ::flame_ide::TypeMappingTrait< + Server, HandlerEndpointUdpData +>; +using ClientDataMatchingTrait = ::flame_ide::TypeMappingTrait< + Client, HandlerEndpointUdpData +>; + +// Integral constants + +template +using IsServer = ::flame_ide::IntegralConstant< + bool + , ::flame_ide::ComparingTypes< + EndpointType, ::flame_ide::os::network::UdpServer + >::VALUE || ::flame_ide::ComparingTypes::VALUE +>; + +template +using IsClient = ::flame_ide::IntegralConstant< + bool + , ::flame_ide::ComparingTypes< + EndpointType, ::flame_ide::os::network::UdpClient + >::VALUE || ::flame_ide::ComparingTypes::VALUE +>; + +template +using IsCommonEndpoint = ::flame_ide::IntegralConstant< + bool, IsServer::VALUE || IsClient::VALUE +>; + +template +using IsHandlerEndpoint = ::flame_ide::IntegralConstant< + bool, ::flame_ide::ComparingTypes::VALUE + || ::flame_ide::ComparingTypes::VALUE +>; +template +using IsOsEndpoint = ::flame_ide::IntegralConstant< + bool + , ::flame_ide::ComparingTypes::VALUE + || ::flame_ide::ComparingTypes::VALUE +>; + +// Mappers + +// Gets os::network::{ UdpServer, UdpCinet } <-> { Server, Client } +template +using EndpointTypeMapper = ::flame_ide::TypeMapper< + EndpointType + , typename ::flame_ide::ChooseType< + IsServer::VALUE, ServerMatchingTrait, ClientMatchingTrait + >::Type +>; + +template +using EndpointTypeMapper = ::flame_ide::TypeMapper< + EndpointType + , typename ::flame_ide::ChooseType< + IsServer::VALUE, ServerMatchingTrait, ClientMatchingTrait + >::Type +>; + +template< + typename HandlerEndpoint + , typename = typename ::flame_ide::EnableType< + IsHandlerEndpoint::VALUE, HandlerEndpoint + >::Type +> +using HandlerEndpointDataMapper = ::flame_ide::TypeMapper< + HandlerEndpoint + , typename ::flame_ide::ChooseType< + IsServer::VALUE + , ServerDataMatchingTrait + , ClientDataMatchingTrait + >::Type +>; + +}}}} // namespace flame_ide::handler::network::udp + +#endif // HANDLERINTERNALUDPENDPOINT_HPP diff --git a/src/Handler/Network/Udp/Headers.cmake b/src/Handler/Network/Udp/Headers.cmake index 001d000a..256714ff 100644 --- a/src/Handler/Network/Udp/Headers.cmake +++ b/src/Handler/Network/Udp/Headers.cmake @@ -1,6 +1,7 @@ set (HEADER_LIST ${CMAKE_CURRENT_SOURCE_DIR}/Client.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Config.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Endpoint.hpp ${CMAKE_CURRENT_SOURCE_DIR}/InternalData.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Server.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Types.hpp diff --git a/src/Handler/Network/Udp/InternalData.cpp b/src/Handler/Network/Udp/InternalData.cpp index 4f8a7796..a6214cd1 100644 --- a/src/Handler/Network/Udp/InternalData.cpp +++ b/src/Handler/Network/Udp/InternalData.cpp @@ -9,26 +9,6 @@ namespace flame_ide {namespace callbacks { -// client - -// TODO -Types::ssize_t clientBytesToRead(void */*data*/) noexcept -{ - return os::STATUS_FAILED; -} - -// TODO -Types::ssize_t clientReceive(void */*data*/, templates::Range) noexcept -{ - return os::STATUS_FAILED; -} - -// TODO -Types::ssize_t clientSend(void */*data*/, templates::Range) noexcept -{ - return os::STATUS_FAILED; -} - // server Types::ssize_t serverBytesToRead(const udp::ServerCommunicationData *data) noexcept @@ -36,8 +16,7 @@ Types::ssize_t serverBytesToRead(const udp::ServerCommunicationData *data) noexc if (!data || !data->message) return os::STATUS_FAILED; - os::threads::Locker{ data->message->spin }; - + os::threads::Locker locker{ data->message->spin }; return data->message->size; } @@ -83,7 +62,7 @@ serverSend( return os::STATUS_FAILED; auto &output = *data->output; - Server::Message *message = nullptr; + ServerMessage *message = nullptr; { os::threads::Locker locker{ output.spin }; message = output.last->pointer(); @@ -111,4 +90,24 @@ serverSend( return rangeSize; } +// client + +// TODO +Types::ssize_t clientBytesToRead(void */*data*/) noexcept +{ + return os::STATUS_FAILED; +} + +// TODO +Types::ssize_t clientReceive(void */*data*/, templates::Range) noexcept +{ + return os::STATUS_FAILED; +} + +// TODO +Types::ssize_t clientSend(void */*data*/, templates::Range) noexcept +{ + return os::STATUS_FAILED; +} + }}}}} // namespace flame_ide::os::network::udp::callbacks diff --git a/src/Handler/Network/Udp/InternalData.hpp b/src/Handler/Network/Udp/InternalData.hpp index c5876728..0a04858c 100644 --- a/src/Handler/Network/Udp/InternalData.hpp +++ b/src/Handler/Network/Udp/InternalData.hpp @@ -13,14 +13,14 @@ namespace flame_ide struct ServerCommunicationData { os::network::UdpServer::WithClient client; - Server::Message *message; + ServerMessage *message; Server::ActualOutput *output; }; struct ClientCommunicationData { os::network::UdpClient *client; - Server::Message *message; + ServerMessage *message; Server::ActualOutput *output; }; @@ -33,17 +33,6 @@ namespace flame_ide {namespace callbacks { -// client - -// TODO -Types::ssize_t clientBytesToRead(void *data) noexcept; - -// TODO -Types::ssize_t clientReceive(void *data, templates::Range) noexcept; - -// TODO -Types::ssize_t clientSend(void *data, templates::Range) noexcept; - // server Types::ssize_t serverBytesToRead(const udp::ServerCommunicationData *message) noexcept; @@ -56,6 +45,17 @@ Types::ssize_t serverSend( udp::ServerCommunicationData *data, templates::Range ) noexcept; +// client + +// TODO +Types::ssize_t clientBytesToRead(void *data) noexcept; + +// TODO +Types::ssize_t clientReceive(void *data, templates::Range) noexcept; + +// TODO +Types::ssize_t clientSend(void *data, templates::Range) noexcept; + }}}}} // namespace flame_ide::os::network::udp::callbacks #endif // HANDLERINTERNALUDPDATA_HPP diff --git a/src/Handler/Network/Udp/Server.hpp b/src/Handler/Network/Udp/Server.hpp index a92ea331..69c7f92c 100644 --- a/src/Handler/Network/Udp/Server.hpp +++ b/src/Handler/Network/Udp/Server.hpp @@ -1,10 +1,8 @@ #ifndef HANDLERINTERNALUDPSERVER_HPP #define HANDLERINTERNALUDPSERVER_HPP -#include #include -#include #include namespace flame_ide @@ -13,33 +11,27 @@ namespace flame_ide {namespace udp { -class Server +struct ServerMessage: public Message { -public: - struct Message - { - mutable os::threads::Spin spin; - - Types::ssize_t size = 0; - flame_ide::os::network::UdpServer::WithClient client; - flame_ide::templates::StaticArray< - flame_ide::byte_t, Constants::MESSAGE_SIZE - > bytes; - MessageState state = MessageState::EMPTY; - }; + ::flame_ide::os::network::UdpServer::WithClient client; +}; +using ServerEndpoint = Endpoint< + ::flame_ide::os::network::UdpServer, ServerMessage + , Constants::SERVER_INPUT_QUEUE_SIZE, Constants::SERVER_OUTPUT_QUEUE_SIZE +>; +class Server: public ServerEndpoint +{ public: - using Optional = flame_ide::templates::Optional< - flame_ide::os::network::UdpServer - >; - - using ActualInput = ActualData; - using ActualOutput = ActualData; + inline ServerEndpoint::Optional &server() noexcept + { + return this->osEndpoint; + } -public: - Optional server; - ActualInput input; - ActualOutput output; + inline const ServerEndpoint::Optional &server() const noexcept + { + return this->osEndpoint; + } }; }}}} // namespace flame_ide::handler::network::udp diff --git a/src/Handler/Network/Udp/Types.hpp b/src/Handler/Network/Udp/Types.hpp index a7e1fe38..a2055528 100644 --- a/src/Handler/Network/Udp/Types.hpp +++ b/src/Handler/Network/Udp/Types.hpp @@ -5,10 +5,13 @@ #include #include +#include #include #include +#include + namespace flame_ide {namespace handler {namespace network @@ -22,6 +25,17 @@ enum class MessageState , READY }; +struct Message +{ + ::flame_ide::templates::StaticArray< + ::flame_ide::byte_t, Constants::MESSAGE_SIZE + > bytes; + ::flame_ide::Types::ssize_t size = 0; + MessageState state = MessageState::EMPTY; + + mutable os::threads::Spin spin; +}; + template struct ActualData { @@ -42,6 +56,113 @@ struct ActualData mutable os::threads::Spin spin; }; +template< + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE +> +class Endpoint +{ +public: + using Data = EndpointData; + using Optional = flame_ide::templates::Optional; + using ActualInput = ActualData; + using ActualOutput = ActualData; + + bool empty() const noexcept; + void attach(EndpointData &&data) noexcept; + EndpointData detach() noexcept; + + Optional &endpoint() noexcept; + const Optional &endpoint() const noexcept; + + ActualInput &input() noexcept; + ActualOutput &output() noexcept; + +protected: + Optional osEndpoint; + ActualInput actualInput; + ActualOutput actualOutput; +}; + +}}}} // namespace flame_ide::handler::network::udp + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +// Endpoint + +template< + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE +> +bool Endpoint::empty() const noexcept +{ + return !(osEndpoint); +} + +template< + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE +> +void Endpoint::attach( + EndpointData &&data +) noexcept +{ + if (!empty()) + return; + + osEndpoint.set(flame_ide::move(data)); +} + +template< + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE +> +EndpointData +Endpoint::detach() noexcept +{ + if (empty()) + return {}; + + Data data = flame_ide::move(osEndpoint.pull()); + return data; +} + +template< + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE +> +typename Endpoint::Optional & +Endpoint::endpoint() noexcept +{ + return osEndpoint; +} + +template< + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE +> +const typename Endpoint::Optional & +Endpoint::endpoint() const noexcept +{ + return osEndpoint; +} + }}}} // namespace flame_ide::handler::network::udp #endif // HANDLERINTERNALUDPTYPES_HPP diff --git a/src/Handler/Network/Udp/Udp.cpp b/src/Handler/Network/Udp/Udp.cpp index 598313b7..4b28e4e6 100644 --- a/src/Handler/Network/Udp/Udp.cpp +++ b/src/Handler/Network/Udp/Udp.cpp @@ -9,21 +9,23 @@ namespace flame_ide {namespace udp { +/* + Server *Udp::push(os::network::UdpServer &&server) noexcept { if (!initPointer(servers, serversSpin)) return nullptr; - return pushData(servers, serversSpin - , /* check = */ [](const Server &i) -> bool - { - return (i.server); - } - , /* assignTo = */ [&server](Server &handle) - { - handle.server = flame_ide::move(server); - } - ); + auto check = [](const Server &i) -> bool + { + return !i.empty(); + }; + auto assignTo = [&server](Server &handle) + { + handle.attach(flame_ide::move(server)); + }; + + return pushData(servers, serversSpin, check, assignTo); } os::network::UdpServer Udp::pop(Server *server) noexcept @@ -31,38 +33,39 @@ os::network::UdpServer Udp::pop(Server *server) noexcept if (!server) return {}; - return popData(servers, serversSpin, server - , /* check = */ [](const Server &input, const Server &internal) -> bool - { - if (!(input.server) || !(internal.server)) - return false; - - return input.server->native().descriptor - == internal.server->native().descriptor; - } - , /* returnData = */ [](Server &internal) -> os::network::UdpServer - { - os::network::UdpServer server = flame_ide::move(*internal.server); - return server; - } - ); + auto check = [](const Server &input, const Server &internal) -> bool + { + if (input.empty() || internal.empty()) + return false; + + const auto inputDescriptor = input.server()->native().descriptor; + const auto internalDescriptor = internal.server()->native().descriptor; + return (inputDescriptor == internalDescriptor); + }; + auto returnData = [](Server &internal) -> os::network::UdpServer + { + os::network::UdpServer server = flame_ide::move(internal.detach()); + return server; + }; + + return popData(servers, serversSpin, server, check, returnData); } -Client *Udp::push(os::network::UdpClient &&/*client*/) noexcept +Client *Udp::push(os::network::UdpClient &&client) noexcept { -// if (!initPointer(clients, clientsSpin)) + if (!initPointer(clients, clientsSpin)) return nullptr; -// return pushData(clients, clientsSpin -// , /* check = */ [](const Client &i) -> const auto & -// { -// return i.client; -// } -// , /* assignTo = */ [&client](Client &handle) -// { -// handle.client = flame_ide::move(client); -// } -// ); + auto check = [](const Client &i) -> bool + { + return !i.empty(); + }; + auto assignTo = [&client](Client &handle) + { + handle.attach(flame_ide::move(client)); + }; + + return pushData(clients, clientsSpin, check, assignTo); } os::network::UdpClient Udp::pop(Client *client) noexcept @@ -70,9 +73,24 @@ os::network::UdpClient Udp::pop(Client *client) noexcept if (!client) return {}; - return {}; + auto check = [](const Client &input, const Client &internal) -> bool + { + if (!(input.client) || !(internal.client)) + return false; + + const auto inputDescriptor = input.client->native().descriptor; + const auto internalDescriptor = internal.client->native().descriptor; + return (inputDescriptor == internalDescriptor); + }; + auto returnData = [](Client &internal) -> os::network::UdpClient + { + os::network::UdpClient client = flame_ide::move(*internal.client); + return client; + }; -// flame_ide::unused(client); + return popData(clients, clientsSpin, client, check, returnData); } +*/ + }}}} // namespace flame_ide::handler::network::udp diff --git a/src/Handler/Network/Udp/Udp.hpp b/src/Handler/Network/Udp/Udp.hpp index d7e9940f..095bad96 100644 --- a/src/Handler/Network/Udp/Udp.hpp +++ b/src/Handler/Network/Udp/Udp.hpp @@ -3,10 +3,9 @@ #include #include +#include -#include -#include -#include +#include namespace flame_ide {namespace handler @@ -14,39 +13,124 @@ namespace flame_ide {namespace udp { -// WARNING: using UniquePointer because malloc doen't work with big sizes -using Servers = ::flame_ide::templates::StaticArray< - templates::UniquePointer, Constants::NUMBER_OF_SERVERS ->; - -// WARNING: using UniquePointer because malloc doen't work with big sizes -using Clients = ::flame_ide::templates::StaticArray< - templates::UniquePointer, Constants::NUMBER_OF_CLIENTS ->; - -using SocketDescriptors = ::flame_ide::templates::StaticArray< - ::flame_ide::os::SocketDescriptor - , Constants::NUMBER_OF_SERVERS + Constants::NUMBER_OF_CLIENTS ->; - class Udp { public: - Server *push(os::network::UdpServer &&server) noexcept; - os::network::UdpServer pop(Server *server) noexcept; + template + auto *push(OsEndpoint &&osEndpoint) noexcept + { + static_assert( + IsOsEndpoint::VALUE + , "Input type is not flame_ide::os::network::UdpServer or" + " flame_ide::os::network::UdpClient" + ); - Client *push(os::network::UdpClient &&client) noexcept; - os::network::UdpClient pop(Client *client) noexcept; + using HandlerEndpoint = typename EndpointTypeMapper::Type; + using HandlerEndpointPointer = + typename ::flame_ide::DefaultTraits::Pointer; + using HandlerEndpointData = typename HandlerEndpointDataMapper< + HandlerEndpoint + >::Type; -public: - templates::UniquePointer servers = decltype(servers)::makeEmpty(); - templates::UniquePointer clients/* = decltype(clients)::makeEmpty()*/; - SocketDescriptors socketDescriptors; + HandlerEndpointData &data = getData(); + // Init container if need + { + os::threads::Locker lock{ data.spin }; + if (!data.container) + data.container = decltype(data.container){}; + if (!data.container) + return HandlerEndpointPointer{ nullptr }; + } + + // Push + HandlerEndpointPointer handlerEndpointPointer = nullptr; + { + os::threads::Locker lock{ data.spin }; + for (auto &i : data.container.reference()) + { + if (!i->empty()) + continue; + + handlerEndpointPointer = i.pointer(); + break; + } + if (handlerEndpointPointer) + handlerEndpointPointer->attach(flame_ide::move(osEndpoint)); + } + return handlerEndpointPointer; + } + + template + auto pop(HandlerEndpoint *handlerEndpoint) noexcept + { + static_assert( + IsHandlerEndpoint::VALUE + , "Input type is not flame_ide::handler::udp::Server or" + " flame_ide::handler::udp::UdpClient" + ); + + using OsEndpoint = typename EndpointTypeMapper::Type; + using HandlerEndpointData = typename HandlerEndpointDataMapper< + HandlerEndpoint + >::Type; + + if (!handlerEndpoint || handlerEndpoint->empty()) + return OsEndpoint{}; + + HandlerEndpointData &data = getData(); + const auto endpointDescriptor = handlerEndpoint->endpoint()->native().descriptor; + + // Pop + { + os::threads::Locker lock{ data.spin }; + for (auto &i : data.container.reference()) + { + if (i->empty()) + continue; + + const auto internalDescriptor = i->endpoint()->native().descriptor; + if (endpointDescriptor != internalDescriptor) + continue; + + OsEndpoint osEndpoint = flame_ide::move(i->detach()); + return osEndpoint; + } + } + return OsEndpoint{}; + } + +private: + template + T &getData() noexcept; + +private: + HandlerEndpointUdpData servers; + HandlerEndpointUdpData clients; - os::threads::Spin serversSpin; - os::threads::Spin clientsSpin; }; }}}} // namespace flame_ide::handler::network::udp +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +template<> inline +HandlerEndpointUdpData & +Udp::getData>() noexcept +{ + return servers; +} + +template<> inline +HandlerEndpointUdpData & +Udp::getData>() noexcept +{ + return clients; +} + +}}}} // namespace flame_ide::handler::network::udp + #endif // HANDLERINTERNALUDP_HPP From e38116d2b28c84126781545af2ffa22a6b16503d Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Mon, 23 Sep 2024 05:49:04 +0500 Subject: [PATCH 07/37] Add pull() member function to Optional --- include/FlameIDE/Templates/Optional.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/FlameIDE/Templates/Optional.hpp b/include/FlameIDE/Templates/Optional.hpp index 3b17ea2e..e45e9122 100644 --- a/include/FlameIDE/Templates/Optional.hpp +++ b/include/FlameIDE/Templates/Optional.hpp @@ -45,6 +45,7 @@ class Optional typename Me::Reference get(); typename Me::ConstReference get() const; + typename Me::MoveReference pull() noexcept; typename Me::Pointer getPointer(); typename Me::PointerToConst getPointer() const; @@ -243,6 +244,13 @@ typename Optional::ConstReference Optional::get() const return *toValue(); } +template +typename Optional::MoveReference Optional::pull() noexcept +{ + isFill = false; + return flame_ide::move(get()); +} + template typename Optional::Pointer Optional::getPointer() { From 94a3ba5a765ca1070f829a1b4d5f47dfb15142f2 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Mon, 23 Sep 2024 06:02:57 +0500 Subject: [PATCH 08/37] Fix compilation errors and warnings --- include/FlameIDE/Common/Expected.hpp | 4 ++-- include/FlameIDE/Templates/Optional.hpp | 8 ++++---- src/Handler/Network/Handler.cpp | 19 +++++++++++-------- src/Handler/Network/Udp/InternalData.cpp | 4 ++-- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/include/FlameIDE/Common/Expected.hpp b/include/FlameIDE/Common/Expected.hpp index cb5388e3..9745f0e8 100644 --- a/include/FlameIDE/Common/Expected.hpp +++ b/include/FlameIDE/Common/Expected.hpp @@ -146,10 +146,10 @@ Expected::operator=(Me &&expected) noexcept { expected.ifResult([this](ResultType &&result) { - operator=(move(result)); + this->operator=(move(result)); }).ifError([this](ErrorType &&error) { - operator=(move(error)); + this->operator=(move(error)); }).done(); return *this; } diff --git a/include/FlameIDE/Templates/Optional.hpp b/include/FlameIDE/Templates/Optional.hpp index e45e9122..77ef27a6 100644 --- a/include/FlameIDE/Templates/Optional.hpp +++ b/include/FlameIDE/Templates/Optional.hpp @@ -56,7 +56,7 @@ class Optional typename Me::Pointer toValue(); typename Me::PointerToConst toValue() const; - AlignObject value; + AlignObject object; bool isFill; }; @@ -67,7 +67,7 @@ namespace flame_ide { template -Optional::Optional() noexcept : value(), isFill(false) +Optional::Optional() noexcept : object(), isFill(false) {} template @@ -277,7 +277,7 @@ template typename Optional::Pointer Optional::toValue() { return static_cast( - static_cast(value.array) + static_cast(object.array) ); } @@ -285,7 +285,7 @@ template typename Optional::PointerToConst Optional::toValue() const { return static_cast( - static_cast(value.array) + static_cast(object.array) ); } diff --git a/src/Handler/Network/Handler.cpp b/src/Handler/Network/Handler.cpp index 86de31d5..6fed2c39 100644 --- a/src/Handler/Network/Handler.cpp +++ b/src/Handler/Network/Handler.cpp @@ -1,6 +1,5 @@ #include -#include #include #include @@ -56,14 +55,15 @@ Handler::ExpectedServerHandle Handler::pushUdp(os::network::UdpServer &&server) const auto descriptor = server.native().descriptor; auto result = internal->udp().push(flame_ide::move(server)); - flame_ide::makeConstReferenceWrapper(result)->ifResult( + const decltype(result) &constResult = result; + constResult.ifResult( [descriptor, this](const auto &) { internal->registrar().pushUdpServer(descriptor); } ); - return result; + return flame_ide::move(result); } Handler::ExpectedSessionHandle Handler::pushUdp(os::network::UdpClient &&client) noexcept @@ -71,14 +71,15 @@ Handler::ExpectedSessionHandle Handler::pushUdp(os::network::UdpClient &&client) const auto descriptor = client.native().descriptor; auto result = internal->udp().push(flame_ide::move(client)); - flame_ide::makeConstReferenceWrapper(result)->ifResult( + const decltype(result) &constResult = result; + constResult.ifResult( [descriptor, this](const auto &) { internal->registrar().pushUdpServer(descriptor); } ); - return result; + return flame_ide::move(result); } Handler::ExpectedServerHandle Handler::pushTcp(os::network::TcpServer &&server) noexcept @@ -86,14 +87,15 @@ Handler::ExpectedServerHandle Handler::pushTcp(os::network::TcpServer &&server) const auto descriptor = server.native().descriptor; auto result = internal->tcp().push(flame_ide::move(server)); - flame_ide::makeConstReferenceWrapper(result)->ifResult( + const decltype(result) &constResult = result; + constResult.ifResult( [descriptor, this](const auto &) { internal->registrar().pushUdpServer(descriptor); } ); - return result; + return flame_ide::move(result); } Handler::ExpectedSessionHandle Handler::pushTcp(os::network::TcpClient &&client) noexcept @@ -101,7 +103,8 @@ Handler::ExpectedSessionHandle Handler::pushTcp(os::network::TcpClient &&client) const auto descriptor = client.native().descriptor; auto result = internal->tcp().push(flame_ide::move(client)); - flame_ide::makeConstReferenceWrapper(result)->ifResult( + const decltype(result) &constResult = result; + constResult.ifResult( [descriptor, this](const auto &) { internal->registrar().pushUdpServer(descriptor); diff --git a/src/Handler/Network/Udp/InternalData.cpp b/src/Handler/Network/Udp/InternalData.cpp index a6214cd1..bcbfe295 100644 --- a/src/Handler/Network/Udp/InternalData.cpp +++ b/src/Handler/Network/Udp/InternalData.cpp @@ -64,10 +64,10 @@ serverSend( auto &output = *data->output; ServerMessage *message = nullptr; { - os::threads::Locker locker{ output.spin }; + os::threads::Locker outputLocker{ output.spin }; message = output.last->pointer(); { - os::threads::Locker locker{ message->spin }; + os::threads::Locker messageLocker{ message->spin }; message->state = MessageState::PROCESSING; } ++output.last; From d651b6bb8cdbf30eedb65a817c1e166b3f2c44aa Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Wed, 25 Sep 2024 04:17:01 +0500 Subject: [PATCH 09/37] Rename Handler tests --- src/Handler/Tests/Network/Headers.cmake | 5 ----- src/Handler/Tests/Network/Sources.cmake | 8 ++++---- .../Tests/Network/{TcpTest.cpp => TcpQueueTest.cpp} | 12 ++++++------ .../Tests/Network/{TcpTest.hpp => TcpQueueTest.hpp} | 6 +++--- .../Tests/Network/{UdpTest.cpp => UdpQueueTest.cpp} | 12 ++++++------ .../Tests/Network/{UdpTest.hpp => UdpQueueTest.hpp} | 6 +++--- 6 files changed, 22 insertions(+), 27 deletions(-) delete mode 100644 src/Handler/Tests/Network/Headers.cmake rename src/Handler/Tests/Network/{TcpTest.cpp => TcpQueueTest.cpp} (76%) rename src/Handler/Tests/Network/{TcpTest.hpp => TcpQueueTest.hpp} (82%) rename src/Handler/Tests/Network/{UdpTest.cpp => UdpQueueTest.cpp} (76%) rename src/Handler/Tests/Network/{UdpTest.hpp => UdpQueueTest.hpp} (82%) diff --git a/src/Handler/Tests/Network/Headers.cmake b/src/Handler/Tests/Network/Headers.cmake deleted file mode 100644 index 0c46a4da..00000000 --- a/src/Handler/Tests/Network/Headers.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set (HEADER_LIST - ${CMAKE_CURRENT_SOURCE_DIR}/InternalTest.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/TcpTest.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/UdpTest.hpp -) diff --git a/src/Handler/Tests/Network/Sources.cmake b/src/Handler/Tests/Network/Sources.cmake index 971e7bf9..5fc038bd 100644 --- a/src/Handler/Tests/Network/Sources.cmake +++ b/src/Handler/Tests/Network/Sources.cmake @@ -3,10 +3,10 @@ set (SOURCE_LIST ${CMAKE_CURRENT_SOURCE_DIR}/HandlerTest.hpp ${CMAKE_CURRENT_SOURCE_DIR}/InternalTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/InternalTest.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/TcpTest.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/TcpTest.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/UdpTest.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/UdpTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/TcpQueueTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/TcpQueueTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/UdpQueueTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/UdpQueueTest.hpp ${CMAKE_CURRENT_SOURCE_DIR}/WorkerTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/WorkerTest.hpp ) diff --git a/src/Handler/Tests/Network/TcpTest.cpp b/src/Handler/Tests/Network/TcpQueueTest.cpp similarity index 76% rename from src/Handler/Tests/Network/TcpTest.cpp rename to src/Handler/Tests/Network/TcpQueueTest.cpp index b450c439..364bed2f 100644 --- a/src/Handler/Tests/Network/TcpTest.cpp +++ b/src/Handler/Tests/Network/TcpQueueTest.cpp @@ -1,4 +1,4 @@ -#include +#include #include namespace flame_ide @@ -7,12 +7,12 @@ namespace flame_ide {namespace tests { -TcpTest::TcpTest() : ::AbstractTest("Tcp") +TcpQueueTest::TcpQueueTest() : ::AbstractTest("TcpQueue") {} -TcpTest::~TcpTest() = default; +TcpQueueTest::~TcpQueueTest() = default; -int TcpTest::vStart() +int TcpQueueTest::vStart() { CHECK_RESULT_SUCCESS(doTestCase( "initialization" @@ -27,13 +27,13 @@ int TcpTest::vStart() return ResultType::SUCCESS; } -int TcpTest::init() +int TcpQueueTest::init() { tcp::Tcp tcp; return ResultType::SUCCESS; } -int TcpTest::serverPushPop() +int TcpQueueTest::serverPushPop() { tcp::Tcp tcp; os::network::TcpServer server{ 65001 }; diff --git a/src/Handler/Tests/Network/TcpTest.hpp b/src/Handler/Tests/Network/TcpQueueTest.hpp similarity index 82% rename from src/Handler/Tests/Network/TcpTest.hpp rename to src/Handler/Tests/Network/TcpQueueTest.hpp index 104e9097..7d5f899d 100644 --- a/src/Handler/Tests/Network/TcpTest.hpp +++ b/src/Handler/Tests/Network/TcpQueueTest.hpp @@ -9,11 +9,11 @@ namespace flame_ide {namespace tests { -class TcpTest: public ::AbstractTest +class TcpQueueTest: public ::AbstractTest { public: - TcpTest(); - virtual ~TcpTest(); + TcpQueueTest(); + virtual ~TcpQueueTest(); private: virtual int vStart(); diff --git a/src/Handler/Tests/Network/UdpTest.cpp b/src/Handler/Tests/Network/UdpQueueTest.cpp similarity index 76% rename from src/Handler/Tests/Network/UdpTest.cpp rename to src/Handler/Tests/Network/UdpQueueTest.cpp index f88f9633..03075703 100644 --- a/src/Handler/Tests/Network/UdpTest.cpp +++ b/src/Handler/Tests/Network/UdpQueueTest.cpp @@ -1,4 +1,4 @@ -#include +#include #include namespace flame_ide @@ -7,12 +7,12 @@ namespace flame_ide {namespace tests { -UdpTest::UdpTest() : ::AbstractTest("Udp") +UdpQueueTest::UdpQueueTest() : ::AbstractTest("UdpQueue") {} -UdpTest::~UdpTest() = default; +UdpQueueTest::~UdpQueueTest() = default; -int UdpTest::vStart() +int UdpQueueTest::vStart() { CHECK_RESULT_SUCCESS(doTestCase( "initialization" @@ -27,13 +27,13 @@ int UdpTest::vStart() return ResultType::SUCCESS; } -int UdpTest::init() +int UdpQueueTest::init() { udp::Udp udp; return ResultType::SUCCESS; } -int UdpTest::serverPushPop() +int UdpQueueTest::serverPushPop() { udp::Udp udp; os::network::UdpServer server{ 65001 }; diff --git a/src/Handler/Tests/Network/UdpTest.hpp b/src/Handler/Tests/Network/UdpQueueTest.hpp similarity index 82% rename from src/Handler/Tests/Network/UdpTest.hpp rename to src/Handler/Tests/Network/UdpQueueTest.hpp index 8583bcb3..a77bba18 100644 --- a/src/Handler/Tests/Network/UdpTest.hpp +++ b/src/Handler/Tests/Network/UdpQueueTest.hpp @@ -9,11 +9,11 @@ namespace flame_ide {namespace tests { -class UdpTest: public ::AbstractTest +class UdpQueueTest: public ::AbstractTest { public: - UdpTest(); - virtual ~UdpTest(); + UdpQueueTest(); + virtual ~UdpQueueTest(); private: virtual int vStart(); From 96ea3c58e55231b01701db92109264ee50695df8 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Wed, 25 Sep 2024 04:20:56 +0500 Subject: [PATCH 10/37] Fix build on MSVC 2017 --- src/Handler/Tests/TestAggregator.cpp | 8 ++++---- src/Os/Network/UdpServer.cpp | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Handler/Tests/TestAggregator.cpp b/src/Handler/Tests/TestAggregator.cpp index 68146c29..a8a93920 100644 --- a/src/Handler/Tests/TestAggregator.cpp +++ b/src/Handler/Tests/TestAggregator.cpp @@ -1,7 +1,7 @@ #include -#include -#include +#include +#include #include #include #include @@ -13,8 +13,8 @@ namespace flame_ide TestAggregator::TestAggregator() : ::TestAggregator("Handler") { - pushBackTest(std::make_shared()); - pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); diff --git a/src/Os/Network/UdpServer.cpp b/src/Os/Network/UdpServer.cpp index 76f38d44..d86e46c7 100644 --- a/src/Os/Network/UdpServer.cpp +++ b/src/Os/Network/UdpServer.cpp @@ -19,8 +19,7 @@ UdpServer::UdpServer(Ipv4::Port port) noexcept : NetworkBase(socket::createUdpSe UdpServer &UdpServer::operator=(UdpServer &&server) noexcept { - NetworkBase &&base = static_cast(server); - operator=(move(base)); + operator=(move(static_cast(server))); return *this; } From 5898af198aa94a119b54f790453d9af1e7a48110 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Wed, 25 Sep 2024 04:25:34 +0500 Subject: [PATCH 11/37] Change returning type in 'Handler::ServerHandle::getSessionHandle()' --- include/FlameIDE/Handler/Network/Handler.hpp | 16 ++++++++-------- src/Handler/Network/ServerHandle.cpp | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/FlameIDE/Handler/Network/Handler.hpp b/include/FlameIDE/Handler/Network/Handler.hpp index cd7265e2..35644d0d 100644 --- a/include/FlameIDE/Handler/Network/Handler.hpp +++ b/include/FlameIDE/Handler/Network/Handler.hpp @@ -135,14 +135,14 @@ class Handler::ServerHandle /// @brief getSessionHandle /// @return /// - Handler::SessionHandle getSessionHandle() noexcept; + Handler::ExpectedSessionHandle getSessionHandle() noexcept; private: friend class Handler::Internal; friend class Handler::Udp; friend class Handler::Tcp; - using CallbackGetSessionHandle = Handler::SessionHandle (*)(void *); + using CallbackGetSessionHandle = Handler::ExpectedSessionHandle (*)(void *); private: void *data = nullptr; @@ -195,13 +195,13 @@ class Handler::SessionHandle private: static constexpr Types::size_t OBJECT_SIZE = 64; - using Object = templates::Object; - using CallbackBytesToRead = Types::ssize_t (*)(const Object *); - using CallbackReceive = Types::ssize_t (*)( - Object *, flame_ide::templates::Range + using Object = ::flame_ide::templates::Object; + using CallbackBytesToRead = ::flame_ide::Types::ssize_t (*)(const Object *); + using CallbackReceive = ::flame_ide::Types::ssize_t (*)( + Object *, ::flame_ide::templates::Range ); - using CallbackSend = Types::ssize_t (*)( - Object *, flame_ide::templates::Range + using CallbackSend = ::flame_ide::Types::ssize_t (*)( + Object *, ::flame_ide::templates::Range ); private: diff --git a/src/Handler/Network/ServerHandle.cpp b/src/Handler/Network/ServerHandle.cpp index 381e1746..7f91396d 100644 --- a/src/Handler/Network/ServerHandle.cpp +++ b/src/Handler/Network/ServerHandle.cpp @@ -10,7 +10,7 @@ Handler::ServerHandle::operator bool() const noexcept return data && callbackGetSessionHandle; } -Handler::SessionHandle Handler::ServerHandle::getSessionHandle() noexcept +Handler::ExpectedSessionHandle Handler::ServerHandle::getSessionHandle() noexcept { return callbackGetSessionHandle(data); } From 14f1f6e160f346ba3fd930bb63968be016860183 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Wed, 25 Sep 2024 04:30:10 +0500 Subject: [PATCH 12/37] Multiple changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Handler::Tcp и Handler::Udp move to their files 2. Add implementations of callbacks to Handler::Upd 3. Move udp::ServerCommunicationData and udp::ClientCommunicationData to storage types 4. Fix macro guards --- src/Handler/Network/Headers.cmake | 2 + src/Handler/Network/Internal.cpp | 68 +------- src/Handler/Network/Internal.hpp | 57 +------ src/Handler/Network/Sources.cmake | 2 + src/Handler/Network/Tcp.cpp | 32 ++++ src/Handler/Network/Tcp.hpp | 40 +++++ src/Handler/Network/Tcp/InternalData.cpp | 12 +- src/Handler/Network/Tcp/Tcp.hpp | 6 +- src/Handler/Network/Udp.cpp | 188 +++++++++++++++++++++++ src/Handler/Network/Udp.hpp | 81 ++++++++++ src/Handler/Network/Udp/Client.hpp | 7 + src/Handler/Network/Udp/InternalData.cpp | 57 +------ src/Handler/Network/Udp/InternalData.hpp | 22 --- src/Handler/Network/Udp/Server.hpp | 6 + src/Handler/Network/Udp/Types.hpp | 62 ++++++++ src/Handler/Network/Udp/Udp.hpp | 6 +- 16 files changed, 441 insertions(+), 207 deletions(-) create mode 100644 src/Handler/Network/Tcp.cpp create mode 100644 src/Handler/Network/Tcp.hpp create mode 100644 src/Handler/Network/Udp.cpp create mode 100644 src/Handler/Network/Udp.hpp diff --git a/src/Handler/Network/Headers.cmake b/src/Handler/Network/Headers.cmake index addd311d..42a58c4e 100644 --- a/src/Handler/Network/Headers.cmake +++ b/src/Handler/Network/Headers.cmake @@ -1,5 +1,7 @@ set (HEADER_LIST ${CMAKE_CURRENT_SOURCE_DIR}/Functions.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Internal.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Tcp.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Udp.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Worker.hpp ) diff --git a/src/Handler/Network/Internal.cpp b/src/Handler/Network/Internal.cpp index e9aa35f5..1b0d4edc 100644 --- a/src/Handler/Network/Internal.cpp +++ b/src/Handler/Network/Internal.cpp @@ -10,76 +10,10 @@ namespace flame_ide {namespace network { -// Hanler::Udp - -Handler::ExpectedServerHandle Handler::Udp::push(os::network::UdpServer &&server) noexcept -{ - flame_ide::unused(server); - - udp::Server *udpServer = udp.push(move(server)); - flame_ide::unused(udpServer); - return { os::STATUS_FAILED }; -} - -Handler::ExpectedSessionHandle Handler::Udp::push(os::network::UdpClient &&client) noexcept -{ - flame_ide::unused(client); - - udp::Client *udpClient = udp.push(move(client)); - flame_ide::unused(udpClient); - return { os::STATUS_FAILED }; -} - -Handler::ExpectedUdpServer Handler::Udp::pop(Handler::ServerHandle &handle) -{ - flame_ide::unused(handle); - return { os::STATUS_FAILED }; -} - -Handler::ExpectedUdpClient Handler::Udp::pop(Handler::SessionHandle &handle) -{ - flame_ide::unused(handle); - return { os::STATUS_FAILED }; -} - -// Handler::Tcp - -Handler::ExpectedServerHandle Handler::Tcp::push(os::network::TcpServer &&server) noexcept -{ - flame_ide::unused(server); - return { os::STATUS_FAILED }; -} - -Handler::ExpectedSessionHandle Handler::Tcp::push(os::network::TcpClient &&client) noexcept -{ - flame_ide::unused(client); - return { os::STATUS_FAILED }; -} - -Handler::ExpectedTcpServer Handler::Tcp::pop(Handler::ServerHandle &handle) -{ - flame_ide::unused(handle); - return { os::STATUS_FAILED }; -} - -Handler::ExpectedTcpClient Handler::Tcp::pop(Handler::SessionHandle &handle) -{ - flame_ide::unused(handle); - return { os::STATUS_FAILED }; -} - -}}} // namespace flame_ide::handler::network - -// Handler::Internal implementation -namespace flame_ide -{namespace handler -{namespace network -{ - Handler::Internal::Internal() noexcept {} -Handler::Internal::~Internal() = default; +Handler::Internal::~Internal() noexcept = default; Handler::Udp &Handler::Internal::udp() noexcept { diff --git a/src/Handler/Network/Internal.hpp b/src/Handler/Network/Internal.hpp index 1762ac71..ce5edd1d 100644 --- a/src/Handler/Network/Internal.hpp +++ b/src/Handler/Network/Internal.hpp @@ -6,65 +6,14 @@ #include #include -#include -#include +#include +#include #include namespace flame_ide {namespace handler {namespace network { - -class Handler::Udp -{ -public: - using CallbackGetSessionHandle = Handler::ServerHandle::CallbackGetSessionHandle; - -public: - // TODO - Handler::ExpectedServerHandle push(os::network::UdpServer &&server) noexcept; - // TODO - Handler::ExpectedSessionHandle push(os::network::UdpClient &&client) noexcept; - - // TODO - Handler::ExpectedUdpServer pop(Handler::ServerHandle &handle); - // TODO - Handler::ExpectedUdpClient pop(Handler::SessionHandle &handle); - - /// @brief serverHandleCallback - /// @return - // TODO - CallbackGetSessionHandle serverHandleCallback() const noexcept; - -private: - udp::Udp udp; -}; - -class Handler::Tcp -{ -public: - using CallbackGetSessionHandle = Handler::ServerHandle::CallbackGetSessionHandle; - -public: - // TODO - Handler::ExpectedServerHandle push(os::network::TcpServer &&server) noexcept; - // TODO - Handler::ExpectedSessionHandle push(os::network::TcpClient &&client) noexcept; - - // TODO - Handler::ExpectedTcpServer pop(Handler::ServerHandle &handle); - // TODO - Handler::ExpectedTcpClient pop(Handler::SessionHandle &handle); - - /// @brief serverHandleCallback - /// @return - // TODO - CallbackGetSessionHandle serverHandleCallback() const noexcept; - -private: - tcp::Tcp tcp; -}; - }}} // namespace flame_ide::handler::network namespace flame_ide @@ -94,12 +43,10 @@ class Handler::Internal /// @brief start /// @return - // TODO os::Status start() noexcept; /// @brief stop /// @return - // TODO os::Status stop() noexcept; private: diff --git a/src/Handler/Network/Sources.cmake b/src/Handler/Network/Sources.cmake index 570fb26b..46e3e35a 100644 --- a/src/Handler/Network/Sources.cmake +++ b/src/Handler/Network/Sources.cmake @@ -3,5 +3,7 @@ set (SOURCE_LIST ${CMAKE_CURRENT_SOURCE_DIR}/Handler.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Internal.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ServerHandle.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Tcp.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Udp.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Worker.cpp ) diff --git a/src/Handler/Network/Tcp.cpp b/src/Handler/Network/Tcp.cpp new file mode 100644 index 00000000..f17f6d2f --- /dev/null +++ b/src/Handler/Network/Tcp.cpp @@ -0,0 +1,32 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{ + +Handler::ExpectedServerHandle Handler::Tcp::push(os::network::TcpServer &&server) noexcept +{ + flame_ide::unused(server); + return { os::STATUS_FAILED }; +} + +Handler::ExpectedSessionHandle Handler::Tcp::push(os::network::TcpClient &&client) noexcept +{ + flame_ide::unused(client); + return { os::STATUS_FAILED }; +} + +Handler::ExpectedTcpServer Handler::Tcp::pop(Handler::ServerHandle &handle) +{ + flame_ide::unused(handle); + return { os::STATUS_FAILED }; +} + +Handler::ExpectedTcpClient Handler::Tcp::pop(Handler::SessionHandle &handle) +{ + flame_ide::unused(handle); + return { os::STATUS_FAILED }; +} + +}}} // namespace flame_ide::handler::network diff --git a/src/Handler/Network/Tcp.hpp b/src/Handler/Network/Tcp.hpp new file mode 100644 index 00000000..b534dbc4 --- /dev/null +++ b/src/Handler/Network/Tcp.hpp @@ -0,0 +1,40 @@ +#ifndef HANDLERINTERNALTCP_HPP +#define HANDLERINTERNALTCP_HPP + +#include + +#include + +namespace flame_ide +{namespace handler +{namespace network +{ + +class Handler::Tcp +{ +public: + using CallbackGetSessionHandle = Handler::ServerHandle::CallbackGetSessionHandle; + +public: + // TODO + Handler::ExpectedServerHandle push(os::network::TcpServer &&server) noexcept; + // TODO + Handler::ExpectedSessionHandle push(os::network::TcpClient &&client) noexcept; + + // TODO + Handler::ExpectedTcpServer pop(Handler::ServerHandle &handle); + // TODO + Handler::ExpectedTcpClient pop(Handler::SessionHandle &handle); + + /// @brief serverHandleCallback + /// @return + // TODO + CallbackGetSessionHandle serverHandleCallback() const noexcept; + +private: + tcp::Tcp tcp; +}; + +}}} // namespace flame_ide::handler::network + +#endif // HANDLERINTERNALTCP_HPP diff --git a/src/Handler/Network/Tcp/InternalData.cpp b/src/Handler/Network/Tcp/InternalData.cpp index ebe14443..872578ee 100644 --- a/src/Handler/Network/Tcp/InternalData.cpp +++ b/src/Handler/Network/Tcp/InternalData.cpp @@ -10,19 +10,19 @@ namespace flame_ide // client // TODO -Types::ssize_t clientBytesToRead(void */*data*/) noexcept +Types::ssize_t clientBytesToRead(void * /* data */) noexcept { return os::STATUS_FAILED; } // TODO -Types::ssize_t clientReceive(void */*data*/, templates::Range) noexcept +Types::ssize_t clientReceive(void * /* data */, templates::Range) noexcept { return os::STATUS_FAILED; } // TODO -Types::ssize_t clientSend(void */*data*/, templates::Range) noexcept +Types::ssize_t clientSend(void * /* data */, templates::Range) noexcept { return os::STATUS_FAILED; } @@ -30,19 +30,19 @@ Types::ssize_t clientSend(void */*data*/, templates::Range) noex // server // TODO -Types::ssize_t serverBytesToRead(void */*data*/) noexcept +Types::ssize_t serverBytesToRead(void * /* data */) noexcept { return os::STATUS_FAILED; } // TODO -Types::ssize_t serverReceive(void */*data*/, templates::Range) noexcept +Types::ssize_t serverReceive(void * /* data */, templates::Range) noexcept { return os::STATUS_FAILED; } // TODO -Types::ssize_t serverSend(void */*data*/, templates::Range) noexcept +Types::ssize_t serverSend(void * /* data */, templates::Range) noexcept { return os::STATUS_FAILED; } diff --git a/src/Handler/Network/Tcp/Tcp.hpp b/src/Handler/Network/Tcp/Tcp.hpp index a7d0893a..87e328ba 100644 --- a/src/Handler/Network/Tcp/Tcp.hpp +++ b/src/Handler/Network/Tcp/Tcp.hpp @@ -1,5 +1,5 @@ -#ifndef HANDLERINTERNALTCP_HPP -#define HANDLERINTERNALTCP_HPP +#ifndef HANDLERINTERNALTCPTCP_HPP +#define HANDLERINTERNALTCPTCP_HPP #include #include @@ -70,4 +70,4 @@ struct Tcp }}}} // namespace flame_ide::handler::network::tcp -#endif // HANDLERINTERNALTCP_HPP +#endif // HANDLERINTERNALTCPTCP_HPP diff --git a/src/Handler/Network/Udp.cpp b/src/Handler/Network/Udp.cpp new file mode 100644 index 00000000..73fd2cfd --- /dev/null +++ b/src/Handler/Network/Udp.cpp @@ -0,0 +1,188 @@ +#include + +#include + +namespace flame_ide +{namespace handler +{namespace network +{ + +Handler::ExpectedServerHandle Handler::Udp::push(os::network::UdpServer &&server) noexcept +{ + udp::Server *udpServer = udp.push(move(server)); + if (!udpServer) + return { os::STATUS_FAILED }; + + Handler::ServerHandle handle; + handle.data = udpServer; + handle.callbackGetSessionHandle = serverHandleCallback(); + flame_ide::unused(handle); + + // TODO + return { os::STATUS_FAILED }; +} + +Handler::ExpectedSessionHandle Handler::Udp::push(os::network::UdpClient &&client) noexcept +{ + udp::Client *udpClient = udp.push(move(client)); + flame_ide::unused(udpClient); + + Handler::SessionHandle handle; + flame_ide::unused(handle); + + return { os::STATUS_FAILED }; +} + +Handler::ExpectedUdpServer Handler::Udp::pop(Handler::ServerHandle &handle) +{ + flame_ide::unused(handle); + + // TODO + return { os::STATUS_FAILED }; +} + +Handler::ExpectedUdpClient Handler::Udp::pop(Handler::SessionHandle &handle) +{ + flame_ide::unused(handle); + + // TODO + return { os::STATUS_FAILED }; +} + +Handler::Udp::CallbackGetSessionHandle Handler::Udp::serverHandleCallback() const noexcept +{ + static const auto callback = [](udp::Server *handlerServer) + -> Handler::ExpectedSessionHandle + { + if (!handlerServer) + return { os::STATUS_FAILED }; + + // В очередь приходят сообщения + auto *message = handlerServer->input().getFilledMessage(); + if (!message) + return { os::STATUS_FAILED }; + + // TODO: надо в самом сообщении это делать + { + flame_ide::os::threads::Locker messageLock{ message->spin }; + if (message->state != udp::MessageState::READY) + return { os::STATUS_FAILED }; + + message->state = udp::MessageState::PROCESSING; + } + + Handler::SessionHandle sessionHandle; + sessionHandle.object = Handler::SessionHandle::Object{ + udp::ServerCommunicationData{ message, &handlerServer->output() } + }; + sessionHandle.callbackBytesToRead = Handler::Udp::serverCallbackBytesToRead(); + sessionHandle.callbackReceive = Handler::Udp::serverCallbackReceive(); + sessionHandle.callbackSend = Handler::Udp::serverCallbackSend(); + ::flame_ide::unused(sessionHandle); + + return { os::STATUS_FAILED }; + }; + return reinterpret_cast(+callback); +}; + +udp::ServerCommunicationData * +Handler::Udp::serverToCommunicationData(Handler::SessionHandle::Object &object) noexcept +{ + if (!object) + return nullptr; + + return &object.get(); +} + +const udp::ServerCommunicationData *Handler::Udp::serverToConstCommunicationData( + const Handler::SessionHandle::Object &object +) noexcept +{ + if (!object) + return nullptr; + + return &object.get(); +} + +Handler::Udp::CallbackBytesToRead Handler::Udp::serverCallbackBytesToRead() noexcept +{ + static const auto callback = [](const Handler::SessionHandle::Object *object) + -> ::flame_ide::Types::ssize_t + { + const auto *data = Handler::Udp::serverToConstCommunicationData(*object); + flame_ide::os::threads::Locker lock{ data->message->spin }; + return data->message->size; + }; + return reinterpret_cast(+callback); +} + +Handler::Udp::CallbackReceive Handler::Udp::serverCallbackReceive() noexcept +{ + static const auto callback = []( + Handler::SessionHandle::Object *object + , ::flame_ide::templates::Range range + ) -> ::flame_ide::Types::ssize_t + { + auto *data = Handler::Udp::serverToCommunicationData(*object); + if (!data) + return -1; + + const auto *message = data->message; + if (!message) + return -1; + + ::flame_ide::Types::ssize_t readData = -1; + { + flame_ide::os::threads::Locker lock{ message->spin }; + + const auto min = ::flame_ide::minimum<::flame_ide::Types::ssize_t>( + (range.end() - range.begin()), message->size + ); + ::flame_ide::templates::copy( + message->bytes.begin(), message->bytes.begin() + min, range.begin() + ); + + data->message->state = udp::MessageState::EMPTY; + data->message->size = 0; + + readData = min; + } + return readData; + }; + return reinterpret_cast(+callback); +} + +Handler::Udp::CallbackSend Handler::Udp::serverCallbackSend() noexcept +{ + static const auto callback = []( + Handler::SessionHandle::Object *object + , ::flame_ide::templates::Range range + ) -> ::flame_ide::Types::ssize_t + { + auto *data = Handler::Udp::serverToCommunicationData(*object); + if (!data) + return -1; + + auto *message = data->output->getEmptyMessage(); + if (!message) + return -1; + + { + flame_ide::os::threads::Locker lock{ message->spin }; + + const auto min = ::flame_ide::minimum<::flame_ide::Types::ssize_t>( + (range.end() - range.begin()), message->bytes.capacity() + ); + ::flame_ide::templates::copy( + range.begin(), range.begin() + min, message->bytes.begin() + ); + + message->state = udp::MessageState::READY; + message->size = min; + } + return message->size; + }; + return reinterpret_cast(+callback); +} + +}}} // namespace flame_ide::handler::network diff --git a/src/Handler/Network/Udp.hpp b/src/Handler/Network/Udp.hpp new file mode 100644 index 00000000..e1d801ba --- /dev/null +++ b/src/Handler/Network/Udp.hpp @@ -0,0 +1,81 @@ +#ifndef HANDLERINTERNALUDP_HPP +#define HANDLERINTERNALUDP_HPP + +#include + +#include + +namespace flame_ide +{namespace handler +{namespace network +{ + +class Handler::Udp +{ +public: + using CallbackGetSessionHandle = Handler::ServerHandle::CallbackGetSessionHandle; + + using CallbackBytesToRead = Handler::SessionHandle::CallbackBytesToRead; + using CallbackReceive = Handler::SessionHandle::CallbackReceive; + using CallbackSend = Handler::SessionHandle::CallbackSend; + +public: + // TODO + Handler::ExpectedServerHandle push(os::network::UdpServer &&server) noexcept; + // TODO + Handler::ExpectedSessionHandle push(os::network::UdpClient &&client) noexcept; + + // TODO + Handler::ExpectedUdpServer pop(Handler::ServerHandle &handle); + // TODO + Handler::ExpectedUdpClient pop(Handler::SessionHandle &handle); + + /// @brief serverHandleCallback + /// @return + CallbackGetSessionHandle serverHandleCallback() const noexcept; + +private: + /// + /// \brief serverToCommunicationData + /// \param object + /// \return + /// + static udp::ServerCommunicationData *serverToCommunicationData( + Handler::SessionHandle::Object &object + ) noexcept; + + /// + /// \brief serverToConstCommunicationData + /// \param object + /// \return + /// + static const udp::ServerCommunicationData *serverToConstCommunicationData( + const Handler::SessionHandle::Object &object + ) noexcept; + + /// + /// \brief serverCallbackBytesToRead + /// \return + /// + static CallbackBytesToRead serverCallbackBytesToRead() noexcept; + + /// + /// \brief serverCallbackReceive + /// \return + /// + static CallbackReceive serverCallbackReceive() noexcept; + + /// + /// \brief serverCallbackSend + /// \return + /// + // TODO + static CallbackSend serverCallbackSend() noexcept; + +private: + udp::Udp udp; +}; + +}}} // namespace flame_ide::handler::network + +#endif // HANDLERINTERNALUDP_HPP diff --git a/src/Handler/Network/Udp/Client.hpp b/src/Handler/Network/Udp/Client.hpp index 068605cb..a0659629 100644 --- a/src/Handler/Network/Udp/Client.hpp +++ b/src/Handler/Network/Udp/Client.hpp @@ -33,6 +33,13 @@ class Client: public ClientEndpoint } }; +struct ClientCommunicationData +{ + os::network::UdpClient *client; + ClientMessage *message; + Client::ActualOutput *output; +}; + }}}} // namespace flame_ide::handler::network::udp #endif // HANDLERINTERNALUDPCLIENT_HPP diff --git a/src/Handler/Network/Udp/InternalData.cpp b/src/Handler/Network/Udp/InternalData.cpp index bcbfe295..3af2b2dc 100644 --- a/src/Handler/Network/Udp/InternalData.cpp +++ b/src/Handler/Network/Udp/InternalData.cpp @@ -25,32 +25,12 @@ serverReceive( udp::ServerCommunicationData *data, templates::Range range ) noexcept { + flame_ide::unused(range); + if (!data || !data->message) return os::STATUS_FAILED; - Types::ssize_t numberToRead = 0; - auto &message = *data->message; - { - os::threads::Locker{ message.spin }; - - const Types::ssize_t rangeSize = range.end() - range.begin(); - const Types::ssize_t messageSize = message.size; - const Types::ssize_t toRead = (rangeSize < messageSize) - ? rangeSize - : messageSize; - - auto begin = range.begin(); - for (Types::ssize_t i = 0; i < toRead; ++i, ++begin) - { - *begin = message.bytes[i]; - } - message.size = 0; - message.client = decltype(message.client){}; - message.state = MessageState::EMPTY; - - numberToRead = toRead; - } - return numberToRead; + return os::STATUS_FAILED; } Types::ssize_t @@ -58,36 +38,11 @@ serverSend( udp::ServerCommunicationData *data, templates::Range range ) noexcept { + flame_ide::unused(range); + if (!data || !data->output) return os::STATUS_FAILED; - - auto &output = *data->output; - ServerMessage *message = nullptr; - { - os::threads::Locker outputLocker{ output.spin }; - message = output.last->pointer(); - { - os::threads::Locker messageLocker{ message->spin }; - message->state = MessageState::PROCESSING; - } - ++output.last; - } - - const Types::ssize_t rangeSize = range.end() - range.begin(); - { - os::threads::Locker locker{ message->spin }; - message->size = rangeSize; - message->client = data->client; - - auto begin = range.begin(); - for (Types::ssize_t i = 0; i < rangeSize; ++i, ++begin) - { - message->bytes[i] = *begin; - } - - message->state = MessageState::READY; - } - return rangeSize; + return os::STATUS_FAILED; } // client diff --git a/src/Handler/Network/Udp/InternalData.hpp b/src/Handler/Network/Udp/InternalData.hpp index 0a04858c..286ef79c 100644 --- a/src/Handler/Network/Udp/InternalData.hpp +++ b/src/Handler/Network/Udp/InternalData.hpp @@ -4,28 +4,6 @@ #include #include -namespace flame_ide -{namespace handler -{namespace network -{namespace udp -{ - -struct ServerCommunicationData -{ - os::network::UdpServer::WithClient client; - ServerMessage *message; - Server::ActualOutput *output; -}; - -struct ClientCommunicationData -{ - os::network::UdpClient *client; - ServerMessage *message; - Server::ActualOutput *output; -}; - -}}}} // namespace flame_ide::os::network::udp - namespace flame_ide {namespace handler {namespace network diff --git a/src/Handler/Network/Udp/Server.hpp b/src/Handler/Network/Udp/Server.hpp index 69c7f92c..00009a8e 100644 --- a/src/Handler/Network/Udp/Server.hpp +++ b/src/Handler/Network/Udp/Server.hpp @@ -34,6 +34,12 @@ class Server: public ServerEndpoint } }; +struct ServerCommunicationData +{ + ServerMessage *message; + Server::ActualOutput *output; +}; + }}}} // namespace flame_ide::handler::network::udp #endif // HANDLERINTERNALUDPSERVER_HPP diff --git a/src/Handler/Network/Udp/Types.hpp b/src/Handler/Network/Udp/Types.hpp index a2055528..fd88f3d8 100644 --- a/src/Handler/Network/Udp/Types.hpp +++ b/src/Handler/Network/Udp/Types.hpp @@ -9,6 +9,7 @@ #include #include +#include #include @@ -39,6 +40,7 @@ struct Message template struct ActualData { +public: using Messages = flame_ide::templates::StaticArray< flame_ide::templates::UniquePointer, SIZE >; @@ -47,6 +49,12 @@ struct ActualData typename Messages::Iterator >; + MessageType *getEmptyMessage() noexcept; + + MessageType *getFilledMessage() noexcept; + +private: + ::flame_ide::Types::size_t amount = 0; Messages messages; MessagesCircularIterator first = MessagesCircularIterator{ messages.begin() @@ -94,6 +102,36 @@ namespace flame_ide {namespace udp { +// ActualData + +template +MessageType *ActualData::getEmptyMessage() noexcept +{ + os::threads::Locker lock{ spin }; + + if (amount == SIZE) + return nullptr; + + auto result = last; + ++amount; + ++last; + return result->pointer(); +} + +template +MessageType *ActualData::getFilledMessage() noexcept +{ + os::threads::Locker lock{ spin }; + + if ((first == last) && (amount == 0)) + return nullptr; + + auto result = first; + --amount; + ++first; + return result->pointer(); +} + // Endpoint template< @@ -163,6 +201,30 @@ Endpoint::endpoint() const n return osEndpoint; } +template< + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE +> +typename Endpoint::ActualInput & +Endpoint::input() noexcept +{ + return actualInput; +} + +template< + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE +> +typename Endpoint::ActualOutput & +Endpoint::output() noexcept +{ + return actualOutput; +} + }}}} // namespace flame_ide::handler::network::udp #endif // HANDLERINTERNALUDPTYPES_HPP diff --git a/src/Handler/Network/Udp/Udp.hpp b/src/Handler/Network/Udp/Udp.hpp index 095bad96..ab416b26 100644 --- a/src/Handler/Network/Udp/Udp.hpp +++ b/src/Handler/Network/Udp/Udp.hpp @@ -1,5 +1,5 @@ -#ifndef HANDLERINTERNALUDP_HPP -#define HANDLERINTERNALUDP_HPP +#ifndef HANDLERINTERNALUDPUDP_HPP +#define HANDLERINTERNALUDPUDP_HPP #include #include @@ -133,4 +133,4 @@ Udp::getData>() noexcept }}}} // namespace flame_ide::handler::network::udp -#endif // HANDLERINTERNALUDP_HPP +#endif // HANDLERINTERNALUDPUDP_HPP From 6b387c8bbf4c398cbba903dc9b8869f773fac268 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Sun, 15 Dec 2024 03:35:30 +0500 Subject: [PATCH 13/37] Common/Expected: add 'ifResultGet()' and 'ifErrorGet()' for change data w/o moving --- include/FlameIDE/Common/Expected.hpp | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/include/FlameIDE/Common/Expected.hpp b/include/FlameIDE/Common/Expected.hpp index 9745f0e8..e83446c1 100644 --- a/include/FlameIDE/Common/Expected.hpp +++ b/include/FlameIDE/Common/Expected.hpp @@ -36,11 +36,17 @@ class Expected template const Me &ifResult(Functor &&functor) const noexcept; + template + Me &ifResultGet(Functor &&functor) noexcept; + template Me &ifError(Functor &&functor) noexcept; template const Me &ifError(Functor &&functor) const noexcept; + template + Me &ifErrorGet(Functor &&functor) noexcept; + void done() noexcept; void done() const noexcept; @@ -221,6 +227,19 @@ Expected::ifResult(Functor &&functor) const noexcept return *this; } +template +template +Expected & +Expected::ifResultGet(Functor &&functor) noexcept +{ + if (State::RESULT != data.state) + return *this; + + functor(data.result.value); + + return *this; +} + template template Expected & @@ -248,6 +267,19 @@ Expected::ifError(Functor &&functor) const noexcept return *this; } +template +template +Expected & +Expected::ifErrorGet(Functor &&functor) noexcept +{ + if (State::ERROR != data.state) + return *this; + + functor(data.error.value); + + return *this; +} + template inline void Expected::done() noexcept {} From a8cc028a3f5aa19d4c9873225c2a2711a7d2dc65 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Sun, 15 Dec 2024 03:36:29 +0500 Subject: [PATCH 14/37] Common/ReferenceWrapper: update, add default copy/move ctorss add assign operators --- include/FlameIDE/Common/ReferenceWrapper.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/FlameIDE/Common/ReferenceWrapper.hpp b/include/FlameIDE/Common/ReferenceWrapper.hpp index 34269554..2fbe7774 100644 --- a/include/FlameIDE/Common/ReferenceWrapper.hpp +++ b/include/FlameIDE/Common/ReferenceWrapper.hpp @@ -13,9 +13,13 @@ template> class ReferenceWrapper { public: + using Me = ReferenceWrapper; using Pointer = typename Traits::Pointer; using Reference = typename Traits::Reference; + ReferenceWrapper(const Me &) noexcept = default; + ReferenceWrapper(Me &&) noexcept = default; + /// /// @brief ReferenceWrapper /// @param initValue @@ -28,6 +32,9 @@ class ReferenceWrapper /// ReferenceWrapper(Reference initValue) noexcept; + Me &operator=(const Me &) noexcept = default; + Me &operator=(Me &&) noexcept = default; + /// /// @brief get /// @return From 81ebedd992d4265013cd79a4c39ecbbb2b74894f Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Sun, 15 Dec 2024 03:39:46 +0500 Subject: [PATCH 15/37] Handler/Network/Tests: fix tests location --- src/Handler/Tests/CMakeLists.txt | 4 +++ src/Handler/Tests/Network/CMakeLists.txt | 8 +++++ src/Handler/Tests/Network/Sources.cmake | 4 --- src/Handler/Tests/Network/Tcp/CMakeLists.txt | 29 +++++++++++++++++++ .../{TcpQueueTest.cpp => Tcp/QueueTest.cpp} | 15 +++++----- .../{TcpQueueTest.hpp => Tcp/QueueTest.hpp} | 9 +++--- src/Handler/Tests/Network/Tcp/Sources.cmake | 4 +++ src/Handler/Tests/Network/Udp/CMakeLists.txt | 29 +++++++++++++++++++ src/Handler/Tests/Network/Udp/Sources.cmake | 4 +++ .../{UdpQueueTest.cpp => Udp/StorageTest.cpp} | 25 ++++++++-------- src/Handler/Tests/Network/Udp/StorageTest.hpp | 29 +++++++++++++++++++ src/Handler/Tests/Network/UdpQueueTest.hpp | 28 ------------------ src/Handler/Tests/TestAggregator.cpp | 12 +++++--- 13 files changed, 141 insertions(+), 59 deletions(-) create mode 100644 src/Handler/Tests/Network/Tcp/CMakeLists.txt rename src/Handler/Tests/Network/{TcpQueueTest.cpp => Tcp/QueueTest.cpp} (71%) rename src/Handler/Tests/Network/{TcpQueueTest.hpp => Tcp/QueueTest.hpp} (69%) create mode 100644 src/Handler/Tests/Network/Tcp/Sources.cmake create mode 100644 src/Handler/Tests/Network/Udp/CMakeLists.txt create mode 100644 src/Handler/Tests/Network/Udp/Sources.cmake rename src/Handler/Tests/Network/{UdpQueueTest.cpp => Udp/StorageTest.cpp} (52%) create mode 100644 src/Handler/Tests/Network/Udp/StorageTest.hpp delete mode 100644 src/Handler/Tests/Network/UdpQueueTest.hpp diff --git a/src/Handler/Tests/CMakeLists.txt b/src/Handler/Tests/CMakeLists.txt index bee5ba08..d8bd9460 100644 --- a/src/Handler/Tests/CMakeLists.txt +++ b/src/Handler/Tests/CMakeLists.txt @@ -23,9 +23,13 @@ set(SHARED_ALIAS_NAME "${FLAME_NAMESPACE}::${NAME_ALIAS}::Shared") set(DEPEND_OBJECTS "${FLAME_NAMESPACE}::Handler::Network::Test::Object" + "${FLAME_NAMESPACE}::Handler::Network::Udp::Test::Object" + "${FLAME_NAMESPACE}::Handler::Network::Tcp::Test::Object" ) set(INDEPEND_OBJECTS "${FLAME_NAMESPACE}::Handler::Network::Test::Object::Independ" + "${FLAME_NAMESPACE}::Handler::Network::Udp::Test::Object::Independ" + "${FLAME_NAMESPACE}::Handler::Network::Tcp::Test::Object::Independ" ) set(MAIN_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp") diff --git a/src/Handler/Tests/Network/CMakeLists.txt b/src/Handler/Tests/Network/CMakeLists.txt index a4c087fd..c3a1fe1f 100644 --- a/src/Handler/Tests/Network/CMakeLists.txt +++ b/src/Handler/Tests/Network/CMakeLists.txt @@ -27,3 +27,11 @@ flame_compile_library( NO_RTTI EXCEPTIONS ) + +set(SOURCE_MODULES + ${CMAKE_CURRENT_LIST_DIR}/Udp + ${CMAKE_CURRENT_LIST_DIR}/Tcp +) +foreach(module ${SOURCE_MODULES}) + add_subdirectory(${module}) +endforeach() diff --git a/src/Handler/Tests/Network/Sources.cmake b/src/Handler/Tests/Network/Sources.cmake index 5fc038bd..52e6858a 100644 --- a/src/Handler/Tests/Network/Sources.cmake +++ b/src/Handler/Tests/Network/Sources.cmake @@ -3,10 +3,6 @@ set (SOURCE_LIST ${CMAKE_CURRENT_SOURCE_DIR}/HandlerTest.hpp ${CMAKE_CURRENT_SOURCE_DIR}/InternalTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/InternalTest.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/TcpQueueTest.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/TcpQueueTest.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/UdpQueueTest.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/UdpQueueTest.hpp ${CMAKE_CURRENT_SOURCE_DIR}/WorkerTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/WorkerTest.hpp ) diff --git a/src/Handler/Tests/Network/Tcp/CMakeLists.txt b/src/Handler/Tests/Network/Tcp/CMakeLists.txt new file mode 100644 index 00000000..7b5b7e3a --- /dev/null +++ b/src/Handler/Tests/Network/Tcp/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.14) + +if(NOT FLAME_TESTING) + return() +endif() + +set(NAME "Handler.Network.Tcp.Test") +set(NAME_ALIAS "Handler::Network::Tcp::Test") + +get_sources(FILE_LIST) + +set(DEPENDENCY_HEADER_TARGETS + "${FLAME_NAMESPACE}::Handler::Network::Headers" +) + +flame_compile_library( + NAME "${NAME}" + SOURCE_LIST "${FILE_LIST}" + INCLUDE_PATHS "${INCLUDE_PATHS}" "${CMAKE_BINARY_DIR}/generated/include" + DEPENDENCY_HEADER_TARGETS "${DEPENDENCY_HEADER_TARGETS}" + + OBJECT_ALIAS_NAME + "${FLAME_NAMESPACE}::${NAME_ALIAS}::Object" + INDEPENDENT_OBJECT_ALIAS_NAME + "${FLAME_NAMESPACE}::${NAME_ALIAS}::Object::Independ" + + NO_RTTI + EXCEPTIONS +) diff --git a/src/Handler/Tests/Network/TcpQueueTest.cpp b/src/Handler/Tests/Network/Tcp/QueueTest.cpp similarity index 71% rename from src/Handler/Tests/Network/TcpQueueTest.cpp rename to src/Handler/Tests/Network/Tcp/QueueTest.cpp index 364bed2f..f9488c6d 100644 --- a/src/Handler/Tests/Network/TcpQueueTest.cpp +++ b/src/Handler/Tests/Network/Tcp/QueueTest.cpp @@ -1,18 +1,19 @@ -#include +#include #include namespace flame_ide {namespace handler {namespace network +{namespace tcp {namespace tests { -TcpQueueTest::TcpQueueTest() : ::AbstractTest("TcpQueue") +QueueTest::QueueTest() : ::AbstractTest("tcp::Queue") {} -TcpQueueTest::~TcpQueueTest() = default; +QueueTest::~QueueTest() = default; -int TcpQueueTest::vStart() +int QueueTest::vStart() { CHECK_RESULT_SUCCESS(doTestCase( "initialization" @@ -27,13 +28,13 @@ int TcpQueueTest::vStart() return ResultType::SUCCESS; } -int TcpQueueTest::init() +int QueueTest::init() { tcp::Tcp tcp; return ResultType::SUCCESS; } -int TcpQueueTest::serverPushPop() +int QueueTest::serverPushPop() { tcp::Tcp tcp; os::network::TcpServer server{ 65001 }; @@ -49,4 +50,4 @@ int TcpQueueTest::serverPushPop() return ResultType::SUCCESS; } -}}}} // namespace flame_ide::handler::network::tests +}}}}} // namespace flame_ide::handler::network::tcp::tests diff --git a/src/Handler/Tests/Network/TcpQueueTest.hpp b/src/Handler/Tests/Network/Tcp/QueueTest.hpp similarity index 69% rename from src/Handler/Tests/Network/TcpQueueTest.hpp rename to src/Handler/Tests/Network/Tcp/QueueTest.hpp index 7d5f899d..0af5c9ef 100644 --- a/src/Handler/Tests/Network/TcpQueueTest.hpp +++ b/src/Handler/Tests/Network/Tcp/QueueTest.hpp @@ -6,14 +6,15 @@ namespace flame_ide {namespace handler {namespace network +{namespace tcp {namespace tests { -class TcpQueueTest: public ::AbstractTest +class QueueTest: public ::AbstractTest { public: - TcpQueueTest(); - virtual ~TcpQueueTest(); + QueueTest(); + virtual ~QueueTest(); private: virtual int vStart(); @@ -23,6 +24,6 @@ class TcpQueueTest: public ::AbstractTest int serverPushPop(); }; -}}}} // namespace flame_ide::handler::network::tests +}}}}} // namespace flame_ide::handler::network::tcp::tests #endif // FLAMEIDE_SRC_HANDLER_NETWORK_TCPTEST_HPP diff --git a/src/Handler/Tests/Network/Tcp/Sources.cmake b/src/Handler/Tests/Network/Tcp/Sources.cmake new file mode 100644 index 00000000..e004d959 --- /dev/null +++ b/src/Handler/Tests/Network/Tcp/Sources.cmake @@ -0,0 +1,4 @@ +set (SOURCE_LIST + ${CMAKE_CURRENT_SOURCE_DIR}/QueueTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/QueueTest.hpp +) diff --git a/src/Handler/Tests/Network/Udp/CMakeLists.txt b/src/Handler/Tests/Network/Udp/CMakeLists.txt new file mode 100644 index 00000000..1e936626 --- /dev/null +++ b/src/Handler/Tests/Network/Udp/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.14) + +if(NOT FLAME_TESTING) + return() +endif() + +set(NAME "Handler.Network.Udp.Test") +set(NAME_ALIAS "Handler::Network::Udp::Test") + +get_sources(FILE_LIST) + +set(DEPENDENCY_HEADER_TARGETS + "${FLAME_NAMESPACE}::Handler::Network::Headers" +) + +flame_compile_library( + NAME "${NAME}" + SOURCE_LIST "${FILE_LIST}" + INCLUDE_PATHS "${INCLUDE_PATHS}" "${CMAKE_BINARY_DIR}/generated/include" + DEPENDENCY_HEADER_TARGETS "${DEPENDENCY_HEADER_TARGETS}" + + OBJECT_ALIAS_NAME + "${FLAME_NAMESPACE}::${NAME_ALIAS}::Object" + INDEPENDENT_OBJECT_ALIAS_NAME + "${FLAME_NAMESPACE}::${NAME_ALIAS}::Object::Independ" + + NO_RTTI + EXCEPTIONS +) diff --git a/src/Handler/Tests/Network/Udp/Sources.cmake b/src/Handler/Tests/Network/Udp/Sources.cmake new file mode 100644 index 00000000..68863d9f --- /dev/null +++ b/src/Handler/Tests/Network/Udp/Sources.cmake @@ -0,0 +1,4 @@ +set (SOURCE_LIST + ${CMAKE_CURRENT_SOURCE_DIR}/StorageTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/StorageTest.hpp +) diff --git a/src/Handler/Tests/Network/UdpQueueTest.cpp b/src/Handler/Tests/Network/Udp/StorageTest.cpp similarity index 52% rename from src/Handler/Tests/Network/UdpQueueTest.cpp rename to src/Handler/Tests/Network/Udp/StorageTest.cpp index 03075703..dfd849ec 100644 --- a/src/Handler/Tests/Network/UdpQueueTest.cpp +++ b/src/Handler/Tests/Network/Udp/StorageTest.cpp @@ -1,18 +1,19 @@ -#include -#include +#include +#include namespace flame_ide {namespace handler {namespace network +{namespace udp {namespace tests { -UdpQueueTest::UdpQueueTest() : ::AbstractTest("UdpQueue") +StorageTest::StorageTest() : ::AbstractTest("udp::Storage") {} -UdpQueueTest::~UdpQueueTest() = default; +StorageTest::~StorageTest() = default; -int UdpQueueTest::vStart() +int StorageTest::vStart() { CHECK_RESULT_SUCCESS(doTestCase( "initialization" @@ -27,26 +28,26 @@ int UdpQueueTest::vStart() return ResultType::SUCCESS; } -int UdpQueueTest::init() +int StorageTest::init() { - udp::Udp udp; + udp::Storage storage; return ResultType::SUCCESS; } -int UdpQueueTest::serverPushPop() +int StorageTest::serverPushPop() { - udp::Udp udp; + udp::Storage storage; os::network::UdpServer server{ 65001 }; const os::Socket expectedSocket = server.native(); - auto handle = udp.push(flame_ide::move(server)); + auto handle = storage.push(flame_ide::move(server)); IN_CASE_CHECK(handle != nullptr); - auto resultServer = udp.pop(handle); + auto resultServer = storage.pop(handle); IN_CASE_CHECK(expectedSocket.descriptor == resultServer.native().descriptor); return ResultType::SUCCESS; } -}}}} // namespace flame_ide::handler::network::tests +}}}}} // namespace flame_ide::handler::network::udp::tests diff --git a/src/Handler/Tests/Network/Udp/StorageTest.hpp b/src/Handler/Tests/Network/Udp/StorageTest.hpp new file mode 100644 index 00000000..b78387d5 --- /dev/null +++ b/src/Handler/Tests/Network/Udp/StorageTest.hpp @@ -0,0 +1,29 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_UDPSTORAGETEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_UDPSTORAGETEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace tests +{ + +class StorageTest: public ::AbstractTest +{ +public: + StorageTest(); + virtual ~StorageTest(); + +private: + virtual int vStart(); + +private: + int init(); + int serverPushPop(); +}; + +}}}}} // namespace flame_ide::handler::network::udp::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_UDPSTORAGETEST_HPP diff --git a/src/Handler/Tests/Network/UdpQueueTest.hpp b/src/Handler/Tests/Network/UdpQueueTest.hpp deleted file mode 100644 index a77bba18..00000000 --- a/src/Handler/Tests/Network/UdpQueueTest.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_UDPTEST_HPP -#define FLAMEIDE_SRC_HANDLER_NETWORK_UDPTEST_HPP - -#include - -namespace flame_ide -{namespace handler -{namespace network -{namespace tests -{ - -class UdpQueueTest: public ::AbstractTest -{ -public: - UdpQueueTest(); - virtual ~UdpQueueTest(); - -private: - virtual int vStart(); - -private: - int init(); - int serverPushPop(); -}; - -}}}} // namespace flame_ide::handler::network::tests - -#endif // FLAMEIDE_SRC_HANDLER_NETWORK_UDPTEST_HPP diff --git a/src/Handler/Tests/TestAggregator.cpp b/src/Handler/Tests/TestAggregator.cpp index a8a93920..d8f0033a 100644 --- a/src/Handler/Tests/TestAggregator.cpp +++ b/src/Handler/Tests/TestAggregator.cpp @@ -1,7 +1,7 @@ #include -#include -#include +#include +#include #include #include #include @@ -13,8 +13,12 @@ namespace flame_ide TestAggregator::TestAggregator() : ::TestAggregator("Handler") { - pushBackTest(std::make_shared()); - pushBackTest(std::make_shared()); + // UDP + pushBackTest(std::make_shared()); + + // TCP + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); From d915dcb67f3f09de49a3fcc0d89afcf92e650a86 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Sun, 15 Dec 2024 03:46:03 +0500 Subject: [PATCH 16/37] Dump changes --- include/FlameIDE/Handler/Network/Handler.hpp | 34 +-- src/Handler/Network/Handler.cpp | 60 ++--- src/Handler/Network/Headers.cmake | 1 + src/Handler/Network/Internal.cpp | 11 +- src/Handler/Network/Internal.hpp | 8 +- src/Handler/Network/Notificator.cpp | 21 ++ src/Handler/Network/Notificator.hpp | 40 ++++ src/Handler/Network/ServerHandle.cpp | 10 +- ...municationHandle.cpp => SessionHandle.cpp} | 15 +- src/Handler/Network/Sources.cmake | 3 +- src/Handler/Network/Tcp.cpp | 16 ++ src/Handler/Network/Udp.cpp | 212 +++++++++++------- src/Handler/Network/Udp.hpp | 99 ++++++-- src/Handler/Network/Udp/Client.cpp | 94 ++++++++ src/Handler/Network/Udp/Client.hpp | 24 +- src/Handler/Network/Udp/Endpoint.hpp | 8 - src/Handler/Network/Udp/Headers.cmake | 3 +- src/Handler/Network/Udp/InternalData.cpp | 68 ------ src/Handler/Network/Udp/InternalData.hpp | 39 ---- src/Handler/Network/Udp/Server.cpp | 67 ++++++ src/Handler/Network/Udp/Server.hpp | 20 +- src/Handler/Network/Udp/Sources.cmake | 4 +- .../Network/Udp/{Udp.hpp => Storage.hpp} | 14 +- src/Handler/Network/Udp/Types.hpp | 62 ++++- src/Handler/Network/Udp/Udp.cpp | 96 -------- src/Handler/Network/Worker.cpp | 110 ++++++++- src/Handler/Network/Worker.hpp | 71 +++++- 27 files changed, 781 insertions(+), 429 deletions(-) create mode 100644 src/Handler/Network/Notificator.cpp create mode 100644 src/Handler/Network/Notificator.hpp rename src/Handler/Network/{CommunicationHandle.cpp => SessionHandle.cpp} (68%) create mode 100644 src/Handler/Network/Udp/Client.cpp delete mode 100644 src/Handler/Network/Udp/InternalData.cpp delete mode 100644 src/Handler/Network/Udp/InternalData.hpp create mode 100644 src/Handler/Network/Udp/Server.cpp rename src/Handler/Network/Udp/{Udp.hpp => Storage.hpp} (90%) delete mode 100644 src/Handler/Network/Udp/Udp.cpp diff --git a/include/FlameIDE/Handler/Network/Handler.hpp b/include/FlameIDE/Handler/Network/Handler.hpp index 35644d0d..f82a19a0 100644 --- a/include/FlameIDE/Handler/Network/Handler.hpp +++ b/include/FlameIDE/Handler/Network/Handler.hpp @@ -56,7 +56,6 @@ class Handler ~Handler() noexcept; Handler &operator=(const Handler &) noexcept = delete; - Handler &operator=(Handler &&handler) noexcept; /// @brief pushUdp @@ -124,12 +123,11 @@ class Handler::ServerHandle public: ServerHandle() noexcept = default; ServerHandle(ServerHandle &&) noexcept = default; - ~ServerHandle() noexcept = default; + ~ServerHandle() noexcept; - ServerHandle &operator=(const ServerHandle &) noexcept = default; ServerHandle &operator=(ServerHandle &&) noexcept = default; - operator bool() const noexcept; + explicit operator bool() const noexcept; /// /// @brief getSessionHandle @@ -138,15 +136,23 @@ class Handler::ServerHandle Handler::ExpectedSessionHandle getSessionHandle() noexcept; private: - friend class Handler::Internal; + friend class Handler; friend class Handler::Udp; friend class Handler::Tcp; - using CallbackGetSessionHandle = Handler::ExpectedSessionHandle (*)(void *); +private: + static constexpr Types::size_t OBJECT_SIZE = 16; + + using Object = ::flame_ide::templates::Object; + using CallbackGetSessionHandle = Handler::ExpectedSessionHandle (*)(Object &); + using CallbackDeregistrate = void (*)(Handler::ServerHandle *); private: - void *data = nullptr; + // void *data = nullptr; + + Object object; CallbackGetSessionHandle callbackGetSessionHandle = nullptr; + CallbackDeregistrate callbackDeregistrate = nullptr; }; }}} // namespace flame_ide::handler::network @@ -162,11 +168,11 @@ class Handler::SessionHandle public: SessionHandle() noexcept = default; SessionHandle(SessionHandle &&) noexcept = default; - ~SessionHandle() noexcept = default; + ~SessionHandle() noexcept; SessionHandle &operator=(SessionHandle &&) noexcept = default; - operator bool() const noexcept; + explicit operator bool() const noexcept; /// /// @brief bytesToRead @@ -187,7 +193,7 @@ class Handler::SessionHandle Types::ssize_t send(flame_ide::templates::Range) noexcept; private: - friend class Handler::Internal; + friend class Handler; friend class Handler::Udp; friend class Handler::Tcp; friend class Handler::ServerHandle; @@ -196,19 +202,21 @@ class Handler::SessionHandle static constexpr Types::size_t OBJECT_SIZE = 64; using Object = ::flame_ide::templates::Object; - using CallbackBytesToRead = ::flame_ide::Types::ssize_t (*)(const Object *); + using CallbackBytesToRead = ::flame_ide::Types::ssize_t (*)(const Object &); using CallbackReceive = ::flame_ide::Types::ssize_t (*)( - Object *, ::flame_ide::templates::Range + Object &, ::flame_ide::templates::Range ); using CallbackSend = ::flame_ide::Types::ssize_t (*)( - Object *, ::flame_ide::templates::Range + Object &, ::flame_ide::templates::Range ); + using CallbackDeregistrate = void (*)(Handler::SessionHandle *); private: Object object; CallbackBytesToRead callbackBytesToRead = nullptr; CallbackReceive callbackReceive = nullptr; CallbackSend callbackSend = nullptr; + CallbackDeregistrate callbackDeregistrate = nullptr; }; }}} // namespace flame_ide::handler::network diff --git a/src/Handler/Network/Handler.cpp b/src/Handler/Network/Handler.cpp index 6fed2c39..91cc0088 100644 --- a/src/Handler/Network/Handler.cpp +++ b/src/Handler/Network/Handler.cpp @@ -52,30 +52,35 @@ Handler &Handler::operator=(Handler &&handler) noexcept Handler::ExpectedServerHandle Handler::pushUdp(os::network::UdpServer &&server) noexcept { - const auto descriptor = server.native().descriptor; - auto result = internal->udp().push(flame_ide::move(server)); - const decltype(result) &constResult = result; - constResult.ifResult( - [descriptor, this](const auto &) + result.ifResultGet( + [this](ServerHandle &result) { - internal->registrar().pushUdpServer(descriptor); + auto &handleData = result.object.get(); + const auto &endpoint = handleData.server->endpoint().get(); + internal->registrar().add(endpoint); + + handleData.handler = this; + result.callbackDeregistrate = + internal->udp().serverCallbackDeregistrate(); } ); - return flame_ide::move(result); } Handler::ExpectedSessionHandle Handler::pushUdp(os::network::UdpClient &&client) noexcept { - const auto descriptor = client.native().descriptor; - auto result = internal->udp().push(flame_ide::move(client)); - const decltype(result) &constResult = result; - constResult.ifResult( - [descriptor, this](const auto &) + result.ifResultGet( + [this](SessionHandle &result) { - internal->registrar().pushUdpServer(descriptor); + auto &handleData = result.object.get(); + const auto &endpoint = handleData.data.client->endpoint().get(); + internal->registrar().add(endpoint); + + handleData.handler = this; + result.callbackDeregistrate = + internal->udp().clientCallbackDeregistrate(); } ); @@ -84,30 +89,31 @@ Handler::ExpectedSessionHandle Handler::pushUdp(os::network::UdpClient &&client) Handler::ExpectedServerHandle Handler::pushTcp(os::network::TcpServer &&server) noexcept { - const auto descriptor = server.native().descriptor; - auto result = internal->tcp().push(flame_ide::move(server)); - const decltype(result) &constResult = result; - constResult.ifResult( - [descriptor, this](const auto &) - { - internal->registrar().pushUdpServer(descriptor); - } - ); - + // const decltype(result) &constResult = result; + // constResult.ifResult( + // [this](const auto &result) + // { + // const auto &endpoint = *static_cast( + // result.data + // ); + // internal->registrar().add(endpoint); + // } + // ); return flame_ide::move(result); } Handler::ExpectedSessionHandle Handler::pushTcp(os::network::TcpClient &&client) noexcept { - const auto descriptor = client.native().descriptor; - auto result = internal->tcp().push(flame_ide::move(client)); const decltype(result) &constResult = result; constResult.ifResult( - [descriptor, this](const auto &) + [](const auto &) { - internal->registrar().pushUdpServer(descriptor); + // TODO + // const auto &endpoint = result.object.get() + // .client->endpoint().get(); + // internal->registrar().add(endpoint); } ); diff --git a/src/Handler/Network/Headers.cmake b/src/Handler/Network/Headers.cmake index 42a58c4e..0bcdf37e 100644 --- a/src/Handler/Network/Headers.cmake +++ b/src/Handler/Network/Headers.cmake @@ -1,6 +1,7 @@ set (HEADER_LIST ${CMAKE_CURRENT_SOURCE_DIR}/Functions.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Internal.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Notificator.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Tcp.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Udp.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Worker.hpp diff --git a/src/Handler/Network/Internal.cpp b/src/Handler/Network/Internal.cpp index 1b0d4edc..82ed9b1a 100644 --- a/src/Handler/Network/Internal.cpp +++ b/src/Handler/Network/Internal.cpp @@ -1,17 +1,14 @@ #include -#include -#include - -#include -#include namespace flame_ide {namespace handler {namespace network { -Handler::Internal::Internal() noexcept -{} +Handler::Internal::Internal() noexcept : notificator{ workers.getConditionVariables() } +{ + registration.setNotificator(notificator); +} Handler::Internal::~Internal() noexcept = default; diff --git a/src/Handler/Network/Internal.hpp b/src/Handler/Network/Internal.hpp index ce5edd1d..9c143c84 100644 --- a/src/Handler/Network/Internal.hpp +++ b/src/Handler/Network/Internal.hpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -27,13 +28,11 @@ class Handler::Internal Internal() noexcept; ~Internal() noexcept; - /// @brief pushUdp - /// @param server + /// @brief udp /// @return Udp &udp() noexcept; - /// @brief pushUdp - /// @param server + /// @brief tcp /// @return Tcp &tcp() noexcept; @@ -53,6 +52,7 @@ class Handler::Internal Handler::Udp udpData; ///< Handler::Tcp tcpData; ///< Workers workers; ///< + Notificator notificator; ///< os::async::network::Registrar registration; ///< }; diff --git a/src/Handler/Network/Notificator.cpp b/src/Handler/Network/Notificator.cpp new file mode 100644 index 00000000..bb6a4a71 --- /dev/null +++ b/src/Handler/Network/Notificator.cpp @@ -0,0 +1,21 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{ + +Notificator::Notificator( + templates::StaticArray< + ReferenceWrapper + , generated::network::Config::HANDLER_NUMBER_OF_WORKERS + > &&initCondvars +) : condvars{ move(initCondvars) } +{} + +Notificator::~Notificator() = default; + +void Notificator::operator()() const noexcept +{} + +}}} // namespace flame_ide::handler::network diff --git a/src/Handler/Network/Notificator.hpp b/src/Handler/Network/Notificator.hpp new file mode 100644 index 00000000..a3c7b7c7 --- /dev/null +++ b/src/Handler/Network/Notificator.hpp @@ -0,0 +1,40 @@ +#ifndef HANDLERNOTIFICATOR_HPP +#define HANDLERNOTIFICATOR_HPP + +#include + +#include +#include + +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{ + +class Notificator: public os::async::network::NotificatorBase +{ +public: + Notificator( + templates::StaticArray< + ReferenceWrapper + , generated::network::Config::HANDLER_NUMBER_OF_WORKERS + > &&initCondvars + ); + virtual ~Notificator(); + + virtual void operator()() const noexcept override; + +private: + templates::StaticArray< + ReferenceWrapper + , generated::network::Config::HANDLER_NUMBER_OF_WORKERS + > condvars; + Types::size_t currentIndex = 0; +}; + +}}} // namespace flame_ide::handler::network + +#endif // HANDLERNOTIFICATOR_HPP diff --git a/src/Handler/Network/ServerHandle.cpp b/src/Handler/Network/ServerHandle.cpp index 7f91396d..877c8ee2 100644 --- a/src/Handler/Network/ServerHandle.cpp +++ b/src/Handler/Network/ServerHandle.cpp @@ -5,14 +5,20 @@ namespace flame_ide {namespace network { +Handler::ServerHandle::~ServerHandle() +{ + if (operator bool()) + callbackDeregistrate(this); +} + Handler::ServerHandle::operator bool() const noexcept { - return data && callbackGetSessionHandle; + return object && callbackGetSessionHandle && callbackDeregistrate; } Handler::ExpectedSessionHandle Handler::ServerHandle::getSessionHandle() noexcept { - return callbackGetSessionHandle(data); + return callbackGetSessionHandle(object); } }}} // namespace flame_ide::handler::network diff --git a/src/Handler/Network/CommunicationHandle.cpp b/src/Handler/Network/SessionHandle.cpp similarity index 68% rename from src/Handler/Network/CommunicationHandle.cpp rename to src/Handler/Network/SessionHandle.cpp index 89f04e08..2e41a766 100644 --- a/src/Handler/Network/CommunicationHandle.cpp +++ b/src/Handler/Network/SessionHandle.cpp @@ -5,26 +5,33 @@ namespace flame_ide {namespace network { +Handler::SessionHandle::~SessionHandle() +{ + if (operator bool()) + callbackDeregistrate(this); +} + Handler::SessionHandle::operator bool() const noexcept { - return object && callbackBytesToRead && callbackReceive && callbackSend; + return object && callbackBytesToRead && callbackReceive && callbackSend + && callbackDeregistrate; } Types::ssize_t Handler::SessionHandle::bytesToRead() const noexcept { - return callbackBytesToRead(&object); + return callbackBytesToRead(object); } Types::ssize_t Handler::SessionHandle::receive(templates::Range bytes) noexcept { - return callbackReceive(&object, bytes); + return callbackReceive(object, bytes); } Types::ssize_t Handler::SessionHandle::send(templates::Range bytes) noexcept { - return callbackSend(&object, bytes); + return callbackSend(object, bytes); } }}} // namespace flame_ide::handler::network diff --git a/src/Handler/Network/Sources.cmake b/src/Handler/Network/Sources.cmake index 46e3e35a..072d8ebb 100644 --- a/src/Handler/Network/Sources.cmake +++ b/src/Handler/Network/Sources.cmake @@ -1,8 +1,9 @@ set (SOURCE_LIST - ${CMAKE_CURRENT_SOURCE_DIR}/CommunicationHandle.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Handler.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Internal.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Notificator.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ServerHandle.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/SessionHandle.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Tcp.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Udp.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Worker.cpp diff --git a/src/Handler/Network/Tcp.cpp b/src/Handler/Network/Tcp.cpp index f17f6d2f..6d242b8d 100644 --- a/src/Handler/Network/Tcp.cpp +++ b/src/Handler/Network/Tcp.cpp @@ -1,5 +1,21 @@ #include +namespace flame_ide +{namespace handler +{namespace network +{ +namespace // anonymous +{ + +struct SeverHandleData +{ + tcp::Server *server; + Handler::Tcp *storage; +}; + +} // namespace anonymous +}}} // namespace flame_ide::handler::network + namespace flame_ide {namespace handler {namespace network diff --git a/src/Handler/Network/Udp.cpp b/src/Handler/Network/Udp.cpp index 73fd2cfd..89d91dee 100644 --- a/src/Handler/Network/Udp.cpp +++ b/src/Handler/Network/Udp.cpp @@ -1,44 +1,59 @@ #include -#include +#include namespace flame_ide {namespace handler {namespace network { -Handler::ExpectedServerHandle Handler::Udp::push(os::network::UdpServer &&server) noexcept +Handler::ExpectedServerHandle +Handler::Udp::push(os::network::UdpServer &&server) noexcept { - udp::Server *udpServer = udp.push(move(server)); + udp::Server *udpServer = storage.push(move(server)); if (!udpServer) return { os::STATUS_FAILED }; Handler::ServerHandle handle; - handle.data = udpServer; + handle.object = Handler::ServerHandle::Object{ + ServerHandleData{ nullptr, udpServer } + }; handle.callbackGetSessionHandle = serverHandleCallback(); - flame_ide::unused(handle); - - // TODO - return { os::STATUS_FAILED }; + handle.callbackDeregistrate = nullptr; + return { flame_ide::move(handle) }; } -Handler::ExpectedSessionHandle Handler::Udp::push(os::network::UdpClient &&client) noexcept +Handler::ExpectedSessionHandle +Handler::Udp::push(os::network::UdpClient &&client) noexcept { - udp::Client *udpClient = udp.push(move(client)); - flame_ide::unused(udpClient); + udp::Client *udpClient = storage.push(move(client)); + if (!udpClient) + return { os::STATUS_FAILED }; Handler::SessionHandle handle; - flame_ide::unused(handle); - - return { os::STATUS_FAILED }; + handle.object = Handler::SessionHandle::Object{ + SessionHandleData{ nullptr, udp::ClientCommunicationData{ udpClient } } + }; + handle.callbackBytesToRead = Handler::Udp::clientCallbackBytesToRead(); + handle.callbackReceive = Handler::Udp::clientCallbackReceive(); + handle.callbackSend = Handler::Udp::clientCallbackSend(); + handle.callbackDeregistrate = nullptr; + return { flame_ide::move(handle) }; } Handler::ExpectedUdpServer Handler::Udp::pop(Handler::ServerHandle &handle) { - flame_ide::unused(handle); + if (!handle) + return { os::STATUS_FAILED }; - // TODO - return { os::STATUS_FAILED }; + auto data = handle.object.move(); + auto server = storage.pop(data.server); + if (!server) + return { os::STATUS_FAILED }; + + handle.callbackGetSessionHandle = nullptr; + handle.callbackDeregistrate = nullptr; + return { flame_ide::move(server) }; } Handler::ExpectedUdpClient Handler::Udp::pop(Handler::SessionHandle &handle) @@ -49,20 +64,25 @@ Handler::ExpectedUdpClient Handler::Udp::pop(Handler::SessionHandle &handle) return { os::STATUS_FAILED }; } +// server + Handler::Udp::CallbackGetSessionHandle Handler::Udp::serverHandleCallback() const noexcept { - static const auto callback = [](udp::Server *handlerServer) + static const auto callback = [](ServerHandle::Object &object) -> Handler::ExpectedSessionHandle { - if (!handlerServer) + static const auto empty = [](void *) -> void {}; + + if (!object) return { os::STATUS_FAILED }; + auto *server = object.get().server; + // В очередь приходят сообщения - auto *message = handlerServer->input().getFilledMessage(); + auto *message = server->input().getFilledMessage(); if (!message) return { os::STATUS_FAILED }; - // TODO: надо в самом сообщении это делать { flame_ide::os::threads::Locker messageLock{ message->spin }; if (message->state != udp::MessageState::READY) @@ -73,20 +93,44 @@ Handler::Udp::CallbackGetSessionHandle Handler::Udp::serverHandleCallback() cons Handler::SessionHandle sessionHandle; sessionHandle.object = Handler::SessionHandle::Object{ - udp::ServerCommunicationData{ message, &handlerServer->output() } + udp::ServerCommunicationData{ message, &server->output() } }; sessionHandle.callbackBytesToRead = Handler::Udp::serverCallbackBytesToRead(); sessionHandle.callbackReceive = Handler::Udp::serverCallbackReceive(); sessionHandle.callbackSend = Handler::Udp::serverCallbackSend(); - ::flame_ide::unused(sessionHandle); + sessionHandle.callbackDeregistrate = + reinterpret_cast(+empty); - return { os::STATUS_FAILED }; + return { flame_ide::move(sessionHandle) }; }; return reinterpret_cast(+callback); }; -udp::ServerCommunicationData * -Handler::Udp::serverToCommunicationData(Handler::SessionHandle::Object &object) noexcept +Handler::Udp::CallbackServerDeregistrate +Handler::Udp::serverCallbackDeregistrate() noexcept +{ + static const auto deregistrate = [](ServerHandle *handle) -> void + { + auto handleData = handle->object.get(); + const auto server = handleData.handler->popUdp(*handle); + }; + return (+deregistrate); +} + +Handler::Udp::CallbackSessionDeregistrate +Handler::Udp::clientCallbackDeregistrate() noexcept +{ + static const auto deregistrate = [](SessionHandle *handle) -> void + { + auto handleData = handle->object.get(); + const auto server = handleData.handler->popUdp(*handle); + }; + return (+deregistrate); +} + +udp::ServerCommunicationData *Handler::Udp::serverToCommunicationData( + Handler::SessionHandle::Object &object +) noexcept { if (!object) return nullptr; @@ -106,12 +150,11 @@ const udp::ServerCommunicationData *Handler::Udp::serverToConstCommunicationData Handler::Udp::CallbackBytesToRead Handler::Udp::serverCallbackBytesToRead() noexcept { - static const auto callback = [](const Handler::SessionHandle::Object *object) + static const auto callback = [](const Handler::SessionHandle::Object &object) -> ::flame_ide::Types::ssize_t { - const auto *data = Handler::Udp::serverToConstCommunicationData(*object); - flame_ide::os::threads::Locker lock{ data->message->spin }; - return data->message->size; + const auto *data = Handler::Udp::serverToConstCommunicationData(object); + return data->bytesToRead(); }; return reinterpret_cast(+callback); } @@ -119,35 +162,12 @@ Handler::Udp::CallbackBytesToRead Handler::Udp::serverCallbackBytesToRead() noex Handler::Udp::CallbackReceive Handler::Udp::serverCallbackReceive() noexcept { static const auto callback = []( - Handler::SessionHandle::Object *object + Handler::SessionHandle::Object &object , ::flame_ide::templates::Range range ) -> ::flame_ide::Types::ssize_t { - auto *data = Handler::Udp::serverToCommunicationData(*object); - if (!data) - return -1; - - const auto *message = data->message; - if (!message) - return -1; - - ::flame_ide::Types::ssize_t readData = -1; - { - flame_ide::os::threads::Locker lock{ message->spin }; - - const auto min = ::flame_ide::minimum<::flame_ide::Types::ssize_t>( - (range.end() - range.begin()), message->size - ); - ::flame_ide::templates::copy( - message->bytes.begin(), message->bytes.begin() + min, range.begin() - ); - - data->message->state = udp::MessageState::EMPTY; - data->message->size = 0; - - readData = min; - } - return readData; + auto *data = Handler::Udp::serverToCommunicationData(object); + return data->receive(range); }; return reinterpret_cast(+callback); } @@ -155,33 +175,75 @@ Handler::Udp::CallbackReceive Handler::Udp::serverCallbackReceive() noexcept Handler::Udp::CallbackSend Handler::Udp::serverCallbackSend() noexcept { static const auto callback = []( - Handler::SessionHandle::Object *object + Handler::SessionHandle::Object &object , ::flame_ide::templates::Range range ) -> ::flame_ide::Types::ssize_t { - auto *data = Handler::Udp::serverToCommunicationData(*object); - if (!data) - return -1; + auto *data = Handler::Udp::serverToCommunicationData(object); + return data->send(range); + }; + return reinterpret_cast(+callback); +} - auto *message = data->output->getEmptyMessage(); - if (!message) - return -1; +// client - { - flame_ide::os::threads::Locker lock{ message->spin }; +udp::ClientCommunicationData *Handler::Udp::clientToCommunicationData( + Handler::SessionHandle::Object &object +) noexcept +{ + if (!object) + return nullptr; - const auto min = ::flame_ide::minimum<::flame_ide::Types::ssize_t>( - (range.end() - range.begin()), message->bytes.capacity() - ); - ::flame_ide::templates::copy( - range.begin(), range.begin() + min, message->bytes.begin() - ); + return &object.get(); +} - message->state = udp::MessageState::READY; - message->size = min; - } - return message->size; +const udp::ClientCommunicationData *Handler::Udp::clientToConstCommunicationData( + const Handler::SessionHandle::Object &object +) noexcept +{ + if (!object) + return nullptr; + + return &object.get(); +} + +Handler::Udp::CallbackBytesToRead Handler::Udp::clientCallbackBytesToRead() noexcept +{ + static const auto callback = [](const Handler::SessionHandle::Object &object) + -> Types::ssize_t + { + const auto *data = Handler::Udp::clientToConstCommunicationData(object); + return data->bytesToRead(); }; + + return reinterpret_cast(+callback); +} + +Handler::Udp::CallbackReceive Handler::Udp::clientCallbackReceive() noexcept +{ + static const auto callback = []( + Handler::SessionHandle::Object &object + , ::flame_ide::templates::Range range + ) -> Types::ssize_t + { + auto *data = Handler::Udp::clientToCommunicationData(object); + return data->receive(range); + }; + + return reinterpret_cast(+callback); +} + +Handler::Udp::CallbackSend Handler::Udp::clientCallbackSend() noexcept +{ + static const auto callback = []( + Handler::SessionHandle::Object &object + , ::flame_ide::templates::Range range + ) -> Types::ssize_t + { + auto *data = Handler::Udp::clientToCommunicationData(object); + return data->send(range); + }; + return reinterpret_cast(+callback); } diff --git a/src/Handler/Network/Udp.hpp b/src/Handler/Network/Udp.hpp index e1d801ba..625ef8e5 100644 --- a/src/Handler/Network/Udp.hpp +++ b/src/Handler/Network/Udp.hpp @@ -3,7 +3,9 @@ #include -#include +#include + +#include namespace flame_ide {namespace handler @@ -14,18 +16,31 @@ class Handler::Udp { public: using CallbackGetSessionHandle = Handler::ServerHandle::CallbackGetSessionHandle; + using CallbackServerDeregistrate = Handler::ServerHandle::CallbackDeregistrate; + using CallbackSessionDeregistrate = Handler::SessionHandle::CallbackDeregistrate; using CallbackBytesToRead = Handler::SessionHandle::CallbackBytesToRead; using CallbackReceive = Handler::SessionHandle::CallbackReceive; using CallbackSend = Handler::SessionHandle::CallbackSend; public: - // TODO + struct ServerHandleData + { + Handler *handler; + udp::Server *server; + }; + + struct SessionHandleData + { + Handler *handler; + udp::ClientCommunicationData data; + }; + +public: Handler::ExpectedServerHandle push(os::network::UdpServer &&server) noexcept; // TODO Handler::ExpectedSessionHandle push(os::network::UdpClient &&client) noexcept; - // TODO Handler::ExpectedUdpServer pop(Handler::ServerHandle &handle); // TODO Handler::ExpectedUdpClient pop(Handler::SessionHandle &handle); @@ -34,46 +49,88 @@ class Handler::Udp /// @return CallbackGetSessionHandle serverHandleCallback() const noexcept; -private: /// - /// \brief serverToCommunicationData - /// \param object - /// \return + /// @brief serverCallbackDeregistrate + /// @return + /// + static CallbackServerDeregistrate serverCallbackDeregistrate() noexcept; + /// + /// @brief serverCallbackDeregistrate + /// @return + /// + static CallbackSessionDeregistrate clientCallbackDeregistrate() noexcept; + +private: + /// @brief serverToCommunicationData + /// @param object + /// @return static udp::ServerCommunicationData *serverToCommunicationData( Handler::SessionHandle::Object &object ) noexcept; - /// - /// \brief serverToConstCommunicationData - /// \param object - /// \return - /// + /// @brief serverToConstCommunicationData + /// @param object + /// @return static const udp::ServerCommunicationData *serverToConstCommunicationData( const Handler::SessionHandle::Object &object ) noexcept; - /// - /// \brief serverCallbackBytesToRead - /// \return + /// @brief serverCallbackBytesToRead + /// @return /// static CallbackBytesToRead serverCallbackBytesToRead() noexcept; /// - /// \brief serverCallbackReceive - /// \return + /// @brief serverCallbackReceive + /// @return /// static CallbackReceive serverCallbackReceive() noexcept; /// - /// \brief serverCallbackSend - /// \return + /// @brief serverCallbackSend + /// @return /// - // TODO static CallbackSend serverCallbackSend() noexcept; + /// + /// @brief clientToCommunicationData + /// @param object + /// @return + /// + static udp::ClientCommunicationData *clientToCommunicationData( + Handler::SessionHandle::Object &object + ) noexcept; + + /// + /// @brief clientToConstCommunicationData + /// @param object + /// @return + /// + static const udp::ClientCommunicationData *clientToConstCommunicationData( + const Handler::SessionHandle::Object &object + ) noexcept; + + /// + /// @brief clientCallbackBytesToRead + /// @return + /// + static CallbackBytesToRead clientCallbackBytesToRead() noexcept; + + /// + /// @brief clientCallbackReceive + /// @return + /// + static CallbackReceive clientCallbackReceive() noexcept; + + /// + /// @brief clientCallbackSend + /// @return + /// + static CallbackSend clientCallbackSend() noexcept; + private: - udp::Udp udp; + udp::Storage storage; }; }}} // namespace flame_ide::handler::network diff --git a/src/Handler/Network/Udp/Client.cpp b/src/Handler/Network/Udp/Client.cpp new file mode 100644 index 00000000..5b595272 --- /dev/null +++ b/src/Handler/Network/Udp/Client.cpp @@ -0,0 +1,94 @@ +#include + +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +Types::ssize_t ClientCommunicationData::bytesToRead() const noexcept +{ + if (!client) + return os::STATUS_FAILED; + + return client->input().getFilledMessageSize(); +} + +Types::ssize_t +ClientCommunicationData::receive(templates::Range range) noexcept +{ + if (!client) + return os::STATUS_FAILED; + + ClientMessage *message = client->input().getFilledMessage(); + if (!message) + return os::STATUS_FAILED; + + const auto raiiClear = flame_ide::templates::makeRaiiCaller( + [&message]() + { + message->spin.lock(); + message->state = MessageState::PROCESSING; + } + , [&message]() + { + message->size = 0; + message->state = MessageState::EMPTY; + message->spin.unlock(); + } + ); + + const auto readBytes = flame_ide::minimum( + Types::ssize_t{ message->size } + , Types::ssize_t{ range.end() - range.begin() } + ); + decltype(readBytes) result = flame_ide::templates::copy( + message->bytes.begin(), message->bytes.begin() + readBytes + , range.begin() + ); + if (readBytes != result) + return os::STATUS_FAILED; + + return readBytes; +} + +Types::ssize_t +ClientCommunicationData::send(templates::Range range) noexcept +{ + if (!client) + return os::STATUS_FAILED; + + ClientMessage *message = client->output().getEmptyMessage(); + if (!message) + return os::STATUS_FAILED; + + const auto raiiClear = flame_ide::templates::makeRaiiCaller( + [&message]() + { + message->spin.lock(); + message->state = MessageState::PROCESSING; + } + , [&message]() + { + message->state = MessageState::READY; + message->spin.unlock(); + } + ); + + const auto wroteBytes = flame_ide::minimum( + Types::ssize_t{ message->size } + , Types::ssize_t{ range.end() - range.begin() } + ); + decltype(wroteBytes) result = flame_ide::templates::copy( + range.begin(), range.begin() + wroteBytes + , message->bytes.begin() + ); + if (wroteBytes != result) + return os::STATUS_FAILED; + return wroteBytes; +} + +}}}} // namespace flame_ide::handler::network::udp diff --git a/src/Handler/Network/Udp/Client.hpp b/src/Handler/Network/Udp/Client.hpp index a0659629..7e830418 100644 --- a/src/Handler/Network/Udp/Client.hpp +++ b/src/Handler/Network/Udp/Client.hpp @@ -14,30 +14,18 @@ namespace flame_ide struct ClientMessage: public Message {}; -using ClientEndpoint = Endpoint< +using Client = Endpoint< ::flame_ide::os::network::UdpClient, ClientMessage , Constants::CLIENT_INPUT_QUEUE_SIZE, Constants::CLIENT_OUTPUT_QUEUE_SIZE >; -class Client: public ClientEndpoint -{ -public: - inline ClientEndpoint::Optional &client() noexcept - { - return this->osEndpoint; - } - - inline const ClientEndpoint::Optional &client() const noexcept - { - return this->osEndpoint; - } -}; - struct ClientCommunicationData { - os::network::UdpClient *client; - ClientMessage *message; - Client::ActualOutput *output; + Client *client; + + Types::ssize_t bytesToRead() const noexcept; + Types::ssize_t receive(templates::Range range) noexcept; + Types::ssize_t send(templates::Range range) noexcept; }; }}}} // namespace flame_ide::handler::network::udp diff --git a/src/Handler/Network/Udp/Endpoint.hpp b/src/Handler/Network/Udp/Endpoint.hpp index bb880362..67f947a5 100644 --- a/src/Handler/Network/Udp/Endpoint.hpp +++ b/src/Handler/Network/Udp/Endpoint.hpp @@ -99,14 +99,6 @@ using EndpointTypeMapper = ::flame_ide::TypeMapper< >::Type >; -template -using EndpointTypeMapper = ::flame_ide::TypeMapper< - EndpointType - , typename ::flame_ide::ChooseType< - IsServer::VALUE, ServerMatchingTrait, ClientMatchingTrait - >::Type ->; - template< typename HandlerEndpoint , typename = typename ::flame_ide::EnableType< diff --git a/src/Handler/Network/Udp/Headers.cmake b/src/Handler/Network/Udp/Headers.cmake index 256714ff..12db723d 100644 --- a/src/Handler/Network/Udp/Headers.cmake +++ b/src/Handler/Network/Udp/Headers.cmake @@ -2,8 +2,7 @@ set (HEADER_LIST ${CMAKE_CURRENT_SOURCE_DIR}/Client.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Config.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Endpoint.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/InternalData.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Server.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Storage.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Types.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/Udp.hpp ) diff --git a/src/Handler/Network/Udp/InternalData.cpp b/src/Handler/Network/Udp/InternalData.cpp deleted file mode 100644 index 3af2b2dc..00000000 --- a/src/Handler/Network/Udp/InternalData.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include - -#include - -namespace flame_ide -{namespace handler -{namespace network -{namespace udp -{namespace callbacks -{ - -// server - -Types::ssize_t serverBytesToRead(const udp::ServerCommunicationData *data) noexcept -{ - if (!data || !data->message) - return os::STATUS_FAILED; - - os::threads::Locker locker{ data->message->spin }; - return data->message->size; -} - -Types::ssize_t -serverReceive( - udp::ServerCommunicationData *data, templates::Range range -) noexcept -{ - flame_ide::unused(range); - - if (!data || !data->message) - return os::STATUS_FAILED; - - return os::STATUS_FAILED; -} - -Types::ssize_t -serverSend( - udp::ServerCommunicationData *data, templates::Range range -) noexcept -{ - flame_ide::unused(range); - - if (!data || !data->output) - return os::STATUS_FAILED; - return os::STATUS_FAILED; -} - -// client - -// TODO -Types::ssize_t clientBytesToRead(void */*data*/) noexcept -{ - return os::STATUS_FAILED; -} - -// TODO -Types::ssize_t clientReceive(void */*data*/, templates::Range) noexcept -{ - return os::STATUS_FAILED; -} - -// TODO -Types::ssize_t clientSend(void */*data*/, templates::Range) noexcept -{ - return os::STATUS_FAILED; -} - -}}}}} // namespace flame_ide::os::network::udp::callbacks diff --git a/src/Handler/Network/Udp/InternalData.hpp b/src/Handler/Network/Udp/InternalData.hpp deleted file mode 100644 index 286ef79c..00000000 --- a/src/Handler/Network/Udp/InternalData.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef HANDLERINTERNALUDPDATA_HPP -#define HANDLERINTERNALUDPDATA_HPP - -#include -#include - -namespace flame_ide -{namespace handler -{namespace network -{namespace udp -{namespace callbacks -{ - -// server - -Types::ssize_t serverBytesToRead(const udp::ServerCommunicationData *message) noexcept; - -Types::ssize_t serverReceive( - udp::ServerCommunicationData *message, templates::Range range -) noexcept; - -Types::ssize_t serverSend( - udp::ServerCommunicationData *data, templates::Range -) noexcept; - -// client - -// TODO -Types::ssize_t clientBytesToRead(void *data) noexcept; - -// TODO -Types::ssize_t clientReceive(void *data, templates::Range) noexcept; - -// TODO -Types::ssize_t clientSend(void *data, templates::Range) noexcept; - -}}}}} // namespace flame_ide::os::network::udp::callbacks - -#endif // HANDLERINTERNALUDPDATA_HPP diff --git a/src/Handler/Network/Udp/Server.cpp b/src/Handler/Network/Udp/Server.cpp new file mode 100644 index 00000000..68f770ef --- /dev/null +++ b/src/Handler/Network/Udp/Server.cpp @@ -0,0 +1,67 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +Types::ssize_t ServerCommunicationData::bytesToRead() const noexcept +{ + if (!message) + return os::STATUS_FAILED; + + os::threads::Locker locker{ message->spin }; + return message->size; +} + +Types::ssize_t ServerCommunicationData::receive(templates::Range range) noexcept +{ + if (!message) + return os::STATUS_FAILED; + + ::flame_ide::Types::ssize_t readData = -1; + { + flame_ide::os::threads::Locker lock{ message->spin }; + + const auto min = ::flame_ide::minimum<::flame_ide::Types::ssize_t>( + (range.end() - range.begin()), message->size + ); + ::flame_ide::templates::copy( + message->bytes.begin(), message->bytes.begin() + min, range.begin() + ); + + message->state = udp::MessageState::EMPTY; + message->size = 0; + + readData = min; + } + return readData; +} + +Types::ssize_t +ServerCommunicationData::send(templates::Range range) noexcept +{ + if (!output) + return os::STATUS_FAILED; + + auto *message = output->getEmptyMessage(); + if (!message) + return os::STATUS_FAILED; + { + flame_ide::os::threads::Locker lock{ message->spin }; + + const auto min = ::flame_ide::minimum<::flame_ide::Types::ssize_t>( + (range.end() - range.begin()), message->bytes.capacity() + ); + ::flame_ide::templates::copy( + range.begin(), range.begin() + min, message->bytes.begin() + ); + + message->state = udp::MessageState::READY; + message->size = min; + } + return message->size; +} + +}}}} // namespace flame_ide::handler::network::udp diff --git a/src/Handler/Network/Udp/Server.hpp b/src/Handler/Network/Udp/Server.hpp index 00009a8e..a8342231 100644 --- a/src/Handler/Network/Udp/Server.hpp +++ b/src/Handler/Network/Udp/Server.hpp @@ -15,29 +15,19 @@ struct ServerMessage: public Message { ::flame_ide::os::network::UdpServer::WithClient client; }; -using ServerEndpoint = Endpoint< +using Server = Endpoint< ::flame_ide::os::network::UdpServer, ServerMessage , Constants::SERVER_INPUT_QUEUE_SIZE, Constants::SERVER_OUTPUT_QUEUE_SIZE >; -class Server: public ServerEndpoint -{ -public: - inline ServerEndpoint::Optional &server() noexcept - { - return this->osEndpoint; - } - - inline const ServerEndpoint::Optional &server() const noexcept - { - return this->osEndpoint; - } -}; - struct ServerCommunicationData { ServerMessage *message; Server::ActualOutput *output; + + Types::ssize_t bytesToRead() const noexcept; + Types::ssize_t receive(templates::Range range) noexcept; + Types::ssize_t send(templates::Range range) noexcept; }; }}}} // namespace flame_ide::handler::network::udp diff --git a/src/Handler/Network/Udp/Sources.cmake b/src/Handler/Network/Udp/Sources.cmake index 75f77690..c34df241 100644 --- a/src/Handler/Network/Udp/Sources.cmake +++ b/src/Handler/Network/Udp/Sources.cmake @@ -1,4 +1,4 @@ set (SOURCE_LIST - ${CMAKE_CURRENT_SOURCE_DIR}/InternalData.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Udp.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Client.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Server.cpp ) diff --git a/src/Handler/Network/Udp/Udp.hpp b/src/Handler/Network/Udp/Storage.hpp similarity index 90% rename from src/Handler/Network/Udp/Udp.hpp rename to src/Handler/Network/Udp/Storage.hpp index ab416b26..93c8ebf7 100644 --- a/src/Handler/Network/Udp/Udp.hpp +++ b/src/Handler/Network/Udp/Storage.hpp @@ -1,5 +1,5 @@ -#ifndef HANDLERINTERNALUDPUDP_HPP -#define HANDLERINTERNALUDPUDP_HPP +#ifndef HANDLERINTERNALUDPSTORAGE_HPP +#define HANDLERINTERNALUDPSTORAGE_HPP #include #include @@ -13,7 +13,7 @@ namespace flame_ide {namespace udp { -class Udp +class Storage { public: template @@ -27,7 +27,7 @@ class Udp using HandlerEndpoint = typename EndpointTypeMapper::Type; using HandlerEndpointPointer = - typename ::flame_ide::DefaultTraits::Pointer; + typename flame_ide::DefaultTraits::Pointer; using HandlerEndpointData = typename HandlerEndpointDataMapper< HandlerEndpoint >::Type; @@ -119,18 +119,18 @@ namespace flame_ide template<> inline HandlerEndpointUdpData & -Udp::getData>() noexcept +Storage::getData>() noexcept { return servers; } template<> inline HandlerEndpointUdpData & -Udp::getData>() noexcept +Storage::getData>() noexcept { return clients; } }}}} // namespace flame_ide::handler::network::udp -#endif // HANDLERINTERNALUDPUDP_HPP +#endif // HANDLERINTERNALUDPSTORAGE_HPP diff --git a/src/Handler/Network/Udp/Types.hpp b/src/Handler/Network/Udp/Types.hpp index fd88f3d8..6af6c975 100644 --- a/src/Handler/Network/Udp/Types.hpp +++ b/src/Handler/Network/Udp/Types.hpp @@ -37,7 +37,7 @@ struct Message mutable os::threads::Spin spin; }; -template +template struct ActualData { public: @@ -50,17 +50,20 @@ struct ActualData >; MessageType *getEmptyMessage() noexcept; - MessageType *getFilledMessage() noexcept; + ::flame_ide::Types::ssize_t getFilledMessageSize() const noexcept; + private: ::flame_ide::Types::size_t amount = 0; + Messages messages; MessagesCircularIterator first = MessagesCircularIterator{ messages.begin() , templates::makeRange(messages.begin(), messages.end()) }; MessagesCircularIterator last = first; + mutable os::threads::Spin spin; }; @@ -86,7 +89,10 @@ class Endpoint const Optional &endpoint() const noexcept; ActualInput &input() noexcept; + const ActualInput &input() const noexcept; + ActualOutput &output() noexcept; + const ActualOutput &output() const noexcept; protected: Optional osEndpoint; @@ -132,6 +138,24 @@ MessageType *ActualData::getFilledMessage() noexcept return result->pointer(); } +template +::flame_ide::Types::ssize_t +ActualData::getFilledMessageSize() const noexcept +{ + os::threads::Locker lock{ spin }; + + if ((first == last) && (amount == 0)) + return 0; + + { + const auto &message = *first; + os::threads::Locker messageLocker{ message->spin }; + if (message->state == MessageState::EMPTY) + return 0; + return message->size; + } +} + // Endpoint template< @@ -213,14 +237,44 @@ Endpoint::input() noexcept return actualInput; } +template< + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE + > +const typename Endpoint< + EndpointData, MessageType, INPUT_SIZE, OUTPUT_SIZE +>::ActualInput & +Endpoint::input() const noexcept +{ + return actualInput; +} + +template< + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE + > +typename Endpoint< +EndpointData, MessageType, INPUT_SIZE, OUTPUT_SIZE +>::ActualOutput & +Endpoint::output() noexcept +{ + return actualOutput; +} + template< typename EndpointData , typename MessageType , ::flame_ide::Types::size_t INPUT_SIZE , ::flame_ide::Types::size_t OUTPUT_SIZE > -typename Endpoint::ActualOutput & -Endpoint::output() noexcept +const typename Endpoint< + EndpointData, MessageType, INPUT_SIZE, OUTPUT_SIZE +>::ActualOutput & +Endpoint::output() const noexcept { return actualOutput; } diff --git a/src/Handler/Network/Udp/Udp.cpp b/src/Handler/Network/Udp/Udp.cpp deleted file mode 100644 index 4b28e4e6..00000000 --- a/src/Handler/Network/Udp/Udp.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include -#include - -#include - -namespace flame_ide -{namespace handler -{namespace network -{namespace udp -{ - -/* - -Server *Udp::push(os::network::UdpServer &&server) noexcept -{ - if (!initPointer(servers, serversSpin)) - return nullptr; - - auto check = [](const Server &i) -> bool - { - return !i.empty(); - }; - auto assignTo = [&server](Server &handle) - { - handle.attach(flame_ide::move(server)); - }; - - return pushData(servers, serversSpin, check, assignTo); -} - -os::network::UdpServer Udp::pop(Server *server) noexcept -{ - if (!server) - return {}; - - auto check = [](const Server &input, const Server &internal) -> bool - { - if (input.empty() || internal.empty()) - return false; - - const auto inputDescriptor = input.server()->native().descriptor; - const auto internalDescriptor = internal.server()->native().descriptor; - return (inputDescriptor == internalDescriptor); - }; - auto returnData = [](Server &internal) -> os::network::UdpServer - { - os::network::UdpServer server = flame_ide::move(internal.detach()); - return server; - }; - - return popData(servers, serversSpin, server, check, returnData); -} - -Client *Udp::push(os::network::UdpClient &&client) noexcept -{ - if (!initPointer(clients, clientsSpin)) - return nullptr; - - auto check = [](const Client &i) -> bool - { - return !i.empty(); - }; - auto assignTo = [&client](Client &handle) - { - handle.attach(flame_ide::move(client)); - }; - - return pushData(clients, clientsSpin, check, assignTo); -} - -os::network::UdpClient Udp::pop(Client *client) noexcept -{ - if (!client) - return {}; - - auto check = [](const Client &input, const Client &internal) -> bool - { - if (!(input.client) || !(internal.client)) - return false; - - const auto inputDescriptor = input.client->native().descriptor; - const auto internalDescriptor = internal.client->native().descriptor; - return (inputDescriptor == internalDescriptor); - }; - auto returnData = [](Client &internal) -> os::network::UdpClient - { - os::network::UdpClient client = flame_ide::move(*internal.client); - return client; - }; - - return popData(clients, clientsSpin, client, check, returnData); -} - -*/ - -}}}} // namespace flame_ide::handler::network::udp diff --git a/src/Handler/Network/Worker.cpp b/src/Handler/Network/Worker.cpp index d70cc3f8..cc3a9497 100644 --- a/src/Handler/Network/Worker.cpp +++ b/src/Handler/Network/Worker.cpp @@ -7,17 +7,82 @@ namespace flame_ide {namespace network { -void Worker::notify() +os::threads::ConditionVariable &Worker::getConditionVariable() noexcept { - condvar.notify(); + return condvar; +} + +void Worker::start() noexcept +{ + run(); +} + +void Worker::stop() noexcept +{ + { + os::threads::Locker locker{ stopSpin }; + stopFlag = true; + } + + if (condvar.isWait()) + condvar.notify(); + + join(); } void Worker::body() noexcept { - while (!condvar.tryWait()) - {} + while (!needStop()) + { + condvar.wait(); + + if (needStop()) + break; + + // UDP + { + // Servers + /* + Алгоритм такой: + 1. От регистрара получаем из очереди сокет (нужен а-ля peek, чтобы совсем не вытащить из очереди) + 2. Проверяем, если такой сокет в базе + 3. Если такой сокет зарегистрирован в обработчике + 0. Вытаскиваем сокет из очереди + 1. Вытаскиваем сервер + 2. Вытаскиваем ближайшее собщение + 3. Читаем в то сообщение + 4. ... что-то еще ... + 4. Если такой сокет не зарегистрирован в обработчике + 1. Идём мимо + */ + + // Есть мысли: + // 1. Специализировать тип нотификашки + // 2. Сделать очередь "причин", и идти к конкретной очереди сокетов + } + + if (needStop()) + break; + + { + // Clients + } + + if (needStop()) + break; + + // TCP + // TODO + } +} + +bool Worker::needStop() noexcept +{ + os::threads::Locker locker{ stopSpin }; + return stopFlag; } + }}} // namespace flame_ide::handler::network namespace flame_ide @@ -33,14 +98,47 @@ Workers::~Workers() noexcept stop(); } -os::Status Workers::start() +templates::StaticArray< + ReferenceWrapper, Workers::NUMBER_OF_WORKERS +> +Workers::getConditionVariables() noexcept +{ + templates::StaticArray< + ReferenceWrapper, NUMBER_OF_WORKERS + > condvars; + for (Types::size_t i = 0; i < NUMBER_OF_WORKERS; ++i) + { + condvars[i] = makeReferenceWrapper(workers[i].getConditionVariable()); + } + return condvars; +} + +os::Status Workers::start() noexcept { return os::STATUS_FAILED; + + for (auto &worker : workers) + { + worker.start(); + if (worker.getStatus() != os::STATUS_SUCCESS) + return worker.getStatus(); + } + + return os::STATUS_SUCCESS; } -os::Status Workers::stop() +os::Status Workers::stop() noexcept { return os::STATUS_FAILED; + + for (auto &worker : workers) + { + worker.stop(); + if (worker.getStatus() != os::STATUS_SUCCESS) + return worker.getStatus(); + } + + return os::STATUS_SUCCESS; } }}} // namespace flame_ide::handler::network diff --git a/src/Handler/Network/Worker.hpp b/src/Handler/Network/Worker.hpp index ba8e1ff0..91394a6b 100644 --- a/src/Handler/Network/Worker.hpp +++ b/src/Handler/Network/Worker.hpp @@ -3,6 +3,8 @@ #include +#include + #include #include #include @@ -14,21 +16,52 @@ namespace flame_ide {namespace network { -class Worker: public os::threads::ThreadCrtp + + +}}} + +namespace flame_ide +{namespace handler +{namespace network +{ + +class Worker: private os::threads::ThreadCrtp { using Parent = os::threads::ThreadCrtp; friend Parent; public: - void notify(); + using Parent::getStatus; + + /// + /// @brief getConditionVariable + /// @return + /// + os::threads::ConditionVariable &getConditionVariable() noexcept; + + /// + /// @brief start + /// + void start() noexcept; + + /// + /// @brief stop + /// + void stop() noexcept; private: // os::threads::ThreadCrtp + // TODO void body() noexcept; + bool needStop() noexcept; + private: os::threads::Mutex mutex; os::threads::ConditionVariable condvar{ mutex }; + + os::threads::Spin stopSpin; + bool stopFlag = false; }; }}} // namespace flame_ide::handler::network @@ -40,20 +73,38 @@ namespace flame_ide class Workers { + static constexpr auto NUMBER_OF_WORKERS = + generated::network::Config::HANDLER_NUMBER_OF_WORKERS; + public: Workers() noexcept; ~Workers() noexcept; - os::Status start(); - os::Status stop(); - -private: - void join() noexcept; + /// + /// @brief getConditionVariables + /// @return + /// + templates::StaticArray< + ReferenceWrapper, NUMBER_OF_WORKERS + > + getConditionVariables() noexcept; + + /// + /// @brief start + /// @return + /// + // TODO + os::Status start() noexcept; + + /// + /// @brief stop + /// @return + /// + // TODO + os::Status stop() noexcept; private: - templates::StaticArray< - Worker, generated::network::Config::HANDLER_NUMBER_OF_WORKERS - > workers; + templates::StaticArray workers; }; }}} // namespace flame_ide::handler::network From 278e7303abc6d1336821086cf22a60a8bec0ef55 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Sun, 15 Dec 2024 03:48:25 +0500 Subject: [PATCH 17/37] Templates/Array: fix compilation error --- include/FlameIDE/Templates/Array.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/FlameIDE/Templates/Array.hpp b/include/FlameIDE/Templates/Array.hpp index a1e73ae7..61e8470f 100644 --- a/include/FlameIDE/Templates/Array.hpp +++ b/include/FlameIDE/Templates/Array.hpp @@ -1323,7 +1323,7 @@ TEMPLATE_DEFINE ARRAY_TYPE::Array(ARRAY_TYPE &&array) noexcept { auto it = this->begin(); - for (MoveReference i : array) + for (auto &&i : array) { *it = move(i); ++it; From 730d45f192e3440a7a6d5afed4dd5d317911ee88 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Sun, 15 Dec 2024 03:49:11 +0500 Subject: [PATCH 18/37] Os/Async/Network/Registrar: remove useless header --- include/FlameIDE/Os/Async/Network/Registrar.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/FlameIDE/Os/Async/Network/Registrar.hpp b/include/FlameIDE/Os/Async/Network/Registrar.hpp index e377592c..e83fea01 100644 --- a/include/FlameIDE/Os/Async/Network/Registrar.hpp +++ b/include/FlameIDE/Os/Async/Network/Registrar.hpp @@ -4,7 +4,6 @@ #include #include #include -#include namespace flame_ide {namespace os From 713482edbb52edbb45c58dd7b8caa649c9bce611 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Sun, 15 Dec 2024 03:50:28 +0500 Subject: [PATCH 19/37] Os/Threads/ConditionVariable: remove tryWait and unwait --- .../FlameIDE/Os/Threads/ConditionVariable.hpp | 16 +++------------- src/Os/Threads/ConditionVarable.cpp | 15 +-------------- 2 files changed, 4 insertions(+), 27 deletions(-) diff --git a/include/FlameIDE/Os/Threads/ConditionVariable.hpp b/include/FlameIDE/Os/Threads/ConditionVariable.hpp index 58e97671..7115692e 100644 --- a/include/FlameIDE/Os/Threads/ConditionVariable.hpp +++ b/include/FlameIDE/Os/Threads/ConditionVariable.hpp @@ -40,16 +40,6 @@ class ConditionVariable template void wait(Functor &&functor) noexcept; - /// - /// @brief Trying wait for signal - /// - bool tryWait() noexcept; - - /// - /// @brief Disable waiting (decrement counter) - /// - void unwait() noexcept; - /// /// @brief isWait /// @return @@ -62,7 +52,7 @@ class ConditionVariable void notify() noexcept; private: - Counter counter; + Counter counter; UniqueLocker locker; }; @@ -75,14 +65,14 @@ namespace flame_ide template ConditionVariable::ConditionVariable(LockObject &lock) noexcept : - locker{ lock, UniqueLocker::LOCK } + counter{ decltype(counter.current()){ 0 } }, locker{ lock, UniqueLocker::LOCK } {} template void ConditionVariable::wait(Functor &&functor) noexcept { static_assert( - CompareTypesResult + ComparingTypes::VALUE , "Return type of input fuctior must be boolean" ); diff --git a/src/Os/Threads/ConditionVarable.cpp b/src/Os/Threads/ConditionVarable.cpp index d9c0f2a9..c63226e4 100644 --- a/src/Os/Threads/ConditionVarable.cpp +++ b/src/Os/Threads/ConditionVarable.cpp @@ -23,19 +23,6 @@ void ConditionVariable::wait() noexcept --counter; } -bool ConditionVariable::tryWait() noexcept -{ - bool lockStatus = locker.tryLock(); - if (lockStatus) - locker.unlock(); - return lockStatus; -} - -void ConditionVariable::unwait() noexcept -{ - --counter; -} - bool ConditionVariable::isWait() const noexcept { return counter.current(); @@ -43,7 +30,7 @@ bool ConditionVariable::isWait() const noexcept void ConditionVariable::notify() noexcept { - volatile auto counterValue = counter.current(); + const volatile auto counterValue = counter.current(); if (!counterValue) return; From ebacb0751254a614f2549a4f5cbefcb6b2f7698c Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Sun, 15 Dec 2024 03:51:12 +0500 Subject: [PATCH 20/37] Os/Threads/Counter: update --- include/FlameIDE/Os/Threads/Counter.hpp | 27 +++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/include/FlameIDE/Os/Threads/Counter.hpp b/include/FlameIDE/Os/Threads/Counter.hpp index 5a3bf480..9491a0e0 100644 --- a/include/FlameIDE/Os/Threads/Counter.hpp +++ b/include/FlameIDE/Os/Threads/Counter.hpp @@ -8,16 +8,20 @@ namespace flame_ide {namespace threads { -template +template class Counter { public: - using Me = Counter; + using Me = Counter; + using Lock = LockType; + using Value = ValueType; Counter() noexcept = default; Counter(const Me &) noexcept = delete; Counter(Me &&) noexcept = default; + Counter(Value initValue) noexcept; + ~Counter() noexcept = default; Me &operator=(const Me &) noexcept = delete; @@ -40,24 +44,31 @@ namespace flame_ide {namespace threads { -template -Counter &Counter::operator++() noexcept +template +Counter::Counter( + Counter::Value initValue +) noexcept : value{ initValue } +{} + +template +Counter &Counter::operator++() noexcept { Locker locker{ lock }; ++value; return *this; } -template -Counter &Counter::operator--() noexcept +template +Counter &Counter::operator--() noexcept { Locker locker{ lock }; --value; return *this; } -template -Value Counter::current() const noexcept +template +typename Counter::Value +Counter::current() const noexcept { Locker locker{ lock }; return value; From 2870e2174a639f568da4aec93710e317d3954200 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Sun, 15 Dec 2024 03:51:43 +0500 Subject: [PATCH 21/37] Templates/Object: fix compilation error --- include/FlameIDE/Templates/Object.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/FlameIDE/Templates/Object.hpp b/include/FlameIDE/Templates/Object.hpp index 22c4d680..92309a3e 100644 --- a/include/FlameIDE/Templates/Object.hpp +++ b/include/FlameIDE/Templates/Object.hpp @@ -206,7 +206,7 @@ template flame_ide::AddMoveReferenceType Object::move() noexcept { callbackDestroy = nullptr; - return flame_ide::move(get()); + return flame_ide::move(get()); } template From f94fcd0a0f898af4ab82ad1e82a5109968b60d6d Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Sun, 15 Dec 2024 03:52:15 +0500 Subject: [PATCH 22/37] Templates/SimpleAlgorithms: fix --- include/FlameIDE/Templates/SimpleAlgorithms.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/FlameIDE/Templates/SimpleAlgorithms.hpp b/include/FlameIDE/Templates/SimpleAlgorithms.hpp index bc34429f..d0171737 100644 --- a/include/FlameIDE/Templates/SimpleAlgorithms.hpp +++ b/include/FlameIDE/Templates/SimpleAlgorithms.hpp @@ -57,7 +57,7 @@ void foreachChangable(InputContainer &container, FuncObject &&func); template void foreachChangable(Range &range, FuncObject &&func); -}} +}} // namespace flame_ide::templates namespace flame_ide {namespace templates @@ -115,7 +115,7 @@ void foreach(IteratorInput start, IteratorInput end, FuncObject &&func) } template -void foreach(const InputContainer& container, FuncObject func) +void foreach(const InputContainer& container, FuncObject &&func) { foreach(container.begin(), container.end(), func); } @@ -138,6 +138,6 @@ void foreachChangable(Range &range, FuncObject &&func) foreach(range.begin(), range.end(), func); } -}} +}} // namespace flame_ide::templates #endif // SIMPLEALGORITHMS_HPP From 62c487a3f4b895c4b40017dc313f315f3e923149 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Sun, 15 Dec 2024 03:54:25 +0500 Subject: [PATCH 23/37] Common/Tests: small fixes in FunctionTrait and VoidType tests --- src/Common/Tests/FunctionalTraitTest.cpp | 6 +++--- src/Common/Tests/VoidTypeTest.cpp | 10 ++++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/Common/Tests/FunctionalTraitTest.cpp b/src/Common/Tests/FunctionalTraitTest.cpp index be993767..ea7934e0 100644 --- a/src/Common/Tests/FunctionalTraitTest.cpp +++ b/src/Common/Tests/FunctionalTraitTest.cpp @@ -33,9 +33,9 @@ int FunctionalTraitTest::typeMapper() // using T3Result = TypeMapper::Type; // static assert using T3Result = TypeMapper::Type; - const bool t1ComparationResult = ComparingTypes::VALUE; - const bool t2ComparationResult = ComparingTypes::VALUE; - const bool t3ComparationResult = ComparingTypes::VALUE; + bool t1ComparationResult = ComparingTypes::VALUE; + bool t2ComparationResult = ComparingTypes::VALUE; + bool t3ComparationResult = ComparingTypes::VALUE; IN_CASE_CHECK(t1ComparationResult == true); IN_CASE_CHECK(t2ComparationResult == true); diff --git a/src/Common/Tests/VoidTypeTest.cpp b/src/Common/Tests/VoidTypeTest.cpp index 8a5ccfc9..7310d72d 100644 --- a/src/Common/Tests/VoidTypeTest.cpp +++ b/src/Common/Tests/VoidTypeTest.cpp @@ -28,8 +28,14 @@ VoidTypeTest::~VoidTypeTest() = default; int VoidTypeTest::vStart() { - IN_CASE_CHECK(HasMemember::VALUE == TrueType::VALUE); - IN_CASE_CHECK_END(HasMemember::VALUE == FalseType::VALUE); + bool isExistMemberStructContainMember = ( + HasMemember::VALUE == true + ); + bool isNotExistMemberStructContainMember = ( + HasMemember::VALUE == false + ); + IN_CASE_CHECK(isExistMemberStructContainMember); + IN_CASE_CHECK_END(isNotExistMemberStructContainMember); } }}} // flame_ide::common::tests From e95b1e4604c86c60ce868f83f87a9081e43c6e9c Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Mon, 16 Dec 2024 23:18:11 +0500 Subject: [PATCH 24/37] Handler/Tests/Network/Udp: add test templates; add tests for UDP storage --- src/Handler/Tests/Network/Udp/ClientTest.cpp | 20 ++ src/Handler/Tests/Network/Udp/ClientTest.hpp | 25 +++ src/Handler/Tests/Network/Udp/ServerTest.cpp | 35 ++++ src/Handler/Tests/Network/Udp/ServerTest.hpp | 28 +++ src/Handler/Tests/Network/Udp/Sources.cmake | 6 + src/Handler/Tests/Network/Udp/StorageTest.cpp | 2 - src/Handler/Tests/Network/Udp/StorageTest.hpp | 6 +- src/Handler/Tests/Network/Udp/UdpTest.cpp | 198 ++++++++++++++++++ src/Handler/Tests/Network/Udp/UdpTest.hpp | 33 +++ src/Handler/Tests/TestAggregator.cpp | 8 + 10 files changed, 356 insertions(+), 5 deletions(-) create mode 100644 src/Handler/Tests/Network/Udp/ClientTest.cpp create mode 100644 src/Handler/Tests/Network/Udp/ClientTest.hpp create mode 100644 src/Handler/Tests/Network/Udp/ServerTest.cpp create mode 100644 src/Handler/Tests/Network/Udp/ServerTest.hpp create mode 100644 src/Handler/Tests/Network/Udp/UdpTest.cpp create mode 100644 src/Handler/Tests/Network/Udp/UdpTest.hpp diff --git a/src/Handler/Tests/Network/Udp/ClientTest.cpp b/src/Handler/Tests/Network/Udp/ClientTest.cpp new file mode 100644 index 00000000..46b0ec7f --- /dev/null +++ b/src/Handler/Tests/Network/Udp/ClientTest.cpp @@ -0,0 +1,20 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace tests +{ + +ClientTest::ClientTest() : ::AbstractTest("udp::Client") +{} + +ClientTest::~ClientTest() = default; + +int ClientTest::vStart() +{ + return ResultType::SUCCESS; +} + +}}}}} // namespace flame_ide::handler::network::udp::tests diff --git a/src/Handler/Tests/Network/Udp/ClientTest.hpp b/src/Handler/Tests/Network/Udp/ClientTest.hpp new file mode 100644 index 00000000..a46eefc5 --- /dev/null +++ b/src/Handler/Tests/Network/Udp/ClientTest.hpp @@ -0,0 +1,25 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_UDP_CLIENTTEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_UDP_CLIENTTEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace tests +{ + +class ClientTest: public ::AbstractTest +{ +public: + ClientTest(); + virtual ~ClientTest(); + +private: + virtual int vStart(); +}; + +}}}}} // namespace flame_ide::handler::network::udp::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_CLIENTTEST_HPP diff --git a/src/Handler/Tests/Network/Udp/ServerTest.cpp b/src/Handler/Tests/Network/Udp/ServerTest.cpp new file mode 100644 index 00000000..391bb77d --- /dev/null +++ b/src/Handler/Tests/Network/Udp/ServerTest.cpp @@ -0,0 +1,35 @@ +#include + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace tests +{ + +ServerTest::ServerTest() : ::AbstractTest("udp::Server") +{} + +ServerTest::~ServerTest() = default; + +int ServerTest::vStart() +{ + CHECK_RESULT_SUCCESS(doTestCase( + "initialization" + , [this]() { return init(); } + + )); + return ResultType::SUCCESS; +} + +int ServerTest::init() noexcept +{ + ServerCommunicationData server; + flame_ide::unused(server); + + return ResultType::SUCCESS; +} + +}}}}} // namespace flame_ide::handler::network::udp::tests diff --git a/src/Handler/Tests/Network/Udp/ServerTest.hpp b/src/Handler/Tests/Network/Udp/ServerTest.hpp new file mode 100644 index 00000000..2f73d021 --- /dev/null +++ b/src/Handler/Tests/Network/Udp/ServerTest.hpp @@ -0,0 +1,28 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_UDP_SERVERTEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_UDP_SERVERTEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace tests +{ + +class ServerTest: public ::AbstractTest +{ +public: + ServerTest(); + virtual ~ServerTest(); + +private: + virtual int vStart(); + +private: + int init() noexcept; +}; + +}}}}} // namespace flame_ide::handler::network::udp::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_SERVERTEST_HPP diff --git a/src/Handler/Tests/Network/Udp/Sources.cmake b/src/Handler/Tests/Network/Udp/Sources.cmake index 68863d9f..a295e9ce 100644 --- a/src/Handler/Tests/Network/Udp/Sources.cmake +++ b/src/Handler/Tests/Network/Udp/Sources.cmake @@ -1,4 +1,10 @@ set (SOURCE_LIST + ${CMAKE_CURRENT_SOURCE_DIR}/ClientTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ClientTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/ServerTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ServerTest.hpp ${CMAKE_CURRENT_SOURCE_DIR}/StorageTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/StorageTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/UdpTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/UdpTest.hpp ) diff --git a/src/Handler/Tests/Network/Udp/StorageTest.cpp b/src/Handler/Tests/Network/Udp/StorageTest.cpp index dfd849ec..fee12e94 100644 --- a/src/Handler/Tests/Network/Udp/StorageTest.cpp +++ b/src/Handler/Tests/Network/Udp/StorageTest.cpp @@ -18,12 +18,10 @@ int StorageTest::vStart() CHECK_RESULT_SUCCESS(doTestCase( "initialization" , [this]() { return init(); } - )); CHECK_RESULT_SUCCESS(doTestCase( "server push-pop" , [this]() { return serverPushPop(); } - )); return ResultType::SUCCESS; } diff --git a/src/Handler/Tests/Network/Udp/StorageTest.hpp b/src/Handler/Tests/Network/Udp/StorageTest.hpp index b78387d5..0d640df4 100644 --- a/src/Handler/Tests/Network/Udp/StorageTest.hpp +++ b/src/Handler/Tests/Network/Udp/StorageTest.hpp @@ -1,5 +1,5 @@ -#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_UDPSTORAGETEST_HPP -#define FLAMEIDE_SRC_HANDLER_NETWORK_UDPSTORAGETEST_HPP +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_UDP_STORAGETEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_UDP_STORAGETEST_HPP #include @@ -26,4 +26,4 @@ class StorageTest: public ::AbstractTest }}}}} // namespace flame_ide::handler::network::udp::tests -#endif // FLAMEIDE_SRC_HANDLER_NETWORK_UDPSTORAGETEST_HPP +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_UDP_STORAGETEST_HPP diff --git a/src/Handler/Tests/Network/Udp/UdpTest.cpp b/src/Handler/Tests/Network/Udp/UdpTest.cpp new file mode 100644 index 00000000..e9f4ac8e --- /dev/null +++ b/src/Handler/Tests/Network/Udp/UdpTest.cpp @@ -0,0 +1,198 @@ +#include + +#include + +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace tests +{ + +using Udp = Handler::Udp; + +UdpTest::UdpTest() : ::AbstractTest("udp::Udp") +{} + +UdpTest::~UdpTest() = default; + +int UdpTest::vStart() +{ + CHECK_RESULT_SUCCESS(doTestCase( + "Initialization" + , [this]() { return init(); } + )); + + CHECK_RESULT_SUCCESS(doTestCase( + "Push & pop server" + , [this]() { return pushPopServer(); } + )); + CHECK_RESULT_SUCCESS(doTestCase( + "Push server" + , [this]() { return pushServer(); } + )); + + CHECK_RESULT_SUCCESS(doTestCase( + "Push & pop client" + , [this]() { return pushPopClient(); } + )); + CHECK_RESULT_SUCCESS(doTestCase( + "Push client" + , [this]() { return pushClient(); } + )); + + return ResultType::SUCCESS; +} + +int UdpTest::init() noexcept +{ + Udp storage; + flame_ide::unused(storage); + + return ResultType::SUCCESS; +} + +int UdpTest::pushPopServer() noexcept +{ + os::network::UdpServer server{ 65001 }; + const os::Socket expectedSocket = server.native(); + IN_CASE_CHECK(expectedSocket.descriptor != os::SOCKET_INVALID.descriptor); + + Udp storage; + Handler::ExpectedServerHandle expectedHandle = storage.push(flame_ide::move(server)); + Handler::ServerHandle handle; + bool isError = false; + expectedHandle.ifResult( + [&handle](Handler::ServerHandle &&result) + { + handle = flame_ide::move(result); + } + ).ifError( + [&isError](os::Status &&) + { + isError = true; + } + ); + IN_CASE_CHECK(isError == false); + IN_CASE_CHECK(handle.operator bool()) + + Handler::ExpectedUdpServer expectedServer = storage.pop(handle); + os::network::UdpServer resultServer; + expectedServer.ifResult( + [&resultServer](os::network::UdpServer &&server) + { + resultServer = flame_ide::move(server); + } + ).ifError( + [&isError](os::Status &&) + { + isError = true; + } + ); + IN_CASE_CHECK(isError == false); + IN_CASE_CHECK(expectedSocket.descriptor == resultServer.native().descriptor); + + return ResultType::SUCCESS; +} + +int UdpTest::pushServer() noexcept +{ + os::network::UdpServer server{ 65001 }; + IN_CASE_CHECK(server.native().descriptor != os::SOCKET_INVALID.descriptor); + + Udp storage; + Handler::ExpectedServerHandle expectedHandle = storage.push(flame_ide::move(server)); + Handler::ServerHandle handle; + bool isError = false; + expectedHandle.ifResult( + [&handle](Handler::ServerHandle &&result) + { + handle = flame_ide::move(result); + } + ).ifError( + [&isError](os::Status &&) + { + isError = true; + } + ); + IN_CASE_CHECK(isError == false); + IN_CASE_CHECK(handle.operator bool()) + + return ResultType::SUCCESS; +} + +int UdpTest::pushPopClient() noexcept +{ + const os::network::Ipv4 ip{ { 127, 0, 0, 1 }, 65001 }; + os::network::UdpClient client{ ip }; + const os::Socket expectedSocket = client.native(); + IN_CASE_CHECK(expectedSocket.descriptor != os::SOCKET_INVALID.descriptor); + + Udp storage; + Handler::ExpectedSessionHandle expectedHandle = storage.push(flame_ide::move(client)); + Handler::SessionHandle handle; + bool isError = false; + expectedHandle.ifResult( + [&handle](Handler::SessionHandle &&result) + { + handle = flame_ide::move(result); + } + ).ifError( + [&isError](os::Status &&) + { + isError = true; + } + ); + IN_CASE_CHECK(isError == false); + IN_CASE_CHECK(handle.operator bool()) + + Handler::ExpectedUdpClient expectedClient = storage.pop(handle); + os::network::UdpClient resultClient; + expectedClient.ifResult( + [&resultClient](os::network::UdpClient &&server) + { + resultClient = flame_ide::move(server); + } + ).ifError( + [&isError](os::Status &&) + { + isError = true; + } + ); + IN_CASE_CHECK(isError == false); + IN_CASE_CHECK(expectedSocket.descriptor == resultClient.native().descriptor); + + return ResultType::SUCCESS; +} + +int UdpTest::pushClient() noexcept +{ + const os::network::Ipv4 ip{ { 127, 0, 0, 1 }, 65001 }; + os::network::UdpClient client{ ip }; + IN_CASE_CHECK(client.native().descriptor != os::SOCKET_INVALID.descriptor); + + Udp storage; + Handler::ExpectedSessionHandle expectedHandle = storage.push(flame_ide::move(client)); + Handler::SessionHandle handle; + bool isError = false; + expectedHandle.ifResult( + [&handle](Handler::SessionHandle &&result) + { + handle = flame_ide::move(result); + } + ).ifError( + [&isError](os::Status &&) + { + isError = true; + } + ); + IN_CASE_CHECK(isError == false); + IN_CASE_CHECK(handle.operator bool()) + + return ResultType::SUCCESS; +} + +}}}}} // namespace flame_ide::handler::network::udp::tests diff --git a/src/Handler/Tests/Network/Udp/UdpTest.hpp b/src/Handler/Tests/Network/Udp/UdpTest.hpp new file mode 100644 index 00000000..dedfa0f0 --- /dev/null +++ b/src/Handler/Tests/Network/Udp/UdpTest.hpp @@ -0,0 +1,33 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_UDP_UDPTEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_UDP_UDPTEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace tests +{ + +class UdpTest: public ::AbstractTest +{ +public: + UdpTest(); + virtual ~UdpTest(); + +private: + virtual int vStart(); + + int init() noexcept; + + int pushPopServer() noexcept; + int pushServer() noexcept; + + int pushPopClient() noexcept; + int pushClient() noexcept; +}; + +}}}}} // namespace flame_ide::handler::network::udp::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_UDPTEST_HPP diff --git a/src/Handler/Tests/TestAggregator.cpp b/src/Handler/Tests/TestAggregator.cpp index d8f0033a..0ad0b1a8 100644 --- a/src/Handler/Tests/TestAggregator.cpp +++ b/src/Handler/Tests/TestAggregator.cpp @@ -1,7 +1,12 @@ #include +#include +#include #include +#include + #include + #include #include #include @@ -14,7 +19,10 @@ namespace flame_ide TestAggregator::TestAggregator() : ::TestAggregator("Handler") { // UDP + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); // TCP pushBackTest(std::make_shared()); From d6add2ecfc5c44d30a396a68c289a53435299b95 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Wed, 12 Aug 2026 00:44:46 +0300 Subject: [PATCH 25/37] Add initial tests for Handler --- src/Handler/Tests/Network/HandlerTest.cpp | 196 ++++++++++++++++++++++ src/Handler/Tests/Network/HandlerTest.hpp | 14 ++ 2 files changed, 210 insertions(+) diff --git a/src/Handler/Tests/Network/HandlerTest.cpp b/src/Handler/Tests/Network/HandlerTest.cpp index eaf22e97..7c994ba8 100644 --- a/src/Handler/Tests/Network/HandlerTest.cpp +++ b/src/Handler/Tests/Network/HandlerTest.cpp @@ -1,6 +1,9 @@ #include #include +#include +#include + namespace flame_ide {namespace handler {namespace network @@ -14,6 +17,199 @@ HandlerTest::~HandlerTest() = default; int HandlerTest::vStart() { + CHECK_RESULT_SUCCESS(doTestCase( + "initialization" + , [this]() { return init(); } + )); + + // UPD + // Server + CHECK_RESULT_SUCCESS(doTestCase( + "UDP Server push-pop" + , [this]() { return udpServerPushPop(); } + )); + CHECK_RESULT_SUCCESS(doTestCase( + "UDP Server communication" + , [this]() { return udpServerCommunicate(); } + )); + // Client + CHECK_RESULT_SUCCESS(doTestCase( + "UDP Client push-pop" + , [this]() { return udpClientPushPop(); } + )); + CHECK_RESULT_SUCCESS(doTestCase( + "UDP Client communication" + , [this]() { return udpClientCommunicate(); } + )); + + // TCP + // Server + CHECK_RESULT_SUCCESS(doTestCase( + "TCP Server push-pop" + , [this]() { return tcpServerPushPop(); } + )); + CHECK_RESULT_SUCCESS(doTestCase( + "TCP Server communication" + , [this]() { return tcpServerCommunicate(); } + )); + // Client + CHECK_RESULT_SUCCESS(doTestCase( + "TCP Client push-pop" + , [this]() { return tcpClientPushPop(); } + )); + CHECK_RESULT_SUCCESS(doTestCase( + "TCP Client communication" + , [this]() { return tcpClientCommunicate(); } + )); + + return ResultType::SUCCESS; +} + +int HandlerTest::init() +{ + Handler handler; + flame_ide::unused(handler); + + return ResultType::SUCCESS; +} + +int HandlerTest::udpServerPushPop() +{ + flame_ide::os::network::UdpServer originalUdpServer{ 65001 }; + const flame_ide::os::Socket originalNativeSocket = originalUdpServer.native(); + + Handler handler; + Handler::ExpectedServerHandle updServerHandle = + handler.pushUdp(::flame_ide::move(originalUdpServer)); + + // Check valid handle + { + ResultType pushResult = ResultType::FAILED; + updServerHandle.ifResultGet( + [&pushResult](auto &) + { + pushResult = ResultType::SUCCESS; + } + ); + IN_CASE_CHECK(pushResult == ResultType::SUCCESS); + } + + // Get handle + Handler::ServerHandle serverHandle; + updServerHandle.ifResult( + [&serverHandle](Handler::ServerHandle &&inputHandle) + { + serverHandle = move(inputHandle); + } + ); + Handler::ExpectedUdpServer udpServer = handler.popUdp(serverHandle); + + // Check valid server + { + ResultType popResult = ResultType::FAILED; + udpServer.ifResultGet( + [&popResult](auto &) + { + popResult = ResultType::SUCCESS; + } + ); + IN_CASE_CHECK(popResult == ResultType::SUCCESS); + } + + // Check valid descriptor + flame_ide::os::network::UdpServer popedUdpServer; + udpServer.ifResult( + [&popedUdpServer](os::network::UdpServer &&inputServer) + { + popedUdpServer = move(inputServer); + } + ); + const flame_ide::os::Socket popedNativeSocket = popedUdpServer.native(); + IN_CASE_CHECK_END(popedNativeSocket.descriptor == originalNativeSocket.descriptor); +} + +int HandlerTest::udpServerCommunicate() +{ + const auto port = ::flame_ide::os::network::Ipv4::Port{ 65001 }; + const auto ip = ::flame_ide::os::network::Ipv4::localhost(port); + + ::flame_ide::os::network::UdpClient udpClient{ ip }; + + ::flame_ide::os::network::UdpServer originalUdpServer{ port }; + Handler handler; + Handler::ExpectedServerHandle updServerHandle = + handler.pushUdp(::flame_ide::move(originalUdpServer)); + + // Check valid handle + { + ResultType pushResult = ResultType::FAILED; + updServerHandle.ifResultGet( + [&pushResult](auto &) + { + pushResult = ResultType::SUCCESS; + } + ); + IN_CASE_CHECK(pushResult == ResultType::SUCCESS); + } + + Handler::ServerHandle serverHandle; + updServerHandle.ifResult( + [&serverHandle](Handler::ServerHandle &&inputHandle) + { + serverHandle = move(inputHandle); + } + ); + + // TODO: communicate a-la pingPong test in UdpTest + + return ResultType::SUCCESS; +} + +int HandlerTest::udpClientPushPop() +{ + Handler handler; + flame_ide::unused(handler); + + return ResultType::SUCCESS; +} + +int HandlerTest::udpClientCommunicate() +{ + Handler handler; + flame_ide::unused(handler); + + return ResultType::SUCCESS; +} + +int HandlerTest::tcpServerPushPop() +{ + Handler handler; + flame_ide::unused(handler); + + return ResultType::SUCCESS; +} + +int HandlerTest::tcpServerCommunicate() +{ + Handler handler; + flame_ide::unused(handler); + + return ResultType::SUCCESS; +} + +int HandlerTest::tcpClientPushPop() +{ + Handler handler; + flame_ide::unused(handler); + + return ResultType::SUCCESS; +} + +int HandlerTest::tcpClientCommunicate() +{ + Handler handler; + flame_ide::unused(handler); + return ResultType::SUCCESS; } diff --git a/src/Handler/Tests/Network/HandlerTest.hpp b/src/Handler/Tests/Network/HandlerTest.hpp index a67fa3d5..a9e72631 100644 --- a/src/Handler/Tests/Network/HandlerTest.hpp +++ b/src/Handler/Tests/Network/HandlerTest.hpp @@ -17,6 +17,20 @@ class HandlerTest: public ::AbstractTest private: virtual int vStart(); + + int init(); + + int udpServerPushPop(); + int udpServerCommunicate(); + + int udpClientPushPop(); + int udpClientCommunicate(); + + int tcpServerPushPop(); + int tcpServerCommunicate(); + + int tcpClientPushPop(); + int tcpClientCommunicate(); }; }}}} // namespace flame_ide::handler::network::tests From 7d1c36da2383411e319a1e7f9b4476c2141e16ca Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Wed, 12 Aug 2026 01:55:36 +0300 Subject: [PATCH 26/37] Fix UdpTest --- src/Handler/Network/Udp.cpp | 18 ++++++++++++++---- src/Handler/Tests/Network/Udp/UdpTest.cpp | 12 ++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/Handler/Network/Udp.cpp b/src/Handler/Network/Udp.cpp index 89d91dee..9d14e049 100644 --- a/src/Handler/Network/Udp.cpp +++ b/src/Handler/Network/Udp.cpp @@ -43,7 +43,7 @@ Handler::Udp::push(os::network::UdpClient &&client) noexcept Handler::ExpectedUdpServer Handler::Udp::pop(Handler::ServerHandle &handle) { - if (!handle) + if (!(handle.object && handle.callbackGetSessionHandle)) return { os::STATUS_FAILED }; auto data = handle.object.move(); @@ -58,10 +58,20 @@ Handler::ExpectedUdpServer Handler::Udp::pop(Handler::ServerHandle &handle) Handler::ExpectedUdpClient Handler::Udp::pop(Handler::SessionHandle &handle) { - flame_ide::unused(handle); + if(!(handle.object && handle.callbackBytesToRead && handle.callbackReceive + && handle.callbackSend)) + return { os::STATUS_FAILED }; + + auto data = handle.object.move(); + auto client = storage.pop(data.data.client); + if (!client) + return { os::STATUS_FAILED }; - // TODO - return { os::STATUS_FAILED }; + handle.callbackBytesToRead = nullptr; + handle.callbackReceive = nullptr; + handle.callbackSend = nullptr; + handle.callbackDeregistrate = nullptr; + return { flame_ide::move(client) }; } // server diff --git a/src/Handler/Tests/Network/Udp/UdpTest.cpp b/src/Handler/Tests/Network/Udp/UdpTest.cpp index e9f4ac8e..7edda20d 100644 --- a/src/Handler/Tests/Network/Udp/UdpTest.cpp +++ b/src/Handler/Tests/Network/Udp/UdpTest.cpp @@ -77,7 +77,7 @@ int UdpTest::pushPopServer() noexcept } ); IN_CASE_CHECK(isError == false); - IN_CASE_CHECK(handle.operator bool()) + // IN_CASE_CHECK(handle.operator bool()); // handle.callbackDeregistrate == nullptr Handler::ExpectedUdpServer expectedServer = storage.pop(handle); os::network::UdpServer resultServer; @@ -119,7 +119,7 @@ int UdpTest::pushServer() noexcept } ); IN_CASE_CHECK(isError == false); - IN_CASE_CHECK(handle.operator bool()) + // IN_CASE_CHECK(handle.operator bool()); // handle.callbackDeregistrate == nullptr return ResultType::SUCCESS; } @@ -147,14 +147,14 @@ int UdpTest::pushPopClient() noexcept } ); IN_CASE_CHECK(isError == false); - IN_CASE_CHECK(handle.operator bool()) + // IN_CASE_CHECK(handle.operator bool()); // handle.callbackDeregistrate == nullptr Handler::ExpectedUdpClient expectedClient = storage.pop(handle); os::network::UdpClient resultClient; expectedClient.ifResult( - [&resultClient](os::network::UdpClient &&server) + [&resultClient](os::network::UdpClient &&client) { - resultClient = flame_ide::move(server); + resultClient = flame_ide::move(client); } ).ifError( [&isError](os::Status &&) @@ -190,7 +190,7 @@ int UdpTest::pushClient() noexcept } ); IN_CASE_CHECK(isError == false); - IN_CASE_CHECK(handle.operator bool()) + // IN_CASE_CHECK(handle.operator bool()); // handle.callbackDeregistrate == nullptr return ResultType::SUCCESS; } From d672fab808ad5f876c995b3e1f580242225af771 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Thu, 13 Aug 2026 02:07:59 +0300 Subject: [PATCH 27/37] Add notification types for five type of sockets events --- .../Os/Async/Network/NotificatorBase.hpp | 20 +++- .../FlameIDE/Os/Async/Network/Registrar.hpp | 8 +- src/Handler/Network/Internal.cpp | 6 +- src/Handler/Network/Internal.hpp | 11 +- src/Handler/Network/Notificator.cpp | 29 +++-- src/Handler/Network/Notificator.hpp | 54 ++++++--- src/Handler/Network/Udp.cpp | 12 +- src/Handler/Network/Udp.hpp | 2 - src/Handler/Network/Udp/Endpoint.hpp | 2 +- src/Os/Async/Network/EventCatcherBase.cpp | 88 ++++++++++++-- src/Os/Async/Network/EventCatcherBase.hpp | 40 ++++++- src/Os/Async/Network/Registrar.cpp | 22 +++- src/Os/Posix/Async/Network/EventCatcher.cpp | 109 +++++++++++++++++- src/Os/Tests/Async/Network/RegistrarTest.cpp | 7 +- .../Async/Network/MessageDispatchThread.cpp | 26 ++++- 15 files changed, 372 insertions(+), 64 deletions(-) diff --git a/include/FlameIDE/Os/Async/Network/NotificatorBase.hpp b/include/FlameIDE/Os/Async/Network/NotificatorBase.hpp index dbf9961b..e53abdd7 100644 --- a/include/FlameIDE/Os/Async/Network/NotificatorBase.hpp +++ b/include/FlameIDE/Os/Async/Network/NotificatorBase.hpp @@ -9,7 +9,25 @@ namespace flame_ide {namespace network { -using NotificatorBase = flame_ide::FunctorConstBase; +namespace tag +{ + +struct UdpServer {}; +struct UdpClient {}; +struct TcpServer {}; +struct TcpAcceptedConnection {}; +struct TcpClient {}; + +} // namespace tag + +template +class NotificatorBase: public flame_ide::DefaultFunctorConstBase {}; + +using UdpServerNotificatorBase = NotificatorBase; +using UdpClientNotificatorBase = NotificatorBase; +using TcpServerNotificatorBase = NotificatorBase; +using TcpAcceptedConnectionNotificatorBase = NotificatorBase; +using TcpClientNotificatorBase = NotificatorBase; }}}} // namespace flame_ide::os::async::network diff --git a/include/FlameIDE/Os/Async/Network/Registrar.hpp b/include/FlameIDE/Os/Async/Network/Registrar.hpp index e83fea01..c3ece887 100644 --- a/include/FlameIDE/Os/Async/Network/Registrar.hpp +++ b/include/FlameIDE/Os/Async/Network/Registrar.hpp @@ -77,8 +77,12 @@ class Registrar bool pushTcpServer(os::SocketDescriptor socket) noexcept; bool pushTcpClient(os::SocketDescriptor socket) noexcept; - void setNotificator(const NotificatorBase ¬ificator) noexcept; - void unsetNotificator() noexcept; + void setNotificator(const UdpServerNotificatorBase ¬ificator) noexcept; + void setNotificator(const UdpClientNotificatorBase ¬ificator) noexcept; + void setNotificator(const TcpServerNotificatorBase ¬ificator) noexcept; + void setNotificator(const TcpAcceptedConnectionNotificatorBase ¬ificator) noexcept; + void setNotificator(const TcpClientNotificatorBase ¬ificator) noexcept; + void unsetNotificators() noexcept; void clear() noexcept; }; diff --git a/src/Handler/Network/Internal.cpp b/src/Handler/Network/Internal.cpp index 82ed9b1a..a704475a 100644 --- a/src/Handler/Network/Internal.cpp +++ b/src/Handler/Network/Internal.cpp @@ -5,10 +5,8 @@ namespace flame_ide {namespace network { -Handler::Internal::Internal() noexcept : notificator{ workers.getConditionVariables() } -{ - registration.setNotificator(notificator); -} +Handler::Internal::Internal() noexcept +{} Handler::Internal::~Internal() noexcept = default; diff --git a/src/Handler/Network/Internal.hpp b/src/Handler/Network/Internal.hpp index 9c143c84..7b6fc8c3 100644 --- a/src/Handler/Network/Internal.hpp +++ b/src/Handler/Network/Internal.hpp @@ -52,7 +52,16 @@ class Handler::Internal Handler::Udp udpData; ///< Handler::Tcp tcpData; ///< Workers workers; ///< - Notificator notificator; ///< + + struct + { + udp::ServerNotificator udpServerNotificator; + udp::ClientNotificator udpClientNotificator; + + tcp::ServerNotificator tcpServerNotificator; + tcp::AcceptedConnectonNotificator tcpAcceptedConnectonNotificator; + tcp::ClientNotificator tcpClientNotificator; + } notificators; ///< os::async::network::Registrar registration; ///< }; diff --git a/src/Handler/Network/Notificator.cpp b/src/Handler/Network/Notificator.cpp index bb6a4a71..c3a9184b 100644 --- a/src/Handler/Network/Notificator.cpp +++ b/src/Handler/Network/Notificator.cpp @@ -3,19 +3,30 @@ namespace flame_ide {namespace handler {namespace network +{namespace udp { -Notificator::Notificator( - templates::StaticArray< - ReferenceWrapper - , generated::network::Config::HANDLER_NUMBER_OF_WORKERS - > &&initCondvars -) : condvars{ move(initCondvars) } +void ServerNotificator::operator()() const noexcept {} -Notificator::~Notificator() = default; +void ClientNotificator::operator()() const noexcept +{} + +}}}} // namespace flame_ide::handler::network::udp + +namespace flame_ide +{namespace handler +{namespace network +{namespace tcp +{ + +void ServerNotificator::operator()() const noexcept +{} + +void AcceptedConnectonNotificator::operator()() const noexcept +{} -void Notificator::operator()() const noexcept +void ClientNotificator::operator()() const noexcept {} -}}} // namespace flame_ide::handler::network +}}}} // namespace flame_ide::handler::network::tcp diff --git a/src/Handler/Network/Notificator.hpp b/src/Handler/Network/Notificator.hpp index a3c7b7c7..cce4b0ce 100644 --- a/src/Handler/Network/Notificator.hpp +++ b/src/Handler/Network/Notificator.hpp @@ -12,29 +12,53 @@ namespace flame_ide {namespace handler {namespace network +{namespace udp { -class Notificator: public os::async::network::NotificatorBase +class ServerNotificator: + public ::flame_ide::os::async::network::UdpServerNotificatorBase { public: - Notificator( - templates::StaticArray< - ReferenceWrapper - , generated::network::Config::HANDLER_NUMBER_OF_WORKERS - > &&initCondvars - ); - virtual ~Notificator(); + virtual void operator()() const noexcept override; +}; + +class ClientNotificator: + public ::flame_ide::os::async::network::UdpClientNotificatorBase +{ +public: + virtual void operator()() const noexcept override; +}; + +}}}} // namespace flame_ide::handler::network::udp + +namespace flame_ide +{namespace handler +{namespace network +{namespace tcp +{ + +class ServerNotificator: + public ::flame_ide::os::async::network::TcpServerNotificatorBase +{ +public: + virtual void operator()() const noexcept override; +}; +class AcceptedConnectonNotificator: + public ::flame_ide::os::async::network + ::TcpAcceptedConnectionNotificatorBase +{ +public: virtual void operator()() const noexcept override; +}; -private: - templates::StaticArray< - ReferenceWrapper - , generated::network::Config::HANDLER_NUMBER_OF_WORKERS - > condvars; - Types::size_t currentIndex = 0; +class ClientNotificator: + public ::flame_ide::os::async::network::TcpClientNotificatorBase +{ +public: + virtual void operator()() const noexcept override; }; -}}} // namespace flame_ide::handler::network +}}}} // namespace flame_ide::handler::network::tcp #endif // HANDLERNOTIFICATOR_HPP diff --git a/src/Handler/Network/Udp.cpp b/src/Handler/Network/Udp.cpp index 9d14e049..4d9facc4 100644 --- a/src/Handler/Network/Udp.cpp +++ b/src/Handler/Network/Udp.cpp @@ -119,23 +119,25 @@ Handler::Udp::CallbackGetSessionHandle Handler::Udp::serverHandleCallback() cons Handler::Udp::CallbackServerDeregistrate Handler::Udp::serverCallbackDeregistrate() noexcept { - static const auto deregistrate = [](ServerHandle *handle) -> void + static const auto callback = [](ServerHandle *handle) -> void { auto handleData = handle->object.get(); const auto server = handleData.handler->popUdp(*handle); + flame_ide::unused(server); }; - return (+deregistrate); + return (+callback); } Handler::Udp::CallbackSessionDeregistrate Handler::Udp::clientCallbackDeregistrate() noexcept { - static const auto deregistrate = [](SessionHandle *handle) -> void + static const auto callback = [](SessionHandle *handle) -> void { auto handleData = handle->object.get(); - const auto server = handleData.handler->popUdp(*handle); + const auto client = handleData.handler->popUdp(*handle); + flame_ide::unused(client); }; - return (+deregistrate); + return (+callback); } udp::ServerCommunicationData *Handler::Udp::serverToCommunicationData( diff --git a/src/Handler/Network/Udp.hpp b/src/Handler/Network/Udp.hpp index 625ef8e5..5d48b6b6 100644 --- a/src/Handler/Network/Udp.hpp +++ b/src/Handler/Network/Udp.hpp @@ -38,11 +38,9 @@ class Handler::Udp public: Handler::ExpectedServerHandle push(os::network::UdpServer &&server) noexcept; - // TODO Handler::ExpectedSessionHandle push(os::network::UdpClient &&client) noexcept; Handler::ExpectedUdpServer pop(Handler::ServerHandle &handle); - // TODO Handler::ExpectedUdpClient pop(Handler::SessionHandle &handle); /// @brief serverHandleCallback diff --git a/src/Handler/Network/Udp/Endpoint.hpp b/src/Handler/Network/Udp/Endpoint.hpp index 67f947a5..06c1e7d2 100644 --- a/src/Handler/Network/Udp/Endpoint.hpp +++ b/src/Handler/Network/Udp/Endpoint.hpp @@ -90,7 +90,7 @@ using IsOsEndpoint = ::flame_ide::IntegralConstant< // Mappers -// Gets os::network::{ UdpServer, UdpCinet } <-> { Server, Client } +// Gets os::network::{ UdpServer, UdpClient } <-> { Server, Client } template using EndpointTypeMapper = ::flame_ide::TypeMapper< EndpointType diff --git a/src/Os/Async/Network/EventCatcherBase.cpp b/src/Os/Async/Network/EventCatcherBase.cpp index 21390952..65f2dcd6 100644 --- a/src/Os/Async/Network/EventCatcherBase.cpp +++ b/src/Os/Async/Network/EventCatcherBase.cpp @@ -11,22 +11,94 @@ SocketQueues &EventCatcherBase::queues() noexcept return socketQueues; } -void EventCatcherBase::setNotificator(const NotificatorBase &inputNotificator) noexcept +void EventCatcherBase::setNotificator(const UdpServerNotificatorBase ¬ificator) noexcept { - notificationObject = decltype(notificationObject)(inputNotificator); + notificationObjects.udpServer = decltype(notificationObjects.udpServer){ notificator }; } -void EventCatcherBase::unsetNotificator() noexcept +void EventCatcherBase::setNotificator(const UdpClientNotificatorBase ¬ificator) noexcept { - notificationObject = decltype(notificationObject)(nullptr); + notificationObjects.udpClient = decltype(notificationObjects.udpClient){ notificator }; } -// protected +void EventCatcherBase::setNotificator(const TcpServerNotificatorBase ¬ificator) noexcept +{ + notificationObjects.tcpServer = decltype(notificationObjects.tcpServer){ notificator }; +} + +void EventCatcherBase::setNotificator(const TcpAcceptedConnectionNotificatorBase ¬ificator) noexcept +{ + notificationObjects.tcpAcceptedConnection = + decltype(notificationObjects.tcpAcceptedConnection){ notificator }; +} + +void EventCatcherBase::setNotificator(const TcpClientNotificatorBase ¬ificator) noexcept +{ + notificationObjects.tcpClient = decltype(notificationObjects.tcpClient){ notificator }; +} + +void EventCatcherBase::unsetNotificator(tag::UdpServer) noexcept +{ + notificationObjects.udpServer = nullptr; +} + +void EventCatcherBase::unsetNotificator(tag::UdpClient) noexcept +{ + notificationObjects.udpClient = nullptr; +} + +void EventCatcherBase::unsetNotificator(tag::TcpServer) noexcept +{ + notificationObjects.tcpServer = nullptr; +} + +void EventCatcherBase::unsetNotificator(tag::TcpAcceptedConnection) noexcept +{ + notificationObjects.tcpAcceptedConnection = nullptr; +} + +void EventCatcherBase::unsetNotificator(tag::TcpClient) noexcept +{ + notificationObjects.tcpClient = nullptr; +} + +void EventCatcherBase::unsetNotificators() noexcept +{ + unsetNotificator(tag::UdpServer{}); + unsetNotificator(tag::UdpClient{}); + unsetNotificator(tag::TcpServer{}); + unsetNotificator(tag::TcpAcceptedConnection{}); + unsetNotificator(tag::TcpClient{}); +} + +void EventCatcherBase::notify(tag::UdpServer) const noexcept +{ + if (notificationObjects.udpServer) + notificationObjects.udpServer.get()(); +} + +void EventCatcherBase::notify(tag::UdpClient) const noexcept +{ + if (notificationObjects.udpClient) + notificationObjects.udpClient.get()(); +} + +void EventCatcherBase::notify(tag::TcpServer) const noexcept +{ + if (notificationObjects.tcpServer) + notificationObjects.tcpServer.get()(); +} + +void EventCatcherBase::notify(tag::TcpAcceptedConnection) const noexcept +{ + if (notificationObjects.tcpAcceptedConnection) + notificationObjects.tcpAcceptedConnection.get()(); +} -void EventCatcherBase::notify() const noexcept +void EventCatcherBase::notify(tag::TcpClient) const noexcept { - if (notificationObject) - notificationObject.get()(); + if (notificationObjects.tcpClient) + notificationObjects.tcpClient.get()(); } }}}} // namespace flame_ide::os::async::network diff --git a/src/Os/Async/Network/EventCatcherBase.hpp b/src/Os/Async/Network/EventCatcherBase.hpp index 9d210f47..87a30a10 100644 --- a/src/Os/Async/Network/EventCatcherBase.hpp +++ b/src/Os/Async/Network/EventCatcherBase.hpp @@ -19,6 +19,13 @@ namespace flame_ide /// class EventCatcherBase { +public: + using UdpServerTag = tag::UdpServer; + using UdpClientTag = tag::UdpClient; + using TcpServerTag = tag::TcpServer; + using TcpAcceptedConnectionTag = tag::TcpAcceptedConnection; + using TcpClientTag = tag::TcpServer; + public: virtual ~EventCatcherBase() noexcept = default; @@ -47,17 +54,34 @@ class EventCatcherBase /// @param notificator /// @note Implementation of NotificatorBase needs thread and signal safe /// - void setNotificator(const NotificatorBase ¬ificator) noexcept; + void setNotificator(const UdpServerNotificatorBase ¬ificator) noexcept; + void setNotificator(const UdpClientNotificatorBase ¬ificator) noexcept; + void setNotificator(const TcpServerNotificatorBase ¬ificator) noexcept; + void setNotificator(const TcpAcceptedConnectionNotificatorBase ¬ificator) noexcept; + void setNotificator(const TcpClientNotificatorBase ¬ificator) noexcept; /// /// @brief unsetNotifcator /// - void unsetNotificator() noexcept; + void unsetNotificator(tag::UdpServer) noexcept; + void unsetNotificator(tag::UdpClient) noexcept; + void unsetNotificator(tag::TcpServer) noexcept; + void unsetNotificator(tag::TcpAcceptedConnection) noexcept; + void unsetNotificator(tag::TcpClient) noexcept; + + /// + /// @brief unsetNotifcators + /// + void unsetNotificators() noexcept; /// /// @brief notify /// - void notify() const noexcept; + void notify(tag::UdpServer) const noexcept; + void notify(tag::UdpClient) const noexcept; + void notify(tag::TcpServer) const noexcept; + void notify(tag::TcpAcceptedConnection) const noexcept; + void notify(tag::TcpClient) const noexcept; public: static EventCatcherBase &get() noexcept; // platform impl @@ -67,7 +91,15 @@ class EventCatcherBase private: SocketQueues socketQueues; - ConstReferenceWrapper notificationObject = nullptr; + struct + { + ConstReferenceWrapper udpServer = nullptr; + ConstReferenceWrapper udpClient = nullptr; + ConstReferenceWrapper tcpServer = nullptr; + ConstReferenceWrapper + tcpAcceptedConnection = nullptr; + ConstReferenceWrapper tcpClient = nullptr; + } notificationObjects; }; }}}} // namespace flame_ide::os::async::network diff --git a/src/Os/Async/Network/Registrar.cpp b/src/Os/Async/Network/Registrar.cpp index a1df1410..d548a64f 100644 --- a/src/Os/Async/Network/Registrar.cpp +++ b/src/Os/Async/Network/Registrar.cpp @@ -177,14 +177,30 @@ bool Registrar::pushTcpClient(os::SocketDescriptor socket) noexcept // notificator -void Registrar::setNotificator(const NotificatorBase ¬ificator) noexcept +void Registrar::setNotificator(const UdpServerNotificatorBase ¬ificator) noexcept +{ + EventCatcherBase::get().setNotificator(notificator); +} +void Registrar::setNotificator(const UdpClientNotificatorBase ¬ificator) noexcept +{ + EventCatcherBase::get().setNotificator(notificator); +} +void Registrar::setNotificator(const TcpServerNotificatorBase ¬ificator) noexcept +{ + EventCatcherBase::get().setNotificator(notificator); +} +void Registrar::setNotificator(const TcpAcceptedConnectionNotificatorBase ¬ificator) noexcept +{ + EventCatcherBase::get().setNotificator(notificator); +} +void Registrar::setNotificator(const TcpClientNotificatorBase ¬ificator) noexcept { EventCatcherBase::get().setNotificator(notificator); } -void Registrar::unsetNotificator() noexcept +void Registrar::unsetNotificators() noexcept { - EventCatcherBase::get().unsetNotificator(); + EventCatcherBase::get().unsetNotificators(); } // other diff --git a/src/Os/Posix/Async/Network/EventCatcher.cpp b/src/Os/Posix/Async/Network/EventCatcher.cpp index ea1dc14b..1d655cd3 100644 --- a/src/Os/Posix/Async/Network/EventCatcher.cpp +++ b/src/Os/Posix/Async/Network/EventCatcher.cpp @@ -1,5 +1,6 @@ #include +#include #include #include @@ -96,6 +97,96 @@ void EventCatcher::signalHandler(int signal, const siginfo_t *info, ucontext_t * return; const auto descriptor = info->si_fd; + + /* + https://man7.org/linux/man-pages/man2/sigaction.2.html + + The following values can be placed in si_code for a SIGIO/SIGPOLL + signal: + + POLL_IN + Data input available. + + POLL_OUT + Output buffers available. + + POLL_MSG + Input message available. + + POLL_ERR + I/O error. + + POLL_PRI + High priority input available. + + POLL_HUP + Device disconnected. + */ + const auto code = info->si_code; + + /* + https://man7.org/linux/man-pages/man2/poll.2.html + + The bits that may be set/returned in events and revents are defined in : + + POLLIN There is data to read. + + POLLPRI + There is some exceptional condition on the file descriptor. + Possibilities include: + • There is out-of-band data on a TCP socket (see tcp(7)). + • A pseudoterminal master in packet mode has seen a state + change on the slave (see ioctl_tty(2)). + • A cgroup.events file has been modified (see cgroups(7)). + + POLLOUT + Writing is now possible, though a write larger than the + available space in a socket or pipe will still block + (unless O_NONBLOCK is set). + + POLLRDHUP (since Linux 2.6.17) + Stream socket peer closed connection, or shut down writing + half of connection. The _GNU_SOURCE feature test macro + must be defined (before including any header files) in + order to obtain this definition. + + POLLERR + Error condition (only returned in revents; ignored in + events). This bit is also set for a file descriptor + referring to the write end of a pipe when the read end has + been closed. + + POLLHUP + Hang up (only returned in revents; ignored in events). + Note that when reading from a channel such as a pipe or a + stream socket, this event merely indicates that the peer + closed its end of the channel. Subsequent reads from the + channel will return 0 (end of file) only after all + outstanding data in the channel has been consumed. + + POLLNVAL + Invalid request: fd not open (only returned in revents; + ignored in events). + + When compiling with _XOPEN_SOURCE defined, one also has the + following, which convey no further information beyond the bits + listed above: + + POLLRDNORM + Equivalent to POLLIN. + + POLLRDBAND + Priority band data can be read (generally unused on Linux). + + POLLWRNORM + Equivalent to POLLOUT. + + POLLWRBAND + Priority data may be written. + */ + const auto events = info->si_band; + flame_ide::unused(code, events); + switch (NetworkBase::callbacks().type(Socket{ {}, descriptor })) { case NetworkBase::SocketType::STREAM: @@ -110,8 +201,6 @@ void EventCatcher::signalHandler(int signal, const siginfo_t *info, ucontext_t * default: return; } - - EventCatcher::get().notify(); } void EventCatcher::handleTcp(SocketDescriptor descriptor) noexcept @@ -124,12 +213,14 @@ void EventCatcher::handleTcp(SocketDescriptor descriptor) noexcept { // Signal has been received from client's socket EventCatcher::get().queues().tcpClients().push(descriptor); + EventCatcher::get().notify(EventCatcher::TcpClientTag{}); return; } if (!serverControl().isListener(socket)) { // Signal has been received from accepted server's socket EventCatcher::get().queues().tcpServers().push(descriptor); + EventCatcher::get().notify(EventCatcher::TcpServerTag{}); return; } @@ -140,15 +231,23 @@ void EventCatcher::handleTcp(SocketDescriptor descriptor) noexcept return; EventCatcher::get().queues().tcpAcceptedConnections() .push({ socket.descriptor, client }); + EventCatcher::get().notify(EventCatcher::TcpAcceptedConnectionTag{}); return; } void EventCatcher::handleUdp(SocketDescriptor descriptor) noexcept { using os::network::NetworkBase; - (NetworkBase::callbacks().isServer(Socket{ {}, descriptor })) - ? EventCatcher::get().queues().udpServers().push(descriptor) - : EventCatcher::get().queues().udpClients().push(descriptor); + if(NetworkBase::callbacks().isServer(Socket{ {}, descriptor })) + { + EventCatcher::get().queues().udpServers().push(descriptor); + EventCatcher::get().notify(EventCatcher::UdpServerTag{}); + } + else + { + EventCatcher::get().queues().udpClients().push(descriptor); + EventCatcher::get().notify(EventCatcher::UdpClientTag{}); + } } os::Status EventCatcher::enableSignal(SocketDescriptor descriptor) noexcept diff --git a/src/Os/Tests/Async/Network/RegistrarTest.cpp b/src/Os/Tests/Async/Network/RegistrarTest.cpp index 2997c727..ca814bdb 100644 --- a/src/Os/Tests/Async/Network/RegistrarTest.cpp +++ b/src/Os/Tests/Async/Network/RegistrarTest.cpp @@ -25,7 +25,8 @@ namespace anonymous {namespace { -class NotificatorTest: public NotificatorBase +template +class NotificatorTest: public NotificatorBaseType { public: bool isNotified() const @@ -364,7 +365,7 @@ int RegistrarTest::udpNotify() os::network::UdpServer server{ port }; os::network::UdpClient client{ ipv4 }; - anonymous::NotificatorTest notificator; + anonymous::NotificatorTest notificator; Registrar registar; registar.setNotificator(notificator); @@ -409,7 +410,7 @@ int RegistrarTest::udpNotify() [®istar]() { registar.clear(); - registar.unsetNotificator(); + registar.unsetNotificators(); } ); diff --git a/src/Os/Windows/Async/Network/MessageDispatchThread.cpp b/src/Os/Windows/Async/Network/MessageDispatchThread.cpp index a9e6e240..484174e0 100644 --- a/src/Os/Windows/Async/Network/MessageDispatchThread.cpp +++ b/src/Os/Windows/Async/Network/MessageDispatchThread.cpp @@ -183,7 +183,6 @@ os::windows::OsResult MessageDispatchThread::action( default: break; } - os::async::network::EventCatcherBase::get().notify(); return ::DefWindowProcA( window, static_cast(message), descriptor, param @@ -202,9 +201,19 @@ void MessageDispatchThread::handleUdp( case Event::WRITE: { if (os::network::NetworkBase::callbacks().isServer(Socket{ descriptor })) + { queues.udpServers().push(descriptor); + os::async::network::EventCatcherBase::get().notify( + os::async::network::EventCatcherBase::UdpServerTag{} + ); + } else + { queues.udpClients().push(descriptor); + os::async::network::EventCatcherBase::get().notify( + os::async::network::EventCatcherBase::UdpClientTag{} + ); + } return; } default: @@ -229,16 +238,31 @@ void MessageDispatchThread::handleTcp( Socket{ descriptor }, &status ); if (os::STATUS_SUCCESS == status) + { queues.tcpAcceptedConnections().push({ descriptor, client }); + os::async::network::EventCatcherBase::get().notify( + os::async::network::EventCatcherBase::TcpAcceptedConnectionTag{} + ); + } return; } case Event::READ: case Event::WRITE: { if (os::network::NetworkBase::callbacks().isServer(Socket{ descriptor })) + { queues.tcpServers().push(descriptor); + os::async::network::EventCatcherBase::get().notify( + os::async::network::EventCatcherBase::TcpServerTag{} + ); + } else + { queues.tcpClients().push(descriptor); + os::async::network::EventCatcherBase::get().notify( + os::async::network::EventCatcherBase::TcpClientTag{} + ); + } return; } default: From aac8a3ea713eb7e9bdaa6b0c3b30c1e8811e0516 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Mon, 17 Aug 2026 01:24:47 +0300 Subject: [PATCH 28/37] Add EventType for async networking --- .../FlameIDE/Os/Async/Network/Registrar.hpp | 36 +++- src/Os/Async/Network/QueuedArray.hpp | 9 + src/Os/Async/Network/Registrar.cpp | 89 +++++++-- src/Os/Async/Network/Types.hpp | 11 +- src/Os/Posix/Async/Network/EventCatcher.cpp | 183 +++++++++--------- src/Os/Posix/Async/Network/EventCatcher.hpp | 5 +- src/Os/Tests/Async/Network/RegistrarTest.cpp | 62 +++--- src/Os/Tests/Async/Network/RegistrarTest.hpp | 2 +- .../Async/Network/MessageDispatchThread.cpp | 38 +++- 9 files changed, 270 insertions(+), 165 deletions(-) diff --git a/include/FlameIDE/Os/Async/Network/Registrar.hpp b/include/FlameIDE/Os/Async/Network/Registrar.hpp index c3ece887..cc2d43d8 100644 --- a/include/FlameIDE/Os/Async/Network/Registrar.hpp +++ b/include/FlameIDE/Os/Async/Network/Registrar.hpp @@ -23,7 +23,18 @@ namespace flame_ide {namespace network { -struct Config +enum class EventType: Types::int_t +{ + ERROR = -1 + , INIT = 0 + , READ + , WRITE + , READ_WRITE + , CLOSE +}; + + +struct SocketsInfo { struct Info { @@ -34,10 +45,18 @@ struct Config Types::size_t tcpClients; }; - Info max; - Info current; + const Info max; + const Info current; }; +struct AsyncEvent +{ + os::SocketDescriptor descriptor = os::SOCKET_INVALID.descriptor; + EventType event = EventType::ERROR; +}; +bool operator==(const AsyncEvent &ae1, const AsyncEvent &ae2) noexcept; +bool operator!=(const AsyncEvent &ae1, const AsyncEvent &ae2) noexcept; + class Registrar { public: @@ -50,7 +69,7 @@ class Registrar Registrar &operator=(Registrar &&) noexcept = default; public: - const Config &getConfig() const noexcept; + SocketsInfo getInfo() const noexcept; public: os::Status add(const os::network::UdpServer &socket) noexcept; @@ -65,11 +84,11 @@ class Registrar os::Status remove(const os::network::TcpServer::WithClient &socket) noexcept; os::Status remove(const os::network::TcpClient &socket) noexcept; - os::SocketDescriptor popUdpServer() noexcept; - os::SocketDescriptor popUdpClient() noexcept; + AsyncEvent popUdpServer() noexcept; + AsyncEvent popUdpClient() noexcept; AcceptedConnection popTcpServerAcception() noexcept; - os::SocketDescriptor popTcpServer() noexcept; - os::SocketDescriptor popTcpClient() noexcept; + AsyncEvent popTcpServer() noexcept; + AsyncEvent popTcpClient() noexcept; bool pushUdpServer(os::SocketDescriptor socket) noexcept; bool pushUdpClient(os::SocketDescriptor socket) noexcept; @@ -82,6 +101,7 @@ class Registrar void setNotificator(const TcpServerNotificatorBase ¬ificator) noexcept; void setNotificator(const TcpAcceptedConnectionNotificatorBase ¬ificator) noexcept; void setNotificator(const TcpClientNotificatorBase ¬ificator) noexcept; + void unsetNotificators() noexcept; void clear() noexcept; diff --git a/src/Os/Async/Network/QueuedArray.hpp b/src/Os/Async/Network/QueuedArray.hpp index 2b5b8986..89a5d813 100644 --- a/src/Os/Async/Network/QueuedArray.hpp +++ b/src/Os/Async/Network/QueuedArray.hpp @@ -23,6 +23,8 @@ class QueuedArray bool push(Type value) noexcept; templates::Expected pop(Type initValue = {}) noexcept; + Types::size_t getSize() const noexcept; + private: using Array = templates::StaticArray; using Pointer = templates::UniquePointer; @@ -104,6 +106,13 @@ QueuedArray::pop(Type initValue) noexcept return templates::Expected{ value }; } +template +Types::size_t QueuedArray::getSize() const noexcept +{ + os::threads::Locker locker{ spin }; + return count; +} + }}}} // namespace flame_ide::os::async::network #endif // ASYNC_NETWORK_QUEUEDARRAY_HPP diff --git a/src/Os/Async/Network/Registrar.cpp b/src/Os/Async/Network/Registrar.cpp index d548a64f..ba824c92 100644 --- a/src/Os/Async/Network/Registrar.cpp +++ b/src/Os/Async/Network/Registrar.cpp @@ -7,6 +7,38 @@ #include #include +#include + +namespace flame_ide +{namespace os +{namespace async +{namespace network +{ +namespace anonymous { namespace { + +static constexpr auto ASYNC_EVENT_INIT_VALUE = AsyncEvent{}; + +}} // namespace anonymous +}}}} // namespace flame_ide::os::async::network + +namespace flame_ide +{namespace os +{namespace async +{namespace network +{ + +bool operator==(const AsyncEvent &ae1, const AsyncEvent &ae2) noexcept +{ + return ((ae1.descriptor == ae2.descriptor) && (ae1.event == ae2.event)); +} + +bool operator!=(const AsyncEvent &ae1, const AsyncEvent &ae2) noexcept +{ + return !(ae1 == ae2); +} + +}}}} // namespace flame_ide::os::async::network + namespace flame_ide {namespace os {namespace async @@ -17,13 +49,30 @@ Registrar::Registrar() noexcept = default; Registrar::~Registrar() noexcept = default; +SocketsInfo Registrar::getInfo() const noexcept +{ + static constexpr SocketsInfo::Info MAX_INFO = SocketsInfo::Info { + generated::network::Config::UDP_SERVERS + , generated::network::Config::UDP_CLIENTS + , generated::network::Config::TCP_SERVERS + , generated::network::Config::TCP_CLIENTS + }; + + auto &queues = EventCatcherBase::get().queues(); + SocketsInfo config = { MAX_INFO, SocketsInfo::Info { + queues.udpServers().getSize(), queues.udpClients().getSize() + , queues.tcpServers().getSize(), queues.tcpClients().getSize() + } }; + return config; +} + // Registrar::add os::Status Registrar::add(const os::network::UdpServer &socket) noexcept { auto &queue = EventCatcherBase::get().queues().udpServers(); if (!queue) - queue.init(os::SOCKET_INVALID.descriptor); + queue.init(anonymous::ASYNC_EVENT_INIT_VALUE); return EventCatcherBase::get().enable(socket.native().descriptor); } @@ -31,7 +80,7 @@ os::Status Registrar::add(const os::network::UdpClient &socket) noexcept { auto &queue = EventCatcherBase::get().queues().udpClients(); if (!queue) - queue.init(os::SOCKET_INVALID.descriptor); + queue.init(anonymous::ASYNC_EVENT_INIT_VALUE); return EventCatcherBase::get().enable(socket.native().descriptor); } @@ -47,7 +96,7 @@ os::Status Registrar::add(const os::network::TcpServer::WithClient &socket) noex { auto &queue = EventCatcherBase::get().queues().tcpServers(); if (!queue) - queue.init(os::SOCKET_INVALID.descriptor); + queue.init(anonymous::ASYNC_EVENT_INIT_VALUE); return EventCatcherBase::get().enable(socket.native().descriptor); } @@ -55,7 +104,7 @@ os::Status Registrar::add(const os::network::TcpClient &socket) noexcept { auto &queue = EventCatcherBase::get().queues().tcpClients(); if (!queue) - queue.init(os::SOCKET_INVALID.descriptor); + queue.init(anonymous::ASYNC_EVENT_INIT_VALUE); return EventCatcherBase::get().enable(socket.native().descriptor); } @@ -88,10 +137,10 @@ os::Status Registrar::remove(const os::network::TcpClient &socket) noexcept // Registrar::pop* -os::SocketDescriptor Registrar::popUdpServer() noexcept +AsyncEvent Registrar::popUdpServer() noexcept { - os::SocketDescriptor descriptor = os::SOCKET_INVALID.descriptor; - EventCatcherBase::get().queues().udpServers().pop(os::SOCKET_INVALID.descriptor) + AsyncEvent descriptor = anonymous::ASYNC_EVENT_INIT_VALUE; + EventCatcherBase::get().queues().udpServers().pop(anonymous::ASYNC_EVENT_INIT_VALUE) .ifResult([&descriptor](auto &&actualDescriptor) { descriptor = actualDescriptor; @@ -100,10 +149,10 @@ os::SocketDescriptor Registrar::popUdpServer() noexcept return descriptor; } -os::SocketDescriptor Registrar::popUdpClient() noexcept +AsyncEvent Registrar::popUdpClient() noexcept { - os::SocketDescriptor descriptor = os::SOCKET_INVALID.descriptor; - EventCatcherBase::get().queues().udpClients().pop(os::SOCKET_INVALID.descriptor) + AsyncEvent descriptor = anonymous::ASYNC_EVENT_INIT_VALUE; + EventCatcherBase::get().queues().udpClients().pop(anonymous::ASYNC_EVENT_INIT_VALUE) .ifResult([&descriptor](auto &&actualDescriptor) { descriptor = actualDescriptor; @@ -124,10 +173,10 @@ AcceptedConnection Registrar::popTcpServerAcception() noexcept return connection; } -os::SocketDescriptor Registrar::popTcpServer() noexcept +AsyncEvent Registrar::popTcpServer() noexcept { - os::SocketDescriptor descriptor = os::SOCKET_INVALID.descriptor; - EventCatcherBase::get().queues().tcpServers().pop(os::SOCKET_INVALID.descriptor) + AsyncEvent descriptor = anonymous::ASYNC_EVENT_INIT_VALUE; + EventCatcherBase::get().queues().tcpServers().pop(anonymous::ASYNC_EVENT_INIT_VALUE) .ifResult([&descriptor](auto &&actualDescriptor) { descriptor = actualDescriptor; @@ -136,10 +185,10 @@ os::SocketDescriptor Registrar::popTcpServer() noexcept return descriptor; } -os::SocketDescriptor Registrar::popTcpClient() noexcept +AsyncEvent Registrar::popTcpClient() noexcept { - os::SocketDescriptor descriptor = os::SOCKET_INVALID.descriptor; - EventCatcherBase::get().queues().tcpClients().pop(os::SOCKET_INVALID.descriptor) + AsyncEvent descriptor = anonymous::ASYNC_EVENT_INIT_VALUE; + EventCatcherBase::get().queues().tcpClients().pop(anonymous::ASYNC_EVENT_INIT_VALUE) .ifResult([&descriptor](auto &&actualDescriptor) { descriptor = actualDescriptor; @@ -207,11 +256,11 @@ void Registrar::unsetNotificators() noexcept void Registrar::clear() noexcept { - while (popUdpServer() != os::SOCKET_INVALID.descriptor); - while (popUdpClient() != os::SOCKET_INVALID.descriptor); + while (popUdpServer() != anonymous::ASYNC_EVENT_INIT_VALUE); + while (popUdpClient() != anonymous::ASYNC_EVENT_INIT_VALUE); while (popTcpServerAcception()); - while (popTcpServer() != os::SOCKET_INVALID.descriptor); - while (popTcpClient() != os::SOCKET_INVALID.descriptor); + while (popTcpServer() != anonymous::ASYNC_EVENT_INIT_VALUE); + while (popTcpClient() != anonymous::ASYNC_EVENT_INIT_VALUE); } }}}} // namespace flame_ide::os::async::network diff --git a/src/Os/Async/Network/Types.hpp b/src/Os/Async/Network/Types.hpp index 206ae6a8..2de356ae 100644 --- a/src/Os/Async/Network/Types.hpp +++ b/src/Os/Async/Network/Types.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -17,16 +18,16 @@ namespace flame_ide static constexpr Types::size_t FACTOR = 4; template -using Descriptors = templates::StaticArray; +using Events = templates::StaticArray; -using UdpServers = Descriptors; -using UdpClients = Descriptors; -using TcpServers = Descriptors< +using UdpServers = Events; +using UdpClients = Events; +using TcpServers = Events< generated::network::Config::TCP_SERVERS * generated::network::Config::TCP_SERVER_BACKLOG * FACTOR >; -using TcpClients = Descriptors; +using TcpClients = Events; using AcceptedConnections = templates::StaticArray< AcceptedConnection, generated::network::Config::TCP_SERVER_BACKLOG * FACTOR diff --git a/src/Os/Posix/Async/Network/EventCatcher.cpp b/src/Os/Posix/Async/Network/EventCatcher.cpp index 1d655cd3..0d21c46b 100644 --- a/src/Os/Posix/Async/Network/EventCatcher.cpp +++ b/src/Os/Posix/Async/Network/EventCatcher.cpp @@ -1,10 +1,12 @@ #include #include +#include #include #include #include +#include namespace flame_ide {namespace os @@ -16,6 +18,45 @@ namespace anonymous{namespace{ static constexpr decltype(SIGPOLL) SIGNAL_POLLING = os::posix::Signal::POLL; +using BandEvent = decltype(siginfo_t{}.si_band); + +enum PollingFlags: BandEvent +{ + INPUT = POLLIN + , PRIORITY = POLLPRI + , OUTPUT = POLLOUT + , ERROR = POLLERR + , HANG_UP = POLLHUP + , INVALID_REQUEST = POLLNVAL + , READ_NORMAL = POLLRDNORM + , READ_PRIORITY = POLLRDBAND + , WRITE_NORMAL = POLLWRNORM + , WRITE_PRIORITY = POLLWRBAND +}; + +::flame_ide::os::async::network::EventType +convertBandEventsToAsyncEvent(BandEvent events) +{ + using ::flame_ide::os::async::network::EventType; + + if ((events & PollingFlags::ERROR) || (events & PollingFlags::INVALID_REQUEST)) + return EventType::ERROR; + + auto eventType = EventType::INIT; + + if ((events & PollingFlags::INPUT) || (events & PollingFlags::READ_NORMAL)) + eventType = EventType::READ; + + if ((events & PollingFlags::OUTPUT) || (events & PollingFlags::WRITE_NORMAL)) + { + eventType = (eventType == EventType::READ) + ? EventType::READ_WRITE + : EventType::WRITE; + } + + return eventType; +} + }} // namespace anonymous }}}}} // namespace flame_ide::os::posix::async::network @@ -89,7 +130,9 @@ EventCatcher::SigAction EventCatcher::makeSigAction() noexcept return action; } -void EventCatcher::signalHandler(int signal, const siginfo_t *info, ucontext_t *) noexcept +void EventCatcher::signalHandler( + int signal, const siginfo_t *info, ucontext_t * +) noexcept { using os::network::NetworkBase; @@ -99,102 +142,34 @@ void EventCatcher::signalHandler(int signal, const siginfo_t *info, ucontext_t * const auto descriptor = info->si_fd; /* - https://man7.org/linux/man-pages/man2/sigaction.2.html - - The following values can be placed in si_code for a SIGIO/SIGPOLL - signal: - - POLL_IN - Data input available. - - POLL_OUT - Output buffers available. - - POLL_MSG - Input message available. - - POLL_ERR - I/O error. - - POLL_PRI - High priority input available. - - POLL_HUP - Device disconnected. - */ - const auto code = info->si_code; - - /* - https://man7.org/linux/man-pages/man2/poll.2.html - - The bits that may be set/returned in events and revents are defined in : - - POLLIN There is data to read. - - POLLPRI - There is some exceptional condition on the file descriptor. - Possibilities include: - • There is out-of-band data on a TCP socket (see tcp(7)). - • A pseudoterminal master in packet mode has seen a state - change on the slave (see ioctl_tty(2)). - • A cgroup.events file has been modified (see cgroups(7)). - - POLLOUT - Writing is now possible, though a write larger than the - available space in a socket or pipe will still block - (unless O_NONBLOCK is set). - - POLLRDHUP (since Linux 2.6.17) - Stream socket peer closed connection, or shut down writing - half of connection. The _GNU_SOURCE feature test macro - must be defined (before including any header files) in - order to obtain this definition. - - POLLERR - Error condition (only returned in revents; ignored in - events). This bit is also set for a file descriptor - referring to the write end of a pipe when the read end has - been closed. - - POLLHUP - Hang up (only returned in revents; ignored in events). - Note that when reading from a channel such as a pipe or a - stream socket, this event merely indicates that the peer - closed its end of the channel. Subsequent reads from the - channel will return 0 (end of file) only after all - outstanding data in the channel has been consumed. - - POLLNVAL - Invalid request: fd not open (only returned in revents; - ignored in events). - - When compiling with _XOPEN_SOURCE defined, one also has the - following, which convey no further information beyond the bits - listed above: - - POLLRDNORM - Equivalent to POLLIN. - - POLLRDBAND - Priority band data can be read (generally unused on Linux). - - POLLWRNORM - Equivalent to POLLOUT. - - POLLWRBAND - Priority data may be written. + POLLIN = (bin) 1 // 0x001 // There is data to read + POLLPRI = (bin) 10 // 0x002 // There is urgent data to read + POLLOUT = (bin) 100 // 0x004 // Writing now will not block + POLLERR = (bin) 1000 // 0x008 // Error condition + POLLHUP = (bin) 10000 // 0x010 // Hung up + POLLNVAL = (bin) 100000 // 0x020 // Invalid polling request + + // defined __USE_XOPEN || defined __USE_XOPEN2K8 + POLLRDNORM = (bin) 1000000 // 0x040 // Normal data may be read + POLLRDBAND = (bin) 10000000 // 0x080 // Priority data may be read + POLLWRNORM = (bin) 100000000 // 0x100 // Writing now will not block + POLLWRBAND = (bin) 1000000000 // 0x200 // Priority data may be written + + // __USE_GNU + POLLMSG = (bin) 10000000000 // 0x400 + POLLREMOVE = (bin) 1000000000000 // 0x1000 + POLLRDHUP = (bin) 10000000000000 // 0x2000 */ const auto events = info->si_band; - flame_ide::unused(code, events); switch (NetworkBase::callbacks().type(Socket{ {}, descriptor })) { case NetworkBase::SocketType::STREAM: - handleTcp(descriptor); + handleTcp(descriptor, events); break; case NetworkBase::SocketType::DATAGRAM: - handleUdp(descriptor); + handleUdp(descriptor, events); break; case NetworkBase::SocketType::UNKNOWN: @@ -203,7 +178,7 @@ void EventCatcher::signalHandler(int signal, const siginfo_t *info, ucontext_t * } } -void EventCatcher::handleTcp(SocketDescriptor descriptor) noexcept +void EventCatcher::handleTcp(SocketDescriptor descriptor, SigEvents events) noexcept { using os::network::TcpServer; @@ -212,14 +187,24 @@ void EventCatcher::handleTcp(SocketDescriptor descriptor) noexcept if (!serverControl().isServer(socket)) { // Signal has been received from client's socket - EventCatcher::get().queues().tcpClients().push(descriptor); + EventCatcher::get().queues().tcpClients().push( + flame_ide::os::async::network::AsyncEvent { + descriptor + , anonymous::convertBandEventsToAsyncEvent(events) + } + ); EventCatcher::get().notify(EventCatcher::TcpClientTag{}); return; } if (!serverControl().isListener(socket)) { // Signal has been received from accepted server's socket - EventCatcher::get().queues().tcpServers().push(descriptor); + EventCatcher::get().queues().tcpServers().push( + flame_ide::os::async::network::AsyncEvent { + descriptor + , anonymous::convertBandEventsToAsyncEvent(events) + } + ); EventCatcher::get().notify(EventCatcher::TcpServerTag{}); return; } @@ -235,17 +220,27 @@ void EventCatcher::handleTcp(SocketDescriptor descriptor) noexcept return; } -void EventCatcher::handleUdp(SocketDescriptor descriptor) noexcept +void EventCatcher::handleUdp(SocketDescriptor descriptor, SigEvents events) noexcept { using os::network::NetworkBase; if(NetworkBase::callbacks().isServer(Socket{ {}, descriptor })) { - EventCatcher::get().queues().udpServers().push(descriptor); + EventCatcher::get().queues().udpServers().push( + flame_ide::os::async::network::AsyncEvent { + descriptor + , anonymous::convertBandEventsToAsyncEvent(events) + } + ); EventCatcher::get().notify(EventCatcher::UdpServerTag{}); } else { - EventCatcher::get().queues().udpClients().push(descriptor); + EventCatcher::get().queues().udpClients().push( + flame_ide::os::async::network::AsyncEvent { + descriptor + , anonymous::convertBandEventsToAsyncEvent(events) + } + ); EventCatcher::get().notify(EventCatcher::UdpClientTag{}); } } diff --git a/src/Os/Posix/Async/Network/EventCatcher.hpp b/src/Os/Posix/Async/Network/EventCatcher.hpp index 26f1d967..0c3fa2a2 100644 --- a/src/Os/Posix/Async/Network/EventCatcher.hpp +++ b/src/Os/Posix/Async/Network/EventCatcher.hpp @@ -25,11 +25,12 @@ class EventCatcher: public os::async::network::EventCatcherBase private: using SigAction = struct ::sigaction; using SigActionHandler = decltype(SigAction{}.sa_sigaction); + using SigEvents = decltype(siginfo_t{}.si_band); static SigAction makeSigAction() noexcept; static void signalHandler(int signal, const siginfo_t *info, ucontext_t *) noexcept; - static void handleTcp(SocketDescriptor descriptor) noexcept; - static void handleUdp(SocketDescriptor descriptor) noexcept; + static void handleTcp(SocketDescriptor descriptor, SigEvents events) noexcept; + static void handleUdp(SocketDescriptor descriptor, SigEvents events) noexcept; static os::Status enableSignal(SocketDescriptor descriptor) noexcept; static os::Status disableSignal(SocketDescriptor descriptor) noexcept; diff --git a/src/Os/Tests/Async/Network/RegistrarTest.cpp b/src/Os/Tests/Async/Network/RegistrarTest.cpp index ca814bdb..7063cce8 100644 --- a/src/Os/Tests/Async/Network/RegistrarTest.cpp +++ b/src/Os/Tests/Async/Network/RegistrarTest.cpp @@ -103,7 +103,7 @@ int RegistrarTest::vStart() "UdpServer notify" , [this] { - return udpNotify(); + return udpServerNotify(); } )); return RegistrarTest::SUCCESS; @@ -127,16 +127,16 @@ int RegistrarTest::udpServer() } // Wait - os::SocketDescriptor resultDescriptor = os::SOCKET_INVALID.descriptor; + AsyncEvent resultEvent{}; for (auto i = numberOfTries - ; i != 0 && os::SOCKET_INVALID.descriptor == resultDescriptor + ; i != 0 && os::SOCKET_INVALID.descriptor == resultEvent.descriptor ; --i ) { - resultDescriptor = registar.popUdpServer(); + resultEvent = registar.popUdpServer(); } - IN_CASE_CHECK(resultDescriptor != os::SOCKET_INVALID.descriptor); - IN_CASE_CHECK(resultDescriptor == server.native().descriptor); + IN_CASE_CHECK(resultEvent.descriptor != os::SOCKET_INVALID.descriptor); + IN_CASE_CHECK(resultEvent.descriptor == server.native().descriptor); auto fromServer = server.wait(); IN_CASE_CHECK(fromServer.getStatus() == sizeof(MESSAGE_PING)); @@ -178,10 +178,10 @@ int RegistrarTest::udpClient() IN_CASE_CHECK(result == sizeof(MESSAGE_PING)); // Wait - os::SocketDescriptor resultDescriptor = os::SOCKET_INVALID.descriptor; - for (auto i = numberOfTries; i != 0 && os::SOCKET_INVALID.descriptor == resultDescriptor; --i) + AsyncEvent resultEvent{}; + for (auto i = numberOfTries; i != 0 && os::SOCKET_INVALID.descriptor == resultEvent.descriptor; --i) { - resultDescriptor = registar.popUdpServer(); + resultEvent = registar.popUdpServer(); } } @@ -218,12 +218,12 @@ int RegistrarTest::udpClient() ); // Wait - os::SocketDescriptor resultDescriptor = os::SOCKET_INVALID.descriptor; - for (auto i = numberOfTries; i != 0 && os::SOCKET_INVALID.descriptor == resultDescriptor; --i) + AsyncEvent resultEvent{}; + for (auto i = numberOfTries; i != 0 && os::SOCKET_INVALID.descriptor == resultEvent.descriptor; --i) { - resultDescriptor = registar.popUdpClient(); + resultEvent = registar.popUdpClient(); } - IN_CASE_CHECK(resultDescriptor == client.native().descriptor); + IN_CASE_CHECK(resultEvent.descriptor == client.native().descriptor); } IN_CASE_CHECK(registar.remove(client) == os::STATUS_SUCCESS); } @@ -299,13 +299,13 @@ int RegistrarTest::tcpServer() IN_CASE_CHECK(client.disconnect() == os::STATUS_SUCCESS); // Wait - os::SocketDescriptor resultDescriptor = os::SOCKET_INVALID.descriptor; - for (auto i = numberOfTries; i != 0 && os::SOCKET_INVALID.descriptor == resultDescriptor; --i) + AsyncEvent resultEvent{}; + for (auto i = numberOfTries; i != 0 && os::SOCKET_INVALID.descriptor == resultEvent.descriptor; --i) { - resultDescriptor = registar.popTcpServer(); + resultEvent = registar.popTcpServer(); } - IN_CASE_CHECK(resultDescriptor != os::SOCKET_INVALID.descriptor); - IN_CASE_CHECK(resultDescriptor == serverConnection.native().descriptor); + IN_CASE_CHECK(resultEvent.descriptor != os::SOCKET_INVALID.descriptor); + IN_CASE_CHECK(resultEvent.descriptor == serverConnection.native().descriptor); IN_CASE_CHECK(registar.remove(serverConnection) == os::STATUS_SUCCESS); @@ -349,18 +349,18 @@ int RegistrarTest::tcpClient() ); // Wait - os::SocketDescriptor resultDescriptor = os::SOCKET_INVALID.descriptor; - for (auto i = numberOfTries; i != 0 && os::SOCKET_INVALID.descriptor == resultDescriptor; --i) + AsyncEvent resultEvent{}; + for (auto i = numberOfTries; i != 0 && os::SOCKET_INVALID.descriptor == resultEvent.descriptor; --i) { - resultDescriptor = registar.popTcpClient(); + resultEvent = registar.popTcpClient(); } - IN_CASE_CHECK(resultDescriptor != os::SOCKET_INVALID.descriptor); - IN_CASE_CHECK(resultDescriptor == client.native().descriptor); + IN_CASE_CHECK(resultEvent.descriptor != os::SOCKET_INVALID.descriptor); + IN_CASE_CHECK(resultEvent.descriptor == client.native().descriptor); return RegistrarTest::SUCCESS; } -int RegistrarTest::udpNotify() +int RegistrarTest::udpServerNotify() { os::network::UdpServer server{ port }; os::network::UdpClient client{ ipv4 }; @@ -382,16 +382,18 @@ int RegistrarTest::udpNotify() } // Wait - os::SocketDescriptor resultDescriptor = os::SOCKET_INVALID.descriptor; + AsyncEvent resultEvent{}; for (auto i = numberOfTries - ; i != 0 && os::SOCKET_INVALID.descriptor == resultDescriptor + ; i != 0 && os::SOCKET_INVALID.descriptor == resultEvent.descriptor ; --i ) { - resultDescriptor = registar.popUdpServer(); + resultEvent = registar.popUdpServer(); } - IN_CASE_CHECK(resultDescriptor != os::SOCKET_INVALID.descriptor); - IN_CASE_CHECK(resultDescriptor == server.native().descriptor); + + IN_CASE_CHECK(notificator.isNotified() == true); + IN_CASE_CHECK(resultEvent.descriptor != os::SOCKET_INVALID.descriptor); + IN_CASE_CHECK(resultEvent.descriptor == server.native().descriptor); auto fromServer = server.wait(); IN_CASE_CHECK(fromServer.getStatus() == sizeof(MESSAGE_PING)); @@ -414,8 +416,6 @@ int RegistrarTest::udpNotify() } ); - IN_CASE_CHECK(notificator.isNotified() == true); - return RegistrarTest::SUCCESS; } diff --git a/src/Os/Tests/Async/Network/RegistrarTest.hpp b/src/Os/Tests/Async/Network/RegistrarTest.hpp index 4c33b1fd..6fb27c8c 100644 --- a/src/Os/Tests/Async/Network/RegistrarTest.hpp +++ b/src/Os/Tests/Async/Network/RegistrarTest.hpp @@ -26,7 +26,7 @@ struct RegistrarTest: public ::AbstractTest int tcpServer(); int tcpClient(); - int udpNotify(); + int udpServerNotify(); private: const Types::size_t numberOfTries = NumberLimitValueMax; diff --git a/src/Os/Windows/Async/Network/MessageDispatchThread.cpp b/src/Os/Windows/Async/Network/MessageDispatchThread.cpp index 484174e0..ca0a16cc 100644 --- a/src/Os/Windows/Async/Network/MessageDispatchThread.cpp +++ b/src/Os/Windows/Async/Network/MessageDispatchThread.cpp @@ -15,6 +15,24 @@ namespace flame_ide constexpr char WINDOW_CLASS_NAME[] = "AsyncSelect"; +flame_ide::os::async::network::EventType convertFromWinEventToAsyncEvent(Event event) +{ + using AsyncEventType = flame_ide::os::async::network::EventType; + switch (event) { + case Event::READ: + return AsyncEventType::READ; + case Event::WRITE: + return AsyncEventType::WRITE; + case Event::CLOSE: + return AsyncEventType::CLOSE; + + case Event::UNKNOWN: + case Event::CONNECT: + default: + return AsyncEventType::INIT; + } +} + }} // namespace anonymous }}}}} // namespace flame_ide::os::windows::async::network @@ -202,14 +220,20 @@ void MessageDispatchThread::handleUdp( { if (os::network::NetworkBase::callbacks().isServer(Socket{ descriptor })) { - queues.udpServers().push(descriptor); + queues.udpServers().push({ + descriptor + , anonymous::convertFromWinEventToAsyncEvent(eventValue) + }); os::async::network::EventCatcherBase::get().notify( os::async::network::EventCatcherBase::UdpServerTag{} ); } else { - queues.udpClients().push(descriptor); + queues.udpClients().push({ + descriptor + , anonymous::convertFromWinEventToAsyncEvent(eventValue) + }); os::async::network::EventCatcherBase::get().notify( os::async::network::EventCatcherBase::UdpClientTag{} ); @@ -251,14 +275,20 @@ void MessageDispatchThread::handleTcp( { if (os::network::NetworkBase::callbacks().isServer(Socket{ descriptor })) { - queues.tcpServers().push(descriptor); + queues.tcpServers().push({ + descriptor + , anonymous::convertFromWinEventToAsyncEvent(eventValue) + }); os::async::network::EventCatcherBase::get().notify( os::async::network::EventCatcherBase::TcpServerTag{} ); } else { - queues.tcpClients().push(descriptor); + queues.tcpClients().push({ + descriptor + , anonymous::convertFromWinEventToAsyncEvent(eventValue) + }); os::async::network::EventCatcherBase::get().notify( os::async::network::EventCatcherBase::TcpClientTag{} ); From 6678693b010ebe5c0b4ad20236f75e330cc4a005 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Mon, 17 Aug 2026 01:28:15 +0300 Subject: [PATCH 29/37] Remove useless push() functions in Registrar --- .../FlameIDE/Os/Async/Network/Registrar.hpp | 6 ----- src/Os/Async/Network/Registrar.cpp | 27 ------------------- 2 files changed, 33 deletions(-) diff --git a/include/FlameIDE/Os/Async/Network/Registrar.hpp b/include/FlameIDE/Os/Async/Network/Registrar.hpp index cc2d43d8..4794b2bb 100644 --- a/include/FlameIDE/Os/Async/Network/Registrar.hpp +++ b/include/FlameIDE/Os/Async/Network/Registrar.hpp @@ -90,12 +90,6 @@ class Registrar AsyncEvent popTcpServer() noexcept; AsyncEvent popTcpClient() noexcept; - bool pushUdpServer(os::SocketDescriptor socket) noexcept; - bool pushUdpClient(os::SocketDescriptor socket) noexcept; - bool pushTcpServerAcception(AcceptedConnection connection) noexcept; - bool pushTcpServer(os::SocketDescriptor socket) noexcept; - bool pushTcpClient(os::SocketDescriptor socket) noexcept; - void setNotificator(const UdpServerNotificatorBase ¬ificator) noexcept; void setNotificator(const UdpClientNotificatorBase ¬ificator) noexcept; void setNotificator(const TcpServerNotificatorBase ¬ificator) noexcept; diff --git a/src/Os/Async/Network/Registrar.cpp b/src/Os/Async/Network/Registrar.cpp index ba824c92..fb8b636d 100644 --- a/src/Os/Async/Network/Registrar.cpp +++ b/src/Os/Async/Network/Registrar.cpp @@ -197,33 +197,6 @@ AsyncEvent Registrar::popTcpClient() noexcept return descriptor; } -// Registrar::push* - -bool Registrar::pushUdpServer(os::SocketDescriptor socket) noexcept -{ - return EventCatcherBase::get().queues().udpServers().push(socket); -} - -bool Registrar::pushUdpClient(os::SocketDescriptor socket) noexcept -{ - return EventCatcherBase::get().queues().udpClients().push(socket); -} - -bool Registrar::pushTcpServerAcception(AcceptedConnection connection) noexcept -{ - return EventCatcherBase::get().queues().tcpAcceptedConnections().push(connection); -} - -bool Registrar::pushTcpServer(os::SocketDescriptor socket) noexcept -{ - return EventCatcherBase::get().queues().tcpServers().push(socket); -} - -bool Registrar::pushTcpClient(os::SocketDescriptor socket) noexcept -{ - return EventCatcherBase::get().queues().tcpClients().push(socket); -} - // notificator void Registrar::setNotificator(const UdpServerNotificatorBase ¬ificator) noexcept From aa3bcf2784378f1ffc73a2634b7a2ffa7c0072d8 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Mon, 17 Aug 2026 01:52:25 +0300 Subject: [PATCH 30/37] Fix build --- .../FlameIDE/Os/Async/Network/Registrar.hpp | 4 +-- include/FlameIDE/Templates/HybridVector.hpp | 32 +++++++++---------- src/Os/Posix/Async/Network/EventCatcher.cpp | 2 +- .../Async/Network/MessageDispatchThread.cpp | 8 ++--- src/Templates/Tests/HybridVectorTest.cpp | 2 ++ src/Templates/Tests/HybridVectorTest.hpp | 1 - 6 files changed, 25 insertions(+), 24 deletions(-) diff --git a/include/FlameIDE/Os/Async/Network/Registrar.hpp b/include/FlameIDE/Os/Async/Network/Registrar.hpp index 4794b2bb..aada524e 100644 --- a/include/FlameIDE/Os/Async/Network/Registrar.hpp +++ b/include/FlameIDE/Os/Async/Network/Registrar.hpp @@ -25,7 +25,7 @@ namespace flame_ide enum class EventType: Types::int_t { - ERROR = -1 + INVALID = -1 , INIT = 0 , READ , WRITE @@ -52,7 +52,7 @@ struct SocketsInfo struct AsyncEvent { os::SocketDescriptor descriptor = os::SOCKET_INVALID.descriptor; - EventType event = EventType::ERROR; + EventType event = EventType::INVALID; }; bool operator==(const AsyncEvent &ae1, const AsyncEvent &ae2) noexcept; bool operator!=(const AsyncEvent &ae1, const AsyncEvent &ae2) noexcept; diff --git a/include/FlameIDE/Templates/HybridVector.hpp b/include/FlameIDE/Templates/HybridVector.hpp index 04af186a..7883769e 100644 --- a/include/FlameIDE/Templates/HybridVector.hpp +++ b/include/FlameIDE/Templates/HybridVector.hpp @@ -827,8 +827,8 @@ bool ITERATOR_TYPE::operator!=(const Me &iterator) const ITERATOR_TEMPLATE bool ITERATOR_TYPE::operator<(const Me &iterator) const { - if (wrappedIterator.template getCurrentIndex() == - iterator.wrappedIterator.template getCurrentIndex()) + if (wrappedIterator.getCurrentIndex() == + iterator.wrappedIterator.getCurrentIndex()) { if (isArrayIterator()) { @@ -853,8 +853,8 @@ bool ITERATOR_TYPE::operator<(const Me &iterator) const ITERATOR_TEMPLATE bool ITERATOR_TYPE::operator>(const Me &iterator) const { - if (wrappedIterator.template getCurrentIndex() == - iterator.wrappedIterator.template getCurrentIndex()) + if (wrappedIterator.getCurrentIndex() == + iterator.wrappedIterator.getCurrentIndex()) { if (isArrayIterator()) { @@ -879,8 +879,8 @@ bool ITERATOR_TYPE::operator>(const Me &iterator) const ITERATOR_TEMPLATE bool ITERATOR_TYPE::operator<=(const Me &iterator) const { - if (wrappedIterator.template getCurrentIndex() == - iterator.wrappedIterator.template getCurrentIndex()) + if (wrappedIterator.getCurrentIndex() == + iterator.wrappedIterator.getCurrentIndex()) { if (isArrayIterator()) { @@ -905,8 +905,8 @@ bool ITERATOR_TYPE::operator<=(const Me &iterator) const ITERATOR_TEMPLATE bool ITERATOR_TYPE::operator>=(const Me &iterator) const { - if (wrappedIterator.template getCurrentIndex() == - iterator.wrappedIterator.template getCurrentIndex()) + if (wrappedIterator.getCurrentIndex() == + iterator.wrappedIterator.getCurrentIndex()) { if (isArrayIterator()) { @@ -1167,8 +1167,8 @@ bool ITERATOR_TYPE::operator!=(const Me &iterator) const ITERATOR_TEMPLATE bool ITERATOR_TYPE::operator<(const Me &iterator) const { - if (wrappedIterator.template getCurrentIndex() == - iterator.wrappedIterator.template getCurrentIndex()) + if (wrappedIterator.getCurrentIndex() == + iterator.wrappedIterator.getCurrentIndex()) { if (isArrayIterator()) { @@ -1196,8 +1196,8 @@ bool ITERATOR_TYPE::operator<(const Me &iterator) const ITERATOR_TEMPLATE bool ITERATOR_TYPE::operator>(const Me &iterator) const { - if (wrappedIterator.template getCurrentIndex() == - iterator.wrappedIterator.template getCurrentIndex()) + if (wrappedIterator.getCurrentIndex() == + iterator.wrappedIterator.getCurrentIndex()) { if (isArrayIterator()) { @@ -1226,8 +1226,8 @@ bool ITERATOR_TYPE::operator>(const Me &iterator) const ITERATOR_TEMPLATE bool ITERATOR_TYPE::operator<=(const Me &iterator) const { - if (wrappedIterator.template getCurrentIndex() == - iterator.wrappedIterator.template getCurrentIndex()) + if (wrappedIterator.getCurrentIndex() == + iterator.wrappedIterator.getCurrentIndex()) { if (isArrayIterator()) { @@ -1256,8 +1256,8 @@ bool ITERATOR_TYPE::operator<=(const Me &iterator) const ITERATOR_TEMPLATE bool ITERATOR_TYPE::operator>=(const Me &iterator) const { - if (wrappedIterator.template getCurrentIndex() == - iterator.wrappedIterator.template getCurrentIndex()) + if (wrappedIterator.getCurrentIndex() == + iterator.wrappedIterator.getCurrentIndex()) { if (isArrayIterator()) { diff --git a/src/Os/Posix/Async/Network/EventCatcher.cpp b/src/Os/Posix/Async/Network/EventCatcher.cpp index 0d21c46b..cb8023e0 100644 --- a/src/Os/Posix/Async/Network/EventCatcher.cpp +++ b/src/Os/Posix/Async/Network/EventCatcher.cpp @@ -40,7 +40,7 @@ convertBandEventsToAsyncEvent(BandEvent events) using ::flame_ide::os::async::network::EventType; if ((events & PollingFlags::ERROR) || (events & PollingFlags::INVALID_REQUEST)) - return EventType::ERROR; + return EventType::INVALID; auto eventType = EventType::INIT; diff --git a/src/Os/Windows/Async/Network/MessageDispatchThread.cpp b/src/Os/Windows/Async/Network/MessageDispatchThread.cpp index ca0a16cc..ad0fc9a5 100644 --- a/src/Os/Windows/Async/Network/MessageDispatchThread.cpp +++ b/src/Os/Windows/Async/Network/MessageDispatchThread.cpp @@ -220,7 +220,7 @@ void MessageDispatchThread::handleUdp( { if (os::network::NetworkBase::callbacks().isServer(Socket{ descriptor })) { - queues.udpServers().push({ + queues.udpServers().push(os::async::network::AsyncEvent{ descriptor , anonymous::convertFromWinEventToAsyncEvent(eventValue) }); @@ -230,7 +230,7 @@ void MessageDispatchThread::handleUdp( } else { - queues.udpClients().push({ + queues.udpClients().push(os::async::network::AsyncEvent{ descriptor , anonymous::convertFromWinEventToAsyncEvent(eventValue) }); @@ -275,7 +275,7 @@ void MessageDispatchThread::handleTcp( { if (os::network::NetworkBase::callbacks().isServer(Socket{ descriptor })) { - queues.tcpServers().push({ + queues.tcpServers().push(os::async::network::AsyncEvent{ descriptor , anonymous::convertFromWinEventToAsyncEvent(eventValue) }); @@ -285,7 +285,7 @@ void MessageDispatchThread::handleTcp( } else { - queues.tcpClients().push({ + queues.tcpClients().push(os::async::network::AsyncEvent{ descriptor , anonymous::convertFromWinEventToAsyncEvent(eventValue) }); diff --git a/src/Templates/Tests/HybridVectorTest.cpp b/src/Templates/Tests/HybridVectorTest.cpp index 9a187073..7a9cddde 100644 --- a/src/Templates/Tests/HybridVectorTest.cpp +++ b/src/Templates/Tests/HybridVectorTest.cpp @@ -3,6 +3,8 @@ #include #include +#include "TestClass.hpp" + namespace flame_ide {namespace templates {namespace test diff --git a/src/Templates/Tests/HybridVectorTest.hpp b/src/Templates/Tests/HybridVectorTest.hpp index a9517875..62bb3892 100644 --- a/src/Templates/Tests/HybridVectorTest.hpp +++ b/src/Templates/Tests/HybridVectorTest.hpp @@ -3,7 +3,6 @@ #include #include -#include "TestClass.hpp" #include #include From 678111dc19467db0fa8003b92ee3e333f772c4e7 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Mon, 17 Aug 2026 20:28:55 +0300 Subject: [PATCH 31/37] Refactoring Udp types --- src/Handler/Network/Udp/ActualData.hpp | 104 +++++++++ src/Handler/Network/Udp/Client.hpp | 9 +- src/Handler/Network/Udp/ContainerTypes.hpp | 35 +++ src/Handler/Network/Udp/Endpoint.hpp | 247 ++++++++++++-------- src/Handler/Network/Udp/Headers.cmake | 4 + src/Handler/Network/Udp/Message.hpp | 29 +++ src/Handler/Network/Udp/Server.hpp | 9 +- src/Handler/Network/Udp/Storage.hpp | 4 +- src/Handler/Network/Udp/TypeMapping.hpp | 120 ++++++++++ src/Handler/Network/Udp/Types.hpp | 257 +-------------------- 10 files changed, 466 insertions(+), 352 deletions(-) create mode 100644 src/Handler/Network/Udp/ActualData.hpp create mode 100644 src/Handler/Network/Udp/ContainerTypes.hpp create mode 100644 src/Handler/Network/Udp/Message.hpp create mode 100644 src/Handler/Network/Udp/TypeMapping.hpp diff --git a/src/Handler/Network/Udp/ActualData.hpp b/src/Handler/Network/Udp/ActualData.hpp new file mode 100644 index 00000000..910bceb3 --- /dev/null +++ b/src/Handler/Network/Udp/ActualData.hpp @@ -0,0 +1,104 @@ +#ifndef HANDLER_INTERNAL_UDP_ACTUAL_DATA_HPP +#define HANDLER_INTERNAL_UDP_ACTUAL_DATA_HPP + +#include +#include + +#include +#include + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +template +struct ActualData +{ +public: + using Messages = flame_ide::templates::StaticArray< + flame_ide::templates::UniquePointer, SIZE + >; + using MessagesCircularIterator = + flame_ide::templates::defaults::CircularForwardIterator< + typename Messages::Iterator + >; + + MessageType *getEmptyMessage() noexcept; + MessageType *getFilledMessage() noexcept; + + ::flame_ide::Types::ssize_t getFilledMessageSize() const noexcept; + +private: + ::flame_ide::Types::size_t amount = 0; + + Messages messages; + MessagesCircularIterator first = MessagesCircularIterator{ + messages.begin() + , templates::makeRange(messages.begin(), messages.end()) + }; + MessagesCircularIterator last = first; + + mutable os::threads::Spin spin; +}; + +}}}} // namespace flame_ide::handler::network::udp + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +template +MessageType *ActualData::getEmptyMessage() noexcept +{ + os::threads::Locker lock{ spin }; + + if (amount == SIZE) + return nullptr; + + auto result = last; + ++amount; + ++last; + return result->pointer(); +} + +template +MessageType *ActualData::getFilledMessage() noexcept +{ + os::threads::Locker lock{ spin }; + + if ((first == last) && (amount == 0)) + return nullptr; + + auto result = first; + --amount; + ++first; + return result->pointer(); +} + +template +::flame_ide::Types::ssize_t +ActualData::getFilledMessageSize() const noexcept +{ + os::threads::Locker lock{ spin }; + + if ((first == last) && (amount == 0)) + return 0; + + { + const auto &message = *first; + os::threads::Locker messageLocker{ message->spin }; + if (message->state == MessageState::EMPTY) + return 0; + return message->size; + } +} + +}}}} // namespace flame_ide::handler::network::udp + +#endif // HANDLER_INTERNAL_UDP_ACTUAL_DATA_HPP diff --git a/src/Handler/Network/Udp/Client.hpp b/src/Handler/Network/Udp/Client.hpp index 7e830418..698ef1ec 100644 --- a/src/Handler/Network/Udp/Client.hpp +++ b/src/Handler/Network/Udp/Client.hpp @@ -1,7 +1,8 @@ #ifndef HANDLERINTERNALUDPCLIENT_HPP #define HANDLERINTERNALUDPCLIENT_HPP -#include +#include +#include #include #include @@ -14,10 +15,12 @@ namespace flame_ide struct ClientMessage: public Message {}; -using Client = Endpoint< + +class Client: public Endpoint< ::flame_ide::os::network::UdpClient, ClientMessage , Constants::CLIENT_INPUT_QUEUE_SIZE, Constants::CLIENT_OUTPUT_QUEUE_SIZE ->; +> +{}; struct ClientCommunicationData { diff --git a/src/Handler/Network/Udp/ContainerTypes.hpp b/src/Handler/Network/Udp/ContainerTypes.hpp new file mode 100644 index 00000000..42c89dd1 --- /dev/null +++ b/src/Handler/Network/Udp/ContainerTypes.hpp @@ -0,0 +1,35 @@ +#ifndef HANDLER_INTERNAL_UDP_CONTAINER_TYPES_HPP +#define HANDLER_INTERNAL_UDP_CONTAINER_TYPES_HPP + +#include + +#include +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +// WARNING: using UniquePointer because malloc doen't work with big sizes +class Servers: public ::flame_ide::templates::StaticArray< + templates::UniquePointer, Constants::NUMBER_OF_SERVERS +> +{}; + +// WARNING: using UniquePointer because malloc doen't work with big sizes +class Clients: public ::flame_ide::templates::StaticArray< + templates::UniquePointer, Constants::NUMBER_OF_CLIENTS +> +{}; + +using SocketDescriptors = ::flame_ide::templates::StaticArray< + ::flame_ide::os::SocketDescriptor + , Constants::NUMBER_OF_SERVERS + Constants::NUMBER_OF_CLIENTS +>; + +}}}} // namespace flame_ide::handler::network::udp + +#endif // HANDLER_INTERNAL_UDP_CONTAINER_TYPES_HPP diff --git a/src/Handler/Network/Udp/Endpoint.hpp b/src/Handler/Network/Udp/Endpoint.hpp index 06c1e7d2..5e20fc64 100644 --- a/src/Handler/Network/Udp/Endpoint.hpp +++ b/src/Handler/Network/Udp/Endpoint.hpp @@ -2,10 +2,10 @@ #define HANDLERINTERNALUDPENDPOINT_HPP #include +#include #include -#include -#include +#include namespace flame_ide {namespace handler @@ -13,106 +13,167 @@ namespace flame_ide {namespace udp { -// Container data +template< + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE +> +class Endpoint +{ +public: + using Data = EndpointData; + using Optional = flame_ide::templates::Optional; + using ActualInput = ActualData; + using ActualOutput = ActualData; -// WARNING: using UniquePointer because malloc doen't work with big sizes -using Servers = ::flame_ide::templates::StaticArray< - templates::UniquePointer, Constants::NUMBER_OF_SERVERS ->; + bool empty() const noexcept; + void attach(EndpointData &&data) noexcept; + EndpointData detach() noexcept; -// WARNING: using UniquePointer because malloc doen't work with big sizes -using Clients = ::flame_ide::templates::StaticArray< - templates::UniquePointer, Constants::NUMBER_OF_CLIENTS ->; + Optional &endpoint() noexcept; + const Optional &endpoint() const noexcept; -using SocketDescriptors = ::flame_ide::templates::StaticArray< - ::flame_ide::os::SocketDescriptor - , Constants::NUMBER_OF_SERVERS + Constants::NUMBER_OF_CLIENTS ->; + ActualInput &input() noexcept; + const ActualInput &input() const noexcept; -template -struct HandlerEndpointUdpData -{ - templates::UniquePointer container = decltype(container)::makeEmpty(); - os::threads::Spin spin; + ActualOutput &output() noexcept; + const ActualOutput &output() const noexcept; + +protected: + Optional osEndpoint; + ActualInput actualInput; + ActualOutput actualOutput; }; -// Matching traits - -using ServerMatchingTrait = ::flame_ide::TypeMappingTrait< - os::network::UdpServer, Server ->; -using ClientMatchingTrait = ::flame_ide::TypeMappingTrait< - os::network::UdpClient, Client ->; - -using ServerDataMatchingTrait = ::flame_ide::TypeMappingTrait< - Server, HandlerEndpointUdpData ->; -using ClientDataMatchingTrait = ::flame_ide::TypeMappingTrait< - Client, HandlerEndpointUdpData ->; - -// Integral constants - -template -using IsServer = ::flame_ide::IntegralConstant< - bool - , ::flame_ide::ComparingTypes< - EndpointType, ::flame_ide::os::network::UdpServer - >::VALUE || ::flame_ide::ComparingTypes::VALUE ->; - -template -using IsClient = ::flame_ide::IntegralConstant< - bool - , ::flame_ide::ComparingTypes< - EndpointType, ::flame_ide::os::network::UdpClient - >::VALUE || ::flame_ide::ComparingTypes::VALUE ->; - -template -using IsCommonEndpoint = ::flame_ide::IntegralConstant< - bool, IsServer::VALUE || IsClient::VALUE ->; - -template -using IsHandlerEndpoint = ::flame_ide::IntegralConstant< - bool, ::flame_ide::ComparingTypes::VALUE - || ::flame_ide::ComparingTypes::VALUE ->; -template -using IsOsEndpoint = ::flame_ide::IntegralConstant< - bool - , ::flame_ide::ComparingTypes::VALUE - || ::flame_ide::ComparingTypes::VALUE ->; - -// Mappers - -// Gets os::network::{ UdpServer, UdpClient } <-> { Server, Client } -template -using EndpointTypeMapper = ::flame_ide::TypeMapper< - EndpointType - , typename ::flame_ide::ChooseType< - IsServer::VALUE, ServerMatchingTrait, ClientMatchingTrait - >::Type ->; +}}}} // namespace flame_ide::handler::network::udp + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ template< - typename HandlerEndpoint - , typename = typename ::flame_ide::EnableType< - IsHandlerEndpoint::VALUE, HandlerEndpoint - >::Type + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE > -using HandlerEndpointDataMapper = ::flame_ide::TypeMapper< - HandlerEndpoint - , typename ::flame_ide::ChooseType< - IsServer::VALUE - , ServerDataMatchingTrait - , ClientDataMatchingTrait - >::Type ->; +bool Endpoint::empty() const noexcept +{ + return !(osEndpoint); +} + +template< + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE +> +void Endpoint::attach( + EndpointData &&data +) noexcept +{ + if (!empty()) + return; + + osEndpoint.set(flame_ide::move(data)); +} + +template< + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE +> +EndpointData +Endpoint::detach() noexcept +{ + if (empty()) + return {}; + + Data data = flame_ide::move(osEndpoint.pull()); + return data; +} + +template< + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE +> +typename Endpoint::Optional & +Endpoint::endpoint() noexcept +{ + return osEndpoint; +} + +template< + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE +> +const typename Endpoint::Optional & +Endpoint::endpoint() const noexcept +{ + return osEndpoint; +} + +template< + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE +> +typename Endpoint::ActualInput & +Endpoint::input() noexcept +{ + return actualInput; +} + +template< + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE + > +const typename Endpoint< + EndpointData, MessageType, INPUT_SIZE, OUTPUT_SIZE +>::ActualInput & +Endpoint::input() const noexcept +{ + return actualInput; +} + +template< + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE + > +typename Endpoint< +EndpointData, MessageType, INPUT_SIZE, OUTPUT_SIZE +>::ActualOutput & +Endpoint::output() noexcept +{ + return actualOutput; +} + +template< + typename EndpointData + , typename MessageType + , ::flame_ide::Types::size_t INPUT_SIZE + , ::flame_ide::Types::size_t OUTPUT_SIZE +> +const typename Endpoint< + EndpointData, MessageType, INPUT_SIZE, OUTPUT_SIZE +>::ActualOutput & +Endpoint::output() const noexcept +{ + return actualOutput; +} }}}} // namespace flame_ide::handler::network::udp diff --git a/src/Handler/Network/Udp/Headers.cmake b/src/Handler/Network/Udp/Headers.cmake index 12db723d..5a03278f 100644 --- a/src/Handler/Network/Udp/Headers.cmake +++ b/src/Handler/Network/Udp/Headers.cmake @@ -1,8 +1,12 @@ set (HEADER_LIST + ${CMAKE_CURRENT_SOURCE_DIR}/ActualData.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Client.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Config.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/ContainerTypes.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Endpoint.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Message.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Server.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Storage.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/TypeMapping.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Types.hpp ) diff --git a/src/Handler/Network/Udp/Message.hpp b/src/Handler/Network/Udp/Message.hpp new file mode 100644 index 00000000..5b5f9f78 --- /dev/null +++ b/src/Handler/Network/Udp/Message.hpp @@ -0,0 +1,29 @@ +#ifndef HANDLER_INTERNAL_UDP_MESSAGE_HPP +#define HANDLER_INTERNAL_UDP_MESSAGE_HPP + +#include +#include + +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +struct Message +{ + ::flame_ide::templates::StaticArray< + ::flame_ide::byte_t, Constants::MESSAGE_SIZE + > bytes; + ::flame_ide::Types::ssize_t size = 0; + MessageState state = MessageState::EMPTY; + + mutable os::threads::Spin spin; +}; + +}}}} // namespace flame_ide::handler::network::udp + +#endif // HANDLER_INTERNAL_UDP_MESSAGE_HPP diff --git a/src/Handler/Network/Udp/Server.hpp b/src/Handler/Network/Udp/Server.hpp index a8342231..4d249f2b 100644 --- a/src/Handler/Network/Udp/Server.hpp +++ b/src/Handler/Network/Udp/Server.hpp @@ -1,7 +1,8 @@ #ifndef HANDLERINTERNALUDPSERVER_HPP #define HANDLERINTERNALUDPSERVER_HPP -#include +#include +#include #include @@ -15,10 +16,12 @@ struct ServerMessage: public Message { ::flame_ide::os::network::UdpServer::WithClient client; }; -using Server = Endpoint< + +class Server: public Endpoint< ::flame_ide::os::network::UdpServer, ServerMessage , Constants::SERVER_INPUT_QUEUE_SIZE, Constants::SERVER_OUTPUT_QUEUE_SIZE ->; +> +{}; struct ServerCommunicationData { diff --git a/src/Handler/Network/Udp/Storage.hpp b/src/Handler/Network/Udp/Storage.hpp index 93c8ebf7..f3bf8e30 100644 --- a/src/Handler/Network/Udp/Storage.hpp +++ b/src/Handler/Network/Udp/Storage.hpp @@ -2,10 +2,12 @@ #define HANDLERINTERNALUDPSTORAGE_HPP #include +#include #include #include -#include +#include +#include namespace flame_ide {namespace handler diff --git a/src/Handler/Network/Udp/TypeMapping.hpp b/src/Handler/Network/Udp/TypeMapping.hpp new file mode 100644 index 00000000..9bd6b4ee --- /dev/null +++ b/src/Handler/Network/Udp/TypeMapping.hpp @@ -0,0 +1,120 @@ +#ifndef HANDLER_INTERNAL_UDP_TYPE_MAPPING_HPP +#define HANDLER_INTERNAL_UDP_TYPE_MAPPING_HPP + +#include + +// Forwards + +namespace flame_ide +{namespace os +{namespace network +{ + +class UdpServer; +class UdpClient; + +}}} // namespace flame_ide::os::network + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +class Server; +class Servers; + +class Client; +class Clients; + +template +class HandlerEndpointUdpData; + +}}}} // / namespace flame_ide::handler::network::udp + +// Mapping + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +using ServerMatchingTrait = ::flame_ide::TypeMappingTrait< + os::network::UdpServer, Server +>; +using ClientMatchingTrait = ::flame_ide::TypeMappingTrait< + os::network::UdpClient, Client +>; + +using ServerDataMatchingTrait = ::flame_ide::TypeMappingTrait< + Server, HandlerEndpointUdpData +>; +using ClientDataMatchingTrait = ::flame_ide::TypeMappingTrait< + Client, HandlerEndpointUdpData +>; + +// Integral constants + +template +using IsServer = ::flame_ide::IntegralConstant< + bool + , ::flame_ide::ComparingTypes< + EndpointType, ::flame_ide::os::network::UdpServer + >::VALUE || ::flame_ide::ComparingTypes::VALUE +>; + +template +using IsClient = ::flame_ide::IntegralConstant< + bool + , ::flame_ide::ComparingTypes< + EndpointType, ::flame_ide::os::network::UdpClient + >::VALUE || ::flame_ide::ComparingTypes::VALUE +>; + +template +using IsCommonEndpoint = ::flame_ide::IntegralConstant< + bool, IsServer::VALUE || IsClient::VALUE +>; + +template +using IsHandlerEndpoint = ::flame_ide::IntegralConstant< + bool, ::flame_ide::ComparingTypes::VALUE + || ::flame_ide::ComparingTypes::VALUE +>; +template +using IsOsEndpoint = ::flame_ide::IntegralConstant< + bool + , ::flame_ide::ComparingTypes::VALUE + || ::flame_ide::ComparingTypes::VALUE +>; + +// Mappers + +// Gets os::network::{ UdpServer, UdpClient } <-> { Server, Client } +template +using EndpointTypeMapper = ::flame_ide::TypeMapper< + EndpointType + , typename ::flame_ide::ChooseType< + IsServer::VALUE, ServerMatchingTrait, ClientMatchingTrait + >::Type +>; + +template< + typename HandlerEndpoint + , typename = typename ::flame_ide::EnableType< + IsHandlerEndpoint::VALUE, HandlerEndpoint + >::Type +> +using HandlerEndpointDataMapper = ::flame_ide::TypeMapper< + HandlerEndpoint + , typename ::flame_ide::ChooseType< + IsServer::VALUE + , ServerDataMatchingTrait + , ClientDataMatchingTrait + >::Type +>; + +}}}} // namespace flame_ide::handler::network::udp + +#endif // HANDLER_INTERNAL_UDP_TYPE_MAPPING_HPP diff --git a/src/Handler/Network/Udp/Types.hpp b/src/Handler/Network/Udp/Types.hpp index 6af6c975..dcdeaf81 100644 --- a/src/Handler/Network/Udp/Types.hpp +++ b/src/Handler/Network/Udp/Types.hpp @@ -1,17 +1,9 @@ #ifndef HANDLERINTERNALUDPTYPES_HPP #define HANDLERINTERNALUDPTYPES_HPP -#include - -#include -#include -#include -#include - #include -#include -#include +#include namespace flame_ide {namespace handler @@ -26,78 +18,11 @@ enum class MessageState , READY }; -struct Message -{ - ::flame_ide::templates::StaticArray< - ::flame_ide::byte_t, Constants::MESSAGE_SIZE - > bytes; - ::flame_ide::Types::ssize_t size = 0; - MessageState state = MessageState::EMPTY; - - mutable os::threads::Spin spin; -}; - -template -struct ActualData -{ -public: - using Messages = flame_ide::templates::StaticArray< - flame_ide::templates::UniquePointer, SIZE - >; - using MessagesCircularIterator = - flame_ide::templates::defaults::CircularForwardIterator< - typename Messages::Iterator - >; - - MessageType *getEmptyMessage() noexcept; - MessageType *getFilledMessage() noexcept; - - ::flame_ide::Types::ssize_t getFilledMessageSize() const noexcept; - -private: - ::flame_ide::Types::size_t amount = 0; - - Messages messages; - MessagesCircularIterator first = MessagesCircularIterator{ - messages.begin() - , templates::makeRange(messages.begin(), messages.end()) - }; - MessagesCircularIterator last = first; - - mutable os::threads::Spin spin; -}; - -template< - typename EndpointData - , typename MessageType - , ::flame_ide::Types::size_t INPUT_SIZE - , ::flame_ide::Types::size_t OUTPUT_SIZE -> -class Endpoint +template +struct HandlerEndpointUdpData { -public: - using Data = EndpointData; - using Optional = flame_ide::templates::Optional; - using ActualInput = ActualData; - using ActualOutput = ActualData; - - bool empty() const noexcept; - void attach(EndpointData &&data) noexcept; - EndpointData detach() noexcept; - - Optional &endpoint() noexcept; - const Optional &endpoint() const noexcept; - - ActualInput &input() noexcept; - const ActualInput &input() const noexcept; - - ActualOutput &output() noexcept; - const ActualOutput &output() const noexcept; - -protected: - Optional osEndpoint; - ActualInput actualInput; - ActualOutput actualOutput; + templates::UniquePointer container = decltype(container)::makeEmpty(); + os::threads::Spin spin; }; }}}} // namespace flame_ide::handler::network::udp @@ -107,178 +32,6 @@ namespace flame_ide {namespace network {namespace udp { - -// ActualData - -template -MessageType *ActualData::getEmptyMessage() noexcept -{ - os::threads::Locker lock{ spin }; - - if (amount == SIZE) - return nullptr; - - auto result = last; - ++amount; - ++last; - return result->pointer(); -} - -template -MessageType *ActualData::getFilledMessage() noexcept -{ - os::threads::Locker lock{ spin }; - - if ((first == last) && (amount == 0)) - return nullptr; - - auto result = first; - --amount; - ++first; - return result->pointer(); -} - -template -::flame_ide::Types::ssize_t -ActualData::getFilledMessageSize() const noexcept -{ - os::threads::Locker lock{ spin }; - - if ((first == last) && (amount == 0)) - return 0; - - { - const auto &message = *first; - os::threads::Locker messageLocker{ message->spin }; - if (message->state == MessageState::EMPTY) - return 0; - return message->size; - } -} - -// Endpoint - -template< - typename EndpointData - , typename MessageType - , ::flame_ide::Types::size_t INPUT_SIZE - , ::flame_ide::Types::size_t OUTPUT_SIZE -> -bool Endpoint::empty() const noexcept -{ - return !(osEndpoint); -} - -template< - typename EndpointData - , typename MessageType - , ::flame_ide::Types::size_t INPUT_SIZE - , ::flame_ide::Types::size_t OUTPUT_SIZE -> -void Endpoint::attach( - EndpointData &&data -) noexcept -{ - if (!empty()) - return; - - osEndpoint.set(flame_ide::move(data)); -} - -template< - typename EndpointData - , typename MessageType - , ::flame_ide::Types::size_t INPUT_SIZE - , ::flame_ide::Types::size_t OUTPUT_SIZE -> -EndpointData -Endpoint::detach() noexcept -{ - if (empty()) - return {}; - - Data data = flame_ide::move(osEndpoint.pull()); - return data; -} - -template< - typename EndpointData - , typename MessageType - , ::flame_ide::Types::size_t INPUT_SIZE - , ::flame_ide::Types::size_t OUTPUT_SIZE -> -typename Endpoint::Optional & -Endpoint::endpoint() noexcept -{ - return osEndpoint; -} - -template< - typename EndpointData - , typename MessageType - , ::flame_ide::Types::size_t INPUT_SIZE - , ::flame_ide::Types::size_t OUTPUT_SIZE -> -const typename Endpoint::Optional & -Endpoint::endpoint() const noexcept -{ - return osEndpoint; -} - -template< - typename EndpointData - , typename MessageType - , ::flame_ide::Types::size_t INPUT_SIZE - , ::flame_ide::Types::size_t OUTPUT_SIZE -> -typename Endpoint::ActualInput & -Endpoint::input() noexcept -{ - return actualInput; -} - -template< - typename EndpointData - , typename MessageType - , ::flame_ide::Types::size_t INPUT_SIZE - , ::flame_ide::Types::size_t OUTPUT_SIZE - > -const typename Endpoint< - EndpointData, MessageType, INPUT_SIZE, OUTPUT_SIZE ->::ActualInput & -Endpoint::input() const noexcept -{ - return actualInput; -} - -template< - typename EndpointData - , typename MessageType - , ::flame_ide::Types::size_t INPUT_SIZE - , ::flame_ide::Types::size_t OUTPUT_SIZE - > -typename Endpoint< -EndpointData, MessageType, INPUT_SIZE, OUTPUT_SIZE ->::ActualOutput & -Endpoint::output() noexcept -{ - return actualOutput; -} - -template< - typename EndpointData - , typename MessageType - , ::flame_ide::Types::size_t INPUT_SIZE - , ::flame_ide::Types::size_t OUTPUT_SIZE -> -const typename Endpoint< - EndpointData, MessageType, INPUT_SIZE, OUTPUT_SIZE ->::ActualOutput & -Endpoint::output() const noexcept -{ - return actualOutput; -} - }}}} // namespace flame_ide::handler::network::udp #endif // HANDLERINTERNALUDPTYPES_HPP From dbe7bff0d1ca19b7834e993052b522346547e684 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Mon, 17 Aug 2026 22:01:15 +0300 Subject: [PATCH 32/37] Replace raw pointer to ReferenceWrapper && add fill() and range() functions to Message --- src/Handler/Network/Udp.cpp | 8 ++++---- src/Handler/Network/Udp.hpp | 4 ++-- src/Handler/Network/Udp/ActualData.hpp | 11 +++++++---- src/Handler/Network/Udp/Client.cpp | 16 ++++++++++++++-- src/Handler/Network/Udp/Client.hpp | 6 ++++-- src/Handler/Network/Udp/Message.cpp | 16 ++++++++++++++++ src/Handler/Network/Udp/Message.hpp | 3 +++ src/Handler/Network/Udp/Server.cpp | 15 ++++++++++++++- src/Handler/Network/Udp/Server.hpp | 6 ++++-- src/Handler/Network/Udp/Sources.cmake | 1 + src/Handler/Network/Udp/Storage.hpp | 10 ++++------ src/Handler/Network/Udp/TypeMapping.hpp | 2 +- src/Handler/Tests/Network/Udp/StorageTest.cpp | 2 +- 13 files changed, 75 insertions(+), 25 deletions(-) create mode 100644 src/Handler/Network/Udp/Message.cpp diff --git a/src/Handler/Network/Udp.cpp b/src/Handler/Network/Udp.cpp index 4d9facc4..99cb0c7b 100644 --- a/src/Handler/Network/Udp.cpp +++ b/src/Handler/Network/Udp.cpp @@ -10,7 +10,7 @@ namespace flame_ide Handler::ExpectedServerHandle Handler::Udp::push(os::network::UdpServer &&server) noexcept { - udp::Server *udpServer = storage.push(move(server)); + ::flame_ide::ReferenceWrapper udpServer = storage.push(move(server)); if (!udpServer) return { os::STATUS_FAILED }; @@ -26,7 +26,7 @@ Handler::Udp::push(os::network::UdpServer &&server) noexcept Handler::ExpectedSessionHandle Handler::Udp::push(os::network::UdpClient &&client) noexcept { - udp::Client *udpClient = storage.push(move(client)); + ::flame_ide::ReferenceWrapper udpClient = storage.push(move(client)); if (!udpClient) return { os::STATUS_FAILED }; @@ -86,10 +86,10 @@ Handler::Udp::CallbackGetSessionHandle Handler::Udp::serverHandleCallback() cons if (!object) return { os::STATUS_FAILED }; - auto *server = object.get().server; + auto server = object.get().server; // В очередь приходят сообщения - auto *message = server->input().getFilledMessage(); + auto message = server->input().getFilledMessage(); if (!message) return { os::STATUS_FAILED }; diff --git a/src/Handler/Network/Udp.hpp b/src/Handler/Network/Udp.hpp index 5d48b6b6..763bdba3 100644 --- a/src/Handler/Network/Udp.hpp +++ b/src/Handler/Network/Udp.hpp @@ -26,8 +26,8 @@ class Handler::Udp public: struct ServerHandleData { - Handler *handler; - udp::Server *server; + ::flame_ide::ReferenceWrapper handler; + ::flame_ide::ReferenceWrapper server; }; struct SessionHandleData diff --git a/src/Handler/Network/Udp/ActualData.hpp b/src/Handler/Network/Udp/ActualData.hpp index 910bceb3..af4ec6b8 100644 --- a/src/Handler/Network/Udp/ActualData.hpp +++ b/src/Handler/Network/Udp/ActualData.hpp @@ -1,6 +1,7 @@ #ifndef HANDLER_INTERNAL_UDP_ACTUAL_DATA_HPP #define HANDLER_INTERNAL_UDP_ACTUAL_DATA_HPP +#include #include #include @@ -27,8 +28,8 @@ struct ActualData typename Messages::Iterator >; - MessageType *getEmptyMessage() noexcept; - MessageType *getFilledMessage() noexcept; + ::flame_ide::ReferenceWrapper getEmptyMessage() noexcept; + ::flame_ide::ReferenceWrapper getFilledMessage() noexcept; ::flame_ide::Types::ssize_t getFilledMessageSize() const noexcept; @@ -54,7 +55,8 @@ namespace flame_ide { template -MessageType *ActualData::getEmptyMessage() noexcept +::flame_ide::ReferenceWrapper +ActualData::getEmptyMessage() noexcept { os::threads::Locker lock{ spin }; @@ -68,7 +70,8 @@ MessageType *ActualData::getEmptyMessage() noexcept } template -MessageType *ActualData::getFilledMessage() noexcept +::flame_ide::ReferenceWrapper +ActualData::getFilledMessage() noexcept { os::threads::Locker lock{ spin }; diff --git a/src/Handler/Network/Udp/Client.cpp b/src/Handler/Network/Udp/Client.cpp index 5b595272..5da1c32d 100644 --- a/src/Handler/Network/Udp/Client.cpp +++ b/src/Handler/Network/Udp/Client.cpp @@ -9,6 +9,18 @@ namespace flame_ide {namespace udp { +void ClientMessage::fill(flame_ide::os::network::UdpClient &endpoint) +{ + os::threads::Locker locker{ spin }; + + auto waitResult = endpoint.wait(); + if (waitResult < 0) + return; + + this->size = endpoint.receive(this->range()); + this->state = MessageState::READY; +} + Types::ssize_t ClientCommunicationData::bytesToRead() const noexcept { if (!client) @@ -23,7 +35,7 @@ ClientCommunicationData::receive(templates::Range range) noexcept if (!client) return os::STATUS_FAILED; - ClientMessage *message = client->input().getFilledMessage(); + ReferenceWrapper message = client->input().getFilledMessage(); if (!message) return os::STATUS_FAILED; @@ -61,7 +73,7 @@ ClientCommunicationData::send(templates::Range range) noexcept if (!client) return os::STATUS_FAILED; - ClientMessage *message = client->output().getEmptyMessage(); + ReferenceWrapper message = client->output().getEmptyMessage(); if (!message) return os::STATUS_FAILED; diff --git a/src/Handler/Network/Udp/Client.hpp b/src/Handler/Network/Udp/Client.hpp index 698ef1ec..5cd54205 100644 --- a/src/Handler/Network/Udp/Client.hpp +++ b/src/Handler/Network/Udp/Client.hpp @@ -14,7 +14,9 @@ namespace flame_ide { struct ClientMessage: public Message -{}; +{ + void fill(flame_ide::os::network::UdpClient &endpoint) noexcept; +}; class Client: public Endpoint< ::flame_ide::os::network::UdpClient, ClientMessage @@ -24,7 +26,7 @@ class Client: public Endpoint< struct ClientCommunicationData { - Client *client; + ::flame_ide::ReferenceWrapper client; Types::ssize_t bytesToRead() const noexcept; Types::ssize_t receive(templates::Range range) noexcept; diff --git a/src/Handler/Network/Udp/Message.cpp b/src/Handler/Network/Udp/Message.cpp new file mode 100644 index 00000000..e3e2b3b4 --- /dev/null +++ b/src/Handler/Network/Udp/Message.cpp @@ -0,0 +1,16 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +::flame_ide::templates::Range<::flame_ide::byte_t *> Message::range() noexcept +{ + return ::flame_ide::templates::makeRange( + bytes.begin().operator->(), bytes.end().operator->() + ); +} + +}}}} // namespace flame_ide::handler::network::udp diff --git a/src/Handler/Network/Udp/Message.hpp b/src/Handler/Network/Udp/Message.hpp index 5b5f9f78..ffe6dbc5 100644 --- a/src/Handler/Network/Udp/Message.hpp +++ b/src/Handler/Network/Udp/Message.hpp @@ -22,6 +22,9 @@ struct Message MessageState state = MessageState::EMPTY; mutable os::threads::Spin spin; + +protected: + ::flame_ide::templates::Range<::flame_ide::byte_t *> range() noexcept; }; }}}} // namespace flame_ide::handler::network::udp diff --git a/src/Handler/Network/Udp/Server.cpp b/src/Handler/Network/Udp/Server.cpp index 68f770ef..ac623a2c 100644 --- a/src/Handler/Network/Udp/Server.cpp +++ b/src/Handler/Network/Udp/Server.cpp @@ -6,6 +6,19 @@ namespace flame_ide {namespace udp { +void ServerMessage::fill(flame_ide::os::network::UdpServer &endpoint) noexcept +{ + os::threads::Locker lock{ this->spin }; + + auto waitResult = endpoint.wait(); + if (waitResult.getStatus() < 0) + return; + + this->client = waitResult; + this->size = this->client.receive(this->range()); + this->state = MessageState::READY; +} + Types::ssize_t ServerCommunicationData::bytesToRead() const noexcept { if (!message) @@ -45,7 +58,7 @@ ServerCommunicationData::send(templates::Range range) noexcept if (!output) return os::STATUS_FAILED; - auto *message = output->getEmptyMessage(); + auto message = output->getEmptyMessage(); if (!message) return os::STATUS_FAILED; { diff --git a/src/Handler/Network/Udp/Server.hpp b/src/Handler/Network/Udp/Server.hpp index 4d249f2b..de717003 100644 --- a/src/Handler/Network/Udp/Server.hpp +++ b/src/Handler/Network/Udp/Server.hpp @@ -14,6 +14,8 @@ namespace flame_ide struct ServerMessage: public Message { + void fill(flame_ide::os::network::UdpServer &endpoint) noexcept; + ::flame_ide::os::network::UdpServer::WithClient client; }; @@ -25,8 +27,8 @@ class Server: public Endpoint< struct ServerCommunicationData { - ServerMessage *message; - Server::ActualOutput *output; + ::flame_ide::ReferenceWrapper message; + ::flame_ide::ReferenceWrapper output; Types::ssize_t bytesToRead() const noexcept; Types::ssize_t receive(templates::Range range) noexcept; diff --git a/src/Handler/Network/Udp/Sources.cmake b/src/Handler/Network/Udp/Sources.cmake index c34df241..2d994597 100644 --- a/src/Handler/Network/Udp/Sources.cmake +++ b/src/Handler/Network/Udp/Sources.cmake @@ -1,4 +1,5 @@ set (SOURCE_LIST ${CMAKE_CURRENT_SOURCE_DIR}/Client.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Message.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Server.cpp ) diff --git a/src/Handler/Network/Udp/Storage.hpp b/src/Handler/Network/Udp/Storage.hpp index f3bf8e30..8a64e1ac 100644 --- a/src/Handler/Network/Udp/Storage.hpp +++ b/src/Handler/Network/Udp/Storage.hpp @@ -19,7 +19,7 @@ class Storage { public: template - auto *push(OsEndpoint &&osEndpoint) noexcept + auto push(OsEndpoint &&osEndpoint) noexcept { static_assert( IsOsEndpoint::VALUE @@ -28,8 +28,6 @@ class Storage ); using HandlerEndpoint = typename EndpointTypeMapper::Type; - using HandlerEndpointPointer = - typename flame_ide::DefaultTraits::Pointer; using HandlerEndpointData = typename HandlerEndpointDataMapper< HandlerEndpoint >::Type; @@ -41,11 +39,11 @@ class Storage if (!data.container) data.container = decltype(data.container){}; if (!data.container) - return HandlerEndpointPointer{ nullptr }; + return ::flame_ide::ReferenceWrapper{ nullptr }; } // Push - HandlerEndpointPointer handlerEndpointPointer = nullptr; + ::flame_ide::ReferenceWrapper handlerEndpointPointer = nullptr; { os::threads::Locker lock{ data.spin }; for (auto &i : data.container.reference()) @@ -63,7 +61,7 @@ class Storage } template - auto pop(HandlerEndpoint *handlerEndpoint) noexcept + auto pop(ReferenceWrapper handlerEndpoint) noexcept { static_assert( IsHandlerEndpoint::VALUE diff --git a/src/Handler/Network/Udp/TypeMapping.hpp b/src/Handler/Network/Udp/TypeMapping.hpp index 9bd6b4ee..7c1bce71 100644 --- a/src/Handler/Network/Udp/TypeMapping.hpp +++ b/src/Handler/Network/Udp/TypeMapping.hpp @@ -28,7 +28,7 @@ class Client; class Clients; template -class HandlerEndpointUdpData; +struct HandlerEndpointUdpData; }}}} // / namespace flame_ide::handler::network::udp diff --git a/src/Handler/Tests/Network/Udp/StorageTest.cpp b/src/Handler/Tests/Network/Udp/StorageTest.cpp index fee12e94..bd125749 100644 --- a/src/Handler/Tests/Network/Udp/StorageTest.cpp +++ b/src/Handler/Tests/Network/Udp/StorageTest.cpp @@ -40,7 +40,7 @@ int StorageTest::serverPushPop() const os::Socket expectedSocket = server.native(); auto handle = storage.push(flame_ide::move(server)); - IN_CASE_CHECK(handle != nullptr); + IN_CASE_CHECK(handle.operator->() != nullptr); auto resultServer = storage.pop(handle); IN_CASE_CHECK(expectedSocket.descriptor == resultServer.native().descriptor); From 5f3ae00bea6f4551a81158574dd7aa4dfb209e2d Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Mon, 17 Aug 2026 23:32:19 +0300 Subject: [PATCH 33/37] Rename onece-include macro checks --- src/Handler/Network/Functions.hpp | 6 +++--- src/Handler/Network/Tcp.hpp | 6 +++--- src/Handler/Network/Tcp/Client.hpp | 4 ++-- src/Handler/Network/Tcp/Config.hpp | 6 +++--- src/Handler/Network/Tcp/InternalData.hpp | 6 +++--- src/Handler/Network/Tcp/Server.hpp | 6 +++--- src/Handler/Network/Tcp/Tcp.hpp | 6 +++--- src/Handler/Network/Tcp/Types.hpp | 6 +++--- src/Handler/Network/Udp.hpp | 6 +++--- src/Handler/Network/Udp/Client.hpp | 6 +++--- src/Handler/Network/Udp/Config.hpp | 6 +++--- src/Handler/Network/Udp/Endpoint.hpp | 6 +++--- src/Handler/Network/Udp/Server.hpp | 6 +++--- src/Handler/Network/Udp/Storage.hpp | 6 +++--- src/Handler/Network/Udp/Types.hpp | 6 +++--- 15 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/Handler/Network/Functions.hpp b/src/Handler/Network/Functions.hpp index e6320fb1..e30b7f25 100644 --- a/src/Handler/Network/Functions.hpp +++ b/src/Handler/Network/Functions.hpp @@ -1,5 +1,5 @@ -#ifndef HANDLERINTERNALFUNCTIONS_HPP -#define HANDLERINTERNALFUNCTIONS_HPP +#ifndef HANDLER_INTERNAL_FUNCTIONS_HPP +#define HANDLER_INTERNAL_FUNCTIONS_HPP #include #include @@ -62,4 +62,4 @@ inline auto popData(Pointer &pointer, os::threads::Spin &spin, Data &data }}} // namespace flame_ide::handler::network -#endif // HANDLERINTERNALFUNCTIONS_HPP +#endif // HANDLER_INTERNAL_FUNCTIONS_HPP diff --git a/src/Handler/Network/Tcp.hpp b/src/Handler/Network/Tcp.hpp index b534dbc4..7e474d17 100644 --- a/src/Handler/Network/Tcp.hpp +++ b/src/Handler/Network/Tcp.hpp @@ -1,5 +1,5 @@ -#ifndef HANDLERINTERNALTCP_HPP -#define HANDLERINTERNALTCP_HPP +#ifndef HANDLER_INTERNAL_TCP_HPP +#define HANDLER_INTERNAL_TCP_HPP #include @@ -37,4 +37,4 @@ class Handler::Tcp }}} // namespace flame_ide::handler::network -#endif // HANDLERINTERNALTCP_HPP +#endif // HANDLER_INTERNAL_TCP_HPP diff --git a/src/Handler/Network/Tcp/Client.hpp b/src/Handler/Network/Tcp/Client.hpp index 007b7e66..239023cb 100644 --- a/src/Handler/Network/Tcp/Client.hpp +++ b/src/Handler/Network/Tcp/Client.hpp @@ -1,5 +1,5 @@ -#ifndef HANDLERINTERNALTCPCLIENT_HPP -#define HANDLERINTERNALTCPCLIENT_HPP +#ifndef HANDLER_INTERNAL_TCPCLIENT_HPP +#define HANDLER_INTERNAL_TCPCLIENT_HPP #include diff --git a/src/Handler/Network/Tcp/Config.hpp b/src/Handler/Network/Tcp/Config.hpp index c95657df..495e20ee 100644 --- a/src/Handler/Network/Tcp/Config.hpp +++ b/src/Handler/Network/Tcp/Config.hpp @@ -1,5 +1,5 @@ -#ifndef HANDLERINTERNALTCPCONFIG_HPP -#define HANDLERINTERNALTCPCONFIG_HPP +#ifndef HANDLER_INTERNAL_TCPCONFIG_HPP +#define HANDLER_INTERNAL_TCPCONFIG_HPP #include #include @@ -39,4 +39,4 @@ struct Constants: ::flame_ide::NonCreational }}}} // namespace flame_ide::handler::network::tcp -#endif // HANDLERINTERNALTCPCONFIG_HPP +#endif // HANDLER_INTERNAL_TCPCONFIG_HPP diff --git a/src/Handler/Network/Tcp/InternalData.hpp b/src/Handler/Network/Tcp/InternalData.hpp index db335595..dfdc8027 100644 --- a/src/Handler/Network/Tcp/InternalData.hpp +++ b/src/Handler/Network/Tcp/InternalData.hpp @@ -1,5 +1,5 @@ -#ifndef HANDLERINTERNALTCPDATA_HPP -#define HANDLERINTERNALTCPDATA_HPP +#ifndef HANDLER_INTERNAL_TCPDATA_HPP +#define HANDLER_INTERNAL_TCPDATA_HPP #include #include @@ -35,4 +35,4 @@ Types::ssize_t serverSend(void *data, templates::Range) noexcept }}}}} // namespace flame_ide::os::network::udp::callbacks -#endif // HANDLERINTERNALTCPDATA_HPP +#endif // HANDLER_INTERNAL_TCPDATA_HPP diff --git a/src/Handler/Network/Tcp/Server.hpp b/src/Handler/Network/Tcp/Server.hpp index 259b315b..b3cc907f 100644 --- a/src/Handler/Network/Tcp/Server.hpp +++ b/src/Handler/Network/Tcp/Server.hpp @@ -1,5 +1,5 @@ -#ifndef HANDLERINTERNALTCPSERVER_HPP -#define HANDLERINTERNALTCPSERVER_HPP +#ifndef HANDLER_INTERNAL_TCPSERVER_HPP +#define HANDLER_INTERNAL_TCPSERVER_HPP #include @@ -64,4 +64,4 @@ class Server }}}} // namespace flame_ide::handler::network::tcp -#endif // HANDLERINTERNALTCPSERVER_HPP +#endif // HANDLER_INTERNAL_TCPSERVER_HPP diff --git a/src/Handler/Network/Tcp/Tcp.hpp b/src/Handler/Network/Tcp/Tcp.hpp index 87e328ba..fbb767b5 100644 --- a/src/Handler/Network/Tcp/Tcp.hpp +++ b/src/Handler/Network/Tcp/Tcp.hpp @@ -1,5 +1,5 @@ -#ifndef HANDLERINTERNALTCPTCP_HPP -#define HANDLERINTERNALTCPTCP_HPP +#ifndef HANDLER_INTERNAL_TCPTCP_HPP +#define HANDLER_INTERNAL_TCPTCP_HPP #include #include @@ -70,4 +70,4 @@ struct Tcp }}}} // namespace flame_ide::handler::network::tcp -#endif // HANDLERINTERNALTCPTCP_HPP +#endif // HANDLER_INTERNAL_TCPTCP_HPP diff --git a/src/Handler/Network/Tcp/Types.hpp b/src/Handler/Network/Tcp/Types.hpp index 8ffa93e7..f566f600 100644 --- a/src/Handler/Network/Tcp/Types.hpp +++ b/src/Handler/Network/Tcp/Types.hpp @@ -1,5 +1,5 @@ -#ifndef HANDLERINTERNALTCPTYPES_HPP -#define HANDLERINTERNALTCPTYPES_HPP +#ifndef HANDLER_INTERNAL_TCPTYPES_HPP +#define HANDLER_INTERNAL_TCPTYPES_HPP #include #include @@ -45,4 +45,4 @@ struct AcceptedConnection }}}} // namespace flame_ide::handler::network::tcp -#endif // HANDLERINTERNALTCPTYPES_HPP +#endif // HANDLER_INTERNAL_TCPTYPES_HPP diff --git a/src/Handler/Network/Udp.hpp b/src/Handler/Network/Udp.hpp index 763bdba3..b52726ce 100644 --- a/src/Handler/Network/Udp.hpp +++ b/src/Handler/Network/Udp.hpp @@ -1,5 +1,5 @@ -#ifndef HANDLERINTERNALUDP_HPP -#define HANDLERINTERNALUDP_HPP +#ifndef HANDLER_INTERNAL_UDP_HPP +#define HANDLER_INTERNAL_UDP_HPP #include @@ -133,4 +133,4 @@ class Handler::Udp }}} // namespace flame_ide::handler::network -#endif // HANDLERINTERNALUDP_HPP +#endif // HANDLER_INTERNAL_UDP_HPP diff --git a/src/Handler/Network/Udp/Client.hpp b/src/Handler/Network/Udp/Client.hpp index 5cd54205..d5118568 100644 --- a/src/Handler/Network/Udp/Client.hpp +++ b/src/Handler/Network/Udp/Client.hpp @@ -1,5 +1,5 @@ -#ifndef HANDLERINTERNALUDPCLIENT_HPP -#define HANDLERINTERNALUDPCLIENT_HPP +#ifndef HANDLER_INTERNAL_UDPCLIENT_HPP +#define HANDLER_INTERNAL_UDPCLIENT_HPP #include #include @@ -35,4 +35,4 @@ struct ClientCommunicationData }}}} // namespace flame_ide::handler::network::udp -#endif // HANDLERINTERNALUDPCLIENT_HPP +#endif // HANDLER_INTERNAL_UDPCLIENT_HPP diff --git a/src/Handler/Network/Udp/Config.hpp b/src/Handler/Network/Udp/Config.hpp index faa7e414..4ec0f1ce 100644 --- a/src/Handler/Network/Udp/Config.hpp +++ b/src/Handler/Network/Udp/Config.hpp @@ -1,5 +1,5 @@ -#ifndef HANDLERINTERNALUDPCONFIG_HPP -#define HANDLERINTERNALUDPCONFIG_HPP +#ifndef HANDLER_INTERNAL_UDPCONFIG_HPP +#define HANDLER_INTERNAL_UDPCONFIG_HPP #include #include @@ -39,4 +39,4 @@ struct Constants: ::flame_ide::NonCreational }}}} // namespace flame_ide::handler::network::udp -#endif // HANDLERINTERNALUDPCONFIG_HPP +#endif // HANDLER_INTERNAL_UDPCONFIG_HPP diff --git a/src/Handler/Network/Udp/Endpoint.hpp b/src/Handler/Network/Udp/Endpoint.hpp index 5e20fc64..9a550db7 100644 --- a/src/Handler/Network/Udp/Endpoint.hpp +++ b/src/Handler/Network/Udp/Endpoint.hpp @@ -1,5 +1,5 @@ -#ifndef HANDLERINTERNALUDPENDPOINT_HPP -#define HANDLERINTERNALUDPENDPOINT_HPP +#ifndef HANDLER_INTERNAL_UDP_ENDPOINT_HPP +#define HANDLER_INTERNAL_UDP_ENDPOINT_HPP #include #include @@ -177,4 +177,4 @@ Endpoint::output() const noe }}}} // namespace flame_ide::handler::network::udp -#endif // HANDLERINTERNALUDPENDPOINT_HPP +#endif // HANDLER_INTERNAL_UDP_ENDPOINT_HPP diff --git a/src/Handler/Network/Udp/Server.hpp b/src/Handler/Network/Udp/Server.hpp index de717003..23464e4c 100644 --- a/src/Handler/Network/Udp/Server.hpp +++ b/src/Handler/Network/Udp/Server.hpp @@ -1,5 +1,5 @@ -#ifndef HANDLERINTERNALUDPSERVER_HPP -#define HANDLERINTERNALUDPSERVER_HPP +#ifndef HANDLER_INTERNAL_UDPSERVER_HPP +#define HANDLER_INTERNAL_UDPSERVER_HPP #include #include @@ -37,4 +37,4 @@ struct ServerCommunicationData }}}} // namespace flame_ide::handler::network::udp -#endif // HANDLERINTERNALUDPSERVER_HPP +#endif // HANDLER_INTERNAL_UDPSERVER_HPP diff --git a/src/Handler/Network/Udp/Storage.hpp b/src/Handler/Network/Udp/Storage.hpp index 8a64e1ac..586f525b 100644 --- a/src/Handler/Network/Udp/Storage.hpp +++ b/src/Handler/Network/Udp/Storage.hpp @@ -1,5 +1,5 @@ -#ifndef HANDLERINTERNALUDPSTORAGE_HPP -#define HANDLERINTERNALUDPSTORAGE_HPP +#ifndef HANDLER_INTERNAL_UDPSTORAGE_HPP +#define HANDLER_INTERNAL_UDPSTORAGE_HPP #include #include @@ -133,4 +133,4 @@ Storage::getData>() noexcept }}}} // namespace flame_ide::handler::network::udp -#endif // HANDLERINTERNALUDPSTORAGE_HPP +#endif // HANDLER_INTERNAL_UDPSTORAGE_HPP diff --git a/src/Handler/Network/Udp/Types.hpp b/src/Handler/Network/Udp/Types.hpp index dcdeaf81..846530b2 100644 --- a/src/Handler/Network/Udp/Types.hpp +++ b/src/Handler/Network/Udp/Types.hpp @@ -1,5 +1,5 @@ -#ifndef HANDLERINTERNALUDPTYPES_HPP -#define HANDLERINTERNALUDPTYPES_HPP +#ifndef HANDLER_INTERNAL_UDP_TYPES_HPP +#define HANDLER_INTERNAL_UDP_TYPES_HPP #include @@ -34,4 +34,4 @@ namespace flame_ide { }}}} // namespace flame_ide::handler::network::udp -#endif // HANDLERINTERNALUDPTYPES_HPP +#endif // HANDLER_INTERNAL_UDP_TYPES_HPP From dc35ae1884a4a8dfdcbb44409698850d58301f6d Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Tue, 18 Aug 2026 17:19:32 +0300 Subject: [PATCH 34/37] Implementation of Worker<->Registrar and Worker<->Storage for UDP --- include/FlameIDE/Common/Expected.hpp | 14 +- .../Os/Async/Network/NotificatorBase.hpp | 2 +- .../FlameIDE/Os/Async/Network/Registrar.hpp | 10 +- src/Handler/Network/Handler.cpp | 6 +- src/Handler/Network/Headers.cmake | 3 +- src/Handler/Network/Internal.cpp | 31 ++-- src/Handler/Network/Internal.hpp | 19 +-- src/Handler/Network/Notificator.cpp | 26 ++-- src/Handler/Network/Notificator.hpp | 56 ++++--- src/Handler/Network/Sources.cmake | 3 +- src/Handler/Network/Udp.cpp | 14 ++ src/Handler/Network/Udp.hpp | 10 ++ src/Handler/Network/Udp/ActualData.hpp | 17 ++- src/Handler/Network/Udp/Client.cpp | 2 +- src/Handler/Network/Udp/ContainerTypes.hpp | 5 - src/Handler/Network/Udp/Headers.cmake | 3 + src/Handler/Network/Udp/Notificators.cpp | 32 ++++ src/Handler/Network/Udp/Notificators.hpp | 44 ++++++ src/Handler/Network/Udp/Processing.cpp | 85 +++++++++++ src/Handler/Network/Udp/Processing.hpp | 63 ++++++++ src/Handler/Network/Udp/Server.cpp | 5 +- src/Handler/Network/Udp/Server.hpp | 2 +- src/Handler/Network/Udp/Sources.cmake | 3 + src/Handler/Network/Udp/Storage.hpp | 9 ++ src/Handler/Network/Udp/TypeMapping.hpp | 33 +++- src/Handler/Network/Udp/Workers.cpp | 68 +++++++++ src/Handler/Network/Udp/Workers.hpp | 63 ++++++++ src/Handler/Network/Worker.cpp | 144 ------------------ src/Handler/Network/Worker.hpp | 112 -------------- src/Handler/Network/WorkerBase.cpp | 64 ++++++++ src/Handler/Network/WorkerBase.hpp | 82 ++++++++++ src/Handler/Network/Workers.cpp | 33 ++++ src/Handler/Network/Workers.hpp | 43 ++++++ src/Handler/Tests/Network/Udp/StorageTest.cpp | 63 ++++++++ src/Handler/Tests/Network/Udp/StorageTest.hpp | 8 + src/Handler/Tests/Network/WorkerTest.cpp | 2 +- src/Os/Async/Network/EventCatcherBase.cpp | 28 ++-- src/Os/Async/Network/EventCatcherBase.hpp | 20 +-- src/Os/Async/Network/Registrar.cpp | 10 +- src/Os/Tests/Async/Network/RegistrarTest.cpp | 2 +- 40 files changed, 855 insertions(+), 384 deletions(-) create mode 100644 src/Handler/Network/Udp/Notificators.cpp create mode 100644 src/Handler/Network/Udp/Notificators.hpp create mode 100644 src/Handler/Network/Udp/Processing.cpp create mode 100644 src/Handler/Network/Udp/Processing.hpp create mode 100644 src/Handler/Network/Udp/Workers.cpp create mode 100644 src/Handler/Network/Udp/Workers.hpp delete mode 100644 src/Handler/Network/Worker.cpp delete mode 100644 src/Handler/Network/Worker.hpp create mode 100644 src/Handler/Network/WorkerBase.cpp create mode 100644 src/Handler/Network/WorkerBase.hpp create mode 100644 src/Handler/Network/Workers.cpp create mode 100644 src/Handler/Network/Workers.hpp diff --git a/include/FlameIDE/Common/Expected.hpp b/include/FlameIDE/Common/Expected.hpp index e83446c1..d43bc0e4 100644 --- a/include/FlameIDE/Common/Expected.hpp +++ b/include/FlameIDE/Common/Expected.hpp @@ -58,7 +58,7 @@ class Expected { UNKNOWN = -1 , RESULT = 0 - , ERROR = 1 + , INVALID = 1 }; union Data @@ -186,7 +186,7 @@ Expected::operator=(const ErrorType &error) noexcept { destroy(); flame_ide::placementNew(&data.error.value, error); - data.state = State::ERROR; + data.state = State::INVALID; return *this; } @@ -196,7 +196,7 @@ Expected::operator=(ErrorType &&error) noexcept { destroy(); flame_ide::placementNew(&data.error.value, move(error)); - data.state = State::ERROR; + data.state = State::INVALID; return *this; } @@ -245,7 +245,7 @@ template Expected & Expected::ifError(Functor &&functor) noexcept { - if (State::ERROR != data.state) + if (State::INVALID != data.state) return *this; functor(move(data.error.value)); @@ -259,7 +259,7 @@ template const Expected & Expected::ifError(Functor &&functor) const noexcept { - if (State::ERROR != data.state) + if (State::INVALID != data.state) return *this; functor(data.error.value); @@ -272,7 +272,7 @@ template Expected & Expected::ifErrorGet(Functor &&functor) noexcept { - if (State::ERROR != data.state) + if (State::INVALID != data.state) return *this; functor(data.error.value); @@ -299,7 +299,7 @@ void Expected::destroy() noexcept data.result.value.~ResultType(); return; - case State::ERROR: + case State::INVALID: data.error.value.~ErrorType(); return; diff --git a/include/FlameIDE/Os/Async/Network/NotificatorBase.hpp b/include/FlameIDE/Os/Async/Network/NotificatorBase.hpp index e53abdd7..e716caa5 100644 --- a/include/FlameIDE/Os/Async/Network/NotificatorBase.hpp +++ b/include/FlameIDE/Os/Async/Network/NotificatorBase.hpp @@ -21,7 +21,7 @@ struct TcpClient {}; } // namespace tag template -class NotificatorBase: public flame_ide::DefaultFunctorConstBase {}; +class NotificatorBase: public flame_ide::DefaultFunctorBase {}; using UdpServerNotificatorBase = NotificatorBase; using UdpClientNotificatorBase = NotificatorBase; diff --git a/include/FlameIDE/Os/Async/Network/Registrar.hpp b/include/FlameIDE/Os/Async/Network/Registrar.hpp index aada524e..4eede700 100644 --- a/include/FlameIDE/Os/Async/Network/Registrar.hpp +++ b/include/FlameIDE/Os/Async/Network/Registrar.hpp @@ -90,11 +90,11 @@ class Registrar AsyncEvent popTcpServer() noexcept; AsyncEvent popTcpClient() noexcept; - void setNotificator(const UdpServerNotificatorBase ¬ificator) noexcept; - void setNotificator(const UdpClientNotificatorBase ¬ificator) noexcept; - void setNotificator(const TcpServerNotificatorBase ¬ificator) noexcept; - void setNotificator(const TcpAcceptedConnectionNotificatorBase ¬ificator) noexcept; - void setNotificator(const TcpClientNotificatorBase ¬ificator) noexcept; + void setNotificator(UdpServerNotificatorBase ¬ificator) noexcept; + void setNotificator(UdpClientNotificatorBase ¬ificator) noexcept; + void setNotificator(TcpServerNotificatorBase ¬ificator) noexcept; + void setNotificator(TcpAcceptedConnectionNotificatorBase ¬ificator) noexcept; + void setNotificator(TcpClientNotificatorBase ¬ificator) noexcept; void unsetNotificators() noexcept; diff --git a/src/Handler/Network/Handler.cpp b/src/Handler/Network/Handler.cpp index 91cc0088..f6ea8905 100644 --- a/src/Handler/Network/Handler.cpp +++ b/src/Handler/Network/Handler.cpp @@ -58,7 +58,8 @@ Handler::ExpectedServerHandle Handler::pushUdp(os::network::UdpServer &&server) { auto &handleData = result.object.get(); const auto &endpoint = handleData.server->endpoint().get(); - internal->registrar().add(endpoint); + const auto status = os::async::network::Registrar{}.add(endpoint); + flame_ide::unused(status); handleData.handler = this; result.callbackDeregistrate = @@ -76,7 +77,8 @@ Handler::ExpectedSessionHandle Handler::pushUdp(os::network::UdpClient &&client) { auto &handleData = result.object.get(); const auto &endpoint = handleData.data.client->endpoint().get(); - internal->registrar().add(endpoint); + const auto status = os::async::network::Registrar{}.add(endpoint); + flame_ide::unused(status); handleData.handler = this; result.callbackDeregistrate = diff --git a/src/Handler/Network/Headers.cmake b/src/Handler/Network/Headers.cmake index 0bcdf37e..bc575dbe 100644 --- a/src/Handler/Network/Headers.cmake +++ b/src/Handler/Network/Headers.cmake @@ -4,5 +4,6 @@ set (HEADER_LIST ${CMAKE_CURRENT_SOURCE_DIR}/Notificator.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Tcp.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Udp.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/Worker.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/WorkerBase.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Workers.hpp ) diff --git a/src/Handler/Network/Internal.cpp b/src/Handler/Network/Internal.cpp index a704475a..cd941f26 100644 --- a/src/Handler/Network/Internal.cpp +++ b/src/Handler/Network/Internal.cpp @@ -6,9 +6,27 @@ namespace flame_ide { Handler::Internal::Internal() noexcept -{} + : workers{ udpData } + , notificators{ + workers.udp().serverNotifier() + , workers.udp().clientNotifier() + } +{ + os::async::network::Registrar registration; + + registration.setNotificator(notificators.udpServer); + registration.setNotificator(notificators.udpClient); -Handler::Internal::~Internal() noexcept = default; + // TODO + registration.setNotificator(notificators.tcpServer); + registration.setNotificator(notificators.tcpAcceptedConnecton); + registration.setNotificator(notificators.tcpClient); +} + +Handler::Internal::~Internal() noexcept +{ + os::async::network::Registrar{}.unsetNotificators(); +} Handler::Udp &Handler::Internal::udp() noexcept { @@ -20,19 +38,14 @@ Handler::Tcp &Handler::Internal::tcp() noexcept return tcpData; } -os::async::network::Registrar &Handler::Internal::registrar() noexcept -{ - return registration; -} - os::Status Handler::Internal::start() noexcept { - return workers.start(); + return workers.start(), os::STATUS_SUCCESS; } os::Status Handler::Internal::stop() noexcept { - return workers.stop(); + return workers.stop(), os::STATUS_SUCCESS; } }}} // namespace flame_ide::os::network diff --git a/src/Handler/Network/Internal.hpp b/src/Handler/Network/Internal.hpp index 7b6fc8c3..617c2714 100644 --- a/src/Handler/Network/Internal.hpp +++ b/src/Handler/Network/Internal.hpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include namespace flame_ide {namespace handler @@ -36,10 +36,6 @@ class Handler::Internal /// @return Tcp &tcp() noexcept; - /// @brief registrar - /// @return - os::async::network::Registrar ®istrar() noexcept; - /// @brief start /// @return os::Status start() noexcept; @@ -52,18 +48,7 @@ class Handler::Internal Handler::Udp udpData; ///< Handler::Tcp tcpData; ///< Workers workers; ///< - - struct - { - udp::ServerNotificator udpServerNotificator; - udp::ClientNotificator udpClientNotificator; - - tcp::ServerNotificator tcpServerNotificator; - tcp::AcceptedConnectonNotificator tcpAcceptedConnectonNotificator; - tcp::ClientNotificator tcpClientNotificator; - } notificators; ///< - - os::async::network::Registrar registration; ///< + Notificators notificators; ///< TODO: Need workers }; }}} // namespace flame_ide::handler::network diff --git a/src/Handler/Network/Notificator.cpp b/src/Handler/Network/Notificator.cpp index c3a9184b..c8e99172 100644 --- a/src/Handler/Network/Notificator.cpp +++ b/src/Handler/Network/Notificator.cpp @@ -3,30 +3,32 @@ namespace flame_ide {namespace handler {namespace network -{namespace udp +{namespace tcp { -void ServerNotificator::operator()() const noexcept +void ServerNotificator::operator()() noexcept {} -void ClientNotificator::operator()() const noexcept +void AcceptedConnectonNotificator::operator()() noexcept {} -}}}} // namespace flame_ide::handler::network::udp +void ClientNotificator::operator()() noexcept +{} + +}}}} // namespace flame_ide::handler::network::tcp namespace flame_ide {namespace handler {namespace network -{namespace tcp { -void ServerNotificator::operator()() const noexcept +Notificators::Notificators( + WorkerBase::Notifier udpServerNotifier + , WorkerBase::Notifier udpClientNotifier +) noexcept + : udpServer{ udpServerNotifier } + , udpClient{ udpClientNotifier } {} -void AcceptedConnectonNotificator::operator()() const noexcept -{} - -void ClientNotificator::operator()() const noexcept -{} +}}} // namespace flame_ide::handler::network -}}}} // namespace flame_ide::handler::network::tcp diff --git a/src/Handler/Network/Notificator.hpp b/src/Handler/Network/Notificator.hpp index cce4b0ce..336ff783 100644 --- a/src/Handler/Network/Notificator.hpp +++ b/src/Handler/Network/Notificator.hpp @@ -1,35 +1,9 @@ #ifndef HANDLERNOTIFICATOR_HPP #define HANDLERNOTIFICATOR_HPP -#include - -#include -#include - #include -#include - -namespace flame_ide -{namespace handler -{namespace network -{namespace udp -{ - -class ServerNotificator: - public ::flame_ide::os::async::network::UdpServerNotificatorBase -{ -public: - virtual void operator()() const noexcept override; -}; - -class ClientNotificator: - public ::flame_ide::os::async::network::UdpClientNotificatorBase -{ -public: - virtual void operator()() const noexcept override; -}; -}}}} // namespace flame_ide::handler::network::udp +#include namespace flame_ide {namespace handler @@ -41,7 +15,7 @@ class ServerNotificator: public ::flame_ide::os::async::network::TcpServerNotificatorBase { public: - virtual void operator()() const noexcept override; + virtual void operator()() noexcept override; }; class AcceptedConnectonNotificator: @@ -49,16 +23,38 @@ class AcceptedConnectonNotificator: ::TcpAcceptedConnectionNotificatorBase { public: - virtual void operator()() const noexcept override; + virtual void operator()() noexcept override; }; class ClientNotificator: public ::flame_ide::os::async::network::TcpClientNotificatorBase { public: - virtual void operator()() const noexcept override; + virtual void operator()() noexcept override; }; }}}} // namespace flame_ide::handler::network::tcp +namespace flame_ide +{namespace handler +{namespace network +{ + +struct Notificators +{ + Notificators( + WorkerBase::Notifier udpServerNotifier + , WorkerBase::Notifier udpClientNotifier + ) noexcept; + + udp::ServerNotificator udpServer; + udp::ClientNotificator udpClient; + + tcp::ServerNotificator tcpServer; + tcp::AcceptedConnectonNotificator tcpAcceptedConnecton; + tcp::ClientNotificator tcpClient; +}; + +}}} // namespace flame_ide::handler::network + #endif // HANDLERNOTIFICATOR_HPP diff --git a/src/Handler/Network/Sources.cmake b/src/Handler/Network/Sources.cmake index 072d8ebb..5250f85a 100644 --- a/src/Handler/Network/Sources.cmake +++ b/src/Handler/Network/Sources.cmake @@ -6,5 +6,6 @@ set (SOURCE_LIST ${CMAKE_CURRENT_SOURCE_DIR}/SessionHandle.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Tcp.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Udp.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Worker.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/WorkerBase.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Workers.cpp ) diff --git a/src/Handler/Network/Udp.cpp b/src/Handler/Network/Udp.cpp index 99cb0c7b..fb02fba5 100644 --- a/src/Handler/Network/Udp.cpp +++ b/src/Handler/Network/Udp.cpp @@ -74,6 +74,20 @@ Handler::ExpectedUdpClient Handler::Udp::pop(Handler::SessionHandle &handle) return { flame_ide::move(client) }; } +void Handler::Udp::process( + udp::ServerProcessor &serverProcessor, os::async::network::AsyncEvent event +) +{ + storage.process(serverProcessor, event); +} + +void Handler::Udp::process( + udp::ClientProcessor &clientProcessor, os::async::network::AsyncEvent event +) +{ + storage.process(clientProcessor, event); +} + // server Handler::Udp::CallbackGetSessionHandle Handler::Udp::serverHandleCallback() const noexcept diff --git a/src/Handler/Network/Udp.hpp b/src/Handler/Network/Udp.hpp index b52726ce..633d0484 100644 --- a/src/Handler/Network/Udp.hpp +++ b/src/Handler/Network/Udp.hpp @@ -6,6 +6,7 @@ #include #include +#include namespace flame_ide {namespace handler @@ -43,6 +44,15 @@ class Handler::Udp Handler::ExpectedUdpServer pop(Handler::ServerHandle &handle); Handler::ExpectedUdpClient pop(Handler::SessionHandle &handle); +public: // For Workers + void process( + udp::ServerProcessor &serverProcessor, os::async::network::AsyncEvent event + ); + void process( + udp::ClientProcessor &clientProcessor, os::async::network::AsyncEvent event + ); + +public: // Callbacks /// @brief serverHandleCallback /// @return CallbackGetSessionHandle serverHandleCallback() const noexcept; diff --git a/src/Handler/Network/Udp/ActualData.hpp b/src/Handler/Network/Udp/ActualData.hpp index af4ec6b8..07883d93 100644 --- a/src/Handler/Network/Udp/ActualData.hpp +++ b/src/Handler/Network/Udp/ActualData.hpp @@ -24,7 +24,7 @@ struct ActualData flame_ide::templates::UniquePointer, SIZE >; using MessagesCircularIterator = - flame_ide::templates::defaults::CircularForwardIterator< + ::flame_ide::templates::defaults::CircularForwardIterator< typename Messages::Iterator >; @@ -38,8 +38,7 @@ struct ActualData Messages messages; MessagesCircularIterator first = MessagesCircularIterator{ - messages.begin() - , templates::makeRange(messages.begin(), messages.end()) + messages.begin(), templates::makeRange(messages.begin(), messages.end()) }; MessagesCircularIterator last = first; @@ -66,6 +65,12 @@ ActualData::getEmptyMessage() noexcept auto result = last; ++amount; ++last; + + { + os::threads::Locker lockMessage{ result->pointer()->spin }; + result->pointer()->state = MessageState::PROCESSING; + } + return result->pointer(); } @@ -81,6 +86,12 @@ ActualData::getFilledMessage() noexcept auto result = first; --amount; ++first; + + { + os::threads::Locker lockMessage{ result->pointer()->spin }; + result->pointer()->state = MessageState::PROCESSING; + } + return result->pointer(); } diff --git a/src/Handler/Network/Udp/Client.cpp b/src/Handler/Network/Udp/Client.cpp index 5da1c32d..e6725132 100644 --- a/src/Handler/Network/Udp/Client.cpp +++ b/src/Handler/Network/Udp/Client.cpp @@ -9,7 +9,7 @@ namespace flame_ide {namespace udp { -void ClientMessage::fill(flame_ide::os::network::UdpClient &endpoint) +void ClientMessage::fill(flame_ide::os::network::UdpClient &endpoint) noexcept { os::threads::Locker locker{ spin }; diff --git a/src/Handler/Network/Udp/ContainerTypes.hpp b/src/Handler/Network/Udp/ContainerTypes.hpp index 42c89dd1..c07be201 100644 --- a/src/Handler/Network/Udp/ContainerTypes.hpp +++ b/src/Handler/Network/Udp/ContainerTypes.hpp @@ -25,11 +25,6 @@ class Clients: public ::flame_ide::templates::StaticArray< > {}; -using SocketDescriptors = ::flame_ide::templates::StaticArray< - ::flame_ide::os::SocketDescriptor - , Constants::NUMBER_OF_SERVERS + Constants::NUMBER_OF_CLIENTS ->; - }}}} // namespace flame_ide::handler::network::udp #endif // HANDLER_INTERNAL_UDP_CONTAINER_TYPES_HPP diff --git a/src/Handler/Network/Udp/Headers.cmake b/src/Handler/Network/Udp/Headers.cmake index 5a03278f..87fe63c3 100644 --- a/src/Handler/Network/Udp/Headers.cmake +++ b/src/Handler/Network/Udp/Headers.cmake @@ -5,8 +5,11 @@ set (HEADER_LIST ${CMAKE_CURRENT_SOURCE_DIR}/ContainerTypes.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Endpoint.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Message.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Notificators.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Processing.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Server.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Storage.hpp ${CMAKE_CURRENT_SOURCE_DIR}/TypeMapping.hpp ${CMAKE_CURRENT_SOURCE_DIR}/Types.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/Workers.hpp ) diff --git a/src/Handler/Network/Udp/Notificators.cpp b/src/Handler/Network/Udp/Notificators.cpp new file mode 100644 index 00000000..92d57e3d --- /dev/null +++ b/src/Handler/Network/Udp/Notificators.cpp @@ -0,0 +1,32 @@ +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +// + +ServerNotificator::ServerNotificator(WorkerBase::Notifier notifierInit) + : notifier{ ::flame_ide::move(notifierInit) } +{} + +void ServerNotificator::operator()() noexcept +{ + notifier(); +} + +// + +ClientNotificator::ClientNotificator(WorkerBase::Notifier notifierInit) + : notifier{ ::flame_ide::move(notifierInit) } +{} + +void ClientNotificator::operator()() noexcept +{ + notifier(); +} + +}}}} // namespace flame_ide::handler::network::udp diff --git a/src/Handler/Network/Udp/Notificators.hpp b/src/Handler/Network/Udp/Notificators.hpp new file mode 100644 index 00000000..214f587b --- /dev/null +++ b/src/Handler/Network/Udp/Notificators.hpp @@ -0,0 +1,44 @@ +#ifndef HANDLER_INTERNAL_UDP_NOTIFICATORS_HPP +#define HANDLER_INTERNAL_UDP_NOTIFICATORS_HPP + +#include + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +/// +/// \brief The ServerNotificator class +/// +class ServerNotificator: + public ::flame_ide::os::async::network::UdpServerNotificatorBase +{ +public: + ServerNotificator(WorkerBase::Notifier notifierInit); + virtual void operator()() noexcept override; + +private: + WorkerBase::Notifier notifier; +}; + +/// +/// \brief The ClientNotificator class +/// +class ClientNotificator: + public ::flame_ide::os::async::network::UdpClientNotificatorBase +{ +public: + ClientNotificator(WorkerBase::Notifier notifierInit); + virtual void operator()() noexcept override; + +private: + WorkerBase::Notifier notifier; +}; + +}}}} // namespace flame_ide::handler::network::udp + +#endif // HANDLER_INTERNAL_UDP_NOTIFICATORS_HPP diff --git a/src/Handler/Network/Udp/Processing.cpp b/src/Handler/Network/Udp/Processing.cpp new file mode 100644 index 00000000..4323bf13 --- /dev/null +++ b/src/Handler/Network/Udp/Processing.cpp @@ -0,0 +1,85 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +bool ServerProcessor::operator()( + HandlerEndpointUdpData &storage, os::async::network::AsyncEvent event +) noexcept +{ + ::flame_ide::ReferenceWrapper endpointData{ nullptr }; + { + ::flame_ide::os::threads::Locker lock{ storage.spin }; + for (templates::UniquePointer &pointer : *storage.container) + { + if (!checkEndpoint(pointer, event.descriptor)) + continue; + + endpointData = decltype(endpointData){ pointer.pointer() }; + } + } + if (!endpointData) + return false; + + switch (event.event) + { + case decltype(event.event)::INVALID: + { + return false; + } + + case decltype(event.event)::READ: + { + os::network::UdpServer &endpoint = *endpointData->endpoint(); + + // Message in processing state + ::flame_ide::ReferenceWrapper message + = endpointData->input().getEmptyMessage(); + if (message) + return false; + return message->fill(endpoint); + } + + case decltype(event.event)::WRITE: + { + return false; + } + + case decltype(event.event)::READ_WRITE: + { + return false; + } + + default: + return false; + } +} + +bool ServerProcessor::checkEndpoint( + const ::flame_ide::templates::UniquePointer &endpoint + , os::SocketDescriptor descriptor +) +{ + if (!endpoint || endpoint->empty()) + return false; + + if (endpoint->endpoint()->native().descriptor != descriptor) + return false; + + return true; +} + +// + +bool ClientProcessor::operator()( + HandlerEndpointUdpData &storage, os::async::network::AsyncEvent event +) noexcept +{ + flame_ide::unused(storage, event); + return false; +} + +}}}} // namespace flame_ide::handler::network::udp diff --git a/src/Handler/Network/Udp/Processing.hpp b/src/Handler/Network/Udp/Processing.hpp new file mode 100644 index 00000000..48eea140 --- /dev/null +++ b/src/Handler/Network/Udp/Processing.hpp @@ -0,0 +1,63 @@ +#ifndef HANDLER_INTERNAL_UDP_PROCESSING_HPP +#define HANDLER_INTERNAL_UDP_PROCESSING_HPP + +#include +#include + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +// Base class for processing clients and servers + +template +class EndpointProcessor: public flame_ide::FunctorBase< + Container, HandlerEndpointUdpData &, os::async::network::AsyncEvent +> +{ +public: + virtual bool operator()( + HandlerEndpointUdpData &storage + , os::async::network::AsyncEvent event + ) noexcept = 0; +}; + +// + +class ServerProcessor: + public flame_ide::FunctorBase< + bool, HandlerEndpointUdpData &, os::async::network::AsyncEvent + > +{ +public: + virtual bool operator()( + HandlerEndpointUdpData &storage, os::async::network::AsyncEvent event + ) noexcept override; + +private: + static bool checkEndpoint( + const ::flame_ide::templates::UniquePointer &endpoint + , os::SocketDescriptor descriptor + ); +}; + +// + +class ClientProcessor: + public flame_ide::FunctorBase< + bool, HandlerEndpointUdpData &, os::async::network::AsyncEvent + > +{ +public: + virtual bool operator()( + HandlerEndpointUdpData &storage, os::async::network::AsyncEvent event + ) noexcept override; +}; + +}}}} // namespace flame_ide::handler::network::udp + +#endif // HANDLER_INTERNAL_UDP_PROCESSING_HPP diff --git a/src/Handler/Network/Udp/Server.cpp b/src/Handler/Network/Udp/Server.cpp index ac623a2c..ccf43bab 100644 --- a/src/Handler/Network/Udp/Server.cpp +++ b/src/Handler/Network/Udp/Server.cpp @@ -6,17 +6,18 @@ namespace flame_ide {namespace udp { -void ServerMessage::fill(flame_ide::os::network::UdpServer &endpoint) noexcept +bool ServerMessage::fill(flame_ide::os::network::UdpServer &endpoint) noexcept { os::threads::Locker lock{ this->spin }; auto waitResult = endpoint.wait(); if (waitResult.getStatus() < 0) - return; + return false; this->client = waitResult; this->size = this->client.receive(this->range()); this->state = MessageState::READY; + return true; } Types::ssize_t ServerCommunicationData::bytesToRead() const noexcept diff --git a/src/Handler/Network/Udp/Server.hpp b/src/Handler/Network/Udp/Server.hpp index 23464e4c..44978527 100644 --- a/src/Handler/Network/Udp/Server.hpp +++ b/src/Handler/Network/Udp/Server.hpp @@ -14,7 +14,7 @@ namespace flame_ide struct ServerMessage: public Message { - void fill(flame_ide::os::network::UdpServer &endpoint) noexcept; + bool fill(flame_ide::os::network::UdpServer &endpoint) noexcept; ::flame_ide::os::network::UdpServer::WithClient client; }; diff --git a/src/Handler/Network/Udp/Sources.cmake b/src/Handler/Network/Udp/Sources.cmake index 2d994597..c25ef745 100644 --- a/src/Handler/Network/Udp/Sources.cmake +++ b/src/Handler/Network/Udp/Sources.cmake @@ -1,5 +1,8 @@ set (SOURCE_LIST ${CMAKE_CURRENT_SOURCE_DIR}/Client.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Message.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Notificators.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Processing.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Server.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Workers.cpp ) diff --git a/src/Handler/Network/Udp/Storage.hpp b/src/Handler/Network/Udp/Storage.hpp index 586f525b..a27bd4bc 100644 --- a/src/Handler/Network/Udp/Storage.hpp +++ b/src/Handler/Network/Udp/Storage.hpp @@ -99,6 +99,15 @@ class Storage return OsEndpoint{}; } + template + void process(EndpointProcessor &processor, os::async::network::AsyncEvent event) + { + using HandlerEndpointData = typename HandlerEndpointDataMapper< + EndpointProcessor + >::Type; + processor(getData(), event); + } + private: template T &getData() noexcept; diff --git a/src/Handler/Network/Udp/TypeMapping.hpp b/src/Handler/Network/Udp/TypeMapping.hpp index 7c1bce71..cde8e810 100644 --- a/src/Handler/Network/Udp/TypeMapping.hpp +++ b/src/Handler/Network/Udp/TypeMapping.hpp @@ -23,9 +23,11 @@ namespace flame_ide class Server; class Servers; +class ServerProcessor; class Client; class Clients; +class ClientProcessor; template struct HandlerEndpointUdpData; @@ -54,6 +56,14 @@ using ClientDataMatchingTrait = ::flame_ide::TypeMappingTrait< Client, HandlerEndpointUdpData >; +using ServerProcessorMatchingTrait = ::flame_ide::TypeMappingTrait< + ServerProcessor, HandlerEndpointUdpData +>; + +using ClientProcessorMatchingTrait = ::flame_ide::TypeMappingTrait< + ClientProcessor, HandlerEndpointUdpData +>; + // Integral constants template @@ -62,6 +72,7 @@ using IsServer = ::flame_ide::IntegralConstant< , ::flame_ide::ComparingTypes< EndpointType, ::flame_ide::os::network::UdpServer >::VALUE || ::flame_ide::ComparingTypes::VALUE + || ::flame_ide::ComparingTypes::VALUE >; template @@ -70,6 +81,7 @@ using IsClient = ::flame_ide::IntegralConstant< , ::flame_ide::ComparingTypes< EndpointType, ::flame_ide::os::network::UdpClient >::VALUE || ::flame_ide::ComparingTypes::VALUE + || ::flame_ide::ComparingTypes::VALUE >; template @@ -77,6 +89,13 @@ using IsCommonEndpoint = ::flame_ide::IntegralConstant< bool, IsServer::VALUE || IsClient::VALUE >; +template +using IsEndpointProcessor = ::flame_ide::IntegralConstant< + bool + , ::flame_ide::ComparingTypes::VALUE + || ::flame_ide::ComparingTypes::VALUE +>; + template using IsHandlerEndpoint = ::flame_ide::IntegralConstant< bool, ::flame_ide::ComparingTypes::VALUE @@ -103,15 +122,23 @@ using EndpointTypeMapper = ::flame_ide::TypeMapper< template< typename HandlerEndpoint , typename = typename ::flame_ide::EnableType< - IsHandlerEndpoint::VALUE, HandlerEndpoint + IsHandlerEndpoint::VALUE || IsEndpointProcessor::VALUE, HandlerEndpoint >::Type > using HandlerEndpointDataMapper = ::flame_ide::TypeMapper< HandlerEndpoint , typename ::flame_ide::ChooseType< IsServer::VALUE - , ServerDataMatchingTrait - , ClientDataMatchingTrait + , typename ::flame_ide::ChooseType< + IsHandlerEndpoint::VALUE + , ServerDataMatchingTrait + , ServerProcessorMatchingTrait + >::Type + , typename ::flame_ide::ChooseType< + IsHandlerEndpoint::VALUE + , ClientDataMatchingTrait + , ClientProcessorMatchingTrait + >::Type >::Type >; diff --git a/src/Handler/Network/Udp/Workers.cpp b/src/Handler/Network/Udp/Workers.cpp new file mode 100644 index 00000000..a81a847e --- /dev/null +++ b/src/Handler/Network/Udp/Workers.cpp @@ -0,0 +1,68 @@ +#include +#include + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +// + +ServerWorker::ServerWorker(Handler::Udp &udpInit) noexcept + : udp{ udpInit } +{} + +void ServerWorker::processing() noexcept +{ + auto event = os::async::network::Registrar{}.popUdpServer(); + if (event == decltype(event){}) + return; + udp.process(*this, event); +} + +// + +ClientWorker::ClientWorker(Handler::Udp &udpInit) noexcept + : udp{ udpInit } +{} + +void ClientWorker::processing() noexcept +{ + auto event = os::async::network::Registrar{}.popUdpClient(); + if (event == decltype(event){}) + return; + udp.process(*this, event); +} + +// + +Workers::Workers(Handler::Udp &udpInit) noexcept + : serverWorker{ udpInit }, clientWorker{ udpInit } +{} + +void Workers::start() noexcept +{ + serverWorker.start(); + clientWorker.start(); +} + +void Workers::stop() noexcept +{ + serverWorker.stop(); + clientWorker.stop(); +} + +WorkerBase::Notifier Workers::serverNotifier() noexcept +{ + return serverWorker.notifier(); +} +WorkerBase::Notifier Workers::clientNotifier() noexcept +{ + return clientWorker.notifier(); +} + + +}}}} // namespace flame_ide::handler::network::udp diff --git a/src/Handler/Network/Udp/Workers.hpp b/src/Handler/Network/Udp/Workers.hpp new file mode 100644 index 00000000..e80b813f --- /dev/null +++ b/src/Handler/Network/Udp/Workers.hpp @@ -0,0 +1,63 @@ +#ifndef HANDLER_INTERNAL_UDP_WORKERS_HPP +#define HANDLER_INTERNAL_UDP_WORKERS_HPP + +#include +#include + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{ + +// + +class ServerWorker: public WorkerBase, private ServerProcessor +{ +public: + ServerWorker(Handler::Udp &udpInit) noexcept; + +private: + void processing() noexcept override; + +private: + Handler::Udp &udp; +}; + +// + +class ClientWorker: public WorkerBase, private ClientProcessor +{ +public: + ClientWorker(Handler::Udp &udpInit) noexcept; + +private: + void processing() noexcept override; + +private: + Handler::Udp &udp; +}; + +// + +class Workers +{ +public: + Workers(Handler::Udp &udpInit) noexcept; + + void start() noexcept; + void stop() noexcept; + + WorkerBase::Notifier serverNotifier() noexcept; + WorkerBase::Notifier clientNotifier() noexcept; + +private: + ServerWorker serverWorker; + ClientWorker clientWorker; +}; + +}}}} // namespace flame_ide::handler::network::udp + +#endif // HANDLER_INTERNAL_UDP_WORKERS_HPP diff --git a/src/Handler/Network/Worker.cpp b/src/Handler/Network/Worker.cpp deleted file mode 100644 index cc3a9497..00000000 --- a/src/Handler/Network/Worker.cpp +++ /dev/null @@ -1,144 +0,0 @@ -#include - -#include - -namespace flame_ide -{namespace handler -{namespace network -{ - -os::threads::ConditionVariable &Worker::getConditionVariable() noexcept -{ - return condvar; -} - -void Worker::start() noexcept -{ - run(); -} - -void Worker::stop() noexcept -{ - { - os::threads::Locker locker{ stopSpin }; - stopFlag = true; - } - - if (condvar.isWait()) - condvar.notify(); - - join(); -} - -void Worker::body() noexcept -{ - while (!needStop()) - { - condvar.wait(); - - if (needStop()) - break; - - // UDP - { - // Servers - /* - Алгоритм такой: - 1. От регистрара получаем из очереди сокет (нужен а-ля peek, чтобы совсем не вытащить из очереди) - 2. Проверяем, если такой сокет в базе - 3. Если такой сокет зарегистрирован в обработчике - 0. Вытаскиваем сокет из очереди - 1. Вытаскиваем сервер - 2. Вытаскиваем ближайшее собщение - 3. Читаем в то сообщение - 4. ... что-то еще ... - 4. Если такой сокет не зарегистрирован в обработчике - 1. Идём мимо - */ - - // Есть мысли: - // 1. Специализировать тип нотификашки - // 2. Сделать очередь "причин", и идти к конкретной очереди сокетов - } - - if (needStop()) - break; - - { - // Clients - } - - if (needStop()) - break; - - // TCP - // TODO - } -} - -bool Worker::needStop() noexcept -{ - os::threads::Locker locker{ stopSpin }; - return stopFlag; -} - - -}}} // namespace flame_ide::handler::network - -namespace flame_ide -{namespace handler -{namespace network -{ - -Workers::Workers() noexcept -{} - -Workers::~Workers() noexcept -{ - stop(); -} - -templates::StaticArray< - ReferenceWrapper, Workers::NUMBER_OF_WORKERS -> -Workers::getConditionVariables() noexcept -{ - templates::StaticArray< - ReferenceWrapper, NUMBER_OF_WORKERS - > condvars; - for (Types::size_t i = 0; i < NUMBER_OF_WORKERS; ++i) - { - condvars[i] = makeReferenceWrapper(workers[i].getConditionVariable()); - } - return condvars; -} - -os::Status Workers::start() noexcept -{ - return os::STATUS_FAILED; - - for (auto &worker : workers) - { - worker.start(); - if (worker.getStatus() != os::STATUS_SUCCESS) - return worker.getStatus(); - } - - return os::STATUS_SUCCESS; -} - -os::Status Workers::stop() noexcept -{ - return os::STATUS_FAILED; - - for (auto &worker : workers) - { - worker.stop(); - if (worker.getStatus() != os::STATUS_SUCCESS) - return worker.getStatus(); - } - - return os::STATUS_SUCCESS; -} - -}}} // namespace flame_ide::handler::network diff --git a/src/Handler/Network/Worker.hpp b/src/Handler/Network/Worker.hpp deleted file mode 100644 index 91394a6b..00000000 --- a/src/Handler/Network/Worker.hpp +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef WORKER_HPP -#define WORKER_HPP - -#include - -#include - -#include -#include -#include - -#include - -namespace flame_ide -{namespace handler -{namespace network -{ - - - -}}} - -namespace flame_ide -{namespace handler -{namespace network -{ - -class Worker: private os::threads::ThreadCrtp -{ - using Parent = os::threads::ThreadCrtp; - friend Parent; - -public: - using Parent::getStatus; - - /// - /// @brief getConditionVariable - /// @return - /// - os::threads::ConditionVariable &getConditionVariable() noexcept; - - /// - /// @brief start - /// - void start() noexcept; - - /// - /// @brief stop - /// - void stop() noexcept; - -private: - // os::threads::ThreadCrtp - // TODO - void body() noexcept; - - bool needStop() noexcept; - -private: - os::threads::Mutex mutex; - os::threads::ConditionVariable condvar{ mutex }; - - os::threads::Spin stopSpin; - bool stopFlag = false; -}; - -}}} // namespace flame_ide::handler::network - -namespace flame_ide -{namespace handler -{namespace network -{ - -class Workers -{ - static constexpr auto NUMBER_OF_WORKERS = - generated::network::Config::HANDLER_NUMBER_OF_WORKERS; - -public: - Workers() noexcept; - ~Workers() noexcept; - - /// - /// @brief getConditionVariables - /// @return - /// - templates::StaticArray< - ReferenceWrapper, NUMBER_OF_WORKERS - > - getConditionVariables() noexcept; - - /// - /// @brief start - /// @return - /// - // TODO - os::Status start() noexcept; - - /// - /// @brief stop - /// @return - /// - // TODO - os::Status stop() noexcept; - -private: - templates::StaticArray workers; -}; - -}}} // namespace flame_ide::handler::network - -#endif // WORKER_HPP diff --git a/src/Handler/Network/WorkerBase.cpp b/src/Handler/Network/WorkerBase.cpp new file mode 100644 index 00000000..4713fcd2 --- /dev/null +++ b/src/Handler/Network/WorkerBase.cpp @@ -0,0 +1,64 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{ + +WorkerBase::Notifier WorkerBase::notifier() noexcept +{ + return WorkerBase::Notifier{ condvar }; +} + +os::Status WorkerBase::start() noexcept +{ + run(); + return getStatus(); + +} + +os::Status WorkerBase::stop() noexcept +{ + { + os::threads::Locker locker{ stopSpin }; + stopFlag = true; + } + + if (condvar.isWait()) + condvar.notify(); + + // join(); + return getStatus(); +} + +void WorkerBase::vRun() noexcept +{ + while (!needStop()) + { + condvar.wait(); + + if (needStop()) + break; + + processing(); + } +} + +bool WorkerBase::needStop() noexcept +{ + os::threads::Locker locker{ stopSpin }; + return stopFlag; +} + +// + +WorkerBase::Notifier::Notifier(os::threads::ConditionVariable &condvarInit) noexcept + : condvar{ &condvarInit } +{} + +void WorkerBase::Notifier::operator()() noexcept +{ + condvar->notify(); +} + +}}} // namespace flame_ide::handler::network diff --git a/src/Handler/Network/WorkerBase.hpp b/src/Handler/Network/WorkerBase.hpp new file mode 100644 index 00000000..a6d92bbe --- /dev/null +++ b/src/Handler/Network/WorkerBase.hpp @@ -0,0 +1,82 @@ +#ifndef HANDLER_INTERNAL_WORKER_BASE_HPP +#define HANDLER_INTERNAL_WORKER_BASE_HPP + +#include +#include +#include +#include + +namespace flame_ide +{namespace handler +{namespace network +{ + +class WorkerBase: private os::threads::ThreadBase +{ + using Parent = os::threads::ThreadBase; + friend Parent; + +public: + class Notifier: public ::flame_ide::DefaultFunctorBase + { + public: + Notifier(const WorkerBase::Notifier &) = default; + Notifier(WorkerBase::Notifier &&) = default; + Notifier(os::threads::ConditionVariable &condvar) noexcept; + + Notifier &operator=(const WorkerBase::Notifier &) = default; + Notifier &operator=(WorkerBase::Notifier &&) = default; + + virtual void operator()() noexcept override; + + private: + Notifier() = default; + + private: + os::threads::ConditionVariable *condvar; + }; + +public: + using Parent::getStatus; + + /// + /// @brief getNotifier + /// @return + /// + Notifier notifier() noexcept; + + /// + /// @brief start + /// @return + /// + os::Status start() noexcept; + + /// + /// @brief stop + /// @return + /// + os::Status stop() noexcept; + +protected: + virtual void processing() noexcept = 0; + + bool needStop() noexcept; + +private: + virtual void vRun() noexcept override; + + +private: + os::threads::Mutex mutex; + os::threads::ConditionVariable condvar{ mutex }; + + os::threads::Spin stopSpin; + bool stopFlag = false; +}; + +// + + +}}} // namespace flame_ide::handler::network + +#endif // HANDLER_INTERNAL_WORKER_BASE_HPP diff --git a/src/Handler/Network/Workers.cpp b/src/Handler/Network/Workers.cpp new file mode 100644 index 00000000..18591ad1 --- /dev/null +++ b/src/Handler/Network/Workers.cpp @@ -0,0 +1,33 @@ +#include + +#include + +namespace flame_ide +{namespace handler +{namespace network +{ + +Workers::Workers(Handler::Udp &udp) noexcept : udpWorkers{ udp } +{} + +Workers::~Workers() noexcept +{ + stop(); +} + +void Workers::start() noexcept +{ + udpWorkers.start(); +} + +void Workers::stop() noexcept +{ + udpWorkers.stop(); +} + +udp::Workers &Workers::udp() noexcept +{ + return udpWorkers; +} + +}}} // namespace flame_ide::handler::network diff --git a/src/Handler/Network/Workers.hpp b/src/Handler/Network/Workers.hpp new file mode 100644 index 00000000..7546e1aa --- /dev/null +++ b/src/Handler/Network/Workers.hpp @@ -0,0 +1,43 @@ +#ifndef HANDLER_INTERNAL_WORKERS_HPP +#define HANDLER_INTERNAL_WORKERS_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{ + +class Workers +{ +public: + Workers(Handler::Udp &udp) noexcept; + ~Workers() noexcept; + + /// + /// @brief start + /// @return + /// + // TODO + void start() noexcept; + + /// + /// @brief stop + /// @return + /// + // TODO + void stop() noexcept; + + /// + /// \brief udp + /// \return + /// + udp::Workers &udp() noexcept; + +private: + udp::Workers udpWorkers; +}; + +}}} // namespace flame_ide::handler::network + +#endif // HANDLER_INTERNAL_WORKERS_HPP diff --git a/src/Handler/Tests/Network/Udp/StorageTest.cpp b/src/Handler/Tests/Network/Udp/StorageTest.cpp index bd125749..aa089837 100644 --- a/src/Handler/Tests/Network/Udp/StorageTest.cpp +++ b/src/Handler/Tests/Network/Udp/StorageTest.cpp @@ -19,10 +19,33 @@ int StorageTest::vStart() "initialization" , [this]() { return init(); } )); + // CHECK_RESULT_SUCCESS(doTestCase( "server push-pop" , [this]() { return serverPushPop(); } )); + CHECK_RESULT_SUCCESS(doTestCase( + "client push-pop" + , [this]() { return clientPushPop(); } + )); + // + CHECK_RESULT_SUCCESS(doTestCase( + "Max servers push-pop" + , [this]() { return maxServersPushPop(); } + )); + CHECK_RESULT_SUCCESS(doTestCase( + "Max clients push-pop" + , [this]() { return maxClientsPushPop(); } + )); + // + CHECK_RESULT_SUCCESS(doTestCase( + "Server process" + , [this]() { return processServer(); } + )); + CHECK_RESULT_SUCCESS(doTestCase( + "Client process" + , [this]() { return processClient(); } + )); return ResultType::SUCCESS; } @@ -48,4 +71,44 @@ int StorageTest::serverPushPop() return ResultType::SUCCESS; } +int StorageTest::clientPushPop() +{ + udp::Storage storage; + os::network::UdpClient client{ os::network::Ipv4::localhost(65001) }; + + const os::Socket expectedSocket = client.native(); + + auto handle = storage.push(flame_ide::move(client)); + IN_CASE_CHECK(handle.operator->() != nullptr); + + auto resultServer = storage.pop(handle); + IN_CASE_CHECK(expectedSocket.descriptor == resultServer.native().descriptor); + + return ResultType::SUCCESS; +} + +int StorageTest::maxServersPushPop() +{ + // Закинуть максимальное количество серверов + 1 + return ResultType::SUCCESS; +} + +int StorageTest::maxClientsPushPop() +{ + // Закинуть максимальное количество клиентов + 1 + return ResultType::SUCCESS; +} + +int StorageTest::processServer() +{ + // отладка ServerProcessor + return ResultType::SUCCESS; +} + +int StorageTest::processClient() +{ + // отладка ClientProcessor + return ResultType::SUCCESS; +} + }}}}} // namespace flame_ide::handler::network::udp::tests diff --git a/src/Handler/Tests/Network/Udp/StorageTest.hpp b/src/Handler/Tests/Network/Udp/StorageTest.hpp index 0d640df4..ba18b57b 100644 --- a/src/Handler/Tests/Network/Udp/StorageTest.hpp +++ b/src/Handler/Tests/Network/Udp/StorageTest.hpp @@ -21,7 +21,15 @@ class StorageTest: public ::AbstractTest private: int init(); + int serverPushPop(); + int clientPushPop(); + + int maxServersPushPop(); + int maxClientsPushPop(); + + int processServer(); + int processClient(); }; }}}}} // namespace flame_ide::handler::network::udp::tests diff --git a/src/Handler/Tests/Network/WorkerTest.cpp b/src/Handler/Tests/Network/WorkerTest.cpp index a3dded3b..d55f2fc7 100644 --- a/src/Handler/Tests/Network/WorkerTest.cpp +++ b/src/Handler/Tests/Network/WorkerTest.cpp @@ -1,5 +1,5 @@ #include -#include +#include namespace flame_ide {namespace handler diff --git a/src/Os/Async/Network/EventCatcherBase.cpp b/src/Os/Async/Network/EventCatcherBase.cpp index 65f2dcd6..9d5b76d0 100644 --- a/src/Os/Async/Network/EventCatcherBase.cpp +++ b/src/Os/Async/Network/EventCatcherBase.cpp @@ -11,30 +11,36 @@ SocketQueues &EventCatcherBase::queues() noexcept return socketQueues; } -void EventCatcherBase::setNotificator(const UdpServerNotificatorBase ¬ificator) noexcept +void EventCatcherBase::setNotificator(UdpServerNotificatorBase ¬ificator) noexcept { - notificationObjects.udpServer = decltype(notificationObjects.udpServer){ notificator }; + notificationObjects.udpServer + = decltype(notificationObjects.udpServer){ notificator }; } -void EventCatcherBase::setNotificator(const UdpClientNotificatorBase ¬ificator) noexcept +void EventCatcherBase::setNotificator(UdpClientNotificatorBase ¬ificator) noexcept { - notificationObjects.udpClient = decltype(notificationObjects.udpClient){ notificator }; + notificationObjects.udpClient + = decltype(notificationObjects.udpClient){ notificator }; } -void EventCatcherBase::setNotificator(const TcpServerNotificatorBase ¬ificator) noexcept +void EventCatcherBase::setNotificator(TcpServerNotificatorBase ¬ificator) noexcept { - notificationObjects.tcpServer = decltype(notificationObjects.tcpServer){ notificator }; + notificationObjects.tcpServer + = decltype(notificationObjects.tcpServer){ notificator }; } -void EventCatcherBase::setNotificator(const TcpAcceptedConnectionNotificatorBase ¬ificator) noexcept +void EventCatcherBase::setNotificator( + TcpAcceptedConnectionNotificatorBase ¬ificator +) noexcept { - notificationObjects.tcpAcceptedConnection = - decltype(notificationObjects.tcpAcceptedConnection){ notificator }; + notificationObjects.tcpAcceptedConnection + = decltype(notificationObjects.tcpAcceptedConnection){ notificator }; } -void EventCatcherBase::setNotificator(const TcpClientNotificatorBase ¬ificator) noexcept +void EventCatcherBase::setNotificator(TcpClientNotificatorBase ¬ificator) noexcept { - notificationObjects.tcpClient = decltype(notificationObjects.tcpClient){ notificator }; + notificationObjects.tcpClient + = decltype(notificationObjects.tcpClient){ notificator }; } void EventCatcherBase::unsetNotificator(tag::UdpServer) noexcept diff --git a/src/Os/Async/Network/EventCatcherBase.hpp b/src/Os/Async/Network/EventCatcherBase.hpp index 87a30a10..d27d576c 100644 --- a/src/Os/Async/Network/EventCatcherBase.hpp +++ b/src/Os/Async/Network/EventCatcherBase.hpp @@ -54,11 +54,11 @@ class EventCatcherBase /// @param notificator /// @note Implementation of NotificatorBase needs thread and signal safe /// - void setNotificator(const UdpServerNotificatorBase ¬ificator) noexcept; - void setNotificator(const UdpClientNotificatorBase ¬ificator) noexcept; - void setNotificator(const TcpServerNotificatorBase ¬ificator) noexcept; - void setNotificator(const TcpAcceptedConnectionNotificatorBase ¬ificator) noexcept; - void setNotificator(const TcpClientNotificatorBase ¬ificator) noexcept; + void setNotificator(UdpServerNotificatorBase ¬ificator) noexcept; + void setNotificator(UdpClientNotificatorBase ¬ificator) noexcept; + void setNotificator(TcpServerNotificatorBase ¬ificator) noexcept; + void setNotificator(TcpAcceptedConnectionNotificatorBase ¬ificator) noexcept; + void setNotificator(TcpClientNotificatorBase ¬ificator) noexcept; /// /// @brief unsetNotifcator @@ -93,12 +93,12 @@ class EventCatcherBase SocketQueues socketQueues; struct { - ConstReferenceWrapper udpServer = nullptr; - ConstReferenceWrapper udpClient = nullptr; - ConstReferenceWrapper tcpServer = nullptr; - ConstReferenceWrapper + ReferenceWrapper udpServer = nullptr; + ReferenceWrapper udpClient = nullptr; + ReferenceWrapper tcpServer = nullptr; + ReferenceWrapper tcpAcceptedConnection = nullptr; - ConstReferenceWrapper tcpClient = nullptr; + ReferenceWrapper tcpClient = nullptr; } notificationObjects; }; diff --git a/src/Os/Async/Network/Registrar.cpp b/src/Os/Async/Network/Registrar.cpp index fb8b636d..726210d9 100644 --- a/src/Os/Async/Network/Registrar.cpp +++ b/src/Os/Async/Network/Registrar.cpp @@ -199,23 +199,23 @@ AsyncEvent Registrar::popTcpClient() noexcept // notificator -void Registrar::setNotificator(const UdpServerNotificatorBase ¬ificator) noexcept +void Registrar::setNotificator(UdpServerNotificatorBase ¬ificator) noexcept { EventCatcherBase::get().setNotificator(notificator); } -void Registrar::setNotificator(const UdpClientNotificatorBase ¬ificator) noexcept +void Registrar::setNotificator(UdpClientNotificatorBase ¬ificator) noexcept { EventCatcherBase::get().setNotificator(notificator); } -void Registrar::setNotificator(const TcpServerNotificatorBase ¬ificator) noexcept +void Registrar::setNotificator(TcpServerNotificatorBase ¬ificator) noexcept { EventCatcherBase::get().setNotificator(notificator); } -void Registrar::setNotificator(const TcpAcceptedConnectionNotificatorBase ¬ificator) noexcept +void Registrar::setNotificator(TcpAcceptedConnectionNotificatorBase ¬ificator) noexcept { EventCatcherBase::get().setNotificator(notificator); } -void Registrar::setNotificator(const TcpClientNotificatorBase ¬ificator) noexcept +void Registrar::setNotificator(TcpClientNotificatorBase ¬ificator) noexcept { EventCatcherBase::get().setNotificator(notificator); } diff --git a/src/Os/Tests/Async/Network/RegistrarTest.cpp b/src/Os/Tests/Async/Network/RegistrarTest.cpp index 7063cce8..fb502c22 100644 --- a/src/Os/Tests/Async/Network/RegistrarTest.cpp +++ b/src/Os/Tests/Async/Network/RegistrarTest.cpp @@ -35,7 +35,7 @@ class NotificatorTest: public NotificatorBaseType return notification; } private: - virtual void operator()() const noexcept override + virtual void operator()() noexcept override { os::threads::Locker{ mutex }; notification = true; From 75d06aeb00b9dd083d4cbd8fdc6ba5d638e2f835 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Wed, 19 Aug 2026 01:40:45 +0300 Subject: [PATCH 35/37] Add initional tests for Handler and Handler/Udp --- src/Handler/Tests/Network/HandlerTest.hpp | 6 ++-- src/Handler/Tests/Network/InternalTest.hpp | 7 +++-- .../Tests/Network/NotificatorsTest.cpp | 19 ++++++++++++ .../Tests/Network/NotificatorsTest.hpp | 25 ++++++++++++++++ .../Tests/Network/ServerHandleTest.cpp | 19 ++++++++++++ .../Tests/Network/ServerHandleTest.hpp | 25 ++++++++++++++++ .../Tests/Network/SessionHandleTest.cpp | 19 ++++++++++++ .../Tests/Network/SessionHandleTest.hpp | 25 ++++++++++++++++ src/Handler/Tests/Network/Sources.cmake | 16 ++++++++-- src/Handler/Tests/Network/TcpTest.cpp | 19 ++++++++++++ src/Handler/Tests/Network/TcpTest.hpp | 25 ++++++++++++++++ .../Tests/Network/Udp/ActualDataTest.cpp | 20 +++++++++++++ .../Tests/Network/Udp/ActualDataTest.hpp | 25 ++++++++++++++++ .../Tests/Network/Udp/EndpointTest.cpp | 20 +++++++++++++ .../Tests/Network/Udp/EndpointTest.hpp | 25 ++++++++++++++++ .../Tests/Network/Udp/NotificatorsTest.cpp | 20 +++++++++++++ .../Tests/Network/Udp/NotificatorsTest.hpp | 25 ++++++++++++++++ .../Tests/Network/Udp/ProcessingTest.cpp | 20 +++++++++++++ .../Tests/Network/Udp/ProcessingTest.hpp | 25 ++++++++++++++++ src/Handler/Tests/Network/Udp/Sources.cmake | 12 ++++++++ .../Tests/Network/Udp/TypeMappingTest.cpp | 20 +++++++++++++ .../Tests/Network/Udp/TypeMappingTest.hpp | 25 ++++++++++++++++ src/Handler/Tests/Network/Udp/WorkersTest.cpp | 20 +++++++++++++ src/Handler/Tests/Network/Udp/WorkersTest.hpp | 25 ++++++++++++++++ src/Handler/Tests/Network/UdpTest.cpp | 19 ++++++++++++ src/Handler/Tests/Network/UdpTest.hpp | 25 ++++++++++++++++ src/Handler/Tests/Network/WorkerBaseTest.cpp | 19 ++++++++++++ src/Handler/Tests/Network/WorkerBaseTest.hpp | 25 ++++++++++++++++ src/Handler/Tests/Network/WorkerTest.hpp | 24 --------------- .../{WorkerTest.cpp => WorkersTest.cpp} | 8 ++--- src/Handler/Tests/Network/WorkersTest.hpp | 24 +++++++++++++++ src/Handler/Tests/TestAggregator.cpp | 29 +++++++++++++++++-- 32 files changed, 622 insertions(+), 38 deletions(-) create mode 100644 src/Handler/Tests/Network/NotificatorsTest.cpp create mode 100644 src/Handler/Tests/Network/NotificatorsTest.hpp create mode 100644 src/Handler/Tests/Network/ServerHandleTest.cpp create mode 100644 src/Handler/Tests/Network/ServerHandleTest.hpp create mode 100644 src/Handler/Tests/Network/SessionHandleTest.cpp create mode 100644 src/Handler/Tests/Network/SessionHandleTest.hpp create mode 100644 src/Handler/Tests/Network/TcpTest.cpp create mode 100644 src/Handler/Tests/Network/TcpTest.hpp create mode 100644 src/Handler/Tests/Network/Udp/ActualDataTest.cpp create mode 100644 src/Handler/Tests/Network/Udp/ActualDataTest.hpp create mode 100644 src/Handler/Tests/Network/Udp/EndpointTest.cpp create mode 100644 src/Handler/Tests/Network/Udp/EndpointTest.hpp create mode 100644 src/Handler/Tests/Network/Udp/NotificatorsTest.cpp create mode 100644 src/Handler/Tests/Network/Udp/NotificatorsTest.hpp create mode 100644 src/Handler/Tests/Network/Udp/ProcessingTest.cpp create mode 100644 src/Handler/Tests/Network/Udp/ProcessingTest.hpp create mode 100644 src/Handler/Tests/Network/Udp/TypeMappingTest.cpp create mode 100644 src/Handler/Tests/Network/Udp/TypeMappingTest.hpp create mode 100644 src/Handler/Tests/Network/Udp/WorkersTest.cpp create mode 100644 src/Handler/Tests/Network/Udp/WorkersTest.hpp create mode 100644 src/Handler/Tests/Network/UdpTest.cpp create mode 100644 src/Handler/Tests/Network/UdpTest.hpp create mode 100644 src/Handler/Tests/Network/WorkerBaseTest.cpp create mode 100644 src/Handler/Tests/Network/WorkerBaseTest.hpp delete mode 100644 src/Handler/Tests/Network/WorkerTest.hpp rename src/Handler/Tests/Network/{WorkerTest.cpp => WorkersTest.cpp} (54%) create mode 100644 src/Handler/Tests/Network/WorkersTest.hpp diff --git a/src/Handler/Tests/Network/HandlerTest.hpp b/src/Handler/Tests/Network/HandlerTest.hpp index a9e72631..9848d192 100644 --- a/src/Handler/Tests/Network/HandlerTest.hpp +++ b/src/Handler/Tests/Network/HandlerTest.hpp @@ -1,5 +1,5 @@ -#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_HANDLERTEST_HPP -#define FLAMEIDE_SRC_HANDLER_NETWORK_HANDLERTEST_HPP +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_HANDLER_TEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_HANDLER_TEST_HPP #include @@ -35,4 +35,4 @@ class HandlerTest: public ::AbstractTest }}}} // namespace flame_ide::handler::network::tests -#endif // FLAMEIDE_SRC_HANDLER_NETWORK_HANDLERTEST_HPP +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_HANDLER_TEST_HPP diff --git a/src/Handler/Tests/Network/InternalTest.hpp b/src/Handler/Tests/Network/InternalTest.hpp index a1e66e8d..913805c2 100644 --- a/src/Handler/Tests/Network/InternalTest.hpp +++ b/src/Handler/Tests/Network/InternalTest.hpp @@ -1,5 +1,5 @@ -#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_INTERNALTEST_HPP -#define FLAMEIDE_SRC_HANDLER_NETWORK_INTERNALTEST_HPP +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_INTERNAL_TEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_INTERNAL_TEST_HPP #include @@ -19,6 +19,7 @@ class InternalTest: public ::AbstractTest virtual int vStart(); }; + }}}} // namespace flame_ide::handler::network::tests -#endif // FLAMEIDE_SRC_HANDLER_NETWORK_INTERNALTEST_HPP +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_INTERNAL_TEST_HPP diff --git a/src/Handler/Tests/Network/NotificatorsTest.cpp b/src/Handler/Tests/Network/NotificatorsTest.cpp new file mode 100644 index 00000000..8684a978 --- /dev/null +++ b/src/Handler/Tests/Network/NotificatorsTest.cpp @@ -0,0 +1,19 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +NotificatorsTest::NotificatorsTest() : ::AbstractTest("Notificators") +{} + +NotificatorsTest::~NotificatorsTest() = default; + +int NotificatorsTest::vStart() +{ + return ResultType::SUCCESS; +} + +}}}} // namespace flame_ide::handler::network::tests diff --git a/src/Handler/Tests/Network/NotificatorsTest.hpp b/src/Handler/Tests/Network/NotificatorsTest.hpp new file mode 100644 index 00000000..4e09363e --- /dev/null +++ b/src/Handler/Tests/Network/NotificatorsTest.hpp @@ -0,0 +1,25 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_NOTIFICATORS_TEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_NOTIFICATORS_TEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +class NotificatorsTest: public ::AbstractTest +{ +public: + NotificatorsTest(); + virtual ~NotificatorsTest(); + +private: + virtual int vStart(); +}; + + +}}}} // namespace flame_ide::handler::network::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_NOTIFICATORS_TEST_HPP diff --git a/src/Handler/Tests/Network/ServerHandleTest.cpp b/src/Handler/Tests/Network/ServerHandleTest.cpp new file mode 100644 index 00000000..8bfd9773 --- /dev/null +++ b/src/Handler/Tests/Network/ServerHandleTest.cpp @@ -0,0 +1,19 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +ServerHandleTest::ServerHandleTest() : ::AbstractTest("ServerHandle") +{} + +ServerHandleTest::~ServerHandleTest() = default; + +int ServerHandleTest::vStart() +{ + return ResultType::SUCCESS; +} + +}}}} // namespace flame_ide::handler::network::tests diff --git a/src/Handler/Tests/Network/ServerHandleTest.hpp b/src/Handler/Tests/Network/ServerHandleTest.hpp new file mode 100644 index 00000000..c83a4797 --- /dev/null +++ b/src/Handler/Tests/Network/ServerHandleTest.hpp @@ -0,0 +1,25 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_SERVER_HANDLE_TEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_SERVER_HANDLE_TEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +class ServerHandleTest: public ::AbstractTest +{ +public: + ServerHandleTest(); + virtual ~ServerHandleTest(); + +private: + virtual int vStart(); +}; + + +}}}} // namespace flame_ide::handler::network::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_SERVER_HANDLE_TEST_HPP diff --git a/src/Handler/Tests/Network/SessionHandleTest.cpp b/src/Handler/Tests/Network/SessionHandleTest.cpp new file mode 100644 index 00000000..46155f5b --- /dev/null +++ b/src/Handler/Tests/Network/SessionHandleTest.cpp @@ -0,0 +1,19 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +SessionHandleTest::SessionHandleTest() : ::AbstractTest("SessionHandle") +{} + +SessionHandleTest::~SessionHandleTest() = default; + +int SessionHandleTest::vStart() +{ + return ResultType::SUCCESS; +} + +}}}} // namespace flame_ide::handler::network::tests diff --git a/src/Handler/Tests/Network/SessionHandleTest.hpp b/src/Handler/Tests/Network/SessionHandleTest.hpp new file mode 100644 index 00000000..56d1677b --- /dev/null +++ b/src/Handler/Tests/Network/SessionHandleTest.hpp @@ -0,0 +1,25 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_SESSION_HANDLE_TEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_SESSION_HANDLE_TEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +class SessionHandleTest: public ::AbstractTest +{ +public: + SessionHandleTest(); + virtual ~SessionHandleTest(); + +private: + virtual int vStart(); +}; + + +}}}} // namespace flame_ide::handler::network::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_SESSION_HANDLE_TEST_HPP diff --git a/src/Handler/Tests/Network/Sources.cmake b/src/Handler/Tests/Network/Sources.cmake index 52e6858a..163cc0c9 100644 --- a/src/Handler/Tests/Network/Sources.cmake +++ b/src/Handler/Tests/Network/Sources.cmake @@ -3,6 +3,18 @@ set (SOURCE_LIST ${CMAKE_CURRENT_SOURCE_DIR}/HandlerTest.hpp ${CMAKE_CURRENT_SOURCE_DIR}/InternalTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/InternalTest.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/WorkerTest.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/WorkerTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/NotificatorsTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/NotificatorsTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/ServerHandleTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ServerHandleTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/SessionHandleTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/SessionHandleTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/TcpTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/TcpTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/UdpTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/UdpTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/WorkerBaseTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/WorkerBaseTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/WorkersTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/WorkersTest.hpp ) diff --git a/src/Handler/Tests/Network/TcpTest.cpp b/src/Handler/Tests/Network/TcpTest.cpp new file mode 100644 index 00000000..067a531f --- /dev/null +++ b/src/Handler/Tests/Network/TcpTest.cpp @@ -0,0 +1,19 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +TcpTest::TcpTest() : ::AbstractTest("Tcp") +{} + +TcpTest::~TcpTest() = default; + +int TcpTest::vStart() +{ + return ResultType::SUCCESS; +} + +}}}} // namespace flame_ide::handler::network::tests diff --git a/src/Handler/Tests/Network/TcpTest.hpp b/src/Handler/Tests/Network/TcpTest.hpp new file mode 100644 index 00000000..a3307507 --- /dev/null +++ b/src/Handler/Tests/Network/TcpTest.hpp @@ -0,0 +1,25 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_TCP_TEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_TCP_TEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +class TcpTest: public ::AbstractTest +{ +public: + TcpTest(); + virtual ~TcpTest(); + +private: + virtual int vStart(); +}; + + +}}}} // namespace flame_ide::handler::network::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_TCP_TEST_HPP diff --git a/src/Handler/Tests/Network/Udp/ActualDataTest.cpp b/src/Handler/Tests/Network/Udp/ActualDataTest.cpp new file mode 100644 index 00000000..15140b49 --- /dev/null +++ b/src/Handler/Tests/Network/Udp/ActualDataTest.cpp @@ -0,0 +1,20 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace tests +{ + +ActualDataTest::ActualDataTest() : ::AbstractTest("udp::ActualData") +{} + +ActualDataTest::~ActualDataTest() = default; + +int ActualDataTest::vStart() +{ + return ResultType::SUCCESS; +} + +}}}}} // namespace flame_ide::handler::network::udp::tests diff --git a/src/Handler/Tests/Network/Udp/ActualDataTest.hpp b/src/Handler/Tests/Network/Udp/ActualDataTest.hpp new file mode 100644 index 00000000..7a64ca42 --- /dev/null +++ b/src/Handler/Tests/Network/Udp/ActualDataTest.hpp @@ -0,0 +1,25 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_UDP_ACTUALDATATEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_UDP_ACTUALDATATEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace tests +{ + +class ActualDataTest: public ::AbstractTest +{ +public: + ActualDataTest(); + virtual ~ActualDataTest(); + +private: + virtual int vStart(); +}; + +}}}}} // namespace flame_ide::handler::network::udp::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_UDP_ACTUALDATATEST_HPP diff --git a/src/Handler/Tests/Network/Udp/EndpointTest.cpp b/src/Handler/Tests/Network/Udp/EndpointTest.cpp new file mode 100644 index 00000000..ded4d8ae --- /dev/null +++ b/src/Handler/Tests/Network/Udp/EndpointTest.cpp @@ -0,0 +1,20 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace tests +{ + +EndpointTest::EndpointTest() : ::AbstractTest("udp::Endpoint") +{} + +EndpointTest::~EndpointTest() = default; + +int EndpointTest::vStart() +{ + return ResultType::SUCCESS; +} + +}}}}} // namespace flame_ide::handler::network::udp::tests diff --git a/src/Handler/Tests/Network/Udp/EndpointTest.hpp b/src/Handler/Tests/Network/Udp/EndpointTest.hpp new file mode 100644 index 00000000..3567bc64 --- /dev/null +++ b/src/Handler/Tests/Network/Udp/EndpointTest.hpp @@ -0,0 +1,25 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_UDP_ENDPOINTTEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_UDP_ENDPOINTTEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace tests +{ + +class EndpointTest: public ::AbstractTest +{ +public: + EndpointTest(); + virtual ~EndpointTest(); + +private: + virtual int vStart(); +}; + +}}}}} // namespace flame_ide::handler::network::udp::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_ENDPOINTUDP_TEST_HPP diff --git a/src/Handler/Tests/Network/Udp/NotificatorsTest.cpp b/src/Handler/Tests/Network/Udp/NotificatorsTest.cpp new file mode 100644 index 00000000..e0d0edc4 --- /dev/null +++ b/src/Handler/Tests/Network/Udp/NotificatorsTest.cpp @@ -0,0 +1,20 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace tests +{ + +NotificatorsTest::NotificatorsTest() : ::AbstractTest("udp::Notificators") +{} + +NotificatorsTest::~NotificatorsTest() = default; + +int NotificatorsTest::vStart() +{ + return ResultType::SUCCESS; +} + +}}}}} // namespace flame_ide::handler::network::udp::tests diff --git a/src/Handler/Tests/Network/Udp/NotificatorsTest.hpp b/src/Handler/Tests/Network/Udp/NotificatorsTest.hpp new file mode 100644 index 00000000..684620b7 --- /dev/null +++ b/src/Handler/Tests/Network/Udp/NotificatorsTest.hpp @@ -0,0 +1,25 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_UDP_NOTIFICATORSTEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_UDP_NOTIFICATORSTEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace tests +{ + +class NotificatorsTest: public ::AbstractTest +{ +public: + NotificatorsTest(); + virtual ~NotificatorsTest(); + +private: + virtual int vStart(); +}; + +}}}}} // namespace flame_ide::handler::network::udp::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_UDP_NOTIFICATORSTEST_HPP diff --git a/src/Handler/Tests/Network/Udp/ProcessingTest.cpp b/src/Handler/Tests/Network/Udp/ProcessingTest.cpp new file mode 100644 index 00000000..7dea9c71 --- /dev/null +++ b/src/Handler/Tests/Network/Udp/ProcessingTest.cpp @@ -0,0 +1,20 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace tests +{ + +ProcessingTest::ProcessingTest() : ::AbstractTest("udp::Processing") +{} + +ProcessingTest::~ProcessingTest() = default; + +int ProcessingTest::vStart() +{ + return ResultType::SUCCESS; +} + +}}}}} // namespace flame_ide::handler::network::udp::tests diff --git a/src/Handler/Tests/Network/Udp/ProcessingTest.hpp b/src/Handler/Tests/Network/Udp/ProcessingTest.hpp new file mode 100644 index 00000000..f76f59c5 --- /dev/null +++ b/src/Handler/Tests/Network/Udp/ProcessingTest.hpp @@ -0,0 +1,25 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_UDP_PROCESSINGTEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_UDP_PROCESSINGTEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace tests +{ + +class ProcessingTest: public ::AbstractTest +{ +public: + ProcessingTest(); + virtual ~ProcessingTest(); + +private: + virtual int vStart(); +}; + +}}}}} // namespace flame_ide::handler::network::udp::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_UDP_PROCESSINGTEST_HPP diff --git a/src/Handler/Tests/Network/Udp/Sources.cmake b/src/Handler/Tests/Network/Udp/Sources.cmake index a295e9ce..b4bb5ddd 100644 --- a/src/Handler/Tests/Network/Udp/Sources.cmake +++ b/src/Handler/Tests/Network/Udp/Sources.cmake @@ -1,10 +1,22 @@ set (SOURCE_LIST + ${CMAKE_CURRENT_SOURCE_DIR}/ActualDataTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ActualDataTest.hpp ${CMAKE_CURRENT_SOURCE_DIR}/ClientTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ClientTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/EndpointTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/EndpointTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/NotificatorsTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/NotificatorsTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/ProcessingTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ProcessingTest.hpp ${CMAKE_CURRENT_SOURCE_DIR}/ServerTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ServerTest.hpp ${CMAKE_CURRENT_SOURCE_DIR}/StorageTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/StorageTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/TypeMappingTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/TypeMappingTest.hpp ${CMAKE_CURRENT_SOURCE_DIR}/UdpTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/UdpTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/WorkersTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/WorkersTest.hpp ) diff --git a/src/Handler/Tests/Network/Udp/TypeMappingTest.cpp b/src/Handler/Tests/Network/Udp/TypeMappingTest.cpp new file mode 100644 index 00000000..f8f3c734 --- /dev/null +++ b/src/Handler/Tests/Network/Udp/TypeMappingTest.cpp @@ -0,0 +1,20 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace tests +{ + +TypeMappingTest::TypeMappingTest() : ::AbstractTest("udp::TypeMapping") +{} + +TypeMappingTest::~TypeMappingTest() = default; + +int TypeMappingTest::vStart() +{ + return ResultType::SUCCESS; +} + +}}}}} // namespace flame_ide::handler::network::udp::tests diff --git a/src/Handler/Tests/Network/Udp/TypeMappingTest.hpp b/src/Handler/Tests/Network/Udp/TypeMappingTest.hpp new file mode 100644 index 00000000..b706088a --- /dev/null +++ b/src/Handler/Tests/Network/Udp/TypeMappingTest.hpp @@ -0,0 +1,25 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_UDP_TYPEMAPPINGTEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_UDP_TYPEMAPPINGTEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace tests +{ + +class TypeMappingTest: public ::AbstractTest +{ +public: + TypeMappingTest(); + virtual ~TypeMappingTest(); + +private: + virtual int vStart(); +}; + +}}}}} // namespace flame_ide::handler::network::udp::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_UDP_TYPEMAPPINGTEST_HPP diff --git a/src/Handler/Tests/Network/Udp/WorkersTest.cpp b/src/Handler/Tests/Network/Udp/WorkersTest.cpp new file mode 100644 index 00000000..9018395a --- /dev/null +++ b/src/Handler/Tests/Network/Udp/WorkersTest.cpp @@ -0,0 +1,20 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace tests +{ + +WorkersTest::WorkersTest() : ::AbstractTest("udp::Workers") +{} + +WorkersTest::~WorkersTest() = default; + +int WorkersTest::vStart() +{ + return ResultType::SUCCESS; +} + +}}}}} // namespace flame_ide::handler::network::udp::tests diff --git a/src/Handler/Tests/Network/Udp/WorkersTest.hpp b/src/Handler/Tests/Network/Udp/WorkersTest.hpp new file mode 100644 index 00000000..cb42e6aa --- /dev/null +++ b/src/Handler/Tests/Network/Udp/WorkersTest.hpp @@ -0,0 +1,25 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_UDP_WORKERSTEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_UDP_WORKERSTEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace udp +{namespace tests +{ + +class WorkersTest: public ::AbstractTest +{ +public: + WorkersTest(); + virtual ~WorkersTest(); + +private: + virtual int vStart(); +}; + +}}}}} // namespace flame_ide::handler::network::udp::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_UDP_WORKERSTEST_HPP diff --git a/src/Handler/Tests/Network/UdpTest.cpp b/src/Handler/Tests/Network/UdpTest.cpp new file mode 100644 index 00000000..777782ed --- /dev/null +++ b/src/Handler/Tests/Network/UdpTest.cpp @@ -0,0 +1,19 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +UdpTest::UdpTest() : ::AbstractTest("Udp") +{} + +UdpTest::~UdpTest() = default; + +int UdpTest::vStart() +{ + return ResultType::SUCCESS; +} + +}}}} // namespace flame_ide::handler::network::tests diff --git a/src/Handler/Tests/Network/UdpTest.hpp b/src/Handler/Tests/Network/UdpTest.hpp new file mode 100644 index 00000000..e013242b --- /dev/null +++ b/src/Handler/Tests/Network/UdpTest.hpp @@ -0,0 +1,25 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_UDP_TEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_UDP_TEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +class UdpTest: public ::AbstractTest +{ +public: + UdpTest(); + virtual ~UdpTest(); + +private: + virtual int vStart(); +}; + + +}}}} // namespace flame_ide::handler::network::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_UDP_TEST_HPP diff --git a/src/Handler/Tests/Network/WorkerBaseTest.cpp b/src/Handler/Tests/Network/WorkerBaseTest.cpp new file mode 100644 index 00000000..d5fb4a05 --- /dev/null +++ b/src/Handler/Tests/Network/WorkerBaseTest.cpp @@ -0,0 +1,19 @@ +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +WorkerBaseTest::WorkerBaseTest() : ::AbstractTest("WorkerBase") +{} + +WorkerBaseTest::~WorkerBaseTest() = default; + +int WorkerBaseTest::vStart() +{ + return ResultType::SUCCESS; +} + +}}}} // namespace flame_ide::handler::network::tests diff --git a/src/Handler/Tests/Network/WorkerBaseTest.hpp b/src/Handler/Tests/Network/WorkerBaseTest.hpp new file mode 100644 index 00000000..5694d925 --- /dev/null +++ b/src/Handler/Tests/Network/WorkerBaseTest.hpp @@ -0,0 +1,25 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_WORKER_BASE_TEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_WORKER_BASE_TEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +class WorkerBaseTest: public ::AbstractTest +{ +public: + WorkerBaseTest(); + virtual ~WorkerBaseTest(); + +private: + virtual int vStart(); +}; + + +}}}} // namespace flame_ide::handler::network::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_WORKER_BASE_TEST_HPP diff --git a/src/Handler/Tests/Network/WorkerTest.hpp b/src/Handler/Tests/Network/WorkerTest.hpp deleted file mode 100644 index d7a96e1a..00000000 --- a/src/Handler/Tests/Network/WorkerTest.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_WORKERTEST_HPP -#define FLAMEIDE_SRC_HANDLER_NETWORK_WORKERTEST_HPP - -#include - -namespace flame_ide -{namespace handler -{namespace network -{namespace tests -{ - -class WorkerTest: public ::AbstractTest -{ -public: - WorkerTest(); - virtual ~WorkerTest(); - -private: - virtual int vStart(); -}; - -}}}} // namespace flame_ide::handler::network::tests - -#endif // FLAMEIDE_SRC_HANDLER_NETWORK_WORKERTEST_HPP diff --git a/src/Handler/Tests/Network/WorkerTest.cpp b/src/Handler/Tests/Network/WorkersTest.cpp similarity index 54% rename from src/Handler/Tests/Network/WorkerTest.cpp rename to src/Handler/Tests/Network/WorkersTest.cpp index d55f2fc7..059f02f9 100644 --- a/src/Handler/Tests/Network/WorkerTest.cpp +++ b/src/Handler/Tests/Network/WorkersTest.cpp @@ -1,4 +1,4 @@ -#include +#include #include namespace flame_ide @@ -7,12 +7,12 @@ namespace flame_ide {namespace tests { -WorkerTest::WorkerTest() : ::AbstractTest("Worker") +WorkersTest::WorkersTest() : ::AbstractTest("Workers") {} -WorkerTest::~WorkerTest() = default; +WorkersTest::~WorkersTest() = default; -int WorkerTest::vStart() +int WorkersTest::vStart() { return ResultType::SUCCESS; } diff --git a/src/Handler/Tests/Network/WorkersTest.hpp b/src/Handler/Tests/Network/WorkersTest.hpp new file mode 100644 index 00000000..8837d305 --- /dev/null +++ b/src/Handler/Tests/Network/WorkersTest.hpp @@ -0,0 +1,24 @@ +#ifndef FLAMEIDE_SRC_HANDLER_NETWORK_WORKERS_TEST_HPP +#define FLAMEIDE_SRC_HANDLER_NETWORK_WORKERS_TEST_HPP + +#include + +namespace flame_ide +{namespace handler +{namespace network +{namespace tests +{ + +class WorkersTest: public ::AbstractTest +{ +public: + WorkersTest(); + virtual ~WorkersTest(); + +private: + virtual int vStart(); +}; + +}}}} // namespace flame_ide::handler::network::tests + +#endif // FLAMEIDE_SRC_HANDLER_NETWORK_WORKERS_TEST_HPP diff --git a/src/Handler/Tests/TestAggregator.cpp b/src/Handler/Tests/TestAggregator.cpp index 0ad0b1a8..1a0a78a8 100644 --- a/src/Handler/Tests/TestAggregator.cpp +++ b/src/Handler/Tests/TestAggregator.cpp @@ -1,5 +1,11 @@ #include +#include +#include +#include +#include +#include +#include #include #include #include @@ -7,7 +13,13 @@ #include -#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -19,6 +31,12 @@ namespace flame_ide TestAggregator::TestAggregator() : ::TestAggregator("Handler") { // UDP + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); @@ -27,7 +45,14 @@ TestAggregator::TestAggregator() : ::TestAggregator("Handler") // TCP pushBackTest(std::make_shared()); - pushBackTest(std::make_shared()); + // Handler + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); } From dcb66a12a2bd29dbd6401e83ae8d84b8deef89fc Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Wed, 19 Aug 2026 16:00:29 +0300 Subject: [PATCH 36/37] Sort test priorities --- src/Handler/Tests/TestAggregator.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Handler/Tests/TestAggregator.cpp b/src/Handler/Tests/TestAggregator.cpp index 1a0a78a8..3440755c 100644 --- a/src/Handler/Tests/TestAggregator.cpp +++ b/src/Handler/Tests/TestAggregator.cpp @@ -1,14 +1,14 @@ #include +#include #include #include +#include +#include +#include #include #include #include -#include -#include -#include -#include #include #include @@ -31,15 +31,15 @@ namespace flame_ide TestAggregator::TestAggregator() : ::TestAggregator("Handler") { // UDP + pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); - pushBackTest(std::make_shared()); - pushBackTest(std::make_shared()); - pushBackTest(std::make_shared()); - pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); // TCP From 1e1e09d730ca9e361dd917254f368293d500ea92 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Wed, 19 Aug 2026 16:00:48 +0300 Subject: [PATCH 37/37] Implement Udp/TypeMappingTest --- .../Tests/Network/Udp/TypeMappingTest.cpp | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/src/Handler/Tests/Network/Udp/TypeMappingTest.cpp b/src/Handler/Tests/Network/Udp/TypeMappingTest.cpp index f8f3c734..f72f7b2b 100644 --- a/src/Handler/Tests/Network/Udp/TypeMappingTest.cpp +++ b/src/Handler/Tests/Network/Udp/TypeMappingTest.cpp @@ -1,5 +1,7 @@ #include +#include + namespace flame_ide {namespace handler {namespace network @@ -7,6 +9,93 @@ namespace flame_ide {namespace tests { +// EndpointTypeMapper + +static ::AbstractTest::ResultType serverEndpointTypeMapper() noexcept +{ + using ResultType = ::AbstractTest::ResultType; + + IN_CASE_CHECK(( + "Server -> os::network::UdpServer" + , ComparingTypes< + os::network::UdpServer + , EndpointTypeMapper::Type + >::VALUE + )); + + IN_CASE_CHECK_END(( + "os::network::UdpServer -> Server" + , ComparingTypes< + Server + , EndpointTypeMapper::Type + >::VALUE + )); +} + +static ::AbstractTest::ResultType clientEndpointTypeMapper() noexcept +{ + using ResultType = ::AbstractTest::ResultType; + + IN_CASE_CHECK(( + "Client -> os::network::UdpClient" + , ComparingTypes< + os::network::UdpClient + , EndpointTypeMapper::Type + >::VALUE + )); + IN_CASE_CHECK_END(( + "os::network::UdpClient -> Client" + , ComparingTypes< + Client + , EndpointTypeMapper::Type + >::VALUE + )); +} + +// HandlerEndpointDataMapper + +static ::AbstractTest::ResultType serverHandlerEndpointDataMapper() noexcept +{ + using ResultType = ::AbstractTest::ResultType; + + IN_CASE_CHECK(( + "Server -> HandlerEndpointUdpData" + , ComparingTypes< + HandlerEndpointUdpData + , HandlerEndpointDataMapper::Type + >::VALUE + )); + IN_CASE_CHECK_END(( + "ServerProcessor -> HandlerEndpointUdpData" + , ComparingTypes< + HandlerEndpointUdpData + , HandlerEndpointDataMapper::Type + >::VALUE + )); +} + +static ::AbstractTest::ResultType clientHandlerEndpointDataMapper() noexcept +{ + using ResultType = ::AbstractTest::ResultType; + + IN_CASE_CHECK(( + "Client -> HandlerEndpointUdpData" + , ComparingTypes< + HandlerEndpointUdpData + , HandlerEndpointDataMapper::Type + >::VALUE + )); + IN_CASE_CHECK_END(( + "ClientProcessor -> HandlerEndpointUdpData" + , ComparingTypes< + HandlerEndpointUdpData + , HandlerEndpointDataMapper::Type + >::VALUE + )); +} + +// + TypeMappingTest::TypeMappingTest() : ::AbstractTest("udp::TypeMapping") {} @@ -14,6 +103,26 @@ TypeMappingTest::~TypeMappingTest() = default; int TypeMappingTest::vStart() { + // + CHECK_RESULT_SUCCESS(doTestCase( + "Server <--> os::network::UdpServer" + , []() { return serverEndpointTypeMapper(); } + )); + CHECK_RESULT_SUCCESS(doTestCase( + "Client <--> os::network::UdpClient" + , []() { return clientEndpointTypeMapper(); } + )); + + // + CHECK_RESULT_SUCCESS(doTestCase( + "Server, ServerProcessor --> HandlerEndpointUdpData" + , []() { return serverHandlerEndpointDataMapper(); } + )); + CHECK_RESULT_SUCCESS(doTestCase( + "Client, ClientProcessor --> HandlerEndpointUdpData" + , []() { return clientHandlerEndpointDataMapper(); } + )); + return ResultType::SUCCESS; }