From 559eb7a4c4db096b03804d613ec4714dd33516c4 Mon Sep 17 00:00:00 2001 From: "U-EB855G7-WIN\\anton" Date: Fri, 15 Mar 2024 22:59:16 +0500 Subject: [PATCH 1/7] Fix build on CL.EXE --- include/FlameIDE/Common/Utils.hpp | 34 +++++++++---------- include/FlameIDE/Os/Windows/Types.hpp | 2 +- src/Os/Network/NetworkBase.cpp | 23 ++++++++++--- src/Os/Tests/Async/Network/RegistrarTest.cpp | 6 ++-- src/Os/Tests/Threads/ThreadFunctionsTest.cpp | 14 +++++--- src/Os/Windows/Async/Network/CMakeLists.txt | 4 +++ src/Os/Windows/Async/Network/EventCatcher.cpp | 21 ++++++------ 7 files changed, 65 insertions(+), 39 deletions(-) diff --git a/include/FlameIDE/Common/Utils.hpp b/include/FlameIDE/Common/Utils.hpp index 219973af..52187db1 100644 --- a/include/FlameIDE/Common/Utils.hpp +++ b/include/FlameIDE/Common/Utils.hpp @@ -236,19 +236,19 @@ void copy(T &src, const U &dest, Types::size_t size); template Types::size_t length(const T *array); -template< - typename T1, typename T2 - , typename = typename EnableType, T1>::Type - , typename = typename EnableType, T2>::Type -> -constexpr decltype(T1{} + T2{}) max(T1 value1, T2 value2) noexcept; - -template< - typename T1, typename T2 - , typename = typename EnableType, T1>::Type - , typename = typename EnableType, T2>::Type -> -constexpr decltype(T1{} + T2{}) min(T1 value1, T2 value2) noexcept; +// template< +// typename T1, typename T2 +// , typename = typename EnableType, T1>::Type +// , typename = typename EnableType, T2>::Type +// > +// constexpr auto max(T1 value1, T2 value2) noexcept -> decltype(operator+(declareValue() + declareValue())); + +// template< +// typename T1, typename T2 +// , typename = typename EnableType, T1>::Type +// , typename = typename EnableType, T2>::Type +// > +// constexpr auto min(T1 value1, T2 value2) noexcept -> decltype(operator+(declareValue() + declareValue())); template void unused(Args &&...); @@ -561,16 +561,16 @@ Types::size_t length(const T *array) return length; } -template -constexpr decltype(T1{} + T2{}) max(T1 value1, T2 value2) noexcept +template +T maximum(T value1, T value2) noexcept { if (value1 > value2) return value1; return value2; } -template -constexpr decltype(T1{} + T2{}) min(T1 value1, T2 value2) noexcept +template +T minimum(T value1, T value2) noexcept { if (value2 > value1) return value1; diff --git a/include/FlameIDE/Os/Windows/Types.hpp b/include/FlameIDE/Os/Windows/Types.hpp index d217a76c..8112aa83 100644 --- a/include/FlameIDE/Os/Windows/Types.hpp +++ b/include/FlameIDE/Os/Windows/Types.hpp @@ -229,7 +229,7 @@ struct OsThreadTaskTrait: public NonCreational { using Return = DWORD; using Argument = LPVOID; - using Task = Return(*)(Argument); + using Task = Return(WINAPI *)(Argument); }; struct OsMutexContext diff --git a/src/Os/Network/NetworkBase.cpp b/src/Os/Network/NetworkBase.cpp index 140796a3..ec4bc56a 100644 --- a/src/Os/Network/NetworkBase.cpp +++ b/src/Os/Network/NetworkBase.cpp @@ -4,6 +4,21 @@ #include +namespace flame_ide +{namespace os +{namespace network +{ +namespace // anonymous +{ + +NetworkBase::SocketType getSocketType(const Socket &socket) noexcept +{ + return static_cast(socket::getType(socket)); +}; + +} // namespace anonymous +}}} // namespace flame_ide::os::network + namespace flame_ide {namespace os {namespace network @@ -42,11 +57,11 @@ const NetworkBase::NativeCallbacks &NetworkBase::callbacks() noexcept callbacks.destroy = socket::destroy; callbacks.receivingBytesNumber = socket::receivingBytesNumber; callbacks.getIpv4 = socket::getIpv4; - callbacks.type = reinterpret_cast(socket::getType); + callbacks.type = getSocketType; callbacks.error = socket::getError; callbacks.isListener = socket::isListener; callbacks.isServer = socket::isServer; - return socketControl; + return callbacks; } (); return socketControl; } @@ -99,8 +114,8 @@ NetworkBase::SocketType NetworkBase::getType() const os::Status NetworkBase::getError() const { - os::Status status = socket::getError(socket); - return status; + os::Status localStatus = socket::getError(socket); + return localStatus; } bool NetworkBase::isServer() const diff --git a/src/Os/Tests/Async/Network/RegistrarTest.cpp b/src/Os/Tests/Async/Network/RegistrarTest.cpp index 6d6e55ce..715ae564 100644 --- a/src/Os/Tests/Async/Network/RegistrarTest.cpp +++ b/src/Os/Tests/Async/Network/RegistrarTest.cpp @@ -188,7 +188,7 @@ int RegistrarTest::udpClient() // server { - auto raii = templates::makeRaiiCaller( + auto raiiServer = templates::makeRaiiCaller( [&server, ®istar]() { registar.add(server); } , [&server, ®istar]() { registar.remove(server); } ); @@ -337,7 +337,7 @@ int RegistrarTest::tcpServer() int RegistrarTest::tcpClient() { - auto nativeControl = os::network::NetworkBase::callbacks; + const auto &callbacks = os::network::NetworkBase::callbacks(); os::network::TcpServer server{ port }; os::network::TcpClient client{ ipv4 }; @@ -368,7 +368,7 @@ int RegistrarTest::tcpClient() resultConnection = registar.popTcpServerAcception(); } IN_CASE_CHECK( - nativeControl().destroy(resultConnection.client) == os::STATUS_SUCCESS + callbacks.destroy(resultConnection.client) == os::STATUS_SUCCESS ); // Wait diff --git a/src/Os/Tests/Threads/ThreadFunctionsTest.cpp b/src/Os/Tests/Threads/ThreadFunctionsTest.cpp index b0f69f18..3896bba0 100644 --- a/src/Os/Tests/Threads/ThreadFunctionsTest.cpp +++ b/src/Os/Tests/Threads/ThreadFunctionsTest.cpp @@ -8,21 +8,27 @@ #include +#ifdef WINAPI +#define CALL WINAPI +#else +#define CALL +#endif + flame_ide::os::ThreadTaskTrait::Return -taskJoin(flame_ide::os::ThreadTaskTrait::Argument) +CALL taskJoin(flame_ide::os::ThreadTaskTrait::Argument) { return {}; } flame_ide::os::ThreadTaskTrait::Return -taskDetach(flame_ide::os::threads::Semaphore *semaphore) +CALL taskDetach(flame_ide::os::threads::Semaphore *semaphore) { semaphore->wait(); return {}; } flame_ide::os::ThreadTaskTrait::Return -taskWorking(flame_ide::os::threads::Spin *spin) +CALL taskWorking(flame_ide::os::threads::Spin *spin) { while (true) { @@ -87,7 +93,7 @@ auto createDetach() noexcept Semaphore semaphore; os::Status status = thread::create( - context, (os::ThreadTaskTrait::Task)(taskDetach), &semaphore + context, reinterpret_cast(taskDetach), &semaphore ); IN_CASE_CHECK(os::STATUS_SUCCESS == status); diff --git a/src/Os/Windows/Async/Network/CMakeLists.txt b/src/Os/Windows/Async/Network/CMakeLists.txt index 4484da3d..f5d5f93f 100644 --- a/src/Os/Windows/Async/Network/CMakeLists.txt +++ b/src/Os/Windows/Async/Network/CMakeLists.txt @@ -9,6 +9,9 @@ set(NAME_ALIAS "Os::Async::Network::${FLAME_PLATFORM}") set(INCLUDE_PATHS ${FLAME_INCLUDE_PATH}) set(DEPENDENCY_HEADER_TARGETS ${FLAME_NAMESPACE}::Os::Headers) +set(DEFINES + _WINSOCK_DEPRECATED_NO_WARNINGS=1 +) get_sources(FILE_LIST) flame_compile_library( @@ -20,6 +23,7 @@ flame_compile_library( "${FLAME_NAMESPACE}::${NAME_ALIAS}::Object" INDEPENDENT_OBJECT_ALIAS_NAME "${FLAME_NAMESPACE}::${NAME_ALIAS}::Object::Independ" + DEFINES ${DEFINES} NO_RTTI NO_EXCEPTIONS diff --git a/src/Os/Windows/Async/Network/EventCatcher.cpp b/src/Os/Windows/Async/Network/EventCatcher.cpp index 146d69cd..f008dad4 100644 --- a/src/Os/Windows/Async/Network/EventCatcher.cpp +++ b/src/Os/Windows/Async/Network/EventCatcher.cpp @@ -74,7 +74,7 @@ os::Status EventCatcher::enable(SocketDescriptor descriptor) noexcept auto socket = Socket{ descriptor, {} }; auto event = anonymous::Event::UNKNOWN; - const auto &control = os::network::NetworkBase::nativeControl(); + const auto &control = os::network::NetworkBase::callbacks(); const auto type = control.type(Socket{ descriptor, {} }); switch(type) { @@ -110,7 +110,7 @@ os::Status EventCatcher::enable(SocketDescriptor descriptor) noexcept descriptor, handle, MESSAGE_SOCKET, anonymous::value(event) ); if (result == SOCKET_ERROR) - result = -::GetLastError(); + result = -static_cast(::GetLastError()); return result; } @@ -121,7 +121,7 @@ os::Status EventCatcher::disable(SocketDescriptor descriptor) noexcept return os::STATUS_FAILED; if (SOCKET_ERROR == ::WSAAsyncSelect(descriptor, handle, 0, 0)) - return -::GetLastError(); + return -static_cast(::GetLastError()); return os::STATUS_SUCCESS; } @@ -149,11 +149,12 @@ void EventCatcher::MessageDispatchThread::body() noexcept init(); - auto status = os::STATUS_SUCCESS; + auto localStatus = os::STATUS_SUCCESS; os::windows::OsMessage message = {}; - while ((status = ::GetMessageA(&message, window.handle, MESSAGE_VALUE_MIN, MESSAGE_VALUE_MAX))) + while (localStatus) { - if (status < 0) + localStatus = ::GetMessageA(&message, window.handle, MESSAGE_VALUE_MIN, MESSAGE_VALUE_MAX); + if (localStatus < 0) break; ::TranslateMessage(&message); @@ -275,7 +276,7 @@ EventCatcher::MessageDispatchThread::action( if ((message != Message::SOCKET) || (WSAGETSELECTERROR(param))) return ::DefWindowProcA(window, static_cast(message), descriptor, param); - const auto type = os::network::NetworkBase::nativeControl().type(Socket{ descriptor }); + const auto type = os::network::NetworkBase::callbacks().type(Socket{ descriptor }); switch(type) { case os::network::NetworkBase::SocketType::DATAGRAM: @@ -306,7 +307,7 @@ void EventCatcher::MessageDispatchThread::handleUdp( case anonymous::Event::READ: case anonymous::Event::WRITE: { - if (os::network::NetworkBase::nativeControl().isServer(Socket{ descriptor })) + if (os::network::NetworkBase::callbacks().isServer(Socket{ descriptor })) queues.udpServers().push(descriptor); else queues.udpClients().push(descriptor); @@ -330,7 +331,7 @@ void EventCatcher::MessageDispatchThread::handleTcp( case anonymous::Event::ACCEPT: { auto status = os::STATUS_SUCCESS; - auto client = os::network::TcpServer::nativeServerControl().accept( + auto client = os::network::TcpServer::callbacks().accept( Socket{ descriptor }, &status ); if (os::STATUS_SUCCESS == status) @@ -340,7 +341,7 @@ void EventCatcher::MessageDispatchThread::handleTcp( case anonymous::Event::READ: case anonymous::Event::WRITE: { - if (os::network::NetworkBase::nativeControl().isServer(Socket{ descriptor })) + if (os::network::NetworkBase::callbacks().isServer(Socket{ descriptor })) queues.tcpServers().push(descriptor); else queues.tcpClients().push(descriptor); From 2bbe0394f9577f132f2b8bb7dbd1ef1386b0e29c Mon Sep 17 00:00:00 2001 From: acidicMercury8 Date: Fri, 15 Mar 2024 23:20:03 +0300 Subject: [PATCH 2/7] Add Bitbucket Pipelines manifest --- bitbucket-pipelines.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 bitbucket-pipelines.yml diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml new file mode 100644 index 00000000..db0635e6 --- /dev/null +++ b/bitbucket-pipelines.yml @@ -0,0 +1,19 @@ +image: + name: gcc:12.3 + +clone: + depth: 1 + +pipelines: + default: + - step: + name: Configure project + script: + - cmake -S . -B build -G "Unix Makefiles" -D FLAME_CONAN_SUPPORT=OFF + - step: + name: Build project + script: + - cmake --build build --config Debug + - cmake --build build --config RelWithDebInfo + # artifacts: + # - build/** From 2438e74d4e25236e6a40d54f03bdf12cbceaa622 Mon Sep 17 00:00:00 2001 From: "U-EB855G7-WIN\\anton" Date: Sun, 17 Mar 2024 22:31:16 +0500 Subject: [PATCH 3/7] Configure pipelines --- bitbucket-pipelines.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml index db0635e6..0bad7b54 100644 --- a/bitbucket-pipelines.yml +++ b/bitbucket-pipelines.yml @@ -1,5 +1,5 @@ image: - name: gcc:12.3 + name: debian:bookworm-slim clone: depth: 1 @@ -7,13 +7,13 @@ clone: pipelines: default: - step: - name: Configure project + name: Install toolchain script: - - cmake -S . -B build -G "Unix Makefiles" -D FLAME_CONAN_SUPPORT=OFF - - step: - name: Build project - script: - - cmake --build build --config Debug - - cmake --build build --config RelWithDebInfo + - apt update + - apt install -y g++ cmake ninja-build git + - mkdir build + - cd build + - cmake -S .. -B . -GNinja -DFLAME_CONAN_SUPPORT=OFF -DCMAKE_BUILD_TYPE=Release + - cmake --build . # artifacts: # - build/** From 772ae8edeb6d9725930f2943fc8ced4748920d6a Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Thu, 23 May 2024 03:37:33 +0500 Subject: [PATCH 4/7] Common: add VoidType and VoidMaker (#7) --- include/FlameIDE/Common/Traits/Defaults.hpp | 12 +++++++ src/Common/Tests/Sources.cmake | 2 ++ src/Common/Tests/TestAggregator.cpp | 2 ++ src/Common/Tests/VoidTypeTest.cpp | 35 +++++++++++++++++++++ src/Common/Tests/VoidTypeTest.hpp | 25 +++++++++++++++ 5 files changed, 76 insertions(+) create mode 100644 src/Common/Tests/VoidTypeTest.cpp create mode 100644 src/Common/Tests/VoidTypeTest.hpp diff --git a/include/FlameIDE/Common/Traits/Defaults.hpp b/include/FlameIDE/Common/Traits/Defaults.hpp index 8a8e01f9..74e47ead 100644 --- a/include/FlameIDE/Common/Traits/Defaults.hpp +++ b/include/FlameIDE/Common/Traits/Defaults.hpp @@ -291,6 +291,18 @@ using AddVolatileType = typename AddVolatileTrait::Type; /// class Empty {}; +/// +/// Make VoidType +/// +template +struct VoidMaker +{ + using Type = void; +}; + +template +using VoidType = typename VoidMaker::Type; + } #endif // FLAMEIDE_COMMON_TRAITS_DEFAULTS_HPP diff --git a/src/Common/Tests/Sources.cmake b/src/Common/Tests/Sources.cmake index 39589de9..3e585535 100644 --- a/src/Common/Tests/Sources.cmake +++ b/src/Common/Tests/Sources.cmake @@ -5,5 +5,7 @@ set (SOURCE_LIST ${CMAKE_CURRENT_SOURCE_DIR}/TestAggregator.hpp ${CMAKE_CURRENT_SOURCE_DIR}/UtilsTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/UtilsTest.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/VoidTypeTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/VoidTypeTest.hpp ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp ) diff --git a/src/Common/Tests/TestAggregator.cpp b/src/Common/Tests/TestAggregator.cpp index 98aaa669..eef69d18 100644 --- a/src/Common/Tests/TestAggregator.cpp +++ b/src/Common/Tests/TestAggregator.cpp @@ -1,5 +1,6 @@ #include #include +#include #include @@ -12,6 +13,7 @@ TestAggregator::TestAggregator() : ::TestAggregator("Common") { pushBackTest(std::make_shared()); pushBackTest(std::make_shared()); + pushBackTest(std::make_shared()); } }}} // namespace flame_ide::common::tests diff --git a/src/Common/Tests/VoidTypeTest.cpp b/src/Common/Tests/VoidTypeTest.cpp new file mode 100644 index 00000000..8a5ccfc9 --- /dev/null +++ b/src/Common/Tests/VoidTypeTest.cpp @@ -0,0 +1,35 @@ +#include + +namespace flame_ide +{namespace common +{namespace tests +{ + +struct ExistMember +{ + int member = 0; +}; + +struct NotExistMember +{}; + +template> +struct HasMemember: public FalseType +{}; + +template +struct HasMemember>: public TrueType +{}; + +VoidTypeTest::VoidTypeTest() : AbstractTest("VoidType") +{} + +VoidTypeTest::~VoidTypeTest() = default; + +int VoidTypeTest::vStart() +{ + IN_CASE_CHECK(HasMemember::VALUE == TrueType::VALUE); + IN_CASE_CHECK_END(HasMemember::VALUE == FalseType::VALUE); +} + +}}} // flame_ide::common::tests diff --git a/src/Common/Tests/VoidTypeTest.hpp b/src/Common/Tests/VoidTypeTest.hpp new file mode 100644 index 00000000..1cb57677 --- /dev/null +++ b/src/Common/Tests/VoidTypeTest.hpp @@ -0,0 +1,25 @@ +#ifndef FLAMEIDE_COMMON_TESTS_VOIDTYPETEST_HPP +#define FLAMEIDE_COMMON_TESTS_VOIDTYPETEST_HPP + +#include + +#include + +namespace flame_ide +{namespace common +{namespace tests +{ + +class VoidTypeTest: public AbstractTest +{ +public: + VoidTypeTest(); + virtual ~VoidTypeTest(); + +private: + virtual int vStart(); +}; + +}}} // flame_ide::common::tests + +#endif // FLAMEIDE_COMMON_TESTS_VOIDTYPETEST_HPP From 80710e0ae7f9cbf2522fd331d100d918ac905559 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Sun, 30 Jun 2024 04:25:31 +0500 Subject: [PATCH 5/7] Refactoring and fix async network test (#8) --- src/Os/Tests/Async/Network/RegistrarTest.cpp | 55 +--- src/Os/Tests/Threads/UtilsTest.cpp | 8 +- src/Os/Threads/Utils.cpp | 3 +- src/Os/Windows/Async/Network/EventCatcher.cpp | 280 +----------------- src/Os/Windows/Async/Network/EventCatcher.hpp | 45 +-- src/Os/Windows/Async/Network/Headers.cmake | 1 + .../Async/Network/MessageDispatchThread.cpp | 249 ++++++++++++++++ .../Async/Network/MessageDispatchThread.hpp | 88 ++++++ src/Os/Windows/Async/Network/Sources.cmake | 1 + 9 files changed, 367 insertions(+), 363 deletions(-) create mode 100644 src/Os/Windows/Async/Network/MessageDispatchThread.cpp create mode 100644 src/Os/Windows/Async/Network/MessageDispatchThread.hpp diff --git a/src/Os/Tests/Async/Network/RegistrarTest.cpp b/src/Os/Tests/Async/Network/RegistrarTest.cpp index 715ae564..2997c727 100644 --- a/src/Os/Tests/Async/Network/RegistrarTest.cpp +++ b/src/Os/Tests/Async/Network/RegistrarTest.cpp @@ -28,48 +28,21 @@ namespace anonymous class NotificatorTest: public NotificatorBase { public: - threads::ConditionVariable &condition() noexcept + bool isNotified() const { - return condvar; + os::threads::Locker{ mutex }; + return notification; } - private: virtual void operator()() const noexcept override { - condvar.notify(); + os::threads::Locker{ mutex }; + notification = true; } private: + mutable bool notification = false; mutable threads::Mutex mutex; - mutable threads::ConditionVariable condvar{ mutex }; -}; - -class NotificationTestThread: public threads::ThreadCrtp -{ -public: - NotificationTestThread(threads::ConditionVariable &initCondvar) : - condvar{ &initCondvar } - {} - - void body() noexcept - { - condvar->wait(); - { - threads::Locker locker{ mutex }; - notified = true; - } - } - - bool isNotified() const - { - threads::Locker locker{ mutex }; - return notified; - } - -private: - threads::ConditionVariable *condvar = nullptr; - mutable threads::Mutex mutex; - bool notified = false; }; }} // namespace anonymous @@ -154,7 +127,10 @@ int RegistrarTest::udpServer() // Wait os::SocketDescriptor resultDescriptor = os::SOCKET_INVALID.descriptor; - for (auto i = numberOfTries; i != 0 && os::SOCKET_INVALID.descriptor == resultDescriptor; --i) + for (auto i = numberOfTries + ; i != 0 && os::SOCKET_INVALID.descriptor == resultDescriptor + ; --i + ) { resultDescriptor = registar.popUdpServer(); } @@ -390,9 +366,6 @@ int RegistrarTest::udpNotify() anonymous::NotificatorTest notificator; - anonymous::NotificationTestThread thread{ notificator.condition() }; - thread.run(); - Registrar registar; registar.setNotificator(notificator); @@ -409,7 +382,10 @@ int RegistrarTest::udpNotify() // Wait os::SocketDescriptor resultDescriptor = os::SOCKET_INVALID.descriptor; - for (auto i = numberOfTries; i != 0 && os::SOCKET_INVALID.descriptor == resultDescriptor; --i) + for (auto i = numberOfTries + ; i != 0 && os::SOCKET_INVALID.descriptor == resultDescriptor + ; --i + ) { resultDescriptor = registar.popUdpServer(); } @@ -437,8 +413,7 @@ int RegistrarTest::udpNotify() } ); - thread.join(); - IN_CASE_CHECK(thread.isNotified() == true); + IN_CASE_CHECK(notificator.isNotified() == true); return RegistrarTest::SUCCESS; } diff --git a/src/Os/Tests/Threads/UtilsTest.cpp b/src/Os/Tests/Threads/UtilsTest.cpp index 430fada9..bfa78f71 100644 --- a/src/Os/Tests/Threads/UtilsTest.cpp +++ b/src/Os/Tests/Threads/UtilsTest.cpp @@ -28,13 +28,13 @@ int check(LockPrimrtive &primitive) { UniqueLocker uniqueLocker{ primitive, UniqueLocker::LOCK }; IN_CASE_CHECK(uniqueLocker.getStatus() == os::STATUS_SUCCESS); - IN_CASE_CHECK(uniqueLocker.tryLock() == false); + IN_CASE_CHECK(uniqueLocker.tryLock() == true); } IN_CASE_CHECK(primitive.getStatus() == os::STATUS_SUCCESS); { UniqueLocker uniqueLocker{ primitive, UniqueLocker::TRY_LOCK }; IN_CASE_CHECK(uniqueLocker.getStatus() == os::STATUS_SUCCESS); - IN_CASE_CHECK(uniqueLocker.tryLock() == false); + IN_CASE_CHECK(uniqueLocker.tryLock() == true); } IN_CASE_CHECK(primitive.getStatus() == os::STATUS_SUCCESS); { @@ -49,7 +49,7 @@ int check(LockPrimrtive &primitive) } IN_CASE_CHECK(primitive.getStatus() == os::STATUS_SUCCESS); - return ::AbstractTest::SUCCESS; + return ResultType::SUCCESS; } }}}} // flame_ide::os::threads::tests @@ -60,7 +60,7 @@ namespace flame_ide {namespace tests { -UtilsTest::UtilsTest() : ::AbstractTest("Thread Utils") +UtilsTest::UtilsTest() : ::AbstractTest("ThreadUtils") {} int UtilsTest::vStart() diff --git a/src/Os/Threads/Utils.cpp b/src/Os/Threads/Utils.cpp index 386b63b1..1105bc25 100644 --- a/src/Os/Threads/Utils.cpp +++ b/src/Os/Threads/Utils.cpp @@ -192,7 +192,8 @@ os::Status UniqueLocker::lock() noexcept bool UniqueLocker::tryLock() noexcept { - locked = callbackTryLock(data); + if (!locked) + locked = callbackTryLock(data); return locked; } diff --git a/src/Os/Windows/Async/Network/EventCatcher.cpp b/src/Os/Windows/Async/Network/EventCatcher.cpp index f008dad4..1f2d370a 100644 --- a/src/Os/Windows/Async/Network/EventCatcher.cpp +++ b/src/Os/Windows/Async/Network/EventCatcher.cpp @@ -5,44 +5,6 @@ #include -namespace flame_ide -{namespace os -{namespace windows -{namespace async -{namespace network -{namespace anonymous{ namespace{ - -const char WINDOW_CLASS_NAME[] = "AsyncSelect"; - -enum class Event -{ - UNKNOWN = -1 - , ACCEPT = FD_ACCEPT - , CONNECT = FD_CONNECT - , READ = FD_READ - , WRITE = FD_WRITE - , CLOSE = FD_CLOSE -}; - -inline Event event(os::windows::OsParam param) -{ - return static_cast(WSAGETSELECTEVENT(param)); -} - -inline auto value(Event event) -> decltype(FD_ACCEPT) -{ - using EventValue = decltype(FD_ACCEPT); - return static_cast(event); -} - -inline Event operator|(Event event1, Event event2) -{ - return static_cast(value(event1) | value(event2)); -} - -}} // namespace anonymous -}}}}} // namespace flame_ide::os::windows::async::network - namespace flame_ide {namespace os {namespace windows @@ -72,26 +34,25 @@ EventCatcher::~EventCatcher() noexcept os::Status EventCatcher::enable(SocketDescriptor descriptor) noexcept { auto socket = Socket{ descriptor, {} }; - auto event = anonymous::Event::UNKNOWN; + auto event = Event::UNKNOWN; const auto &control = os::network::NetworkBase::callbacks(); const auto type = control.type(Socket{ descriptor, {} }); switch(type) { case os::network::NetworkBase::SocketType::DATAGRAM: - event = anonymous::Event::READ | anonymous::Event::WRITE; + event = Event::READ | Event::WRITE; break; case os::network::NetworkBase::SocketType::STREAM: { if (control.isListener(socket)) - event = anonymous::Event::ACCEPT; + event = Event::ACCEPT; else if (control.isServer) - event = anonymous::Event::READ | anonymous::Event::WRITE; + event = Event::READ | Event::WRITE; else - event = anonymous::Event::READ | anonymous::Event::WRITE - | anonymous::Event::CONNECT; + event = Event::READ | Event::WRITE | Event::CONNECT; break; } @@ -106,9 +67,7 @@ os::Status EventCatcher::enable(SocketDescriptor descriptor) noexcept constexpr auto MESSAGE_SOCKET = static_cast(Message::SOCKET); os::Status result = os::STATUS_SUCCESS; - result = ::WSAAsyncSelect( - descriptor, handle, MESSAGE_SOCKET, anonymous::value(event) - ); + result = ::WSAAsyncSelect(descriptor, handle, MESSAGE_SOCKET, value(event)); if (result == SOCKET_ERROR) result = -static_cast(::GetLastError()); return result; @@ -127,233 +86,6 @@ os::Status EventCatcher::disable(SocketDescriptor descriptor) noexcept }}}}} // namespace flame_ide::os::windows::async::network -// MessageDispatchThread -namespace flame_ide -{namespace os -{namespace windows -{namespace async -{namespace network -{ - -// public - thread - -EventCatcher::MessageDispatchThread::MessageDispatchThread() noexcept -{} - -void EventCatcher::MessageDispatchThread::body() noexcept -{ - constexpr auto MESSAGE_VALUE_MIN = static_cast(Message::SOCKET); - constexpr auto MESSAGE_VALUE_MAX = static_cast(Message::FINISH); - - constexpr auto MESSAGE_FINISH = static_cast(Message::FINISH); - - init(); - - auto localStatus = os::STATUS_SUCCESS; - os::windows::OsMessage message = {}; - while (localStatus) - { - localStatus = ::GetMessageA(&message, window.handle, MESSAGE_VALUE_MIN, MESSAGE_VALUE_MAX); - if (localStatus < 0) - break; - - ::TranslateMessage(&message); - if (MESSAGE_FINISH == message.message) - { - ::PostQuitMessage(0); - break; - } - ::DispatchMessageA(&message); - } - - destroy(); -} - -// public - api - -const os::windows::OsWindow & -EventCatcher::MessageDispatchThread::getWindow() const noexcept -{ - os::threads::Locker lock{ spin }; - return window; -} - -void EventCatcher::MessageDispatchThread::wait() const noexcept -{ - while (!isWindowInited()); -} - -void EventCatcher::MessageDispatchThread::stop() noexcept -{ - constexpr auto FINISH_MESSAGE = static_cast(Message::FINISH); - if (getWindow().handle) - ::PostMessageA(window.handle, FINISH_MESSAGE, {}, {}); -} - -// private - help - -void EventCatcher::MessageDispatchThread::init() noexcept -{ - os::threads::Locker lock{ spin }; - window = EventCatcher::MessageDispatchThread::makeWindow(anonymous::WINDOW_CLASS_NAME); - started = true; - if (!window.handle) - return; -} - -void EventCatcher::MessageDispatchThread::destroy() noexcept -{ - os::threads::Locker lock{ spin }; - EventCatcher::MessageDispatchThread::destroyWindow(window, anonymous::WINDOW_CLASS_NAME); -} - -bool EventCatcher::MessageDispatchThread::isWindowInited() const noexcept -{ - os::threads::Locker lock{ spin }; - return started; -} - -// private - WSA + static - -os::windows::OsWindow -EventCatcher::MessageDispatchThread::makeWindow(const char *className) noexcept -{ - if (!className) - return {}; - - os::windows::OsWindowClass windowsClass = {}; - windowsClass.style = CS_HREDRAW | CS_VREDRAW; - windowsClass.lpfnWndProc = reinterpret_cast( - MessageDispatchThread::action - ); - windowsClass.cbClsExtra = 0; - windowsClass.cbWndExtra = 0; - windowsClass.hInstance = nullptr; - windowsClass.hIcon = LoadIconA(nullptr, IDI_APPLICATION); - windowsClass.hCursor = LoadCursorA(nullptr, IDC_ARROW); - windowsClass.hbrBackground = reinterpret_cast( - GetStockObject(WHITE_BRUSH) - ); - windowsClass.lpszMenuName = nullptr; - windowsClass.lpszClassName = className; - const auto atom = ::RegisterClassA(&windowsClass); - if (!atom) - return os::windows::OsWindow{ - {}, static_cast(::GetLastError()) - }; - - auto handle = ::CreateWindowA( - className, nullptr, WS_OVERLAPPEDWINDOW - , CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT - , nullptr, nullptr, nullptr, nullptr - ); - if (!handle) - { - os::windows::OsWindow result{ - {}, static_cast(::GetLastError()) - }; - ::UnregisterClassA(className, nullptr); - return result; - } - auto window = os::windows::OsWindow{ handle, atom }; - return window; -} - -void EventCatcher::MessageDispatchThread::destroyWindow( - os::windows::OsWindow &window, const char *className -) -{ - ::DestroyWindow(window.handle); - ::UnregisterClassA(className, nullptr); -} - -os::windows::OsResult -EventCatcher::MessageDispatchThread::action( - os::windows::OsWindowHandle window, Message message, os::SocketDescriptor descriptor - , os::windows::OsParam param -) -{ - if ((message != Message::SOCKET) || (WSAGETSELECTERROR(param))) - return ::DefWindowProcA(window, static_cast(message), descriptor, param); - - const auto type = os::network::NetworkBase::callbacks().type(Socket{ descriptor }); - switch(type) - { - case os::network::NetworkBase::SocketType::DATAGRAM: - MessageDispatchThread::handleUdp(descriptor, param); - break; - - case os::network::NetworkBase::SocketType::STREAM: - MessageDispatchThread::handleTcp(descriptor, param); - break; - - case os::network::NetworkBase::SocketType::UNKNOWN: - default: - break; - } - EventCatcher::get().notify(); - - return ::DefWindowProcA(window, static_cast(message), descriptor, param); -} - -void EventCatcher::MessageDispatchThread::handleUdp( - os::SocketDescriptor descriptor, os::windows::OsParam param -) -{ - const auto event = anonymous::event(param); - auto &queues = EventCatcher::get().queues(); - switch (event) - { - case anonymous::Event::READ: - case anonymous::Event::WRITE: - { - if (os::network::NetworkBase::callbacks().isServer(Socket{ descriptor })) - queues.udpServers().push(descriptor); - else - queues.udpClients().push(descriptor); - return; - } - default: - return; - } -} - -void EventCatcher::MessageDispatchThread::handleTcp( - os::SocketDescriptor descriptor, os::windows::OsParam param -) -{ - flame_ide::unused(descriptor); - - const auto event = anonymous::event(param); - auto &queues = EventCatcher::get().queues(); - switch (event) - { - case anonymous::Event::ACCEPT: - { - auto status = os::STATUS_SUCCESS; - auto client = os::network::TcpServer::callbacks().accept( - Socket{ descriptor }, &status - ); - if (os::STATUS_SUCCESS == status) - queues.tcpAcceptedConnections().push({ descriptor, client }); - return; - } - case anonymous::Event::READ: - case anonymous::Event::WRITE: - { - if (os::network::NetworkBase::callbacks().isServer(Socket{ descriptor })) - queues.tcpServers().push(descriptor); - else - queues.tcpClients().push(descriptor); - return; - } - default: - return; - } -} - -}}}}} // namespace flame_ide::os::windows::async::network - namespace flame_ide {namespace os {namespace async diff --git a/src/Os/Windows/Async/Network/EventCatcher.hpp b/src/Os/Windows/Async/Network/EventCatcher.hpp index 9df0a476..e10d35f5 100644 --- a/src/Os/Windows/Async/Network/EventCatcher.hpp +++ b/src/Os/Windows/Async/Network/EventCatcher.hpp @@ -2,6 +2,7 @@ #define WINDOWS_ASYNC_NETWORK_EVENTCATCHER_HPP #include +#include #include #include @@ -23,50 +24,6 @@ class EventCatcher: public os::async::network::EventCatcherBase virtual os::Status enable(SocketDescriptor descriptor) noexcept override; virtual os::Status disable(SocketDescriptor descriptor) noexcept override; -private: - using MessageValue = Types::uint_t; - enum class Message: MessageValue - { - SOCKET = WM_USER + 1 - , FINISH = SOCKET + 1 - }; - -private: - class MessageDispatchThread: public os::threads::ThreadCrtp - { - public: - MessageDispatchThread() noexcept; - - void body() noexcept; - - public: - const os::windows::OsWindow &getWindow() const noexcept; - void wait() const noexcept; - void stop() noexcept; - - private: - void init() noexcept; - void destroy() noexcept; - - bool isWindowInited() const noexcept; - - private: - static os::windows::OsWindow makeWindow(const char *className) noexcept; - static void destroyWindow(os::windows::OsWindow &window, const char *className); - - static os::windows::OsResult action( - os::windows::OsWindowHandle window, Message message, os::SocketDescriptor socket - , os::windows::OsParam param - ); - static void handleUdp(os::SocketDescriptor socket, os::windows::OsParam param); - static void handleTcp(os::SocketDescriptor socket, os::windows::OsParam param); - - private: - mutable os::threads::Spin spin; - os::windows::OsWindow window; - bool started = false; - }; - private: MessageDispatchThread thread; }; diff --git a/src/Os/Windows/Async/Network/Headers.cmake b/src/Os/Windows/Async/Network/Headers.cmake index 417bf8b4..77388f4c 100644 --- a/src/Os/Windows/Async/Network/Headers.cmake +++ b/src/Os/Windows/Async/Network/Headers.cmake @@ -1,3 +1,4 @@ set (HEADER_LIST ${CMAKE_CURRENT_SOURCE_DIR}/EventCatcher.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/MessageDispatchThread.hpp ) diff --git a/src/Os/Windows/Async/Network/MessageDispatchThread.cpp b/src/Os/Windows/Async/Network/MessageDispatchThread.cpp new file mode 100644 index 00000000..a9e6e240 --- /dev/null +++ b/src/Os/Windows/Async/Network/MessageDispatchThread.cpp @@ -0,0 +1,249 @@ +#include +#include + +#include +#include + +#include + +namespace flame_ide +{namespace os +{namespace windows +{namespace async +{namespace network +{namespace anonymous{ namespace{ + +constexpr char WINDOW_CLASS_NAME[] = "AsyncSelect"; + +}} // namespace anonymous +}}}}} // namespace flame_ide::os::windows::async::network + +namespace flame_ide +{namespace os +{namespace windows +{namespace async +{namespace network +{ + +// public - thread + +MessageDispatchThread::MessageDispatchThread() noexcept +{} + +void MessageDispatchThread::body() noexcept +{ + constexpr auto MESSAGE_VALUE_MIN = static_cast(Message::SOCKET); + constexpr auto MESSAGE_VALUE_MAX = static_cast(Message::FINISH); + + constexpr auto MESSAGE_FINISH = static_cast(Message::FINISH); + + init(); + + os::Status localStatus = 1; + os::windows::OsMessage message = {}; + while (localStatus) + { + localStatus = ::GetMessageA( + &message, window.handle, MESSAGE_VALUE_MIN, MESSAGE_VALUE_MAX + ); + if (localStatus < 0) + break; + + ::TranslateMessage(&message); + if (MESSAGE_FINISH == message.message) + { + ::PostQuitMessage(0); + break; + } + ::DispatchMessageA(&message); + } + + destroy(); +} + +// public - api + +const os::windows::OsWindow & +MessageDispatchThread::getWindow() const noexcept +{ + os::threads::Locker lock{ spin }; + return window; +} + +void MessageDispatchThread::wait() const noexcept +{ + while (!isWindowInited()); +} + +void MessageDispatchThread::stop() noexcept +{ + constexpr auto FINISH_MESSAGE = static_cast(Message::FINISH); + if (getWindow().handle) + ::PostMessageA(window.handle, FINISH_MESSAGE, {}, {}); +} + +// private - help + +void MessageDispatchThread::init() noexcept +{ + os::threads::Locker lock{ spin }; + window = MessageDispatchThread::makeWindow(anonymous::WINDOW_CLASS_NAME); + started = true; + if (!window.handle) + return; +} + +void MessageDispatchThread::destroy() noexcept +{ + os::threads::Locker lock{ spin }; + MessageDispatchThread::destroyWindow(window, anonymous::WINDOW_CLASS_NAME); +} + +bool MessageDispatchThread::isWindowInited() const noexcept +{ + os::threads::Locker lock{ spin }; + return started; +} + +// private - WSA + static + +os::windows::OsWindow MessageDispatchThread::makeWindow(const char *className) noexcept +{ + if (!className) + return {}; + + os::windows::OsWindowClass windowsClass = {}; + windowsClass.style = CS_HREDRAW | CS_VREDRAW; + windowsClass.lpfnWndProc = reinterpret_cast( + MessageDispatchThread::action + ); + windowsClass.cbClsExtra = 0; + windowsClass.cbWndExtra = 0; + windowsClass.hInstance = nullptr; + windowsClass.hIcon = LoadIconA(nullptr, IDI_APPLICATION); + windowsClass.hCursor = LoadCursorA(nullptr, IDC_ARROW); + windowsClass.hbrBackground = reinterpret_cast( + GetStockObject(WHITE_BRUSH) + ); + windowsClass.lpszMenuName = nullptr; + windowsClass.lpszClassName = className; + const auto atom = ::RegisterClassA(&windowsClass); + if (!atom) + return os::windows::OsWindow{ + {}, static_cast(::GetLastError()) + }; + + auto handle = ::CreateWindowA( + className, nullptr, WS_OVERLAPPEDWINDOW + , CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT + , nullptr, nullptr, nullptr, nullptr + ); + if (!handle) + { + os::windows::OsWindow result{ + {}, static_cast(::GetLastError()) + }; + ::UnregisterClassA(className, nullptr); + return result; + } + auto window = os::windows::OsWindow{ handle, atom }; + return window; +} + +void MessageDispatchThread::destroyWindow( + os::windows::OsWindow &window, const char *className +) +{ + ::DestroyWindow(window.handle); + ::UnregisterClassA(className, nullptr); +} + +os::windows::OsResult MessageDispatchThread::action( + os::windows::OsWindowHandle window, Message message + , os::SocketDescriptor descriptor, os::windows::OsParam param +) +{ + if ((message != Message::SOCKET) || (WSAGETSELECTERROR(param))) + return ::DefWindowProcA( + window, static_cast(message), descriptor, param + ); + + const auto type = os::network::NetworkBase::callbacks().type(Socket{ descriptor }); + switch(type) + { + case os::network::NetworkBase::SocketType::DATAGRAM: + MessageDispatchThread::handleUdp(descriptor, param); + break; + + case os::network::NetworkBase::SocketType::STREAM: + MessageDispatchThread::handleTcp(descriptor, param); + break; + + case os::network::NetworkBase::SocketType::UNKNOWN: + default: + break; + } + os::async::network::EventCatcherBase::get().notify(); + + return ::DefWindowProcA( + window, static_cast(message), descriptor, param + ); +} + +void MessageDispatchThread::handleUdp( + os::SocketDescriptor descriptor, os::windows::OsParam param +) +{ + const auto eventValue = event(param); + auto &queues = os::async::network::EventCatcherBase::get().queues(); + switch (eventValue) + { + case Event::READ: + case Event::WRITE: + { + if (os::network::NetworkBase::callbacks().isServer(Socket{ descriptor })) + queues.udpServers().push(descriptor); + else + queues.udpClients().push(descriptor); + return; + } + default: + return; + } +} + +void MessageDispatchThread::handleTcp( + os::SocketDescriptor descriptor, os::windows::OsParam param +) +{ + flame_ide::unused(descriptor); + + const auto eventValue = event(param); + auto &queues = os::async::network::EventCatcherBase::get().queues(); + switch (eventValue) + { + case Event::ACCEPT: + { + auto status = os::STATUS_SUCCESS; + auto client = os::network::TcpServer::callbacks().accept( + Socket{ descriptor }, &status + ); + if (os::STATUS_SUCCESS == status) + queues.tcpAcceptedConnections().push({ descriptor, client }); + return; + } + case Event::READ: + case Event::WRITE: + { + if (os::network::NetworkBase::callbacks().isServer(Socket{ descriptor })) + queues.tcpServers().push(descriptor); + else + queues.tcpClients().push(descriptor); + return; + } + default: + return; + } +} + +}}}}} // namespace flame_ide::os::windows::async::network diff --git a/src/Os/Windows/Async/Network/MessageDispatchThread.hpp b/src/Os/Windows/Async/Network/MessageDispatchThread.hpp new file mode 100644 index 00000000..1e2ce45a --- /dev/null +++ b/src/Os/Windows/Async/Network/MessageDispatchThread.hpp @@ -0,0 +1,88 @@ +#ifndef WINDOWS_ASYNC_NETWORK_MESSAGEDISPATCHTHREAD_HPP +#define WINDOWS_ASYNC_NETWORK_MESSAGEDISPATCHTHREAD_HPP + +#include +#include + +namespace flame_ide +{namespace os +{namespace windows +{namespace async +{namespace network +{ + +// Events + +enum class Event +{ + UNKNOWN = -1 + , ACCEPT = FD_ACCEPT + , CONNECT = FD_CONNECT + , READ = FD_READ + , WRITE = FD_WRITE + , CLOSE = FD_CLOSE +}; + +inline constexpr auto value(Event event) -> decltype(FD_ACCEPT) +{ + using EventValue = decltype(FD_ACCEPT); + return static_cast(event); +} + +inline constexpr Event event(os::windows::OsParam param) +{ + return static_cast(WSAGETSELECTEVENT(param)); +} + +inline constexpr Event operator|(Event event1, Event event2) +{ + return static_cast(value(event1) | value(event2)); +} + +// Messages + +using MessageValue = Types::uint_t; +enum class Message: MessageValue +{ + SOCKET = WM_USER + 1 + , FINISH = SOCKET + 1 +}; + +class MessageDispatchThread: public os::threads::ThreadCrtp +{ +public: + MessageDispatchThread() noexcept; + + void body() noexcept; + +public: + const os::windows::OsWindow &getWindow() const noexcept; + void wait() const noexcept; + void stop() noexcept; + +private: + void init() noexcept; + void destroy() noexcept; + + bool isWindowInited() const noexcept; + +private: + static os::windows::OsWindow makeWindow(const char *className) noexcept; + static void destroyWindow(os::windows::OsWindow &window, const char *className); + + static os::windows::OsResult action( + os::windows::OsWindowHandle window, Message message, os::SocketDescriptor socket + , os::windows::OsParam param + ); + static void handleUdp(os::SocketDescriptor socket, os::windows::OsParam param); + static void handleTcp(os::SocketDescriptor socket, os::windows::OsParam param); + +private: + mutable os::threads::Spin spin; + os::windows::OsWindow window; + bool started = false; +}; + +}}}}} // namespace flame_ide::os::windows::async::network + +#endif // WINDOWS_ASYNC_NETWORK_MESSAGEDISPATCHTHREAD_HPP diff --git a/src/Os/Windows/Async/Network/Sources.cmake b/src/Os/Windows/Async/Network/Sources.cmake index a24ed0e6..7ec877a9 100644 --- a/src/Os/Windows/Async/Network/Sources.cmake +++ b/src/Os/Windows/Async/Network/Sources.cmake @@ -1,3 +1,4 @@ set (SOURCE_LIST ${CMAKE_CURRENT_SOURCE_DIR}/EventCatcher.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/MessageDispatchThread.cpp ) From 9b96fb92a37cf3cef70311c97cf4475f4f16e7e2 Mon Sep 17 00:00:00 2001 From: Anton Kashcheev Date: Wed, 3 Jul 2024 22:52:19 +0500 Subject: [PATCH 6/7] Add pipelines for building project (#9) * Add GitHub Actions manifest * Fix compilation errors * Add todos to disabled shared tests for Os and Pkcs11 * Disabled Streams module Co-authored-by: Anton Kashcheev , acidicMercury8 --- .github/workflows/build-libraries.yml | 101 ++++++++++++++++++ CMakeLists.txt | 4 + include/FlameIDE/CMakeLists.txt | 2 +- include/FlameIDE/Common/Traits/Numbers.hpp | 2 +- include/FlameIDE/Common/Utils.hpp | 12 +-- .../Serialization/SpecializedValue.hpp | 2 +- src/CMakeLists.txt | 2 +- src/Crypto/Pkcs11/Tests/CMakeLists.txt | 5 +- src/Os/Tests/CMakeLists.txt | 5 +- src/Os/Windows/Network/SocketFunctions.cpp | 6 +- src/Templates/Tests/SerializationTest.cpp | 28 +++-- src/Templates/Tests/TestAggregator.cpp | 48 ++++----- tests/CMakeLists.txt | 2 +- 13 files changed, 165 insertions(+), 54 deletions(-) create mode 100644 .github/workflows/build-libraries.yml diff --git a/.github/workflows/build-libraries.yml b/.github/workflows/build-libraries.yml new file mode 100644 index 00000000..c49ba6f0 --- /dev/null +++ b/.github/workflows/build-libraries.yml @@ -0,0 +1,101 @@ +name: 'Build libraries' + +on: + push: + branches: + - '**' + paths: + - '.github/workflows/**' + - 'cmake/**' + - 'include/**' + - 'src/**' + - 'tests/**' + - '**/CMakeLists.txt' + - '**/*.pro' + pull_request: + branches: + - '**' + paths: + - '.github/workflows/**' + - 'cmake/**' + - 'include/**' + - 'src/**' + - 'tests/**' + - '**/CMakeLists.txt' + - '**/*.pro' + +defaults: + run: + shell: pwsh + +jobs: + build-libraries: + name: 'Build libraries' + + strategy: + matrix: + include: + - { system: windows-latest, config: Debug, cc: cl, cpp: cl } + - { system: windows-latest, config: Release, cc: cl, cpp: cl } + - { system: windows-latest, config: Debug, cc: gcc, cpp: g++ } + - { system: windows-latest, config: Release, cc: gcc, cpp: g++ } + - { system: ubuntu-latest, config: Debug, cc: gcc-11, cpp: g++-11 } + - { system: ubuntu-latest, config: Release, cc: gcc-11, cpp: g++-11} + - { system: ubuntu-latest, config: Debug, cc: clang-14, cpp: clang++-14 } + - { system: ubuntu-latest, config: Release, cc: clang-14, cpp: clang++-14 } + fail-fast: false + + runs-on: ${{ matrix.system }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Visual Studio Build Tools + uses: ilammy/msvc-dev-cmd@v1 + if: ${{ runner.os == 'Windows' && matrix.cc == 'cl' }} + + - name: Setup MSYS2 + uses: msys2/setup-msys2@v2 + if: ${{ runner.os == 'Windows' && matrix.cc == 'gcc' }} + with: + msystem: UCRT64 + update: true + install: mingw-w64-ucrt-x86_64-gcc + + - name: Setup GCC and Clang + if: ${{ runner.os == 'Linux' }} + run: | + sudo apt update && ` + sudo apt install -y ` + gcc-11 ` + g++-11 ` + clang-14 + + - name: Setup Ninja + uses: imesense/gha-setup-ninja@v0.2 + + - name: Configure project + run: | + cmake ` + -S . ` + -B build ` + -G "Ninja" ` + -DCMAKE_C_COMPILER=${{ matrix.cc }} ` + -DCMAKE_CXX_COMPILER=${{ matrix.cpp }} ` + -DFLAME_CONAN_SUPPORT=OFF ` + -DCMAKE_BUILD_TYPE=${{ matrix.config }} + + - name: Build project + run: | + cmake ` + --build build ` + --config ${{ matrix.config }} + + - name: Run tests + run: | + cmake ` + --build build ` + --target test diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f027206..c684e387 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,10 @@ flame_resolver_settings( PROJECT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR} LOCAL_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/install ) +if(FLAME_TESTING) + message(STATUS "Tests enabled") + enable_testing() +endif() add_subdirectory(${FLAME_INCLUDE_SUBMODLUES_PATH}) add_subdirectory(${FLAME_SOURCE_SUBMODLUES_PATH}) diff --git a/include/FlameIDE/CMakeLists.txt b/include/FlameIDE/CMakeLists.txt index 6aa7ea37..2c05b3a4 100644 --- a/include/FlameIDE/CMakeLists.txt +++ b/include/FlameIDE/CMakeLists.txt @@ -10,7 +10,7 @@ set(HEADER_MODULES ${FLAME_INCLUDE_SUBMODLUES_PATH}/Crypto ${FLAME_INCLUDE_SUBMODLUES_PATH}/Os ${FLAME_INCLUDE_SUBMODLUES_PATH}/Others - ${FLAME_INCLUDE_SUBMODLUES_PATH}/Streams + # ${FLAME_INCLUDE_SUBMODLUES_PATH}/Streams ${FLAME_INCLUDE_SUBMODLUES_PATH}/Templates ${FLAME_INCLUDE_SUBMODLUES_PATH}/Ubjson ) diff --git a/include/FlameIDE/Common/Traits/Numbers.hpp b/include/FlameIDE/Common/Traits/Numbers.hpp index 2f1df606..2c469236 100644 --- a/include/FlameIDE/Common/Traits/Numbers.hpp +++ b/include/FlameIDE/Common/Traits/Numbers.hpp @@ -218,7 +218,7 @@ constexpr auto IsUnsignedValue = IsUnsignedTrait::VALUE; /// template struct IsIntegralTrait: public IntegralConstant< - bool, IsPrimitiveValue && !IsFloatValue + bool, IsPrimitiveTrait::VALUE && !IsFloatTrait::VALUE > {}; diff --git a/include/FlameIDE/Common/Utils.hpp b/include/FlameIDE/Common/Utils.hpp index 52187db1..97210bec 100644 --- a/include/FlameIDE/Common/Utils.hpp +++ b/include/FlameIDE/Common/Utils.hpp @@ -159,18 +159,17 @@ template inline typename Container::ConstReverseIterator crend(const Container &container); template -Tt __implementation_decval__(int) noexcept; +Tt declareValueImpl(int) noexcept; template -T __implementation_decval__(long) noexcept; +T declareValueImpl(long) noexcept; /// /// @brief declareValue /// @tparam First param. /// template -decltype(__implementation_decval__) declareValue() noexcept; - +decltype(declareValueImpl(0)) declareValue() noexcept; /// /// @brief alignedPointer @@ -481,10 +480,9 @@ typename Container::SizeType size(const Container &container) } template -decltype(__implementation_decval__) declareValue() noexcept +decltype(declareValueImpl(0)) declareValue() noexcept { - static_assert(FalseType::VALUE, "It can't ba called"); - return __implementation_decval__(0); + return declareValueImpl(0); } template diff --git a/include/FlameIDE/Templates/Serialization/SpecializedValue.hpp b/include/FlameIDE/Templates/Serialization/SpecializedValue.hpp index a026df21..8bddc9cf 100644 --- a/include/FlameIDE/Templates/Serialization/SpecializedValue.hpp +++ b/include/FlameIDE/Templates/Serialization/SpecializedValue.hpp @@ -422,7 +422,7 @@ template typename ValueInfo::Iterator SpecializedValue::begin() { - return makeByteRange(getValue()).begin() + return makeByteRange(getValue()).begin() + sizeof(getValue()) - getSize() - getOffset(); } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4c906be6..a6842898 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,7 +6,7 @@ set(SOURCE_MODULES ${FLAME_SOURCE_SUBMODLUES_PATH}/Common ${FLAME_SOURCE_SUBMODLUES_PATH}/Crypto ${FLAME_SOURCE_SUBMODLUES_PATH}/Os - ${FLAME_SOURCE_SUBMODLUES_PATH}/Streams + # ${FLAME_SOURCE_SUBMODLUES_PATH}/Streams ${FLAME_SOURCE_SUBMODLUES_PATH}/Ubjson ) foreach(module ${SOURCE_MODULES}) diff --git a/src/Crypto/Pkcs11/Tests/CMakeLists.txt b/src/Crypto/Pkcs11/Tests/CMakeLists.txt index d2f33687..731e6a82 100644 --- a/src/Crypto/Pkcs11/Tests/CMakeLists.txt +++ b/src/Crypto/Pkcs11/Tests/CMakeLists.txt @@ -57,8 +57,9 @@ if(FLAME_TESTING) NO_RTTI EXCEPTIONS - TEST - TEST_ARGUMENTS "" + # TODO: need Resolver fix + #TEST + #TEST_ARGUMENTS "" ) endif() diff --git a/src/Os/Tests/CMakeLists.txt b/src/Os/Tests/CMakeLists.txt index f15d047d..a36c7ede 100644 --- a/src/Os/Tests/CMakeLists.txt +++ b/src/Os/Tests/CMakeLists.txt @@ -71,8 +71,9 @@ if(FLAME_MAKE_SHARED) NO_RTTI EXCEPTIONS - TEST - TEST_ARGUMENTS "" + # TODO: need Resolver fix + #TEST + #TEST_ARGUMENTS "" ) endif() diff --git a/src/Os/Windows/Network/SocketFunctions.cpp b/src/Os/Windows/Network/SocketFunctions.cpp index 4a7d8a7d..5c6067d5 100644 --- a/src/Os/Windows/Network/SocketFunctions.cpp +++ b/src/Os/Windows/Network/SocketFunctions.cpp @@ -41,7 +41,7 @@ namespace flame_ide namespace // anonymous { -::SOCKET udpСreateSocket() noexcept +::SOCKET udpCreateSocket() noexcept { return ::WSASocketW(AF_INET, SOCK_DGRAM, IPPROTO_UDP, nullptr, 0, WSA_FLAG_OVERLAPPED); } @@ -107,7 +107,7 @@ Socket createUdpServer(Ipv4::Port port) noexcept if (!winsockInit()) return socket; - socket = Socket{ udpСreateSocket(), ipAddressServer(port) }; + socket = Socket{ udpCreateSocket(), ipAddressServer(port) }; if (socket.descriptor == os::SOCKET_INVALID.descriptor) return os::SOCKET_INVALID; @@ -137,7 +137,7 @@ Socket createUdpClient(Ipv4 ipServer) noexcept if (!winsockInit()) return socket; - socket = Socket{ udpСreateSocket(), ipAddressClient(ipServer) }; + socket = Socket{ udpCreateSocket(), ipAddressClient(ipServer) }; if (socket.descriptor == os::SOCKET_INVALID.descriptor) return os::SOCKET_INVALID; return socket; diff --git a/src/Templates/Tests/SerializationTest.cpp b/src/Templates/Tests/SerializationTest.cpp index 2806b23f..cd015a30 100644 --- a/src/Templates/Tests/SerializationTest.cpp +++ b/src/Templates/Tests/SerializationTest.cpp @@ -20,10 +20,10 @@ using templates::CompileTimeReverseBytes; int SerializationTest::vStart() { - CHECK_RESULT_SUCCESS(le()); - CHECK_RESULT_SUCCESS(be()); - CHECK_RESULT_SUCCESS(leSpec()); - CHECK_RESULT_SUCCESS_END(beSpec()); + IN_CASE_CHECK(ResultType::SUCCESS == le()); + IN_CASE_CHECK(ResultType::SUCCESS == be()); + IN_CASE_CHECK(ResultType::SUCCESS == leSpec()); + IN_CASE_CHECK_END(ResultType::SUCCESS == beSpec()); } // LITTLE_ENDIAN_ORDER @@ -480,7 +480,8 @@ bool SerializationTest::beSpec64() | (Types::ulong_t(BYTES[5]) << 16) | (Types::ulong_t(BYTES[6]) << 8) | (Types::ulong_t(BYTES[7])); - templates::Vector vector(8); + templates::Vector vector; + vector.resize(8); CHECK_RESULT_SUCCESS(doTestCase( "be64 spec (LE numbers) serialize/deserialize" @@ -517,18 +518,23 @@ bool SerializationTest::beSpec64() auto serializer = templates::SerializerBe(&vector[0]); serializer(specValue64Be); - IN_CASE_CHECK(vector[0] == BYTES[2] - && vector[1] == BYTES[3] - && vector[2] == BYTES[4] - && vector[3] == BYTES[5] - && vector[4] == BYTES[6]); + IN_CASE_CHECK(vector[0] == BYTES[2]); + IN_CASE_CHECK(vector[1] == BYTES[3]); + IN_CASE_CHECK(vector[2] == BYTES[4]); + IN_CASE_CHECK(vector[3] == BYTES[5]); + IN_CASE_CHECK(vector[4] == BYTES[6]); auto deserializer = templates::DeserializerBe(&vector[0]); deserializer(resultValue64Be); auto range1 = templates::makeRange(specValue64Be.begin(), specValue64Be.end()); auto range2 = templates::makeRange(resultValue64Be.begin(), resultValue64Be.end()); - IN_CASE_CHECK_END(ResultType::SUCCESS == compareContainers(range1, range2)); + + IN_CASE_CHECK(*(range1.begin() + 0) == *(range2.begin() + 0)); + IN_CASE_CHECK(*(range1.begin() + 1) == *(range2.begin() + 1)); + IN_CASE_CHECK(*(range1.begin() + 2) == *(range2.begin() + 2)); + IN_CASE_CHECK(*(range1.begin() + 3) == *(range2.begin() + 3)); + IN_CASE_CHECK_END(*(range1.begin() + 4) == *(range2.begin() + 4)); } )); diff --git a/src/Templates/Tests/TestAggregator.cpp b/src/Templates/Tests/TestAggregator.cpp index 46a10ce0..72308ad5 100644 --- a/src/Templates/Tests/TestAggregator.cpp +++ b/src/Templates/Tests/TestAggregator.cpp @@ -19,7 +19,7 @@ #include #include #include -#include +// #include #include #include @@ -33,30 +33,30 @@ namespace flame_ide TestAggregator::TestAggregator() : ::TestAggregator("Templates") { - 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()); + // 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()); - 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()); + // pushBackTest(std::make_shared()); + // pushBackTest(std::make_shared()); + // pushBackTest(std::make_shared()); + // // pushBackTest(std::make_shared()); + // pushBackTest(std::make_shared()); } }}} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4f4a4c7e..080a255e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -7,7 +7,7 @@ endfunction(remove_source_dir) set(TEST_MODULES ${FLAME_SOURCE_SUBMODLUES_PATH}/Templates/Tests - ${FLAME_SOURCE_SUBMODLUES_PATH}/Streams/Tests + # ${FLAME_SOURCE_SUBMODLUES_PATH}/Streams/Tests ${FLAME_SOURCE_SUBMODLUES_PATH}/Common/Tests ${FLAME_SOURCE_SUBMODLUES_PATH}/Os/Tests ${FLAME_SOURCE_SUBMODLUES_PATH}/Crypto/Pkcs11/Tests From 4f42715853ae8b4c5f1b2de6f1e83a18add4977d Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 4 Sep 2024 01:49:57 +0300 Subject: [PATCH 7/7] Os/Async/Network: fix typo in static_assert() (#11) Now network module would work if SONETWORKCONN == 128. Co-authored-by: leha-bot --- src/Os/Async/Network/Config.hpp.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Os/Async/Network/Config.hpp.in b/src/Os/Async/Network/Config.hpp.in index 4d6f9040..2fa957d9 100644 --- a/src/Os/Async/Network/Config.hpp.in +++ b/src/Os/Async/Network/Config.hpp.in @@ -34,7 +34,7 @@ struct Config: public flame_ide::NonCreational # define SOMAXCONN1_STR(VALUE) #VALUE # define SOMAXCONN_STR(VALUE) SOMAXCONN1_STR(VALUE) static_assert( - TCP_SERVER_BACKLOG < flame_ide::os::SOCKET_TCP_MAX_CLIENTS + TCP_SERVER_BACKLOG <= flame_ide::os::SOCKET_TCP_MAX_CLIENTS , "Generated server backlog more than SOMAXCONN = " SOMAXCONN_STR(SOMAXCONN) ); # undef SOMAXCONN_STR