From 3a4199123743456e2a2e014fa7ffe8cf5038d950 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Mon, 1 Feb 2021 11:31:42 +0100 Subject: [PATCH 001/143] iox-#350 added event variable interfaces Signed-off-by: Christian Eltzschig --- .../popo/building_blocks/event_listener.hpp | 50 +++++++++++++++++++ .../popo/building_blocks/event_notifier.hpp | 40 +++++++++++++++ .../building_blocks/event_variable_data.hpp | 36 +++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp create mode 100644 iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp create mode 100644 iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp new file mode 100644 index 00000000000..4aa9343094d --- /dev/null +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp @@ -0,0 +1,50 @@ +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_LISTENER_HPP +#define IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_LISTENER_HPP + +#include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" +#include "iceoryx_utils/cxx/vector.hpp" +#include "iceoryx_utils/internal/units/duration.hpp" + +#include + +namespace iox +{ +namespace popo +{ +class EventListener +{ + public: + EventListener(EventVariableData& dataRef) noexcept + { + } + + cxx::vector wait() noexcept + { + } + + cxx::vector timedWait(const units::Duration timeToWait) noexcept + { + } + + void reset(const uint64_t index) noexcept + { + } +}; +} // namespace popo +} // namespace iox + +#endif diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp new file mode 100644 index 00000000000..fd76f169267 --- /dev/null +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp @@ -0,0 +1,40 @@ +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_NOTIFIER_HPP +#define IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_NOTIFIER_HPP + +#include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" + +#include + +namespace iox +{ +namespace popo +{ +class EventNotifier +{ + public: + EventNotifier(EventVariableData& dataRef, const uint64_t index) noexcept + { + } + void notify() + { + } +}; +} // namespace popo +} // namespace iox + +#endif + diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp new file mode 100644 index 00000000000..d5b306fde1a --- /dev/null +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp @@ -0,0 +1,36 @@ +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_VARIABLE_DATA_HPP +#define IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_VARIABLE_DATA_HPP + +#include "iceoryx_utils/cxx/vector.hpp" + +#include + +namespace iox +{ +namespace popo +{ +class EventVariableData +{ + public: + private: + cxx::vector m_activeNotifications; +}; +} // namespace popo +} // namespace iox + +#endif + From eb3befa94601eb5b7133f0278b2865c9773d1ec2 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Mon, 1 Feb 2021 11:35:16 +0100 Subject: [PATCH 002/143] iox-#350 added interface to acquire event variable from shm Signed-off-by: Christian Eltzschig --- .../internal/popo/building_blocks/event_variable_data.hpp | 5 ++--- iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp | 6 ++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp index d5b306fde1a..3f1953a2bcf 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp @@ -15,6 +15,7 @@ #ifndef IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_VARIABLE_DATA_HPP #define IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_VARIABLE_DATA_HPP +#include "iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp" #include "iceoryx_utils/cxx/vector.hpp" #include @@ -23,10 +24,8 @@ namespace iox { namespace popo { -class EventVariableData +struct EventVariableData : public ConditionVariableData { - public: - private: cxx::vector m_activeNotifications; }; } // namespace popo diff --git a/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp b/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp index d54c3b5b791..376cc5f44d5 100644 --- a/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp +++ b/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp @@ -17,6 +17,7 @@ #include "iceoryx_posh/capro/service_description.hpp" #include "iceoryx_posh/iceoryx_posh_types.hpp" #include "iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp" +#include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" #include "iceoryx_posh/internal/popo/ports/application_port.hpp" #include "iceoryx_posh/internal/popo/ports/interface_port.hpp" #include "iceoryx_posh/internal/popo/ports/publisher_port_user.hpp" @@ -123,6 +124,11 @@ class PoshRuntime /// @return pointer to a created condition variable data popo::ConditionVariableData* getMiddlewareConditionVariable() noexcept; + popo::EventVariableData* getMiddlewareEventVariable() noexcept + { + return nullptr; + } + /// @brief request the RouDi daemon to create a node /// @param[in] nodeProperty class which contains all properties which the node should have /// @return pointer to the data of the node From 425ab87224681c84160335b91cfb43e45b0120d2 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Mon, 1 Feb 2021 11:51:15 +0100 Subject: [PATCH 003/143] iox-#350 added ActiveCallSet properties to posh types Signed-off-by: Christian Eltzschig --- iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp b/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp index 3b0876757ca..7169f4d2a68 100644 --- a/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp +++ b/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp @@ -104,6 +104,9 @@ constexpr uint32_t MAX_REQUEST_QUEUE_CAPACITY = 1024; // Waitset constexpr uint32_t MAX_NUMBER_OF_CONDITION_VARIABLES = 1024U; constexpr uint32_t MAX_NUMBER_OF_EVENTS_PER_WAITSET = 128U; +// ActiveCallSet +constexpr uint32_t MAX_NUMBER_OF_EVENT_VARIABLES = 128U; +constexpr uint32_t MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET = 128U; //--------- Communication Resources End--------------------- constexpr uint32_t MAX_APPLICATION_CAPRO_FIFO_SIZE = 128U; From fdca8db47b3b62792c0ffbdb16a3a43db2715988 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Mon, 1 Feb 2021 15:22:53 +0100 Subject: [PATCH 004/143] iox-#350 added forEach construct in helplets Signed-off-by: Christian Eltzschig --- iceoryx_posh/source/popo/active_call_set.cpp | 0 .../include/iceoryx_utils/cxx/helplets.hpp | 14 ++++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 iceoryx_posh/source/popo/active_call_set.cpp diff --git a/iceoryx_posh/source/popo/active_call_set.cpp b/iceoryx_posh/source/popo/active_call_set.cpp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp index fba53603842..edd8a4064de 100644 --- a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp +++ b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp @@ -178,6 +178,20 @@ auto enumTypeAsUnderlyingType(enum_type const value) -> typename std::underlying return static_cast::type>(value); } +/// calls a given functor for every element in a given container +/// @tparam[in] Container type which must be iteratable +/// @tparam[in] Functor which has one argument, the element type of the container +/// @param[in] c container which should be iterated +/// @param[in] f functor which should be applied to every element +template +void forEach(Container& c, const Functor& f) noexcept +{ + for (auto& element : c) + { + f(element); + } +} + /// @brief Get the size of a string represented by a char array at compile time. /// @tparam The size of the char array filled out by the compiler. /// @param[in] The actual content of the char array is not of interest. Its just the size of the array that matters. From 79357d9d449e392905631478e9804ccd3fcb2c11 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Mon, 1 Feb 2021 15:23:18 +0100 Subject: [PATCH 005/143] iox-#350 implemented first ActiveCallSet draft Signed-off-by: Christian Eltzschig --- iceoryx_meta/CMakeLists.txt | 1 + iceoryx_posh/CMakeLists.txt | 5 +- .../iceoryx_posh/popo/active_call_set.hpp | 114 ++++++++++++++ iceoryx_posh/source/popo/active_call_set.cpp | 148 ++++++++++++++++++ 4 files changed, 266 insertions(+), 2 deletions(-) create mode 100644 iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp diff --git a/iceoryx_meta/CMakeLists.txt b/iceoryx_meta/CMakeLists.txt index 17a5cc68f51..cd35ad5aac7 100644 --- a/iceoryx_meta/CMakeLists.txt +++ b/iceoryx_meta/CMakeLists.txt @@ -63,6 +63,7 @@ if(EXAMPLES) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../iceoryx_examples/iceperf ${CMAKE_BINARY_DIR}/iceoryx_examples/iceperf) endif() add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../iceoryx_examples/waitset ${CMAKE_BINARY_DIR}/iceoryx_examples/waitset) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../iceoryx_examples/callbacks ${CMAKE_BINARY_DIR}/iceoryx_examples/callbacks) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../iceoryx_examples/singleprocess ${CMAKE_BINARY_DIR}/iceoryx_examples/singleprocess) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../iceoryx_examples/ice_multi_publisher ${CMAKE_BINARY_DIR}/iceoryx_examples/ice_multi_publisher) endif() diff --git a/iceoryx_posh/CMakeLists.txt b/iceoryx_posh/CMakeLists.txt index 5faa647fd7d..633b614e54a 100644 --- a/iceoryx_posh/CMakeLists.txt +++ b/iceoryx_posh/CMakeLists.txt @@ -102,10 +102,11 @@ add_library(iceoryx_posh source/popo/building_blocks/condition_variable_waiter.cpp source/popo/building_blocks/locking_policy.cpp source/popo/building_blocks/typed_unique_id.cpp - source/popo/user_trigger.cpp + source/popo/active_call_set.cpp + source/popo/event_info.cpp source/popo/trigger.cpp source/popo/trigger_handle.cpp - source/popo/event_info.cpp + source/popo/user_trigger.cpp source/version/version_info.cpp source/runtime/message_queue_interface.cpp source/runtime/message_queue_message.cpp diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp new file mode 100644 index 00000000000..a4385892c21 --- /dev/null +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -0,0 +1,114 @@ +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef IOX_POSH_POPO_ACTIVE_CALL_SET_HPP +#define IOX_POSH_POPO_ACTIVE_CALL_SET_HPP + +#include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" +#include "iceoryx_utils/cxx/expected.hpp" +#include "iceoryx_utils/cxx/types.hpp" +#include "iceoryx_utils/internal/concurrent/loffli.hpp" + +#include +#include + +namespace iox +{ +namespace popo +{ +enum class ActiveCallSetError +{ + +}; + +class ActiveCallSet +{ + public: + template + using Callback_t = void (*)(T* const); + + ActiveCallSet() noexcept; + ~ActiveCallSet(); + + + template + cxx::expected attachEvent(T& eventOrigin, const Callback_t& eventCallback) noexcept + { + return cxx::success<>(); + } + + template ::value>> + cxx::expected + attachEvent(T& eventOrigin, const EventType eventType, const Callback_t& eventCallback) noexcept + { + return cxx::success<>(); + } + + template ::value>> + cxx::expected detachEvent(T& eventOrigin, const EventType eventType) noexcept + { + return cxx::success<>(); + } + + template + cxx::expected detachEvent(T& eventOrigin) noexcept + { + return cxx::success<>(); + } + + private: + struct Event_t; + + void threadLoop() noexcept; + void addEvent(void* const origin, const uint64_t eventType, const Callback_t callback) noexcept; + void removeEvent(void* const origin, const uint64_t eventType) noexcept; + + private: + enum class CallbackState + { + INACTIVE, + ACTIVE, + DELETED, + }; + + struct Event_t + { + bool isEqualTo(const void* const origin, const uint64_t eventType) const noexcept; + void reset() noexcept; + void init(void* const origin, const uint64_t eventType, const Callback_t callback) noexcept; + void set(void* const origin, const uint64_t eventType, const Callback_t callback) noexcept; + void operator()() noexcept; + + void* m_origin = nullptr; + uint64_t m_eventType = 0U; + std::atomic m_setCounter{0U}; + + Callback_t m_callback = nullptr; + std::atomic m_callbackState{CallbackState::DELETED}; + }; + + std::thread m_thread; + Event_t m_events[MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET]; + + std::atomic_bool m_wasDtorCalled{false}; + EventVariableData* m_eventVariable = nullptr; + + uint32_t m_loffliStorage[concurrent::LoFFLi::requiredMemorySize(MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET) + / sizeof(uint32_t)]; + concurrent::LoFFLi m_indexManager; +}; +} // namespace popo +} // namespace iox + +#endif diff --git a/iceoryx_posh/source/popo/active_call_set.cpp b/iceoryx_posh/source/popo/active_call_set.cpp index e69de29bb2d..ae855addd4a 100644 --- a/iceoryx_posh/source/popo/active_call_set.cpp +++ b/iceoryx_posh/source/popo/active_call_set.cpp @@ -0,0 +1,148 @@ +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "iceoryx_posh/popo/active_call_set.hpp" +#include "iceoryx_posh/internal/popo/building_blocks/event_listener.hpp" +#include "iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp" +#include "iceoryx_posh/runtime/posh_runtime.hpp" +#include "iceoryx_utils/cxx/helplets.hpp" + +namespace iox +{ +namespace popo +{ +ActiveCallSet::ActiveCallSet() noexcept + : m_eventVariable(runtime::PoshRuntime::getInstance().getMiddlewareEventVariable()) +{ + m_indexManager.init(m_loffliStorage, MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); +} + +ActiveCallSet::~ActiveCallSet() +{ + m_wasDtorCalled.store(true, std::memory_order_relaxed); + + // notify eventVariable without origin to signal that we are in the dtor + m_eventVariable->m_semaphore.post(); + + m_eventVariable->m_toBeDestroyed.store(true, std::memory_order_relaxed); +} + +void ActiveCallSet::addEvent(void* const origin, const uint64_t eventType, const Callback_t callback) noexcept +{ + uint32_t index = 0U; + if (!m_indexManager.pop(index)) + { + return; + } + + m_events[index].init(origin, eventType, callback); +} + +void ActiveCallSet::removeEvent(void* const origin, const uint64_t eventType) noexcept +{ + for (uint32_t index = 0U; index < MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++index) + { + if (!m_events[index].isEqualTo(origin, eventType)) + { + continue; + } + + m_events[index].reset(); + m_indexManager.push(index); + + break; + } +} + +void ActiveCallSet::threadLoop() noexcept +{ + EventListener eventListener(*m_eventVariable); + while (m_wasDtorCalled.load(std::memory_order_relaxed) == false) + { + auto activateNotificationIds = eventListener.wait(); + + cxx::forEach(activateNotificationIds, [this](auto id) { m_events[id](); }); + } +} + +//////////////// +// Event_t +//////////////// +void ActiveCallSet::Event_t::operator()() noexcept +{ + CallbackState expectedState = CallbackState::INACTIVE; + + if (m_callbackState.compare_exchange_strong( + expectedState, CallbackState::ACTIVE, std::memory_order_relaxed, std::memory_order_relaxed)) + { + m_callback(m_origin); + m_callbackState.store(CallbackState::INACTIVE, std::memory_order_relaxed); + } +} + +void ActiveCallSet::Event_t::init(void* const origin, + const uint64_t eventType, + const Callback_t callback) noexcept +{ + set(origin, eventType, callback); + m_callbackState.store(CallbackState::INACTIVE, std::memory_order_relaxed); +} + +void ActiveCallSet::Event_t::reset() noexcept +{ + CallbackState expectedState = CallbackState::INACTIVE; + while (!m_callbackState.compare_exchange_strong( + expectedState, CallbackState::DELETED, std::memory_order_relaxed, std::memory_order_relaxed)) + { + if (expectedState == CallbackState::DELETED) + { + return; + } + expectedState = CallbackState::INACTIVE; + } + + set(nullptr, 0U, nullptr); +} + +bool ActiveCallSet::Event_t::isEqualTo(const void* const origin, const uint64_t eventType) const noexcept +{ + if (m_callbackState.load(std::memory_order_relaxed) == CallbackState::DELETED) + { + return false; + } + + // to ensure correctness when removeEvent is called twice concurrently for the same event + uint64_t setCounter = 0U; + do + { + setCounter = m_setCounter.load(std::memory_order_acquire); + if (m_origin != origin || m_eventType != eventType) + { + return false; + } + } while (setCounter != m_setCounter.load(std::memory_order_acquire)); + + return true; +} + +void ActiveCallSet::Event_t::set(void* const origin, const uint64_t eventType, const Callback_t callback) noexcept +{ + m_origin = origin; + m_eventType = eventType; + m_callback = callback; + m_setCounter.fetch_add(1, std::memory_order_release); +} + +} // namespace popo +} // namespace iox From 0f9a1fc6e4c0d04ea3fd54e5663b7fde51a921e4 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Mon, 1 Feb 2021 15:27:27 +0100 Subject: [PATCH 006/143] iox-#350 corrected memory order Signed-off-by: Christian Eltzschig --- iceoryx_posh/source/popo/active_call_set.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iceoryx_posh/source/popo/active_call_set.cpp b/iceoryx_posh/source/popo/active_call_set.cpp index ae855addd4a..87ab6b2bc3c 100644 --- a/iceoryx_posh/source/popo/active_call_set.cpp +++ b/iceoryx_posh/source/popo/active_call_set.cpp @@ -84,7 +84,7 @@ void ActiveCallSet::Event_t::operator()() noexcept CallbackState expectedState = CallbackState::INACTIVE; if (m_callbackState.compare_exchange_strong( - expectedState, CallbackState::ACTIVE, std::memory_order_relaxed, std::memory_order_relaxed)) + expectedState, CallbackState::ACTIVE, std::memory_order_acq_rel, std::memory_order_relaxed)) { m_callback(m_origin); m_callbackState.store(CallbackState::INACTIVE, std::memory_order_relaxed); @@ -96,7 +96,7 @@ void ActiveCallSet::Event_t::init(void* const origin, const Callback_t callback) noexcept { set(origin, eventType, callback); - m_callbackState.store(CallbackState::INACTIVE, std::memory_order_relaxed); + m_callbackState.store(CallbackState::INACTIVE, std::memory_order_release); } void ActiveCallSet::Event_t::reset() noexcept From cd712015e89dc5f1da7ab69286282f156fa5b517 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Mon, 1 Feb 2021 18:54:41 +0100 Subject: [PATCH 007/143] iox-#350 active call set is non blocking in reset Signed-off-by: Christian Eltzschig --- .../internal/popo/active_call_set.inl | 0 .../iceoryx_posh/popo/active_call_set.hpp | 15 +++- iceoryx_posh/source/popo/active_call_set.cpp | 77 ++++++++++++++----- 3 files changed, 71 insertions(+), 21 deletions(-) create mode 100644 iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp index a4385892c21..28fd2a2fcc2 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -79,14 +79,20 @@ class ActiveCallSet { INACTIVE, ACTIVE, - DELETED, + TO_BE_DELETED, + EMPTY }; struct Event_t { bool isEqualTo(const void* const origin, const uint64_t eventType) const noexcept; + void toBeDeleted() noexcept; void reset() noexcept; - void init(void* const origin, const uint64_t eventType, const Callback_t callback) noexcept; + void init(concurrent::LoFFLi& indexManager, + const uint32_t index, + void* const origin, + const uint64_t eventType, + const Callback_t callback) noexcept; void set(void* const origin, const uint64_t eventType, const Callback_t callback) noexcept; void operator()() noexcept; @@ -95,7 +101,10 @@ class ActiveCallSet std::atomic m_setCounter{0U}; Callback_t m_callback = nullptr; - std::atomic m_callbackState{CallbackState::DELETED}; + std::atomic m_callbackState{CallbackState::EMPTY}; + + uint32_t m_index = 0U; + concurrent::LoFFLi* m_indexManager = nullptr; }; std::thread m_thread; diff --git a/iceoryx_posh/source/popo/active_call_set.cpp b/iceoryx_posh/source/popo/active_call_set.cpp index 87ab6b2bc3c..f471405e7ed 100644 --- a/iceoryx_posh/source/popo/active_call_set.cpp +++ b/iceoryx_posh/source/popo/active_call_set.cpp @@ -46,7 +46,7 @@ void ActiveCallSet::addEvent(void* const origin, const uint64_t eventType, const return; } - m_events[index].init(origin, eventType, callback); + m_events[index].init(m_indexManager, index, origin, eventType, callback); } void ActiveCallSet::removeEvent(void* const origin, const uint64_t eventType) noexcept @@ -58,8 +58,7 @@ void ActiveCallSet::removeEvent(void* const origin, const uint64_t eventType) no continue; } - m_events[index].reset(); - m_indexManager.push(index); + m_events[index].toBeDeleted(); break; } @@ -87,42 +86,84 @@ void ActiveCallSet::Event_t::operator()() noexcept expectedState, CallbackState::ACTIVE, std::memory_order_acq_rel, std::memory_order_relaxed)) { m_callback(m_origin); - m_callbackState.store(CallbackState::INACTIVE, std::memory_order_relaxed); - } -} -void ActiveCallSet::Event_t::init(void* const origin, - const uint64_t eventType, - const Callback_t callback) noexcept -{ - set(origin, eventType, callback); - m_callbackState.store(CallbackState::INACTIVE, std::memory_order_release); + expectedState = CallbackState::ACTIVE; + if (!m_callbackState.compare_exchange_strong( + expectedState, CallbackState::INACTIVE, std::memory_order_relaxed, std::memory_order_relaxed)) + { + if (expectedState == CallbackState::TO_BE_DELETED) + { + m_callbackState.exchange(CallbackState::EMPTY, std::memory_order_relaxed); + reset(); + } + else + { + // FATAL logic error + } + } + } + else + { + // FATAL logic error if expectedState == ACTIVE, TO_BE_DELETED + } } -void ActiveCallSet::Event_t::reset() noexcept +void ActiveCallSet::Event_t::toBeDeleted() noexcept { CallbackState expectedState = CallbackState::INACTIVE; + CallbackState newState = CallbackState::EMPTY; + while (!m_callbackState.compare_exchange_strong( - expectedState, CallbackState::DELETED, std::memory_order_relaxed, std::memory_order_relaxed)) + expectedState, newState, std::memory_order_relaxed, std::memory_order_relaxed)) { - if (expectedState == CallbackState::DELETED) + if (expectedState == CallbackState::EMPTY || expectedState == CallbackState::TO_BE_DELETED) { return; } - expectedState = CallbackState::INACTIVE; + else if (expectedState == CallbackState::ACTIVE) + { + newState = CallbackState::TO_BE_DELETED; + } + else if (expectedState == CallbackState::INACTIVE) + { + newState = CallbackState::EMPTY; + } + } + + if (newState == CallbackState::EMPTY) + { + reset(); } +} +void ActiveCallSet::Event_t::reset() noexcept +{ set(nullptr, 0U, nullptr); + m_indexManager->push(m_index); + m_indexManager = nullptr; + m_index = 0U; +} + +void ActiveCallSet::Event_t::init(concurrent::LoFFLi& indexManager, + const uint32_t index, + void* const origin, + const uint64_t eventType, + const Callback_t callback) noexcept +{ + m_indexManager = &indexManager; + m_index = index; + set(origin, eventType, callback); + m_callbackState.store(CallbackState::INACTIVE, std::memory_order_release); } bool ActiveCallSet::Event_t::isEqualTo(const void* const origin, const uint64_t eventType) const noexcept { - if (m_callbackState.load(std::memory_order_relaxed) == CallbackState::DELETED) + auto currentCallbackState = m_callbackState.load(std::memory_order_relaxed); + if (currentCallbackState == CallbackState::TO_BE_DELETED || currentCallbackState == CallbackState::EMPTY) { return false; } - // to ensure correctness when removeEvent is called twice concurrently for the same event uint64_t setCounter = 0U; do { From 05135e22cd3411e959a6049004d7cc10a83b4f08 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Mon, 1 Feb 2021 20:07:01 +0100 Subject: [PATCH 008/143] iox-#350 rebuild active call set with smart_lock - it is much simpler now Signed-off-by: Christian Eltzschig --- .../internal/popo/active_call_set.inl | 64 +++++++++ .../iceoryx_posh/popo/active_call_set.hpp | 68 ++++------ iceoryx_posh/source/popo/active_call_set.cpp | 128 ++++-------------- 3 files changed, 118 insertions(+), 142 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl index e69de29bb2d..d9bd8c1f91b 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl @@ -0,0 +1,64 @@ +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef IOX_POSH_POPO_ACTIVE_CALL_SET_INL +#define IOX_POSH_POPO_ACTIVE_CALL_SET_INL +namespace iox +{ +namespace popo +{ +namespace internal +{ +template +inline void callsetCallback(void* const origin, void (*underlyingCallback)(void* const)) +{ + reinterpret_cast(underlyingCallback)(static_cast(origin)); +} +} // namespace internal + +template +inline cxx::expected ActiveCallSet::attachEvent(T& eventOrigin, + const Callback_t eventCallback) noexcept +{ + addEvent(&eventOrigin, 0U, reinterpret_cast>(eventCallback), internal::callsetCallback); + return cxx::success<>(); +} + +template ::value>> +inline cxx::expected +ActiveCallSet::attachEvent(T& eventOrigin, const EventType eventType, const Callback_t eventCallback) noexcept +{ + addEvent(&eventOrigin, + static_cast(eventType), + reinterpret_cast>(eventCallback), + internal::callsetCallback); + return cxx::success<>(); +} + +template ::value>> +inline void ActiveCallSet::detachEvent(T& eventOrigin, const EventType eventType) noexcept +{ + removeEvent(&eventOrigin, static_cast(eventType)); +} + +template +inline void ActiveCallSet::detachEvent(T& eventOrigin) noexcept +{ + removeEvent(&eventOrigin, 0U); +} + + +} // namespace popo +} // namespace iox +#endif diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp index 28fd2a2fcc2..0df8a788aae 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -19,6 +19,7 @@ #include "iceoryx_utils/cxx/expected.hpp" #include "iceoryx_utils/cxx/types.hpp" #include "iceoryx_utils/internal/concurrent/loffli.hpp" +#include "iceoryx_utils/internal/concurrent/smart_lock.hpp" #include #include @@ -37,78 +38,55 @@ class ActiveCallSet public: template using Callback_t = void (*)(T* const); + using TranslationCallback_t = void (*)(void* const, void (*const)(void* const)); ActiveCallSet() noexcept; ~ActiveCallSet(); - template - cxx::expected attachEvent(T& eventOrigin, const Callback_t& eventCallback) noexcept - { - return cxx::success<>(); - } + cxx::expected attachEvent(T& eventOrigin, const Callback_t eventCallback) noexcept; template ::value>> cxx::expected - attachEvent(T& eventOrigin, const EventType eventType, const Callback_t& eventCallback) noexcept - { - return cxx::success<>(); - } + attachEvent(T& eventOrigin, const EventType eventType, const Callback_t eventCallback) noexcept; template ::value>> - cxx::expected detachEvent(T& eventOrigin, const EventType eventType) noexcept - { - return cxx::success<>(); - } + void detachEvent(T& eventOrigin, const EventType eventType) noexcept; template - cxx::expected detachEvent(T& eventOrigin) noexcept - { - return cxx::success<>(); - } + void detachEvent(T& eventOrigin) noexcept; private: - struct Event_t; + class Event_t; void threadLoop() noexcept; - void addEvent(void* const origin, const uint64_t eventType, const Callback_t callback) noexcept; + void addEvent(void* const origin, + const uint64_t eventType, + const Callback_t callback, + const TranslationCallback_t translationCallback) noexcept; void removeEvent(void* const origin, const uint64_t eventType) noexcept; private: - enum class CallbackState + class Event_t { - INACTIVE, - ACTIVE, - TO_BE_DELETED, - EMPTY - }; - - struct Event_t - { - bool isEqualTo(const void* const origin, const uint64_t eventType) const noexcept; - void toBeDeleted() noexcept; - void reset() noexcept; - void init(concurrent::LoFFLi& indexManager, - const uint32_t index, - void* const origin, + public: + bool resetIfEqualTo(const void* const origin, const uint64_t eventType) noexcept; + void init(void* const origin, const uint64_t eventType, - const Callback_t callback) noexcept; - void set(void* const origin, const uint64_t eventType, const Callback_t callback) noexcept; - void operator()() noexcept; + const Callback_t callback, + const TranslationCallback_t translationCallback) noexcept; + void executeCallback() noexcept; + bool isInitialized() const noexcept; + private: void* m_origin = nullptr; uint64_t m_eventType = 0U; - std::atomic m_setCounter{0U}; - Callback_t m_callback = nullptr; - std::atomic m_callbackState{CallbackState::EMPTY}; - - uint32_t m_index = 0U; - concurrent::LoFFLi* m_indexManager = nullptr; + TranslationCallback_t m_translationCallback = nullptr; }; std::thread m_thread; - Event_t m_events[MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET]; + concurrent::smart_lock m_events[MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET]; std::atomic_bool m_wasDtorCalled{false}; EventVariableData* m_eventVariable = nullptr; @@ -120,4 +98,6 @@ class ActiveCallSet } // namespace popo } // namespace iox +#include "iceoryx_posh/internal/popo/active_call_set.inl" + #endif diff --git a/iceoryx_posh/source/popo/active_call_set.cpp b/iceoryx_posh/source/popo/active_call_set.cpp index f471405e7ed..ec791978fd0 100644 --- a/iceoryx_posh/source/popo/active_call_set.cpp +++ b/iceoryx_posh/source/popo/active_call_set.cpp @@ -38,7 +38,10 @@ ActiveCallSet::~ActiveCallSet() m_eventVariable->m_toBeDestroyed.store(true, std::memory_order_relaxed); } -void ActiveCallSet::addEvent(void* const origin, const uint64_t eventType, const Callback_t callback) noexcept +void ActiveCallSet::addEvent(void* const origin, + const uint64_t eventType, + const Callback_t callback, + const TranslationCallback_t translationCallback) noexcept { uint32_t index = 0U; if (!m_indexManager.pop(index)) @@ -46,21 +49,18 @@ void ActiveCallSet::addEvent(void* const origin, const uint64_t eventType, const return; } - m_events[index].init(m_indexManager, index, origin, eventType, callback); + m_events[index]->init(origin, eventType, callback, translationCallback); } void ActiveCallSet::removeEvent(void* const origin, const uint64_t eventType) noexcept { for (uint32_t index = 0U; index < MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++index) { - if (!m_events[index].isEqualTo(origin, eventType)) + if (m_events[index]->resetIfEqualTo(origin, eventType)) { - continue; + m_indexManager.push(index); + break; } - - m_events[index].toBeDeleted(); - - break; } } @@ -71,118 +71,50 @@ void ActiveCallSet::threadLoop() noexcept { auto activateNotificationIds = eventListener.wait(); - cxx::forEach(activateNotificationIds, [this](auto id) { m_events[id](); }); + cxx::forEach(activateNotificationIds, [this](auto id) { m_events[id]->executeCallback(); }); } } //////////////// // Event_t //////////////// -void ActiveCallSet::Event_t::operator()() noexcept +void ActiveCallSet::Event_t::executeCallback() noexcept { - CallbackState expectedState = CallbackState::INACTIVE; - - if (m_callbackState.compare_exchange_strong( - expectedState, CallbackState::ACTIVE, std::memory_order_acq_rel, std::memory_order_relaxed)) - { - m_callback(m_origin); - - expectedState = CallbackState::ACTIVE; - if (!m_callbackState.compare_exchange_strong( - expectedState, CallbackState::INACTIVE, std::memory_order_relaxed, std::memory_order_relaxed)) - { - if (expectedState == CallbackState::TO_BE_DELETED) - { - m_callbackState.exchange(CallbackState::EMPTY, std::memory_order_relaxed); - reset(); - } - else - { - // FATAL logic error - } - } - } - else + if (!isInitialized()) { - // FATAL logic error if expectedState == ACTIVE, TO_BE_DELETED - } -} - -void ActiveCallSet::Event_t::toBeDeleted() noexcept -{ - CallbackState expectedState = CallbackState::INACTIVE; - CallbackState newState = CallbackState::EMPTY; - - while (!m_callbackState.compare_exchange_strong( - expectedState, newState, std::memory_order_relaxed, std::memory_order_relaxed)) - { - if (expectedState == CallbackState::EMPTY || expectedState == CallbackState::TO_BE_DELETED) - { - return; - } - else if (expectedState == CallbackState::ACTIVE) - { - newState = CallbackState::TO_BE_DELETED; - } - else if (expectedState == CallbackState::INACTIVE) - { - newState = CallbackState::EMPTY; - } + return; } - if (newState == CallbackState::EMPTY) - { - reset(); - } + m_translationCallback(m_origin, m_callback); } -void ActiveCallSet::Event_t::reset() noexcept -{ - set(nullptr, 0U, nullptr); - m_indexManager->push(m_index); - m_indexManager = nullptr; - m_index = 0U; -} - -void ActiveCallSet::Event_t::init(concurrent::LoFFLi& indexManager, - const uint32_t index, - void* const origin, +void ActiveCallSet::Event_t::init(void* const origin, const uint64_t eventType, - const Callback_t callback) noexcept + const Callback_t callback, + const TranslationCallback_t translationCallback) noexcept { - m_indexManager = &indexManager; - m_index = index; - set(origin, eventType, callback); - m_callbackState.store(CallbackState::INACTIVE, std::memory_order_release); + m_origin = origin; + m_eventType = eventType; + m_callback = callback; + m_translationCallback = translationCallback; } -bool ActiveCallSet::Event_t::isEqualTo(const void* const origin, const uint64_t eventType) const noexcept +bool ActiveCallSet::Event_t::resetIfEqualTo(const void* const origin, const uint64_t eventType) noexcept { - auto currentCallbackState = m_callbackState.load(std::memory_order_relaxed); - if (currentCallbackState == CallbackState::TO_BE_DELETED || currentCallbackState == CallbackState::EMPTY) + if (m_origin == origin && m_eventType == eventType) { - return false; + m_origin = nullptr; + m_eventType = 0U; + m_callback = nullptr; + m_translationCallback = nullptr; + return true; } - - uint64_t setCounter = 0U; - do - { - setCounter = m_setCounter.load(std::memory_order_acquire); - if (m_origin != origin || m_eventType != eventType) - { - return false; - } - } while (setCounter != m_setCounter.load(std::memory_order_acquire)); - - return true; + return false; } -void ActiveCallSet::Event_t::set(void* const origin, const uint64_t eventType, const Callback_t callback) noexcept +bool ActiveCallSet::Event_t::isInitialized() const noexcept { - m_origin = origin; - m_eventType = eventType; - m_callback = callback; - m_setCounter.fetch_add(1, std::memory_order_release); + return m_origin != nullptr; } } // namespace popo From b7cec6e7df10e5082cff24aeb192e5e2576d1364 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Mon, 1 Feb 2021 20:19:21 +0100 Subject: [PATCH 009/143] iox-#350 implemented event listener Signed-off-by: Marika Lehmann --- .../popo/building_blocks/event_listener.hpp | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp index 4aa9343094d..007b4431877 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp @@ -15,6 +15,7 @@ #ifndef IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_LISTENER_HPP #define IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_LISTENER_HPP +#include "iceoryx_posh/iceoryx_posh_types.hpp" #include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" #include "iceoryx_utils/cxx/vector.hpp" #include "iceoryx_utils/internal/units/duration.hpp" @@ -29,20 +30,46 @@ class EventListener { public: EventListener(EventVariableData& dataRef) noexcept + : m_pointerToEventVariableData(&dataRef) { } - cxx::vector wait() noexcept + cxx::vector wait() noexcept { + cxx::vector activeNotifications; + if (getMembers()->m_semaphore.wait().has_error()) + { + errorHandler(Error::kPOPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_WAIT, nullptr, ErrorLevel::FATAL); + } + else + { + // return vector of true entries in activeNotifications + // mutex? + for (uint64_t i = 0U; i < getMembers()->m_activeNotifications.size(); i++) + { + if (getMembers()->m_activeNotifications[i]) + { + activeNotifications.emplace_back(i); + } + } + } + return activeNotifications; } - cxx::vector timedWait(const units::Duration timeToWait) noexcept + void reset(const uint64_t index) noexcept { + // count the semaphores down to zero? + m_pointerToEventVariableData->m_activeNotifications[index] = false; } - void reset(const uint64_t index) noexcept + private: + const EventVariableData* getMembers() const noexcept { + return m_pointerToEventVariableData; } + + private: + EventVariableData* m_pointerToEventVariableData{nullptr}; }; } // namespace popo } // namespace iox From 95cec2e92c2a07481b2c2834ff00bcbb3982059a Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Mon, 1 Feb 2021 20:20:26 +0100 Subject: [PATCH 010/143] iox-#350 implemented event notifier Signed-off-by: Marika Lehmann --- .../internal/popo/building_blocks/event_notifier.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp index fd76f169267..a76438fd29d 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp @@ -27,11 +27,20 @@ class EventNotifier { public: EventNotifier(EventVariableData& dataRef, const uint64_t index) noexcept + : m_pointerToEventVariableData(&dataRef) + , m_notificationIndex(index) { } + void notify() { + m_pointerToEventVariableData->m_activeNotifications[m_notificationIndex] = true; + m_pointerToEventVariableData->m_semaphore.post(); } + + private: + EventVariableData* m_pointerToEventVariableData{nullptr}; + uint64_t m_notificationIndex{0U}; }; } // namespace popo } // namespace iox From e27236f791253ef44752d6d7b2b8f38f0d6d3112 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Mon, 1 Feb 2021 20:21:15 +0100 Subject: [PATCH 011/143] iox-#350 implemented event variable data Signed-off-by: Marika Lehmann --- .../internal/popo/building_blocks/event_variable_data.hpp | 3 ++- .../include/iceoryx_utils/error_handling/error_handling.hpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp index 3f1953a2bcf..442eec6f280 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp @@ -26,7 +26,8 @@ namespace popo { struct EventVariableData : public ConditionVariableData { - cxx::vector m_activeNotifications; + // todo: C array, Events per active callset + cxx::vector m_activeNotifications; }; } // namespace popo } // namespace iox diff --git a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp index c39e4e8beda..403690bf2bc 100644 --- a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp +++ b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp @@ -77,6 +77,7 @@ namespace iox error(POPO__CONDITION_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_TIMED_WAIT) \ error(POPO__CONDITION_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_RESET) \ error(POPO__EVENT_INFO_TYPE_INCONSISTENCY_IN_GET_ORIGIN) \ + error(POPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_WAIT) \ error(POPO__TYPED_UNIQUE_ID_ROUDI_HAS_NO_DEFINED_UNIQUE_ID) \ error(POPO__TYPED_UNIQUE_ID_ROUDI_HAS_ALREADY_DEFINED_UNIQUE_ID) \ error(POPO__TYPED_UNIQUE_ID_OVERFLOW) \ From 99ad7d5b27f29227a47126c97cefef20ab2613ab Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 2 Feb 2021 08:55:51 +0100 Subject: [PATCH 012/143] iox-#350 replace vector in EventVariableData by C array Signed-off-by: Marika Lehmann --- .../popo/building_blocks/condition_variable_data.hpp | 1 + .../internal/popo/building_blocks/event_listener.hpp | 7 +++---- .../popo/building_blocks/event_variable_data.hpp | 10 +++++++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp index 4f517a7276c..63914404cf1 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp @@ -26,6 +26,7 @@ namespace popo { struct ConditionVariableData { + ConditionVariableData() noexcept = default; ConditionVariableData(const ProcessName_t& process) noexcept; ConditionVariableData(const ConditionVariableData& rhs) = delete; ConditionVariableData(ConditionVariableData&& rhs) = delete; diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp index 007b4431877..8019d0405b4 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp @@ -34,9 +34,9 @@ class EventListener { } - cxx::vector wait() noexcept + cxx::vector wait() noexcept { - cxx::vector activeNotifications; + cxx::vector activeNotifications; if (getMembers()->m_semaphore.wait().has_error()) { errorHandler(Error::kPOPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_WAIT, nullptr, ErrorLevel::FATAL); @@ -45,7 +45,7 @@ class EventListener { // return vector of true entries in activeNotifications // mutex? - for (uint64_t i = 0U; i < getMembers()->m_activeNotifications.size(); i++) + for (uint64_t i = 0U; i < MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; i++) { if (getMembers()->m_activeNotifications[i]) { @@ -58,7 +58,6 @@ class EventListener void reset(const uint64_t index) noexcept { - // count the semaphores down to zero? m_pointerToEventVariableData->m_activeNotifications[index] = false; } diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp index 442eec6f280..48d0eb54bf7 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp @@ -16,7 +16,7 @@ #define IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_VARIABLE_DATA_HPP #include "iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp" -#include "iceoryx_utils/cxx/vector.hpp" +#include "iceoryx_utils/cxx/helplets.hpp" #include @@ -26,8 +26,12 @@ namespace popo { struct EventVariableData : public ConditionVariableData { - // todo: C array, Events per active callset - cxx::vector m_activeNotifications; + EventVariableData() noexcept + { + iox::cxx::forEach(m_activeNotifications, [](auto& id) { id = false; }); + } + + std::atomic_bool m_activeNotifications[MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET]; }; } // namespace popo } // namespace iox From fd6bfb41a0d03fb330b70bebf5e3de09965175d1 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 2 Feb 2021 10:42:17 +0100 Subject: [PATCH 013/143] iox-#350 move implementations into cpp files Signed-off-by: Marika Lehmann --- .../popo/building_blocks/event_listener.hpp | 44 ++-------------- .../popo/building_blocks/event_notifier.hpp | 14 +---- .../building_blocks/event_variable_data.hpp | 8 +-- .../popo/building_blocks/event_listener.cpp | 51 +++++++++++++++++++ .../popo/building_blocks/event_notifier.cpp | 34 +++++++++++++ .../building_blocks/event_variable_data.cpp | 27 ++++++++++ 6 files changed, 119 insertions(+), 59 deletions(-) create mode 100644 iceoryx_posh/source/popo/building_blocks/event_listener.cpp create mode 100644 iceoryx_posh/source/popo/building_blocks/event_notifier.cpp create mode 100644 iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp index 8019d0405b4..e03d5f418d3 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp @@ -15,57 +15,21 @@ #ifndef IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_LISTENER_HPP #define IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_LISTENER_HPP -#include "iceoryx_posh/iceoryx_posh_types.hpp" #include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" -#include "iceoryx_utils/cxx/vector.hpp" -#include "iceoryx_utils/internal/units/duration.hpp" - -#include namespace iox { namespace popo { +/// only one event listener per event variable class EventListener { public: - EventListener(EventVariableData& dataRef) noexcept - : m_pointerToEventVariableData(&dataRef) - { - } - - cxx::vector wait() noexcept - { - cxx::vector activeNotifications; - if (getMembers()->m_semaphore.wait().has_error()) - { - errorHandler(Error::kPOPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_WAIT, nullptr, ErrorLevel::FATAL); - } - else - { - // return vector of true entries in activeNotifications - // mutex? - for (uint64_t i = 0U; i < MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; i++) - { - if (getMembers()->m_activeNotifications[i]) - { - activeNotifications.emplace_back(i); - } - } - } - return activeNotifications; - } + EventListener(EventVariableData& dataRef) noexcept; - void reset(const uint64_t index) noexcept - { - m_pointerToEventVariableData->m_activeNotifications[index] = false; - } + cxx::vector wait() noexcept; - private: - const EventVariableData* getMembers() const noexcept - { - return m_pointerToEventVariableData; - } + void reset(const uint64_t index) noexcept; private: EventVariableData* m_pointerToEventVariableData{nullptr}; diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp index a76438fd29d..ca716728245 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp @@ -17,8 +17,6 @@ #include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" -#include - namespace iox { namespace popo @@ -26,17 +24,9 @@ namespace popo class EventNotifier { public: - EventNotifier(EventVariableData& dataRef, const uint64_t index) noexcept - : m_pointerToEventVariableData(&dataRef) - , m_notificationIndex(index) - { - } + EventNotifier(EventVariableData& dataRef, const uint64_t index) noexcept; - void notify() - { - m_pointerToEventVariableData->m_activeNotifications[m_notificationIndex] = true; - m_pointerToEventVariableData->m_semaphore.post(); - } + void notify() noexcept; private: EventVariableData* m_pointerToEventVariableData{nullptr}; diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp index 48d0eb54bf7..d6a5cd49b40 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp @@ -16,9 +16,6 @@ #define IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_VARIABLE_DATA_HPP #include "iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp" -#include "iceoryx_utils/cxx/helplets.hpp" - -#include namespace iox { @@ -26,10 +23,7 @@ namespace popo { struct EventVariableData : public ConditionVariableData { - EventVariableData() noexcept - { - iox::cxx::forEach(m_activeNotifications, [](auto& id) { id = false; }); - } + EventVariableData() noexcept; std::atomic_bool m_activeNotifications[MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET]; }; diff --git a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp new file mode 100644 index 00000000000..61507d71f1c --- /dev/null +++ b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp @@ -0,0 +1,51 @@ +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "iceoryx_posh/internal/popo/building_blocks/event_listener.hpp" + +namespace iox +{ +namespace popo +{ +EventListener::EventListener(EventVariableData& dataRef) noexcept + : m_pointerToEventVariableData(&dataRef) +{ +} + +cxx::vector EventListener::wait() noexcept +{ + cxx::vector activeNotifications; + if (m_pointerToEventVariableData->m_semaphore.wait().has_error()) + { + errorHandler(Error::kPOPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_WAIT, nullptr, ErrorLevel::FATAL); + } + else + { + for (uint64_t i = 0U; i < MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; i++) + { + if (m_pointerToEventVariableData->m_activeNotifications[i].load(std::memory_order_relaxed)) + { + activeNotifications.emplace_back(i); + } + } + } + return activeNotifications; +} + +void EventListener::reset(const uint64_t index) noexcept +{ + m_pointerToEventVariableData->m_activeNotifications[index].store(false, std::memory_order_relaxed); +} +} // namespace popo +} // namespace iox diff --git a/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp b/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp new file mode 100644 index 00000000000..354cb2d0335 --- /dev/null +++ b/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp @@ -0,0 +1,34 @@ +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp" + +namespace iox +{ +namespace popo +{ +EventNotifier::EventNotifier(EventVariableData& dataRef, const uint64_t index) noexcept + : m_pointerToEventVariableData(&dataRef) + , m_notificationIndex(index) +{ +} + +void EventNotifier::notify() noexcept +{ + m_pointerToEventVariableData->m_activeNotifications[m_notificationIndex].store(true, std::memory_order_release); + m_pointerToEventVariableData->m_semaphore.post(); +} +} // namespace popo +} // namespace iox + diff --git a/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp b/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp new file mode 100644 index 00000000000..ed118e6b37f --- /dev/null +++ b/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp @@ -0,0 +1,27 @@ +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" + +namespace iox +{ +namespace popo +{ +EventVariableData::EventVariableData() noexcept +{ + iox::cxx::forEach(m_activeNotifications, [](auto& id) { id.store(false, std::memory_order_relaxed); }); +} +} // namespace popo +} // namespace iox + From c8a7f9abe97df5be16b3ad64d2951c9aea22d791 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 2 Feb 2021 11:31:06 +0100 Subject: [PATCH 014/143] iox-#350 added error enum, cannot add same event twice, verify event enum with value and type hash Signed-off-by: Christian Eltzschig --- .../internal/popo/active_call_set.inl | 17 ++-- .../iceoryx_posh/popo/active_call_set.hpp | 46 +++++++---- iceoryx_posh/source/popo/active_call_set.cpp | 77 +++++++++++++++---- 3 files changed, 104 insertions(+), 36 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl index d9bd8c1f91b..7d4471315ea 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl @@ -29,19 +29,24 @@ inline void callsetCallback(void* const origin, void (*underlyingCallback)(void* template inline cxx::expected ActiveCallSet::attachEvent(T& eventOrigin, - const Callback_t eventCallback) noexcept + CallbackRef_t eventCallback) noexcept { - addEvent(&eventOrigin, 0U, reinterpret_cast>(eventCallback), internal::callsetCallback); + addEvent(&eventOrigin, + 0U, + typeid(void).hash_code(), + reinterpret_cast>(eventCallback), + internal::callsetCallback); return cxx::success<>(); } template ::value>> inline cxx::expected -ActiveCallSet::attachEvent(T& eventOrigin, const EventType eventType, const Callback_t eventCallback) noexcept +ActiveCallSet::attachEvent(T& eventOrigin, const EventType eventType, CallbackRef_t eventCallback) noexcept { addEvent(&eventOrigin, static_cast(eventType), - reinterpret_cast>(eventCallback), + typeid(EventType).hash_code(), + reinterpret_cast>(eventCallback), internal::callsetCallback); return cxx::success<>(); } @@ -49,13 +54,13 @@ ActiveCallSet::attachEvent(T& eventOrigin, const EventType eventType, const Call template ::value>> inline void ActiveCallSet::detachEvent(T& eventOrigin, const EventType eventType) noexcept { - removeEvent(&eventOrigin, static_cast(eventType)); + removeEvent(&eventOrigin, static_cast(eventType), typeid(EventType).hash_code()); } template inline void ActiveCallSet::detachEvent(T& eventOrigin) noexcept { - removeEvent(&eventOrigin, 0U); + removeEvent(&eventOrigin, 0U, typeid(void).hash_code()); } diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp index 0df8a788aae..ff760d2d653 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -30,25 +30,30 @@ namespace popo { enum class ActiveCallSetError { - + ACTIVE_CALL_SET_FULL, + EVENT_ALREADY_ATTACHED, }; class ActiveCallSet { public: template - using Callback_t = void (*)(T* const); - using TranslationCallback_t = void (*)(void* const, void (*const)(void* const)); + using CallbackRef_t = void (&)(T* const); + using TranslationCallbackRef_t = void (&)(void* const, void (*const)(void* const)); + + template + using CallbackPtr_t = void (*)(T* const); + using TranslationCallbackPtr_t = void (*)(void* const, void (*const)(void* const)); ActiveCallSet() noexcept; ~ActiveCallSet(); template - cxx::expected attachEvent(T& eventOrigin, const Callback_t eventCallback) noexcept; + cxx::expected attachEvent(T& eventOrigin, CallbackRef_t eventCallback) noexcept; template ::value>> cxx::expected - attachEvent(T& eventOrigin, const EventType eventType, const Callback_t eventCallback) noexcept; + attachEvent(T& eventOrigin, const EventType eventType, CallbackRef_t eventCallback) noexcept; template ::value>> void detachEvent(T& eventOrigin, const EventType eventType) noexcept; @@ -56,37 +61,48 @@ class ActiveCallSet template void detachEvent(T& eventOrigin) noexcept; + protected: + ActiveCallSet(EventVariableData* eventVariable) noexcept; + private: class Event_t; void threadLoop() noexcept; - void addEvent(void* const origin, - const uint64_t eventType, - const Callback_t callback, - const TranslationCallback_t translationCallback) noexcept; - void removeEvent(void* const origin, const uint64_t eventType) noexcept; + cxx::expected addEvent(void* const origin, + const uint64_t eventType, + const uint64_t eventTypeHash, + CallbackRef_t callback, + TranslationCallbackRef_t translationCallback) noexcept; + void removeEvent(void* const origin, const uint64_t eventType, const uint64_t eventTypeHash) noexcept; + + void removeTrigger(const uint64_t index) noexcept; private: class Event_t { public: - bool resetIfEqualTo(const void* const origin, const uint64_t eventType) noexcept; + bool isEqualTo(const void* const origin, const uint64_t eventType, const uint64_t eventTypeHash) const noexcept; + bool resetIfEqualTo(const void* const origin, const uint64_t eventType, const uint64_t eventTypeHash) noexcept; + bool reset() noexcept; void init(void* const origin, const uint64_t eventType, - const Callback_t callback, - const TranslationCallback_t translationCallback) noexcept; + const uint64_t eventTypeHash, + CallbackRef_t callback, + TranslationCallbackRef_t translationCallback) noexcept; void executeCallback() noexcept; bool isInitialized() const noexcept; private: void* m_origin = nullptr; uint64_t m_eventType = 0U; - Callback_t m_callback = nullptr; - TranslationCallback_t m_translationCallback = nullptr; + uint64_t m_eventTypeHash = 0U; + CallbackPtr_t m_callback = nullptr; + TranslationCallbackPtr_t m_translationCallback = nullptr; }; std::thread m_thread; concurrent::smart_lock m_events[MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET]; + std::mutex m_addEventMutex; std::atomic_bool m_wasDtorCalled{false}; EventVariableData* m_eventVariable = nullptr; diff --git a/iceoryx_posh/source/popo/active_call_set.cpp b/iceoryx_posh/source/popo/active_call_set.cpp index ec791978fd0..d1d5a0eeec8 100644 --- a/iceoryx_posh/source/popo/active_call_set.cpp +++ b/iceoryx_posh/source/popo/active_call_set.cpp @@ -23,7 +23,12 @@ namespace iox namespace popo { ActiveCallSet::ActiveCallSet() noexcept - : m_eventVariable(runtime::PoshRuntime::getInstance().getMiddlewareEventVariable()) + : ActiveCallSet(runtime::PoshRuntime::getInstance().getMiddlewareEventVariable()) +{ +} + +ActiveCallSet::ActiveCallSet(EventVariableData* eventVariable) noexcept + : m_eventVariable(eventVariable) { m_indexManager.init(m_loffliStorage, MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); } @@ -38,25 +43,37 @@ ActiveCallSet::~ActiveCallSet() m_eventVariable->m_toBeDestroyed.store(true, std::memory_order_relaxed); } -void ActiveCallSet::addEvent(void* const origin, - const uint64_t eventType, - const Callback_t callback, - const TranslationCallback_t translationCallback) noexcept +cxx::expected ActiveCallSet::addEvent(void* const origin, + const uint64_t eventType, + const uint64_t eventTypeHash, + CallbackRef_t callback, + TranslationCallbackRef_t translationCallback) noexcept { + std::lock_guard lock(m_addEventMutex); + + for (uint64_t i = 0U; i < MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) + { + if (m_events[i]->isEqualTo(origin, eventType, eventTypeHash)) + { + return cxx::error(ActiveCallSetError::EVENT_ALREADY_ATTACHED); + } + } + uint32_t index = 0U; if (!m_indexManager.pop(index)) { - return; + return cxx::error(ActiveCallSetError::ACTIVE_CALL_SET_FULL); } - m_events[index]->init(origin, eventType, callback, translationCallback); + m_events[index]->init(origin, eventType, eventTypeHash, callback, translationCallback); + return cxx::success<>(); } -void ActiveCallSet::removeEvent(void* const origin, const uint64_t eventType) noexcept +void ActiveCallSet::removeEvent(void* const origin, const uint64_t eventType, const uint64_t eventTypeHash) noexcept { for (uint32_t index = 0U; index < MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++index) { - if (m_events[index]->resetIfEqualTo(origin, eventType)) + if (m_events[index]->resetIfEqualTo(origin, eventType, eventTypeHash)) { m_indexManager.push(index); break; @@ -75,6 +92,19 @@ void ActiveCallSet::threadLoop() noexcept } } +void ActiveCallSet::removeTrigger(const uint64_t index) noexcept +{ + if (index >= MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET) + { + return; + } + + if (m_events[index]->reset()) + { + m_indexManager.push(static_cast(index)); + } +} + //////////////// // Event_t //////////////// @@ -90,23 +120,40 @@ void ActiveCallSet::Event_t::executeCallback() noexcept void ActiveCallSet::Event_t::init(void* const origin, const uint64_t eventType, - const Callback_t callback, - const TranslationCallback_t translationCallback) noexcept + const uint64_t eventTypeHash, + CallbackRef_t callback, + TranslationCallbackRef_t translationCallback) noexcept { m_origin = origin; m_eventType = eventType; - m_callback = callback; - m_translationCallback = translationCallback; + m_eventTypeHash = eventTypeHash; + m_callback = &callback; + m_translationCallback = &translationCallback; } -bool ActiveCallSet::Event_t::resetIfEqualTo(const void* const origin, const uint64_t eventType) noexcept +bool ActiveCallSet::Event_t::isEqualTo(const void* const origin, + const uint64_t eventType, + const uint64_t eventTypeHash) const noexcept { - if (m_origin == origin && m_eventType == eventType) + return (m_origin == origin && m_eventType == eventType && m_eventTypeHash == eventTypeHash); +} + +bool ActiveCallSet::Event_t::resetIfEqualTo(const void* const origin, + const uint64_t eventType, + const uint64_t eventTypeHash) noexcept +{ + return (isEqualTo(origin, eventType, eventTypeHash)) ? reset() : false; +} + +bool ActiveCallSet::Event_t::reset() noexcept +{ + if (isInitialized()) { m_origin = nullptr; m_eventType = 0U; m_callback = nullptr; m_translationCallback = nullptr; + return true; } return false; From 1ae143262f7e581f5cbb3af2500b71c935ad481b Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 2 Feb 2021 11:36:14 +0100 Subject: [PATCH 015/143] iox-#350 implement getMiddlewareEventVariable Signed-off-by: Marika Lehmann --- .../runtime/message_queue_interface.hpp | 4 ++ .../iceoryx_posh/runtime/posh_runtime.hpp | 12 ++-- iceoryx_posh/source/runtime/posh_runtime.cpp | 69 +++++++++++++++++++ .../error_handling/error_handling.hpp | 3 + 4 files changed, 83 insertions(+), 5 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/runtime/message_queue_interface.hpp b/iceoryx_posh/include/iceoryx_posh/internal/runtime/message_queue_interface.hpp index 5d1e33a84c2..fce481e1e48 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/runtime/message_queue_interface.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/runtime/message_queue_interface.hpp @@ -59,6 +59,8 @@ enum class MqMessageType : int32_t CREATE_APPLICATION_ACK, CREATE_CONDITION_VARIABLE, CREATE_CONDITION_VARIABLE_ACK, + CREATE_EVENT_VARIABLE, + CREATE_EVENT_VARIABLE_ACK, CREATE_NODE, CREATE_NODE_ACK, FIND_SERVICE, @@ -83,9 +85,11 @@ enum class MqMessageErrorType : int32_t REQUEST_PUBLISHER_WRONG_MESSAGE_QUEUE_RESPONSE, REQUEST_SUBSCRIBER_WRONG_MESSAGE_QUEUE_RESPONSE, REQUEST_CONDITION_VARIABLE_WRONG_MESSAGE_QUEUE_RESPONSE, + REQUEST_EVENT_VARIABLE_WRONG_MESSAGE_QUEUE_RESPONSE, PUBLISHER_LIST_FULL, SUBSCRIBER_LIST_FULL, CONDITION_VARIABLE_LIST_FULL, + EVENT_VARIABLE_LIST_FULL, NODE_DATA_LIST_FULL, END, }; diff --git a/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp b/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp index 376cc5f44d5..09ea50ba0b3 100644 --- a/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp +++ b/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp @@ -120,14 +120,13 @@ class PoshRuntime /// @return pointer to a created application port data popo::ApplicationPortData* getMiddlewareApplication() noexcept; - /// @brief request the RouDi daemon to create an condition variable + /// @brief request the RouDi daemon to create a condition variable /// @return pointer to a created condition variable data popo::ConditionVariableData* getMiddlewareConditionVariable() noexcept; - popo::EventVariableData* getMiddlewareEventVariable() noexcept - { - return nullptr; - } + /// @brief request the RouDi daemon to create an event variable + /// @return pointer to a created event variable data + popo::EventVariableData* getMiddlewareEventVariable() noexcept; /// @brief request the RouDi daemon to create a node /// @param[in] nodeProperty class which contains all properties which the node should have @@ -192,6 +191,9 @@ class PoshRuntime cxx::expected requestConditionVariableFromRoudi(const MqMessage& sendBuffer) noexcept; + cxx::expected + requestEventVariableFromRoudi(const MqMessage& sendBuffer) noexcept; + /// @brief checks the given application name for certain constraints like length or if is empty const ProcessName_t& verifyInstanceName(cxx::optional name) noexcept; diff --git a/iceoryx_posh/source/runtime/posh_runtime.cpp b/iceoryx_posh/source/runtime/posh_runtime.cpp index 7b4c68b5c73..675874688a2 100644 --- a/iceoryx_posh/source/runtime/posh_runtime.cpp +++ b/iceoryx_posh/source/runtime/posh_runtime.cpp @@ -517,6 +517,43 @@ PoshRuntime::requestConditionVariableFromRoudi(const MqMessage& sendBuffer) noex return cxx::error(MqMessageErrorType::REQUEST_CONDITION_VARIABLE_WRONG_MESSAGE_QUEUE_RESPONSE); } +cxx::expected +PoshRuntime::requestEventVariableFromRoudi(const MqMessage& sendBuffer) noexcept +{ + MqMessage receiveBuffer; + if (sendRequestToRouDi(sendBuffer, receiveBuffer) && (3U == receiveBuffer.getNumberOfElements())) + { + std::string mqMessage = receiveBuffer.getElementAtIndex(0U); + + if (stringToMqMessageType(mqMessage.c_str()) == MqMessageType::CREATE_EVENT_VARIABLE_ACK) + { + RelativePointer::id_t segmentId{0U}; + cxx::convert::fromString(receiveBuffer.getElementAtIndex(2U).c_str(), segmentId); + RelativePointer::offset_t offset{0U}; + cxx::convert::fromString(receiveBuffer.getElementAtIndex(1U).c_str(), offset); + auto ptr = RelativePointer::getPtr(segmentId, offset); + return cxx::success(reinterpret_cast(ptr)); + } + } + else + { + if (receiveBuffer.getNumberOfElements() == 2U) + { + std::string mqMessage1 = receiveBuffer.getElementAtIndex(0U); + std::string mqMessage2 = receiveBuffer.getElementAtIndex(1U); + if (stringToMqMessageType(mqMessage1.c_str()) == MqMessageType::ERROR) + { + LogError() << "Request event variable received no valid event variable port from RouDi."; + return cxx::error(stringToMqMessageErrorType(mqMessage2.c_str())); + } + } + } + + LogError() << "Request event variable got wrong response from message queue :'" << receiveBuffer.getMessage() + << "'"; + return cxx::error(MqMessageErrorType::REQUEST_EVENT_VARIABLE_WRONG_MESSAGE_QUEUE_RESPONSE); +} + popo::ConditionVariableData* PoshRuntime::getMiddlewareConditionVariable() noexcept { MqMessage sendBuffer; @@ -549,6 +586,38 @@ popo::ConditionVariableData* PoshRuntime::getMiddlewareConditionVariable() noexc return maybeConditionVariable.value(); } +popo::EventVariableData* PoshRuntime::getMiddlewareEventVariable() noexcept +{ + MqMessage sendBuffer; + sendBuffer << mqMessageTypeToString(MqMessageType::CREATE_EVENT_VARIABLE) << m_appName; + + auto maybeEventVariable = requestEventVariableFromRoudi(sendBuffer); + if (maybeEventVariable.has_error()) + { + switch (maybeEventVariable.get_error()) + { + case MqMessageErrorType::EVENT_VARIABLE_LIST_FULL: + LogWarn() << "Could not create event variable as we are out of memory for event variables."; + errorHandler(Error::kPOSH__RUNTIME_ROUDI_EVENT_VARIABLE_LIST_FULL, nullptr, iox::ErrorLevel::SEVERE); + break; + case MqMessageErrorType::REQUEST_EVENT_VARIABLE_WRONG_MESSAGE_QUEUE_RESPONSE: + LogWarn() << "Could not create event variables; received wrong message queue response."; + errorHandler(Error::kPOSH__RUNTIME_ROUDI_REQUEST_EVENT_VARIABLE_WRONG_MESSAGE_QUEUE_RESPONSE, + nullptr, + iox::ErrorLevel::SEVERE); + break; + default: + LogWarn() << "Undefined behavior occurred while creating event variable"; + errorHandler(Error::kPOSH__RUNTIME_ROUDI_EVENT_VARIABLE_CREATION_UNDEFINED_BEHAVIOR, + nullptr, + iox::ErrorLevel::SEVERE); + break; + } + return nullptr; + } + return maybeEventVariable.value(); +} + bool PoshRuntime::sendRequestToRouDi(const MqMessage& msg, MqMessage& answer) noexcept { // runtime must be thread safe diff --git a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp index 403690bf2bc..ceca48cd303 100644 --- a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp +++ b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp @@ -38,13 +38,16 @@ namespace iox error(POSH__RUNTIME_ROUDI_PUBLISHER_LIST_FULL) \ error(POSH__RUNTIME_ROUDI_SUBSCRIBER_LIST_FULL) \ error(POSH__RUNTIME_ROUDI_CONDITION_VARIABLE_LIST_FULL) \ + error(POSH__RUNTIME_ROUDI_EVENT_VARIABLE_LIST_FULL) \ error(POSH__RUNTIME_ROUDI_REQUEST_PUBLISHER_WRONG_MESSAGE_QUEUE_RESPONSE) \ error(POSH__RUNTIME_ROUDI_REQUEST_SUBSCRIBER_WRONG_MESSAGE_QUEUE_RESPONSE) \ error(POSH__RUNTIME_ROUDI_REQUEST_CONDITION_VARIABLE_WRONG_MESSAGE_QUEUE_RESPONSE) \ + error(POSH__RUNTIME_ROUDI_REQUEST_EVENT_VARIABLE_WRONG_MESSAGE_QUEUE_RESPONSE) \ error(POSH__RUNTIME_ROUDI_GET_MW_INTERFACE_WRONG_MESSAGE_QUEUE_RESPONSE) \ error(POSH__RUNTIME_ROUDI_CREATE_NODE_WRONG_MESSAGE_QUEUE_RESPONSE) \ error(POSH__RUNTIME_ROUDI_GET_MW_APPLICATION_WRONG_MESSAGE_QUEUE_RESPONSE) \ error(POSH__RUNTIME_ROUDI_CONDITION_VARIABLE_CREATION_UNDEFINED_BEHAVIOR) \ + error(POSH__RUNTIME_ROUDI_EVENT_VARIABLE_CREATION_UNDEFINED_BEHAVIOR) \ error(POSH__PORT_MANAGER_PUBLISHERPORT_NOT_UNIQUE) \ error(POSH__MEMPOOL_POSSIBLE_DOUBLE_FREE) \ error(POSH__RECEIVERPORT_DELIVERYFIFO_OVERFLOW) \ From 23b08f6c40224b3b79c8d202e544db548f8ad884 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 2 Feb 2021 11:43:10 +0100 Subject: [PATCH 016/143] iox-#350 add new cpp files to CMakeLists.txt Signed-off-by: Marika Lehmann --- iceoryx_posh/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iceoryx_posh/CMakeLists.txt b/iceoryx_posh/CMakeLists.txt index 633b614e54a..f376c6e7acb 100644 --- a/iceoryx_posh/CMakeLists.txt +++ b/iceoryx_posh/CMakeLists.txt @@ -100,6 +100,9 @@ add_library(iceoryx_posh source/popo/building_blocks/condition_variable_data.cpp source/popo/building_blocks/condition_variable_signaler.cpp source/popo/building_blocks/condition_variable_waiter.cpp + source/popo/building_blocks/event_variable_data.cpp + source/popo/building_blocks/event_listener.cpp + source/popo/building_blocks/event_notifier.cpp source/popo/building_blocks/locking_policy.cpp source/popo/building_blocks/typed_unique_id.cpp source/popo/active_call_set.cpp From bb2ebaa705f074d1a01946f4bd230bcb5ad49c39 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 2 Feb 2021 12:46:20 +0100 Subject: [PATCH 017/143] iox-#350 added example and handle invalidation callback Signed-off-by: Christian Eltzschig --- iceoryx_examples/callbacks/CMakeLists.txt | 51 +++++++++++++++ iceoryx_examples/callbacks/README.md | 2 + .../callbacks/ice_callbacks_publisher.cpp | 56 +++++++++++++++++ .../callbacks/ice_callbacks_subscriber.cpp | 62 +++++++++++++++++++ iceoryx_examples/callbacks/topic_data.hpp | 25 ++++++++ .../internal/popo/active_call_set.inl | 24 +++---- .../iceoryx_posh/popo/active_call_set.hpp | 6 +- .../iceoryx_posh/popo/event_attorney.hpp | 1 + iceoryx_posh/source/popo/active_call_set.cpp | 17 +++-- 9 files changed, 225 insertions(+), 19 deletions(-) create mode 100644 iceoryx_examples/callbacks/CMakeLists.txt create mode 100644 iceoryx_examples/callbacks/README.md create mode 100644 iceoryx_examples/callbacks/ice_callbacks_publisher.cpp create mode 100644 iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp create mode 100644 iceoryx_examples/callbacks/topic_data.hpp diff --git a/iceoryx_examples/callbacks/CMakeLists.txt b/iceoryx_examples/callbacks/CMakeLists.txt new file mode 100644 index 00000000000..15c376a9fc5 --- /dev/null +++ b/iceoryx_examples/callbacks/CMakeLists.txt @@ -0,0 +1,51 @@ +# Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +cmake_minimum_required(VERSION 3.5) +project(example_waitset) + +include(GNUInstallDirs) + +find_package(iceoryx_posh CONFIG REQUIRED) + +get_target_property(ICEORYX_CXX_STANDARD iceoryx_posh::iceoryx_posh CXX_STANDARD) +if ( NOT ICEORYX_CXX_STANDARD ) + include(IceoryxPlatform) +endif () + +add_executable(iox-ex-callbacks-publisher ./ice_callbacks_publisher.cpp) +target_link_libraries(iox-ex-callbacks-publisher + iceoryx_posh::iceoryx_posh +) +target_compile_options(iox-ex-callbacks-publisher PRIVATE ${ICEORYX_WARNINGS} ${ICEORYX_SANITIZER_FLAGS}) + +add_executable(iox-ex-callbacks-subscriber ./ice_callbacks_subscriber.cpp) +target_link_libraries(iox-ex-callbacks-subscriber + iceoryx_posh::iceoryx_posh +) +target_compile_options(iox-ex-callbacks-subscriber PRIVATE ${ICEORYX_WARNINGS} ${ICEORYX_SANITIZER_FLAGS}) + +set_target_properties( + iox-ex-callbacks-subscriber + iox-ex-callbacks-publisher + PROPERTIES + CXX_STANDARD_REQUIRED ON + CXX_STANDARD ${ICEORYX_CXX_STANDARD} + POSITION_INDEPENDENT_CODE ON +) + +install( + TARGETS iox-ex-callbacks-publisher iox-ex-callbacks-subscriber + RUNTIME DESTINATION bin +) diff --git a/iceoryx_examples/callbacks/README.md b/iceoryx_examples/callbacks/README.md new file mode 100644 index 00000000000..01f23349ac5 --- /dev/null +++ b/iceoryx_examples/callbacks/README.md @@ -0,0 +1,2 @@ +# ActiveCallSet - WORK IN PROGRESS - + diff --git a/iceoryx_examples/callbacks/ice_callbacks_publisher.cpp b/iceoryx_examples/callbacks/ice_callbacks_publisher.cpp new file mode 100644 index 00000000000..9ec2a1aa664 --- /dev/null +++ b/iceoryx_examples/callbacks/ice_callbacks_publisher.cpp @@ -0,0 +1,56 @@ +// Copyright (c) 2020 by Apex.AI Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "iceoryx_posh/popo/publisher.hpp" +#include "iceoryx_posh/runtime/posh_runtime.hpp" +#include "topic_data.hpp" + +#include +#include +#include + +bool killswitch = false; + +static void sigHandler(int f_sig [[gnu::unused]]) +{ + killswitch = true; +} + +void sending() +{ + iox::runtime::PoshRuntime::initRuntime("iox-ex-callbacks-publisher"); + + iox::popo::TypedPublisher myPublisher({"Radar", "FrontLeft", "Counter"}); + myPublisher.offer(); + + for (uint32_t counter = 0U; !killswitch; ++counter) + { + myPublisher.publishCopyOf(CounterTopic{counter}); + std::cout << "Sending: " << counter << std::endl; + + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + + myPublisher.stopOffer(); +} + +int main() +{ + signal(SIGINT, sigHandler); + + std::thread tx(sending); + tx.join(); + + return (EXIT_SUCCESS); +} diff --git a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp new file mode 100644 index 00000000000..eb8c0552e0a --- /dev/null +++ b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp @@ -0,0 +1,62 @@ +// Copyright (c) 2020 by Apex.AI Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "iceoryx_posh/popo/active_call_set.hpp" +#include "iceoryx_posh/popo/typed_subscriber.hpp" +#include "iceoryx_posh/popo/user_trigger.hpp" +#include "iceoryx_posh/runtime/posh_runtime.hpp" +#include "topic_data.hpp" + +#include +#include +#include + +iox::popo::UserTrigger shutdownTrigger; + +static void sigHandler(int f_sig [[gnu::unused]]) +{ + shutdownTrigger.trigger(); +} + +void shutdownTriggerCallback(iox::popo::UserTrigger* trigger) +{ +} + +void subscriberCallback(iox::popo::TypedSubscriber* subscriber) +{ +} + +int main() +{ + signal(SIGINT, sigHandler); + + iox::runtime::PoshRuntime::initRuntime("iox-ex-callbacks-subscriber"); + + iox::popo::ActiveCallSet callSet; + + // attach shutdownTrigger to handle CTRL+C + callSet.attachEvent(shutdownTrigger, shutdownTriggerCallback); + + // create two subscribers, subscribe to the service and attach them to the waitset + iox::popo::TypedSubscriber subscriber1({"Radar", "FrontLeft", "Counter"}); + + subscriber1.subscribe(); + + callSet.attachEvent(subscriber1, iox::popo::SubscriberEvent::HAS_SAMPLES, subscriberCallback); + + callSet.detachEvent(shutdownTrigger); + callSet.detachEvent(subscriber1, iox::popo::SubscriberEvent::HAS_SAMPLES); + + return (EXIT_SUCCESS); +} diff --git a/iceoryx_examples/callbacks/topic_data.hpp b/iceoryx_examples/callbacks/topic_data.hpp new file mode 100644 index 00000000000..a48f4ed746b --- /dev/null +++ b/iceoryx_examples/callbacks/topic_data.hpp @@ -0,0 +1,25 @@ +// Copyright (c) 2020 by Apex.AI Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef IOX_EXAMPLES_WAITSET_TOPIC_DATA_HPP +#define IOX_EXAMPLES_WAITSET_TOPIC_DATA_HPP + +#include + +struct CounterTopic +{ + uint32_t counter; +}; + +#endif // IOX_EXAMPLES_WAITSET_TOPIC_DATA_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl index 7d4471315ea..c60203269f9 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl @@ -31,24 +31,24 @@ template inline cxx::expected ActiveCallSet::attachEvent(T& eventOrigin, CallbackRef_t eventCallback) noexcept { - addEvent(&eventOrigin, - 0U, - typeid(void).hash_code(), - reinterpret_cast>(eventCallback), - internal::callsetCallback); - return cxx::success<>(); + return addEvent(&eventOrigin, + 0U, + typeid(void).hash_code(), + reinterpret_cast>(eventCallback), + internal::callsetCallback, + EventAttorney::getInvalidateTriggerMethod(eventOrigin)); } template ::value>> inline cxx::expected ActiveCallSet::attachEvent(T& eventOrigin, const EventType eventType, CallbackRef_t eventCallback) noexcept { - addEvent(&eventOrigin, - static_cast(eventType), - typeid(EventType).hash_code(), - reinterpret_cast>(eventCallback), - internal::callsetCallback); - return cxx::success<>(); + return addEvent(&eventOrigin, + static_cast(eventType), + typeid(EventType).hash_code(), + reinterpret_cast>(eventCallback), + internal::callsetCallback, + EventAttorney::getInvalidateTriggerMethod(eventOrigin)); } template ::value>> diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp index ff760d2d653..2e2b81f1774 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -16,7 +16,9 @@ #define IOX_POSH_POPO_ACTIVE_CALL_SET_HPP #include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" +#include "iceoryx_posh/popo/event_attorney.hpp" #include "iceoryx_utils/cxx/expected.hpp" +#include "iceoryx_utils/cxx/method_callback.hpp" #include "iceoryx_utils/cxx/types.hpp" #include "iceoryx_utils/internal/concurrent/loffli.hpp" #include "iceoryx_utils/internal/concurrent/smart_lock.hpp" @@ -72,7 +74,8 @@ class ActiveCallSet const uint64_t eventType, const uint64_t eventTypeHash, CallbackRef_t callback, - TranslationCallbackRef_t translationCallback) noexcept; + TranslationCallbackRef_t translationCallback, + const cxx::MethodCallback invalidationCallback) noexcept; void removeEvent(void* const origin, const uint64_t eventType, const uint64_t eventTypeHash) noexcept; void removeTrigger(const uint64_t index) noexcept; @@ -98,6 +101,7 @@ class ActiveCallSet uint64_t m_eventTypeHash = 0U; CallbackPtr_t m_callback = nullptr; TranslationCallbackPtr_t m_translationCallback = nullptr; + cxx::MethodCallback m_invalidationCallback; }; std::thread m_thread; diff --git a/iceoryx_posh/include/iceoryx_posh/popo/event_attorney.hpp b/iceoryx_posh/include/iceoryx_posh/popo/event_attorney.hpp index 0b0f153e617..38f70531abe 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/event_attorney.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/event_attorney.hpp @@ -30,6 +30,7 @@ class EventAttorney { template friend class WaitSet; + friend class ActiveCallSet; private: template diff --git a/iceoryx_posh/source/popo/active_call_set.cpp b/iceoryx_posh/source/popo/active_call_set.cpp index d1d5a0eeec8..5ca46935e0b 100644 --- a/iceoryx_posh/source/popo/active_call_set.cpp +++ b/iceoryx_posh/source/popo/active_call_set.cpp @@ -43,11 +43,13 @@ ActiveCallSet::~ActiveCallSet() m_eventVariable->m_toBeDestroyed.store(true, std::memory_order_relaxed); } -cxx::expected ActiveCallSet::addEvent(void* const origin, - const uint64_t eventType, - const uint64_t eventTypeHash, - CallbackRef_t callback, - TranslationCallbackRef_t translationCallback) noexcept +cxx::expected +ActiveCallSet::addEvent(void* const origin, + const uint64_t eventType, + const uint64_t eventTypeHash, + CallbackRef_t callback, + TranslationCallbackRef_t translationCallback, + const cxx::MethodCallback invalidationCallback) noexcept { std::lock_guard lock(m_addEventMutex); @@ -88,7 +90,10 @@ void ActiveCallSet::threadLoop() noexcept { auto activateNotificationIds = eventListener.wait(); - cxx::forEach(activateNotificationIds, [this](auto id) { m_events[id]->executeCallback(); }); + cxx::forEach(activateNotificationIds, [this, &eventListener](auto id) { + eventListener.reset(id); + m_events[id]->executeCallback(); + }); } } From 11dddd39cdf47124885f7ced1c9dc335a6aba78c Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 2 Feb 2021 13:51:59 +0100 Subject: [PATCH 018/143] iox-#350 add event variable methods to port manager, port pool and roudi process Signed-off-by: Marika Lehmann --- .../building_blocks/event_variable_data.hpp | 1 + .../internal/roudi/port_manager.hpp | 9 ++++- .../internal/roudi/port_pool_data.hpp | 2 + .../internal/roudi/roudi_process.hpp | 2 + .../include/iceoryx_posh/roudi/port_pool.hpp | 6 +++ .../building_blocks/event_variable_data.cpp | 4 ++ iceoryx_posh/source/roudi/port_manager.cpp | 29 ++++++++++++++ iceoryx_posh/source/roudi/port_pool.cpp | 25 ++++++++++++ iceoryx_posh/source/roudi/roudi.cpp | 15 ++++++++ iceoryx_posh/source/roudi/roudi_process.cpp | 38 +++++++++++++++++++ .../error_handling/error_handling.hpp | 1 + 11 files changed, 131 insertions(+), 1 deletion(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp index d6a5cd49b40..1bcc0f9825c 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp @@ -24,6 +24,7 @@ namespace popo struct EventVariableData : public ConditionVariableData { EventVariableData() noexcept; + EventVariableData(const ProcessName_t& process) noexcept; std::atomic_bool m_activeNotifications[MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET]; }; diff --git a/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp b/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp index b0823ab70ea..90f56b9e3ca 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp @@ -18,6 +18,7 @@ #include "iceoryx_posh/iceoryx_posh_types.hpp" #include "iceoryx_posh/internal/capro/capro_message.hpp" #include "iceoryx_posh/internal/mepoo/memory_manager.hpp" +#include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" #include "iceoryx_posh/internal/popo/ports/application_port.hpp" #include "iceoryx_posh/internal/popo/ports/interface_port.hpp" #include "iceoryx_posh/internal/popo/ports/publisher_port_roudi.hpp" @@ -86,6 +87,9 @@ class PortManager cxx::expected acquireConditionVariableData(const ProcessName_t& process) noexcept; + cxx::expected + acquireEventVariableData(const ProcessName_t& process) noexcept; + void deletePortsOfProcess(const ProcessName_t& processName) noexcept; void destroyPublisherPort(PublisherPortRouDiType::MemberType_t* const publisherPortData) noexcept; @@ -108,6 +112,8 @@ class PortManager void handleConditionVariables() noexcept; + void handleEventVariables() noexcept; + bool sendToAllMatchingPublisherPorts(const capro::CaproMessage& message, SubscriberPortType& subscriberSource) noexcept; @@ -120,7 +126,8 @@ class PortManager void removeEntryFromServiceRegistry(const capro::IdString_t& service, const capro::IdString_t& instance) noexcept; template ::value>* = nullptr> - cxx::optional doesViolateCommunicationPolicy(const capro::ServiceDescription& service) const noexcept; + cxx::optional + doesViolateCommunicationPolicy(const capro::ServiceDescription& service) const noexcept; template ::value>* = nullptr> cxx::optional doesViolateCommunicationPolicy(const capro::ServiceDescription& service diff --git a/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_pool_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_pool_data.hpp index 53a494bb452..2db247992fc 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_pool_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_pool_data.hpp @@ -16,6 +16,7 @@ #include "iceoryx_posh/iceoryx_posh_types.hpp" #include "iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp" +#include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" #include "iceoryx_posh/internal/popo/ports/application_port.hpp" #include "iceoryx_posh/internal/popo/ports/interface_port.hpp" #include "iceoryx_posh/internal/popo/ports/publisher_port_data.hpp" @@ -54,6 +55,7 @@ struct PortPoolData FixedPositionContainer m_applicationPortMembers; FixedPositionContainer m_nodeMembers; FixedPositionContainer m_conditionVariableMembers; + FixedPositionContainer m_eventVariableMembers; FixedPositionContainer m_publisherPortMembers; FixedPositionContainer m_subscriberPortMembers; diff --git a/iceoryx_posh/include/iceoryx_posh/internal/roudi/roudi_process.hpp b/iceoryx_posh/include/iceoryx_posh/internal/roudi/roudi_process.hpp index 2a70bdacb64..a539349634d 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/roudi/roudi_process.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/roudi/roudi_process.hpp @@ -156,6 +156,8 @@ class ProcessManager : public ProcessManagerInterface void addConditionVariableForProcess(const ProcessName_t& processName) noexcept; + void addEventVariableForProcess(const ProcessName_t& processName) noexcept; + void initIntrospection(ProcessIntrospectionType* processIntrospection) noexcept; void run() noexcept; diff --git a/iceoryx_posh/include/iceoryx_posh/roudi/port_pool.hpp b/iceoryx_posh/include/iceoryx_posh/roudi/port_pool.hpp index 2158cb06b0f..025ea21163c 100644 --- a/iceoryx_posh/include/iceoryx_posh/roudi/port_pool.hpp +++ b/iceoryx_posh/include/iceoryx_posh/roudi/port_pool.hpp @@ -16,6 +16,7 @@ #include "iceoryx_posh/iceoryx_posh_types.hpp" #include "iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp" +#include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" #include "iceoryx_posh/internal/popo/ports/application_port.hpp" #include "iceoryx_posh/internal/popo/ports/interface_port.hpp" #include "iceoryx_posh/internal/popo/ports/publisher_port_data.hpp" @@ -43,6 +44,7 @@ enum class PortPoolError : uint8_t APPLICATION_PORT_LIST_FULL, NODE_DATA_LIST_FULL, CONDITION_VARIABLE_LIST_FULL, + EVENT_VARIABLE_LIST_FULL, }; class PortPool @@ -62,6 +64,7 @@ class PortPool cxx::vector getNodeDataList() noexcept; cxx::vector getConditionVariableDataList() noexcept; + cxx::vector getEventVariableDataList() noexcept; cxx::expected addPublisherPort(const capro::ServiceDescription& serviceDescription, @@ -100,12 +103,15 @@ class PortPool cxx::expected addConditionVariableData(const ProcessName_t& process) noexcept; + cxx::expected addEventVariableData(const ProcessName_t& process) noexcept; + void removePublisherPort(PublisherPortRouDiType::MemberType_t* const portData) noexcept; void removeSubscriberPort(SubscriberPortType::MemberType_t* const portData) noexcept; void removeInterfacePort(popo::InterfacePortData* const portData) noexcept; void removeApplicationPort(popo::ApplicationPortData* const portData) noexcept; void removeNodeData(runtime::NodeData* const nodeData) noexcept; void removeConditionVariableData(popo::ConditionVariableData* const conditionVariableData) noexcept; + void removeEventVariableData(popo::EventVariableData* const eventVariableData) noexcept; std::atomic* serviceRegistryChangeCounter() noexcept; diff --git a/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp b/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp index ed118e6b37f..68984e3350c 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp @@ -22,6 +22,10 @@ EventVariableData::EventVariableData() noexcept { iox::cxx::forEach(m_activeNotifications, [](auto& id) { id.store(false, std::memory_order_relaxed); }); } +EventVariableData::EventVariableData(const ProcessName_t& process) noexcept + : ConditionVariableData(process) +{ +} } // namespace popo } // namespace iox diff --git a/iceoryx_posh/source/roudi/port_manager.cpp b/iceoryx_posh/source/roudi/port_manager.cpp index 21dd70052b1..1425255b198 100644 --- a/iceoryx_posh/source/roudi/port_manager.cpp +++ b/iceoryx_posh/source/roudi/port_manager.cpp @@ -123,6 +123,8 @@ void PortManager::doDiscovery() noexcept handleNodes(); handleConditionVariables(); + + handleEventVariables(); } void PortManager::handlePublisherPorts() noexcept @@ -346,6 +348,18 @@ void PortManager::handleConditionVariables() noexcept } } +void PortManager::handleEventVariables() noexcept +{ + for (auto eventVariableData : m_portPool->getEventVariableDataList()) + { + if (eventVariableData->m_toBeDestroyed.load(std::memory_order_relaxed)) + { + m_portPool->removeEventVariableData(eventVariableData); + LogDebug() << "Destroyed EventVariableData"; + } + } +} + bool PortManager::sendToAllMatchingPublisherPorts(const capro::CaproMessage& message, SubscriberPortType& subscriberSource) noexcept { @@ -483,6 +497,15 @@ void PortManager::deletePortsOfProcess(const ProcessName_t& processName) noexcep LogDebug() << "Deleted condition variable of application" << processName; } } + + for (auto eventVariableData : m_portPool->getEventVariableDataList()) + { + if (processName == eventVariableData->m_process) + { + m_portPool->removeEventVariableData(eventVariableData); + LogDebug() << "Deleted event variable of application" << processName; + } + } } void PortManager::destroyPublisherPort(PublisherPortRouDiType::MemberType_t* const publisherPortData) noexcept @@ -677,5 +700,11 @@ PortManager::acquireConditionVariableData(const ProcessName_t& process) noexcept return m_portPool->addConditionVariableData(process); } +cxx::expected +PortManager::acquireEventVariableData(const ProcessName_t& process) noexcept +{ + return m_portPool->addEventVariableData(process); +} + } // namespace roudi } // namespace iox diff --git a/iceoryx_posh/source/roudi/port_pool.cpp b/iceoryx_posh/source/roudi/port_pool.cpp index 3a2721801c3..3696effb0e2 100644 --- a/iceoryx_posh/source/roudi/port_pool.cpp +++ b/iceoryx_posh/source/roudi/port_pool.cpp @@ -46,6 +46,11 @@ PortPool::getConditionVariableDataList() noexcept return m_portPoolData->m_conditionVariableMembers.content(); } +cxx::vector PortPool::getEventVariableDataList() noexcept +{ + return m_portPoolData->m_eventVariableMembers.content(); +} + cxx::expected PortPool::addInterfacePort(const ProcessName_t& applicationName, const capro::Interfaces interface) noexcept { @@ -107,6 +112,21 @@ PortPool::addConditionVariableData(const ProcessName_t& process) noexcept } } +cxx::expected +PortPool::addEventVariableData(const ProcessName_t& process) noexcept +{ + if (m_portPoolData->m_eventVariableMembers.hasFreeSpace()) + { + auto eventVariableData = m_portPoolData->m_eventVariableMembers.insert(process); + return cxx::success(eventVariableData); + } + else + { + errorHandler(Error::kPORT_POOL__EVENT_VARIABLE_LIST_OVERFLOW, nullptr, ErrorLevel::MODERATE); + return cxx::error(PortPoolError::EVENT_VARIABLE_LIST_FULL); + } +} + void PortPool::removeInterfacePort(popo::InterfacePortData* const portData) noexcept { m_portPoolData->m_interfacePortMembers.erase(portData); @@ -127,6 +147,11 @@ void PortPool::removeConditionVariableData(popo::ConditionVariableData* const co m_portPoolData->m_conditionVariableMembers.erase(conditionVariableData); } +void PortPool::removeEventVariableData(popo::EventVariableData* const eventVariableData) noexcept +{ + m_portPoolData->m_eventVariableMembers.erase(eventVariableData); +} + std::atomic* PortPool::serviceRegistryChangeCounter() noexcept { return &m_portPoolData->m_serviceRegistryChangeCounter; diff --git a/iceoryx_posh/source/roudi/roudi.cpp b/iceoryx_posh/source/roudi/roudi.cpp index 953e28eff83..b89b00eab7b 100644 --- a/iceoryx_posh/source/roudi/roudi.cpp +++ b/iceoryx_posh/source/roudi/roudi.cpp @@ -235,6 +235,21 @@ void RouDi::processMessage(const runtime::MqMessage& message, } break; } + case runtime::MqMessageType::CREATE_EVENT_VARIABLE: + { + if (message.getNumberOfElements() != 2) + { + LogError() << "Wrong number of parameters for \"MqMessageType::CREATE_EVENT_VARIABLE\" from \"" + << processName << "\"received!"; + errorHandler( + Error::kPORT_MANAGER__INTROSPECTION_MEMORY_MANAGER_UNAVAILABLE, nullptr, iox::ErrorLevel::MODERATE); + } + else + { + m_prcMgr.addEventVariableForProcess(processName); + } + break; + } case runtime::MqMessageType::CREATE_INTERFACE: { if (message.getNumberOfElements() != 4) diff --git a/iceoryx_posh/source/roudi/roudi_process.cpp b/iceoryx_posh/source/roudi/roudi_process.cpp index d919a9a81f2..852550960ce 100644 --- a/iceoryx_posh/source/roudi/roudi_process.cpp +++ b/iceoryx_posh/source/roudi/roudi_process.cpp @@ -747,6 +747,44 @@ void ProcessManager::addConditionVariableForProcess(const ProcessName_t& process } } +void ProcessManager::addEventVariableForProcess(const ProcessName_t& processName) noexcept +{ + std::lock_guard g(m_mutex); + + RouDiProcess* process = getProcessFromList(processName); + if (nullptr != process) + { + // Try to create a event variable + m_portManager.acquireEventVariableData(processName) + .and_then([&](auto condVar) { + auto offset = RelativePointer::getOffset(m_mgmtSegmentId, condVar); + + runtime::MqMessage sendBuffer; + sendBuffer << runtime::mqMessageTypeToString(runtime::MqMessageType::CREATE_EVENT_VARIABLE_ACK) + << std::to_string(offset) << std::to_string(m_mgmtSegmentId); + process->sendToMQ(sendBuffer); + + LogDebug() << "Created new EventVariable for application " << processName; + }) + .or_else([&](PortPoolError error) { + runtime::MqMessage sendBuffer; + sendBuffer << runtime::mqMessageTypeToString(runtime::MqMessageType::ERROR); + if (error == PortPoolError::EVENT_VARIABLE_LIST_FULL) + { + sendBuffer << runtime::mqMessageErrorTypeToString( + runtime::MqMessageErrorType::EVENT_VARIABLE_LIST_FULL); + } + process->sendToMQ(sendBuffer); + + LogDebug() << "Could not create new EventVariable for application " << processName; + }); + } + else + { + LogWarn() << "Unknown application " << processName << " requested a EventVariable."; + } +} + void ProcessManager::initIntrospection(ProcessIntrospectionType* processIntrospection) noexcept { m_processIntrospection = processIntrospection; diff --git a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp index ceca48cd303..9dde425cccf 100644 --- a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp +++ b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp @@ -105,6 +105,7 @@ namespace iox error(PORT_POOL__APPLICATIONLIST_OVERFLOW) \ error(PORT_POOL__NODELIST_OVERFLOW) \ error(PORT_POOL__CONDITION_VARIABLE_LIST_OVERFLOW) \ + error(PORT_POOL__EVENT_VARIABLE_LIST_OVERFLOW) \ error(PORT_MANAGER__PORT_POOL_UNAVAILABLE) \ error(PORT_MANAGER__INTROSPECTION_MEMORY_MANAGER_UNAVAILABLE) \ error(PORT_MANAGER__HANDLE_PUBLISHER_PORTS_INVALID_CAPRO_MESSAGE) \ From 44a389e2bfc65b72cc9ec51a1a57f9e69a616a22 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 2 Feb 2021 13:58:57 +0100 Subject: [PATCH 019/143] iox-#350 active call set basics finished and draft example implementeD Signed-off-by: Christian Eltzschig --- .../callbacks/ice_callbacks_subscriber.cpp | 3 ++ .../internal/popo/active_call_set.inl | 19 +++++++--- .../iceoryx_posh/popo/active_call_set.hpp | 38 ++++++++++++++----- iceoryx_posh/source/popo/active_call_set.cpp | 26 ++++++++++--- 4 files changed, 65 insertions(+), 21 deletions(-) diff --git a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp index eb8c0552e0a..dfb4e68ecf2 100644 --- a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp +++ b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp @@ -55,6 +55,9 @@ int main() callSet.attachEvent(subscriber1, iox::popo::SubscriberEvent::HAS_SAMPLES, subscriberCallback); + std::this_thread::sleep_for(std::chrono::seconds(100000)); + + callSet.detachEvent(shutdownTrigger); callSet.detachEvent(subscriber1, iox::popo::SubscriberEvent::HAS_SAMPLES); diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl index c60203269f9..c48ab0ae4e8 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl @@ -32,11 +32,15 @@ inline cxx::expected ActiveCallSet::attachEvent(T& eventOrig CallbackRef_t eventCallback) noexcept { return addEvent(&eventOrigin, - 0U, - typeid(void).hash_code(), + static_cast(NoEnumUsed::PLACEHOLDER), + typeid(NoEnumUsed).hash_code(), reinterpret_cast>(eventCallback), internal::callsetCallback, - EventAttorney::getInvalidateTriggerMethod(eventOrigin)); + EventAttorney::getInvalidateTriggerMethod(eventOrigin)) + .and_then([&](auto& eventId) { + EventAttorney::enableEvent(eventOrigin, + TriggerHandle(m_eventVariable, {*this, &ActiveCallSet::removeTrigger}, eventId)); + }); } template ::value>> @@ -48,7 +52,12 @@ ActiveCallSet::attachEvent(T& eventOrigin, const EventType eventType, CallbackRe typeid(EventType).hash_code(), reinterpret_cast>(eventCallback), internal::callsetCallback, - EventAttorney::getInvalidateTriggerMethod(eventOrigin)); + EventAttorney::getInvalidateTriggerMethod(eventOrigin)) + .and_then([&](auto& eventId) { + EventAttorney::enableEvent(eventOrigin, + TriggerHandle(m_eventVariable, {*this, &ActiveCallSet::removeTrigger}, eventId), + eventType); + }); } template ::value>> @@ -60,7 +69,7 @@ inline void ActiveCallSet::detachEvent(T& eventOrigin, const EventType eventType template inline void ActiveCallSet::detachEvent(T& eventOrigin) noexcept { - removeEvent(&eventOrigin, 0U, typeid(void).hash_code()); + detachEvent(eventOrigin, NoEnumUsed::PLACEHOLDER); } diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp index 2e2b81f1774..fdfb3877d28 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -17,6 +17,7 @@ #include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" #include "iceoryx_posh/popo/event_attorney.hpp" +#include "iceoryx_posh/popo/trigger_handle.hpp" #include "iceoryx_utils/cxx/expected.hpp" #include "iceoryx_utils/cxx/method_callback.hpp" #include "iceoryx_utils/cxx/types.hpp" @@ -70,37 +71,54 @@ class ActiveCallSet class Event_t; void threadLoop() noexcept; - cxx::expected addEvent(void* const origin, - const uint64_t eventType, - const uint64_t eventTypeHash, - CallbackRef_t callback, - TranslationCallbackRef_t translationCallback, - const cxx::MethodCallback invalidationCallback) noexcept; + cxx::expected + addEvent(void* const origin, + const uint64_t eventType, + const uint64_t eventTypeHash, + CallbackRef_t callback, + TranslationCallbackRef_t translationCallback, + const cxx::MethodCallback invalidationCallback) noexcept; void removeEvent(void* const origin, const uint64_t eventType, const uint64_t eventTypeHash) noexcept; void removeTrigger(const uint64_t index) noexcept; private: + enum class NoEnumUsed + { + PLACEHOLDER = 0 + }; + class Event_t { public: + ~Event_t(); + bool isEqualTo(const void* const origin, const uint64_t eventType, const uint64_t eventTypeHash) const noexcept; bool resetIfEqualTo(const void* const origin, const uint64_t eventType, const uint64_t eventTypeHash) noexcept; bool reset() noexcept; - void init(void* const origin, + void init(const uint64_t eventId, + void* const origin, const uint64_t eventType, const uint64_t eventTypeHash, CallbackRef_t callback, - TranslationCallbackRef_t translationCallback) noexcept; + TranslationCallbackRef_t translationCallback, + const cxx::MethodCallback invalidationCallback) noexcept; void executeCallback() noexcept; bool isInitialized() const noexcept; private: + static constexpr uint64_t INVALID_ID = std::numeric_limits::max(); + + // EventInfo void* m_origin = nullptr; - uint64_t m_eventType = 0U; - uint64_t m_eventTypeHash = 0U; + uint64_t m_eventType = INVALID_ID; + uint64_t m_eventTypeHash = INVALID_ID; + CallbackPtr_t m_callback = nullptr; TranslationCallbackPtr_t m_translationCallback = nullptr; + + // TriggerHandle + uint64_t m_eventId = INVALID_ID; cxx::MethodCallback m_invalidationCallback; }; diff --git a/iceoryx_posh/source/popo/active_call_set.cpp b/iceoryx_posh/source/popo/active_call_set.cpp index 5ca46935e0b..0bc9bb7e285 100644 --- a/iceoryx_posh/source/popo/active_call_set.cpp +++ b/iceoryx_posh/source/popo/active_call_set.cpp @@ -43,7 +43,7 @@ ActiveCallSet::~ActiveCallSet() m_eventVariable->m_toBeDestroyed.store(true, std::memory_order_relaxed); } -cxx::expected +cxx::expected ActiveCallSet::addEvent(void* const origin, const uint64_t eventType, const uint64_t eventTypeHash, @@ -67,8 +67,8 @@ ActiveCallSet::addEvent(void* const origin, return cxx::error(ActiveCallSetError::ACTIVE_CALL_SET_FULL); } - m_events[index]->init(origin, eventType, eventTypeHash, callback, translationCallback); - return cxx::success<>(); + m_events[index]->init(index, origin, eventType, eventTypeHash, callback, translationCallback, invalidationCallback); + return cxx::success(index); } void ActiveCallSet::removeEvent(void* const origin, const uint64_t eventType, const uint64_t eventTypeHash) noexcept @@ -113,6 +113,11 @@ void ActiveCallSet::removeTrigger(const uint64_t index) noexcept //////////////// // Event_t //////////////// +ActiveCallSet::Event_t::~Event_t() +{ + reset(); +} + void ActiveCallSet::Event_t::executeCallback() noexcept { if (!isInitialized()) @@ -123,17 +128,21 @@ void ActiveCallSet::Event_t::executeCallback() noexcept m_translationCallback(m_origin, m_callback); } -void ActiveCallSet::Event_t::init(void* const origin, +void ActiveCallSet::Event_t::init(const uint64_t eventId, + void* const origin, const uint64_t eventType, const uint64_t eventTypeHash, CallbackRef_t callback, - TranslationCallbackRef_t translationCallback) noexcept + TranslationCallbackRef_t translationCallback, + const cxx::MethodCallback invalidationCallback) noexcept { + m_eventId = eventId; m_origin = origin; m_eventType = eventType; m_eventTypeHash = eventTypeHash; m_callback = &callback; m_translationCallback = &translationCallback; + m_invalidationCallback = invalidationCallback; } bool ActiveCallSet::Event_t::isEqualTo(const void* const origin, @@ -154,10 +163,15 @@ bool ActiveCallSet::Event_t::reset() noexcept { if (isInitialized()) { + m_invalidationCallback(m_eventId); + + m_eventId = INVALID_ID; m_origin = nullptr; - m_eventType = 0U; + m_eventType = INVALID_ID; + m_eventTypeHash = INVALID_ID; m_callback = nullptr; m_translationCallback = nullptr; + m_invalidationCallback = cxx::MethodCallback(); return true; } From fbe4c4a3488e95cc5c82d26ca471aba2a5d02c6c Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 2 Feb 2021 14:32:27 +0100 Subject: [PATCH 020/143] iox-#350 add tests for getMiddlewareEventVariable Signed-off-by: Marika Lehmann --- .../test/moduletests/test_posh_runtime.cpp | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp index d9b2308d33c..8efa1387349 100644 --- a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp +++ b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp @@ -401,6 +401,36 @@ TEST_F(PoshRuntime_test, GetMiddlewareConditionVariableListOverflow) EXPECT_TRUE(conditionVariableListOverflowDetected); } +TEST_F(PoshRuntime_test, GetMiddlewareEventVariableIsSuccessful) +{ + auto eventVariable = m_runtime->getMiddlewareEventVariable(); + EXPECT_THAT(eventVariable, Ne(nullptr)); +} + +TEST_F(PoshRuntime_test, GetMiddlewareEventVariableListOverflow) +{ + auto eventVariableListOverflowDetected{false}; + auto errorHandlerGuard = iox::ErrorHandler::SetTemporaryErrorHandler( + [&eventVariableListOverflowDetected]( + const iox::Error error, const std::function, const iox::ErrorLevel) { + if (error == iox::Error::kPORT_POOL__EVENT_VARIABLE_LIST_OVERFLOW) + { + eventVariableListOverflowDetected = true; + } + }); + + for (uint32_t i = 0U; i < iox::MAX_NUMBER_OF_EVENT_VARIABLES; ++i) + { + auto eventVariable = m_runtime->getMiddlewareEventVariable(); + ASSERT_THAT(eventVariable, Ne(nullptr)); + } + EXPECT_THAT(eventVariableListOverflowDetected, Eq(false)); + + auto eventVariable = m_runtime->getMiddlewareEventVariable(); + EXPECT_THAT(eventVariable, Eq(nullptr)); + EXPECT_THAT(eventVariableListOverflowDetected, Eq(true)); +} + TIMING_TEST_F(PoshRuntime_test, GetServiceRegistryChangeCounterOfferStopOfferService, Repeat(5), [&] { auto serviceCounter = m_runtime->getServiceRegistryChangeCounter(); auto initialCout = serviceCounter->load(); From 54b9bc812772dc5db63f9c1b0e5dc4af71d5cb46 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 2 Feb 2021 14:50:41 +0100 Subject: [PATCH 021/143] iox-#350 removed copy/move ctor/assignment and integrated threadloop Signed-off-by: Christian Eltzschig --- iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp | 1 - iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp | 5 +++++ iceoryx_posh/source/popo/active_call_set.cpp | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp index dfb4e68ecf2..25b6d45a0b3 100644 --- a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp +++ b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp @@ -57,7 +57,6 @@ int main() std::this_thread::sleep_for(std::chrono::seconds(100000)); - callSet.detachEvent(shutdownTrigger); callSet.detachEvent(subscriber1, iox::popo::SubscriberEvent::HAS_SAMPLES); diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp index fdfb3877d28..3ba311da8cc 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -49,8 +49,13 @@ class ActiveCallSet using TranslationCallbackPtr_t = void (*)(void* const, void (*const)(void* const)); ActiveCallSet() noexcept; + ActiveCallSet(const ActiveCallSet&) = delete; + ActiveCallSet(ActiveCallSet&&) = delete; ~ActiveCallSet(); + ActiveCallSet& operator=(const ActiveCallSet&) = delete; + ActiveCallSet& operator=(ActiveCallSet&&) = delete; + template cxx::expected attachEvent(T& eventOrigin, CallbackRef_t eventCallback) noexcept; diff --git a/iceoryx_posh/source/popo/active_call_set.cpp b/iceoryx_posh/source/popo/active_call_set.cpp index 0bc9bb7e285..6bb11cb041a 100644 --- a/iceoryx_posh/source/popo/active_call_set.cpp +++ b/iceoryx_posh/source/popo/active_call_set.cpp @@ -31,6 +31,7 @@ ActiveCallSet::ActiveCallSet(EventVariableData* eventVariable) noexcept : m_eventVariable(eventVariable) { m_indexManager.init(m_loffliStorage, MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); + m_thread = std::thread(&ActiveCallSet::threadLoop, this); } ActiveCallSet::~ActiveCallSet() @@ -41,6 +42,8 @@ ActiveCallSet::~ActiveCallSet() m_eventVariable->m_semaphore.post(); m_eventVariable->m_toBeDestroyed.store(true, std::memory_order_relaxed); + + m_thread.join(); } cxx::expected From afe679207600a97ca82173810d9fc74d6484b44d Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 2 Feb 2021 15:15:05 +0100 Subject: [PATCH 022/143] iox-#350 add tests for acquireEventVariableData Signed-off-by: Marika Lehmann --- .../moduletests/test_roudi_portmanager.cpp | 105 +++++++++++++++++- 1 file changed, 103 insertions(+), 2 deletions(-) diff --git a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp index 67703916f65..0d7a0a4e8fa 100644 --- a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp +++ b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp @@ -439,6 +439,109 @@ TEST_F(PortManager_test, ConditionVariablesDestroy) } } +TEST_F(PortManager_test, AcquiringMaximumNumberOfEventVariablesWorks) +{ + std::string process = "BuddyHolly"; + + for (unsigned int i = 0U; i < iox::MAX_NUMBER_OF_EVENT_VARIABLES; i++) + { + iox::ProcessName_t newProcessName(iox::cxx::TruncateToCapacity, process + std::to_string(i)); + auto eventVariableDataResult = m_portManager->acquireEventVariableData(newProcessName); + EXPECT_THAT(eventVariableDataResult.has_error(), Eq(false)); + } +} + +TEST_F(PortManager_test, AcquiringOneMoreThanMaximumNumberOfEventVariableFails) +{ + std::string process = "BuddyHollysBrille"; + + // first acquire all possible event variables + for (unsigned int i = 0U; i < iox::MAX_NUMBER_OF_EVENT_VARIABLES; i++) + { + iox::ProcessName_t newProcessName(iox::cxx::TruncateToCapacity, process + std::to_string(i)); + auto eventVariableDataResult = m_portManager->acquireEventVariableData(newProcessName); + ASSERT_THAT(eventVariableDataResult.has_error(), Eq(false)); + } + + // test if overflow errors get hit + auto errorHandlerCalled{false}; + auto errorHandlerGuard = iox::ErrorHandler::SetTemporaryErrorHandler( + [&errorHandlerCalled](const iox::Error, const std::function, const iox::ErrorLevel) { + errorHandlerCalled = true; + }); + + auto eventVariableDataResult = m_portManager->acquireEventVariableData("AnotherBrille"); + EXPECT_THAT(eventVariableDataResult.has_error(), Eq(true)); + EXPECT_THAT(errorHandlerCalled, Eq(true)); + EXPECT_THAT(eventVariableDataResult.get_error(), Eq(PortPoolError::EVENT_VARIABLE_LIST_FULL)); +} + +TEST_F(PortManager_test, DeletingEventVariableWorks) +{ + std::string process = "BudSpencer"; + + // first acquire all possible event variables + for (unsigned int i = 0U; i < iox::MAX_NUMBER_OF_EVENT_VARIABLES; i++) + { + iox::ProcessName_t newProcessName(iox::cxx::TruncateToCapacity, process + std::to_string(i)); + auto eventVariableDataResult = m_portManager->acquireEventVariableData(newProcessName); + ASSERT_THAT(eventVariableDataResult.has_error(), Eq(false)); + } + + // test if overflow errors get hit + auto errorHandlerCalled{false}; + auto errorHandlerGuard = iox::ErrorHandler::SetTemporaryErrorHandler( + [&errorHandlerCalled](const iox::Error, const std::function, const iox::ErrorLevel) { + errorHandlerCalled = true; + }); + + auto eventVariableDataResult = m_portManager->acquireEventVariableData("AnotherItalianActor"); + ASSERT_THAT(eventVariableDataResult.has_error(), Eq(true)); + ASSERT_THAT(errorHandlerCalled, Eq(true)); + ASSERT_THAT(eventVariableDataResult.get_error(), Eq(PortPoolError::EVENT_VARIABLE_LIST_FULL)); + + // delete one and add one eventVariableDataResult should be possible now + unsigned int i = 0U; + iox::ProcessName_t newProcessName(iox::cxx::TruncateToCapacity, process + std::to_string(i)); + m_portManager->deletePortsOfProcess(newProcessName); + + eventVariableDataResult = m_portManager->acquireEventVariableData(newProcessName); + EXPECT_THAT(eventVariableDataResult.has_error(), Eq(false)); +} + +TEST_F(PortManager_test, DestroyEventVariableAndAddNewOneSucceeds) +{ + iox::ProcessName_t process = "Terence Hill"; + std::vector eventVariableContainer; + + // first acquire all possible event variables + for (unsigned int i = 0U; i < iox::MAX_NUMBER_OF_EVENT_VARIABLES; i++) + { + auto eventVariableDataResult = m_portManager->acquireEventVariableData(process); + EXPECT_THAT(eventVariableDataResult.has_error(), Eq(false)); + eventVariableContainer.push_back(eventVariableDataResult.value()); + } + + // so now no event variables should be available + auto eventVariableDataResult = m_portManager->acquireEventVariableData(process); + EXPECT_THAT(eventVariableDataResult.has_error(), Eq(true)); + + // set the destroy flag and let the discovery loop take care + for (unsigned int i = 0U; i < iox::MAX_NUMBER_OF_EVENT_VARIABLES; i++) + { + eventVariableContainer[i]->m_toBeDestroyed.store(true, std::memory_order_relaxed); + } + m_portManager->doDiscovery(); + eventVariableContainer.clear(); + + // so we should be able to get some more now + for (unsigned int i = 0U; i < iox::MAX_NUMBER_OF_EVENT_VARIABLES; i++) + { + auto eventVariableDataResult = m_portManager->acquireEventVariableData(process); + EXPECT_THAT(eventVariableDataResult.has_error(), Eq(false)); + } +} + TEST_F(PortManager_test, AcquiringMaximumNumberOfNodesWorks) { std::string process = "Process"; @@ -520,7 +623,6 @@ TEST_F(PortManager_test, DeletingNodeWorks) EXPECT_THAT(nodeData.value()->m_process, StrEq(newProcessName)); } - TEST_F(PortManager_test, DestroyNodeDataAndAddNewNodeDataSucceeds) { iox::ProcessName_t process = "Humuhumunukunukuapua'a"; @@ -555,7 +657,6 @@ TEST_F(PortManager_test, DestroyNodeDataAndAddNewNodeDataSucceeds) } } - TEST_F(PortManager_test, PortDestroy) { iox::ProcessName_t p1 = "myProcess1"; From 4b2d6ddd103919efdb4768af82f0ef919001ce0d Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 2 Feb 2021 15:44:59 +0100 Subject: [PATCH 023/143] iox-#350 integrated event variable into building blocks - active call set works Signed-off-by: Christian Eltzschig --- .../callbacks/ice_callbacks_subscriber.cpp | 4 +++ .../internal/popo/base_subscriber.inl | 10 +++++++- .../popo/building_blocks/chunk_queue_data.hpp | 1 + .../building_blocks/chunk_queue_popper.hpp | 3 +++ .../building_blocks/chunk_queue_popper.inl | 9 +++++++ .../building_blocks/chunk_queue_pusher.hpp | 3 +++ .../building_blocks/chunk_queue_pusher.inl | 15 ++++++++--- .../popo/ports/subscriber_port_user.hpp | 2 ++ .../iceoryx_posh/popo/trigger_handle.hpp | 7 ++++++ .../popo/ports/subscriber_port_user.cpp | 5 ++++ iceoryx_posh/source/popo/trigger_handle.cpp | 25 ++++++++++++++++++- 11 files changed, 78 insertions(+), 6 deletions(-) diff --git a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp index 25b6d45a0b3..027797e450b 100644 --- a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp +++ b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp @@ -16,6 +16,7 @@ #include "iceoryx_posh/popo/typed_subscriber.hpp" #include "iceoryx_posh/popo/user_trigger.hpp" #include "iceoryx_posh/runtime/posh_runtime.hpp" +#include "iceoryx_utils/posix_wrapper/semaphore.hpp" #include "topic_data.hpp" #include @@ -23,6 +24,8 @@ #include iox::popo::UserTrigger shutdownTrigger; +iox::posix::Semaphore mainLoopBlocker = + iox::posix::Semaphore::create(iox::posix::CreateUnnamedSingleProcessSemaphore, 0).value(); static void sigHandler(int f_sig [[gnu::unused]]) { @@ -35,6 +38,7 @@ void shutdownTriggerCallback(iox::popo::UserTrigger* trigger) void subscriberCallback(iox::popo::TypedSubscriber* subscriber) { + subscriber->take_1_0().and_then([](auto& sample) { printf("received: %d\n", sample->counter); }); } int main() diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/base_subscriber.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/base_subscriber.inl index 4186b55dedb..52ba9fae277 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/base_subscriber.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/base_subscriber.inl @@ -158,7 +158,15 @@ BaseSubscriber::enableEvent(iox::popo::TriggerHandle&& tr [[gnu::unused]] const SubscriberEvent subscriberEvent) noexcept { m_trigger = std::move(triggerHandle); - m_port.setConditionVariable(m_trigger.getConditionVariableData()); + if (m_trigger.doesContainEventVariable()) + { + m_port.setEventVariable(*reinterpret_cast(m_trigger.getConditionVariableData()), + m_trigger.getUniqueId()); + } + else + { + m_port.setConditionVariable(m_trigger.getConditionVariableData()); + } } template diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_data.hpp index d7900113e37..5e5519c7128 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_data.hpp @@ -40,6 +40,7 @@ struct ChunkQueueData : public LockingPolicy std::atomic_bool m_queueHasOverflown{false}; relative_ptr m_conditionVariableDataPtr{nullptr}; + cxx::optional m_eventVariableIndex; }; } // namespace popo diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp index 1332cda8d7e..4677d8bab19 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp @@ -17,6 +17,7 @@ #include "iceoryx_posh/internal/mepoo/shared_chunk.hpp" #include "iceoryx_posh/internal/popo/building_blocks/chunk_queue_data.hpp" #include "iceoryx_posh/internal/popo/building_blocks/chunk_queue_types.hpp" +#include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" #include "iceoryx_utils/cxx/helplets.hpp" #include "iceoryx_utils/cxx/optional.hpp" @@ -81,6 +82,8 @@ class ChunkQueuePopper /// @param[in] ConditionVariableDataPtr, pointer to an condition variable data object void setConditionVariable(cxx::not_null conditionVariableDataPtr) noexcept; + void setEventVariable(EventVariableData& eventVariableDataPtr, const uint64_t eventId) noexcept; + /// @brief Detaches a condition variable void unsetConditionVariable() noexcept; diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.inl index 61617e43051..b05f4a5a91c 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.inl @@ -124,11 +124,20 @@ inline void ChunkQueuePopper::setConditionVariable( getMembers()->m_conditionVariableDataPtr = conditionVariableDataPtr; } +template +inline void ChunkQueuePopper::setEventVariable(EventVariableData& eventVariableDataPtr, + const uint64_t eventId) noexcept +{ + getMembers()->m_conditionVariableDataPtr = &eventVariableDataPtr; + getMembers()->m_eventVariableIndex.emplace(eventId); +} + template inline void ChunkQueuePopper::unsetConditionVariable() noexcept { typename MemberType_t::LockGuard_t lock(*getMembers()); getMembers()->m_conditionVariableDataPtr = nullptr; + getMembers()->m_eventVariableIndex.reset(); } template diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp index e2918c98493..f18a0c28a68 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp @@ -14,9 +14,12 @@ #ifndef IOX_POSH_POPO_BUILDING_BLOCKS_CHUNK_QUEUE_PUSHER_HPP #define IOX_POSH_POPO_BUILDING_BLOCKS_CHUNK_QUEUE_PUSHER_HPP +#include "iceoryx_posh/internal/log/posh_logging.hpp" #include "iceoryx_posh/internal/mepoo/shared_chunk.hpp" #include "iceoryx_posh/internal/popo/building_blocks/chunk_queue_data.hpp" #include "iceoryx_posh/internal/popo/building_blocks/chunk_queue_types.hpp" +#include "iceoryx_posh/internal/popo/building_blocks/condition_variable_signaler.hpp" +#include "iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp" #include "iceoryx_utils/cxx/expected.hpp" #include "iceoryx_utils/cxx/helplets.hpp" diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.inl index 948971156c5..3994a439a75 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.inl @@ -14,8 +14,6 @@ #ifndef IOX_POSH_POPO_BUILDING_BLOCKS_CHUNK_QUEUE_PUSHER_INL #define IOX_POSH_POPO_BUILDING_BLOCKS_CHUNK_QUEUE_PUSHER_INL -#include "iceoryx_posh/internal/log/posh_logging.hpp" -#include "iceoryx_posh/internal/popo/building_blocks/condition_variable_signaler.hpp" namespace iox { @@ -67,8 +65,17 @@ inline void ChunkQueuePusher::push(mepoo::SharedChunk chunk) typename MemberType_t::LockGuard_t lock(*getMembers()); if (getMembers()->m_conditionVariableDataPtr) { - ConditionVariableSignaler condVarSignaler(getMembers()->m_conditionVariableDataPtr.get()); - condVarSignaler.notifyOne(); + if (getMembers()->m_eventVariableIndex) + { + EventNotifier(*reinterpret_cast(getMembers()->m_conditionVariableDataPtr.get()), + *getMembers()->m_eventVariableIndex) + .notify(); + } + else + { + ConditionVariableSignaler condVarSignaler(getMembers()->m_conditionVariableDataPtr.get()); + condVarSignaler.notifyOne(); + } } } } diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp index 850b97ac761..facbefb8446 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp @@ -83,6 +83,8 @@ class SubscriberPortUser : public BasePort /// @brief attach a condition variable (via its pointer) to subscriber void setConditionVariable(ConditionVariableData* conditionVariableDataPtr) noexcept; + void setEventVariable(EventVariableData& eventVariableData, const uint64_t eventId) noexcept; + /// @brief detach a condition variable from subscriber void unsetConditionVariable() noexcept; diff --git a/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp b/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp index 9bfc7448ef5..fd3e689b132 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp @@ -16,6 +16,7 @@ #define IOX_POSH_POPO_TRIGGER_HANDLE_HPP #include "iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp" +#include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" #include "iceoryx_posh/popo/trigger.hpp" #include "iceoryx_utils/cxx/method_callback.hpp" @@ -35,6 +36,9 @@ class TriggerHandle { public: TriggerHandle() = default; + TriggerHandle(EventVariableData* const eventVariableDataPtr, + const cxx::MethodCallback resetCallback, + const uint64_t uniqueTriggerId) noexcept; /// @brief Creates a TriggerHandle /// @param[in] conditionVariableDataPtr pointer to a condition variable data struct /// @param[in] resetCallback callback which will be called it goes out of scope or reset is called @@ -74,10 +78,13 @@ class TriggerHandle /// @brief returns the pointer to the ConditionVariableData ConditionVariableData* getConditionVariableData() noexcept; + bool doesContainEventVariable() const noexcept; + private: ConditionVariableData* m_conditionVariableDataPtr = nullptr; cxx::MethodCallback m_resetCallback; uint64_t m_uniqueTriggerId = 0U; + bool m_doesContainEventVariable = false; mutable std::recursive_mutex m_mutex; }; } // namespace popo diff --git a/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp b/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp index 02408fa047b..904d9a000bf 100644 --- a/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp +++ b/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp @@ -91,6 +91,11 @@ void SubscriberPortUser::setConditionVariable(ConditionVariableData* conditionVa m_chunkReceiver.setConditionVariable(conditionVariableDataPtr); } +void SubscriberPortUser::setEventVariable(EventVariableData& eventVariableData, const uint64_t eventId) noexcept +{ + m_chunkReceiver.setEventVariable(eventVariableData, eventId); +} + void SubscriberPortUser::unsetConditionVariable() noexcept { m_chunkReceiver.unsetConditionVariable(); diff --git a/iceoryx_posh/source/popo/trigger_handle.cpp b/iceoryx_posh/source/popo/trigger_handle.cpp index fdf2a9eebf6..d85cdfc9444 100644 --- a/iceoryx_posh/source/popo/trigger_handle.cpp +++ b/iceoryx_posh/source/popo/trigger_handle.cpp @@ -14,11 +14,20 @@ #include "iceoryx_posh/popo/trigger_handle.hpp" #include "iceoryx_posh/internal/popo/building_blocks/condition_variable_signaler.hpp" +#include "iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp" namespace iox { namespace popo { +TriggerHandle::TriggerHandle(EventVariableData* const eventVariableDataPtr, + const cxx::MethodCallback resetCallback, + const uint64_t uniqueTriggerId) noexcept + : TriggerHandle(static_cast(eventVariableDataPtr), resetCallback, uniqueTriggerId) +{ + m_doesContainEventVariable = true; +} + TriggerHandle::TriggerHandle(ConditionVariableData* const conditionVariableDataPtr, const cxx::MethodCallback resetCallback, const uint64_t uniqueTriggerId) noexcept @@ -46,6 +55,7 @@ TriggerHandle& TriggerHandle::operator=(TriggerHandle&& rhs) noexcept m_conditionVariableDataPtr = std::move(rhs.m_conditionVariableDataPtr); m_resetCallback = std::move(rhs.m_resetCallback); m_uniqueTriggerId = rhs.m_uniqueTriggerId; + m_doesContainEventVariable = rhs.m_doesContainEventVariable; rhs.invalidate(); } @@ -76,7 +86,15 @@ void TriggerHandle::trigger() noexcept if (isValid()) { - ConditionVariableSignaler(m_conditionVariableDataPtr).notifyOne(); + if (m_doesContainEventVariable) + { + EventNotifier(*reinterpret_cast(m_conditionVariableDataPtr), m_uniqueTriggerId) + .notify(); + } + else + { + ConditionVariableSignaler(m_conditionVariableDataPtr).notifyOne(); + } } } @@ -117,5 +135,10 @@ uint64_t TriggerHandle::getUniqueId() const noexcept return m_uniqueTriggerId; } +bool TriggerHandle::doesContainEventVariable() const noexcept +{ + return m_doesContainEventVariable; +} + } // namespace popo } // namespace iox From f4be735515b1090f6315f05d61afed03ec93ecaa Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 2 Feb 2021 17:39:51 +0100 Subject: [PATCH 024/143] iox-#350 fixed logical equal issue, two trigger must be logical equal if the have two different user event ids otherwise they both would attach to the subscriber for instance which would override the conditionvariabledata Signed-off-by: Christian Eltzschig --- .../iceoryx_posh/internal/popo/active_call_set.inl | 6 +++--- .../include/iceoryx_posh/internal/popo/wait_set.inl | 4 ++-- iceoryx_posh/include/iceoryx_posh/popo/trigger.hpp | 1 - .../include/iceoryx_posh/popo/trigger_handle.hpp | 4 ++-- iceoryx_posh/source/popo/trigger.cpp | 3 +-- iceoryx_posh/source/popo/trigger_handle.cpp | 8 ++++---- iceoryx_posh/test/mocks/subscriber_mock.hpp | 1 + iceoryx_posh/test/moduletests/test_popo_trigger.cpp | 8 ++++---- .../test/moduletests/test_popo_trigger_handle.cpp | 8 ++++---- iceoryx_posh/test/moduletests/test_popo_waitset.cpp | 11 ++++++++++- 10 files changed, 31 insertions(+), 23 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl index c48ab0ae4e8..b595f9c5181 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl @@ -38,8 +38,8 @@ inline cxx::expected ActiveCallSet::attachEvent(T& eventOrig internal::callsetCallback, EventAttorney::getInvalidateTriggerMethod(eventOrigin)) .and_then([&](auto& eventId) { - EventAttorney::enableEvent(eventOrigin, - TriggerHandle(m_eventVariable, {*this, &ActiveCallSet::removeTrigger}, eventId)); + EventAttorney::enableEvent( + eventOrigin, TriggerHandle(*m_eventVariable, {*this, &ActiveCallSet::removeTrigger}, eventId)); }); } @@ -55,7 +55,7 @@ ActiveCallSet::attachEvent(T& eventOrigin, const EventType eventType, CallbackRe EventAttorney::getInvalidateTriggerMethod(eventOrigin)) .and_then([&](auto& eventId) { EventAttorney::enableEvent(eventOrigin, - TriggerHandle(m_eventVariable, {*this, &ActiveCallSet::removeTrigger}, eventId), + TriggerHandle(*m_eventVariable, {*this, &ActiveCallSet::removeTrigger}, eventId), eventType); }); } diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/wait_set.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/wait_set.inl index 86a64dfae6f..1034cb659ce 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/wait_set.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/wait_set.inl @@ -86,7 +86,7 @@ inline cxx::expected WaitSet::attachEvent(T& eventOrigin return attachEventImpl(eventOrigin, hasTriggeredCallback, eventId, eventCallback).and_then([&](auto& uniqueId) { EventAttorney::enableEvent( eventOrigin, - TriggerHandle(m_conditionVariableDataPtr, {*this, &WaitSet::removeTrigger}, uniqueId), + TriggerHandle(*m_conditionVariableDataPtr, {*this, &WaitSet::removeTrigger}, uniqueId), eventType); }); } @@ -110,7 +110,7 @@ inline cxx::expected WaitSet::attachEvent(T& eventOrigin return attachEventImpl(eventOrigin, hasTriggeredCallback, eventId, eventCallback).and_then([&](auto& uniqueId) { EventAttorney::enableEvent( - eventOrigin, TriggerHandle(m_conditionVariableDataPtr, {*this, &WaitSet::removeTrigger}, uniqueId)); + eventOrigin, TriggerHandle(*m_conditionVariableDataPtr, {*this, &WaitSet::removeTrigger}, uniqueId)); }); } diff --git a/iceoryx_posh/include/iceoryx_posh/popo/trigger.hpp b/iceoryx_posh/include/iceoryx_posh/popo/trigger.hpp index a6c9a8c855d..e3314827917 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/trigger.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/trigger.hpp @@ -90,7 +90,6 @@ class Trigger /// @brief returns true if the Triggers are logical equal otherwise false. Two Triggers are logical equal when /// - origin == rhs.origin /// - hasTriggeredCallback == rhs.hasTriggeredCallback - /// - eventId == rhs.eventId bool isLogicalEqualTo(const Trigger& rhs) const noexcept; /// @brief sets a new origin of the trigger diff --git a/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp b/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp index fd3e689b132..63fc195eb1c 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp @@ -36,7 +36,7 @@ class TriggerHandle { public: TriggerHandle() = default; - TriggerHandle(EventVariableData* const eventVariableDataPtr, + TriggerHandle(EventVariableData& eventVariableDataPtr, const cxx::MethodCallback resetCallback, const uint64_t uniqueTriggerId) noexcept; /// @brief Creates a TriggerHandle @@ -44,7 +44,7 @@ class TriggerHandle /// @param[in] resetCallback callback which will be called it goes out of scope or reset is called /// @param[in] uniqueTriggerId the unique trigger id of the Trigger which corresponds to the TriggerHandle. Usually /// stored in a Notifyable. It is required for the resetCallback - TriggerHandle(ConditionVariableData* const conditionVariableDataPtr, + TriggerHandle(ConditionVariableData& conditionVariableDataPtr, const cxx::MethodCallback resetCallback, const uint64_t uniqueTriggerId) noexcept; TriggerHandle(const TriggerHandle&) = delete; diff --git a/iceoryx_posh/source/popo/trigger.cpp b/iceoryx_posh/source/popo/trigger.cpp index 70ae116425f..9cf3349efd8 100644 --- a/iceoryx_posh/source/popo/trigger.cpp +++ b/iceoryx_posh/source/popo/trigger.cpp @@ -70,8 +70,7 @@ bool Trigger::isValid() const noexcept bool Trigger::isLogicalEqualTo(const Trigger& rhs) const noexcept { return (isValid() && rhs.isValid() && m_eventInfo.m_eventOrigin == rhs.m_eventInfo.m_eventOrigin - && m_hasTriggeredCallback == rhs.m_hasTriggeredCallback - && m_eventInfo.m_eventId == rhs.m_eventInfo.m_eventId); + && m_hasTriggeredCallback == rhs.m_hasTriggeredCallback); } Trigger::Trigger(Trigger&& rhs) noexcept diff --git a/iceoryx_posh/source/popo/trigger_handle.cpp b/iceoryx_posh/source/popo/trigger_handle.cpp index d85cdfc9444..017eb8a3b7c 100644 --- a/iceoryx_posh/source/popo/trigger_handle.cpp +++ b/iceoryx_posh/source/popo/trigger_handle.cpp @@ -20,18 +20,18 @@ namespace iox { namespace popo { -TriggerHandle::TriggerHandle(EventVariableData* const eventVariableDataPtr, +TriggerHandle::TriggerHandle(EventVariableData& eventVariableDataPtr, const cxx::MethodCallback resetCallback, const uint64_t uniqueTriggerId) noexcept - : TriggerHandle(static_cast(eventVariableDataPtr), resetCallback, uniqueTriggerId) + : TriggerHandle(static_cast(eventVariableDataPtr), resetCallback, uniqueTriggerId) { m_doesContainEventVariable = true; } -TriggerHandle::TriggerHandle(ConditionVariableData* const conditionVariableDataPtr, +TriggerHandle::TriggerHandle(ConditionVariableData& conditionVariableDataPtr, const cxx::MethodCallback resetCallback, const uint64_t uniqueTriggerId) noexcept - : m_conditionVariableDataPtr(conditionVariableDataPtr) + : m_conditionVariableDataPtr(&conditionVariableDataPtr) , m_resetCallback(resetCallback) , m_uniqueTriggerId(uniqueTriggerId) { diff --git a/iceoryx_posh/test/mocks/subscriber_mock.hpp b/iceoryx_posh/test/mocks/subscriber_mock.hpp index a085010d8e1..47e4b6c720d 100644 --- a/iceoryx_posh/test/mocks/subscriber_mock.hpp +++ b/iceoryx_posh/test/mocks/subscriber_mock.hpp @@ -51,6 +51,7 @@ class MockSubscriberPortUser MOCK_CONST_METHOD0(hasNewChunks, bool()); MOCK_METHOD0(hasLostChunksSinceLastCall, bool()); MOCK_METHOD1(setConditionVariable, bool(iox::popo::ConditionVariableData*)); + MOCK_METHOD2(setEventVariable, bool(iox::popo::EventVariableData&, uint64_t)); MOCK_METHOD0(isConditionVariableSet, bool()); MOCK_METHOD0(unsetConditionVariable, bool()); MOCK_METHOD0(destroy, bool()); diff --git a/iceoryx_posh/test/moduletests/test_popo_trigger.cpp b/iceoryx_posh/test/moduletests/test_popo_trigger.cpp index d15f0225fb6..29f84398b3c 100644 --- a/iceoryx_posh/test/moduletests/test_popo_trigger.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_trigger.cpp @@ -310,7 +310,7 @@ TEST_F(Trigger_test, TwoTriggersAreLogicalEqualIfRequirementsAreFullfilled) Trigger sut2(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - 891U, + 892U, TriggerClass::callback); @@ -318,7 +318,7 @@ TEST_F(Trigger_test, TwoTriggersAreLogicalEqualIfRequirementsAreFullfilled) EXPECT_TRUE(sut2.isLogicalEqualTo(sut1)); } -TEST_F(Trigger_test, TwoTriggersAreNotLogicalEqualIfTriggerIdDiffers) +TEST_F(Trigger_test, TwoTriggersAreLogicalEqualIfOnlyTriggerIdDiffers) { Trigger sut1(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, @@ -333,8 +333,8 @@ TEST_F(Trigger_test, TwoTriggersAreNotLogicalEqualIfTriggerIdDiffers) TriggerClass::callback); - EXPECT_FALSE(sut1.isLogicalEqualTo(sut2)); - EXPECT_FALSE(sut2.isLogicalEqualTo(sut1)); + EXPECT_TRUE(sut1.isLogicalEqualTo(sut2)); + EXPECT_TRUE(sut2.isLogicalEqualTo(sut1)); } TEST_F(Trigger_test, TwoTriggersAreNotLogicalEqualIfHasTriggeredCallbackDiffers) diff --git a/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp b/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp index 1ff9c55bb78..bdd1d95532d 100644 --- a/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp @@ -34,7 +34,7 @@ class TriggerHandle_test : public Test ConditionVariableData m_condVar{"Horscht"}; TriggerHandle_test* m_self = this; - TriggerHandle m_sut{&m_condVar, {*this, &TriggerHandle_test::resetCallback}, 12}; + TriggerHandle m_sut{m_condVar, {*this, &TriggerHandle_test::resetCallback}, 12}; }; @@ -44,9 +44,9 @@ TEST_F(TriggerHandle_test, isValidWhenConditionVariableIsNotNull) EXPECT_TRUE(m_sut); } -TEST_F(TriggerHandle_test, isNotValidWhenConditionVariableIsNull) +TEST_F(TriggerHandle_test, defaultCTorConstructsInvalidHandle) { - TriggerHandle sut2{nullptr, {*m_self, &TriggerHandle_test::resetCallback}, 12}; + TriggerHandle sut2; EXPECT_FALSE(sut2.isValid()); EXPECT_FALSE(sut2); @@ -88,7 +88,7 @@ TEST_F(TriggerHandle_test, getConditionVariableDataReturnsCorrectVar) TEST_F(TriggerHandle_test, getUniqueIdReturnsCorrectId) { - TriggerHandle sut2{nullptr, {*m_self, &TriggerHandle_test::resetCallback}, 8912}; + TriggerHandle sut2{m_condVar, {*m_self, &TriggerHandle_test::resetCallback}, 8912}; EXPECT_EQ(sut2.getUniqueId(), 8912); } diff --git a/iceoryx_posh/test/moduletests/test_popo_waitset.cpp b/iceoryx_posh/test/moduletests/test_popo_waitset.cpp index 7e2aa01c00a..538275a0065 100644 --- a/iceoryx_posh/test/moduletests/test_popo_waitset.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_waitset.cpp @@ -178,6 +178,15 @@ TEST_F(WaitSet_test, AcquireSameTriggerWithNonNullIdTwiceResultsInError) EXPECT_THAT(result2.get_error(), Eq(WaitSetError::EVENT_ALREADY_ATTACHED)); } +TEST_F(WaitSet_test, AcquireSameTriggerWithDifferentIdResultsInError) +{ + m_sut.attachEvent(m_simpleEvents[0], 2101U); + auto result2 = m_sut.attachEvent(m_simpleEvents[0], 9121U); + + ASSERT_TRUE(result2.has_error()); + EXPECT_THAT(result2.get_error(), Eq(WaitSetError::EVENT_ALREADY_ATTACHED)); +} + TEST_F(WaitSet_test, ResetCallbackIsCalledWhenWaitsetGoesOutOfScope) { uint64_t uniqueTriggerId = 0U; @@ -206,7 +215,7 @@ TEST_F(WaitSet_test, TriggerRemovesItselfFromWaitsetWhenGoingOutOfScope) // waitset is already full } - auto result = m_sut.attachEvent(m_simpleEvents[0], 0U); + auto result = m_sut.attachEvent(m_simpleEvents.back(), 0U); EXPECT_FALSE(result.has_error()); } From 6a87eaf3fe5ef288bb2bc00f84d103394ab3a337 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 2 Feb 2021 17:52:10 +0100 Subject: [PATCH 025/143] iox-#350 add unit tests for EventVariableData struct Signed-off-by: Marika Lehmann --- .../building_blocks/event_variable_data.cpp | 1 + .../moduletests/test_popo_event_variable.cpp | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 iceoryx_posh/test/moduletests/test_popo_event_variable.cpp diff --git a/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp b/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp index 68984e3350c..811b85a9d20 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp @@ -25,6 +25,7 @@ EventVariableData::EventVariableData() noexcept EventVariableData::EventVariableData(const ProcessName_t& process) noexcept : ConditionVariableData(process) { + iox::cxx::forEach(m_activeNotifications, [](auto& id) { id.store(false, std::memory_order_relaxed); }); } } // namespace popo } // namespace iox diff --git a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp new file mode 100644 index 00000000000..99a54cba984 --- /dev/null +++ b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp @@ -0,0 +1,49 @@ +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" + +#include "test.hpp" + +using namespace ::testing; +using namespace iox::popo; + +class EventVariable_test : public Test +{ + public: + EventVariableData m_eventVarData{"Ferdinand"}; +}; + +TEST_F(EventVariable_test, AllNotificationsAreFalseAfterConstruction) +{ + EventVariableData sut; + for (auto& notification : sut.m_activeNotifications) + { + EXPECT_THAT(notification, Eq(false)); + } +} + +TEST_F(EventVariable_test, CorrectProcessNameAfterConstructionWithProcessName) +{ + EXPECT_THAT(m_eventVarData.m_process.c_str(), StrEq("Ferdinand")); +} + +TEST_F(EventVariable_test, AllNotificationsAreFalseAfterConstructionWithProcessName) +{ + for (auto& notification : m_eventVarData.m_activeNotifications) + { + EXPECT_THAT(notification, Eq(false)); + } +} + From 24805e4a29531d63d06a795ebbeb9152d559b729 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 2 Feb 2021 18:39:13 +0100 Subject: [PATCH 026/143] iox-#350 add unit tests for EventNotifier class Signed-off-by: Marika Lehmann --- .../popo/building_blocks/event_notifier.cpp | 5 ++- .../moduletests/test_popo_event_variable.cpp | 31 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp b/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp index 354cb2d0335..46548071dc7 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp @@ -26,7 +26,10 @@ EventNotifier::EventNotifier(EventVariableData& dataRef, const uint64_t index) n void EventNotifier::notify() noexcept { - m_pointerToEventVariableData->m_activeNotifications[m_notificationIndex].store(true, std::memory_order_release); + if (m_notificationIndex < MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET) + { + m_pointerToEventVariableData->m_activeNotifications[m_notificationIndex].store(true, std::memory_order_release); + } m_pointerToEventVariableData->m_semaphore.post(); } } // namespace popo diff --git a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp index 99a54cba984..bccb3e0b45a 100644 --- a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp" #include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" #include "test.hpp" @@ -47,3 +48,33 @@ TEST_F(EventVariable_test, AllNotificationsAreFalseAfterConstructionWithProcessN } } +TEST_F(EventVariable_test, NotifyActivatesCorrectIndex) +{ + uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1; + EventNotifier sut(m_eventVarData, index); + sut.notify(); + for (uint64_t i = 0U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; i++) + { + if (i == index) + { + EXPECT_THAT(m_eventVarData.m_activeNotifications[i], Eq(true)); + } + else + { + EXPECT_THAT(m_eventVarData.m_activeNotifications[i], Eq(false)); + } + } +} + + +TEST_F(EventVariable_test, NotifyActivatesNoIndexIfIndexIsTooLarge) +{ + uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; + EventNotifier sut(m_eventVarData, index); + sut.notify(); + for (const auto& notification : m_eventVarData.m_activeNotifications) + { + EXPECT_THAT(notification, Eq(false)); + } +} + From afd927de34375c92ae316594fea93af42ebeb8b5 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 2 Feb 2021 18:46:00 +0100 Subject: [PATCH 027/143] iox-#350 attach detach single process tests added for active call set Signed-off-by: Christian Eltzschig --- .../internal/popo/active_call_set.inl | 9 +- .../iceoryx_posh/popo/active_call_set.hpp | 7 +- iceoryx_posh/source/popo/active_call_set.cpp | 7 + .../moduletests/test_popo_active_call_set.cpp | 341 ++++++++++++++++++ 4 files changed, 360 insertions(+), 4 deletions(-) create mode 100644 iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl index b595f9c5181..35580384b43 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl @@ -43,7 +43,7 @@ inline cxx::expected ActiveCallSet::attachEvent(T& eventOrig }); } -template ::value>> +template inline cxx::expected ActiveCallSet::attachEvent(T& eventOrigin, const EventType eventType, CallbackRef_t eventCallback) noexcept { @@ -60,7 +60,7 @@ ActiveCallSet::attachEvent(T& eventOrigin, const EventType eventType, CallbackRe }); } -template ::value>> +template inline void ActiveCallSet::detachEvent(T& eventOrigin, const EventType eventType) noexcept { removeEvent(&eventOrigin, static_cast(eventType), typeid(EventType).hash_code()); @@ -72,6 +72,11 @@ inline void ActiveCallSet::detachEvent(T& eventOrigin) noexcept detachEvent(eventOrigin, NoEnumUsed::PLACEHOLDER); } +inline constexpr uint64_t ActiveCallSet::capacity() noexcept +{ + return MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; +} + } // namespace popo } // namespace iox diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp index 3ba311da8cc..c3ea9a5b727 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -69,6 +69,10 @@ class ActiveCallSet template void detachEvent(T& eventOrigin) noexcept; + static constexpr uint64_t capacity() noexcept; + + uint64_t size() const noexcept; + protected: ActiveCallSet(EventVariableData* eventVariable) noexcept; @@ -114,7 +118,6 @@ class ActiveCallSet private: static constexpr uint64_t INVALID_ID = std::numeric_limits::max(); - // EventInfo void* m_origin = nullptr; uint64_t m_eventType = INVALID_ID; uint64_t m_eventTypeHash = INVALID_ID; @@ -122,7 +125,6 @@ class ActiveCallSet CallbackPtr_t m_callback = nullptr; TranslationCallbackPtr_t m_translationCallback = nullptr; - // TriggerHandle uint64_t m_eventId = INVALID_ID; cxx::MethodCallback m_invalidationCallback; }; @@ -131,6 +133,7 @@ class ActiveCallSet concurrent::smart_lock m_events[MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET]; std::mutex m_addEventMutex; + std::atomic m_size{0U}; std::atomic_bool m_wasDtorCalled{false}; EventVariableData* m_eventVariable = nullptr; diff --git a/iceoryx_posh/source/popo/active_call_set.cpp b/iceoryx_posh/source/popo/active_call_set.cpp index 6bb11cb041a..9e23ecfe61e 100644 --- a/iceoryx_posh/source/popo/active_call_set.cpp +++ b/iceoryx_posh/source/popo/active_call_set.cpp @@ -70,6 +70,7 @@ ActiveCallSet::addEvent(void* const origin, return cxx::error(ActiveCallSetError::ACTIVE_CALL_SET_FULL); } + ++m_size; m_events[index]->init(index, origin, eventType, eventTypeHash, callback, translationCallback, invalidationCallback); return cxx::success(index); } @@ -81,11 +82,17 @@ void ActiveCallSet::removeEvent(void* const origin, const uint64_t eventType, co if (m_events[index]->resetIfEqualTo(origin, eventType, eventTypeHash)) { m_indexManager.push(index); + --m_size; break; } } } +uint64_t ActiveCallSet::size() const noexcept +{ + return m_size.load(std::memory_order_relaxed); +} + void ActiveCallSet::threadLoop() noexcept { EventListener eventListener(*m_eventVariable); diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp new file mode 100644 index 00000000000..77234127ba2 --- /dev/null +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -0,0 +1,341 @@ +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "iceoryx_posh/iceoryx_posh_types.hpp" +#include "iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp" +#include "iceoryx_posh/popo/active_call_set.hpp" +#include "iceoryx_posh/popo/user_trigger.hpp" +#include "iceoryx_utils/cxx/vector.hpp" +#include "mocks/wait_set_mock.hpp" +#include "test.hpp" +#include "testutils/timing_test.hpp" + +#include +#include +#include + +using namespace ::testing; +using ::testing::Return; +using namespace iox::popo; +using namespace iox::cxx; +using namespace iox::units::duration_literals; + +class ActiveCallSet_test : public Test +{ + public: + enum SimpleEvent + { + StoepselBachelorParty, + Hypnotoad + }; + + class SimpleEventClass + { + public: + SimpleEventClass() = default; + SimpleEventClass(const SimpleEventClass&) = delete; + SimpleEventClass(SimpleEventClass&&) = delete; + + SimpleEventClass& operator=(const SimpleEventClass&) = delete; + SimpleEventClass& operator=(SimpleEventClass&&) = delete; + + ~SimpleEventClass() + { + } + + void enableEvent(iox::popo::TriggerHandle&& handle, const SimpleEvent event) noexcept + { + if (event == SimpleEvent::StoepselBachelorParty) + { + m_handleStoepsel = std::move(handle); + } + else + { + m_handleHypnotoad = std::move(handle); + } + } + + void enableEvent(iox::popo::TriggerHandle&& handle) noexcept + { + m_handleHypnotoad = std::move(handle); + } + + void invalidateTrigger(const uint64_t id) + { + m_invalidateTriggerId = id; + if (m_handleHypnotoad.getUniqueId() == id) + { + m_handleHypnotoad.invalidate(); + } + else if (m_handleStoepsel.getUniqueId() == id) + { + m_handleStoepsel.invalidate(); + } + } + + iox::cxx::ConstMethodCallback getHasTriggeredCallbackForEvent() const noexcept + { + return {*this, &SimpleEventClass::hasTriggered}; + } + + bool hasTriggered() const + { + return m_hasTriggered.exchange(false); + } + + void disableEvent(const SimpleEvent event) + { + if (event == SimpleEvent::StoepselBachelorParty) + { + m_handleStoepsel.reset(); + } + else + { + m_handleHypnotoad.reset(); + } + } + + void disableEvent() + { + m_handleHypnotoad.reset(); + } + + void triggerStoepsel() + { + m_hasTriggered.store(true); + m_handleStoepsel.trigger(); + } + + void resetTrigger() + { + m_hasTriggered.store(false); + } + + iox::popo::TriggerHandle m_handleHypnotoad; + iox::popo::TriggerHandle m_handleStoepsel; + mutable std::atomic_bool m_hasTriggered{false}; + static uint64_t m_invalidateTriggerId; + + std::array m_triggerCallbackArg{nullptr}; + }; + + class ActiveCallSetMock : public ActiveCallSet + { + public: + ActiveCallSetMock(EventVariableData* data) noexcept + : ActiveCallSet(data) + { + } + }; + + EventVariableData m_eventVarData{"Maulbeerblatt"}; + ActiveCallSetMock m_sut{&m_eventVarData}; + + template + static void triggerCallback(ActiveCallSet_test::SimpleEventClass* const event) + { + event->m_triggerCallbackArg[N] = event; + } + + void SetUp() + { + ActiveCallSet_test::SimpleEventClass::m_invalidateTriggerId = 0U; + }; + + void TearDown(){}; + + using eventVector_t = iox::cxx::vector; + eventVector_t m_simpleEvents{iox::MAX_NUMBER_OF_EVENTS_PER_WAITSET + 1}; +}; +uint64_t ActiveCallSet_test::SimpleEventClass::m_invalidateTriggerId = 0U; + +////////////////////////////////// +// attach / detach test collection +////////////////////////////////// + +TEST_F(ActiveCallSet_test, IsEmptyWhenConstructed) +{ + EXPECT_THAT(m_sut.size(), Eq(0U)); +} + +TEST_F(ActiveCallSet_test, AttachingWithoutEnumIfEnoughSpaceAvailableWorks) +{ + EXPECT_FALSE(m_sut.attachEvent(m_simpleEvents[0], ActiveCallSet_test::triggerCallback<0>).has_error()); + EXPECT_THAT(m_sut.size(), Eq(1U)); +} + +TEST_F(ActiveCallSet_test, AttachWithoutEnumTillCapacityIsFullWorks) +{ + for (uint64_t i = 0U; i < m_sut.capacity(); ++i) + { + EXPECT_FALSE(m_sut.attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>).has_error()); + } + EXPECT_THAT(m_sut.size(), Eq(m_sut.capacity())); +} + +TEST_F(ActiveCallSet_test, DetachDecreasesSize) +{ + for (uint64_t i = 0U; i < m_sut.capacity(); ++i) + { + m_sut.attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>); + } + m_sut.detachEvent(m_simpleEvents[0]); + EXPECT_THAT(m_sut.size(), Eq(m_sut.capacity() - 1)); +} + +TEST_F(ActiveCallSet_test, AttachWithoutEnumOneMoreThanCapacityFails) +{ + for (uint64_t i = 0U; i < m_sut.capacity(); ++i) + { + m_sut.attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>).has_error(); + } + EXPECT_TRUE( + m_sut.attachEvent(m_simpleEvents[m_sut.capacity()], ActiveCallSet_test::triggerCallback<0>).has_error()); +} + +TEST_F(ActiveCallSet_test, AttachingWithEnumIfEnoughSpaceAvailableWorks) +{ + EXPECT_FALSE(m_sut + .attachEvent(m_simpleEvents[0], + ActiveCallSet_test::SimpleEvent::Hypnotoad, + ActiveCallSet_test::triggerCallback<0>) + .has_error()); +} + +TEST_F(ActiveCallSet_test, AttachWithEnumTillCapacityIsFullWorks) +{ + for (uint64_t i = 0U; i < m_sut.capacity(); ++i) + { + EXPECT_FALSE(m_sut + .attachEvent(m_simpleEvents[i], + ActiveCallSet_test::SimpleEvent::Hypnotoad, + ActiveCallSet_test::triggerCallback<0>) + .has_error()); + } +} + +TEST_F(ActiveCallSet_test, AttachWithEnumOneMoreThanCapacityFails) +{ + for (uint64_t i = 0U; i < m_sut.capacity(); ++i) + { + m_sut + .attachEvent( + m_simpleEvents[i], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0>) + .has_error(); + } + EXPECT_TRUE(m_sut + .attachEvent(m_simpleEvents[m_sut.capacity()], + ActiveCallSet_test::SimpleEvent::Hypnotoad, + ActiveCallSet_test::triggerCallback<0>) + .has_error()); +} + +TEST_F(ActiveCallSet_test, DetachMakesSpaceForAnotherAttachWithEventEnum) +{ + for (uint64_t i = 0U; i < m_sut.capacity(); ++i) + { + m_sut + .attachEvent( + m_simpleEvents[i], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0>) + .has_error(); + } + + m_sut.detachEvent(m_simpleEvents[0], ActiveCallSet_test::SimpleEvent::Hypnotoad); + EXPECT_FALSE(m_sut + .attachEvent(m_simpleEvents[m_sut.capacity()], + ActiveCallSet_test::SimpleEvent::Hypnotoad, + ActiveCallSet_test::triggerCallback<0>) + .has_error()); +} + +TEST_F(ActiveCallSet_test, DetachMakesSpaceForAnotherAttachWithoutEventEnum) +{ + for (uint64_t i = 0U; i < m_sut.capacity(); ++i) + { + m_sut.attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>).has_error(); + } + + m_sut.detachEvent(m_simpleEvents[0]); + EXPECT_FALSE(m_sut + .attachEvent(m_simpleEvents[m_sut.capacity()], + ActiveCallSet_test::SimpleEvent::Hypnotoad, + ActiveCallSet_test::triggerCallback<0>) + .has_error()); +} + +TEST_F(ActiveCallSet_test, AttachingEventWithoutEventTypeLeadsToAttachedTriggerHandle) +{ + m_sut.attachEvent(m_simpleEvents[0], ActiveCallSet_test::triggerCallback<0>); + EXPECT_TRUE(m_simpleEvents[0].m_handleHypnotoad.isValid()); +} + +TEST_F(ActiveCallSet_test, AttachingEventWithEventTypeLeadsToAttachedTriggerHandle) +{ + m_sut.attachEvent(m_simpleEvents[0], + ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, + ActiveCallSet_test::triggerCallback<0>); + EXPECT_TRUE(m_simpleEvents[0].m_handleStoepsel.isValid()); +} + +TEST_F(ActiveCallSet_test, AttachingSameEventWithEventEnumTwiceFails) +{ + m_sut.attachEvent(m_simpleEvents[0], + ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, + ActiveCallSet_test::triggerCallback<0>); + + EXPECT_TRUE(m_sut + .attachEvent(m_simpleEvents[0], + ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, + ActiveCallSet_test::triggerCallback<0>) + .has_error()); +} + +TEST_F(ActiveCallSet_test, AttachingSameEventWithoutEventEnumTwiceFails) +{ + m_sut.attachEvent(m_simpleEvents[0], ActiveCallSet_test::triggerCallback<0>); + + EXPECT_TRUE(m_sut.attachEvent(m_simpleEvents[0], ActiveCallSet_test::triggerCallback<0>).has_error()); +} + +TEST_F(ActiveCallSet_test, AttachingSameClassWithTwoDifferentEventsWorks) +{ + m_sut.attachEvent( + m_simpleEvents[0], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0>); + + EXPECT_FALSE(m_sut + .attachEvent(m_simpleEvents[0], + ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, + ActiveCallSet_test::triggerCallback<0>) + .has_error()); +} + +TEST_F(ActiveCallSet_test, DetachingSameClassWithDifferentEventEnumChangesNothing) +{ + m_sut.attachEvent( + m_simpleEvents[0], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0>); + + m_sut.detachEvent(m_simpleEvents[0], ActiveCallSet_test::SimpleEvent::StoepselBachelorParty); + EXPECT_THAT(m_sut.size(), Eq(1U)); +} + +TEST_F(ActiveCallSet_test, DetachingDifferentClassWithSameEventEnumChangesNothing) +{ + m_sut.attachEvent( + m_simpleEvents[0], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0>); + + m_sut.detachEvent(m_simpleEvents[1], ActiveCallSet_test::SimpleEvent::Hypnotoad); + EXPECT_THAT(m_sut.size(), Eq(1U)); +} + +// From 71651b25ea79dc10d2aeb057a1465f42ab2c6c41 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 2 Feb 2021 19:39:00 +0100 Subject: [PATCH 028/143] iox-#350 fixed wrong size tracking Signed-off-by: Christian Eltzschig --- .../iceoryx_posh/popo/active_call_set.hpp | 21 +- iceoryx_posh/source/popo/active_call_set.cpp | 40 +++- .../moduletests/test_popo_active_call_set.cpp | 196 +++++++++++------- 3 files changed, 170 insertions(+), 87 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp index c3ea9a5b727..c677bb655e3 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -129,17 +129,28 @@ class ActiveCallSet cxx::MethodCallback m_invalidationCallback; }; + // TODO: integrate in LoFFLi?! + class IndexManager_t + { + public: + IndexManager_t() noexcept; + bool pop(uint32_t& index) noexcept; + void push(const uint32_t index) noexcept; + uint64_t size() const noexcept; + + uint32_t m_loffliStorage[concurrent::LoFFLi::requiredMemorySize(MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET) + / sizeof(uint32_t)]; + concurrent::LoFFLi m_loffli; + std::atomic m_size{0U}; + } m_indexManager; + + std::thread m_thread; concurrent::smart_lock m_events[MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET]; std::mutex m_addEventMutex; - std::atomic m_size{0U}; std::atomic_bool m_wasDtorCalled{false}; EventVariableData* m_eventVariable = nullptr; - - uint32_t m_loffliStorage[concurrent::LoFFLi::requiredMemorySize(MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET) - / sizeof(uint32_t)]; - concurrent::LoFFLi m_indexManager; }; } // namespace popo } // namespace iox diff --git a/iceoryx_posh/source/popo/active_call_set.cpp b/iceoryx_posh/source/popo/active_call_set.cpp index 9e23ecfe61e..bc8f770c0ef 100644 --- a/iceoryx_posh/source/popo/active_call_set.cpp +++ b/iceoryx_posh/source/popo/active_call_set.cpp @@ -30,7 +30,6 @@ ActiveCallSet::ActiveCallSet() noexcept ActiveCallSet::ActiveCallSet(EventVariableData* eventVariable) noexcept : m_eventVariable(eventVariable) { - m_indexManager.init(m_loffliStorage, MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); m_thread = std::thread(&ActiveCallSet::threadLoop, this); } @@ -70,7 +69,6 @@ ActiveCallSet::addEvent(void* const origin, return cxx::error(ActiveCallSetError::ACTIVE_CALL_SET_FULL); } - ++m_size; m_events[index]->init(index, origin, eventType, eventTypeHash, callback, translationCallback, invalidationCallback); return cxx::success(index); } @@ -82,7 +80,6 @@ void ActiveCallSet::removeEvent(void* const origin, const uint64_t eventType, co if (m_events[index]->resetIfEqualTo(origin, eventType, eventTypeHash)) { m_indexManager.push(index); - --m_size; break; } } @@ -90,7 +87,7 @@ void ActiveCallSet::removeEvent(void* const origin, const uint64_t eventType, co uint64_t ActiveCallSet::size() const noexcept { - return m_size.load(std::memory_order_relaxed); + return m_indexManager.size(); } void ActiveCallSet::threadLoop() noexcept @@ -190,8 +187,41 @@ bool ActiveCallSet::Event_t::reset() noexcept bool ActiveCallSet::Event_t::isInitialized() const noexcept { - return m_origin != nullptr; + return m_origin != nullptr || m_eventId == INVALID_ID || m_eventType == INVALID_ID || m_eventTypeHash == INVALID_ID + || m_callback == nullptr || m_translationCallback == nullptr + || m_invalidationCallback == cxx::MethodCallback(); +} + +////////////////// +// IndexManager_t +////////////////// + +ActiveCallSet::IndexManager_t::IndexManager_t() noexcept +{ + m_loffli.init(m_loffliStorage, MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); +} + +bool ActiveCallSet::IndexManager_t::pop(uint32_t& value) noexcept +{ + if (m_loffli.pop(value)) + { + ++m_size; + return true; + } + return false; +} + +void ActiveCallSet::IndexManager_t::push(const uint32_t index) noexcept +{ + m_loffli.push(index); + --m_size; } +uint64_t ActiveCallSet::IndexManager_t::size() const noexcept +{ + return m_size.load(std::memory_order_relaxed); +} + + } // namespace popo } // namespace iox diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index 77234127ba2..aefaaebb13b 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -16,6 +16,7 @@ #include "iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp" #include "iceoryx_posh/popo/active_call_set.hpp" #include "iceoryx_posh/popo/user_trigger.hpp" +#include "iceoryx_utils/cxx/optional.hpp" #include "iceoryx_utils/cxx/vector.hpp" #include "mocks/wait_set_mock.hpp" #include "test.hpp" @@ -52,6 +53,8 @@ class ActiveCallSet_test : public Test ~SimpleEventClass() { + m_handleStoepsel.reset(); + m_handleHypnotoad.reset(); } void enableEvent(iox::popo::TriggerHandle&& handle, const SimpleEvent event) noexcept @@ -84,16 +87,6 @@ class ActiveCallSet_test : public Test } } - iox::cxx::ConstMethodCallback getHasTriggeredCallbackForEvent() const noexcept - { - return {*this, &SimpleEventClass::hasTriggered}; - } - - bool hasTriggered() const - { - return m_hasTriggered.exchange(false); - } - void disableEvent(const SimpleEvent event) { if (event == SimpleEvent::StoepselBachelorParty) @@ -140,7 +133,7 @@ class ActiveCallSet_test : public Test }; EventVariableData m_eventVarData{"Maulbeerblatt"}; - ActiveCallSetMock m_sut{&m_eventVarData}; + iox::cxx::optional m_sut; template static void triggerCallback(ActiveCallSet_test::SimpleEventClass* const event) @@ -150,6 +143,7 @@ class ActiveCallSet_test : public Test void SetUp() { + m_sut.emplace(&m_eventVarData); ActiveCallSet_test::SimpleEventClass::m_invalidateTriggerId = 0U; }; @@ -166,176 +160,224 @@ uint64_t ActiveCallSet_test::SimpleEventClass::m_invalidateTriggerId = 0U; TEST_F(ActiveCallSet_test, IsEmptyWhenConstructed) { - EXPECT_THAT(m_sut.size(), Eq(0U)); + EXPECT_THAT(m_sut->size(), Eq(0U)); } TEST_F(ActiveCallSet_test, AttachingWithoutEnumIfEnoughSpaceAvailableWorks) { - EXPECT_FALSE(m_sut.attachEvent(m_simpleEvents[0], ActiveCallSet_test::triggerCallback<0>).has_error()); - EXPECT_THAT(m_sut.size(), Eq(1U)); + EXPECT_FALSE(m_sut->attachEvent(m_simpleEvents[0], ActiveCallSet_test::triggerCallback<0>).has_error()); + EXPECT_THAT(m_sut->size(), Eq(1U)); } TEST_F(ActiveCallSet_test, AttachWithoutEnumTillCapacityIsFullWorks) { - for (uint64_t i = 0U; i < m_sut.capacity(); ++i) + for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { - EXPECT_FALSE(m_sut.attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>).has_error()); + EXPECT_FALSE(m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>).has_error()); } - EXPECT_THAT(m_sut.size(), Eq(m_sut.capacity())); + EXPECT_THAT(m_sut->size(), Eq(m_sut->capacity())); } TEST_F(ActiveCallSet_test, DetachDecreasesSize) { - for (uint64_t i = 0U; i < m_sut.capacity(); ++i) + for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { - m_sut.attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>); + m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>); } - m_sut.detachEvent(m_simpleEvents[0]); - EXPECT_THAT(m_sut.size(), Eq(m_sut.capacity() - 1)); + m_sut->detachEvent(m_simpleEvents[0]); + EXPECT_THAT(m_sut->size(), Eq(m_sut->capacity() - 1)); } TEST_F(ActiveCallSet_test, AttachWithoutEnumOneMoreThanCapacityFails) { - for (uint64_t i = 0U; i < m_sut.capacity(); ++i) + for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { - m_sut.attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>).has_error(); + m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>).has_error(); } - EXPECT_TRUE( - m_sut.attachEvent(m_simpleEvents[m_sut.capacity()], ActiveCallSet_test::triggerCallback<0>).has_error()); + auto result = m_sut->attachEvent(m_simpleEvents[m_sut->capacity()], ActiveCallSet_test::triggerCallback<0>); + + ASSERT_TRUE(result.has_error()); + EXPECT_THAT(result.get_error(), Eq(ActiveCallSetError::ACTIVE_CALL_SET_FULL)); } TEST_F(ActiveCallSet_test, AttachingWithEnumIfEnoughSpaceAvailableWorks) { EXPECT_FALSE(m_sut - .attachEvent(m_simpleEvents[0], - ActiveCallSet_test::SimpleEvent::Hypnotoad, - ActiveCallSet_test::triggerCallback<0>) + ->attachEvent(m_simpleEvents[0], + ActiveCallSet_test::SimpleEvent::Hypnotoad, + ActiveCallSet_test::triggerCallback<0>) .has_error()); } TEST_F(ActiveCallSet_test, AttachWithEnumTillCapacityIsFullWorks) { - for (uint64_t i = 0U; i < m_sut.capacity(); ++i) + for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { EXPECT_FALSE(m_sut - .attachEvent(m_simpleEvents[i], - ActiveCallSet_test::SimpleEvent::Hypnotoad, - ActiveCallSet_test::triggerCallback<0>) + ->attachEvent(m_simpleEvents[i], + ActiveCallSet_test::SimpleEvent::Hypnotoad, + ActiveCallSet_test::triggerCallback<0>) .has_error()); } } TEST_F(ActiveCallSet_test, AttachWithEnumOneMoreThanCapacityFails) { - for (uint64_t i = 0U; i < m_sut.capacity(); ++i) + for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { m_sut - .attachEvent( + ->attachEvent( m_simpleEvents[i], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0>) .has_error(); } - EXPECT_TRUE(m_sut - .attachEvent(m_simpleEvents[m_sut.capacity()], - ActiveCallSet_test::SimpleEvent::Hypnotoad, - ActiveCallSet_test::triggerCallback<0>) - .has_error()); + auto result = m_sut->attachEvent(m_simpleEvents[m_sut->capacity()], + ActiveCallSet_test::SimpleEvent::Hypnotoad, + ActiveCallSet_test::triggerCallback<0>); + + ASSERT_TRUE(result.has_error()); + EXPECT_THAT(result.get_error(), Eq(ActiveCallSetError::ACTIVE_CALL_SET_FULL)); } TEST_F(ActiveCallSet_test, DetachMakesSpaceForAnotherAttachWithEventEnum) { - for (uint64_t i = 0U; i < m_sut.capacity(); ++i) + for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { m_sut - .attachEvent( + ->attachEvent( m_simpleEvents[i], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0>) .has_error(); } - m_sut.detachEvent(m_simpleEvents[0], ActiveCallSet_test::SimpleEvent::Hypnotoad); + m_sut->detachEvent(m_simpleEvents[0], ActiveCallSet_test::SimpleEvent::Hypnotoad); EXPECT_FALSE(m_sut - .attachEvent(m_simpleEvents[m_sut.capacity()], - ActiveCallSet_test::SimpleEvent::Hypnotoad, - ActiveCallSet_test::triggerCallback<0>) + ->attachEvent(m_simpleEvents[m_sut->capacity()], + ActiveCallSet_test::SimpleEvent::Hypnotoad, + ActiveCallSet_test::triggerCallback<0>) .has_error()); } TEST_F(ActiveCallSet_test, DetachMakesSpaceForAnotherAttachWithoutEventEnum) { - for (uint64_t i = 0U; i < m_sut.capacity(); ++i) + for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { - m_sut.attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>).has_error(); + m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>).has_error(); } - m_sut.detachEvent(m_simpleEvents[0]); + m_sut->detachEvent(m_simpleEvents[0]); EXPECT_FALSE(m_sut - .attachEvent(m_simpleEvents[m_sut.capacity()], - ActiveCallSet_test::SimpleEvent::Hypnotoad, - ActiveCallSet_test::triggerCallback<0>) + ->attachEvent(m_simpleEvents[m_sut->capacity()], + ActiveCallSet_test::SimpleEvent::Hypnotoad, + ActiveCallSet_test::triggerCallback<0>) .has_error()); } TEST_F(ActiveCallSet_test, AttachingEventWithoutEventTypeLeadsToAttachedTriggerHandle) { - m_sut.attachEvent(m_simpleEvents[0], ActiveCallSet_test::triggerCallback<0>); + m_sut->attachEvent(m_simpleEvents[0], ActiveCallSet_test::triggerCallback<0>); EXPECT_TRUE(m_simpleEvents[0].m_handleHypnotoad.isValid()); } TEST_F(ActiveCallSet_test, AttachingEventWithEventTypeLeadsToAttachedTriggerHandle) { - m_sut.attachEvent(m_simpleEvents[0], - ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, - ActiveCallSet_test::triggerCallback<0>); + m_sut->attachEvent(m_simpleEvents[0], + ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, + ActiveCallSet_test::triggerCallback<0>); EXPECT_TRUE(m_simpleEvents[0].m_handleStoepsel.isValid()); } TEST_F(ActiveCallSet_test, AttachingSameEventWithEventEnumTwiceFails) { - m_sut.attachEvent(m_simpleEvents[0], - ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, - ActiveCallSet_test::triggerCallback<0>); - - EXPECT_TRUE(m_sut - .attachEvent(m_simpleEvents[0], - ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, - ActiveCallSet_test::triggerCallback<0>) - .has_error()); + m_sut->attachEvent(m_simpleEvents[0], + ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, + ActiveCallSet_test::triggerCallback<0>); + + auto result = m_sut->attachEvent(m_simpleEvents[0], + ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, + ActiveCallSet_test::triggerCallback<0>); + ASSERT_TRUE(result.has_error()); + EXPECT_THAT(result.get_error(), Eq(ActiveCallSetError::EVENT_ALREADY_ATTACHED)); } TEST_F(ActiveCallSet_test, AttachingSameEventWithoutEventEnumTwiceFails) { - m_sut.attachEvent(m_simpleEvents[0], ActiveCallSet_test::triggerCallback<0>); + m_sut->attachEvent(m_simpleEvents[0], ActiveCallSet_test::triggerCallback<0>); - EXPECT_TRUE(m_sut.attachEvent(m_simpleEvents[0], ActiveCallSet_test::triggerCallback<0>).has_error()); + auto result = m_sut->attachEvent(m_simpleEvents[0], ActiveCallSet_test::triggerCallback<0>); + ASSERT_TRUE(result.has_error()); + EXPECT_THAT(result.get_error(), Eq(ActiveCallSetError::EVENT_ALREADY_ATTACHED)); } TEST_F(ActiveCallSet_test, AttachingSameClassWithTwoDifferentEventsWorks) { - m_sut.attachEvent( + m_sut->attachEvent( m_simpleEvents[0], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0>); EXPECT_FALSE(m_sut - .attachEvent(m_simpleEvents[0], - ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, - ActiveCallSet_test::triggerCallback<0>) + ->attachEvent(m_simpleEvents[0], + ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, + ActiveCallSet_test::triggerCallback<0>) .has_error()); } TEST_F(ActiveCallSet_test, DetachingSameClassWithDifferentEventEnumChangesNothing) { - m_sut.attachEvent( + m_sut->attachEvent( m_simpleEvents[0], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0>); - m_sut.detachEvent(m_simpleEvents[0], ActiveCallSet_test::SimpleEvent::StoepselBachelorParty); - EXPECT_THAT(m_sut.size(), Eq(1U)); + m_sut->detachEvent(m_simpleEvents[0], ActiveCallSet_test::SimpleEvent::StoepselBachelorParty); + EXPECT_THAT(m_sut->size(), Eq(1U)); } TEST_F(ActiveCallSet_test, DetachingDifferentClassWithSameEventEnumChangesNothing) { - m_sut.attachEvent( + m_sut->attachEvent( m_simpleEvents[0], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0>); - m_sut.detachEvent(m_simpleEvents[1], ActiveCallSet_test::SimpleEvent::Hypnotoad); - EXPECT_THAT(m_sut.size(), Eq(1U)); + m_sut->detachEvent(m_simpleEvents[1], ActiveCallSet_test::SimpleEvent::Hypnotoad); + EXPECT_THAT(m_sut->size(), Eq(1U)); } -// +TEST_F(ActiveCallSet_test, AttachingTillCapacityFilledSetsUpTriggerHandle) +{ + for (uint64_t i = 0U; i < m_sut->capacity(); ++i) + { + m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>).has_error(); + } + + for (uint64_t i = 0U; i < m_sut->capacity(); ++i) + { + EXPECT_TRUE(m_simpleEvents[i].m_handleHypnotoad.isValid()); + } +} + +TEST_F(ActiveCallSet_test, DTorDetachesAllAttachedEvents) +{ + for (uint64_t i = 0U; i < m_sut->capacity(); ++i) + { + m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>).has_error(); + } + + m_sut.reset(); + + for (uint64_t i = 0U; i < m_sut->capacity(); ++i) + { + EXPECT_FALSE(m_simpleEvents[i].m_handleHypnotoad.isValid()); + } +} + +TEST_F(ActiveCallSet_test, AttachedEventDTorDetachesItself) +{ + { + SimpleEventClass fuu; + m_sut->attachEvent(fuu, ActiveCallSet_test::triggerCallback<0>); + } + + EXPECT_THAT(m_sut->size(), Eq(0U)); +} + +////////////////////////////////// +// concurrent attach / detach +////////////////////////////////// + + +// -- goes out of scope while callback is running From 63c9fabcb544b9a0d5a0ae246b659f2bc15d9c4c Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 2 Feb 2021 19:43:34 +0100 Subject: [PATCH 029/143] iox-#350 add unit tests for EventListener class Signed-off-by: Marika Lehmann --- .../moduletests/test_popo_event_variable.cpp | 86 ++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp index bccb3e0b45a..9c909d9f591 100644 --- a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp @@ -12,10 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "iceoryx_posh/internal/popo/building_blocks/event_listener.hpp" #include "iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp" #include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" #include "test.hpp" +#include "testutils/timing_test.hpp" + +#include using namespace ::testing; using namespace iox::popo; @@ -23,6 +27,7 @@ using namespace iox::popo; class EventVariable_test : public Test { public: + using notificationVector = iox::cxx::vector; EventVariableData m_eventVarData{"Ferdinand"}; }; @@ -66,7 +71,6 @@ TEST_F(EventVariable_test, NotifyActivatesCorrectIndex) } } - TEST_F(EventVariable_test, NotifyActivatesNoIndexIfIndexIsTooLarge) { uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; @@ -78,3 +82,83 @@ TEST_F(EventVariable_test, NotifyActivatesNoIndexIfIndexIsTooLarge) } } +TEST_F(EventVariable_test, GetCorrectNotificationVectorAfterNotifyAndWait) +{ + uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; + EventNotifier notifier(m_eventVarData, index); + EventListener listener(m_eventVarData); + + notifier.notify(); + const auto& activeNotifications = listener.wait(); + ASSERT_THAT(activeNotifications.size(), Eq(1U)); + EXPECT_THAT(activeNotifications[0], Eq(index)); +} + +TEST_F(EventVariable_test, GetCorrectNotificationVectorAfterMultipleNotifyAndWait) +{ + uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; + EventNotifier notifier1(m_eventVarData, index); + EventNotifier notifier2(m_eventVarData, 0U); + EventListener listener(m_eventVarData); + + notifier1.notify(); + notifier2.notify(); + const auto& activeNotifications = listener.wait(); + ASSERT_THAT(activeNotifications.size(), Eq(2U)); + EXPECT_THAT(activeNotifications[0], Eq(0U)); + EXPECT_THAT(activeNotifications[1], Eq(index)); +} + +TEST_F(EventVariable_test, GetEmptyNotificationVectorAfterNotifyWithTooLargeAndWait) +{ + uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET + 1U; + EventNotifier notifier(m_eventVarData, index); + EventListener listener(m_eventVarData); + + notifier.notify(); + const auto& activeNotifications = listener.wait(); + EXPECT_THAT(activeNotifications.size(), Eq(0U)); +} + +TEST_F(EventVariable_test, WaitAndNotifyResultsInCorrectNotificationVector) +{ + uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 5U; + EventNotifier notifier(m_eventVarData, index); + EventListener listener(m_eventVarData); + notificationVector activeNotifications; + + std::thread waiter([&] { + activeNotifications = listener.wait(); + ASSERT_THAT(activeNotifications.size(), Eq(1U)); + EXPECT_THAT(activeNotifications[0], Eq(index)); + }); + + notifier.notify(); + waiter.join(); +} + +TIMING_TEST_F(EventVariable_test, WaitBlocks, Repeat(5), [&] { + uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 5U; + EventNotifier notifier(m_eventVarData, index); + EventListener listener(m_eventVarData); + notificationVector activeNotifications; + iox::posix::Semaphore semaphore = + iox::posix::Semaphore::create(iox::posix::CreateUnnamedSingleProcessSemaphore, 0U).value(); + std::atomic_bool hasWaited{false}; + + std::thread waiter([&] { + semaphore.post(); + activeNotifications = listener.wait(); + hasWaited.store(true, std::memory_order_relaxed); + ASSERT_THAT(activeNotifications.size(), Eq(1U)); + EXPECT_THAT(activeNotifications[0], Eq(index)); + }); + + semaphore.wait(); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + hasWaited.store(false, std::memory_order_relaxed); + notifier.notify(); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + hasWaited.store(true, std::memory_order_relaxed); + waiter.join(); +}) From f5ae83173929d2167bb3f1a926bdba7e69a2afae Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Wed, 3 Feb 2021 09:28:44 +0100 Subject: [PATCH 030/143] iox-#350 add more unit tests for EventListener class Signed-off-by: Marika Lehmann --- .../popo/building_blocks/event_listener.cpp | 5 ++- .../moduletests/test_popo_event_variable.cpp | 35 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp index 61507d71f1c..1c54111aa35 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp @@ -45,7 +45,10 @@ cxx::vector EventListener::w void EventListener::reset(const uint64_t index) noexcept { - m_pointerToEventVariableData->m_activeNotifications[index].store(false, std::memory_order_relaxed); + if (index < MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET) + { + m_pointerToEventVariableData->m_activeNotifications[index].store(false, std::memory_order_relaxed); + } } } // namespace popo } // namespace iox diff --git a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp index 9c909d9f591..e3d2fdc1238 100644 --- a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp @@ -162,3 +162,38 @@ TIMING_TEST_F(EventVariable_test, WaitBlocks, Repeat(5), [&] { hasWaited.store(true, std::memory_order_relaxed); waiter.join(); }) + +TEST_F(EventVariable_test, ResetTrueEntryResultsInFalse) +{ + uint64_t index = 3U; + EventNotifier notifier(m_eventVarData, index); + EventListener listener(m_eventVarData); + + notifier.notify(); + ASSERT_THAT(m_eventVarData.m_activeNotifications[index], Eq(true)); + + listener.reset(index); + EXPECT_THAT(m_eventVarData.m_activeNotifications[index], Eq(false)); +} + +TEST_F(EventVariable_test, ResetFalseEntryResultsInFalse) +{ + uint64_t index = 0U; + EventListener listener(m_eventVarData); + + ASSERT_THAT(m_eventVarData.m_activeNotifications[index], Eq(false)); + listener.reset(index); + EXPECT_THAT(m_eventVarData.m_activeNotifications[index], Eq(false)); +} + +TEST_F(EventVariable_test, ResetWithTooLargeIndexDoesNotChangeNotificationArray) +{ + uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; + EventListener listener(m_eventVarData); + + listener.reset(index); + for (const auto& notification : m_eventVarData.m_activeNotifications) + { + EXPECT_THAT(notification, Eq(false)); + } +} From 282af2154faa2abee9c50c5c3d1fcf22aabbc615 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Thu, 4 Feb 2021 14:23:51 +0100 Subject: [PATCH 031/143] iox-#350 correct wait method of EventListener and add more tests Signed-off-by: Marika Lehmann --- .../popo/building_blocks/event_listener.hpp | 2 + .../popo/building_blocks/event_listener.cpp | 29 +++++++++++ .../moduletests/test_popo_event_variable.cpp | 49 ++++++++++++++----- .../error_handling/error_handling.hpp | 1 + 4 files changed, 68 insertions(+), 13 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp index e03d5f418d3..b8ee7c26330 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp @@ -32,6 +32,8 @@ class EventListener void reset(const uint64_t index) noexcept; private: + void resetSemaphore() noexcept; + EventVariableData* m_pointerToEventVariableData{nullptr}; }; } // namespace popo diff --git a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp index 1c54111aa35..1c02d3d4686 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp @@ -25,7 +25,21 @@ EventListener::EventListener(EventVariableData& dataRef) noexcept cxx::vector EventListener::wait() noexcept { + resetSemaphore(); cxx::vector activeNotifications; + for (uint64_t i = 0U; i < MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; i++) + { + if (m_pointerToEventVariableData->m_activeNotifications[i].load(std::memory_order_relaxed)) + { + reset(i); + activeNotifications.emplace_back(i); + } + } + if (!activeNotifications.empty()) + { + return activeNotifications; + } + if (m_pointerToEventVariableData->m_semaphore.wait().has_error()) { errorHandler(Error::kPOPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_WAIT, nullptr, ErrorLevel::FATAL); @@ -36,6 +50,7 @@ cxx::vector EventListener::w { if (m_pointerToEventVariableData->m_activeNotifications[i].load(std::memory_order_relaxed)) { + reset(i); activeNotifications.emplace_back(i); } } @@ -50,5 +65,19 @@ void EventListener::reset(const uint64_t index) noexcept m_pointerToEventVariableData->m_activeNotifications[index].store(false, std::memory_order_relaxed); } } + +void EventListener::resetSemaphore() noexcept +{ + // Count the semaphore down to zero + while (m_pointerToEventVariableData->m_semaphore.tryWait() + .or_else([](posix::SemaphoreError) { + errorHandler( + Error::kPOPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_RESET, nullptr, ErrorLevel::FATAL); + }) + .value()) + { + } +} } // namespace popo } // namespace iox + diff --git a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp index e3d2fdc1238..d644721ead5 100644 --- a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp @@ -109,17 +109,6 @@ TEST_F(EventVariable_test, GetCorrectNotificationVectorAfterMultipleNotifyAndWai EXPECT_THAT(activeNotifications[1], Eq(index)); } -TEST_F(EventVariable_test, GetEmptyNotificationVectorAfterNotifyWithTooLargeAndWait) -{ - uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET + 1U; - EventNotifier notifier(m_eventVarData, index); - EventListener listener(m_eventVarData); - - notifier.notify(); - const auto& activeNotifications = listener.wait(); - EXPECT_THAT(activeNotifications.size(), Eq(0U)); -} - TEST_F(EventVariable_test, WaitAndNotifyResultsInCorrectNotificationVector) { uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 5U; @@ -156,10 +145,43 @@ TIMING_TEST_F(EventVariable_test, WaitBlocks, Repeat(5), [&] { semaphore.wait(); std::this_thread::sleep_for(std::chrono::milliseconds(10)); - hasWaited.store(false, std::memory_order_relaxed); + EXPECT_THAT(hasWaited, Eq(false)); notifier.notify(); std::this_thread::sleep_for(std::chrono::milliseconds(10)); - hasWaited.store(true, std::memory_order_relaxed); + EXPECT_THAT(hasWaited, Eq(true)); + waiter.join(); +}) + +TIMING_TEST_F(EventVariable_test, SecondWaitBlocksUntilNewNotification, Repeat(5), [&] { + uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 2U; + EventNotifier notifier1(m_eventVarData, index); + EventNotifier notifier2(m_eventVarData, 0U); + EventListener listener(m_eventVarData); + iox::posix::Semaphore semaphore = + iox::posix::Semaphore::create(iox::posix::CreateUnnamedSingleProcessSemaphore, 0U).value(); + std::atomic_bool hasWaited{false}; + + notifier1.notify(); + notifier2.notify(); + notificationVector activeNotifications = listener.wait(); + ASSERT_THAT(activeNotifications.size(), Eq(2U)); + EXPECT_THAT(activeNotifications[0], Eq(0U)); + EXPECT_THAT(activeNotifications[1], Eq(index)); + + std::thread waiter([&] { + semaphore.post(); + activeNotifications = listener.wait(); + hasWaited.store(true, std::memory_order_relaxed); + ASSERT_THAT(activeNotifications.size(), Eq(1U)); + EXPECT_THAT(activeNotifications[0], Eq(index)); + }); + + semaphore.wait(); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + EXPECT_THAT(hasWaited, Eq(false)); + notifier1.notify(); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + EXPECT_THAT(hasWaited, Eq(true)); waiter.join(); }) @@ -197,3 +219,4 @@ TEST_F(EventVariable_test, ResetWithTooLargeIndexDoesNotChangeNotificationArray) EXPECT_THAT(notification, Eq(false)); } } + diff --git a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp index 9dde425cccf..42d696aaba5 100644 --- a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp +++ b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp @@ -81,6 +81,7 @@ namespace iox error(POPO__CONDITION_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_RESET) \ error(POPO__EVENT_INFO_TYPE_INCONSISTENCY_IN_GET_ORIGIN) \ error(POPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_WAIT) \ + error(POPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_RESET) \ error(POPO__TYPED_UNIQUE_ID_ROUDI_HAS_NO_DEFINED_UNIQUE_ID) \ error(POPO__TYPED_UNIQUE_ID_ROUDI_HAS_ALREADY_DEFINED_UNIQUE_ID) \ error(POPO__TYPED_UNIQUE_ID_OVERFLOW) \ From b817cda00446ad319bf29c9d05d21081a13218c2 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Fri, 5 Feb 2021 14:19:26 +0100 Subject: [PATCH 032/143] iox-#350 fixed race condition while destroying active call set which led to deadlock. Introduced destroy() method in EventListener to make wait() non blocking Signed-off-by: Christian Eltzschig --- .../popo/building_blocks/event_listener.hpp | 2 + .../iceoryx_posh/popo/active_call_set.hpp | 2 + iceoryx_posh/source/popo/active_call_set.cpp | 16 +++----- .../popo/building_blocks/event_listener.cpp | 39 ++++++++++--------- .../moduletests/test_popo_active_call_set.cpp | 16 ++++++++ .../error_handling/error_handling.hpp | 1 + 6 files changed, 47 insertions(+), 29 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp index b8ee7c26330..66716386659 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp @@ -30,10 +30,12 @@ class EventListener cxx::vector wait() noexcept; void reset(const uint64_t index) noexcept; + void destroy() noexcept; private: void resetSemaphore() noexcept; + std::atomic_bool m_toBeDestroyed{false}; EventVariableData* m_pointerToEventVariableData{nullptr}; }; } // namespace popo diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp index c677bb655e3..0e4b9ddf98b 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -15,6 +15,7 @@ #ifndef IOX_POSH_POPO_ACTIVE_CALL_SET_HPP #define IOX_POSH_POPO_ACTIVE_CALL_SET_HPP +#include "iceoryx_posh/internal/popo/building_blocks/event_listener.hpp" #include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" #include "iceoryx_posh/popo/event_attorney.hpp" #include "iceoryx_posh/popo/trigger_handle.hpp" @@ -151,6 +152,7 @@ class ActiveCallSet std::atomic_bool m_wasDtorCalled{false}; EventVariableData* m_eventVariable = nullptr; + EventListener m_eventListener; }; } // namespace popo } // namespace iox diff --git a/iceoryx_posh/source/popo/active_call_set.cpp b/iceoryx_posh/source/popo/active_call_set.cpp index bc8f770c0ef..4f5d6aa1349 100644 --- a/iceoryx_posh/source/popo/active_call_set.cpp +++ b/iceoryx_posh/source/popo/active_call_set.cpp @@ -29,6 +29,7 @@ ActiveCallSet::ActiveCallSet() noexcept ActiveCallSet::ActiveCallSet(EventVariableData* eventVariable) noexcept : m_eventVariable(eventVariable) + , m_eventListener(*eventVariable) { m_thread = std::thread(&ActiveCallSet::threadLoop, this); } @@ -36,13 +37,10 @@ ActiveCallSet::ActiveCallSet(EventVariableData* eventVariable) noexcept ActiveCallSet::~ActiveCallSet() { m_wasDtorCalled.store(true, std::memory_order_relaxed); - - // notify eventVariable without origin to signal that we are in the dtor - m_eventVariable->m_semaphore.post(); - - m_eventVariable->m_toBeDestroyed.store(true, std::memory_order_relaxed); + m_eventListener.destroy(); m_thread.join(); + m_eventVariable->m_toBeDestroyed.store(true, std::memory_order_relaxed); } cxx::expected @@ -92,15 +90,11 @@ uint64_t ActiveCallSet::size() const noexcept void ActiveCallSet::threadLoop() noexcept { - EventListener eventListener(*m_eventVariable); while (m_wasDtorCalled.load(std::memory_order_relaxed) == false) { - auto activateNotificationIds = eventListener.wait(); + auto activateNotificationIds = m_eventListener.wait(); - cxx::forEach(activateNotificationIds, [this, &eventListener](auto id) { - eventListener.reset(id); - m_events[id]->executeCallback(); - }); + cxx::forEach(activateNotificationIds, [this](auto id) { m_events[id]->executeCallback(); }); } } diff --git a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp index 1c02d3d4686..4bc82e66039 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp @@ -23,28 +23,21 @@ EventListener::EventListener(EventVariableData& dataRef) noexcept { } -cxx::vector EventListener::wait() noexcept +void EventListener::destroy() noexcept { - resetSemaphore(); - cxx::vector activeNotifications; - for (uint64_t i = 0U; i < MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; i++) + m_toBeDestroyed.store(true, std::memory_order_relaxed); + if (m_pointerToEventVariableData->m_semaphore.post().has_error()) { - if (m_pointerToEventVariableData->m_activeNotifications[i].load(std::memory_order_relaxed)) - { - reset(i); - activeNotifications.emplace_back(i); - } - } - if (!activeNotifications.empty()) - { - return activeNotifications; + errorHandler(Error::kPOPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_DESTROY, nullptr, ErrorLevel::FATAL); } +} - if (m_pointerToEventVariableData->m_semaphore.wait().has_error()) - { - errorHandler(Error::kPOPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_WAIT, nullptr, ErrorLevel::FATAL); - } - else +cxx::vector EventListener::wait() noexcept +{ + cxx::vector activeNotifications; + + resetSemaphore(); + while (!m_toBeDestroyed.load(std::memory_order_relaxed)) { for (uint64_t i = 0U; i < MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; i++) { @@ -54,7 +47,17 @@ cxx::vector EventListener::w activeNotifications.emplace_back(i); } } + if (!activeNotifications.empty()) + { + return activeNotifications; + } + + if (m_pointerToEventVariableData->m_semaphore.wait().has_error()) + { + errorHandler(Error::kPOPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_WAIT, nullptr, ErrorLevel::FATAL); + } } + return activeNotifications; } diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index aefaaebb13b..96632ac3326 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -381,3 +381,19 @@ TEST_F(ActiveCallSet_test, AttachedEventDTorDetachesItself) // -- goes out of scope while callback is running + + +/////////////////////////////////// +// calling callbacks +/////////////////////////////////// +TIMING_TEST_F(ActiveCallSet_test, CallbackIsCalledAfterNotify, Repeat(5), [&] { + SimpleEventClass fuu; + m_sut->attachEvent( + fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0>); + + fuu.triggerStoepsel(); + m_sut.reset(); + + TIMING_TEST_EXPECT_TRUE(fuu.m_triggerCallbackArg[0] == &fuu); +}); + diff --git a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp index 42d696aaba5..885c9c5fda8 100644 --- a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp +++ b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp @@ -80,6 +80,7 @@ namespace iox error(POPO__CONDITION_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_TIMED_WAIT) \ error(POPO__CONDITION_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_RESET) \ error(POPO__EVENT_INFO_TYPE_INCONSISTENCY_IN_GET_ORIGIN) \ + error(POPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_DESTROY) \ error(POPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_WAIT) \ error(POPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_RESET) \ error(POPO__TYPED_UNIQUE_ID_ROUDI_HAS_NO_DEFINED_UNIQUE_ID) \ From 91f63172ce2dee188f744d818b92f26fdb523dd7 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Fri, 5 Feb 2021 14:37:13 +0100 Subject: [PATCH 033/143] iox-#350 fixed race condition caused by error in Event_t::isInitialized Signed-off-by: Christian Eltzschig --- iceoryx_posh/source/popo/active_call_set.cpp | 6 +++--- .../test/moduletests/test_popo_active_call_set.cpp | 13 +++++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/iceoryx_posh/source/popo/active_call_set.cpp b/iceoryx_posh/source/popo/active_call_set.cpp index 4f5d6aa1349..709b83dfb43 100644 --- a/iceoryx_posh/source/popo/active_call_set.cpp +++ b/iceoryx_posh/source/popo/active_call_set.cpp @@ -181,9 +181,9 @@ bool ActiveCallSet::Event_t::reset() noexcept bool ActiveCallSet::Event_t::isInitialized() const noexcept { - return m_origin != nullptr || m_eventId == INVALID_ID || m_eventType == INVALID_ID || m_eventTypeHash == INVALID_ID - || m_callback == nullptr || m_translationCallback == nullptr - || m_invalidationCallback == cxx::MethodCallback(); + return m_origin != nullptr && m_eventId != INVALID_ID && m_eventType != INVALID_ID && m_eventTypeHash != INVALID_ID + && m_callback != nullptr && m_translationCallback != nullptr + && m_invalidationCallback != cxx::MethodCallback(); } ////////////////// diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index 96632ac3326..ad0e241055b 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -119,8 +119,6 @@ class ActiveCallSet_test : public Test iox::popo::TriggerHandle m_handleStoepsel; mutable std::atomic_bool m_hasTriggered{false}; static uint64_t m_invalidateTriggerId; - - std::array m_triggerCallbackArg{nullptr}; }; class ActiveCallSetMock : public ActiveCallSet @@ -138,11 +136,15 @@ class ActiveCallSet_test : public Test template static void triggerCallback(ActiveCallSet_test::SimpleEventClass* const event) { - event->m_triggerCallbackArg[N] = event; + ActiveCallSet_test::m_triggerCallbackArg[N] = event; } void SetUp() { + for (auto& e : m_triggerCallbackArg) + { + e = nullptr; + } m_sut.emplace(&m_eventVarData); ActiveCallSet_test::SimpleEventClass::m_invalidateTriggerId = 0U; }; @@ -151,8 +153,11 @@ class ActiveCallSet_test : public Test using eventVector_t = iox::cxx::vector; eventVector_t m_simpleEvents{iox::MAX_NUMBER_OF_EVENTS_PER_WAITSET + 1}; + static std::array m_triggerCallbackArg; }; uint64_t ActiveCallSet_test::SimpleEventClass::m_invalidateTriggerId = 0U; +std::array + ActiveCallSet_test::m_triggerCallbackArg; ////////////////////////////////// // attach / detach test collection @@ -394,6 +399,6 @@ TIMING_TEST_F(ActiveCallSet_test, CallbackIsCalledAfterNotify, Repeat(5), [&] { fuu.triggerStoepsel(); m_sut.reset(); - TIMING_TEST_EXPECT_TRUE(fuu.m_triggerCallbackArg[0] == &fuu); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == &fuu); }); From 4979407e3aa5cfacc5c80ed2576bd7b14157d2fc Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 9 Feb 2021 11:18:55 +0100 Subject: [PATCH 034/143] iox-#350 added further timing tests Signed-off-by: Christian Eltzschig --- .../popo/building_blocks/event_listener.cpp | 1 + .../moduletests/test_popo_active_call_set.cpp | 93 ++++++++++++++++++- 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp index 4bc82e66039..8074f985ee9 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp @@ -56,6 +56,7 @@ cxx::vector EventListener::w { errorHandler(Error::kPOPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_WAIT, nullptr, ErrorLevel::FATAL); } + resetSemaphore(); } return activeNotifications; diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index ad0e241055b..772a25ca25f 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -137,6 +137,7 @@ class ActiveCallSet_test : public Test static void triggerCallback(ActiveCallSet_test::SimpleEventClass* const event) { ActiveCallSet_test::m_triggerCallbackArg[N] = event; + std::this_thread::sleep_for(std::chrono::milliseconds(m_triggerCallbackRuntimeInMs)); } void SetUp() @@ -147,17 +148,23 @@ class ActiveCallSet_test : public Test } m_sut.emplace(&m_eventVarData); ActiveCallSet_test::SimpleEventClass::m_invalidateTriggerId = 0U; + ActiveCallSet_test::m_triggerCallbackRuntimeInMs = 0U; }; void TearDown(){}; using eventVector_t = iox::cxx::vector; eventVector_t m_simpleEvents{iox::MAX_NUMBER_OF_EVENTS_PER_WAITSET + 1}; + static std::array m_triggerCallbackArg; + static constexpr uint64_t CALLBACK_WAIT_IN_MS = 10U; + static uint64_t m_triggerCallbackRuntimeInMs; }; uint64_t ActiveCallSet_test::SimpleEventClass::m_invalidateTriggerId = 0U; std::array ActiveCallSet_test::m_triggerCallbackArg; +constexpr uint64_t ActiveCallSet_test::CALLBACK_WAIT_IN_MS; +uint64_t ActiveCallSet_test::m_triggerCallbackRuntimeInMs; ////////////////////////////////// // attach / detach test collection @@ -397,8 +404,92 @@ TIMING_TEST_F(ActiveCallSet_test, CallbackIsCalledAfterNotify, Repeat(5), [&] { fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0>); fuu.triggerStoepsel(); - m_sut.reset(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == &fuu); +}); + +TIMING_TEST_F(ActiveCallSet_test, CallbackIsCalledOnlyOnceWhenTriggered, Repeat(5), [&] { + SimpleEventClass fuu1; + SimpleEventClass fuu2; + m_sut->attachEvent( + fuu1, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0>); + m_sut->attachEvent( + fuu2, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<1>); + + fuu1.triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + m_triggerCallbackArg[0] = nullptr; + fuu2.triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == nullptr); +}); + +TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherOneTimeCallback, Repeat(5), [&] { + SimpleEventClass fuu; + m_sut->attachEvent( + fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0>); + + m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + fuu.triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + m_triggerCallbackArg[0] = nullptr; + fuu.triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == &fuu); }); +TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnotherOneTimeCallback, Repeat(5), [&] { + SimpleEventClass fuu; + m_sut->attachEvent( + fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0>); + + m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + fuu.triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + m_triggerCallbackArg[0] = nullptr; + fuu.triggerStoepsel(); + fuu.triggerStoepsel(); + fuu.triggerStoepsel(); + fuu.triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + m_triggerCallbackArg[0] = nullptr; + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS * 2)); + + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == nullptr); +}); + +TIMING_TEST_F(ActiveCallSet_test, NoTriggerLeadsToNoCallback, Repeat(5), [&] { + SimpleEventClass fuu; + m_sut->attachEvent( + fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0>); + + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == nullptr); +}); + +template +struct AttachEvent; + +template <> +struct AttachEvent<0> +{ +}; + +TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacksOnce, Repeat(5), [&] { + std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); + + for (uint64_t i = 0U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) + m_sut->attachEvent( + events[i], ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback); + + m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + fuu.triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == nullptr); +}); + From ef4a850a8384c4fd0292741392251299851985b6 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 9 Feb 2021 11:35:30 +0100 Subject: [PATCH 035/143] iox-#350 multi callback test with templates integrated Signed-off-by: Christian Eltzschig --- .../moduletests/test_popo_active_call_set.cpp | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index 772a25ca25f..6e235874e47 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -472,22 +472,37 @@ TIMING_TEST_F(ActiveCallSet_test, NoTriggerLeadsToNoCallback, Repeat(5), [&] { }); template -struct AttachEvent; +struct AttachEvent +{ + template + static void doIt(ActiveCallSet_test::ActiveCallSetMock& sut, + std::vector& events, + const EventType event) + { + sut.attachEvent(events[N], event, ActiveCallSet_test::triggerCallback); + AttachEvent::doIt(sut, events, event); + } +}; template <> struct AttachEvent<0> { + template + static void doIt(ActiveCallSet_test::ActiveCallSetMock& sut, + std::vector& events, + const EventType event) + { + sut.attachEvent(events[0], event, ActiveCallSet_test::triggerCallback<0>); + } }; TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacksOnce, Repeat(5), [&] { std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - for (uint64_t i = 0U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) - m_sut->attachEvent( - events[i], ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback); + AttachEvent::doIt( + *m_sut, events, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty); m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; - fuu.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == nullptr); From 7a312e590cf186ec12812448626570209c2244c3 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 9 Feb 2021 11:52:50 +0100 Subject: [PATCH 036/143] iox-#350 make reset() private and adapt tests Signed-off-by: Marika Lehmann --- .../popo/building_blocks/event_listener.hpp | 3 +- .../popo/building_blocks/event_listener.cpp | 1 - .../moduletests/test_popo_event_variable.cpp | 35 ++++++------------- 3 files changed, 12 insertions(+), 27 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp index 66716386659..21cca69a49e 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp @@ -29,10 +29,11 @@ class EventListener cxx::vector wait() noexcept; - void reset(const uint64_t index) noexcept; void destroy() noexcept; private: + void reset(const uint64_t index) noexcept; + void resetSemaphore() noexcept; std::atomic_bool m_toBeDestroyed{false}; diff --git a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp index 8074f985ee9..4bc82e66039 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp @@ -56,7 +56,6 @@ cxx::vector EventListener::w { errorHandler(Error::kPOPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_WAIT, nullptr, ErrorLevel::FATAL); } - resetSemaphore(); } return activeNotifications; diff --git a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp index d644721ead5..b8592e608eb 100644 --- a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp @@ -185,35 +185,20 @@ TIMING_TEST_F(EventVariable_test, SecondWaitBlocksUntilNewNotification, Repeat(5 waiter.join(); }) -TEST_F(EventVariable_test, ResetTrueEntryResultsInFalse) +TEST_F(EventVariable_test, AllEntriesAreResetToFalseInsideWait) { - uint64_t index = 3U; - EventNotifier notifier(m_eventVarData, index); - EventListener listener(m_eventVarData); - - notifier.notify(); - ASSERT_THAT(m_eventVarData.m_activeNotifications[index], Eq(true)); - - listener.reset(index); - EXPECT_THAT(m_eventVarData.m_activeNotifications[index], Eq(false)); -} - -TEST_F(EventVariable_test, ResetFalseEntryResultsInFalse) -{ - uint64_t index = 0U; + uint64_t index1 = 3U; + uint64_t index2 = 1U; + EventNotifier notifier1(m_eventVarData, index1); + EventNotifier notifier2(m_eventVarData, index2); EventListener listener(m_eventVarData); - ASSERT_THAT(m_eventVarData.m_activeNotifications[index], Eq(false)); - listener.reset(index); - EXPECT_THAT(m_eventVarData.m_activeNotifications[index], Eq(false)); -} - -TEST_F(EventVariable_test, ResetWithTooLargeIndexDoesNotChangeNotificationArray) -{ - uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; - EventListener listener(m_eventVarData); + notifier1.notify(); + ASSERT_THAT(m_eventVarData.m_activeNotifications[index1], Eq(true)); + notifier2.notify(); + ASSERT_THAT(m_eventVarData.m_activeNotifications[index2], Eq(true)); - listener.reset(index); + listener.wait(); for (const auto& notification : m_eventVarData.m_activeNotifications) { EXPECT_THAT(notification, Eq(false)); From 5692ddcd556a3828c2efbfed8dcb5417e73c610d Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 9 Feb 2021 12:24:19 +0100 Subject: [PATCH 037/143] iox-#350 add unit tests for destroy Signed-off-by: Marika Lehmann --- .../moduletests/test_popo_event_variable.cpp | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp index b8592e608eb..154c5787ef0 100644 --- a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp @@ -198,10 +198,47 @@ TEST_F(EventVariable_test, AllEntriesAreResetToFalseInsideWait) notifier2.notify(); ASSERT_THAT(m_eventVarData.m_activeNotifications[index2], Eq(true)); - listener.wait(); + const auto& activeNotifications = listener.wait(); + EXPECT_THAT(activeNotifications.size(), Eq(2U)); for (const auto& notification : m_eventVarData.m_activeNotifications) { EXPECT_THAT(notification, Eq(false)); } } +TEST_F(EventVariable_test, WaitIsNonBlockingAfterDestroyAndReturnsEmptyVector) +{ + EventListener sut(m_eventVarData); + sut.destroy(); + const auto& activeNotifications = sut.wait(); + + EXPECT_THAT(activeNotifications.size(), Eq(0U)); +} + +TEST_F(EventVariable_test, WaitIsNonBlockingAfterDestroyAndNotifyAndReturnsEmptyVector) +{ + EventListener sut(m_eventVarData); + sut.destroy(); + + EventNotifier notifier(m_eventVarData, 0U); + notifier.notify(); + + const auto& activeNotifications = sut.wait(); + EXPECT_THAT(activeNotifications.size(), Eq(0U)); +} + +TEST_F(EventVariable_test, DestroyWakesUpWaitWhichReturnsEmptyVector) +{ + EventListener sut(m_eventVarData); + + notificationVector activeNotifications; + + std::thread waiter([&] { + activeNotifications = sut.wait(); + EXPECT_THAT(activeNotifications.size(), Eq(0U)); + }); + + sut.destroy(); + waiter.join(); +} + From cddaa8990a53ae29d86b6eb75f7ede84546830fc Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 9 Feb 2021 12:37:24 +0100 Subject: [PATCH 038/143] iox-#350 added concurrent attach/detach tests Signed-off-by: Christian Eltzschig --- .../moduletests/test_popo_active_call_set.cpp | 230 +++++++++++++++++- 1 file changed, 217 insertions(+), 13 deletions(-) diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index 6e235874e47..f1c7a9720f4 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -140,6 +140,18 @@ class ActiveCallSet_test : public Test std::this_thread::sleep_for(std::chrono::milliseconds(m_triggerCallbackRuntimeInMs)); } + template + static void attachCallback(ActiveCallSet_test::SimpleEventClass* const) + { + m_toBeAttached[N].sut->attachEvent(m_toBeAttached[N].object, triggerCallback); + } + + template + static void detachCallback(ActiveCallSet_test::SimpleEventClass* const) + { + m_toBeAttached[N].sut->detachEvent(m_toBeAttached[N].object, triggerCallback); + } + void SetUp() { for (auto& e : m_triggerCallbackArg) @@ -149,13 +161,22 @@ class ActiveCallSet_test : public Test m_sut.emplace(&m_eventVarData); ActiveCallSet_test::SimpleEventClass::m_invalidateTriggerId = 0U; ActiveCallSet_test::m_triggerCallbackRuntimeInMs = 0U; + ActiveCallSet_test::m_toBeAttached.clear(); }; void TearDown(){}; + struct ToBeAttached_t + { + SimpleEventClass* object; + ActiveCallSetMock* sut; + }; + using eventVector_t = iox::cxx::vector; eventVector_t m_simpleEvents{iox::MAX_NUMBER_OF_EVENTS_PER_WAITSET + 1}; + static std::vector m_toBeAttached; + static std::vector m_toBeDetached; static std::array m_triggerCallbackArg; static constexpr uint64_t CALLBACK_WAIT_IN_MS = 10U; static uint64_t m_triggerCallbackRuntimeInMs; @@ -165,11 +186,12 @@ std::array ActiveCallSet_test::m_toBeAttached; +std::vector ActiveCallSet_test::m_toBeDetached; ////////////////////////////////// -// attach / detach test collection +// attach / detach ////////////////////////////////// - TEST_F(ActiveCallSet_test, IsEmptyWhenConstructed) { EXPECT_THAT(m_sut->size(), Eq(0U)); @@ -387,14 +409,6 @@ TEST_F(ActiveCallSet_test, AttachedEventDTorDetachesItself) EXPECT_THAT(m_sut->size(), Eq(0U)); } -////////////////////////////////// -// concurrent attach / detach -////////////////////////////////// - - -// -- goes out of scope while callback is running - - /////////////////////////////////// // calling callbacks /////////////////////////////////// @@ -426,7 +440,7 @@ TIMING_TEST_F(ActiveCallSet_test, CallbackIsCalledOnlyOnceWhenTriggered, Repeat( TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == nullptr); }); -TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherOneTimeCallback, Repeat(5), [&] { +TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherCallback, Repeat(5), [&] { SimpleEventClass fuu; m_sut->attachEvent( fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0>); @@ -441,7 +455,31 @@ TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherOneTimeCal TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == &fuu); }); -TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnotherOneTimeCallback, Repeat(5), [&] { +TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherCallbackOnce, Repeat(5), [&] { + SimpleEventClass fuu; + SimpleEventClass bar; + m_sut->attachEvent( + fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0>); + m_sut->attachEvent( + bar, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<1>); + + m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + fuu.triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + m_triggerCallbackArg[0] = nullptr; + fuu.triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + + m_triggerCallbackArg[0] = nullptr; + + bar.triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(4 * CALLBACK_WAIT_IN_MS)); + + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == nullptr); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1] == &bar); +}); + +TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnotherCallback, Repeat(5), [&] { SimpleEventClass fuu; m_sut->attachEvent( fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0>); @@ -461,6 +499,33 @@ TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnot TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == nullptr); }); +TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnotherCallbackOnce, Repeat(5), [&] { + SimpleEventClass fuu; + SimpleEventClass bar; + m_sut->attachEvent( + fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0>); + m_sut->attachEvent( + bar, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<1>); + + m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + fuu.triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + m_triggerCallbackArg[0] = nullptr; + fuu.triggerStoepsel(); + fuu.triggerStoepsel(); + fuu.triggerStoepsel(); + fuu.triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + + m_triggerCallbackArg[0] = nullptr; + + bar.triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(4 * CALLBACK_WAIT_IN_MS)); + + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == nullptr); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1] == &bar); +}); + TIMING_TEST_F(ActiveCallSet_test, NoTriggerLeadsToNoCallback, Repeat(5), [&] { SimpleEventClass fuu; m_sut->attachEvent( @@ -496,15 +561,154 @@ struct AttachEvent<0> } }; +TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacks, Repeat(5), [&] { + std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); + + AttachEvent::doIt( + *m_sut, events, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty); + + m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + events[0].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + m_triggerCallbackArg[0] = nullptr; + m_triggerCallbackRuntimeInMs = 0; + + for (auto& e : events) + e.triggerStoepsel(); + + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + + for (uint64_t i = 0U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) + { + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i] == &events[i]); + } +}); + TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacksOnce, Repeat(5), [&] { std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - AttachEvent::doIt( + AttachEvent::doIt( *m_sut, events, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty); m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + events[0].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + m_triggerCallbackArg[0] = nullptr; + m_triggerCallbackRuntimeInMs = 0; + + for (auto& e : events) + e.triggerStoepsel(); + + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + for (auto& t : m_triggerCallbackArg) + { + t = nullptr; + } + + events[0].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + + for (uint64_t i = 1U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) + { + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i] == nullptr); + } +}); + +// TODO -- goes out of scope while callback is running +// TODO attach in callback, detach in callback (blocking!) + +////////////////////////////////// +// concurrent attach / detach +////////////////////////////////// +TIMING_TEST_F(ActiveCallSet_test, AttachingWhileCallbackIsRunningWorks, Repeat(5), [&] { + std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); + + m_sut->attachEvent(events[0], SimpleEvent::StoepselBachelorParty, triggerCallback<0>); + + m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + events[0].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + + m_sut->attachEvent(events[1], SimpleEvent::StoepselBachelorParty, triggerCallback<1>); + events[1].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1] == &events[1]); +}); + +TIMING_TEST_F(ActiveCallSet_test, AttachingMultipleWhileCallbackIsRunningWorks, Repeat(5), [&] { + std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); + + m_sut->attachEvent(events[iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1], + SimpleEvent::StoepselBachelorParty, + triggerCallback); + + m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + events[iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + + AttachEvent::doIt( + *m_sut, events, SimpleEvent::StoepselBachelorParty); + + m_triggerCallbackRuntimeInMs = 0; + for (uint64_t i = 0U; i + 1 < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) + { + events[i].triggerStoepsel(); + } + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + + for (uint64_t i = 0U; i + 1 < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) + { + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i] == &events[i]); + } +}); + +TIMING_TEST_F(ActiveCallSet_test, DetachingWhileCallbackIsRunningWorks, Repeat(5), [&] { + std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); + + m_sut->attachEvent(events[0], SimpleEvent::StoepselBachelorParty, triggerCallback<0>); + + m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + events[0].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + + m_triggerCallbackArg[0] = nullptr; + m_sut->detachEvent(events[0], SimpleEvent::StoepselBachelorParty); + events[0].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == nullptr); }); +TIMING_TEST_F(ActiveCallSet_test, DetachingMultipleWhileCallbackIsRunningWorks, Repeat(5), [&] { + std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); + AttachEvent::doIt( + *m_sut, events, SimpleEvent::StoepselBachelorParty); + + m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + events[0].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + + m_triggerCallbackRuntimeInMs = 0U; + for (auto& e : events) + { + m_sut->detachEvent(e, SimpleEvent::StoepselBachelorParty); + } + + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + for (auto& t : m_triggerCallbackArg) + { + t = nullptr; + } + for (auto& e : events) + { + e.triggerStoepsel(); + } + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + + for (uint64_t i = 0; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) + { + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i] == nullptr); + } +}); + From 84f5237aeb52875f68345758b74f6c8117ec9dd0 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 9 Feb 2021 15:12:27 +0100 Subject: [PATCH 039/143] iox-#350 add doxygen comments for EventVariableData, EventListener, EventNotifier Signed-off-by: Marika Lehmann --- .../internal/popo/building_blocks/event_listener.hpp | 12 ++++++++++++ .../internal/popo/building_blocks/event_notifier.hpp | 6 ++++++ .../popo/building_blocks/event_variable_data.hpp | 5 +++++ .../popo/building_blocks/event_variable_data.cpp | 1 + 4 files changed, 24 insertions(+) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp index 21cca69a49e..40ac09a14e8 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp @@ -25,15 +25,27 @@ namespace popo class EventListener { public: + /// @brief creates new EventListener + /// + /// @param dataRef reference to EventVariableData EventListener(EventVariableData& dataRef) noexcept; + /// @brief returns vector of indices of active notifications; blocking if EventVariableData was not notified unless + /// toBeDestroyed flag is true + /// + /// @return vector of active notifications cxx::vector wait() noexcept; + /// @brief sets toBeDestroyed flag to true void destroy() noexcept; private: + /// @brief sets entry of EventVariableData's activeNotifications array to false + /// + /// @param index index corresponding to trigger id void reset(const uint64_t index) noexcept; + /// @brief counts the semaphore down to zero void resetSemaphore() noexcept; std::atomic_bool m_toBeDestroyed{false}; diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp index ca716728245..7318ee41add 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp @@ -24,8 +24,14 @@ namespace popo class EventNotifier { public: + /// @brief creates new EventNotifier + /// + /// @param dataRef reference to EventVariableData + /// @param index index corresponding to trigger id EventNotifier(EventVariableData& dataRef, const uint64_t index) noexcept; + /// @brief sets corresponding entry in EventVariableData array to true which means that the respective signaller has + /// triggered the event variable void notify() noexcept; private: diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp index 1bcc0f9825c..a963267121d 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp @@ -23,7 +23,12 @@ namespace popo { struct EventVariableData : public ConditionVariableData { + /// @brief sets all entries of notification array to false EventVariableData() noexcept; + + /// @brief sets all entries of notification array to false and sets process name + /// + /// @param process name of process EventVariableData(const ProcessName_t& process) noexcept; std::atomic_bool m_activeNotifications[MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET]; diff --git a/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp b/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp index 811b85a9d20..19616cffd76 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp @@ -22,6 +22,7 @@ EventVariableData::EventVariableData() noexcept { iox::cxx::forEach(m_activeNotifications, [](auto& id) { id.store(false, std::memory_order_relaxed); }); } + EventVariableData::EventVariableData(const ProcessName_t& process) noexcept : ConditionVariableData(process) { From a35b62ec9b941de6a5632d65bcff7dfa83346b20 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 9 Feb 2021 17:48:21 +0100 Subject: [PATCH 040/143] iox-#350 added concurrent in callback attach / detach tests Signed-off-by: Christian Eltzschig --- .../moduletests/test_popo_active_call_set.cpp | 155 ++++++++++++++++-- 1 file changed, 145 insertions(+), 10 deletions(-) diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index f1c7a9720f4..d22e8cab140 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -140,18 +140,32 @@ class ActiveCallSet_test : public Test std::this_thread::sleep_for(std::chrono::milliseconds(m_triggerCallbackRuntimeInMs)); } - template static void attachCallback(ActiveCallSet_test::SimpleEventClass* const) { - m_toBeAttached[N].sut->attachEvent(m_toBeAttached[N].object, triggerCallback); + for (auto& e : m_toBeAttached) + { + e.sut->attachEvent(*e.object, SimpleEvent::StoepselBachelorParty, triggerCallback<0>); + } } - template static void detachCallback(ActiveCallSet_test::SimpleEventClass* const) { - m_toBeAttached[N].sut->detachEvent(m_toBeAttached[N].object, triggerCallback); + for (auto& e : m_toBeDetached) + { + e.sut->detachEvent(*e.object, SimpleEvent::StoepselBachelorParty); + } + } + + static void notifyAndThenDetachCallback(ActiveCallSet_test::SimpleEventClass* const) + { + for (auto& e : m_toBeDetached) + { + e.object->triggerStoepsel(); + e.sut->detachEvent(*e.object, SimpleEvent::StoepselBachelorParty); + } } + void SetUp() { for (auto& e : m_triggerCallbackArg) @@ -162,6 +176,7 @@ class ActiveCallSet_test : public Test ActiveCallSet_test::SimpleEventClass::m_invalidateTriggerId = 0U; ActiveCallSet_test::m_triggerCallbackRuntimeInMs = 0U; ActiveCallSet_test::m_toBeAttached.clear(); + ActiveCallSet_test::m_toBeDetached.clear(); }; void TearDown(){}; @@ -178,7 +193,7 @@ class ActiveCallSet_test : public Test static std::vector m_toBeAttached; static std::vector m_toBeDetached; static std::array m_triggerCallbackArg; - static constexpr uint64_t CALLBACK_WAIT_IN_MS = 10U; + static constexpr uint64_t CALLBACK_WAIT_IN_MS = 100U; static uint64_t m_triggerCallbackRuntimeInMs; }; uint64_t ActiveCallSet_test::SimpleEventClass::m_invalidateTriggerId = 0U; @@ -544,7 +559,7 @@ struct AttachEvent std::vector& events, const EventType event) { - sut.attachEvent(events[N], event, ActiveCallSet_test::triggerCallback); + EXPECT_THAT(sut.attachEvent(events[N], event, ActiveCallSet_test::triggerCallback).has_error(), Eq(false)); AttachEvent::doIt(sut, events, event); } }; @@ -557,7 +572,7 @@ struct AttachEvent<0> std::vector& events, const EventType event) { - sut.attachEvent(events[0], event, ActiveCallSet_test::triggerCallback<0>); + EXPECT_THAT(sut.attachEvent(events[0], event, ActiveCallSet_test::triggerCallback<0>).has_error(), Eq(false)); } }; @@ -614,9 +629,6 @@ TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacksOnce, Repe } }); -// TODO -- goes out of scope while callback is running -// TODO attach in callback, detach in callback (blocking!) - ////////////////////////////////// // concurrent attach / detach ////////////////////////////////// @@ -680,6 +692,37 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingWhileCallbackIsRunningWorks, Repeat(5 TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == nullptr); }); +TIMING_TEST_F(ActiveCallSet_test, DetachingWhileCallbackIsRunningBlocksDetach, Repeat(5), [&] { + std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); + m_sut->attachEvent(events[0], SimpleEvent::StoepselBachelorParty, triggerCallback<0>); + m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + events[0].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 4)); + + auto begin = std::chrono::system_clock::now(); + m_sut->detachEvent(events[0], SimpleEvent::StoepselBachelorParty); + auto end = std::chrono::system_clock::now(); + + auto elapsed = std::chrono::duration_cast(end - begin); + TIMING_TEST_EXPECT_TRUE(static_cast(elapsed.count()) > CALLBACK_WAIT_IN_MS / 2); +}); + +TIMING_TEST_F(ActiveCallSet_test, EventDestructorBlocksWhenCallbackIsRunning, Repeat(5), [&] { + SimpleEventClass* event = new SimpleEventClass(); + m_sut->attachEvent(*event, SimpleEvent::StoepselBachelorParty, triggerCallback<0>); + m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + event->triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 4)); + + auto begin = std::chrono::system_clock::now(); + delete event; + auto end = std::chrono::system_clock::now(); + + auto elapsed = std::chrono::duration_cast(end - begin); + TIMING_TEST_EXPECT_TRUE(static_cast(elapsed.count()) > CALLBACK_WAIT_IN_MS / 2); +}); + + TIMING_TEST_F(ActiveCallSet_test, DetachingMultipleWhileCallbackIsRunningWorks, Repeat(5), [&] { std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); AttachEvent::doIt( @@ -712,3 +755,95 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingMultipleWhileCallbackIsRunningWorks, } }); +TIMING_TEST_F(ActiveCallSet_test, AttachingDetachingRunsIndependentOfCallback, Repeat(5), [&] { + std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); + m_sut->attachEvent(events[iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1], + SimpleEvent::StoepselBachelorParty, + triggerCallback); + m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + events[iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + + AttachEvent::doIt( + *m_sut, events, SimpleEvent::StoepselBachelorParty); + + for (auto& e : events) + { + m_sut->detachEvent(e, SimpleEvent::StoepselBachelorParty); + } + + // EXPECT_* (assert step) is inside of doIt call. We expect that every event can + // be attached + AttachEvent::doIt( + *m_sut, events, SimpleEvent::StoepselBachelorParty); +}); + +////////////////////////////////// +// attach / detach in callbacks +////////////////////////////////// +TIMING_TEST_F(ActiveCallSet_test, DetachingSelfInCallbackWorks, Repeat(5), [&] { + m_toBeDetached.clear(); + + std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); + m_toBeDetached.push_back({&events[0], &*m_sut}); + m_sut->attachEvent(events[0], SimpleEvent::StoepselBachelorParty, detachCallback); + + events[0].triggerStoepsel(); + + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + + TIMING_TEST_EXPECT_TRUE(m_sut->size() == 0); +}); + +TIMING_TEST_F(ActiveCallSet_test, DetachingNonSelfEventInCallbackWorks, Repeat(5), [&] { + m_toBeDetached.clear(); + + std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); + m_toBeDetached.push_back({&events[1], &*m_sut}); + m_sut->attachEvent(events[0], SimpleEvent::StoepselBachelorParty, detachCallback); + m_sut->attachEvent(events[1], SimpleEvent::StoepselBachelorParty, triggerCallback<1>); + + events[0].triggerStoepsel(); + + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + + TIMING_TEST_EXPECT_TRUE(m_sut->size() == 1); +}); + +TIMING_TEST_F(ActiveCallSet_test, DetachedCallbacksAreNotBeingCalledWhenTriggeredBefore, Repeat(5), [&] { + m_toBeDetached.clear(); + + std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); + m_toBeDetached.push_back({&events[1], &*m_sut}); + m_sut->attachEvent(events[0], SimpleEvent::StoepselBachelorParty, notifyAndThenDetachCallback); + m_sut->attachEvent(events[1], SimpleEvent::StoepselBachelorParty, triggerCallback<1>); + + m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + events[1].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + m_triggerCallbackArg[1] = nullptr; + m_triggerCallbackRuntimeInMs = 0; + + events[0].triggerStoepsel(); + events[1].triggerStoepsel(); + + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1] == nullptr); +}); + +TIMING_TEST_F(ActiveCallSet_test, AttachingInCallbackWorks, Repeat(1), [&] { + m_toBeAttached.clear(); + + std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); + m_toBeAttached.push_back({&events[1], &*m_sut}); + m_sut->attachEvent(events[0], SimpleEvent::StoepselBachelorParty, attachCallback); + + events[0].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + events[1].triggerStoepsel(); + + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == &events[1]); +}); From 4a2bb27844f4f3f97c755c3b038f6b5b44c7e70e Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 9 Feb 2021 18:23:32 +0100 Subject: [PATCH 041/143] iox-#350 add todos Signed-off-by: Marika Lehmann --- .../internal/popo/building_blocks/chunk_queue_popper.hpp | 2 ++ .../iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp index 4677d8bab19..4d89f1622e2 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp @@ -82,6 +82,8 @@ class ChunkQueuePopper /// @param[in] ConditionVariableDataPtr, pointer to an condition variable data object void setConditionVariable(cxx::not_null conditionVariableDataPtr) noexcept; + // TODO: remove once ConditionVariable and EventVariable are combined + // unset is done with unsetConditionVariable void setEventVariable(EventVariableData& eventVariableDataPtr, const uint64_t eventId) noexcept; /// @brief Detaches a condition variable diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp index facbefb8446..e059765edc8 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp @@ -83,6 +83,8 @@ class SubscriberPortUser : public BasePort /// @brief attach a condition variable (via its pointer) to subscriber void setConditionVariable(ConditionVariableData* conditionVariableDataPtr) noexcept; + // TODO: remove once ConditionVariable and EventVariable are combined + // do we need an unsetEventVariable method? void setEventVariable(EventVariableData& eventVariableData, const uint64_t eventId) noexcept; /// @brief detach a condition variable from subscriber From f4c08c1965e3056eb0ff1618822d0d267ab67d57 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 9 Feb 2021 18:24:50 +0100 Subject: [PATCH 042/143] iox-#350 adjusted copyright headers Signed-off-by: Christian Eltzschig --- iceoryx_examples/callbacks/ice_callbacks_publisher.cpp | 2 +- iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp | 2 +- iceoryx_examples/callbacks/topic_data.hpp | 2 +- iceoryx_meta/CMakeLists.txt | 3 ++- iceoryx_posh/CMakeLists.txt | 3 ++- iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp | 3 ++- .../include/iceoryx_posh/internal/popo/base_subscriber.inl | 3 ++- .../internal/popo/building_blocks/chunk_queue_data.hpp | 1 + .../internal/popo/building_blocks/chunk_queue_popper.hpp | 1 + .../internal/popo/building_blocks/chunk_queue_popper.inl | 1 + .../internal/popo/building_blocks/chunk_queue_pusher.hpp | 1 + .../internal/popo/building_blocks/chunk_queue_pusher.inl | 1 + .../internal/popo/building_blocks/condition_variable_data.hpp | 1 + .../iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp | 1 + .../include/iceoryx_posh/internal/roudi/port_manager.hpp | 1 + .../include/iceoryx_posh/internal/roudi/port_pool_data.hpp | 1 + .../include/iceoryx_posh/internal/roudi/roudi_process.hpp | 3 ++- .../iceoryx_posh/internal/runtime/message_queue_interface.hpp | 3 ++- iceoryx_posh/include/iceoryx_posh/roudi/port_pool.hpp | 3 ++- iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp | 3 ++- iceoryx_posh/source/popo/ports/subscriber_port_user.cpp | 1 + iceoryx_posh/source/roudi/port_manager.cpp | 3 ++- iceoryx_posh/source/roudi/port_pool.cpp | 3 ++- iceoryx_posh/source/roudi/roudi.cpp | 3 ++- iceoryx_posh/source/roudi/roudi_process.cpp | 3 ++- iceoryx_posh/source/runtime/posh_runtime.cpp | 3 ++- iceoryx_posh/test/mocks/subscriber_mock.hpp | 3 ++- iceoryx_posh/test/moduletests/test_popo_waitset.cpp | 3 ++- iceoryx_posh/test/moduletests/test_posh_runtime.cpp | 3 ++- iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp | 3 ++- iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp | 1 + .../include/iceoryx_utils/error_handling/error_handling.hpp | 3 ++- 32 files changed, 50 insertions(+), 21 deletions(-) diff --git a/iceoryx_examples/callbacks/ice_callbacks_publisher.cpp b/iceoryx_examples/callbacks/ice_callbacks_publisher.cpp index 9ec2a1aa664..2b89cfea4e8 100644 --- a/iceoryx_examples/callbacks/ice_callbacks_publisher.cpp +++ b/iceoryx_examples/callbacks/ice_callbacks_publisher.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp index 027797e450b..bb2b9bb7ec6 100644 --- a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp +++ b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_examples/callbacks/topic_data.hpp b/iceoryx_examples/callbacks/topic_data.hpp index a48f4ed746b..4d4e2c11add 100644 --- a/iceoryx_examples/callbacks/topic_data.hpp +++ b/iceoryx_examples/callbacks/topic_data.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_meta/CMakeLists.txt b/iceoryx_meta/CMakeLists.txt index cd35ad5aac7..c9142afcfa9 100644 --- a/iceoryx_meta/CMakeLists.txt +++ b/iceoryx_meta/CMakeLists.txt @@ -1,4 +1,5 @@ -# Copyright (c) 2019, 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +# Copyright (c) 2019, 2020 by Robert Bosch GmbH. All rights reserved. +# Copyright (c) 2020, 2021 by Apex.AI Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/CMakeLists.txt b/iceoryx_posh/CMakeLists.txt index f376c6e7acb..3f8b89b23d3 100644 --- a/iceoryx_posh/CMakeLists.txt +++ b/iceoryx_posh/CMakeLists.txt @@ -1,4 +1,5 @@ -# Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +# Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +# Copyright (c) 2020, 2021 by Apex.AI Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp b/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp index 7169f4d2a68..aa1f82fa258 100644 --- a/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp +++ b/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp @@ -1,4 +1,5 @@ -// Copyright (c) 2019 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/base_subscriber.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/base_subscriber.inl index 52ba9fae277..fb3086c6c76 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/base_subscriber.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/base_subscriber.inl @@ -1,4 +1,5 @@ -// Copyright (c) 2020, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2020, 2021 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2020, 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_data.hpp index 5e5519c7128..fd7456c871b 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_data.hpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp index 4677d8bab19..7b75a1a357a 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.inl index b05f4a5a91c..0aa4f0e9e76 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.inl @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp index f18a0c28a68..dae762cabf3 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.inl index 3994a439a75..ffc8363e507 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.inl @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp index 63914404cf1..93af2c10ddb 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp index facbefb8446..f10725fa079 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp b/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp index 90f56b9e3ca..26f887106d2 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp @@ -1,4 +1,5 @@ // Copyright (c) 2019, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_pool_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_pool_data.hpp index 2db247992fc..8c5e57c3c60 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_pool_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_pool_data.hpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/include/iceoryx_posh/internal/roudi/roudi_process.hpp b/iceoryx_posh/include/iceoryx_posh/internal/roudi/roudi_process.hpp index a539349634d..2773871fc66 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/roudi/roudi_process.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/roudi/roudi_process.hpp @@ -1,4 +1,5 @@ -// Copyright (c) 2019, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2019, 2021 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/include/iceoryx_posh/internal/runtime/message_queue_interface.hpp b/iceoryx_posh/include/iceoryx_posh/internal/runtime/message_queue_interface.hpp index fce481e1e48..1c934855e5b 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/runtime/message_queue_interface.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/runtime/message_queue_interface.hpp @@ -1,4 +1,5 @@ -// Copyright (c) 2019, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2019, 2021 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/include/iceoryx_posh/roudi/port_pool.hpp b/iceoryx_posh/include/iceoryx_posh/roudi/port_pool.hpp index 025ea21163c..40a835183a3 100644 --- a/iceoryx_posh/include/iceoryx_posh/roudi/port_pool.hpp +++ b/iceoryx_posh/include/iceoryx_posh/roudi/port_pool.hpp @@ -1,4 +1,5 @@ -// Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2020, 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp b/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp index 09ea50ba0b3..3bc1a0d32e4 100644 --- a/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp +++ b/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp @@ -1,4 +1,5 @@ -// Copyright (c) 2019, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp b/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp index 904d9a000bf..7fc3b67e2a3 100644 --- a/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp +++ b/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/source/roudi/port_manager.cpp b/iceoryx_posh/source/roudi/port_manager.cpp index 1425255b198..f30f8d9124c 100644 --- a/iceoryx_posh/source/roudi/port_manager.cpp +++ b/iceoryx_posh/source/roudi/port_manager.cpp @@ -1,4 +1,5 @@ -// Copyright (c) 2019, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/source/roudi/port_pool.cpp b/iceoryx_posh/source/roudi/port_pool.cpp index 3696effb0e2..f6ea55bf299 100644 --- a/iceoryx_posh/source/roudi/port_pool.cpp +++ b/iceoryx_posh/source/roudi/port_pool.cpp @@ -1,4 +1,5 @@ -// Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2020, 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/source/roudi/roudi.cpp b/iceoryx_posh/source/roudi/roudi.cpp index b89b00eab7b..6ec5f79dfb8 100644 --- a/iceoryx_posh/source/roudi/roudi.cpp +++ b/iceoryx_posh/source/roudi/roudi.cpp @@ -1,4 +1,5 @@ -// Copyright (c) 2019, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/source/roudi/roudi_process.cpp b/iceoryx_posh/source/roudi/roudi_process.cpp index 852550960ce..eb02fef27ae 100644 --- a/iceoryx_posh/source/roudi/roudi_process.cpp +++ b/iceoryx_posh/source/roudi/roudi_process.cpp @@ -1,4 +1,5 @@ -// Copyright (c) 2019, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/source/runtime/posh_runtime.cpp b/iceoryx_posh/source/runtime/posh_runtime.cpp index 675874688a2..6c1fa54b2f6 100644 --- a/iceoryx_posh/source/runtime/posh_runtime.cpp +++ b/iceoryx_posh/source/runtime/posh_runtime.cpp @@ -1,4 +1,5 @@ -// Copyright (c) 2019, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/test/mocks/subscriber_mock.hpp b/iceoryx_posh/test/mocks/subscriber_mock.hpp index 47e4b6c720d..08393b347ea 100644 --- a/iceoryx_posh/test/mocks/subscriber_mock.hpp +++ b/iceoryx_posh/test/mocks/subscriber_mock.hpp @@ -1,4 +1,5 @@ -// Copyright (c) 2020, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2020, 2021 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2020, 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/test/moduletests/test_popo_waitset.cpp b/iceoryx_posh/test/moduletests/test_popo_waitset.cpp index 538275a0065..625e3ec27f3 100644 --- a/iceoryx_posh/test/moduletests/test_popo_waitset.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_waitset.cpp @@ -1,4 +1,5 @@ -// Copyright (c) 2020, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2020, 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp index 8efa1387349..1ff1a05cb2a 100644 --- a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp +++ b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp @@ -1,4 +1,5 @@ -// Copyright (c) 2020, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2020, 2021 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2020, 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp index 0d7a0a4e8fa..acb3a7b6f5b 100644 --- a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp +++ b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp @@ -1,4 +1,5 @@ -// Copyright (c) 2019, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2019, 2021 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp index edd8a4064de..3f1839d3207 100644 --- a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp +++ b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp @@ -1,4 +1,5 @@ // Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp index 885c9c5fda8..d6808cdef4f 100644 --- a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp +++ b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp @@ -1,4 +1,5 @@ -// Copyright (c) 2019, 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2019, 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2020, 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. From e0b6c34559c5b5a897dca61cd0b3f1fc29997af1 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 9 Feb 2021 20:08:45 +0100 Subject: [PATCH 043/143] iox-#350 added and adjusted doxygen comments in Event* Signed-off-by: Christian Eltzschig --- .../popo/building_blocks/event_listener.hpp | 24 +++++++++++-------- .../popo/building_blocks/event_notifier.hpp | 10 ++++---- .../building_blocks/event_variable_data.hpp | 1 + 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp index 40ac09a14e8..13448d3e7de 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp @@ -21,31 +21,35 @@ namespace iox { namespace popo { -/// only one event listener per event variable +/// @brief An EventListener performs a blocking wait on a shared event variable. +/// When wait returns a list of all the EventNotifier id's which had +/// triggered the EventVariable is returned and the state is reseted. +/// +/// IMPORTANT! Do not use multiple EventListener at the same time for the +/// samen EventVariable class EventListener { public: /// @brief creates new EventListener /// - /// @param dataRef reference to EventVariableData + /// @param[in] dataRef reference to EventVariableData EventListener(EventVariableData& dataRef) noexcept; - /// @brief returns vector of indices of active notifications; blocking if EventVariableData was not notified unless - /// toBeDestroyed flag is true + /// @brief returns vector of indices of active notifications; blocking if EventVariableData was + /// not notified unless destroy() was called before. The indices of active notifications is + /// never empty unless destroy() was called, then its always empty. /// /// @return vector of active notifications cxx::vector wait() noexcept; - /// @brief sets toBeDestroyed flag to true + /// @brief Used in classes to signal a thread which waits in wait() to return + /// and stop working. Destroy will send an empty notification to wait() and + /// after this call wait() turns into a non blocking call which always + /// returns an empty vector. void destroy() noexcept; private: - /// @brief sets entry of EventVariableData's activeNotifications array to false - /// - /// @param index index corresponding to trigger id void reset(const uint64_t index) noexcept; - - /// @brief counts the semaphore down to zero void resetSemaphore() noexcept; std::atomic_bool m_toBeDestroyed{false}; diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp index 7318ee41add..8b8f3099a15 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp @@ -21,17 +21,19 @@ namespace iox { namespace popo { +/// @brief An EventNotifier notifies a corresponding EventListener via notify() which is +/// waiting on the same EventVariable. class EventNotifier { public: /// @brief creates new EventNotifier /// - /// @param dataRef reference to EventVariableData - /// @param index index corresponding to trigger id + /// @param[in] dataRef reference to EventVariableData + /// @param[in] index index which identifies EventNotifier uniquely. The user has to ensure the uniqueness and the + /// index has to be in the range of [0, iox::MAX_EVENTS_PER_ACTIVE_CALLSET] EventNotifier(EventVariableData& dataRef, const uint64_t index) noexcept; - /// @brief sets corresponding entry in EventVariableData array to true which means that the respective signaller has - /// triggered the event variable + /// @brief wakes up the corresponding EventListener which is waiting in wait() void notify() noexcept; private: diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp index a963267121d..cacf5a56fbf 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp @@ -21,6 +21,7 @@ namespace iox { namespace popo { +/// @brief Shared member variable structure used by EventListener and EventNotifier struct EventVariableData : public ConditionVariableData { /// @brief sets all entries of notification array to false From 11119168a96132b37238b2da15d754adada13a87 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 9 Feb 2021 20:34:29 +0100 Subject: [PATCH 044/143] iox-#350 fixed colcon double package issue and adjusted roudi process to new IPC API Signed-off-by: Christian Eltzschig --- iceoryx_examples/callbacks/CMakeLists.txt | 2 +- iceoryx_posh/source/roudi/roudi_process.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iceoryx_examples/callbacks/CMakeLists.txt b/iceoryx_examples/callbacks/CMakeLists.txt index 15c376a9fc5..b9f32f48556 100644 --- a/iceoryx_examples/callbacks/CMakeLists.txt +++ b/iceoryx_examples/callbacks/CMakeLists.txt @@ -13,7 +13,7 @@ # limitations under the License. cmake_minimum_required(VERSION 3.5) -project(example_waitset) +project(example_callbacks) include(GNUInstallDirs) diff --git a/iceoryx_posh/source/roudi/roudi_process.cpp b/iceoryx_posh/source/roudi/roudi_process.cpp index 8d2c549bd58..5ddb548f8d5 100644 --- a/iceoryx_posh/source/roudi/roudi_process.cpp +++ b/iceoryx_posh/source/roudi/roudi_process.cpp @@ -762,7 +762,7 @@ void ProcessManager::addEventVariableForProcess(const ProcessName_t& processName runtime::MqMessage sendBuffer; sendBuffer << runtime::mqMessageTypeToString(runtime::MqMessageType::CREATE_EVENT_VARIABLE_ACK) << std::to_string(offset) << std::to_string(m_mgmtSegmentId); - process->sendToMQ(sendBuffer); + process->sendViaIpcChannel(sendBuffer); LogDebug() << "Created new EventVariable for application " << processName; }) @@ -774,7 +774,7 @@ void ProcessManager::addEventVariableForProcess(const ProcessName_t& processName sendBuffer << runtime::mqMessageErrorTypeToString( runtime::MqMessageErrorType::EVENT_VARIABLE_LIST_FULL); } - process->sendToMQ(sendBuffer); + process->sendViaIpcChannel(sendBuffer); LogDebug() << "Could not create new EventVariable for application " << processName; }); From d5296b4577f5a1b97781dd75caf8744bd546f5aa Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 9 Feb 2021 20:49:54 +0100 Subject: [PATCH 045/143] iox-#350 fixed undefined behavior in test Signed-off-by: Christian Eltzschig --- iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index d22e8cab140..cd64fe9fc8b 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -401,14 +401,15 @@ TEST_F(ActiveCallSet_test, AttachingTillCapacityFilledSetsUpTriggerHandle) TEST_F(ActiveCallSet_test, DTorDetachesAllAttachedEvents) { - for (uint64_t i = 0U; i < m_sut->capacity(); ++i) + auto capacity = m_sut->capacity(); + for (uint64_t i = 0U; i < capacity; ++i) { m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>).has_error(); } m_sut.reset(); - for (uint64_t i = 0U; i < m_sut->capacity(); ++i) + for (uint64_t i = 0U; i < capacity; ++i) { EXPECT_FALSE(m_simpleEvents[i].m_handleHypnotoad.isValid()); } From 8fa9ffdba5ae31440699713713d38aaa9419d8ce Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Wed, 10 Feb 2021 09:41:02 +0100 Subject: [PATCH 046/143] iox-#350 fix review findings Signed-off-by: Marika Lehmann --- .../callbacks/ice_callbacks_subscriber.cpp | 9 ++++----- .../source/popo/building_blocks/event_notifier.cpp | 5 +++++ .../popo/building_blocks/event_variable_data.cpp | 4 ++-- .../test/moduletests/test_popo_event_variable.cpp | 2 +- .../test/moduletests/test_posh_runtime.cpp | 9 +++++++++ .../test/moduletests/test_roudi_portmanager.cpp | 14 +------------- 6 files changed, 22 insertions(+), 21 deletions(-) diff --git a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp index 027797e450b..affd5da87fa 100644 --- a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp +++ b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp @@ -52,17 +52,16 @@ int main() // attach shutdownTrigger to handle CTRL+C callSet.attachEvent(shutdownTrigger, shutdownTriggerCallback); - // create two subscribers, subscribe to the service and attach them to the waitset - iox::popo::TypedSubscriber subscriber1({"Radar", "FrontLeft", "Counter"}); + iox::popo::TypedSubscriber subscriber({"Radar", "FrontLeft", "Counter"}); - subscriber1.subscribe(); + subscriber.subscribe(); - callSet.attachEvent(subscriber1, iox::popo::SubscriberEvent::HAS_SAMPLES, subscriberCallback); + callSet.attachEvent(subscriber, iox::popo::SubscriberEvent::HAS_SAMPLES, subscriberCallback); std::this_thread::sleep_for(std::chrono::seconds(100000)); callSet.detachEvent(shutdownTrigger); - callSet.detachEvent(subscriber1, iox::popo::SubscriberEvent::HAS_SAMPLES); + callSet.detachEvent(subscriber, iox::popo::SubscriberEvent::HAS_SAMPLES); return (EXIT_SUCCESS); } diff --git a/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp b/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp index 46548071dc7..d48571f3cfd 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include "iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp" +#include "iceoryx_posh/internal/log/posh_logging.hpp" namespace iox { @@ -22,6 +23,10 @@ EventNotifier::EventNotifier(EventVariableData& dataRef, const uint64_t index) n : m_pointerToEventVariableData(&dataRef) , m_notificationIndex(index) { + if (index >= MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET) + { + LogWarn() << "The provided index " << index << " is too large."; + } } void EventNotifier::notify() noexcept diff --git a/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp b/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp index 19616cffd76..db214cee2bf 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp @@ -20,13 +20,13 @@ namespace popo { EventVariableData::EventVariableData() noexcept { - iox::cxx::forEach(m_activeNotifications, [](auto& id) { id.store(false, std::memory_order_relaxed); }); + cxx::forEach(m_activeNotifications, [](auto& id) { id.store(false, std::memory_order_relaxed); }); } EventVariableData::EventVariableData(const ProcessName_t& process) noexcept : ConditionVariableData(process) { - iox::cxx::forEach(m_activeNotifications, [](auto& id) { id.store(false, std::memory_order_relaxed); }); + cxx::forEach(m_activeNotifications, [](auto& id) { id.store(false, std::memory_order_relaxed); }); } } // namespace popo } // namespace iox diff --git a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp index 154c5787ef0..9f2b82d2ad3 100644 --- a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp @@ -55,7 +55,7 @@ TEST_F(EventVariable_test, AllNotificationsAreFalseAfterConstructionWithProcessN TEST_F(EventVariable_test, NotifyActivatesCorrectIndex) { - uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1; + uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; EventNotifier sut(m_eventVarData, index); sut.notify(); for (uint64_t i = 0U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; i++) diff --git a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp index 8efa1387349..b5f4ff4f60d 100644 --- a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp +++ b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp @@ -407,6 +407,15 @@ TEST_F(PoshRuntime_test, GetMiddlewareEventVariableIsSuccessful) EXPECT_THAT(eventVariable, Ne(nullptr)); } +TEST_F(PoshRuntime_test, GetMaxNumberOfMiddlewareEventVariables) +{ + for (uint32_t i = 0U; i < iox::MAX_NUMBER_OF_EVENT_VARIABLES; ++i) + { + auto eventVariable = m_runtime->getMiddlewareEventVariable(); + EXPECT_THAT(eventVariable, Ne(nullptr)); + } +} + TEST_F(PoshRuntime_test, GetMiddlewareEventVariableListOverflow) { auto eventVariableListOverflowDetected{false}; diff --git a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp index 0d7a0a4e8fa..a0e03904177 100644 --- a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp +++ b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp @@ -488,24 +488,12 @@ TEST_F(PortManager_test, DeletingEventVariableWorks) ASSERT_THAT(eventVariableDataResult.has_error(), Eq(false)); } - // test if overflow errors get hit - auto errorHandlerCalled{false}; - auto errorHandlerGuard = iox::ErrorHandler::SetTemporaryErrorHandler( - [&errorHandlerCalled](const iox::Error, const std::function, const iox::ErrorLevel) { - errorHandlerCalled = true; - }); - - auto eventVariableDataResult = m_portManager->acquireEventVariableData("AnotherItalianActor"); - ASSERT_THAT(eventVariableDataResult.has_error(), Eq(true)); - ASSERT_THAT(errorHandlerCalled, Eq(true)); - ASSERT_THAT(eventVariableDataResult.get_error(), Eq(PortPoolError::EVENT_VARIABLE_LIST_FULL)); - // delete one and add one eventVariableDataResult should be possible now unsigned int i = 0U; iox::ProcessName_t newProcessName(iox::cxx::TruncateToCapacity, process + std::to_string(i)); m_portManager->deletePortsOfProcess(newProcessName); - eventVariableDataResult = m_portManager->acquireEventVariableData(newProcessName); + auto eventVariableDataResult = m_portManager->acquireEventVariableData(newProcessName); EXPECT_THAT(eventVariableDataResult.has_error(), Eq(false)); } From 430e825d87ede94a39905b7f3fef7acbc528f1ae Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Wed, 10 Feb 2021 15:08:11 +0100 Subject: [PATCH 047/143] iox-#350 added license identifier Signed-off-by: Christian Eltzschig --- iceoryx_examples/callbacks/CMakeLists.txt | 2 ++ .../callbacks/ice_callbacks_publisher.cpp | 2 ++ .../callbacks/ice_callbacks_subscriber.cpp | 2 ++ iceoryx_examples/callbacks/topic_data.hpp | 2 ++ iceoryx_meta/CMakeLists.txt | 2 ++ iceoryx_posh/CMakeLists.txt | 2 ++ .../include/iceoryx_posh/iceoryx_posh_types.hpp | 3 +++ .../internal/popo/active_call_set.inl | 2 ++ .../internal/popo/base_subscriber.inl | 2 ++ .../popo/building_blocks/chunk_queue_data.hpp | 3 +++ .../popo/building_blocks/chunk_queue_popper.hpp | 3 +++ .../popo/building_blocks/chunk_queue_popper.inl | 3 +++ .../popo/building_blocks/chunk_queue_pusher.hpp | 3 +++ .../popo/building_blocks/chunk_queue_pusher.inl | 3 +++ .../building_blocks/condition_variable_data.hpp | 3 +++ .../popo/building_blocks/event_listener.hpp | 3 +++ .../popo/building_blocks/event_notifier.hpp | 3 +++ .../building_blocks/event_variable_data.hpp | 3 +++ .../popo/ports/subscriber_port_user.hpp | 3 +++ .../iceoryx_posh/internal/popo/wait_set.inl | 3 +++ .../internal/roudi/port_manager.hpp | 3 +++ .../internal/roudi/port_pool_data.hpp | 3 +++ .../internal/roudi/roudi_process.hpp | 3 +++ .../runtime/message_queue_interface.hpp | 3 +++ .../iceoryx_posh/popo/active_call_set.hpp | 2 ++ .../iceoryx_posh/popo/event_attorney.hpp | 3 +++ .../include/iceoryx_posh/popo/trigger.hpp | 3 +++ .../iceoryx_posh/popo/trigger_handle.hpp | 3 +++ .../include/iceoryx_posh/roudi/port_pool.hpp | 3 +++ .../iceoryx_posh/runtime/posh_runtime.hpp | 3 +++ iceoryx_posh/source/popo/active_call_set.cpp | 2 ++ .../popo/building_blocks/event_listener.cpp | 3 +++ .../popo/building_blocks/event_notifier.cpp | 3 +++ .../building_blocks/event_variable_data.cpp | 3 +++ .../source/popo/ports/subscriber_port_user.cpp | 3 +++ iceoryx_posh/source/popo/trigger.cpp | 3 +++ iceoryx_posh/source/popo/trigger_handle.cpp | 3 +++ iceoryx_posh/source/roudi/port_manager.cpp | 3 +++ iceoryx_posh/source/roudi/port_pool.cpp | 3 +++ iceoryx_posh/source/roudi/roudi.cpp | 17 ++++++++++------- iceoryx_posh/source/roudi/roudi_process.cpp | 3 +++ iceoryx_posh/source/runtime/posh_runtime.cpp | 3 +++ iceoryx_posh/test/mocks/subscriber_mock.hpp | 3 +++ .../moduletests/test_popo_active_call_set.cpp | 3 +++ .../moduletests/test_popo_event_variable.cpp | 3 +++ .../test/moduletests/test_popo_trigger.cpp | 3 +++ .../moduletests/test_popo_trigger_handle.cpp | 3 +++ .../test/moduletests/test_popo_waitset.cpp | 3 +++ .../test/moduletests/test_posh_runtime.cpp | 3 +++ .../test/moduletests/test_roudi_portmanager.cpp | 3 +++ .../include/iceoryx_utils/cxx/helplets.hpp | 3 +++ .../error_handling/error_handling.hpp | 3 +++ 52 files changed, 153 insertions(+), 7 deletions(-) diff --git a/iceoryx_examples/callbacks/CMakeLists.txt b/iceoryx_examples/callbacks/CMakeLists.txt index b9f32f48556..e76847e26e5 100644 --- a/iceoryx_examples/callbacks/CMakeLists.txt +++ b/iceoryx_examples/callbacks/CMakeLists.txt @@ -11,6 +11,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 cmake_minimum_required(VERSION 3.5) project(example_callbacks) diff --git a/iceoryx_examples/callbacks/ice_callbacks_publisher.cpp b/iceoryx_examples/callbacks/ice_callbacks_publisher.cpp index 2b89cfea4e8..e75aaf2d436 100644 --- a/iceoryx_examples/callbacks/ice_callbacks_publisher.cpp +++ b/iceoryx_examples/callbacks/ice_callbacks_publisher.cpp @@ -11,6 +11,8 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 #include "iceoryx_posh/popo/publisher.hpp" #include "iceoryx_posh/runtime/posh_runtime.hpp" diff --git a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp index 287d52a6123..ef2ccc24233 100644 --- a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp +++ b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp @@ -11,6 +11,8 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 #include "iceoryx_posh/popo/active_call_set.hpp" #include "iceoryx_posh/popo/typed_subscriber.hpp" diff --git a/iceoryx_examples/callbacks/topic_data.hpp b/iceoryx_examples/callbacks/topic_data.hpp index 4d4e2c11add..63a122f0212 100644 --- a/iceoryx_examples/callbacks/topic_data.hpp +++ b/iceoryx_examples/callbacks/topic_data.hpp @@ -11,6 +11,8 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 #ifndef IOX_EXAMPLES_WAITSET_TOPIC_DATA_HPP #define IOX_EXAMPLES_WAITSET_TOPIC_DATA_HPP diff --git a/iceoryx_meta/CMakeLists.txt b/iceoryx_meta/CMakeLists.txt index 1196f968c9a..db005449c57 100644 --- a/iceoryx_meta/CMakeLists.txt +++ b/iceoryx_meta/CMakeLists.txt @@ -12,6 +12,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 cmake_minimum_required(VERSION 3.5) file (STRINGS "../VERSION" iceoryx_VERSION) diff --git a/iceoryx_posh/CMakeLists.txt b/iceoryx_posh/CMakeLists.txt index 3f8b89b23d3..65a31858578 100644 --- a/iceoryx_posh/CMakeLists.txt +++ b/iceoryx_posh/CMakeLists.txt @@ -12,6 +12,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 cmake_minimum_required(VERSION 3.5) file (STRINGS "../VERSION" iceoryx_posh_VERSION) diff --git a/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp b/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp index e43b0efd9f5..89da0bcf746 100644 --- a/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp +++ b/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_ICEORYX_POSH_TYPES_HPP #define IOX_POSH_ICEORYX_POSH_TYPES_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl index 35580384b43..92471d6a371 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl @@ -11,6 +11,8 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 #ifndef IOX_POSH_POPO_ACTIVE_CALL_SET_INL #define IOX_POSH_POPO_ACTIVE_CALL_SET_INL diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/base_subscriber.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/base_subscriber.inl index fb3086c6c76..0318665729e 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/base_subscriber.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/base_subscriber.inl @@ -12,6 +12,8 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 #ifndef IOX_POSH_POPO_BASE_SUBSCRIBER_INL #define IOX_POSH_POPO_BASE_SUBSCRIBER_INL diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_data.hpp index fd7456c871b..f2ef69978b2 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_data.hpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_POPO_BUILDING_BLOCKS_CHUNK_QUEUE_DATA_HPP #define IOX_POSH_POPO_BUILDING_BLOCKS_CHUNK_QUEUE_DATA_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp index 2436ec92828..ed4a8c26464 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_POPO_BUILDING_BLOCKS_CHUNK_QUEUE_POPPER_HPP #define IOX_POSH_POPO_BUILDING_BLOCKS_CHUNK_QUEUE_POPPER_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.inl index 0aa4f0e9e76..d77de94775c 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.inl @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_POPO_BUILDING_BLOCKS_CHUNK_QUEUE_POPPER_INL #define IOX_POSH_POPO_BUILDING_BLOCKS_CHUNK_QUEUE_POPPER_INL diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp index dae762cabf3..27a04f5c175 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_POPO_BUILDING_BLOCKS_CHUNK_QUEUE_PUSHER_HPP #define IOX_POSH_POPO_BUILDING_BLOCKS_CHUNK_QUEUE_PUSHER_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.inl index ffc8363e507..40145d92aa8 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.inl @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_POPO_BUILDING_BLOCKS_CHUNK_QUEUE_PUSHER_INL #define IOX_POSH_POPO_BUILDING_BLOCKS_CHUNK_QUEUE_PUSHER_INL diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp index 93af2c10ddb..9cc42a9c660 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_POPO_BUILDING_BLOCKS_CONDITION_VARIABLE_DATA_HPP #define IOX_POSH_POPO_BUILDING_BLOCKS_CONDITION_VARIABLE_DATA_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp index 13448d3e7de..86026a57e45 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp @@ -11,6 +11,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_LISTENER_HPP #define IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_LISTENER_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp index 8b8f3099a15..22b970ff298 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp @@ -11,6 +11,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_NOTIFIER_HPP #define IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_NOTIFIER_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp index cacf5a56fbf..0310c7741b5 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp @@ -11,6 +11,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_VARIABLE_DATA_HPP #define IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_VARIABLE_DATA_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp index 03ec3911031..1a5930c2326 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POPO_SUBSCRIBER_PORT_USER_HPP_ #define IOX_POPO_SUBSCRIBER_PORT_USER_HPP_ diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/wait_set.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/wait_set.inl index 1034cb659ce..30b4903f9d6 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/wait_set.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/wait_set.inl @@ -11,6 +11,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_POPO_WAIT_SET_INL #define IOX_POSH_POPO_WAIT_SET_INL diff --git a/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp b/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp index 26f887106d2..c58cf268978 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_ROUDI_PORT_MANAGER_HPP #define IOX_POSH_ROUDI_PORT_MANAGER_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_pool_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_pool_data.hpp index 8c5e57c3c60..579f59000c8 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_pool_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_pool_data.hpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_ROUDI_PORT_POOL_DATA_HPP #define IOX_POSH_ROUDI_PORT_POOL_DATA_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/internal/roudi/roudi_process.hpp b/iceoryx_posh/include/iceoryx_posh/internal/roudi/roudi_process.hpp index 91c5a4ced4a..9dd5ab7e773 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/roudi/roudi_process.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/roudi/roudi_process.hpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_ROUDI_ROUDI_PROCESS_HPP #define IOX_POSH_ROUDI_ROUDI_PROCESS_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/internal/runtime/message_queue_interface.hpp b/iceoryx_posh/include/iceoryx_posh/internal/runtime/message_queue_interface.hpp index 1c934855e5b..be1cd2de140 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/runtime/message_queue_interface.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/runtime/message_queue_interface.hpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_RUNTIME_MESSAGE_QUEUE_INTERFACE_HPP #define IOX_POSH_RUNTIME_MESSAGE_QUEUE_INTERFACE_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp index 0e4b9ddf98b..0b0ab9dd687 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -11,6 +11,8 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 #ifndef IOX_POSH_POPO_ACTIVE_CALL_SET_HPP #define IOX_POSH_POPO_ACTIVE_CALL_SET_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/popo/event_attorney.hpp b/iceoryx_posh/include/iceoryx_posh/popo/event_attorney.hpp index 38f70531abe..706531fbd2e 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/event_attorney.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/event_attorney.hpp @@ -11,6 +11,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_POPO_EVENT_ATTORNEY_HPP #define IOX_POSH_POPO_EVENT_ATTORNEY_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/popo/trigger.hpp b/iceoryx_posh/include/iceoryx_posh/popo/trigger.hpp index e3314827917..e03980cf6b1 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/trigger.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/trigger.hpp @@ -11,6 +11,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_POPO_TRIGGER_HPP #define IOX_POSH_POPO_TRIGGER_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp b/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp index 63fc195eb1c..3db340046dc 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp @@ -11,6 +11,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_POPO_TRIGGER_HANDLE_HPP #define IOX_POSH_POPO_TRIGGER_HANDLE_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/roudi/port_pool.hpp b/iceoryx_posh/include/iceoryx_posh/roudi/port_pool.hpp index 40a835183a3..98d3549e146 100644 --- a/iceoryx_posh/include/iceoryx_posh/roudi/port_pool.hpp +++ b/iceoryx_posh/include/iceoryx_posh/roudi/port_pool.hpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_ROUDI_PORT_POOL_HPP #define IOX_POSH_ROUDI_PORT_POOL_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp b/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp index 407df6956f5..8b0476ef5b3 100644 --- a/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp +++ b/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_POSH_RUNTIME_POSH_RUNTIME_HPP #define IOX_POSH_RUNTIME_POSH_RUNTIME_HPP diff --git a/iceoryx_posh/source/popo/active_call_set.cpp b/iceoryx_posh/source/popo/active_call_set.cpp index 709b83dfb43..e3d0c976e77 100644 --- a/iceoryx_posh/source/popo/active_call_set.cpp +++ b/iceoryx_posh/source/popo/active_call_set.cpp @@ -11,6 +11,8 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 #include "iceoryx_posh/popo/active_call_set.hpp" #include "iceoryx_posh/internal/popo/building_blocks/event_listener.hpp" diff --git a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp index 4bc82e66039..5a238cbbd75 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp @@ -11,6 +11,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #include "iceoryx_posh/internal/popo/building_blocks/event_listener.hpp" diff --git a/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp b/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp index d48571f3cfd..89373093147 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp @@ -11,6 +11,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #include "iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp" #include "iceoryx_posh/internal/log/posh_logging.hpp" diff --git a/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp b/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp index db214cee2bf..5ca9c42f0c9 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp @@ -11,6 +11,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" diff --git a/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp b/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp index 7fc3b67e2a3..48105377981 100644 --- a/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp +++ b/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #include "iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp" #include "iceoryx_posh/internal/log/posh_logging.hpp" diff --git a/iceoryx_posh/source/popo/trigger.cpp b/iceoryx_posh/source/popo/trigger.cpp index 9cf3349efd8..3f8f0ddb005 100644 --- a/iceoryx_posh/source/popo/trigger.cpp +++ b/iceoryx_posh/source/popo/trigger.cpp @@ -11,6 +11,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #include "iceoryx_posh/popo/trigger.hpp" #include "iceoryx_posh/internal/popo/building_blocks/condition_variable_signaler.hpp" diff --git a/iceoryx_posh/source/popo/trigger_handle.cpp b/iceoryx_posh/source/popo/trigger_handle.cpp index 017eb8a3b7c..edc46bc6909 100644 --- a/iceoryx_posh/source/popo/trigger_handle.cpp +++ b/iceoryx_posh/source/popo/trigger_handle.cpp @@ -11,6 +11,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #include "iceoryx_posh/popo/trigger_handle.hpp" #include "iceoryx_posh/internal/popo/building_blocks/condition_variable_signaler.hpp" diff --git a/iceoryx_posh/source/roudi/port_manager.cpp b/iceoryx_posh/source/roudi/port_manager.cpp index 52e4b93a203..b5c2ff8beaf 100644 --- a/iceoryx_posh/source/roudi/port_manager.cpp +++ b/iceoryx_posh/source/roudi/port_manager.cpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #include "iceoryx_posh/internal/roudi/port_manager.hpp" #include "iceoryx_posh/iceoryx_posh_types.hpp" diff --git a/iceoryx_posh/source/roudi/port_pool.cpp b/iceoryx_posh/source/roudi/port_pool.cpp index f6ea55bf299..5e4db698177 100644 --- a/iceoryx_posh/source/roudi/port_pool.cpp +++ b/iceoryx_posh/source/roudi/port_pool.cpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #include "iceoryx_posh/roudi/port_pool.hpp" #include "iceoryx_posh/internal/roudi/port_pool_data.hpp" diff --git a/iceoryx_posh/source/roudi/roudi.cpp b/iceoryx_posh/source/roudi/roudi.cpp index 7018ebd8284..7cb68c48df0 100644 --- a/iceoryx_posh/source/roudi/roudi.cpp +++ b/iceoryx_posh/source/roudi/roudi.cpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #include "iceoryx_posh/internal/roudi/roudi.hpp" #include "iceoryx_posh/internal/log/posh_logging.hpp" @@ -36,16 +39,16 @@ RouDi::RouDi(RouDiMemoryInterface& roudiMemoryInterface, , m_roudiMemoryInterface(&roudiMemoryInterface) , m_portManager(&portManager) , m_prcMgr(*m_roudiMemoryInterface, portManager, roudiStartupParameters.m_compatibilityCheckLevel) - , m_mempoolIntrospection( - *m_roudiMemoryInterface->introspectionMemoryManager() - .value(), /// @todo create a RouDiMemoryManagerData struct with all the pointer - *m_roudiMemoryInterface->segmentManager().value(), - PublisherPortUserType(m_prcMgr.addIntrospectionPublisherPort(IntrospectionMempoolService, IPC_CHANNEL_ROUDI_NAME))) + , m_mempoolIntrospection(*m_roudiMemoryInterface->introspectionMemoryManager() + .value(), /// @todo create a RouDiMemoryManagerData struct with all the pointer + *m_roudiMemoryInterface->segmentManager().value(), + PublisherPortUserType(m_prcMgr.addIntrospectionPublisherPort(IntrospectionMempoolService, + IPC_CHANNEL_ROUDI_NAME))) , m_monitoringMode(roudiStartupParameters.m_monitoringMode) , m_processKillDelay(roudiStartupParameters.m_processKillDelay) { - m_processIntrospection.registerPublisherPort( - PublisherPortUserType(m_prcMgr.addIntrospectionPublisherPort(IntrospectionProcessService, IPC_CHANNEL_ROUDI_NAME))); + m_processIntrospection.registerPublisherPort(PublisherPortUserType( + m_prcMgr.addIntrospectionPublisherPort(IntrospectionProcessService, IPC_CHANNEL_ROUDI_NAME))); m_prcMgr.initIntrospection(&m_processIntrospection); m_processIntrospection.run(); m_mempoolIntrospection.run(); diff --git a/iceoryx_posh/source/roudi/roudi_process.cpp b/iceoryx_posh/source/roudi/roudi_process.cpp index 5ddb548f8d5..aae8728af6b 100644 --- a/iceoryx_posh/source/roudi/roudi_process.cpp +++ b/iceoryx_posh/source/roudi/roudi_process.cpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #include "iceoryx_posh/internal/roudi/roudi_process.hpp" #include "iceoryx_posh/iceoryx_posh_types.hpp" diff --git a/iceoryx_posh/source/runtime/posh_runtime.cpp b/iceoryx_posh/source/runtime/posh_runtime.cpp index 207f958cca7..3caee178b45 100644 --- a/iceoryx_posh/source/runtime/posh_runtime.cpp +++ b/iceoryx_posh/source/runtime/posh_runtime.cpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #include "iceoryx_posh/runtime/posh_runtime.hpp" diff --git a/iceoryx_posh/test/mocks/subscriber_mock.hpp b/iceoryx_posh/test/mocks/subscriber_mock.hpp index 08393b347ea..3c08afe4d7a 100644 --- a/iceoryx_posh/test/mocks/subscriber_mock.hpp +++ b/iceoryx_posh/test/mocks/subscriber_mock.hpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #include "iceoryx_posh/capro/service_description.hpp" #include "iceoryx_posh/mepoo/chunk_header.hpp" diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index cd64fe9fc8b..27ecf4a772d 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -11,6 +11,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #include "iceoryx_posh/iceoryx_posh_types.hpp" #include "iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp" diff --git a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp index 9f2b82d2ad3..b82dc80a4a1 100644 --- a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp @@ -11,6 +11,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #include "iceoryx_posh/internal/popo/building_blocks/event_listener.hpp" #include "iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp" diff --git a/iceoryx_posh/test/moduletests/test_popo_trigger.cpp b/iceoryx_posh/test/moduletests/test_popo_trigger.cpp index 29f84398b3c..845b7a9c9c6 100644 --- a/iceoryx_posh/test/moduletests/test_popo_trigger.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_trigger.cpp @@ -11,6 +11,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #include "iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp" #include "iceoryx_posh/internal/popo/building_blocks/condition_variable_waiter.hpp" diff --git a/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp b/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp index bdd1d95532d..5c1041a2b65 100644 --- a/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp @@ -11,6 +11,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #include "iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp" #include "iceoryx_posh/internal/popo/building_blocks/condition_variable_waiter.hpp" diff --git a/iceoryx_posh/test/moduletests/test_popo_waitset.cpp b/iceoryx_posh/test/moduletests/test_popo_waitset.cpp index 625e3ec27f3..18bacc39b59 100644 --- a/iceoryx_posh/test/moduletests/test_popo_waitset.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_waitset.cpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #include "iceoryx_posh/iceoryx_posh_types.hpp" #include "iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp" diff --git a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp index 6394099aec3..ccf4d00e00d 100644 --- a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp +++ b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #include "iceoryx_posh/internal/roudi_environment/roudi_environment.hpp" #include "iceoryx_posh/runtime/posh_runtime.hpp" #include "test.hpp" diff --git a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp index 7e8de95db1f..c1cfb8bebcd 100644 --- a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp +++ b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #include "test.hpp" diff --git a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp index 3f1839d3207..25ab080176b 100644 --- a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp +++ b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_UTILS_CXX_HELPLETS_HPP #define IOX_UTILS_CXX_HELPLETS_HPP diff --git a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp index fb54fedccfd..2a4234cbf63 100644 --- a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp +++ b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp @@ -12,6 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + #ifndef IOX_UTILS_ERROR_HANDLING_ERROR_HANDLING_HPP #define IOX_UTILS_ERROR_HANDLING_ERROR_HANDLING_HPP From 5a00f5356e535e43cbe2bff4f880ff5d4195a686 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Wed, 10 Feb 2021 15:26:11 +0100 Subject: [PATCH 048/143] iox-#350 added doxygen comments for active call set Signed-off-by: Christian Eltzschig --- .../iceoryx_posh/popo/active_call_set.hpp | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp index 0b0ab9dd687..5c4d54a4719 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -40,6 +40,9 @@ enum class ActiveCallSetError EVENT_ALREADY_ATTACHED, }; +/// @brief The ActiveCallSet is a class which reacts to registered events by +/// executing a corresponding callback concurrently. This is achieved via +/// an encapsulated thread inside this class. class ActiveCallSet { public: @@ -59,21 +62,51 @@ class ActiveCallSet ActiveCallSet& operator=(const ActiveCallSet&) = delete; ActiveCallSet& operator=(ActiveCallSet&&) = delete; + /// @brief Attaches an event. Hereby the event is defined as a class T, the eventOrigin and + /// the corresponding callback which will be called when the event occurs. + /// @note This method can be called from any thread concurrently without any restrictions! + /// @tparam[in] T type of the class which will signal the event + /// @param[in] eventOrigin the object which will signal the event (the origin) + /// @param[in] eventCallback callback which will be executed concurrently when the event occurs + /// @return If an error occurs the enum which describes the error. template cxx::expected attachEvent(T& eventOrigin, CallbackRef_t eventCallback) noexcept; + /// @brief Attaches an event. Hereby the event is defined as a class T, the eventOrigin, an enum which further + /// defines the event inside the class and the corresponding callback which will be called when the event + /// occurs. + /// @note This method can be called from any thread concurrently without any restrictions! + /// @tparam[in] T type of the class which will signal the event + /// @param[in] eventOrigin the object which will signal the event (the origin) + /// @param[in] eventType enum required to specify the type of event inside of eventOrigin + /// @param[in] eventCallback callback which will be executed concurrently when the event occurs + /// @return If an error occurs the enum which describes the error. template ::value>> cxx::expected attachEvent(T& eventOrigin, const EventType eventType, CallbackRef_t eventCallback) noexcept; + /// @brief Detaches an event. Hereby, the event is defined as a class T, the eventOrigin and + /// the eventType with further specifies the event inside of eventOrigin + /// @note This method can be called from any thread concurrently without any restrictions! + /// @tparam[in] T type of the class which will signal the event + /// @param[in] eventOrigin the object which will signal the event (the origin) + /// @param[in] eventType enum required to specify the type of event inside of eventOrigin template ::value>> void detachEvent(T& eventOrigin, const EventType eventType) noexcept; + /// @brief Detaches an event. Hereby, the event is defined as a class T, the eventOrigin. + /// @note This method can be called from any thread concurrently without any restrictions! + /// @tparam[in] T type of the class which will signal the event + /// @param[in] eventType enum required to specify the type of event inside of eventOrigin template void detachEvent(T& eventOrigin) noexcept; + /// @brief Returns the capacity of the ActiveCallSet + /// @return capacity of the ActiveCallSet static constexpr uint64_t capacity() noexcept; + /// @brief Returns the size of the ActiveCallSet + /// @return size of the ActiveCallSet uint64_t size() const noexcept; protected: From c5495918a08e91cabec4d87a638af53feeca1c21 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Wed, 10 Feb 2021 15:45:36 +0100 Subject: [PATCH 049/143] iox-#350 added Us and timing adjustments to active call set test Signed-off-by: Christian Eltzschig --- .../moduletests/test_popo_active_call_set.cpp | 360 +++++++++--------- 1 file changed, 180 insertions(+), 180 deletions(-) diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index 27ecf4a772d..942c581ae16 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -77,7 +77,7 @@ class ActiveCallSet_test : public Test m_handleHypnotoad = std::move(handle); } - void invalidateTrigger(const uint64_t id) + void invalidateTrigger(const uint64_t id) noexcept { m_invalidateTriggerId = id; if (m_handleHypnotoad.getUniqueId() == id) @@ -90,7 +90,7 @@ class ActiveCallSet_test : public Test } } - void disableEvent(const SimpleEvent event) + void disableEvent(const SimpleEvent event) noexcept { if (event == SimpleEvent::StoepselBachelorParty) { @@ -102,18 +102,18 @@ class ActiveCallSet_test : public Test } } - void disableEvent() + void disableEvent() noexcept { m_handleHypnotoad.reset(); } - void triggerStoepsel() + void triggerStoepsel() noexcept { m_hasTriggered.store(true); m_handleStoepsel.trigger(); } - void resetTrigger() + void resetTrigger() noexcept { m_hasTriggered.store(false); } @@ -137,21 +137,21 @@ class ActiveCallSet_test : public Test iox::cxx::optional m_sut; template - static void triggerCallback(ActiveCallSet_test::SimpleEventClass* const event) + static void triggerCallback(ActiveCallSet_test::SimpleEventClass* const event) noexcept { ActiveCallSet_test::m_triggerCallbackArg[N] = event; std::this_thread::sleep_for(std::chrono::milliseconds(m_triggerCallbackRuntimeInMs)); } - static void attachCallback(ActiveCallSet_test::SimpleEventClass* const) + static void attachCallback(ActiveCallSet_test::SimpleEventClass* const) noexcept { for (auto& e : m_toBeAttached) { - e.sut->attachEvent(*e.object, SimpleEvent::StoepselBachelorParty, triggerCallback<0>); + e.sut->attachEvent(*e.object, SimpleEvent::StoepselBachelorParty, triggerCallback<0U>); } } - static void detachCallback(ActiveCallSet_test::SimpleEventClass* const) + static void detachCallback(ActiveCallSet_test::SimpleEventClass* const) noexcept { for (auto& e : m_toBeDetached) { @@ -159,7 +159,7 @@ class ActiveCallSet_test : public Test } } - static void notifyAndThenDetachCallback(ActiveCallSet_test::SimpleEventClass* const) + static void notifyAndThenDetachCallback(ActiveCallSet_test::SimpleEventClass* const) noexcept { for (auto& e : m_toBeDetached) { @@ -190,8 +190,8 @@ class ActiveCallSet_test : public Test ActiveCallSetMock* sut; }; - using eventVector_t = iox::cxx::vector; - eventVector_t m_simpleEvents{iox::MAX_NUMBER_OF_EVENTS_PER_WAITSET + 1}; + using eventVector_t = iox::cxx::vector; + eventVector_t m_simpleEvents{iox::MAX_NUMBER_OF_EVENTS_PER_WAITSET + 1U}; static std::vector m_toBeAttached; static std::vector m_toBeDetached; @@ -217,7 +217,7 @@ TEST_F(ActiveCallSet_test, IsEmptyWhenConstructed) TEST_F(ActiveCallSet_test, AttachingWithoutEnumIfEnoughSpaceAvailableWorks) { - EXPECT_FALSE(m_sut->attachEvent(m_simpleEvents[0], ActiveCallSet_test::triggerCallback<0>).has_error()); + EXPECT_FALSE(m_sut->attachEvent(m_simpleEvents[0U], ActiveCallSet_test::triggerCallback<0U>).has_error()); EXPECT_THAT(m_sut->size(), Eq(1U)); } @@ -225,7 +225,7 @@ TEST_F(ActiveCallSet_test, AttachWithoutEnumTillCapacityIsFullWorks) { for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { - EXPECT_FALSE(m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>).has_error()); + EXPECT_FALSE(m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>).has_error()); } EXPECT_THAT(m_sut->size(), Eq(m_sut->capacity())); } @@ -234,19 +234,19 @@ TEST_F(ActiveCallSet_test, DetachDecreasesSize) { for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { - m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>); + m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>); } - m_sut->detachEvent(m_simpleEvents[0]); - EXPECT_THAT(m_sut->size(), Eq(m_sut->capacity() - 1)); + m_sut->detachEvent(m_simpleEvents[0U]); + EXPECT_THAT(m_sut->size(), Eq(m_sut->capacity() - 1U)); } TEST_F(ActiveCallSet_test, AttachWithoutEnumOneMoreThanCapacityFails) { for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { - m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>).has_error(); + m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>).has_error(); } - auto result = m_sut->attachEvent(m_simpleEvents[m_sut->capacity()], ActiveCallSet_test::triggerCallback<0>); + auto result = m_sut->attachEvent(m_simpleEvents[m_sut->capacity()], ActiveCallSet_test::triggerCallback<0U>); ASSERT_TRUE(result.has_error()); EXPECT_THAT(result.get_error(), Eq(ActiveCallSetError::ACTIVE_CALL_SET_FULL)); @@ -255,9 +255,9 @@ TEST_F(ActiveCallSet_test, AttachWithoutEnumOneMoreThanCapacityFails) TEST_F(ActiveCallSet_test, AttachingWithEnumIfEnoughSpaceAvailableWorks) { EXPECT_FALSE(m_sut - ->attachEvent(m_simpleEvents[0], + ->attachEvent(m_simpleEvents[0U], ActiveCallSet_test::SimpleEvent::Hypnotoad, - ActiveCallSet_test::triggerCallback<0>) + ActiveCallSet_test::triggerCallback<0U>) .has_error()); } @@ -268,7 +268,7 @@ TEST_F(ActiveCallSet_test, AttachWithEnumTillCapacityIsFullWorks) EXPECT_FALSE(m_sut ->attachEvent(m_simpleEvents[i], ActiveCallSet_test::SimpleEvent::Hypnotoad, - ActiveCallSet_test::triggerCallback<0>) + ActiveCallSet_test::triggerCallback<0U>) .has_error()); } } @@ -279,12 +279,12 @@ TEST_F(ActiveCallSet_test, AttachWithEnumOneMoreThanCapacityFails) { m_sut ->attachEvent( - m_simpleEvents[i], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0>) + m_simpleEvents[i], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>) .has_error(); } auto result = m_sut->attachEvent(m_simpleEvents[m_sut->capacity()], ActiveCallSet_test::SimpleEvent::Hypnotoad, - ActiveCallSet_test::triggerCallback<0>); + ActiveCallSet_test::triggerCallback<0U>); ASSERT_TRUE(result.has_error()); EXPECT_THAT(result.get_error(), Eq(ActiveCallSetError::ACTIVE_CALL_SET_FULL)); @@ -296,15 +296,15 @@ TEST_F(ActiveCallSet_test, DetachMakesSpaceForAnotherAttachWithEventEnum) { m_sut ->attachEvent( - m_simpleEvents[i], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0>) + m_simpleEvents[i], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>) .has_error(); } - m_sut->detachEvent(m_simpleEvents[0], ActiveCallSet_test::SimpleEvent::Hypnotoad); + m_sut->detachEvent(m_simpleEvents[0U], ActiveCallSet_test::SimpleEvent::Hypnotoad); EXPECT_FALSE(m_sut ->attachEvent(m_simpleEvents[m_sut->capacity()], ActiveCallSet_test::SimpleEvent::Hypnotoad, - ActiveCallSet_test::triggerCallback<0>) + ActiveCallSet_test::triggerCallback<0U>) .has_error()); } @@ -312,49 +312,49 @@ TEST_F(ActiveCallSet_test, DetachMakesSpaceForAnotherAttachWithoutEventEnum) { for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { - m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>).has_error(); + m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>).has_error(); } - m_sut->detachEvent(m_simpleEvents[0]); + m_sut->detachEvent(m_simpleEvents[0U]); EXPECT_FALSE(m_sut ->attachEvent(m_simpleEvents[m_sut->capacity()], ActiveCallSet_test::SimpleEvent::Hypnotoad, - ActiveCallSet_test::triggerCallback<0>) + ActiveCallSet_test::triggerCallback<0U>) .has_error()); } TEST_F(ActiveCallSet_test, AttachingEventWithoutEventTypeLeadsToAttachedTriggerHandle) { - m_sut->attachEvent(m_simpleEvents[0], ActiveCallSet_test::triggerCallback<0>); - EXPECT_TRUE(m_simpleEvents[0].m_handleHypnotoad.isValid()); + m_sut->attachEvent(m_simpleEvents[0U], ActiveCallSet_test::triggerCallback<0U>); + EXPECT_TRUE(m_simpleEvents[0U].m_handleHypnotoad.isValid()); } TEST_F(ActiveCallSet_test, AttachingEventWithEventTypeLeadsToAttachedTriggerHandle) { - m_sut->attachEvent(m_simpleEvents[0], + m_sut->attachEvent(m_simpleEvents[0U], ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, - ActiveCallSet_test::triggerCallback<0>); - EXPECT_TRUE(m_simpleEvents[0].m_handleStoepsel.isValid()); + ActiveCallSet_test::triggerCallback<0U>); + EXPECT_TRUE(m_simpleEvents[0U].m_handleStoepsel.isValid()); } TEST_F(ActiveCallSet_test, AttachingSameEventWithEventEnumTwiceFails) { - m_sut->attachEvent(m_simpleEvents[0], + m_sut->attachEvent(m_simpleEvents[0U], ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, - ActiveCallSet_test::triggerCallback<0>); + ActiveCallSet_test::triggerCallback<0U>); - auto result = m_sut->attachEvent(m_simpleEvents[0], + auto result = m_sut->attachEvent(m_simpleEvents[0U], ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, - ActiveCallSet_test::triggerCallback<0>); + ActiveCallSet_test::triggerCallback<0U>); ASSERT_TRUE(result.has_error()); EXPECT_THAT(result.get_error(), Eq(ActiveCallSetError::EVENT_ALREADY_ATTACHED)); } TEST_F(ActiveCallSet_test, AttachingSameEventWithoutEventEnumTwiceFails) { - m_sut->attachEvent(m_simpleEvents[0], ActiveCallSet_test::triggerCallback<0>); + m_sut->attachEvent(m_simpleEvents[0U], ActiveCallSet_test::triggerCallback<0U>); - auto result = m_sut->attachEvent(m_simpleEvents[0], ActiveCallSet_test::triggerCallback<0>); + auto result = m_sut->attachEvent(m_simpleEvents[0U], ActiveCallSet_test::triggerCallback<0U>); ASSERT_TRUE(result.has_error()); EXPECT_THAT(result.get_error(), Eq(ActiveCallSetError::EVENT_ALREADY_ATTACHED)); } @@ -362,30 +362,30 @@ TEST_F(ActiveCallSet_test, AttachingSameEventWithoutEventEnumTwiceFails) TEST_F(ActiveCallSet_test, AttachingSameClassWithTwoDifferentEventsWorks) { m_sut->attachEvent( - m_simpleEvents[0], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0>); + m_simpleEvents[0U], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); EXPECT_FALSE(m_sut - ->attachEvent(m_simpleEvents[0], + ->attachEvent(m_simpleEvents[0U], ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, - ActiveCallSet_test::triggerCallback<0>) + ActiveCallSet_test::triggerCallback<0U>) .has_error()); } TEST_F(ActiveCallSet_test, DetachingSameClassWithDifferentEventEnumChangesNothing) { m_sut->attachEvent( - m_simpleEvents[0], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0>); + m_simpleEvents[0U], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); - m_sut->detachEvent(m_simpleEvents[0], ActiveCallSet_test::SimpleEvent::StoepselBachelorParty); + m_sut->detachEvent(m_simpleEvents[0U], ActiveCallSet_test::SimpleEvent::StoepselBachelorParty); EXPECT_THAT(m_sut->size(), Eq(1U)); } TEST_F(ActiveCallSet_test, DetachingDifferentClassWithSameEventEnumChangesNothing) { m_sut->attachEvent( - m_simpleEvents[0], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0>); + m_simpleEvents[0U], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); - m_sut->detachEvent(m_simpleEvents[1], ActiveCallSet_test::SimpleEvent::Hypnotoad); + m_sut->detachEvent(m_simpleEvents[1U], ActiveCallSet_test::SimpleEvent::Hypnotoad); EXPECT_THAT(m_sut->size(), Eq(1U)); } @@ -393,7 +393,7 @@ TEST_F(ActiveCallSet_test, AttachingTillCapacityFilledSetsUpTriggerHandle) { for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { - m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>).has_error(); + m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>).has_error(); } for (uint64_t i = 0U; i < m_sut->capacity(); ++i) @@ -407,7 +407,7 @@ TEST_F(ActiveCallSet_test, DTorDetachesAllAttachedEvents) auto capacity = m_sut->capacity(); for (uint64_t i = 0U; i < capacity; ++i) { - m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0>).has_error(); + m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>).has_error(); } m_sut.reset(); @@ -422,7 +422,7 @@ TEST_F(ActiveCallSet_test, AttachedEventDTorDetachesItself) { { SimpleEventClass fuu; - m_sut->attachEvent(fuu, ActiveCallSet_test::triggerCallback<0>); + m_sut->attachEvent(fuu, ActiveCallSet_test::triggerCallback<0U>); } EXPECT_THAT(m_sut->size(), Eq(0U)); @@ -434,125 +434,124 @@ TEST_F(ActiveCallSet_test, AttachedEventDTorDetachesItself) TIMING_TEST_F(ActiveCallSet_test, CallbackIsCalledAfterNotify, Repeat(5), [&] { SimpleEventClass fuu; m_sut->attachEvent( - fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0>); + fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); fuu.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == &fuu); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U] == &fuu); }); TIMING_TEST_F(ActiveCallSet_test, CallbackIsCalledOnlyOnceWhenTriggered, Repeat(5), [&] { SimpleEventClass fuu1; SimpleEventClass fuu2; m_sut->attachEvent( - fuu1, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0>); + fuu1, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); m_sut->attachEvent( - fuu2, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<1>); + fuu2, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<1U>); fuu1.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - m_triggerCallbackArg[0] = nullptr; + m_triggerCallbackArg[0U] = nullptr; fuu2.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == nullptr); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U] == nullptr); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U] == &fuu2); }); TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherCallback, Repeat(5), [&] { SimpleEventClass fuu; m_sut->attachEvent( - fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0>); + fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); - m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; fuu.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - m_triggerCallbackArg[0] = nullptr; + m_triggerCallbackArg[0U] = nullptr; fuu.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == &fuu); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U] == &fuu); }); TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherCallbackOnce, Repeat(5), [&] { SimpleEventClass fuu; SimpleEventClass bar; m_sut->attachEvent( - fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0>); + fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); m_sut->attachEvent( - bar, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<1>); + bar, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<1U>); - m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; fuu.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - m_triggerCallbackArg[0] = nullptr; + m_triggerCallbackArg[0U] = nullptr; fuu.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - m_triggerCallbackArg[0] = nullptr; + m_triggerCallbackArg[0U] = nullptr; bar.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(4 * CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == nullptr); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1] == &bar); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U] == nullptr); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U] == &bar); }); TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnotherCallback, Repeat(5), [&] { SimpleEventClass fuu; m_sut->attachEvent( - fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0>); + fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); - m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; fuu.triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - m_triggerCallbackArg[0] = nullptr; + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2U)); + m_triggerCallbackArg[0U] = nullptr; fuu.triggerStoepsel(); fuu.triggerStoepsel(); fuu.triggerStoepsel(); fuu.triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - m_triggerCallbackArg[0] = nullptr; - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS * 2)); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS * 2U)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == nullptr); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U] == &fuu); }); TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnotherCallbackOnce, Repeat(5), [&] { SimpleEventClass fuu; SimpleEventClass bar; m_sut->attachEvent( - fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0>); + fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); m_sut->attachEvent( - bar, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<1>); + bar, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<1U>); - m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; fuu.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - m_triggerCallbackArg[0] = nullptr; + m_triggerCallbackArg[0U] = nullptr; fuu.triggerStoepsel(); fuu.triggerStoepsel(); fuu.triggerStoepsel(); fuu.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - m_triggerCallbackArg[0] = nullptr; - + // trigger bar and fuu should not be triggered again + m_triggerCallbackArg[0U] = nullptr; bar.triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(4 * CALLBACK_WAIT_IN_MS)); + std::this_thread::sleep_for(std::chrono::milliseconds(4U * CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == nullptr); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1] == &bar); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U] == nullptr); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U] == &bar); }); TIMING_TEST_F(ActiveCallSet_test, NoTriggerLeadsToNoCallback, Repeat(5), [&] { SimpleEventClass fuu; m_sut->attachEvent( - fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0>); + fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == nullptr); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U] == nullptr); }); template @@ -564,33 +563,33 @@ struct AttachEvent const EventType event) { EXPECT_THAT(sut.attachEvent(events[N], event, ActiveCallSet_test::triggerCallback).has_error(), Eq(false)); - AttachEvent::doIt(sut, events, event); + AttachEvent::doIt(sut, events, event); } }; template <> -struct AttachEvent<0> +struct AttachEvent<0U> { template static void doIt(ActiveCallSet_test::ActiveCallSetMock& sut, std::vector& events, const EventType event) { - EXPECT_THAT(sut.attachEvent(events[0], event, ActiveCallSet_test::triggerCallback<0>).has_error(), Eq(false)); + EXPECT_THAT(sut.attachEvent(events[0U], event, ActiveCallSet_test::triggerCallback<0U>).has_error(), Eq(false)); } }; TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacks, Repeat(5), [&] { std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - AttachEvent::doIt( + AttachEvent::doIt( *m_sut, events, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty); - m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; - events[0].triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); - m_triggerCallbackArg[0] = nullptr; - m_triggerCallbackRuntimeInMs = 0; + m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; + events[0U].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2U)); + m_triggerCallbackArg[0U] = nullptr; + m_triggerCallbackRuntimeInMs = 0U; for (auto& e : events) e.triggerStoepsel(); @@ -609,11 +608,11 @@ TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacksOnce, Repe AttachEvent::doIt( *m_sut, events, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty); - m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; - events[0].triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); - m_triggerCallbackArg[0] = nullptr; - m_triggerCallbackRuntimeInMs = 0; + m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; + events[0U].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2U)); + m_triggerCallbackArg[0U] = nullptr; + m_triggerCallbackRuntimeInMs = 0U; for (auto& e : events) e.triggerStoepsel(); @@ -624,9 +623,10 @@ TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacksOnce, Repe t = nullptr; } - events[0].triggerStoepsel(); + events[0U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == &events[0U]); for (uint64_t i = 1U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) { TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i] == nullptr); @@ -639,41 +639,41 @@ TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacksOnce, Repe TIMING_TEST_F(ActiveCallSet_test, AttachingWhileCallbackIsRunningWorks, Repeat(5), [&] { std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - m_sut->attachEvent(events[0], SimpleEvent::StoepselBachelorParty, triggerCallback<0>); + m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, triggerCallback<0U>); - m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; - events[0].triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; + events[0U].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - m_sut->attachEvent(events[1], SimpleEvent::StoepselBachelorParty, triggerCallback<1>); - events[1].triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + m_sut->attachEvent(events[1U], SimpleEvent::StoepselBachelorParty, triggerCallback<1U>); + events[1U].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS * 2U)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1] == &events[1]); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U] == &events[1U]); }); TIMING_TEST_F(ActiveCallSet_test, AttachingMultipleWhileCallbackIsRunningWorks, Repeat(5), [&] { std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - m_sut->attachEvent(events[iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1], + m_sut->attachEvent(events[iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U], SimpleEvent::StoepselBachelorParty, - triggerCallback); + triggerCallback); - m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; events[iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1].triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - AttachEvent::doIt( + AttachEvent::doIt( *m_sut, events, SimpleEvent::StoepselBachelorParty); - m_triggerCallbackRuntimeInMs = 0; - for (uint64_t i = 0U; i + 1 < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) + m_triggerCallbackRuntimeInMs = 0U; + for (uint64_t i = 0U; i + 1U < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) { events[i].triggerStoepsel(); } - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2U)); - for (uint64_t i = 0U; i + 1 < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) + for (uint64_t i = 0U; i + 1U < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) { TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i] == &events[i]); } @@ -682,59 +682,59 @@ TIMING_TEST_F(ActiveCallSet_test, AttachingMultipleWhileCallbackIsRunningWorks, TIMING_TEST_F(ActiveCallSet_test, DetachingWhileCallbackIsRunningWorks, Repeat(5), [&] { std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - m_sut->attachEvent(events[0], SimpleEvent::StoepselBachelorParty, triggerCallback<0>); + m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, triggerCallback<0U>); - m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; - events[0].triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; + events[0U].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - m_triggerCallbackArg[0] = nullptr; - m_sut->detachEvent(events[0], SimpleEvent::StoepselBachelorParty); - events[0].triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + m_triggerCallbackArg[0U] = nullptr; + m_sut->detachEvent(events[0U], SimpleEvent::StoepselBachelorParty); + events[0U].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == nullptr); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U] == nullptr); }); TIMING_TEST_F(ActiveCallSet_test, DetachingWhileCallbackIsRunningBlocksDetach, Repeat(5), [&] { std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - m_sut->attachEvent(events[0], SimpleEvent::StoepselBachelorParty, triggerCallback<0>); - m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; - events[0].triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 4)); + m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, triggerCallback<0U>); + m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; + events[0U].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 4U)); auto begin = std::chrono::system_clock::now(); - m_sut->detachEvent(events[0], SimpleEvent::StoepselBachelorParty); + m_sut->detachEvent(events[0U], SimpleEvent::StoepselBachelorParty); auto end = std::chrono::system_clock::now(); auto elapsed = std::chrono::duration_cast(end - begin); - TIMING_TEST_EXPECT_TRUE(static_cast(elapsed.count()) > CALLBACK_WAIT_IN_MS / 2); + TIMING_TEST_EXPECT_TRUE(static_cast(elapsed.count()) > CALLBACK_WAIT_IN_MS / 2U); }); TIMING_TEST_F(ActiveCallSet_test, EventDestructorBlocksWhenCallbackIsRunning, Repeat(5), [&] { SimpleEventClass* event = new SimpleEventClass(); - m_sut->attachEvent(*event, SimpleEvent::StoepselBachelorParty, triggerCallback<0>); - m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; + m_sut->attachEvent(*event, SimpleEvent::StoepselBachelorParty, triggerCallback<0U>); + m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; event->triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 4)); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 4U)); auto begin = std::chrono::system_clock::now(); delete event; auto end = std::chrono::system_clock::now(); auto elapsed = std::chrono::duration_cast(end - begin); - TIMING_TEST_EXPECT_TRUE(static_cast(elapsed.count()) > CALLBACK_WAIT_IN_MS / 2); + TIMING_TEST_EXPECT_TRUE(static_cast(elapsed.count()) > CALLBACK_WAIT_IN_MS / 2U); }); TIMING_TEST_F(ActiveCallSet_test, DetachingMultipleWhileCallbackIsRunningWorks, Repeat(5), [&] { std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - AttachEvent::doIt( + AttachEvent::doIt( *m_sut, events, SimpleEvent::StoepselBachelorParty); - m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; - events[0].triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; + events[0U].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); m_triggerCallbackRuntimeInMs = 0U; for (auto& e : events) @@ -742,7 +742,7 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingMultipleWhileCallbackIsRunningWorks, m_sut->detachEvent(e, SimpleEvent::StoepselBachelorParty); } - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); for (auto& t : m_triggerCallbackArg) { t = nullptr; @@ -751,9 +751,9 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingMultipleWhileCallbackIsRunningWorks, { e.triggerStoepsel(); } - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - for (uint64_t i = 0; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) + for (uint64_t i = 0U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) { TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i] == nullptr); } @@ -761,14 +761,14 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingMultipleWhileCallbackIsRunningWorks, TIMING_TEST_F(ActiveCallSet_test, AttachingDetachingRunsIndependentOfCallback, Repeat(5), [&] { std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - m_sut->attachEvent(events[iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1], + m_sut->attachEvent(events[iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U], SimpleEvent::StoepselBachelorParty, - triggerCallback); - m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; - events[iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1].triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + triggerCallback); + m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; + events[iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2U)); - AttachEvent::doIt( + AttachEvent::doIt( *m_sut, events, SimpleEvent::StoepselBachelorParty); for (auto& e : events) @@ -778,7 +778,7 @@ TIMING_TEST_F(ActiveCallSet_test, AttachingDetachingRunsIndependentOfCallback, R // EXPECT_* (assert step) is inside of doIt call. We expect that every event can // be attached - AttachEvent::doIt( + AttachEvent::doIt( *m_sut, events, SimpleEvent::StoepselBachelorParty); }); @@ -789,65 +789,65 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingSelfInCallbackWorks, Repeat(5), [&] { m_toBeDetached.clear(); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - m_toBeDetached.push_back({&events[0], &*m_sut}); - m_sut->attachEvent(events[0], SimpleEvent::StoepselBachelorParty, detachCallback); + m_toBeDetached.push_back({&events[0U], &*m_sut}); + m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, detachCallback); - events[0].triggerStoepsel(); + events[0U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_sut->size() == 0); + TIMING_TEST_EXPECT_TRUE(m_sut->size() == 0U); }); TIMING_TEST_F(ActiveCallSet_test, DetachingNonSelfEventInCallbackWorks, Repeat(5), [&] { m_toBeDetached.clear(); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - m_toBeDetached.push_back({&events[1], &*m_sut}); - m_sut->attachEvent(events[0], SimpleEvent::StoepselBachelorParty, detachCallback); - m_sut->attachEvent(events[1], SimpleEvent::StoepselBachelorParty, triggerCallback<1>); + m_toBeDetached.push_back({&events[1U], &*m_sut}); + m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, detachCallback); + m_sut->attachEvent(events[1U], SimpleEvent::StoepselBachelorParty, triggerCallback<1U>); - events[0].triggerStoepsel(); + events[0U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_sut->size() == 1); + TIMING_TEST_EXPECT_TRUE(m_sut->size() == 1U); }); TIMING_TEST_F(ActiveCallSet_test, DetachedCallbacksAreNotBeingCalledWhenTriggeredBefore, Repeat(5), [&] { m_toBeDetached.clear(); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - m_toBeDetached.push_back({&events[1], &*m_sut}); - m_sut->attachEvent(events[0], SimpleEvent::StoepselBachelorParty, notifyAndThenDetachCallback); - m_sut->attachEvent(events[1], SimpleEvent::StoepselBachelorParty, triggerCallback<1>); - - m_triggerCallbackRuntimeInMs = 3 * CALLBACK_WAIT_IN_MS / 2; - events[1].triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); - m_triggerCallbackArg[1] = nullptr; - m_triggerCallbackRuntimeInMs = 0; + m_toBeDetached.push_back({&events[1U], &*m_sut}); + m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, notifyAndThenDetachCallback); + m_sut->attachEvent(events[1U], SimpleEvent::StoepselBachelorParty, triggerCallback<1U>); + + m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; + events[1U].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2U)); + m_triggerCallbackArg[1U] = nullptr; + m_triggerCallbackRuntimeInMs = 0U; - events[0].triggerStoepsel(); - events[1].triggerStoepsel(); + events[0U].triggerStoepsel(); + events[1U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1] == nullptr); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U] == nullptr); }); TIMING_TEST_F(ActiveCallSet_test, AttachingInCallbackWorks, Repeat(1), [&] { m_toBeAttached.clear(); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - m_toBeAttached.push_back({&events[1], &*m_sut}); - m_sut->attachEvent(events[0], SimpleEvent::StoepselBachelorParty, attachCallback); + m_toBeAttached.push_back({&events[1U], &*m_sut}); + m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, attachCallback); - events[0].triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); - events[1].triggerStoepsel(); + events[0U].triggerStoepsel(); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2U)); + events[1U].triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2)); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2U)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == &events[1]); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U] == &events[1U]); }); From a51828387bfaa6499b12a06ef7fbf5fe9c3849c0 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Wed, 10 Feb 2021 15:51:33 +0100 Subject: [PATCH 050/143] iox-#350 fixed unit test in wait set Signed-off-by: Christian Eltzschig --- iceoryx_posh/test/moduletests/test_popo_waitset.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iceoryx_posh/test/moduletests/test_popo_waitset.cpp b/iceoryx_posh/test/moduletests/test_popo_waitset.cpp index 18bacc39b59..d92f0e3b96d 100644 --- a/iceoryx_posh/test/moduletests/test_popo_waitset.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_waitset.cpp @@ -226,7 +226,7 @@ TEST_F(WaitSet_test, TriggerRemovesItselfFromWaitsetWhenGoingOutOfScope) TEST_F(WaitSet_test, MultipleTimerRemovingThemselfFromWaitsetWhenGoingOutOfScope) { iox::cxx::vector*, iox::MAX_NUMBER_OF_EVENTS_PER_WAITSET> trigger; - for (uint64_t i = 0U; i + 3U < iox::MAX_NUMBER_OF_EVENTS_PER_WAITSET; ++i) + for (uint64_t i = 3U; i < iox::MAX_NUMBER_OF_EVENTS_PER_WAITSET; ++i) { m_sut.attachEvent(m_simpleEvents[i], 100U + i); } From 5f8de15381fbc253ed096c56a2e428f8a58afbd0 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Wed, 10 Feb 2021 16:14:08 +0100 Subject: [PATCH 051/143] iox-#350 adjusted user trigger storage size for c binding Signed-off-by: Christian Eltzschig --- iceoryx_binding_c/include/iceoryx_binding_c/types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/types.h b/iceoryx_binding_c/include/iceoryx_binding_c/types.h index f5cd0ebf153..d961903f959 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/types.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/types.h @@ -37,7 +37,7 @@ struct iox_user_trigger_storage_t_ // the value of the array size is the result of the following formula: // sizeof(UserTrigger) / 8 #if defined(__APPLE__) - uint64_t do_not_touch_me[16]; + uint64_t do_not_touch_me[17]; #else uint64_t do_not_touch_me[14]; #endif From f0715a255abd2128933bb278bab69db426b4e478 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Wed, 10 Feb 2021 16:14:57 +0100 Subject: [PATCH 052/143] iox-#350 adjusted subscriber storage size for c binding Signed-off-by: Christian Eltzschig --- iceoryx_binding_c/include/iceoryx_binding_c/types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/types.h b/iceoryx_binding_c/include/iceoryx_binding_c/types.h index d961903f959..fd4973e53ae 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/types.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/types.h @@ -49,7 +49,7 @@ struct iox_sub_storage_t_ // the value of the array size is the result of the following formula: // sizeof(cpp2c_Subscriber) / 8 #if defined(__APPLE__) - uint64_t do_not_touch_me[16]; + uint64_t do_not_touch_me[17]; #else uint64_t do_not_touch_me[14]; #endif From 8b6ca3cfc831444770f669f3d0e3e99da9c8aec0 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Thu, 11 Feb 2021 09:30:13 +0100 Subject: [PATCH 053/143] iox-#350 make warning more precise Signed-off-by: Marika Lehmann --- iceoryx_posh/source/popo/building_blocks/event_notifier.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp b/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp index d48571f3cfd..6d8988d0cb0 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp @@ -25,7 +25,8 @@ EventNotifier::EventNotifier(EventVariableData& dataRef, const uint64_t index) n { if (index >= MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET) { - LogWarn() << "The provided index " << index << " is too large."; + LogWarn() << "The provided index " << index << " is too large. The index has to be in the range of [0, " + << MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET << ")."; } } From 037ec747d46a92239ab6b31773f06395ceb0295e Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Thu, 11 Feb 2021 09:35:29 +0100 Subject: [PATCH 054/143] iox-#350 fix comments Signed-off-by: Marika Lehmann --- .../internal/popo/building_blocks/event_listener.hpp | 6 +++--- .../internal/popo/building_blocks/event_notifier.hpp | 2 +- iceoryx_posh/source/roudi/roudi_process.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp index 86026a57e45..ac7a7c48313 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp @@ -26,10 +26,10 @@ namespace popo { /// @brief An EventListener performs a blocking wait on a shared event variable. /// When wait returns a list of all the EventNotifier id's which had -/// triggered the EventVariable is returned and the state is reseted. +/// triggered the EventVariable is returned and the state is reset. /// /// IMPORTANT! Do not use multiple EventListener at the same time for the -/// samen EventVariable +/// same EventVariable class EventListener { public: @@ -40,7 +40,7 @@ class EventListener /// @brief returns vector of indices of active notifications; blocking if EventVariableData was /// not notified unless destroy() was called before. The indices of active notifications is - /// never empty unless destroy() was called, then its always empty. + /// never empty unless destroy() was called, then it's always empty. /// /// @return vector of active notifications cxx::vector wait() noexcept; diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp index 22b970ff298..ea23ad1cb85 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp @@ -33,7 +33,7 @@ class EventNotifier /// /// @param[in] dataRef reference to EventVariableData /// @param[in] index index which identifies EventNotifier uniquely. The user has to ensure the uniqueness and the - /// index has to be in the range of [0, iox::MAX_EVENTS_PER_ACTIVE_CALLSET] + /// index has to be in the range of [0, MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET) EventNotifier(EventVariableData& dataRef, const uint64_t index) noexcept; /// @brief wakes up the corresponding EventListener which is waiting in wait() diff --git a/iceoryx_posh/source/roudi/roudi_process.cpp b/iceoryx_posh/source/roudi/roudi_process.cpp index aae8728af6b..4c55118a185 100644 --- a/iceoryx_posh/source/roudi/roudi_process.cpp +++ b/iceoryx_posh/source/roudi/roudi_process.cpp @@ -757,7 +757,7 @@ void ProcessManager::addEventVariableForProcess(const ProcessName_t& processName RouDiProcess* process = getProcessFromList(processName); if (nullptr != process) { - // Try to create a event variable + // Try to create an event variable m_portManager.acquireEventVariableData(processName) .and_then([&](auto condVar) { auto offset = RelativePointer::getOffset(m_mgmtSegmentId, condVar); From 83d2ae8a40e254c0fbf9ce8565effef9c9bc6978 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Thu, 11 Feb 2021 11:21:26 +0100 Subject: [PATCH 055/143] iox-#350 fixed review findings - removed unnecessary code from tests and added a more detailed doxygen docu Signed-off-by: Christian Eltzschig --- .../iceoryx_posh/popo/trigger_handle.hpp | 13 ++++++--- .../moduletests/test_popo_active_call_set.cpp | 27 ++++++++++--------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp b/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp index 3db340046dc..a963c6cc292 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp @@ -39,15 +39,21 @@ class TriggerHandle { public: TriggerHandle() = default; - TriggerHandle(EventVariableData& eventVariableDataPtr, + /// @brief Creates a TriggerHandle + /// @param[in] eventVariableDataRef reference to a event variable data struct + /// @param[in] resetCallback callback which will be called it goes out of scope or reset is called + /// @param[in] uniqueTriggerId the unique trigger id of the Trigger which corresponds to the TriggerHandle. Usually + /// stored in a Notifyable. It is required for the resetCallback + TriggerHandle(EventVariableData& eventVariableDataRef, const cxx::MethodCallback resetCallback, const uint64_t uniqueTriggerId) noexcept; + /// @brief Creates a TriggerHandle - /// @param[in] conditionVariableDataPtr pointer to a condition variable data struct + /// @param[in] conditionVariableDataRef reference to a condition variable data struct /// @param[in] resetCallback callback which will be called it goes out of scope or reset is called /// @param[in] uniqueTriggerId the unique trigger id of the Trigger which corresponds to the TriggerHandle. Usually /// stored in a Notifyable. It is required for the resetCallback - TriggerHandle(ConditionVariableData& conditionVariableDataPtr, + TriggerHandle(ConditionVariableData& conditionVariableDataRef, const cxx::MethodCallback resetCallback, const uint64_t uniqueTriggerId) noexcept; TriggerHandle(const TriggerHandle&) = delete; @@ -81,6 +87,7 @@ class TriggerHandle /// @brief returns the pointer to the ConditionVariableData ConditionVariableData* getConditionVariableData() noexcept; + /// @brief returns true if it contains an EventVariable, otherwise false bool doesContainEventVariable() const noexcept; private: diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index 942c581ae16..6aa757d8bef 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -190,6 +190,7 @@ class ActiveCallSet_test : public Test ActiveCallSetMock* sut; }; + // + 1U to test the maximum capacity using eventVector_t = iox::cxx::vector; eventVector_t m_simpleEvents{iox::MAX_NUMBER_OF_EVENTS_PER_WAITSET + 1U}; @@ -244,7 +245,7 @@ TEST_F(ActiveCallSet_test, AttachWithoutEnumOneMoreThanCapacityFails) { for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { - m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>).has_error(); + m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>); } auto result = m_sut->attachEvent(m_simpleEvents[m_sut->capacity()], ActiveCallSet_test::triggerCallback<0U>); @@ -277,10 +278,8 @@ TEST_F(ActiveCallSet_test, AttachWithEnumOneMoreThanCapacityFails) { for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { - m_sut - ->attachEvent( - m_simpleEvents[i], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>) - .has_error(); + m_sut->attachEvent( + m_simpleEvents[i], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); } auto result = m_sut->attachEvent(m_simpleEvents[m_sut->capacity()], ActiveCallSet_test::SimpleEvent::Hypnotoad, @@ -294,10 +293,8 @@ TEST_F(ActiveCallSet_test, DetachMakesSpaceForAnotherAttachWithEventEnum) { for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { - m_sut - ->attachEvent( - m_simpleEvents[i], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>) - .has_error(); + m_sut->attachEvent( + m_simpleEvents[i], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); } m_sut->detachEvent(m_simpleEvents[0U], ActiveCallSet_test::SimpleEvent::Hypnotoad); @@ -312,7 +309,7 @@ TEST_F(ActiveCallSet_test, DetachMakesSpaceForAnotherAttachWithoutEventEnum) { for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { - m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>).has_error(); + m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>); } m_sut->detachEvent(m_simpleEvents[0U]); @@ -393,7 +390,7 @@ TEST_F(ActiveCallSet_test, AttachingTillCapacityFilledSetsUpTriggerHandle) { for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { - m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>).has_error(); + m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>); } for (uint64_t i = 0U; i < m_sut->capacity(); ++i) @@ -407,7 +404,7 @@ TEST_F(ActiveCallSet_test, DTorDetachesAllAttachedEvents) auto capacity = m_sut->capacity(); for (uint64_t i = 0U; i < capacity; ++i) { - m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>).has_error(); + m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>); } m_sut.reset(); @@ -588,6 +585,11 @@ TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacks, Repeat(5 m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; events[0U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2U)); + + // we triggered events[0] with a long runtime to safely trigger all events again + // while the callback is still running. to verify that events[0] is called again + // we reset the m_triggerCallbackArg[0] to nullptr (which is again set by the + // event[0] callback) and set the runtime of the callbacks to zero m_triggerCallbackArg[0U] = nullptr; m_triggerCallbackRuntimeInMs = 0U; @@ -611,7 +613,6 @@ TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacksOnce, Repe m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; events[0U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2U)); - m_triggerCallbackArg[0U] = nullptr; m_triggerCallbackRuntimeInMs = 0U; for (auto& e : events) From b51f95e118353fcd0d719a577b1e824b1110a285 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Mon, 15 Feb 2021 16:58:27 +0100 Subject: [PATCH 056/143] iox-#350 add issue number and replace forEach by range based for loop Signed-off-by: Marika Lehmann --- .../popo/building_blocks/chunk_queue_popper.hpp | 2 +- .../popo/building_blocks/event_variable_data.cpp | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp index 325b6b9ba51..16fd69acec4 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp @@ -85,7 +85,7 @@ class ChunkQueuePopper /// @param[in] ConditionVariableDataPtr, pointer to an condition variable data object void setConditionVariable(cxx::not_null conditionVariableDataPtr) noexcept; - // TODO: remove once ConditionVariable and EventVariable are combined + // TODO: iox-#350 remove once ConditionVariable and EventVariable are combined // unset is done with unsetConditionVariable void setEventVariable(EventVariableData& eventVariableDataPtr, const uint64_t eventId) noexcept; diff --git a/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp b/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp index 5ca9c42f0c9..4cff60df575 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_variable_data.cpp @@ -23,13 +23,19 @@ namespace popo { EventVariableData::EventVariableData() noexcept { - cxx::forEach(m_activeNotifications, [](auto& id) { id.store(false, std::memory_order_relaxed); }); + for (auto& id : m_activeNotifications) + { + id.store(false, std::memory_order_relaxed); + } } EventVariableData::EventVariableData(const ProcessName_t& process) noexcept : ConditionVariableData(process) { - cxx::forEach(m_activeNotifications, [](auto& id) { id.store(false, std::memory_order_relaxed); }); + for (auto& id : m_activeNotifications) + { + id.store(false, std::memory_order_relaxed); + } } } // namespace popo } // namespace iox From 9a329558cef3098ebb5e3c4ac9e421adbe136a25 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Mon, 15 Feb 2021 18:19:36 +0100 Subject: [PATCH 057/143] iox-#350 rework port manager tests and make name of posh runtime test more precise Signed-off-by: Marika Lehmann --- iceoryx_posh/source/roudi/roudi.cpp | 2 +- .../test/moduletests/test_posh_runtime.cpp | 2 +- .../moduletests/test_roudi_portmanager.cpp | 61 ++++++++----------- 3 files changed, 27 insertions(+), 38 deletions(-) diff --git a/iceoryx_posh/source/roudi/roudi.cpp b/iceoryx_posh/source/roudi/roudi.cpp index ebb06e5ec1a..87b08d5e23d 100644 --- a/iceoryx_posh/source/roudi/roudi.cpp +++ b/iceoryx_posh/source/roudi/roudi.cpp @@ -242,7 +242,7 @@ void RouDi::processMessage(const runtime::IpcMessage& message, { if (message.getNumberOfElements() != 2) { - LogError() << "Wrong number of parameters for \"MqMessageType::CREATE_EVENT_VARIABLE\" from \"" + LogError() << "Wrong number of parameters for \"IpcMessageType::CREATE_EVENT_VARIABLE\" from \"" << processName << "\"received!"; errorHandler( Error::kPORT_MANAGER__INTROSPECTION_MEMORY_MANAGER_UNAVAILABLE, nullptr, iox::ErrorLevel::MODERATE); diff --git a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp index 0351a2711de..5cf191d6cd7 100644 --- a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp +++ b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp @@ -410,7 +410,7 @@ TEST_F(PoshRuntime_test, GetMiddlewareEventVariableIsSuccessful) EXPECT_THAT(eventVariable, Ne(nullptr)); } -TEST_F(PoshRuntime_test, GetMaxNumberOfMiddlewareEventVariables) +TEST_F(PoshRuntime_test, GetMaxNumberOfMiddlewareEventVariablesIsSuccessful) { for (uint32_t i = 0U; i < iox::MAX_NUMBER_OF_EVENT_VARIABLES; ++i) { diff --git a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp index 6523064b7ec..00ae7e3c88b 100644 --- a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp +++ b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp @@ -122,6 +122,22 @@ class PortManager_test : public Test iox::cxx::GenericRAII m_uniqueRouDiId{[] { iox::popo::internal::setUniqueRouDiId(0); }, [] { iox::popo::internal::unsetUniqueRouDiId(); }}; + + void acquireMaxNumberOfEventVariables( + const std::string& process, + std::function f = std::function()) + { + for (unsigned int i = 0U; i < iox::MAX_NUMBER_OF_EVENT_VARIABLES; i++) + { + iox::ProcessName_t newProcessName(iox::cxx::TruncateToCapacity, process + std::to_string(i)); + auto eventVariableDataResult = m_portManager->acquireEventVariableData(newProcessName); + ASSERT_THAT(eventVariableDataResult.has_error(), Eq(false)); + if (f) + { + f(eventVariableDataResult.value()); + } + } + } }; @@ -446,12 +462,7 @@ TEST_F(PortManager_test, AcquiringMaximumNumberOfEventVariablesWorks) { std::string process = "BuddyHolly"; - for (unsigned int i = 0U; i < iox::MAX_NUMBER_OF_EVENT_VARIABLES; i++) - { - iox::ProcessName_t newProcessName(iox::cxx::TruncateToCapacity, process + std::to_string(i)); - auto eventVariableDataResult = m_portManager->acquireEventVariableData(newProcessName); - EXPECT_THAT(eventVariableDataResult.has_error(), Eq(false)); - } + acquireMaxNumberOfEventVariables(process); } TEST_F(PortManager_test, AcquiringOneMoreThanMaximumNumberOfEventVariableFails) @@ -459,12 +470,7 @@ TEST_F(PortManager_test, AcquiringOneMoreThanMaximumNumberOfEventVariableFails) std::string process = "BuddyHollysBrille"; // first acquire all possible event variables - for (unsigned int i = 0U; i < iox::MAX_NUMBER_OF_EVENT_VARIABLES; i++) - { - iox::ProcessName_t newProcessName(iox::cxx::TruncateToCapacity, process + std::to_string(i)); - auto eventVariableDataResult = m_portManager->acquireEventVariableData(newProcessName); - ASSERT_THAT(eventVariableDataResult.has_error(), Eq(false)); - } + acquireMaxNumberOfEventVariables(process); // test if overflow errors get hit auto errorHandlerCalled{false}; @@ -484,12 +490,7 @@ TEST_F(PortManager_test, DeletingEventVariableWorks) std::string process = "BudSpencer"; // first acquire all possible event variables - for (unsigned int i = 0U; i < iox::MAX_NUMBER_OF_EVENT_VARIABLES; i++) - { - iox::ProcessName_t newProcessName(iox::cxx::TruncateToCapacity, process + std::to_string(i)); - auto eventVariableDataResult = m_portManager->acquireEventVariableData(newProcessName); - ASSERT_THAT(eventVariableDataResult.has_error(), Eq(false)); - } + acquireMaxNumberOfEventVariables(process); // delete one and add one eventVariableDataResult should be possible now unsigned int i = 0U; @@ -506,31 +507,19 @@ TEST_F(PortManager_test, DestroyEventVariableAndAddNewOneSucceeds) std::vector eventVariableContainer; // first acquire all possible event variables - for (unsigned int i = 0U; i < iox::MAX_NUMBER_OF_EVENT_VARIABLES; i++) - { - auto eventVariableDataResult = m_portManager->acquireEventVariableData(process); - EXPECT_THAT(eventVariableDataResult.has_error(), Eq(false)); - eventVariableContainer.push_back(eventVariableDataResult.value()); - } - - // so now no event variables should be available - auto eventVariableDataResult = m_portManager->acquireEventVariableData(process); - EXPECT_THAT(eventVariableDataResult.has_error(), Eq(true)); + acquireMaxNumberOfEventVariables( + process, [&](auto eventVariableDataResult) { eventVariableContainer.push_back(eventVariableDataResult); }); // set the destroy flag and let the discovery loop take care - for (unsigned int i = 0U; i < iox::MAX_NUMBER_OF_EVENT_VARIABLES; i++) + for (const auto& eventVariable : eventVariableContainer) { - eventVariableContainer[i]->m_toBeDestroyed.store(true, std::memory_order_relaxed); + eventVariable->m_toBeDestroyed.store(true, std::memory_order_relaxed); } m_portManager->doDiscovery(); eventVariableContainer.clear(); - // so we should be able to get some more now - for (unsigned int i = 0U; i < iox::MAX_NUMBER_OF_EVENT_VARIABLES; i++) - { - auto eventVariableDataResult = m_portManager->acquireEventVariableData(process); - EXPECT_THAT(eventVariableDataResult.has_error(), Eq(false)); - } + // we should be able to get some more now + acquireMaxNumberOfEventVariables(process); } TEST_F(PortManager_test, AcquiringMaximumNumberOfNodesWorks) From 0945dfe1a0ecb6e25c2d1023b3a6270d04c02586 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 16 Feb 2021 11:01:18 +0100 Subject: [PATCH 058/143] iox-#350 use doxygen tags Signed-off-by: Marika Lehmann --- .../internal/popo/building_blocks/chunk_queue_popper.hpp | 2 +- .../internal/popo/building_blocks/event_listener.hpp | 3 +-- .../iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp index 16fd69acec4..024a39329b7 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp @@ -85,7 +85,7 @@ class ChunkQueuePopper /// @param[in] ConditionVariableDataPtr, pointer to an condition variable data object void setConditionVariable(cxx::not_null conditionVariableDataPtr) noexcept; - // TODO: iox-#350 remove once ConditionVariable and EventVariable are combined + /// @todo iox-#350 remove once ConditionVariable and EventVariable are combined // unset is done with unsetConditionVariable void setEventVariable(EventVariableData& eventVariableDataPtr, const uint64_t eventId) noexcept; diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp index ac7a7c48313..c8ca6ead3c2 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp @@ -28,8 +28,7 @@ namespace popo /// When wait returns a list of all the EventNotifier id's which had /// triggered the EventVariable is returned and the state is reset. /// -/// IMPORTANT! Do not use multiple EventListener at the same time for the -/// same EventVariable +/// @attention Do not use multiple EventListener at the same time for the same EventVariable class EventListener { public: diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp index 0c97d04b8e7..eea753cf5e4 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp @@ -86,7 +86,7 @@ class SubscriberPortUser : public BasePort /// @brief attach a condition variable (via its pointer) to subscriber void setConditionVariable(ConditionVariableData* conditionVariableDataPtr) noexcept; - // TODO: remove once ConditionVariable and EventVariable are combined + /// @todo remove once ConditionVariable and EventVariable are combined // do we need an unsetEventVariable method? void setEventVariable(EventVariableData& eventVariableData, const uint64_t eventId) noexcept; From 9f57ca76bc3e3eef957386ab5dd49edd808fd6c1 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 16 Feb 2021 12:00:12 +0100 Subject: [PATCH 059/143] iox-#350 fix c&p error, some renaming Signed-off-by: Marika Lehmann --- iceoryx_posh/source/roudi/roudi.cpp | 5 ++--- iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp | 8 ++++---- .../iceoryx_utils/error_handling/error_handling.hpp | 2 ++ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/iceoryx_posh/source/roudi/roudi.cpp b/iceoryx_posh/source/roudi/roudi.cpp index 87b08d5e23d..4fd7a11ca15 100644 --- a/iceoryx_posh/source/roudi/roudi.cpp +++ b/iceoryx_posh/source/roudi/roudi.cpp @@ -230,7 +230,7 @@ void RouDi::processMessage(const runtime::IpcMessage& message, LogError() << "Wrong number of parameters for \"IpcMessageType::CREATE_CONDITION_VARIABLE\" from \"" << processName << "\"received!"; errorHandler( - Error::kPORT_MANAGER__INTROSPECTION_MEMORY_MANAGER_UNAVAILABLE, nullptr, iox::ErrorLevel::MODERATE); + Error::kPORT_MANAGER__UNABLE_TO_ACQUIRE_CONDITION_VARIABLE, nullptr, iox::ErrorLevel::MODERATE); } else { @@ -244,8 +244,7 @@ void RouDi::processMessage(const runtime::IpcMessage& message, { LogError() << "Wrong number of parameters for \"IpcMessageType::CREATE_EVENT_VARIABLE\" from \"" << processName << "\"received!"; - errorHandler( - Error::kPORT_MANAGER__INTROSPECTION_MEMORY_MANAGER_UNAVAILABLE, nullptr, iox::ErrorLevel::MODERATE); + errorHandler(Error::kPORT_MANAGER__UNABLE_TO_ACQUIRE_EVENT_VARIABLE, nullptr, iox::ErrorLevel::MODERATE); } else { diff --git a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp index 00ae7e3c88b..ce5b2e99425 100644 --- a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp +++ b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp @@ -130,11 +130,11 @@ class PortManager_test : public Test for (unsigned int i = 0U; i < iox::MAX_NUMBER_OF_EVENT_VARIABLES; i++) { iox::ProcessName_t newProcessName(iox::cxx::TruncateToCapacity, process + std::to_string(i)); - auto eventVariableDataResult = m_portManager->acquireEventVariableData(newProcessName); - ASSERT_THAT(eventVariableDataResult.has_error(), Eq(false)); + auto eventVariableData = m_portManager->acquireEventVariableData(newProcessName); + ASSERT_THAT(eventVariableData.has_error(), Eq(false)); if (f) { - f(eventVariableDataResult.value()); + f(eventVariableData.value()); } } } @@ -508,7 +508,7 @@ TEST_F(PortManager_test, DestroyEventVariableAndAddNewOneSucceeds) // first acquire all possible event variables acquireMaxNumberOfEventVariables( - process, [&](auto eventVariableDataResult) { eventVariableContainer.push_back(eventVariableDataResult); }); + process, [&](auto eventVariableData) { eventVariableContainer.push_back(eventVariableData); }); // set the destroy flag and let the discovery loop take care for (const auto& eventVariable : eventVariableContainer) diff --git a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp index 56ffdac9347..a81a8c5fa52 100644 --- a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp +++ b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp @@ -119,6 +119,8 @@ namespace iox error(PORT_MANAGER__NO_PUBLISHER_PORT_FOR_INTROSPECTIONPORTTHROUGHPUTSERVICE) \ error(PORT_MANAGER__NO_PUBLISHER_PORT_FOR_INTROSPECTIONCHANGINGDATASERVICE) \ error(PORT_MANAGER__NO_PUBLISHER_PORT_FOR_INTROSPECTION_SENDER_PORT) \ + error(PORT_MANAGER__UNABLE_TO_ACQUIRE_CONDITION_VARIABLE) \ + error(PORT_MANAGER__UNABLE_TO_ACQUIRE_EVENT_VARIABLE) \ error(ROUDI_COMPONENTS__SHARED_MEMORY_UNAVAILABLE) \ error(ROUDI_MEMORY__COULD_NOT_REGISTER_SIGBUS) \ error(ROUDI_MEMORY__COULD_NOT_UNREGISTER_SIGBUS) \ From a84741eb6cba5db9e67590042773fa3b6e040539 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 16 Feb 2021 12:16:00 +0100 Subject: [PATCH 060/143] iox-#350 add issue number for todo Signed-off-by: Marika Lehmann --- .../iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp index eea753cf5e4..423c79f67e4 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp @@ -86,7 +86,7 @@ class SubscriberPortUser : public BasePort /// @brief attach a condition variable (via its pointer) to subscriber void setConditionVariable(ConditionVariableData* conditionVariableDataPtr) noexcept; - /// @todo remove once ConditionVariable and EventVariable are combined + /// @todo iox-#350 remove once ConditionVariable and EventVariable are combined // do we need an unsetEventVariable method? void setEventVariable(EventVariableData& eventVariableData, const uint64_t eventId) noexcept; From a81c48c32131c3e5b78275e470b515c4eb7d2168 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Wed, 17 Feb 2021 13:19:31 +0100 Subject: [PATCH 061/143] iox-#350 added example readme into docu structure, used sigaction instead of signal, removed magic numbers Signed-off-by: Christian Eltzschig --- .../examples/intermediate-examples.md | 1 + iceoryx_examples/README.md | 1 + .../callbacks/ice_callbacks_subscriber.cpp | 16 +++++- .../building_blocks/chunk_queue_popper.hpp | 2 +- .../building_blocks/chunk_queue_pusher.hpp | 1 - .../popo/building_blocks/event_listener.hpp | 2 +- .../iceoryx_posh/popo/active_call_set.hpp | 1 - iceoryx_posh/source/popo/trigger_handle.cpp | 4 +- .../moduletests/test_popo_active_call_set.cpp | 55 ++++++++++--------- .../test/moduletests/test_popo_trigger.cpp | 35 ++++++++---- .../test/moduletests/test_popo_waitset.cpp | 37 ++++++++----- tools/iceoryx_build_test.sh | 2 +- 12 files changed, 93 insertions(+), 64 deletions(-) diff --git a/doc/website/getting-started/examples/intermediate-examples.md b/doc/website/getting-started/examples/intermediate-examples.md index b573df9c681..d87c629de39 100644 --- a/doc/website/getting-started/examples/intermediate-examples.md +++ b/doc/website/getting-started/examples/intermediate-examples.md @@ -1,5 +1,6 @@ # Intermediate examples +{! ./../iceoryx_examples/callbacks/README.md !} {! ./../iceoryx_examples/waitset/README.md !} {! ./../iceoryx_examples/waitset_in_c/README.md !} {! ./../iceoryx_examples/singleprocess/README.md !} diff --git a/iceoryx_examples/README.md b/iceoryx_examples/README.md index 9f9d7a47d79..ef63b1a66a6 100644 --- a/iceoryx_examples/README.md +++ b/iceoryx_examples/README.md @@ -22,6 +22,7 @@ cd someExample | Example | Description |Level | |:-------------------------------------------------------|:------------|:----:| +|[callbacks](./callbacks/) | Implement callbacks which are triggered by events. | Intermediate | |[icedelivery](./icedelivery/) | You are new to iceoryx then take a look at this example which demonstrates the basics of iceoryx by sending data from one process to another process. | Beginner | |[icedelivery_in_c](./icedelivery_in_c/) | Shows the same use case as the ice delivery example but with the iceoryx C API | Beginner | |[ice_multi_publisher](./ice_multi_publisher/) | Shows how multiple publishers can be used to publish on the same topic. | Intermediate | diff --git a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp index ef2ccc24233..64a6e83f6a9 100644 --- a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp +++ b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp @@ -29,13 +29,16 @@ iox::popo::UserTrigger shutdownTrigger; iox::posix::Semaphore mainLoopBlocker = iox::posix::Semaphore::create(iox::posix::CreateUnnamedSingleProcessSemaphore, 0).value(); +std::atomic_bool keepRunning{true}; + static void sigHandler(int f_sig [[gnu::unused]]) { shutdownTrigger.trigger(); } -void shutdownTriggerCallback(iox::popo::UserTrigger* trigger) +void shutdownTriggerCallback(iox::popo::UserTrigger*) { + keepRunning.store(false); } void subscriberCallback(iox::popo::TypedSubscriber* subscriber) @@ -45,7 +48,11 @@ void subscriberCallback(iox::popo::TypedSubscriber* subscriber) int main() { - signal(SIGINT, sigHandler); + struct sigaction act; + sigemptyset(&act.sa_mask); + act.sa_handler = sigHandler; + act.sa_flags = 0; + sigaction(SIGINT, &act, nullptr); iox::runtime::PoshRuntime::initRuntime("iox-ex-callbacks-subscriber"); @@ -60,7 +67,10 @@ int main() callSet.attachEvent(subscriber, iox::popo::SubscriberEvent::HAS_SAMPLES, subscriberCallback); - std::this_thread::sleep_for(std::chrono::seconds(100000)); + while (keepRunning) + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } callSet.detachEvent(shutdownTrigger); callSet.detachEvent(subscriber, iox::popo::SubscriberEvent::HAS_SAMPLES); diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp index ed4a8c26464..d051a9b7547 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_popper.hpp @@ -86,7 +86,7 @@ class ChunkQueuePopper /// @param[in] ConditionVariableDataPtr, pointer to an condition variable data object void setConditionVariable(cxx::not_null conditionVariableDataPtr) noexcept; - // TODO: remove once ConditionVariable and EventVariable are combined + /// @todo remove once ConditionVariable and EventVariable are combined // unset is done with unsetConditionVariable void setEventVariable(EventVariableData& eventVariableDataPtr, const uint64_t eventId) noexcept; diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp index 27a04f5c175..009fcdacfd0 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_queue_pusher.hpp @@ -18,7 +18,6 @@ #ifndef IOX_POSH_POPO_BUILDING_BLOCKS_CHUNK_QUEUE_PUSHER_HPP #define IOX_POSH_POPO_BUILDING_BLOCKS_CHUNK_QUEUE_PUSHER_HPP -#include "iceoryx_posh/internal/log/posh_logging.hpp" #include "iceoryx_posh/internal/mepoo/shared_chunk.hpp" #include "iceoryx_posh/internal/popo/building_blocks/chunk_queue_data.hpp" #include "iceoryx_posh/internal/popo/building_blocks/chunk_queue_types.hpp" diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp index ac7a7c48313..6ca515fddfe 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp @@ -28,7 +28,7 @@ namespace popo /// When wait returns a list of all the EventNotifier id's which had /// triggered the EventVariable is returned and the state is reset. /// -/// IMPORTANT! Do not use multiple EventListener at the same time for the +/// @attention Do not use multiple EventListener at the same time for the /// same EventVariable class EventListener { diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp index 5c4d54a4719..421f819084d 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -165,7 +165,6 @@ class ActiveCallSet cxx::MethodCallback m_invalidationCallback; }; - // TODO: integrate in LoFFLi?! class IndexManager_t { public: diff --git a/iceoryx_posh/source/popo/trigger_handle.cpp b/iceoryx_posh/source/popo/trigger_handle.cpp index edc46bc6909..ce337d954fe 100644 --- a/iceoryx_posh/source/popo/trigger_handle.cpp +++ b/iceoryx_posh/source/popo/trigger_handle.cpp @@ -23,10 +23,10 @@ namespace iox { namespace popo { -TriggerHandle::TriggerHandle(EventVariableData& eventVariableDataPtr, +TriggerHandle::TriggerHandle(EventVariableData& eventVariableDataRef, const cxx::MethodCallback resetCallback, const uint64_t uniqueTriggerId) noexcept - : TriggerHandle(static_cast(eventVariableDataPtr), resetCallback, uniqueTriggerId) + : TriggerHandle(static_cast(eventVariableDataRef), resetCallback, uniqueTriggerId) { m_doesContainEventVariable = true; } diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index 6aa757d8bef..d6ee09808f4 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -191,8 +191,8 @@ class ActiveCallSet_test : public Test }; // + 1U to test the maximum capacity - using eventVector_t = iox::cxx::vector; - eventVector_t m_simpleEvents{iox::MAX_NUMBER_OF_EVENTS_PER_WAITSET + 1U}; + using eventVector_t = iox::cxx::vector; + eventVector_t m_simpleEvents{iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET + 1U}; static std::vector m_toBeAttached; static std::vector m_toBeDetached; @@ -208,6 +208,32 @@ uint64_t ActiveCallSet_test::m_triggerCallbackRuntimeInMs; std::vector ActiveCallSet_test::m_toBeAttached; std::vector ActiveCallSet_test::m_toBeDetached; +template +struct AttachEvent +{ + template + static void doIt(ActiveCallSet_test::ActiveCallSetMock& sut, + std::vector& events, + const EventType event) + { + EXPECT_THAT(sut.attachEvent(events[N], event, ActiveCallSet_test::triggerCallback).has_error(), Eq(false)); + AttachEvent::doIt(sut, events, event); + } +}; + +template <> +struct AttachEvent<0U> +{ + template + static void doIt(ActiveCallSet_test::ActiveCallSetMock& sut, + std::vector& events, + const EventType event) + { + EXPECT_THAT(sut.attachEvent(events[0U], event, ActiveCallSet_test::triggerCallback<0U>).has_error(), Eq(false)); + } +}; + + ////////////////////////////////// // attach / detach ////////////////////////////////// @@ -551,31 +577,6 @@ TIMING_TEST_F(ActiveCallSet_test, NoTriggerLeadsToNoCallback, Repeat(5), [&] { TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U] == nullptr); }); -template -struct AttachEvent -{ - template - static void doIt(ActiveCallSet_test::ActiveCallSetMock& sut, - std::vector& events, - const EventType event) - { - EXPECT_THAT(sut.attachEvent(events[N], event, ActiveCallSet_test::triggerCallback).has_error(), Eq(false)); - AttachEvent::doIt(sut, events, event); - } -}; - -template <> -struct AttachEvent<0U> -{ - template - static void doIt(ActiveCallSet_test::ActiveCallSetMock& sut, - std::vector& events, - const EventType event) - { - EXPECT_THAT(sut.attachEvent(events[0U], event, ActiveCallSet_test::triggerCallback<0U>).has_error(), Eq(false)); - } -}; - TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacks, Repeat(5), [&] { std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); diff --git a/iceoryx_posh/test/moduletests/test_popo_trigger.cpp b/iceoryx_posh/test/moduletests/test_popo_trigger.cpp index 845b7a9c9c6..102d493f12a 100644 --- a/iceoryx_posh/test/moduletests/test_popo_trigger.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_trigger.cpp @@ -234,11 +234,12 @@ TEST_F(Trigger_test, UpdateOriginLeadsToDifferentHasTriggeredCallback) TEST_F(Trigger_test, UpdateOriginDoesNotUpdateHasTriggeredIfItsNotOriginatingFromOrigin) { + uint64_t userDefinedEventId = 891U; TriggerClass secondTriggerClass, thirdTriggerClass; Trigger sut(&m_triggerClass, {thirdTriggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - 891U, + userDefinedEventId, TriggerClass::callback); sut.updateOrigin(&secondTriggerClass); @@ -262,11 +263,12 @@ TEST_F(Trigger_test, UpdateOriginLeadsToDifferentResetCallback) TEST_F(Trigger_test, UpdateOriginDoesNotUpdateResetIfItsNotOriginatingFromOrigin) { + uint64_t userDefinedEventId = 892U; TriggerClass secondTriggerClass, thirdTriggerClass; Trigger sut(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {thirdTriggerClass, &TriggerClass::resetCall}, - 891U, + userDefinedEventId, TriggerClass::callback); sut.updateOrigin(&secondTriggerClass); @@ -277,11 +279,12 @@ TEST_F(Trigger_test, UpdateOriginDoesNotUpdateResetIfItsNotOriginatingFromOrigin TEST_F(Trigger_test, UpdateOriginUpdatesOriginOfEventInfo) { + uint64_t userDefinedEventId = 893U; TriggerClass secondTriggerClass; Trigger sut(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - 891U, + userDefinedEventId, TriggerClass::callback); sut.updateOrigin(&secondTriggerClass); @@ -293,10 +296,11 @@ TEST_F(Trigger_test, UpdateOriginUpdatesOriginOfEventInfo) /// - hasTriggeredCallback TEST_F(Trigger_test, TriggerIsLogicalEqualToItself) { + uint64_t userDefinedEventId = 894U; Trigger sut1(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - 8911U, + userDefinedEventId, TriggerClass::callback); EXPECT_TRUE(sut1.isLogicalEqualTo(sut1)); @@ -304,16 +308,18 @@ TEST_F(Trigger_test, TriggerIsLogicalEqualToItself) TEST_F(Trigger_test, TwoTriggersAreLogicalEqualIfRequirementsAreFullfilled) { + uint64_t userDefinedEventId = 896U; + uint64_t anotherUserDefinedEventId = 8961U; Trigger sut1(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - 891U, + userDefinedEventId, TriggerClass::callback); Trigger sut2(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - 892U, + anotherUserDefinedEventId, TriggerClass::callback); @@ -323,16 +329,18 @@ TEST_F(Trigger_test, TwoTriggersAreLogicalEqualIfRequirementsAreFullfilled) TEST_F(Trigger_test, TwoTriggersAreLogicalEqualIfOnlyTriggerIdDiffers) { + uint64_t userDefinedEventId = 2896U; + uint64_t anotherUserDefinedEventId = 28961U; Trigger sut1(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - 2891U, + userDefinedEventId, TriggerClass::callback); Trigger sut2(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - 3891U, + anotherUserDefinedEventId, TriggerClass::callback); @@ -342,17 +350,19 @@ TEST_F(Trigger_test, TwoTriggersAreLogicalEqualIfOnlyTriggerIdDiffers) TEST_F(Trigger_test, TwoTriggersAreNotLogicalEqualIfHasTriggeredCallbackDiffers) { + uint64_t userDefinedEventId = 4896U; + uint64_t anotherUserDefinedEventId = 48961U; TriggerClass secondTriggerClass; Trigger sut1(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - 4891U, + userDefinedEventId, TriggerClass::callback); Trigger sut2(&m_triggerClass, {secondTriggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - 4891U, + anotherUserDefinedEventId, TriggerClass::callback); @@ -362,17 +372,18 @@ TEST_F(Trigger_test, TwoTriggersAreNotLogicalEqualIfHasTriggeredCallbackDiffers) TEST_F(Trigger_test, TwoTriggersAreNotLogicalEqualIfOriginDiffers) { + uint64_t userDefinedEventId = 4896U; TriggerClass secondTriggerClass; Trigger sut1(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - 4891U, + userDefinedEventId, TriggerClass::callback); Trigger sut2(&secondTriggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - 4891U, + userDefinedEventId, TriggerClass::callback); diff --git a/iceoryx_posh/test/moduletests/test_popo_waitset.cpp b/iceoryx_posh/test/moduletests/test_popo_waitset.cpp index d92f0e3b96d..daa0c957aa6 100644 --- a/iceoryx_posh/test/moduletests/test_popo_waitset.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_waitset.cpp @@ -166,8 +166,9 @@ TEST_F(WaitSet_test, AcquireMaximumAllowedPlusOneTriggerFails) TEST_F(WaitSet_test, AcquireSameTriggerTwiceResultsInError) { - m_sut.attachEvent(m_simpleEvents[0], 0U); - auto result2 = m_sut.attachEvent(m_simpleEvents[0], 0U); + uint64_t userDefinedEventId = 0U; + m_sut.attachEvent(m_simpleEvents[0], userDefinedEventId); + auto result2 = m_sut.attachEvent(m_simpleEvents[0], userDefinedEventId); ASSERT_TRUE(result2.has_error()); EXPECT_THAT(result2.get_error(), Eq(WaitSetError::EVENT_ALREADY_ATTACHED)); @@ -175,8 +176,9 @@ TEST_F(WaitSet_test, AcquireSameTriggerTwiceResultsInError) TEST_F(WaitSet_test, AcquireSameTriggerWithNonNullIdTwiceResultsInError) { - m_sut.attachEvent(m_simpleEvents[0], 121U); - auto result2 = m_sut.attachEvent(m_simpleEvents[0], 121U); + uint64_t userDefinedEventId = 121U; + m_sut.attachEvent(m_simpleEvents[0], userDefinedEventId); + auto result2 = m_sut.attachEvent(m_simpleEvents[0], userDefinedEventId); ASSERT_TRUE(result2.has_error()); EXPECT_THAT(result2.get_error(), Eq(WaitSetError::EVENT_ALREADY_ATTACHED)); @@ -184,8 +186,10 @@ TEST_F(WaitSet_test, AcquireSameTriggerWithNonNullIdTwiceResultsInError) TEST_F(WaitSet_test, AcquireSameTriggerWithDifferentIdResultsInError) { - m_sut.attachEvent(m_simpleEvents[0], 2101U); - auto result2 = m_sut.attachEvent(m_simpleEvents[0], 9121U); + uint64_t userDefinedEventId = 2101U; + uint64_t anotherUserDefinedEventId = 9121U; + m_sut.attachEvent(m_simpleEvents[0], userDefinedEventId); + auto result2 = m_sut.attachEvent(m_simpleEvents[0], anotherUserDefinedEventId); ASSERT_TRUE(result2.has_error()); EXPECT_THAT(result2.get_error(), Eq(WaitSetError::EVENT_ALREADY_ATTACHED)); @@ -197,7 +201,8 @@ TEST_F(WaitSet_test, ResetCallbackIsCalledWhenWaitsetGoesOutOfScope) SimpleEventClass simpleEvent; { WaitSetMock sut{&m_condVarData}; - sut.attachEvent(simpleEvent, 421337U); + uint64_t userDefinedEventId = 421337U; + sut.attachEvent(simpleEvent, userDefinedEventId); uniqueTriggerId = simpleEvent.getUniqueId(); } EXPECT_THAT(SimpleEventClass::m_invalidateTriggerId, Eq(uniqueTriggerId)); @@ -211,15 +216,16 @@ TEST_F(WaitSet_test, TriggerRemovesItselfFromWaitsetWhenGoingOutOfScope) m_sut.attachEvent(m_simpleEvents[i], 100U + i); } + uint64_t userDefinedEventId = 0U; { SimpleEventClass temporaryTrigger; - m_sut.attachEvent(temporaryTrigger, 0U); + m_sut.attachEvent(temporaryTrigger, userDefinedEventId); // goes out of scope here and creates space again for an additional trigger // if this doesn't work we are unable to acquire another trigger since the // waitset is already full } - auto result = m_sut.attachEvent(m_simpleEvents.back(), 0U); + auto result = m_sut.attachEvent(m_simpleEvents.back(), userDefinedEventId); EXPECT_FALSE(result.has_error()); } @@ -231,20 +237,21 @@ TEST_F(WaitSet_test, MultipleTimerRemovingThemselfFromWaitsetWhenGoingOutOfScope m_sut.attachEvent(m_simpleEvents[i], 100U + i); } + uint64_t userDefinedEventId = 0U; { SimpleEventClass temporaryTrigger1, temporaryTrigger2, temporaryTrigger3; - m_sut.attachEvent(temporaryTrigger1, 0U); - m_sut.attachEvent(temporaryTrigger2, 0U); - m_sut.attachEvent(temporaryTrigger3, 0U); + m_sut.attachEvent(temporaryTrigger1, userDefinedEventId); + m_sut.attachEvent(temporaryTrigger2, userDefinedEventId); + m_sut.attachEvent(temporaryTrigger3, userDefinedEventId); // goes out of scope here and creates space again for an additional trigger // if this doesn't work we are unable to acquire another trigger since the // waitset is already full } - auto result0 = m_sut.attachEvent(m_simpleEvents[0], 0U); - auto result1 = m_sut.attachEvent(m_simpleEvents[1], 0U); - auto result2 = m_sut.attachEvent(m_simpleEvents[2], 0U); + auto result0 = m_sut.attachEvent(m_simpleEvents[0], userDefinedEventId); + auto result1 = m_sut.attachEvent(m_simpleEvents[1], userDefinedEventId); + auto result2 = m_sut.attachEvent(m_simpleEvents[2], userDefinedEventId); EXPECT_FALSE(result0.has_error()); EXPECT_FALSE(result1.has_error()); EXPECT_FALSE(result2.has_error()); diff --git a/tools/iceoryx_build_test.sh b/tools/iceoryx_build_test.sh index 4985cedd812..371a8a3eba5 100755 --- a/tools/iceoryx_build_test.sh +++ b/tools/iceoryx_build_test.sh @@ -45,7 +45,7 @@ EXAMPLE_FLAG="OFF" BUILD_ALL_FLAG="OFF" BUILD_SHARED="OFF" TOML_FLAG="ON" -EXAMPLES="ice_multi_publisher icedelivery singleprocess waitset" +EXAMPLES="callbacks ice_multi_publisher icedelivery singleprocess waitset" COMPONENTS="iceoryx_posh iceoryx_utils iceoryx_introspection iceoryx_binding_c iceoryx_component iceoryx_dds" while (( "$#" )); do From 1f52c3fe223211363d6a98ee09fd63abfcc6eb31 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Wed, 17 Feb 2021 18:55:42 +0100 Subject: [PATCH 062/143] iox-#350 adjusted examples to new API Signed-off-by: Christian Eltzschig --- .../callbacks/ice_callbacks_publisher.cpp | 2 +- .../callbacks/ice_callbacks_subscriber.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/iceoryx_examples/callbacks/ice_callbacks_publisher.cpp b/iceoryx_examples/callbacks/ice_callbacks_publisher.cpp index e75aaf2d436..fe9a01552a5 100644 --- a/iceoryx_examples/callbacks/ice_callbacks_publisher.cpp +++ b/iceoryx_examples/callbacks/ice_callbacks_publisher.cpp @@ -33,7 +33,7 @@ void sending() { iox::runtime::PoshRuntime::initRuntime("iox-ex-callbacks-publisher"); - iox::popo::TypedPublisher myPublisher({"Radar", "FrontLeft", "Counter"}); + iox::popo::Publisher myPublisher({"Radar", "FrontLeft", "Counter"}); myPublisher.offer(); for (uint32_t counter = 0U; !killswitch; ++counter) diff --git a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp index 64a6e83f6a9..ea03e8adfa8 100644 --- a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp +++ b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp @@ -15,7 +15,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "iceoryx_posh/popo/active_call_set.hpp" -#include "iceoryx_posh/popo/typed_subscriber.hpp" +#include "iceoryx_posh/popo/subscriber.hpp" #include "iceoryx_posh/popo/user_trigger.hpp" #include "iceoryx_posh/runtime/posh_runtime.hpp" #include "iceoryx_utils/posix_wrapper/semaphore.hpp" @@ -41,9 +41,9 @@ void shutdownTriggerCallback(iox::popo::UserTrigger*) keepRunning.store(false); } -void subscriberCallback(iox::popo::TypedSubscriber* subscriber) +void subscriberCallback(iox::popo::Subscriber* subscriber) { - subscriber->take_1_0().and_then([](auto& sample) { printf("received: %d\n", sample->counter); }); + subscriber->take().and_then([](auto& sample) { printf("received: %d\n", sample->counter); }); } int main() @@ -61,11 +61,11 @@ int main() // attach shutdownTrigger to handle CTRL+C callSet.attachEvent(shutdownTrigger, shutdownTriggerCallback); - iox::popo::TypedSubscriber subscriber({"Radar", "FrontLeft", "Counter"}); + iox::popo::Subscriber subscriber({"Radar", "FrontLeft", "Counter"}); subscriber.subscribe(); - callSet.attachEvent(subscriber, iox::popo::SubscriberEvent::HAS_SAMPLES, subscriberCallback); + callSet.attachEvent(subscriber, iox::popo::SubscriberEvent::HAS_DATA, subscriberCallback); while (keepRunning) { @@ -73,7 +73,7 @@ int main() } callSet.detachEvent(shutdownTrigger); - callSet.detachEvent(subscriber, iox::popo::SubscriberEvent::HAS_SAMPLES); + callSet.detachEvent(subscriber, iox::popo::SubscriberEvent::HAS_DATA); return (EXIT_SUCCESS); } From 91f8c4569462a9397fffdd7aec01445b2f45c858 Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Thu, 18 Feb 2021 15:57:41 +0100 Subject: [PATCH 063/143] iox-#408 renamed c api functions Signed-off-by: Matthias Killat --- .../include/iceoryx_binding_c/enums.h | 2 +- .../include/iceoryx_binding_c/publisher.h | 6 ++--- .../include/iceoryx_binding_c/subscriber.h | 2 +- iceoryx_binding_c/source/c_publisher.cpp | 6 ++--- iceoryx_binding_c/source/c_subscriber.cpp | 4 ++-- .../test/moduletests/test_publisher.cpp | 24 +++++++++---------- .../test/moduletests/test_subscriber.cpp | 12 +++++----- iceoryx_examples/icedelivery_in_c/README.md | 6 ++--- .../icedelivery_in_c/ice_c_publisher.c | 4 ++-- .../icedelivery_in_c/ice_c_subscriber.c | 2 +- iceoryx_examples/iceperf/iceoryx_c.cpp | 6 ++--- iceoryx_examples/waitset_in_c/README.md | 6 ++--- .../waitset_in_c/ice_c_waitset_gateway.c | 2 +- .../waitset_in_c/ice_c_waitset_grouping.c | 2 +- .../waitset_in_c/ice_c_waitset_individual.c | 2 +- .../waitset_in_c/ice_c_waitset_publisher.c | 4 ++-- 16 files changed, 45 insertions(+), 45 deletions(-) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/enums.h b/iceoryx_binding_c/include/iceoryx_binding_c/enums.h index c611808a091..9f3e37b3367 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/enums.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/enums.h @@ -38,7 +38,7 @@ enum iox_SubscribeState enum iox_ChunkReceiveResult { ChunkReceiveResult_TOO_MANY_CHUNKS_HELD_IN_PARALLEL, - ChunkReceiveResult_NO_CHUNK_RECEIVED, + ChunkReceiveResult_NO_CHUNK_AVAILABLE, ChunkReceiveResult_UNDEFINED_ERROR, ChunkReceiveResult_SUCCESS, }; diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h index 412bb758f14..382356e4592 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h @@ -49,7 +49,7 @@ void iox_pub_deinit(iox_pub_t const self); /// @param[in] payloadSize size of the allocated chunk /// @return on success it returns AllocationResult_SUCCESS otherwise a value which /// describes the error -ENUM iox_AllocationResult iox_pub_allocate_chunk(iox_pub_t const self, void** const chunk, const uint32_t payloadSize); +ENUM iox_AllocationResult iox_pub_loan_chunk(iox_pub_t const self, void** const chunk, const uint32_t payloadSize); /// @brief frees a previously allocated chunk without sending it /// @param[in] self handle of the publisher @@ -59,13 +59,13 @@ void iox_pub_free_chunk(iox_pub_t const self, void* const chunk); /// @brief sends a previously allocated chunk /// @param[in] self handle of the publisher /// @param[in] chunk chunk which should be send -void iox_pub_send_chunk(iox_pub_t const self, void* const chunk); +void iox_pub_publish_chunk(iox_pub_t const self, void* const chunk); /// @brief returns the previously sended chunk /// @param[in] self handle of the publisher /// @return nullptr if no chunk was previously send otherwise a pointer to the /// previous chunk -const void* iox_pub_try_get_previous_chunk(iox_pub_t const self); +const void* iox_pub_loan_previous_chunk(iox_pub_t const self); /// @brief offers the service /// @param[in] self handle of the publisher diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h index df6547af060..2400e1f05f8 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h @@ -64,7 +64,7 @@ ENUM iox_SubscribeState iox_sub_get_subscription_state(iox_sub_t const self); /// @param[in] chunk pointer in which the pointer to the chunk is stored /// @return if a chunk could be received it returns ChunkReceiveResult_SUCCESS otherwise /// an enum which describes the error -ENUM iox_ChunkReceiveResult iox_sub_get_chunk(iox_sub_t const self, const void** const chunk); +ENUM iox_ChunkReceiveResult iox_sub_take_chunk(iox_sub_t const self, const void** const chunk); /// @brief release a previously acquired chunk (via iox_sub_getChunk) /// @param[in] self handle to the subscriber diff --git a/iceoryx_binding_c/source/c_publisher.cpp b/iceoryx_binding_c/source/c_publisher.cpp index f29f519c4a0..1c03693f117 100644 --- a/iceoryx_binding_c/source/c_publisher.cpp +++ b/iceoryx_binding_c/source/c_publisher.cpp @@ -58,7 +58,7 @@ void iox_pub_deinit(iox_pub_t const self) self->~cpp2c_Publisher(); } -iox_AllocationResult iox_pub_allocate_chunk(iox_pub_t const self, void** const chunk, const uint32_t payloadSize) +iox_AllocationResult iox_pub_loan_chunk(iox_pub_t const self, void** const chunk, const uint32_t payloadSize) { auto result = PublisherPortUser(self->m_portData).tryAllocateChunk(payloadSize).and_then([&](ChunkHeader* h) { *chunk = h->payload(); @@ -76,12 +76,12 @@ void iox_pub_free_chunk(iox_pub_t const self, void* const chunk) PublisherPortUser(self->m_portData).releaseChunk(ChunkHeader::fromPayload(chunk)); } -void iox_pub_send_chunk(iox_pub_t const self, void* const chunk) +void iox_pub_publish_chunk(iox_pub_t const self, void* const chunk) { PublisherPortUser(self->m_portData).sendChunk(ChunkHeader::fromPayload(chunk)); } -const void* iox_pub_try_get_previous_chunk(iox_pub_t const self) +const void* iox_pub_loan_previous_chunk(iox_pub_t const self) { const void* returnValue = nullptr; PublisherPortUser(self->m_portData).tryGetPreviousChunk().and_then([&](const ChunkHeader* h) { diff --git a/iceoryx_binding_c/source/c_subscriber.cpp b/iceoryx_binding_c/source/c_subscriber.cpp index 26529751cd1..ff2c6b91544 100644 --- a/iceoryx_binding_c/source/c_subscriber.cpp +++ b/iceoryx_binding_c/source/c_subscriber.cpp @@ -78,7 +78,7 @@ iox_SubscribeState iox_sub_get_subscription_state(iox_sub_t const self) return cpp2c::SubscribeState(SubscriberPortUser(self->m_portData).getSubscriptionState()); } -iox_ChunkReceiveResult iox_sub_get_chunk(iox_sub_t const self, const void** const payload) +iox_ChunkReceiveResult iox_sub_take_chunk(iox_sub_t const self, const void** const payload) { auto result = SubscriberPortUser(self->m_portData).tryGetChunk(); if (result.has_error()) @@ -88,7 +88,7 @@ iox_ChunkReceiveResult iox_sub_get_chunk(iox_sub_t const self, const void** cons if (!result->has_value()) { - return ChunkReceiveResult_NO_CHUNK_RECEIVED; + return ChunkReceiveResult_NO_CHUNK_AVAILABLE; } *payload = (**result)->payload(); diff --git a/iceoryx_binding_c/test/moduletests/test_publisher.cpp b/iceoryx_binding_c/test/moduletests/test_publisher.cpp index 574a0748b24..6ad3bd22c7b 100644 --- a/iceoryx_binding_c/test/moduletests/test_publisher.cpp +++ b/iceoryx_binding_c/test/moduletests/test_publisher.cpp @@ -157,7 +157,7 @@ TEST_F(iox_pub_test, noSubscribersAfterUnsubscribe) TEST_F(iox_pub_test, allocateChunkForOneChunkIsSuccessful) { void* chunk = nullptr; - EXPECT_EQ(AllocationResult_SUCCESS, iox_pub_allocate_chunk(&m_sut, &chunk, sizeof(DummySample))); + EXPECT_EQ(AllocationResult_SUCCESS, iox_pub_loan_chunk(&m_sut, &chunk, sizeof(DummySample))); } TEST_F(iox_pub_test, allocate_chunkFailsWhenHoldingToManyChunksInParallel) @@ -165,10 +165,10 @@ TEST_F(iox_pub_test, allocate_chunkFailsWhenHoldingToManyChunksInParallel) void* chunk = nullptr; for (int i = 0; i < 8 /* ///@todo actually it should be MAX_CHUNKS_HELD_PER_RECEIVER but it does not work*/; ++i) { - EXPECT_EQ(AllocationResult_SUCCESS, iox_pub_allocate_chunk(&m_sut, &chunk, 100)); + EXPECT_EQ(AllocationResult_SUCCESS, iox_pub_loan_chunk(&m_sut, &chunk, 100)); } - EXPECT_EQ(AllocationResult_TOO_MANY_CHUNKS_ALLOCATED_IN_PARALLEL, iox_pub_allocate_chunk(&m_sut, &chunk, 100)); + EXPECT_EQ(AllocationResult_TOO_MANY_CHUNKS_ALLOCATED_IN_PARALLEL, iox_pub_loan_chunk(&m_sut, &chunk, 100)); } TEST_F(iox_pub_test, allocate_chunkFailsWhenOutOfChunks) @@ -184,36 +184,36 @@ TEST_F(iox_pub_test, allocate_chunkFailsWhenOutOfChunks) } void* chunk = nullptr; - EXPECT_EQ(AllocationResult_RUNNING_OUT_OF_CHUNKS, iox_pub_allocate_chunk(&m_sut, &chunk, 100)); + EXPECT_EQ(AllocationResult_RUNNING_OUT_OF_CHUNKS, iox_pub_loan_chunk(&m_sut, &chunk, 100)); } TEST_F(iox_pub_test, allocatingChunkAcquiresMemory) { void* chunk = nullptr; - iox_pub_allocate_chunk(&m_sut, &chunk, 100); + iox_pub_loan_chunk(&m_sut, &chunk, 100); EXPECT_THAT(m_memoryManager.getMemPoolInfo(0).m_usedChunks, Eq(1u)); } TEST_F(iox_pub_test, freeingAnAllocatedChunkReleasesTheMemory) { void* chunk = nullptr; - iox_pub_allocate_chunk(&m_sut, &chunk, 100); + iox_pub_loan_chunk(&m_sut, &chunk, 100); iox_pub_free_chunk(&m_sut, chunk); EXPECT_THAT(m_memoryManager.getMemPoolInfo(0).m_usedChunks, Eq(0u)); } TEST_F(iox_pub_test, noLastChunkWhenNothingSent) { - EXPECT_EQ(iox_pub_try_get_previous_chunk(&m_sut), nullptr); + EXPECT_EQ(iox_pub_loan_previous_chunk(&m_sut), nullptr); } TEST_F(iox_pub_test, lastChunkAvailableAfterSend) { void* chunk = nullptr; - iox_pub_allocate_chunk(&m_sut, &chunk, 100); - iox_pub_send_chunk(&m_sut, chunk); + iox_pub_loan_chunk(&m_sut, &chunk, 100); + iox_pub_publish_chunk(&m_sut, chunk); - const void* lastChunk = iox_pub_try_get_previous_chunk(&m_sut); + const void* lastChunk = iox_pub_loan_previous_chunk(&m_sut); EXPECT_EQ(chunk, lastChunk); } @@ -223,9 +223,9 @@ TEST_F(iox_pub_test, sendDeliversChunk) void* chunk = nullptr; iox_pub_offer(&m_sut); this->Subscribe(&m_publisherPortData); - iox_pub_allocate_chunk(&m_sut, &chunk, 100); + iox_pub_loan_chunk(&m_sut, &chunk, 100); static_cast(chunk)->dummy = 4711; - iox_pub_send_chunk(&m_sut, chunk); + iox_pub_publish_chunk(&m_sut, chunk); iox::popo::ChunkQueuePopper m_chunkQueuePopper(&m_chunkQueueData); auto maybeSharedChunk = m_chunkQueuePopper.tryPop(); diff --git a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp index 900cd321637..7d19a36ceac 100644 --- a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp +++ b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp @@ -157,7 +157,7 @@ TEST_F(iox_sub_test, UnsubscribeLeadsToUnscribeRequestedState) TEST_F(iox_sub_test, initialStateNoChunksAvailable) { const void* chunk = nullptr; - EXPECT_EQ(iox_sub_get_chunk(m_sut, &chunk), ChunkReceiveResult_NO_CHUNK_RECEIVED); + EXPECT_EQ(iox_sub_take_chunk(m_sut, &chunk), ChunkReceiveResult_NO_CHUNK_AVAILABLE); } TEST_F(iox_sub_test, receiveChunkWhenThereIsOne) @@ -166,7 +166,7 @@ TEST_F(iox_sub_test, receiveChunkWhenThereIsOne) m_chunkPusher.push(m_memoryManager.getChunk(100U)); const void* chunk = nullptr; - EXPECT_EQ(iox_sub_get_chunk(m_sut, &chunk), ChunkReceiveResult_SUCCESS); + EXPECT_EQ(iox_sub_take_chunk(m_sut, &chunk), ChunkReceiveResult_SUCCESS); } TEST_F(iox_sub_test, receiveChunkWithContent) @@ -183,7 +183,7 @@ TEST_F(iox_sub_test, receiveChunkWithContent) const void* chunk = nullptr; - ASSERT_EQ(iox_sub_get_chunk(m_sut, &chunk), ChunkReceiveResult_SUCCESS); + ASSERT_EQ(iox_sub_take_chunk(m_sut, &chunk), ChunkReceiveResult_SUCCESS); EXPECT_THAT(static_cast(chunk)->value, Eq(1234)); } @@ -194,11 +194,11 @@ TEST_F(iox_sub_test, receiveChunkWhenToManyChunksAreHold) for (uint64_t i = 0U; i < MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY + 1U; ++i) { m_chunkPusher.push(m_memoryManager.getChunk(100U)); - iox_sub_get_chunk(m_sut, &chunk); + iox_sub_take_chunk(m_sut, &chunk); } m_chunkPusher.push(m_memoryManager.getChunk(100U)); - EXPECT_EQ(iox_sub_get_chunk(m_sut, &chunk), ChunkReceiveResult_TOO_MANY_CHUNKS_HELD_IN_PARALLEL); + EXPECT_EQ(iox_sub_take_chunk(m_sut, &chunk), ChunkReceiveResult_TOO_MANY_CHUNKS_HELD_IN_PARALLEL); } TEST_F(iox_sub_test, releaseChunkWorks) @@ -207,7 +207,7 @@ TEST_F(iox_sub_test, releaseChunkWorks) m_chunkPusher.push(m_memoryManager.getChunk(100U)); const void* chunk = nullptr; - iox_sub_get_chunk(m_sut, &chunk); + iox_sub_take_chunk(m_sut, &chunk); EXPECT_THAT(m_memoryManager.getMemPoolInfo(0).m_usedChunks, Eq(1U)); iox_sub_release_chunk(m_sut, chunk); diff --git a/iceoryx_examples/icedelivery_in_c/README.md b/iceoryx_examples/icedelivery_in_c/README.md index d5408d777c7..949dc573067 100644 --- a/iceoryx_examples/icedelivery_in_c/README.md +++ b/iceoryx_examples/icedelivery_in_c/README.md @@ -67,7 +67,7 @@ Let's take a look at the `receiving` function which comes with the if (SubscribeState_SUBSCRIBED == iox_sub_get_subscription_state(subscriber)) { const void* chunk = NULL; - while (ChunkReceiveResult_SUCCESS == iox_sub_get_chunk(subscriber, &chunk)) + while (ChunkReceiveResult_SUCCESS == iox_sub_take_chunk(subscriber, &chunk)) { const struct RadarObject* sample = (const struct RadarObject*)(chunk); printf("Got value: %.0f\n", sample->x); @@ -135,7 +135,7 @@ Let's take a look at the `sending` function which comes with the while (!killswitch) { void* chunk = NULL; - if (AllocationResult_SUCCESS == iox_pub_allocate_chunk(publisher, &chunk, sizeof(struct RadarObject))) + if (AllocationResult_SUCCESS == iox_pub_loan_chunk(publisher, &chunk, sizeof(struct RadarObject))) { struct RadarObject* sample = (struct RadarObject*)chunk; @@ -145,7 +145,7 @@ Let's take a look at the `sending` function which comes with the printf("Sent value: %.0f\n", ct); - iox_pub_send_chunk(publisher, chunk); + iox_pub_publish_chunk(publisher, chunk); ++ct; diff --git a/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c b/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c index e2e3a19ce59..28ccc5889d9 100644 --- a/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c +++ b/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c @@ -48,7 +48,7 @@ void sending() while (!killswitch) { void* chunk = NULL; - if (AllocationResult_SUCCESS == iox_pub_allocate_chunk(publisher, &chunk, sizeof(struct RadarObject))) + if (AllocationResult_SUCCESS == iox_pub_loan_chunk(publisher, &chunk, sizeof(struct RadarObject))) { struct RadarObject* sample = (struct RadarObject*)chunk; @@ -58,7 +58,7 @@ void sending() printf("Sent value: %.0f\n", ct); - iox_pub_send_chunk(publisher, chunk); + iox_pub_publish_chunk(publisher, chunk); ++ct; diff --git a/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c b/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c index 324e1b802a1..0765b80b263 100644 --- a/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c +++ b/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c @@ -56,7 +56,7 @@ void receiving() const void* chunk = NULL; // we will receive here more then one sample since the publisher is sending a // new sample every 400ms and we check for new samples only every second - while (ChunkReceiveResult_SUCCESS == iox_sub_get_chunk(subscriber, &chunk)) + while (ChunkReceiveResult_SUCCESS == iox_sub_take_chunk(subscriber, &chunk)) { const struct RadarObject* sample = (const struct RadarObject*)(chunk); printf("Got value: %.0f\n", sample->x); diff --git a/iceoryx_examples/iceperf/iceoryx_c.cpp b/iceoryx_examples/iceperf/iceoryx_c.cpp index 32d67f4d1b3..945051d80ca 100644 --- a/iceoryx_examples/iceperf/iceoryx_c.cpp +++ b/iceoryx_examples/iceperf/iceoryx_c.cpp @@ -78,13 +78,13 @@ void IceoryxC::shutdown() noexcept void IceoryxC::sendPerfTopic(uint32_t payloadSizeInBytes, bool runFlag) noexcept { void* chunk = nullptr; - if (iox_pub_allocate_chunk(m_publisher, &chunk, payloadSizeInBytes) == AllocationResult_SUCCESS) + if (iox_pub_loan_chunk(m_publisher, &chunk, payloadSizeInBytes) == AllocationResult_SUCCESS) { auto sendSample = static_cast(chunk); sendSample->payloadSize = payloadSizeInBytes; sendSample->run = runFlag; sendSample->subPackets = 1; - iox_pub_send_chunk(m_publisher, chunk); + iox_pub_publish_chunk(m_publisher, chunk); } } @@ -96,7 +96,7 @@ PerfTopic IceoryxC::receivePerfTopic() noexcept do { const void* sample = nullptr; - if (iox_sub_get_chunk(m_subscriber, &sample) == ChunkReceiveResult_SUCCESS) + if (iox_sub_take_chunk(m_subscriber, &sample) == ChunkReceiveResult_SUCCESS) { receivedSample = *(static_cast(sample)); hasReceivedSample = true; diff --git a/iceoryx_examples/waitset_in_c/README.md b/iceoryx_examples/waitset_in_c/README.md index 02185f79585..1f02adffced 100644 --- a/iceoryx_examples/waitset_in_c/README.md +++ b/iceoryx_examples/waitset_in_c/README.md @@ -30,7 +30,7 @@ prints out the subscriber pointer and the content of the received sample. void subscriberCallback(iox_sub_t const subscriber) { const void* chunk; - if (iox_sub_get_chunk(subscriber, &chunk)) + if (iox_sub_take_chunk(subscriber, &chunk)) { printf("subscriber: %p received %u\n", subscriber, ((struct CounterTopic*)chunk)->counter); @@ -203,7 +203,7 @@ for (uint64_t i = 0U; i < numberOfEvents; ++i) { iox_sub_t subscriber = iox_event_info_get_subscriber_origin(event); const void* chunk; - if (iox_sub_get_chunk(subscriber, &chunk)) + if (iox_sub_take_chunk(subscriber, &chunk)) { printf("received: %u\n", ((struct CounterTopic*)chunk)->counter); @@ -295,7 +295,7 @@ originated from the second subscriber we discard the data. else if (iox_event_info_does_originate_from_subscriber(event, subscriber[0])) { const void* chunk; - if (iox_sub_get_chunk(subscriber[0], &chunk)) + if (iox_sub_take_chunk(subscriber[0], &chunk)) { printf("subscriber 1 received: %u\n", ((struct CounterTopic*)chunk)->counter); diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c index 3a0e37a35af..9b89eac2f79 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c @@ -47,7 +47,7 @@ static void sigHandler(int signalValue) void subscriberCallback(iox_sub_t const subscriber) { const void* chunk; - if (iox_sub_get_chunk(subscriber, &chunk)) + if (iox_sub_take_chunk(subscriber, &chunk)) { printf("subscriber: %p received %u\n", subscriber, ((struct CounterTopic*)chunk)->counter); diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c index 35e77dd2622..a332bc3b88d 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c @@ -113,7 +113,7 @@ int main() { iox_sub_t subscriber = iox_event_info_get_subscriber_origin(event); const void* chunk; - if (iox_sub_get_chunk(subscriber, &chunk)) + if (iox_sub_take_chunk(subscriber, &chunk)) { printf("received: %u\n", ((struct CounterTopic*)chunk)->counter); diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c index 4918debb76c..d59bfc8c22a 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c @@ -103,7 +103,7 @@ int main() else if (iox_event_info_does_originate_from_subscriber(event, subscriber[0U])) { const void* chunk; - if (iox_sub_get_chunk(subscriber[0U], &chunk)) + if (iox_sub_take_chunk(subscriber[0U], &chunk)) { printf("subscriber 1 received: %u\n", ((struct CounterTopic*)chunk)->counter); diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c index 33519b657b2..c4ccd80998f 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c @@ -46,14 +46,14 @@ void sending() for (uint32_t counter = 0U; !killswitch; ++counter) { void* chunk = NULL; - if (AllocationResult_SUCCESS == iox_pub_allocate_chunk(publisher, &chunk, sizeof(struct CounterTopic))) + if (AllocationResult_SUCCESS == iox_pub_loan_chunk(publisher, &chunk, sizeof(struct CounterTopic))) { struct CounterTopic* sample = (struct CounterTopic*)chunk; sample->counter = counter; printf("Sending: %u\n", counter); - iox_pub_send_chunk(publisher, chunk); + iox_pub_publish_chunk(publisher, chunk); sleep_for(1000); } From 21b170682c4219c79464a82392f28a3af78ecee4 Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Thu, 18 Feb 2021 16:45:45 +0100 Subject: [PATCH 064/143] iox-#408 basic chunk header support in c api Signed-off-by: Matthias Killat --- iceoryx_binding_c/CMakeLists.txt | 1 + .../include/iceoryx_binding_c/chunk.h | 42 +++++++++++++++++++ iceoryx_binding_c/source/c_chunk.cpp | 34 +++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 iceoryx_binding_c/include/iceoryx_binding_c/chunk.h create mode 100644 iceoryx_binding_c/source/c_chunk.cpp diff --git a/iceoryx_binding_c/CMakeLists.txt b/iceoryx_binding_c/CMakeLists.txt index 11f4f6b62cf..72965cf965e 100644 --- a/iceoryx_binding_c/CMakeLists.txt +++ b/iceoryx_binding_c/CMakeLists.txt @@ -53,6 +53,7 @@ add_library(${PROJECT_NAME} source/c_subscriber.cpp source/c_event_info.cpp source/c_wait_set.cpp + source/c_chunk.cpp source/cpp2c_enum_translation.cpp source/cpp2c_publisher.cpp source/cpp2c_subscriber.cpp diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/chunk.h b/iceoryx_binding_c/include/iceoryx_binding_c/chunk.h new file mode 100644 index 00000000000..3ce03458a37 --- /dev/null +++ b/iceoryx_binding_c/include/iceoryx_binding_c/chunk.h @@ -0,0 +1,42 @@ +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IOX_BINDING_C_CHUNK_H +#define IOX_BINDING_C_CHUNK_H + +#include "iceoryx_binding_c/internal/c2cpp_binding.h" + +///@todo: we will need a way to access the chunkheader properly, +/// define a structure for it and decide on functions operating on it +/// (cf. chunkheader.hpp) +/// otherwise you need C++ to do anything with the header safely + +/// consider to define void* payload_t as well + +/// @brief handle of the chunk header +typedef void* iox_chunk_header_t; + +/// @brief gets the payload from the chunk header +/// @param[in] pointer to the chunk header +/// @return pointer to the payload +void* iox_chunk_header_to_payload(iox_chunk_header_t const header); + +/// @brief gets the chunk header from the payload +/// @param[in] pointer to the payload +/// @return pointer to the chunk header +iox_chunk_header_t iox_chunk_payload_to_header(const void* const payload); + +#endif \ No newline at end of file diff --git a/iceoryx_binding_c/source/c_chunk.cpp b/iceoryx_binding_c/source/c_chunk.cpp new file mode 100644 index 00000000000..4d3a997e7cb --- /dev/null +++ b/iceoryx_binding_c/source/c_chunk.cpp @@ -0,0 +1,34 @@ +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +#include "iceoryx_posh/mepoo/chunk_header.hpp" + + +extern "C" { +#include "iceoryx_binding_c/chunk.h" +} + +using namespace iox::mepoo; + +void* iox_chunk_header_to_payload(iox_chunk_header_t const header) +{ + return reinterpret_cast(header)->payload(); +} + +iox_chunk_header_t iox_chunk_payload_to_header(const void* const payload) +{ + return ChunkHeader::fromPayload(payload); +} From 19dda101c3427b7602d0e5ede9aeb0cfe326f80d Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Thu, 18 Feb 2021 18:13:32 +0100 Subject: [PATCH 065/143] iox-#350 fix review findings Signed-off-by: Marika Lehmann --- .../iceoryx_posh/iceoryx_posh_types.hpp | 4 +- .../popo/building_blocks/event_listener.hpp | 4 +- .../popo/building_blocks/event_listener.cpp | 10 +- .../popo/building_blocks/event_notifier.cpp | 5 +- iceoryx_posh/source/roudi/roudi.cpp | 3 - .../moduletests/test_popo_event_variable.cpp | 94 ++++++++++--------- .../moduletests/test_roudi_portmanager.cpp | 6 +- .../error_handling/error_handling.hpp | 3 +- 8 files changed, 68 insertions(+), 61 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp b/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp index 9a598d5ca47..800a1a9acbb 100644 --- a/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp +++ b/iceoryx_posh/include/iceoryx_posh/iceoryx_posh_types.hpp @@ -103,8 +103,8 @@ constexpr uint32_t MAX_REQUEST_QUEUE_CAPACITY = 1024; constexpr uint32_t MAX_NUMBER_OF_CONDITION_VARIABLES = 1024U; constexpr uint32_t MAX_NUMBER_OF_EVENTS_PER_WAITSET = 128U; // ActiveCallSet -constexpr uint32_t MAX_NUMBER_OF_EVENT_VARIABLES = 128U; -constexpr uint32_t MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET = 128U; +constexpr uint8_t MAX_NUMBER_OF_EVENT_VARIABLES = 128U; +constexpr uint8_t MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET = 128U; //--------- Communication Resources End--------------------- constexpr uint32_t MAX_APPLICATION_CAPRO_FIFO_SIZE = 128U; diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp index c8ca6ead3c2..43178e4410d 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp @@ -42,7 +42,9 @@ class EventListener /// never empty unless destroy() was called, then it's always empty. /// /// @return vector of active notifications - cxx::vector wait() noexcept; + cxx::vector::type, + MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET> + wait() noexcept; /// @brief Used in classes to signal a thread which waits in wait() to return /// and stop working. Destroy will send an empty notification to wait() and diff --git a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp index 5a238cbbd75..b1391ab8994 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp @@ -35,14 +35,18 @@ void EventListener::destroy() noexcept } } -cxx::vector EventListener::wait() noexcept +cxx::vector::type, + MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET> +EventListener::wait() noexcept { - cxx::vector activeNotifications; + cxx::vector::type, + MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET> + activeNotifications; resetSemaphore(); while (!m_toBeDestroyed.load(std::memory_order_relaxed)) { - for (uint64_t i = 0U; i < MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; i++) + for (uint8_t i = 0U; i < MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; i++) { if (m_pointerToEventVariableData->m_activeNotifications[i].load(std::memory_order_relaxed)) { diff --git a/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp b/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp index f1ffc25c639..de7d1327264 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_notifier.cpp @@ -28,8 +28,9 @@ EventNotifier::EventNotifier(EventVariableData& dataRef, const uint64_t index) n { if (index >= MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET) { - LogWarn() << "The provided index " << index << " is too large. The index has to be in the range of [0, " - << MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET << ")."; + LogError() << "The provided index " << index << " is too large. The index has to be in the range of [0, " + << MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET << "[."; + errorHandler(Error::kPOPO__EVENT_NOTIFIER_INDEX_TOO_LARGE, nullptr, ErrorLevel::MODERATE); } } diff --git a/iceoryx_posh/source/roudi/roudi.cpp b/iceoryx_posh/source/roudi/roudi.cpp index 4fd7a11ca15..c216dc67bf1 100644 --- a/iceoryx_posh/source/roudi/roudi.cpp +++ b/iceoryx_posh/source/roudi/roudi.cpp @@ -229,8 +229,6 @@ void RouDi::processMessage(const runtime::IpcMessage& message, { LogError() << "Wrong number of parameters for \"IpcMessageType::CREATE_CONDITION_VARIABLE\" from \"" << processName << "\"received!"; - errorHandler( - Error::kPORT_MANAGER__UNABLE_TO_ACQUIRE_CONDITION_VARIABLE, nullptr, iox::ErrorLevel::MODERATE); } else { @@ -244,7 +242,6 @@ void RouDi::processMessage(const runtime::IpcMessage& message, { LogError() << "Wrong number of parameters for \"IpcMessageType::CREATE_EVENT_VARIABLE\" from \"" << processName << "\"received!"; - errorHandler(Error::kPORT_MANAGER__UNABLE_TO_ACQUIRE_EVENT_VARIABLE, nullptr, iox::ErrorLevel::MODERATE); } else { diff --git a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp index b82dc80a4a1..ce716f7bada 100644 --- a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp @@ -30,8 +30,10 @@ using namespace iox::popo; class EventVariable_test : public Test { public: - using notificationVector = iox::cxx::vector; - EventVariableData m_eventVarData{"Ferdinand"}; + using NotificationVector_t = iox::cxx::vector; + + const iox::ProcessName_t m_process{"Ferdinand"}; + EventVariableData m_eventVarData{m_process}; }; TEST_F(EventVariable_test, AllNotificationsAreFalseAfterConstruction) @@ -45,7 +47,7 @@ TEST_F(EventVariable_test, AllNotificationsAreFalseAfterConstruction) TEST_F(EventVariable_test, CorrectProcessNameAfterConstructionWithProcessName) { - EXPECT_THAT(m_eventVarData.m_process.c_str(), StrEq("Ferdinand")); + EXPECT_THAT(m_eventVarData.m_process.c_str(), StrEq(m_process)); } TEST_F(EventVariable_test, AllNotificationsAreFalseAfterConstructionWithProcessName) @@ -58,12 +60,12 @@ TEST_F(EventVariable_test, AllNotificationsAreFalseAfterConstructionWithProcessN TEST_F(EventVariable_test, NotifyActivatesCorrectIndex) { - uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; - EventNotifier sut(m_eventVarData, index); + const uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; + EventNotifier sut(m_eventVarData, EVENT_INDEX); sut.notify(); - for (uint64_t i = 0U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; i++) + for (uint8_t i = 0U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; i++) { - if (i == index) + if (i == EVENT_INDEX) { EXPECT_THAT(m_eventVarData.m_activeNotifications[i], Eq(true)); } @@ -76,8 +78,8 @@ TEST_F(EventVariable_test, NotifyActivatesCorrectIndex) TEST_F(EventVariable_test, NotifyActivatesNoIndexIfIndexIsTooLarge) { - uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; - EventNotifier sut(m_eventVarData, index); + const uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; + EventNotifier sut(m_eventVarData, EVENT_INDEX); sut.notify(); for (const auto& notification : m_eventVarData.m_activeNotifications) { @@ -87,42 +89,43 @@ TEST_F(EventVariable_test, NotifyActivatesNoIndexIfIndexIsTooLarge) TEST_F(EventVariable_test, GetCorrectNotificationVectorAfterNotifyAndWait) { - uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; - EventNotifier notifier(m_eventVarData, index); + const uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; + EventNotifier notifier(m_eventVarData, EVENT_INDEX); EventListener listener(m_eventVarData); notifier.notify(); const auto& activeNotifications = listener.wait(); ASSERT_THAT(activeNotifications.size(), Eq(1U)); - EXPECT_THAT(activeNotifications[0], Eq(index)); + EXPECT_THAT(activeNotifications[0], Eq(EVENT_INDEX)); } TEST_F(EventVariable_test, GetCorrectNotificationVectorAfterMultipleNotifyAndWait) { - uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; - EventNotifier notifier1(m_eventVarData, index); - EventNotifier notifier2(m_eventVarData, 0U); + const uint8_t FIRST_EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; + const uint8_t SECOND_EVENT_INDEX = 0U; + EventNotifier notifier1(m_eventVarData, FIRST_EVENT_INDEX); + EventNotifier notifier2(m_eventVarData, SECOND_EVENT_INDEX); EventListener listener(m_eventVarData); notifier1.notify(); notifier2.notify(); const auto& activeNotifications = listener.wait(); ASSERT_THAT(activeNotifications.size(), Eq(2U)); - EXPECT_THAT(activeNotifications[0], Eq(0U)); - EXPECT_THAT(activeNotifications[1], Eq(index)); + EXPECT_THAT(activeNotifications[0], Eq(SECOND_EVENT_INDEX)); + EXPECT_THAT(activeNotifications[1], Eq(FIRST_EVENT_INDEX)); } TEST_F(EventVariable_test, WaitAndNotifyResultsInCorrectNotificationVector) { - uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 5U; - EventNotifier notifier(m_eventVarData, index); + const uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 5U; + EventNotifier notifier(m_eventVarData, EVENT_INDEX); EventListener listener(m_eventVarData); - notificationVector activeNotifications; + NotificationVector_t activeNotifications; std::thread waiter([&] { activeNotifications = listener.wait(); ASSERT_THAT(activeNotifications.size(), Eq(1U)); - EXPECT_THAT(activeNotifications[0], Eq(index)); + EXPECT_THAT(activeNotifications[0], Eq(EVENT_INDEX)); }); notifier.notify(); @@ -130,23 +133,23 @@ TEST_F(EventVariable_test, WaitAndNotifyResultsInCorrectNotificationVector) } TIMING_TEST_F(EventVariable_test, WaitBlocks, Repeat(5), [&] { - uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 5U; - EventNotifier notifier(m_eventVarData, index); + const uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 5U; + EventNotifier notifier(m_eventVarData, EVENT_INDEX); EventListener listener(m_eventVarData); - notificationVector activeNotifications; - iox::posix::Semaphore semaphore = + NotificationVector_t activeNotifications; + iox::posix::Semaphore threadSetupSemaphore = iox::posix::Semaphore::create(iox::posix::CreateUnnamedSingleProcessSemaphore, 0U).value(); std::atomic_bool hasWaited{false}; std::thread waiter([&] { - semaphore.post(); + threadSetupSemaphore.post(); activeNotifications = listener.wait(); hasWaited.store(true, std::memory_order_relaxed); ASSERT_THAT(activeNotifications.size(), Eq(1U)); - EXPECT_THAT(activeNotifications[0], Eq(index)); + EXPECT_THAT(activeNotifications[0], Eq(EVENT_INDEX)); }); - semaphore.wait(); + threadSetupSemaphore.wait(); std::this_thread::sleep_for(std::chrono::milliseconds(10)); EXPECT_THAT(hasWaited, Eq(false)); notifier.notify(); @@ -156,30 +159,31 @@ TIMING_TEST_F(EventVariable_test, WaitBlocks, Repeat(5), [&] { }) TIMING_TEST_F(EventVariable_test, SecondWaitBlocksUntilNewNotification, Repeat(5), [&] { - uint64_t index = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 2U; - EventNotifier notifier1(m_eventVarData, index); - EventNotifier notifier2(m_eventVarData, 0U); + const uint8_t FIRST_EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 2U; + const uint8_t SECOND_EVENT_INDEX = 0U; + EventNotifier notifier1(m_eventVarData, FIRST_EVENT_INDEX); + EventNotifier notifier2(m_eventVarData, SECOND_EVENT_INDEX); EventListener listener(m_eventVarData); - iox::posix::Semaphore semaphore = + iox::posix::Semaphore threadSetupSemaphore = iox::posix::Semaphore::create(iox::posix::CreateUnnamedSingleProcessSemaphore, 0U).value(); std::atomic_bool hasWaited{false}; notifier1.notify(); notifier2.notify(); - notificationVector activeNotifications = listener.wait(); + NotificationVector_t activeNotifications = listener.wait(); ASSERT_THAT(activeNotifications.size(), Eq(2U)); - EXPECT_THAT(activeNotifications[0], Eq(0U)); - EXPECT_THAT(activeNotifications[1], Eq(index)); + EXPECT_THAT(activeNotifications[0], Eq(SECOND_EVENT_INDEX)); + EXPECT_THAT(activeNotifications[1], Eq(FIRST_EVENT_INDEX)); std::thread waiter([&] { - semaphore.post(); + threadSetupSemaphore.post(); activeNotifications = listener.wait(); hasWaited.store(true, std::memory_order_relaxed); ASSERT_THAT(activeNotifications.size(), Eq(1U)); - EXPECT_THAT(activeNotifications[0], Eq(index)); + EXPECT_THAT(activeNotifications[0], Eq(FIRST_EVENT_INDEX)); }); - semaphore.wait(); + threadSetupSemaphore.wait(); std::this_thread::sleep_for(std::chrono::milliseconds(10)); EXPECT_THAT(hasWaited, Eq(false)); notifier1.notify(); @@ -190,16 +194,16 @@ TIMING_TEST_F(EventVariable_test, SecondWaitBlocksUntilNewNotification, Repeat(5 TEST_F(EventVariable_test, AllEntriesAreResetToFalseInsideWait) { - uint64_t index1 = 3U; - uint64_t index2 = 1U; - EventNotifier notifier1(m_eventVarData, index1); - EventNotifier notifier2(m_eventVarData, index2); + const uint8_t FIRST_EVENT_INDEX = 3U; + const uint8_t SECOND_EVENT_INDEX = 1U; + EventNotifier notifier1(m_eventVarData, FIRST_EVENT_INDEX); + EventNotifier notifier2(m_eventVarData, SECOND_EVENT_INDEX); EventListener listener(m_eventVarData); notifier1.notify(); - ASSERT_THAT(m_eventVarData.m_activeNotifications[index1], Eq(true)); + ASSERT_THAT(m_eventVarData.m_activeNotifications[FIRST_EVENT_INDEX], Eq(true)); notifier2.notify(); - ASSERT_THAT(m_eventVarData.m_activeNotifications[index2], Eq(true)); + ASSERT_THAT(m_eventVarData.m_activeNotifications[SECOND_EVENT_INDEX], Eq(true)); const auto& activeNotifications = listener.wait(); EXPECT_THAT(activeNotifications.size(), Eq(2U)); @@ -234,7 +238,7 @@ TEST_F(EventVariable_test, DestroyWakesUpWaitWhichReturnsEmptyVector) { EventListener sut(m_eventVarData); - notificationVector activeNotifications; + NotificationVector_t activeNotifications; std::thread waiter([&] { activeNotifications = sut.wait(); diff --git a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp index ce5b2e99425..34a2abde4db 100644 --- a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp +++ b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp @@ -130,11 +130,11 @@ class PortManager_test : public Test for (unsigned int i = 0U; i < iox::MAX_NUMBER_OF_EVENT_VARIABLES; i++) { iox::ProcessName_t newProcessName(iox::cxx::TruncateToCapacity, process + std::to_string(i)); - auto eventVariableData = m_portManager->acquireEventVariableData(newProcessName); - ASSERT_THAT(eventVariableData.has_error(), Eq(false)); + auto eventVariableDataResult = m_portManager->acquireEventVariableData(newProcessName); + ASSERT_THAT(eventVariableDataResult.has_error(), Eq(false)); if (f) { - f(eventVariableData.value()); + f(eventVariableDataResult.value()); } } } diff --git a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp index a81a8c5fa52..fbafb1d6c64 100644 --- a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp +++ b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp @@ -86,6 +86,7 @@ namespace iox error(POPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_DESTROY) \ error(POPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_WAIT) \ error(POPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_RESET) \ + error(POPO__EVENT_NOTIFIER_INDEX_TOO_LARGE) \ error(POPO__TYPED_UNIQUE_ID_ROUDI_HAS_NO_DEFINED_UNIQUE_ID) \ error(POPO__TYPED_UNIQUE_ID_ROUDI_HAS_ALREADY_DEFINED_UNIQUE_ID) \ error(POPO__TYPED_UNIQUE_ID_OVERFLOW) \ @@ -119,8 +120,6 @@ namespace iox error(PORT_MANAGER__NO_PUBLISHER_PORT_FOR_INTROSPECTIONPORTTHROUGHPUTSERVICE) \ error(PORT_MANAGER__NO_PUBLISHER_PORT_FOR_INTROSPECTIONCHANGINGDATASERVICE) \ error(PORT_MANAGER__NO_PUBLISHER_PORT_FOR_INTROSPECTION_SENDER_PORT) \ - error(PORT_MANAGER__UNABLE_TO_ACQUIRE_CONDITION_VARIABLE) \ - error(PORT_MANAGER__UNABLE_TO_ACQUIRE_EVENT_VARIABLE) \ error(ROUDI_COMPONENTS__SHARED_MEMORY_UNAVAILABLE) \ error(ROUDI_MEMORY__COULD_NOT_REGISTER_SIGBUS) \ error(ROUDI_MEMORY__COULD_NOT_UNREGISTER_SIGBUS) \ From f02b0ff912ff88125354f15e7a7e4f9a71190052 Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Fri, 19 Feb 2021 10:25:41 +0100 Subject: [PATCH 066/143] iox-#408 publisher options c api Signed-off-by: Matthias Killat --- .../include/iceoryx_binding_c/publisher.h | 15 +++++++++++---- iceoryx_binding_c/source/c_publisher.cpp | 11 +++++------ iceoryx_examples/icedelivery_in_c/README.md | 7 ++++--- .../icedelivery_in_c/ice_c_publisher.c | 7 ++++--- iceoryx_examples/iceperf/iceoryx_c.cpp | 11 +++++++++-- .../waitset_in_c/ice_c_waitset_publisher.c | 7 ++++--- 6 files changed, 37 insertions(+), 21 deletions(-) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h index 382356e4592..4ab2871572c 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h @@ -24,20 +24,27 @@ /// @brief publisher handle typedef struct cpp2c_Publisher* iox_pub_t; +/// @brief options to be set for a publisher +typedef struct +{ + // size of the history chunk queue + uint64_t historyCapacity; + + // name of the node the publisher belongs to + const char* nodeName; +} iox_publisher_options_t; + /// @brief creates a publisher handle /// @param[in] self pointer to preallocated memory of size = sizeof(iox_pub_storage_t) /// @param[in] service serviceString /// @param[in] instance instanceString /// @param[in] event eventString -/// @param[in] historyCapacity size of the history chunk queue -/// @param[in] nodeName name of the node the publisher belongs to /// @return handle of the publisher iox_pub_t iox_pub_init(iox_pub_storage_t* self, const char* const service, const char* const instance, const char* const event, - const uint64_t historyCapacity, - const char* const nodeName); + const iox_publisher_options_t options); /// @brief removes a publisher handle /// @param[in] self the handle which should be removed diff --git a/iceoryx_binding_c/source/c_publisher.cpp b/iceoryx_binding_c/source/c_publisher.cpp index 1c03693f117..a0983e2b1cf 100644 --- a/iceoryx_binding_c/source/c_publisher.cpp +++ b/iceoryx_binding_c/source/c_publisher.cpp @@ -34,21 +34,20 @@ iox_pub_t iox_pub_init(iox_pub_storage_t* self, const char* const service, const char* const instance, const char* const event, - const uint64_t historyCapacity, - const char* const nodeName) + const iox_publisher_options_t options) { new (self) cpp2c_Publisher(); iox_pub_t me = reinterpret_cast(self); - PublisherOptions options; - options.historyCapacity = historyCapacity; - options.nodeName = NodeName_t(TruncateToCapacity, nodeName); + PublisherOptions publisherOptions; + publisherOptions.historyCapacity = options.historyCapacity; + publisherOptions.nodeName = NodeName_t(TruncateToCapacity, options.nodeName); me->m_portData = PoshRuntime::getInstance().getMiddlewarePublisher( ServiceDescription{ IdString_t(TruncateToCapacity, service), IdString_t(TruncateToCapacity, instance), IdString_t(TruncateToCapacity, event), }, - options); + publisherOptions); return me; } diff --git a/iceoryx_examples/icedelivery_in_c/README.md b/iceoryx_examples/icedelivery_in_c/README.md index 949dc573067..65b2c85a60a 100644 --- a/iceoryx_examples/icedelivery_in_c/README.md +++ b/iceoryx_examples/icedelivery_in_c/README.md @@ -116,10 +116,11 @@ Let's take a look at the `sending` function which comes with the 2. We create a publisher with the service {"Radar", "FrontLeft", "Counter"} ```c - const uint64_t historyRequest = 10U; - const char* const nodeName = "iox-c-publisher-node"; + iox_publisher_options_t options; + options.historyCapacity = 10U; + options.nodeName = "iox-c-publisher-node"; iox_pub_storage_t publisherStorage; - iox_pub_t publisher = iox_pub_init(&publisherStorage, "Radar", "FrontLeft", "Object", historyRequest, nodeName); + iox_pub_t publisher = iox_pub_init(&publisherStorage, "Radar", "FrontLeft", "Object", options); ``` 3. We offer our service to the world. ```c diff --git a/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c b/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c index 28ccc5889d9..016b1b9c768 100644 --- a/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c +++ b/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c @@ -36,10 +36,11 @@ void sending() { iox_runtime_init("iox-c-publisher"); - const uint64_t historyCapacity = 10U; - const char* const nodeName = "iox-c-publisher-node"; + iox_publisher_options_t options; + options.historyCapacity = 10U; + options.nodeName = "iox-c-publisher-node"; iox_pub_storage_t publisherStorage; - iox_pub_t publisher = iox_pub_init(&publisherStorage, "Radar", "FrontLeft", "Object", historyCapacity, nodeName); + iox_pub_t publisher = iox_pub_init(&publisherStorage, "Radar", "FrontLeft", "Object", options); iox_pub_offer(publisher); diff --git a/iceoryx_examples/iceperf/iceoryx_c.cpp b/iceoryx_examples/iceperf/iceoryx_c.cpp index 945051d80ca..01dec1f3e6d 100644 --- a/iceoryx_examples/iceperf/iceoryx_c.cpp +++ b/iceoryx_examples/iceperf/iceoryx_c.cpp @@ -20,9 +20,16 @@ #include IceoryxC::IceoryxC(const iox::capro::IdString_t& publisherName, const iox::capro::IdString_t& subscriberName) noexcept - : m_publisher(iox_pub_init(&m_publisherStorage, "Comedians", publisherName.c_str(), "Duo", 0U, "Slapstick")) - , m_subscriber(iox_sub_init(&m_subscriberStorage, "Comedians", subscriberName.c_str(), "Duo", 10U, 0U, "Slapstick")) { + iox_publisher_options_t publisherOptions; + publisherOptions.historyCapacity = 0U; + publisherOptions.nodeName = "SlapStick"; + m_publisher = iox_pub_init(&m_publisherStorage, "Comedians", publisherName.c_str(), "Duo", publisherOptions); + + // iox_subscriber_options_t subscriberOptions; + // subscriberOptions.historyCapacity = 0U; + // subscriberOptions.nodeName = "SlapStick"; + m_subscriber = iox_sub_init(&m_subscriberStorage, "Comedians", subscriberName.c_str(), "Duo", 10U, 0U, "Slapstick"); } IceoryxC::~IceoryxC() diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c index c4ccd80998f..ccc0672acbc 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c @@ -36,10 +36,11 @@ void sending() { iox_runtime_init("iox-c-ex-waitset-publisher"); - const uint64_t historyCapacity = 0U; - const char* const nodeName = "iox-c-ex-waitset-publisher-node"; + iox_publisher_options_t options; + options.historyCapacity = 0U; + options.nodeName = "iox-c-ex-waitset-publisher-node"; iox_pub_storage_t publisherStorage; - iox_pub_t publisher = iox_pub_init(&publisherStorage, "Radar", "FrontLeft", "Counter", historyCapacity, nodeName); + iox_pub_t publisher = iox_pub_init(&publisherStorage, "Radar", "FrontLeft", "Counter", options); iox_pub_offer(publisher); From cff149a3b37d719cc2c1c18139fede5ecb142223 Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Fri, 19 Feb 2021 10:56:16 +0100 Subject: [PATCH 067/143] iox-#408 subscriber options c api Signed-off-by: Matthias Killat --- .../include/iceoryx_binding_c/publisher.h | 2 + .../include/iceoryx_binding_c/subscriber.h | 22 ++++++++--- iceoryx_binding_c/source/c_subscriber.cpp | 14 +++---- iceoryx_examples/icedelivery_in_c/README.md | 10 +++-- .../icedelivery_in_c/ice_c_subscriber.c | 9 +++-- iceoryx_examples/iceperf/iceoryx_c.cpp | 9 +++-- iceoryx_examples/waitset_in_c/README.md | 37 +++++++++++-------- .../waitset_in_c/ice_c_waitset_gateway.c | 10 +++-- .../waitset_in_c/ice_c_waitset_grouping.c | 9 +++-- .../waitset_in_c/ice_c_waitset_individual.c | 17 +++++---- 10 files changed, 82 insertions(+), 57 deletions(-) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h index 4ab2871572c..77d04057300 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h @@ -39,7 +39,9 @@ typedef struct /// @param[in] service serviceString /// @param[in] instance instanceString /// @param[in] event eventString +/// @param[in] options publisher options set by the user /// @return handle of the publisher +/// @attention the options must be set to valid values iox_pub_t iox_pub_init(iox_pub_storage_t* self, const char* const service, const char* const instance, diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h index 2400e1f05f8..35f75b291f7 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h @@ -24,22 +24,32 @@ /// @brief Subscriber handle typedef struct cpp2c_Subscriber* iox_sub_t; +/// @brief options to be set for a subscriber +typedef struct +{ + // size of the history chunk queue + uint64_t queueCapacity; + + // number of chunks received after subscription if chunks are available + uint64_t historyRequest; + + // name of the node the publisher belongs to + const char* nodeName; +} iox_subscriber_options_t; + /// @brief initialize subscriber handle /// @param[in] self pointer to preallocated memory of size = sizeof(iox_sub_storage_t) /// @param[in] service serviceString /// @param[in] instance instanceString /// @param[in] event eventString -/// @param[in] queueCapacity size of the receiver queue -/// @param[in] historyRequest of chunks received after subscription if chunks are available -/// @param[in] nodeName name of node where the subscriber belongs to +/// @param[in] options publisher options set by the user /// @return handle of the subscriber +/// @attention the options must be set to valid values iox_sub_t iox_sub_init(iox_sub_storage_t* self, const char* const service, const char* const instance, const char* const event, - const uint64_t queueCapacity, - const uint64_t historyRequest, - const char* const nodeName); + const iox_subscriber_options_t options); /// @brief deinitialize a subscriber handle /// @param[in] self the handle which should be removed diff --git a/iceoryx_binding_c/source/c_subscriber.cpp b/iceoryx_binding_c/source/c_subscriber.cpp index ff2c6b91544..5f99f108e7f 100644 --- a/iceoryx_binding_c/source/c_subscriber.cpp +++ b/iceoryx_binding_c/source/c_subscriber.cpp @@ -39,21 +39,19 @@ iox_sub_t iox_sub_init(iox_sub_storage_t* self, const char* const service, const char* const instance, const char* const event, - const uint64_t queueCapacity, - const uint64_t historyRequest, - const char* const nodeName) + const iox_subscriber_options_t options) { new (self) cpp2c_Subscriber(); iox_sub_t me = reinterpret_cast(self); - SubscriberOptions options; - options.queueCapacity = queueCapacity; - options.historyRequest = historyRequest; - options.nodeName = NodeName_t(TruncateToCapacity, nodeName); + SubscriberOptions subscriberOptions; + subscriberOptions.queueCapacity = options.queueCapacity; + subscriberOptions.historyRequest = options.historyRequest; + subscriberOptions.nodeName = NodeName_t(TruncateToCapacity, options.nodeName); me->m_portData = PoshRuntime::getInstance().getMiddlewareSubscriber(ServiceDescription{IdString_t(TruncateToCapacity, service), IdString_t(TruncateToCapacity, instance), IdString_t(TruncateToCapacity, event)}, - options); + subscriberOptions); return me; } diff --git a/iceoryx_examples/icedelivery_in_c/README.md b/iceoryx_examples/icedelivery_in_c/README.md index 65b2c85a60a..95415954011 100644 --- a/iceoryx_examples/icedelivery_in_c/README.md +++ b/iceoryx_examples/icedelivery_in_c/README.md @@ -46,11 +46,13 @@ Let's take a look at the `receiving` function which comes with the The `subscriberStorage` is the place where the subscriber is stored in memory and `subscriber` is actually a pointer to that location. ```c - const uint64_t historyRequest = 10U; - const uint64_t queueCapacity = 5U; - const char* const nodeName = "iox-c-subscriber-node"; + iox_subscriber_options_t options; + options.historyRequest = 10U; + options.queueCapacity = 5U; + options.nodeName = "iox-c-subscriber-node"; + iox_sub_storage_t subscriberStorage; - iox_sub_t subscriber = iox_sub_init(&subscriberStorage, "Radar", "FrontLeft", "Object", queueCapacity, historyRequest, nodeName); + iox_sub_t subscriber = iox_sub_init(&subscriberStorage, "Radar", "FrontLeft", "Object", options); ``` 3. We subscribe to the service. diff --git a/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c b/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c index 0765b80b263..efa8fe27c34 100644 --- a/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c +++ b/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c @@ -40,13 +40,14 @@ void receiving() // When starting the subscriber late it will miss the first samples which the // publisher has send. The history ensures that we at least get the last 10 // samples send by the publisher when we subscribe. - const uint64_t historyRequest = 10U; - const uint64_t queueCapacity = 5U; - const char* const nodeName = "iox-c-subscriber-node"; + iox_subscriber_options_t options; + options.historyRequest = 10U; + options.queueCapacity = 5U; + options.nodeName = "iox-c-subscriber-node"; iox_sub_storage_t subscriberStorage; iox_sub_t subscriber = - iox_sub_init(&subscriberStorage, "Radar", "FrontLeft", "Object", queueCapacity, historyRequest, nodeName); + iox_sub_init(&subscriberStorage, "Radar", "FrontLeft", "Object", options); iox_sub_subscribe(subscriber); while (!killswitch) diff --git a/iceoryx_examples/iceperf/iceoryx_c.cpp b/iceoryx_examples/iceperf/iceoryx_c.cpp index 01dec1f3e6d..a514b1dd082 100644 --- a/iceoryx_examples/iceperf/iceoryx_c.cpp +++ b/iceoryx_examples/iceperf/iceoryx_c.cpp @@ -26,10 +26,11 @@ IceoryxC::IceoryxC(const iox::capro::IdString_t& publisherName, const iox::capro publisherOptions.nodeName = "SlapStick"; m_publisher = iox_pub_init(&m_publisherStorage, "Comedians", publisherName.c_str(), "Duo", publisherOptions); - // iox_subscriber_options_t subscriberOptions; - // subscriberOptions.historyCapacity = 0U; - // subscriberOptions.nodeName = "SlapStick"; - m_subscriber = iox_sub_init(&m_subscriberStorage, "Comedians", subscriberName.c_str(), "Duo", 10U, 0U, "Slapstick"); + iox_subscriber_options_t subscriberOptions; + subscriberOptions.queueCapacity = 10U; + subscriberOptions.historyRequest = 0U; + subscriberOptions.nodeName = "Slapstick"; + m_subscriber = iox_sub_init(&m_subscriberStorage, "Comedians", subscriberName.c_str(), "Duo", subscriberOptions); } IceoryxC::~IceoryxC() diff --git a/iceoryx_examples/waitset_in_c/README.md b/iceoryx_examples/waitset_in_c/README.md index 1f02adffced..194648b0835 100644 --- a/iceoryx_examples/waitset_in_c/README.md +++ b/iceoryx_examples/waitset_in_c/README.md @@ -58,12 +58,13 @@ the `subscriberCallback` and an event id `1U`. ```c iox_sub_storage_t subscriberStorage[NUMBER_OF_SUBSCRIBERS]; -const uint64_t historyRequest = 1U; -const uint64_t queueCapacity = 256U; -const char* const nodeName = "iox-c-ex-waitSet-gateway-node"; +iox_subscriber_options_t options; +options.historyRequest = 1U; +options.queueCapacity = 256U; +options.nodeName = "iox-c-ex-waitSet-gateway-node"; for (uint64_t i = 0U; i < NUMBER_OF_SUBSCRIBERS; ++i) { - iox_sub_t subscriber = iox_sub_init(&(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", queueCapacity, historyRequest, nodeName); + iox_sub_t subscriber = iox_sub_init(&(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", options); iox_sub_subscribe(subscriber); iox_ws_attach_subscriber_event(waitSet, subscriber, SubscriberEvent_HAS_DATA, 1U, subscriberCallback); @@ -141,12 +142,13 @@ After that we can create a list of subscribers and subscribe them to our topic. iox_sub_storage_t subscriberStorage[NUMBER_OF_SUBSCRIBERS]; iox_sub_t subscriber[NUMBER_OF_SUBSCRIBERS]; -const uint64_t historyRequest = 1U; -const uint64_t queueCapacity = 256U; -const char* const nodeName = "iox-c-ex-waitset-grouping-node"; +iox_subscriber_options_t options; +options.historyRequest = 1U; +options.queueCapacity = 256U; +options.nodeName = "iox-c-ex-waitset-grouping-node"; for (uint64_t i = 0U; i < NUMBER_OF_SUBSCRIBERS; ++i) { - subscriber[i] = iox_sub_init(&(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", queueCapacity, historyRequest, nodeName); + subscriber[i] = iox_sub_init(&(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", options); iox_sub_subscribe(subscriber[i]); } @@ -252,14 +254,17 @@ iox_ws_attach_user_trigger_event(waitSet, shutdownTrigger, 0U, NULL); Now we create two subscriber, subscribe them to our topic and attach them to the waitset without a callback and with the same trigger id. ```c -const uint64_t historyRequest = 1U; -const uint64_t queueCapacity = 256U; - -const char* const nodeName1 = "iox-c-ex-waitset-individual-node1"; -const char* const nodeName2 = "iox-c-ex-waitset-individual-node2"; - -subscriber[0] = iox_sub_init(&(subscriberStorage[0]), "Radar", "FrontLeft", "Counter", queueCapacity, historyRequest, nodeName1); -subscriber[1] = iox_sub_init(&(subscriberStorage[1]), "Radar", "FrontLeft", "Counter", queueCapacity, historyRequest, nodeName2); +iox_subscriber_options_t options1, options2; +options1.historyRequest = 1U; +options1.queueCapacity = 256U; +options1.nodeName = "iox-c-ex-waitset-individual-node1"; + +options2.historyRequest = 1U; +options2.queueCapacity = 256U; +options2.nodeName = "iox-c-ex-waitset-individual-node2"; + +subscriber[0] = iox_sub_init(&(subscriberStorage[0]), "Radar", "FrontLeft", "Counter", options1); +subscriber[1] = iox_sub_init(&(subscriberStorage[1]), "Radar", "FrontLeft", "Counter", options2); iox_sub_subscribe(subscriber[0]); iox_sub_subscribe(subscriber[1]); diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c index 9b89eac2f79..9b80c862921 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c @@ -73,13 +73,15 @@ int main() iox_sub_storage_t subscriberStorage[NUMBER_OF_SUBSCRIBERS]; // create subscriber and subscribe them to our service - const uint64_t historyRequest = 1U; - const uint64_t queueCapacity = 256U; - const char* const nodeName = "iox-c-ex-waitSet-gateway-node"; + + iox_subscriber_options_t options; + options.historyRequest = 1U; + options.queueCapacity = 256U; + options.nodeName = "iox-c-ex-waitSet-gateway-node"; for (uint64_t i = 0U; i < NUMBER_OF_SUBSCRIBERS; ++i) { iox_sub_t subscriber = iox_sub_init( - &(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", queueCapacity, historyRequest, nodeName); + &(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", options); iox_sub_subscribe(subscriber); iox_ws_attach_subscriber_event(waitSet, subscriber, SubscriberEvent_HAS_DATA, 1U, subscriberCallback); diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c index a332bc3b88d..c7215cb3cbd 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c @@ -60,13 +60,14 @@ int main() iox_sub_t subscriber[NUMBER_OF_SUBSCRIBERS]; // create subscriber and subscribe them to our service - const uint64_t historyRequest = 1U; - const uint64_t queueCapacity = 256U; - const char* const nodeName = "iox-c-ex-waitset-grouping-node"; + iox_subscriber_options_t options; + options.historyRequest = 1U; + options.queueCapacity = 256U; + options.nodeName = "iox-c-ex-waitset-grouping-node"; for (uint64_t i = 0U; i < NUMBER_OF_SUBSCRIBERS; ++i) { subscriber[i] = iox_sub_init( - &(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", queueCapacity, historyRequest, nodeName); + &(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", options); iox_sub_subscribe(subscriber[i]); } diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c index d59bfc8c22a..30b7c1db1fb 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c @@ -60,16 +60,19 @@ int main() iox_sub_t subscriber[NUMBER_OF_SUBSCRIBERS]; // create two subscribers, subscribe to the service and attach them to the waitset - const uint64_t historyRequest = 1U; - const uint64_t queueCapacity = 256U; - - const char* const nodeName1 = "iox-c-ex-waitset-individual-node1"; - const char* const nodeName2 = "iox-c-ex-waitset-individual-node2"; + iox_subscriber_options_t options1, options2; + options1.historyRequest = 1U; + options1.queueCapacity = 256U; + options1.nodeName = "iox-c-ex-waitset-individual-node1"; + + options2.historyRequest = 1U; + options2.queueCapacity = 256U; + options2.nodeName = "iox-c-ex-waitset-individual-node2"; subscriber[0] = iox_sub_init( - &(subscriberStorage[0]), "Radar", "FrontLeft", "Counter", queueCapacity, historyRequest, nodeName1); + &(subscriberStorage[0]), "Radar", "FrontLeft", "Counter", options1); subscriber[1] = iox_sub_init( - &(subscriberStorage[1]), "Radar", "FrontLeft", "Counter", queueCapacity, historyRequest, nodeName2); + &(subscriberStorage[1]), "Radar", "FrontLeft", "Counter", options2); iox_sub_subscribe(subscriber[0]); iox_sub_subscribe(subscriber[1]); From 3d66e9827f1b6f279e180ccb7bc757a552a03936 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Fri, 19 Feb 2021 11:05:08 +0100 Subject: [PATCH 068/143] iox-#350 adjusted the subscriber example to be more consistent with the design document Signed-off-by: Christian Eltzschig --- iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp index ea03e8adfa8..55be99247ec 100644 --- a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp +++ b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp @@ -41,7 +41,7 @@ void shutdownTriggerCallback(iox::popo::UserTrigger*) keepRunning.store(false); } -void subscriberCallback(iox::popo::Subscriber* subscriber) +void onSampleReceived(iox::popo::Subscriber* subscriber) { subscriber->take().and_then([](auto& sample) { printf("received: %d\n", sample->counter); }); } @@ -65,7 +65,7 @@ int main() subscriber.subscribe(); - callSet.attachEvent(subscriber, iox::popo::SubscriberEvent::HAS_DATA, subscriberCallback); + callSet.attachEvent(subscriber, iox::popo::SubscriberEvent::HAS_DATA, onSampleReceived); while (keepRunning) { From e12ed6a70167bf90f319d2604e914fda0d195990 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Fri, 19 Feb 2021 12:10:41 +0100 Subject: [PATCH 069/143] iox-#350 add Seppuku class to prevent a potential deadlock in event variable tests Signed-off-by: Marika Lehmann --- .../moduletests/test_popo_event_variable.cpp | 69 ++++++++++--------- iceoryx_utils/testutils/seppuku.hpp | 62 +++++++++++++++++ 2 files changed, 100 insertions(+), 31 deletions(-) create mode 100644 iceoryx_utils/testutils/seppuku.hpp diff --git a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp index ce716f7bada..063dc4bbdb6 100644 --- a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp @@ -14,18 +14,19 @@ // // SPDX-License-Identifier: Apache-2.0 - #include "iceoryx_posh/internal/popo/building_blocks/event_listener.hpp" #include "iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp" #include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" #include "test.hpp" +#include "testutils/seppuku.hpp" #include "testutils/timing_test.hpp" #include using namespace ::testing; using namespace iox::popo; +using namespace iox::units::duration_literals; class EventVariable_test : public Test { @@ -34,6 +35,8 @@ class EventVariable_test : public Test const iox::ProcessName_t m_process{"Ferdinand"}; EventVariableData m_eventVarData{m_process}; + + const iox::units::Duration m_timeToWait = 2_s; }; TEST_F(EventVariable_test, AllNotificationsAreFalseAfterConstruction) @@ -60,7 +63,7 @@ TEST_F(EventVariable_test, AllNotificationsAreFalseAfterConstructionWithProcessN TEST_F(EventVariable_test, NotifyActivatesCorrectIndex) { - const uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; + constexpr uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; EventNotifier sut(m_eventVarData, EVENT_INDEX); sut.notify(); for (uint8_t i = 0U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; i++) @@ -78,7 +81,7 @@ TEST_F(EventVariable_test, NotifyActivatesCorrectIndex) TEST_F(EventVariable_test, NotifyActivatesNoIndexIfIndexIsTooLarge) { - const uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; + constexpr uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; EventNotifier sut(m_eventVarData, EVENT_INDEX); sut.notify(); for (const auto& notification : m_eventVarData.m_activeNotifications) @@ -89,27 +92,35 @@ TEST_F(EventVariable_test, NotifyActivatesNoIndexIfIndexIsTooLarge) TEST_F(EventVariable_test, GetCorrectNotificationVectorAfterNotifyAndWait) { - const uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; + constexpr uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; EventNotifier notifier(m_eventVarData, EVENT_INDEX); EventListener listener(m_eventVarData); + Seppuku seppuku(m_timeToWait); + seppuku.doSeppuku([&] { listener.destroy(); }); + notifier.notify(); const auto& activeNotifications = listener.wait(); + ASSERT_THAT(activeNotifications.size(), Eq(1U)); EXPECT_THAT(activeNotifications[0], Eq(EVENT_INDEX)); } TEST_F(EventVariable_test, GetCorrectNotificationVectorAfterMultipleNotifyAndWait) { - const uint8_t FIRST_EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; - const uint8_t SECOND_EVENT_INDEX = 0U; + constexpr uint8_t FIRST_EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; + constexpr uint8_t SECOND_EVENT_INDEX = 0U; EventNotifier notifier1(m_eventVarData, FIRST_EVENT_INDEX); EventNotifier notifier2(m_eventVarData, SECOND_EVENT_INDEX); EventListener listener(m_eventVarData); + Seppuku seppuku(m_timeToWait); + seppuku.doSeppuku([&] { listener.destroy(); }); + notifier1.notify(); notifier2.notify(); const auto& activeNotifications = listener.wait(); + ASSERT_THAT(activeNotifications.size(), Eq(2U)); EXPECT_THAT(activeNotifications[0], Eq(SECOND_EVENT_INDEX)); EXPECT_THAT(activeNotifications[1], Eq(FIRST_EVENT_INDEX)); @@ -117,11 +128,14 @@ TEST_F(EventVariable_test, GetCorrectNotificationVectorAfterMultipleNotifyAndWai TEST_F(EventVariable_test, WaitAndNotifyResultsInCorrectNotificationVector) { - const uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 5U; + constexpr uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 5U; EventNotifier notifier(m_eventVarData, EVENT_INDEX); EventListener listener(m_eventVarData); NotificationVector_t activeNotifications; + Seppuku seppuku(m_timeToWait); + seppuku.doSeppuku([&] { listener.destroy(); }); + std::thread waiter([&] { activeNotifications = listener.wait(); ASSERT_THAT(activeNotifications.size(), Eq(1U)); @@ -133,7 +147,7 @@ TEST_F(EventVariable_test, WaitAndNotifyResultsInCorrectNotificationVector) } TIMING_TEST_F(EventVariable_test, WaitBlocks, Repeat(5), [&] { - const uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 5U; + constexpr uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 5U; EventNotifier notifier(m_eventVarData, EVENT_INDEX); EventListener listener(m_eventVarData); NotificationVector_t activeNotifications; @@ -141,6 +155,9 @@ TIMING_TEST_F(EventVariable_test, WaitBlocks, Repeat(5), [&] { iox::posix::Semaphore::create(iox::posix::CreateUnnamedSingleProcessSemaphore, 0U).value(); std::atomic_bool hasWaited{false}; + Seppuku seppuku(m_timeToWait); + seppuku.doSeppuku([&] { listener.destroy(); }); + std::thread waiter([&] { threadSetupSemaphore.post(); activeNotifications = listener.wait(); @@ -159,8 +176,8 @@ TIMING_TEST_F(EventVariable_test, WaitBlocks, Repeat(5), [&] { }) TIMING_TEST_F(EventVariable_test, SecondWaitBlocksUntilNewNotification, Repeat(5), [&] { - const uint8_t FIRST_EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 2U; - const uint8_t SECOND_EVENT_INDEX = 0U; + constexpr uint8_t FIRST_EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 2U; + constexpr uint8_t SECOND_EVENT_INDEX = 0U; EventNotifier notifier1(m_eventVarData, FIRST_EVENT_INDEX); EventNotifier notifier2(m_eventVarData, SECOND_EVENT_INDEX); EventListener listener(m_eventVarData); @@ -168,19 +185,30 @@ TIMING_TEST_F(EventVariable_test, SecondWaitBlocksUntilNewNotification, Repeat(5 iox::posix::Semaphore::create(iox::posix::CreateUnnamedSingleProcessSemaphore, 0U).value(); std::atomic_bool hasWaited{false}; + Seppuku seppukuFirstWait(m_timeToWait); + seppukuFirstWait.doSeppuku([&] { listener.destroy(); }); + notifier1.notify(); notifier2.notify(); NotificationVector_t activeNotifications = listener.wait(); + ASSERT_THAT(activeNotifications.size(), Eq(2U)); EXPECT_THAT(activeNotifications[0], Eq(SECOND_EVENT_INDEX)); EXPECT_THAT(activeNotifications[1], Eq(FIRST_EVENT_INDEX)); + Seppuku seppukuSecondWait(m_timeToWait); + seppukuSecondWait.doSeppuku([&] { listener.destroy(); }); + std::thread waiter([&] { threadSetupSemaphore.post(); activeNotifications = listener.wait(); hasWaited.store(true, std::memory_order_relaxed); ASSERT_THAT(activeNotifications.size(), Eq(1U)); EXPECT_THAT(activeNotifications[0], Eq(FIRST_EVENT_INDEX)); + for (const auto& notification : m_eventVarData.m_activeNotifications) + { + EXPECT_THAT(notification, Eq(false)); + } }); threadSetupSemaphore.wait(); @@ -192,27 +220,6 @@ TIMING_TEST_F(EventVariable_test, SecondWaitBlocksUntilNewNotification, Repeat(5 waiter.join(); }) -TEST_F(EventVariable_test, AllEntriesAreResetToFalseInsideWait) -{ - const uint8_t FIRST_EVENT_INDEX = 3U; - const uint8_t SECOND_EVENT_INDEX = 1U; - EventNotifier notifier1(m_eventVarData, FIRST_EVENT_INDEX); - EventNotifier notifier2(m_eventVarData, SECOND_EVENT_INDEX); - EventListener listener(m_eventVarData); - - notifier1.notify(); - ASSERT_THAT(m_eventVarData.m_activeNotifications[FIRST_EVENT_INDEX], Eq(true)); - notifier2.notify(); - ASSERT_THAT(m_eventVarData.m_activeNotifications[SECOND_EVENT_INDEX], Eq(true)); - - const auto& activeNotifications = listener.wait(); - EXPECT_THAT(activeNotifications.size(), Eq(2U)); - for (const auto& notification : m_eventVarData.m_activeNotifications) - { - EXPECT_THAT(notification, Eq(false)); - } -} - TEST_F(EventVariable_test, WaitIsNonBlockingAfterDestroyAndReturnsEmptyVector) { EventListener sut(m_eventVarData); diff --git a/iceoryx_utils/testutils/seppuku.hpp b/iceoryx_utils/testutils/seppuku.hpp new file mode 100644 index 00000000000..0d4ea182389 --- /dev/null +++ b/iceoryx_utils/testutils/seppuku.hpp @@ -0,0 +1,62 @@ +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IOX_UTILS_TESTUTILS_SEPPUKU_HPP +#define IOX_UTILS_TESTUTILS_SEPPUKU_HPP + +#include + +using namespace iox::units::duration_literals; + +// class for killing the application if a test takes too much time to finish +class Seppuku +{ + public: + Seppuku(const iox::units::Duration& timeToWait) noexcept + : m_timeToWait(timeToWait) + { + } + + ~Seppuku() noexcept + { + m_seppukuSemaphore.post(); + m_seppuku.join(); + } + + void doSeppuku(std::function f) noexcept + { + struct timespec timeout = m_timeToWait.timespec(iox::units::TimeSpecReference::Epoch); + m_seppuku = std::thread([=] { + m_seppukuSemaphore.timedWait(&timeout, false) + .and_then([&](auto& result) { + if (result == iox::posix::SemaphoreWaitState::TIMEOUT) + { + f(); + EXPECT_TRUE(false); + } + }) + .or_else([](auto&) { EXPECT_TRUE(false); }); + }); + } + + private: + iox::units::Duration m_timeToWait{0_s}; + iox::posix::Semaphore m_seppukuSemaphore{ + iox::posix::Semaphore::create(iox::posix::CreateUnnamedSingleProcessSemaphore, 0U).value()}; + std::thread m_seppuku; +}; + +#endif // IOX_UTILS_TESTUTILS_SEPPUKU_HPP From fde7444256aa5ee4f8bfd22a2855fd6e88f67a04 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Mon, 22 Feb 2021 10:58:33 +0100 Subject: [PATCH 070/143] iox-#350 added missing includes in seppuku class, renamed methods to be more understandable and used signal handler abstraction in example Signed-off-by: Christian Eltzschig --- .../callbacks/ice_callbacks_publisher.cpp | 4 +- .../callbacks/ice_callbacks_subscriber.cpp | 8 ++-- .../iceoryx_posh/popo/active_call_set.hpp | 6 +-- iceoryx_posh/source/popo/active_call_set.cpp | 16 +++---- .../test/moduletests/test_popo_trigger.cpp | 46 +++++++++---------- iceoryx_utils/testutils/seppuku.hpp | 8 +++- 6 files changed, 46 insertions(+), 42 deletions(-) diff --git a/iceoryx_examples/callbacks/ice_callbacks_publisher.cpp b/iceoryx_examples/callbacks/ice_callbacks_publisher.cpp index fe9a01552a5..776eba8a580 100644 --- a/iceoryx_examples/callbacks/ice_callbacks_publisher.cpp +++ b/iceoryx_examples/callbacks/ice_callbacks_publisher.cpp @@ -16,6 +16,7 @@ #include "iceoryx_posh/popo/publisher.hpp" #include "iceoryx_posh/runtime/posh_runtime.hpp" +#include "iceoryx_utils/posix_wrapper/signal_handler.hpp" #include "topic_data.hpp" #include @@ -49,7 +50,8 @@ void sending() int main() { - signal(SIGINT, sigHandler); + auto signalIntGuard = iox::posix::registerSignalHandler(iox::posix::Signal::INT, sigHandler); + auto signalTermGuard = iox::posix::registerSignalHandler(iox::posix::Signal::TERM, sigHandler); std::thread tx(sending); tx.join(); diff --git a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp index 55be99247ec..7f21dc2c829 100644 --- a/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp +++ b/iceoryx_examples/callbacks/ice_callbacks_subscriber.cpp @@ -19,6 +19,7 @@ #include "iceoryx_posh/popo/user_trigger.hpp" #include "iceoryx_posh/runtime/posh_runtime.hpp" #include "iceoryx_utils/posix_wrapper/semaphore.hpp" +#include "iceoryx_utils/posix_wrapper/signal_handler.hpp" #include "topic_data.hpp" #include @@ -48,11 +49,8 @@ void onSampleReceived(iox::popo::Subscriber* subscriber) int main() { - struct sigaction act; - sigemptyset(&act.sa_mask); - act.sa_handler = sigHandler; - act.sa_flags = 0; - sigaction(SIGINT, &act, nullptr); + auto signalIntGuard = iox::posix::registerSignalHandler(iox::posix::Signal::INT, sigHandler); + auto signalTermGuard = iox::posix::registerSignalHandler(iox::posix::Signal::TERM, sigHandler); iox::runtime::PoshRuntime::initRuntime("iox-ex-callbacks-subscriber"); diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp index 421f819084d..8ab65a8e1dd 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -116,7 +116,7 @@ class ActiveCallSet class Event_t; void threadLoop() noexcept; - cxx::expected + cxx::expected addEvent(void* const origin, const uint64_t eventType, const uint64_t eventTypeHash, @@ -171,12 +171,12 @@ class ActiveCallSet IndexManager_t() noexcept; bool pop(uint32_t& index) noexcept; void push(const uint32_t index) noexcept; - uint64_t size() const noexcept; + uint64_t indicesInUse() const noexcept; uint32_t m_loffliStorage[concurrent::LoFFLi::requiredMemorySize(MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET) / sizeof(uint32_t)]; concurrent::LoFFLi m_loffli; - std::atomic m_size{0U}; + std::atomic m_indicesInUse{0U}; } m_indexManager; diff --git a/iceoryx_posh/source/popo/active_call_set.cpp b/iceoryx_posh/source/popo/active_call_set.cpp index e3d0c976e77..767585642c4 100644 --- a/iceoryx_posh/source/popo/active_call_set.cpp +++ b/iceoryx_posh/source/popo/active_call_set.cpp @@ -45,7 +45,7 @@ ActiveCallSet::~ActiveCallSet() m_eventVariable->m_toBeDestroyed.store(true, std::memory_order_relaxed); } -cxx::expected +cxx::expected ActiveCallSet::addEvent(void* const origin, const uint64_t eventType, const uint64_t eventTypeHash, @@ -55,7 +55,7 @@ ActiveCallSet::addEvent(void* const origin, { std::lock_guard lock(m_addEventMutex); - for (uint64_t i = 0U; i < MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) + for (uint32_t i = 0U; i < MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) { if (m_events[i]->isEqualTo(origin, eventType, eventTypeHash)) { @@ -70,7 +70,7 @@ ActiveCallSet::addEvent(void* const origin, } m_events[index]->init(index, origin, eventType, eventTypeHash, callback, translationCallback, invalidationCallback); - return cxx::success(index); + return cxx::success(index); } void ActiveCallSet::removeEvent(void* const origin, const uint64_t eventType, const uint64_t eventTypeHash) noexcept @@ -87,7 +87,7 @@ void ActiveCallSet::removeEvent(void* const origin, const uint64_t eventType, co uint64_t ActiveCallSet::size() const noexcept { - return m_indexManager.size(); + return m_indexManager.indicesInUse(); } void ActiveCallSet::threadLoop() noexcept @@ -201,7 +201,7 @@ bool ActiveCallSet::IndexManager_t::pop(uint32_t& value) noexcept { if (m_loffli.pop(value)) { - ++m_size; + ++m_indicesInUse; return true; } return false; @@ -210,12 +210,12 @@ bool ActiveCallSet::IndexManager_t::pop(uint32_t& value) noexcept void ActiveCallSet::IndexManager_t::push(const uint32_t index) noexcept { m_loffli.push(index); - --m_size; + --m_indicesInUse; } -uint64_t ActiveCallSet::IndexManager_t::size() const noexcept +uint64_t ActiveCallSet::IndexManager_t::indicesInUse() const noexcept { - return m_size.load(std::memory_order_relaxed); + return m_indicesInUse.load(std::memory_order_relaxed); } diff --git a/iceoryx_posh/test/moduletests/test_popo_trigger.cpp b/iceoryx_posh/test/moduletests/test_popo_trigger.cpp index 052a83ff3a8..f99f9bd1de1 100644 --- a/iceoryx_posh/test/moduletests/test_popo_trigger.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_trigger.cpp @@ -233,12 +233,12 @@ TEST_F(Trigger_test, UpdateOriginLeadsToDifferentHasTriggeredCallback) TEST_F(Trigger_test, UpdateOriginDoesNotUpdateHasTriggeredIfItsNotOriginatingFromOrigin) { - uint64_t userDefinedEventId = 891U; + constexpr uint64_t USER_DEFINED_EVENT_ID = 891U; TriggerClass secondTriggerClass, thirdTriggerClass; Trigger sut(&m_triggerClass, {thirdTriggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - userDefinedEventId, + USER_DEFINED_EVENT_ID, TriggerClass::callback); sut.updateOrigin(&secondTriggerClass); @@ -262,12 +262,12 @@ TEST_F(Trigger_test, UpdateOriginLeadsToDifferentResetCallback) TEST_F(Trigger_test, UpdateOriginDoesNotUpdateResetIfItsNotOriginatingFromOrigin) { - uint64_t userDefinedEventId = 892U; + constexpr uint64_t USER_DEFINED_EVENT_ID = 892U; TriggerClass secondTriggerClass, thirdTriggerClass; Trigger sut(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {thirdTriggerClass, &TriggerClass::resetCall}, - userDefinedEventId, + USER_DEFINED_EVENT_ID, TriggerClass::callback); sut.updateOrigin(&secondTriggerClass); @@ -278,12 +278,12 @@ TEST_F(Trigger_test, UpdateOriginDoesNotUpdateResetIfItsNotOriginatingFromOrigin TEST_F(Trigger_test, UpdateOriginUpdatesOriginOfEventInfo) { - uint64_t userDefinedEventId = 893U; + constexpr uint64_t USER_DEFINED_EVENT_ID = 893U; TriggerClass secondTriggerClass; Trigger sut(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - userDefinedEventId, + USER_DEFINED_EVENT_ID, TriggerClass::callback); sut.updateOrigin(&secondTriggerClass); @@ -295,11 +295,11 @@ TEST_F(Trigger_test, UpdateOriginUpdatesOriginOfEventInfo) /// - hasTriggeredCallback TEST_F(Trigger_test, TriggerIsLogicalEqualToItself) { - uint64_t userDefinedEventId = 894U; + constexpr uint64_t USER_DEFINED_EVENT_ID = 894U; Trigger sut1(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - userDefinedEventId, + USER_DEFINED_EVENT_ID, TriggerClass::callback); EXPECT_TRUE(sut1.isLogicalEqualTo(sut1)); @@ -307,18 +307,18 @@ TEST_F(Trigger_test, TriggerIsLogicalEqualToItself) TEST_F(Trigger_test, TwoTriggersAreLogicalEqualIfRequirementsAreFullfilled) { - uint64_t userDefinedEventId = 896U; - uint64_t anotherUserDefinedEventId = 8961U; + constexpr uint64_t USER_DEFINED_EVENT_ID = 896U; + constexpr uint64_t ANOTHER_USER_DEFINED_EVENT_ID = 8961U; Trigger sut1(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - userDefinedEventId, + USER_DEFINED_EVENT_ID, TriggerClass::callback); Trigger sut2(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - anotherUserDefinedEventId, + ANOTHER_USER_DEFINED_EVENT_ID, TriggerClass::callback); @@ -328,18 +328,18 @@ TEST_F(Trigger_test, TwoTriggersAreLogicalEqualIfRequirementsAreFullfilled) TEST_F(Trigger_test, TwoTriggersAreLogicalEqualIfOnlyTriggerIdDiffers) { - uint64_t userDefinedEventId = 2896U; - uint64_t anotherUserDefinedEventId = 28961U; + constexpr uint64_t USER_DEFINED_EVENT_ID = 2896U; + constexpr uint64_t ANOTHER_USER_DEFINED_EVENT_ID = 28961U; Trigger sut1(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - userDefinedEventId, + USER_DEFINED_EVENT_ID, TriggerClass::callback); Trigger sut2(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - anotherUserDefinedEventId, + ANOTHER_USER_DEFINED_EVENT_ID, TriggerClass::callback); @@ -349,19 +349,19 @@ TEST_F(Trigger_test, TwoTriggersAreLogicalEqualIfOnlyTriggerIdDiffers) TEST_F(Trigger_test, TwoTriggersAreNotLogicalEqualIfHasTriggeredCallbackDiffers) { - uint64_t userDefinedEventId = 4896U; - uint64_t anotherUserDefinedEventId = 48961U; + constexpr uint64_t USER_DEFINED_EVENT_ID = 4896U; + constexpr uint64_t ANOTHER_USER_DEFINED_EVENT_ID = 48961U; TriggerClass secondTriggerClass; Trigger sut1(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - userDefinedEventId, + USER_DEFINED_EVENT_ID, TriggerClass::callback); Trigger sut2(&m_triggerClass, {secondTriggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - anotherUserDefinedEventId, + ANOTHER_USER_DEFINED_EVENT_ID, TriggerClass::callback); @@ -371,18 +371,18 @@ TEST_F(Trigger_test, TwoTriggersAreNotLogicalEqualIfHasTriggeredCallbackDiffers) TEST_F(Trigger_test, TwoTriggersAreNotLogicalEqualIfOriginDiffers) { - uint64_t userDefinedEventId = 4896U; + constexpr uint64_t USER_DEFINED_EVENT_ID = 4896U; TriggerClass secondTriggerClass; Trigger sut1(&m_triggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - userDefinedEventId, + USER_DEFINED_EVENT_ID, TriggerClass::callback); Trigger sut2(&secondTriggerClass, {m_triggerClass, &TriggerClass::hasTriggered}, {m_triggerClass, &TriggerClass::resetCall}, - userDefinedEventId, + USER_DEFINED_EVENT_ID, TriggerClass::callback); diff --git a/iceoryx_utils/testutils/seppuku.hpp b/iceoryx_utils/testutils/seppuku.hpp index 0d4ea182389..4f545eeb1b6 100644 --- a/iceoryx_utils/testutils/seppuku.hpp +++ b/iceoryx_utils/testutils/seppuku.hpp @@ -17,6 +17,11 @@ #ifndef IOX_UTILS_TESTUTILS_SEPPUKU_HPP #define IOX_UTILS_TESTUTILS_SEPPUKU_HPP +#include "iceoryx_utils/internal/units/duration.hpp" +#include "iceoryx_utils/posix_wrapper/semaphore.hpp" + +#include +#include #include using namespace iox::units::duration_literals; @@ -38,9 +43,8 @@ class Seppuku void doSeppuku(std::function f) noexcept { - struct timespec timeout = m_timeToWait.timespec(iox::units::TimeSpecReference::Epoch); m_seppuku = std::thread([=] { - m_seppukuSemaphore.timedWait(&timeout, false) + m_seppukuSemaphore.timedWait(m_timeToWait, false) .and_then([&](auto& result) { if (result == iox::posix::SemaphoreWaitState::TIMEOUT) { From 8206650a7c1027ee8221e05499676500dbb67be4 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Mon, 22 Feb 2021 14:03:47 +0100 Subject: [PATCH 071/143] iox-#350 move EventListner destroy tests, add struct to get best fitting unsigned integer type Signed-off-by: Marika Lehmann --- .../popo/building_blocks/event_listener.hpp | 3 +- .../popo/building_blocks/event_listener.cpp | 5 +- .../moduletests/test_popo_event_variable.cpp | 95 ++++++++++--------- .../include/iceoryx_utils/cxx/helplets.hpp | 38 ++++++++ 4 files changed, 90 insertions(+), 51 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp index 43178e4410d..18e3d322705 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp @@ -19,6 +19,7 @@ #define IOX_POSH_POPO_BUILDING_BLOCKS_EVENT_LISTENER_HPP #include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" +#include "iceoryx_utils/cxx/helplets.hpp" namespace iox { @@ -42,7 +43,7 @@ class EventListener /// never empty unless destroy() was called, then it's always empty. /// /// @return vector of active notifications - cxx::vector::type, + cxx::vector, MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET> wait() noexcept; diff --git a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp index b1391ab8994..997ee106713 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp @@ -35,11 +35,10 @@ void EventListener::destroy() noexcept } } -cxx::vector::type, - MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET> +cxx::vector, MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET> EventListener::wait() noexcept { - cxx::vector::type, + cxx::vector, MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET> activeNotifications; diff --git a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp index 063dc4bbdb6..c9b61ebc6b6 100644 --- a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp @@ -31,7 +31,8 @@ using namespace iox::units::duration_literals; class EventVariable_test : public Test { public: - using NotificationVector_t = iox::cxx::vector; + using Type_t = iox::cxx::BestFittingType_t; + using NotificationVector_t = iox::cxx::vector; const iox::ProcessName_t m_process{"Ferdinand"}; EventVariableData m_eventVarData{m_process}; @@ -63,10 +64,10 @@ TEST_F(EventVariable_test, AllNotificationsAreFalseAfterConstructionWithProcessN TEST_F(EventVariable_test, NotifyActivatesCorrectIndex) { - constexpr uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; + constexpr Type_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; EventNotifier sut(m_eventVarData, EVENT_INDEX); sut.notify(); - for (uint8_t i = 0U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; i++) + for (Type_t i = 0U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; i++) { if (i == EVENT_INDEX) { @@ -81,7 +82,7 @@ TEST_F(EventVariable_test, NotifyActivatesCorrectIndex) TEST_F(EventVariable_test, NotifyActivatesNoIndexIfIndexIsTooLarge) { - constexpr uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; + constexpr Type_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; EventNotifier sut(m_eventVarData, EVENT_INDEX); sut.notify(); for (const auto& notification : m_eventVarData.m_activeNotifications) @@ -90,9 +91,45 @@ TEST_F(EventVariable_test, NotifyActivatesNoIndexIfIndexIsTooLarge) } } +TEST_F(EventVariable_test, WaitIsNonBlockingAfterDestroyAndReturnsEmptyVector) +{ + EventListener sut(m_eventVarData); + sut.destroy(); + const auto& activeNotifications = sut.wait(); + + EXPECT_THAT(activeNotifications.size(), Eq(0U)); +} + +TEST_F(EventVariable_test, WaitIsNonBlockingAfterDestroyAndNotifyAndReturnsEmptyVector) +{ + EventListener sut(m_eventVarData); + sut.destroy(); + + EventNotifier notifier(m_eventVarData, 0U); + notifier.notify(); + + const auto& activeNotifications = sut.wait(); + EXPECT_THAT(activeNotifications.size(), Eq(0U)); +} + +TEST_F(EventVariable_test, DestroyWakesUpWaitWhichReturnsEmptyVector) +{ + EventListener sut(m_eventVarData); + + NotificationVector_t activeNotifications; + + std::thread waiter([&] { + activeNotifications = sut.wait(); + EXPECT_THAT(activeNotifications.size(), Eq(0U)); + }); + + sut.destroy(); + waiter.join(); +} + TEST_F(EventVariable_test, GetCorrectNotificationVectorAfterNotifyAndWait) { - constexpr uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; + constexpr Type_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; EventNotifier notifier(m_eventVarData, EVENT_INDEX); EventListener listener(m_eventVarData); @@ -108,8 +145,8 @@ TEST_F(EventVariable_test, GetCorrectNotificationVectorAfterNotifyAndWait) TEST_F(EventVariable_test, GetCorrectNotificationVectorAfterMultipleNotifyAndWait) { - constexpr uint8_t FIRST_EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; - constexpr uint8_t SECOND_EVENT_INDEX = 0U; + constexpr Type_t FIRST_EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U; + constexpr Type_t SECOND_EVENT_INDEX = 0U; EventNotifier notifier1(m_eventVarData, FIRST_EVENT_INDEX); EventNotifier notifier2(m_eventVarData, SECOND_EVENT_INDEX); EventListener listener(m_eventVarData); @@ -128,7 +165,7 @@ TEST_F(EventVariable_test, GetCorrectNotificationVectorAfterMultipleNotifyAndWai TEST_F(EventVariable_test, WaitAndNotifyResultsInCorrectNotificationVector) { - constexpr uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 5U; + constexpr Type_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 5U; EventNotifier notifier(m_eventVarData, EVENT_INDEX); EventListener listener(m_eventVarData); NotificationVector_t activeNotifications; @@ -147,7 +184,7 @@ TEST_F(EventVariable_test, WaitAndNotifyResultsInCorrectNotificationVector) } TIMING_TEST_F(EventVariable_test, WaitBlocks, Repeat(5), [&] { - constexpr uint8_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 5U; + constexpr Type_t EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 5U; EventNotifier notifier(m_eventVarData, EVENT_INDEX); EventListener listener(m_eventVarData); NotificationVector_t activeNotifications; @@ -176,8 +213,8 @@ TIMING_TEST_F(EventVariable_test, WaitBlocks, Repeat(5), [&] { }) TIMING_TEST_F(EventVariable_test, SecondWaitBlocksUntilNewNotification, Repeat(5), [&] { - constexpr uint8_t FIRST_EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 2U; - constexpr uint8_t SECOND_EVENT_INDEX = 0U; + constexpr Type_t FIRST_EVENT_INDEX = iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 2U; + constexpr Type_t SECOND_EVENT_INDEX = 0U; EventNotifier notifier1(m_eventVarData, FIRST_EVENT_INDEX); EventNotifier notifier2(m_eventVarData, SECOND_EVENT_INDEX); EventListener listener(m_eventVarData); @@ -220,39 +257,3 @@ TIMING_TEST_F(EventVariable_test, SecondWaitBlocksUntilNewNotification, Repeat(5 waiter.join(); }) -TEST_F(EventVariable_test, WaitIsNonBlockingAfterDestroyAndReturnsEmptyVector) -{ - EventListener sut(m_eventVarData); - sut.destroy(); - const auto& activeNotifications = sut.wait(); - - EXPECT_THAT(activeNotifications.size(), Eq(0U)); -} - -TEST_F(EventVariable_test, WaitIsNonBlockingAfterDestroyAndNotifyAndReturnsEmptyVector) -{ - EventListener sut(m_eventVarData); - sut.destroy(); - - EventNotifier notifier(m_eventVarData, 0U); - notifier.notify(); - - const auto& activeNotifications = sut.wait(); - EXPECT_THAT(activeNotifications.size(), Eq(0U)); -} - -TEST_F(EventVariable_test, DestroyWakesUpWaitWhichReturnsEmptyVector) -{ - EventListener sut(m_eventVarData); - - NotificationVector_t activeNotifications; - - std::thread waiter([&] { - activeNotifications = sut.wait(); - EXPECT_THAT(activeNotifications.size(), Eq(0U)); - }); - - sut.destroy(); - waiter.join(); -} - diff --git a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp index d7ffdbbff3c..485fe6585ab 100644 --- a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp +++ b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp @@ -22,6 +22,7 @@ #include #include +#include #include namespace iox @@ -205,6 +206,43 @@ static constexpr uint64_t strlen2(char const (&/*notInterested*/)[SizeValue]) return SizeValue - 1; } +/// @brief struct to find the best fitting unsigned integer type +template +struct bestFittingTypeImpl +{ + using Type_t = uint64_t; +}; + +template <> +struct bestFittingTypeImpl +{ + using Type_t = uint8_t; +}; + +template <> +struct bestFittingTypeImpl +{ + using Type_t = uint16_t; +}; + +template <> +struct bestFittingTypeImpl +{ + using Type_t = uint32_t; +}; + +/// @brief get the best fitting unsigned integer type for a given value at compile time +template +struct bestFittingType +{ + using Type_t = typename bestFittingTypeImpl<(Value > std::numeric_limits::max()), + (Value > std::numeric_limits::max()), + (Value > std::numeric_limits::max())>::Type_t; +}; + +template +using BestFittingType_t = typename bestFittingType::Type_t; + /// @brief if a function has a return value which you do not want to use then you can wrap the function with that macro. /// Purpose is to suppress the unused compiler warning by adding an attribute to the return value /// @param[in] name name of the function where the return value is not used. From f934b7841806f4e44a6f2b2ac2c1f030518c580b Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Mon, 22 Feb 2021 14:20:16 +0100 Subject: [PATCH 072/143] iox-#350 fix bestFittingType struct Signed-off-by: Marika Lehmann --- iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp index 485fe6585ab..b5c5aeddfd2 100644 --- a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp +++ b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp @@ -237,7 +237,7 @@ struct bestFittingType { using Type_t = typename bestFittingTypeImpl<(Value > std::numeric_limits::max()), (Value > std::numeric_limits::max()), - (Value > std::numeric_limits::max())>::Type_t; + (Value > std::numeric_limits::max())>::Type_t; }; template From 2855c0ee0fb96c4a41d83bcbf3cfcd264bd31c3d Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Mon, 22 Feb 2021 19:58:20 +0100 Subject: [PATCH 073/143] iox-#350 refactored timing tests with semaphore and counter to make them more robust Signed-off-by: Christian Eltzschig --- .../moduletests/test_popo_active_call_set.cpp | 156 +++++++++++------- 1 file changed, 100 insertions(+), 56 deletions(-) diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index d6ee09808f4..b75d3a55251 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -21,6 +21,7 @@ #include "iceoryx_posh/popo/user_trigger.hpp" #include "iceoryx_utils/cxx/optional.hpp" #include "iceoryx_utils/cxx/vector.hpp" +#include "iceoryx_utils/posix_wrapper/semaphore.hpp" #include "mocks/wait_set_mock.hpp" #include "test.hpp" #include "testutils/timing_test.hpp" @@ -139,7 +140,13 @@ class ActiveCallSet_test : public Test template static void triggerCallback(ActiveCallSet_test::SimpleEventClass* const event) noexcept { - ActiveCallSet_test::m_triggerCallbackArg[N] = event; + ActiveCallSet_test::m_triggerCallbackArg[N].m_source = event; + ++ActiveCallSet_test::m_triggerCallbackArg[N].m_count; + + if (m_callbackBlocker) + { + m_callbackBlocker->wait(); + } std::this_thread::sleep_for(std::chrono::milliseconds(m_triggerCallbackRuntimeInMs)); } @@ -171,9 +178,11 @@ class ActiveCallSet_test : public Test void SetUp() { + m_callbackBlocker.reset(); for (auto& e : m_triggerCallbackArg) { - e = nullptr; + e.m_source = nullptr; + e.m_count = 0U; } m_sut.emplace(&m_eventVarData); ActiveCallSet_test::SimpleEventClass::m_invalidateTriggerId = 0U; @@ -182,6 +191,20 @@ class ActiveCallSet_test : public Test ActiveCallSet_test::m_toBeDetached.clear(); }; + void blockTriggerCallback() noexcept + { + ActiveCallSet_test::m_callbackBlocker.emplace( + iox::posix::Semaphore::create(iox::posix::CreateUnnamedSingleProcessSemaphore, 0U).value()); + } + + void unblockTriggerCallback(const uint64_t numberOfUnblocks) noexcept + { + for (uint64_t i = 0U; i < numberOfUnblocks; ++i) + { + m_callbackBlocker->post(); + } + } + void TearDown(){}; struct ToBeAttached_t @@ -194,19 +217,27 @@ class ActiveCallSet_test : public Test using eventVector_t = iox::cxx::vector; eventVector_t m_simpleEvents{iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET + 1U}; + struct TriggerSourceAndCount + { + SimpleEventClass* m_source = nullptr; + uint64_t m_count = 0U; + }; + static std::vector m_toBeAttached; static std::vector m_toBeDetached; - static std::array m_triggerCallbackArg; + static std::array m_triggerCallbackArg; static constexpr uint64_t CALLBACK_WAIT_IN_MS = 100U; static uint64_t m_triggerCallbackRuntimeInMs; + static iox::cxx::optional m_callbackBlocker; }; uint64_t ActiveCallSet_test::SimpleEventClass::m_invalidateTriggerId = 0U; -std::array +std::array ActiveCallSet_test::m_triggerCallbackArg; constexpr uint64_t ActiveCallSet_test::CALLBACK_WAIT_IN_MS; uint64_t ActiveCallSet_test::m_triggerCallbackRuntimeInMs; std::vector ActiveCallSet_test::m_toBeAttached; std::vector ActiveCallSet_test::m_toBeDetached; +iox::cxx::optional ActiveCallSet_test::m_callbackBlocker; template struct AttachEvent @@ -462,7 +493,8 @@ TIMING_TEST_F(ActiveCallSet_test, CallbackIsCalledAfterNotify, Repeat(5), [&] { fuu.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U] == &fuu); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_source == &fuu); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_count == 1U); }); TIMING_TEST_F(ActiveCallSet_test, CallbackIsCalledOnlyOnceWhenTriggered, Repeat(5), [&] { @@ -475,12 +507,13 @@ TIMING_TEST_F(ActiveCallSet_test, CallbackIsCalledOnlyOnceWhenTriggered, Repeat( fuu1.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - m_triggerCallbackArg[0U] = nullptr; fuu2.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U] == nullptr); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U] == &fuu2); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_source == &fuu1); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_count == 1U); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U].m_source == &fuu2); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U].m_count == 1U); }); TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherCallback, Repeat(5), [&] { @@ -488,14 +521,18 @@ TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherCallback, m_sut->attachEvent( fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); - m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; + constexpr uint64_t NUMBER_OF_TRIGGER_UNBLOCKS = 10U; + + blockTriggerCallback(); fuu.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - m_triggerCallbackArg[0U] = nullptr; + fuu.triggerStoepsel(); + unblockTriggerCallback(NUMBER_OF_TRIGGER_UNBLOCKS); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U] == &fuu); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_source == &fuu); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_count == 2U); }); TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherCallbackOnce, Repeat(5), [&] { @@ -506,20 +543,21 @@ TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherCallbackOn m_sut->attachEvent( bar, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<1U>); - m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; - fuu.triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - m_triggerCallbackArg[0U] = nullptr; + constexpr uint64_t NUMBER_OF_TRIGGER_UNBLOCKS = 10U; + + blockTriggerCallback(); fuu.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - m_triggerCallbackArg[0U] = nullptr; - + fuu.triggerStoepsel(); bar.triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(4 * CALLBACK_WAIT_IN_MS)); + unblockTriggerCallback(NUMBER_OF_TRIGGER_UNBLOCKS); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U] == nullptr); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U] == &bar); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_source == &fuu); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_count == 2U); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U].m_source == &bar); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U].m_count == 1U); }); TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnotherCallback, Repeat(5), [&] { @@ -527,17 +565,21 @@ TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnot m_sut->attachEvent( fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); - m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; - fuu.triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2U)); - m_triggerCallbackArg[0U] = nullptr; - fuu.triggerStoepsel(); - fuu.triggerStoepsel(); - fuu.triggerStoepsel(); + constexpr uint64_t NUMBER_OF_RETRIGGERS = 10U; + + blockTriggerCallback(); fuu.triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS * 2U)); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U] == &fuu); + for (uint64_t i = 0U; i < NUMBER_OF_RETRIGGERS; ++i) + { + fuu.triggerStoepsel(); + } + unblockTriggerCallback(NUMBER_OF_RETRIGGERS); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_source == &fuu); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_count == 2U); }); TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnotherCallbackOnce, Repeat(5), [&] { @@ -548,23 +590,24 @@ TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnot m_sut->attachEvent( bar, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<1U>); - m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; - fuu.triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - m_triggerCallbackArg[0U] = nullptr; - fuu.triggerStoepsel(); - fuu.triggerStoepsel(); - fuu.triggerStoepsel(); + constexpr uint64_t NUMBER_OF_RETRIGGERS = 10U; + + blockTriggerCallback(); fuu.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - // trigger bar and fuu should not be triggered again - m_triggerCallbackArg[0U] = nullptr; + for (uint64_t i = 0U; i < NUMBER_OF_RETRIGGERS; ++i) + { + fuu.triggerStoepsel(); + } bar.triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(4U * CALLBACK_WAIT_IN_MS)); + unblockTriggerCallback(NUMBER_OF_RETRIGGERS + 1); + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U] == nullptr); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U] == &bar); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_source == &fuu); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_count == 2U); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U].m_source == &bar); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U].m_count == 1U); }); TIMING_TEST_F(ActiveCallSet_test, NoTriggerLeadsToNoCallback, Repeat(5), [&] { @@ -574,7 +617,8 @@ TIMING_TEST_F(ActiveCallSet_test, NoTriggerLeadsToNoCallback, Repeat(5), [&] { std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U] == nullptr); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_source == nullptr); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_count == 0U); }); TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacks, Repeat(5), [&] { @@ -591,7 +635,7 @@ TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacks, Repeat(5 // while the callback is still running. to verify that events[0] is called again // we reset the m_triggerCallbackArg[0] to nullptr (which is again set by the // event[0] callback) and set the runtime of the callbacks to zero - m_triggerCallbackArg[0U] = nullptr; + m_triggerCallbackArg[0U].m_source = nullptr; m_triggerCallbackRuntimeInMs = 0U; for (auto& e : events) @@ -601,7 +645,7 @@ TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacks, Repeat(5 for (uint64_t i = 0U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) { - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i] == &events[i]); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i].m_source == &events[i]); } }); @@ -622,16 +666,16 @@ TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacksOnce, Repe std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); for (auto& t : m_triggerCallbackArg) { - t = nullptr; + t.m_source = nullptr; } events[0U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0] == &events[0U]); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0].m_source == &events[0U]); for (uint64_t i = 1U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) { - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i] == nullptr); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i].m_source == nullptr); } }); @@ -651,7 +695,7 @@ TIMING_TEST_F(ActiveCallSet_test, AttachingWhileCallbackIsRunningWorks, Repeat(5 events[1U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS * 2U)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U] == &events[1U]); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U].m_source == &events[1U]); }); TIMING_TEST_F(ActiveCallSet_test, AttachingMultipleWhileCallbackIsRunningWorks, Repeat(5), [&] { @@ -677,7 +721,7 @@ TIMING_TEST_F(ActiveCallSet_test, AttachingMultipleWhileCallbackIsRunningWorks, for (uint64_t i = 0U; i + 1U < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) { - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i] == &events[i]); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i].m_source == &events[i]); } }); @@ -690,12 +734,12 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingWhileCallbackIsRunningWorks, Repeat(5 events[0U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - m_triggerCallbackArg[0U] = nullptr; + m_triggerCallbackArg[0U].m_source = nullptr; m_sut->detachEvent(events[0U], SimpleEvent::StoepselBachelorParty); events[0U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U] == nullptr); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_source == nullptr); }); TIMING_TEST_F(ActiveCallSet_test, DetachingWhileCallbackIsRunningBlocksDetach, Repeat(5), [&] { @@ -747,7 +791,7 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingMultipleWhileCallbackIsRunningWorks, std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); for (auto& t : m_triggerCallbackArg) { - t = nullptr; + t.m_source = nullptr; } for (auto& e : events) { @@ -757,7 +801,7 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingMultipleWhileCallbackIsRunningWorks, for (uint64_t i = 0U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) { - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i] == nullptr); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i].m_source == nullptr); } }); @@ -827,7 +871,7 @@ TIMING_TEST_F(ActiveCallSet_test, DetachedCallbacksAreNotBeingCalledWhenTriggere m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; events[1U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2U)); - m_triggerCallbackArg[1U] = nullptr; + m_triggerCallbackArg[1U].m_source = nullptr; m_triggerCallbackRuntimeInMs = 0U; events[0U].triggerStoepsel(); @@ -835,7 +879,7 @@ TIMING_TEST_F(ActiveCallSet_test, DetachedCallbacksAreNotBeingCalledWhenTriggere std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U] == nullptr); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U].m_source == nullptr); }); TIMING_TEST_F(ActiveCallSet_test, AttachingInCallbackWorks, Repeat(1), [&] { @@ -851,5 +895,5 @@ TIMING_TEST_F(ActiveCallSet_test, AttachingInCallbackWorks, Repeat(1), [&] { std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2U)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U] == &events[1U]); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_source == &events[1U]); }); From c8d39ca2872587656664cee4f607bb29938133d7 Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Wed, 24 Feb 2021 18:13:40 +0100 Subject: [PATCH 074/143] iox-#408 refactored internal trygetchunk - removed optional Signed-off-by: Matthias Killat --- .../include/iceoryx_binding_c/subscriber.h | 6 +-- iceoryx_binding_c/source/c_subscriber.cpp | 8 +-- .../source/cpp2c_enum_translation.cpp | 2 + .../test_cpp2c_enum_translation.cpp | 4 +- .../internal/popo/base_subscriber.inl | 17 +------ .../popo/building_blocks/chunk_receiver.hpp | 6 +-- .../popo/building_blocks/chunk_receiver.inl | 10 ++-- .../popo/ports/subscriber_port_user.hpp | 7 +-- .../popo/ports/subscriber_port_user.cpp | 2 +- .../test_popo_chunk_building_blocks.cpp | 49 ++++++++++--------- .../test_popo_port_user_building_blocks.cpp | 24 ++++----- iceoryx_posh/test/mocks/subscriber_mock.hpp | 4 +- .../moduletests/test_popo_base_subscriber.cpp | 19 ++----- .../moduletests/test_popo_chunk_receiver.cpp | 31 +++++------- .../moduletests/test_popo_subscriber_port.cpp | 7 +-- 15 files changed, 81 insertions(+), 115 deletions(-) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h index 35f75b291f7..0503e976016 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h @@ -33,7 +33,7 @@ typedef struct // number of chunks received after subscription if chunks are available uint64_t historyRequest; - // name of the node the publisher belongs to + // name of the node the subscriber belongs to const char* nodeName; } iox_subscriber_options_t; @@ -87,12 +87,12 @@ void iox_sub_release_queued_chunks(iox_sub_t const self); /// @brief are new chunks available? /// @param[in] self handle to the subscriber -/// @return true if there are chunks otherwise false +/// @return true if there are chunks, otherwise false bool iox_sub_has_chunks(iox_sub_t const self); /// @brief are chunks lost? /// @param[in] self handle to the subscriber -/// @return true if there are lost chunks otherwise false +/// @return true if there are lost chunks due to overflowing queue, otherwise false bool iox_sub_has_lost_chunks(iox_sub_t const self); #endif diff --git a/iceoryx_binding_c/source/c_subscriber.cpp b/iceoryx_binding_c/source/c_subscriber.cpp index 5f99f108e7f..4f4e218f711 100644 --- a/iceoryx_binding_c/source/c_subscriber.cpp +++ b/iceoryx_binding_c/source/c_subscriber.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2020, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -84,12 +85,7 @@ iox_ChunkReceiveResult iox_sub_take_chunk(iox_sub_t const self, const void** con return cpp2c::ChunkReceiveResult(result.get_error()); } - if (!result->has_value()) - { - return ChunkReceiveResult_NO_CHUNK_AVAILABLE; - } - - *payload = (**result)->payload(); + *payload = result.value()->payload(); return ChunkReceiveResult_SUCCESS; } diff --git a/iceoryx_binding_c/source/cpp2c_enum_translation.cpp b/iceoryx_binding_c/source/cpp2c_enum_translation.cpp index 35a21a94cc6..696b6deb82b 100644 --- a/iceoryx_binding_c/source/cpp2c_enum_translation.cpp +++ b/iceoryx_binding_c/source/cpp2c_enum_translation.cpp @@ -45,6 +45,8 @@ iox_ChunkReceiveResult ChunkReceiveResult(const iox::popo::ChunkReceiveResult va { switch (value) { + case ChunkReceiveResult::NO_CHUNK_AVAILABLE: + return ChunkReceiveResult_NO_CHUNK_AVAILABLE; case ChunkReceiveResult::TOO_MANY_CHUNKS_HELD_IN_PARALLEL: return ChunkReceiveResult_TOO_MANY_CHUNKS_HELD_IN_PARALLEL; default: diff --git a/iceoryx_binding_c/test/moduletests/test_cpp2c_enum_translation.cpp b/iceoryx_binding_c/test/moduletests/test_cpp2c_enum_translation.cpp index 48c84d215b5..66b27266081 100644 --- a/iceoryx_binding_c/test/moduletests/test_cpp2c_enum_translation.cpp +++ b/iceoryx_binding_c/test/moduletests/test_cpp2c_enum_translation.cpp @@ -38,6 +38,9 @@ TEST(cpp2c_enum_translation_test, SubscribeState) TEST(cpp2c_enum_translation_test, ChunkReceiveResult) { + EXPECT_EQ(cpp2c::ChunkReceiveResult(iox::popo::ChunkReceiveResult::NO_CHUNK_AVAILABLE), + ChunkReceiveResult_NO_CHUNK_AVAILABLE); + EXPECT_EQ(cpp2c::ChunkReceiveResult(iox::popo::ChunkReceiveResult::TOO_MANY_CHUNKS_HELD_IN_PARALLEL), ChunkReceiveResult_TOO_MANY_CHUNKS_HELD_IN_PARALLEL); @@ -75,4 +78,3 @@ TEST(cpp2c_enum_translation_test, WaitSetResult) EXPECT_EQ(cpp2c::WaitSetResult(static_cast(-1)), WaitSetResult_UNDEFINED_ERROR); #pragma GCC diagnostic pop } - diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/base_subscriber.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/base_subscriber.inl index 08ece9f35cd..8e073268c22 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/base_subscriber.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/base_subscriber.inl @@ -88,22 +88,7 @@ inline bool BaseSubscriber::hasMissedData() noexcept template inline cxx::expected BaseSubscriber::takeChunk() noexcept { - auto result = m_port.tryGetChunk(); - if (result.has_error()) - { - return cxx::error(result.get_error()); - } - else - { - auto maybeHeader = result.value(); - if (maybeHeader.has_value()) - { - return cxx::success(maybeHeader.value()); - } - } - ///@todo: optimization - we could move this to a tryGetChunk but then we should remove expected> there in - /// the call chain - return cxx::error(ChunkReceiveResult::NO_CHUNK_AVAILABLE); + return m_port.tryGetChunk(); } template diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_receiver.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_receiver.hpp index f8e3072bc7e..db6203a842f 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_receiver.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_receiver.hpp @@ -57,9 +57,9 @@ class ChunkReceiver : public ChunkQueuePopper, ChunkReceiveResult> tryGet() noexcept; + /// @return New chunk header, ChunkReceiveResult on error + /// or if there are no new chunks in the underlying queue + cxx::expected tryGet() noexcept; /// @brief Release a chunk that was obtained with get /// @param[in] chunkHeader, pointer to the ChunkHeader to release diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_receiver.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_receiver.inl index 0db74d629df..97a27204132 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_receiver.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_receiver.inl @@ -45,7 +45,7 @@ ChunkReceiver::getMembers() noexcept } template -inline cxx::expected, ChunkReceiveResult> +inline cxx::expected ChunkReceiver::tryGet() noexcept { auto popRet = this->tryPop(); @@ -57,7 +57,7 @@ ChunkReceiver::tryGet() noexcept // if the application holds too many chunks, don't provide more if (getMembers()->m_chunksInUse.insert(sharedChunk)) { - return cxx::success>( + return cxx::success( const_cast(sharedChunk.getChunkHeader())); } else @@ -67,11 +67,7 @@ ChunkReceiver::tryGet() noexcept return cxx::error(ChunkReceiveResult::TOO_MANY_CHUNKS_HELD_IN_PARALLEL); } } - else - { - // no new chunk - return cxx::success>(cxx::nullopt_t()); - } + return cxx::error(ChunkReceiveResult::NO_CHUNK_AVAILABLE); } template diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp index 4bb5abfefe4..8f1ca921374 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -63,9 +64,9 @@ class SubscriberPortUser : public BasePort /// @brief Tries to get the next chunk from the queue. If there is a new one, the ChunkHeader of the oldest chunk in /// the queue is returned (FiFo queue) - /// @return optional that has a new chunk header or no value if there are no new chunks in the underlying queue, - /// ChunkReceiveResult on error - cxx::expected, ChunkReceiveResult> tryGetChunk() noexcept; + /// @return New chunk header, ChunkReceiveResult on error + /// or if there are no new chunks in the underlying queue + cxx::expected tryGetChunk() noexcept; /// @brief Release a chunk that was obtained with tryGetChunk /// @param[in] chunkHeader, pointer to the ChunkHeader to release diff --git a/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp b/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp index 90d5dfb8600..88fb47036c9 100644 --- a/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp +++ b/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp @@ -63,7 +63,7 @@ SubscribeState SubscriberPortUser::getSubscriptionState() const noexcept return getMembers()->m_subscriptionState; } -cxx::expected, ChunkReceiveResult> SubscriberPortUser::tryGetChunk() noexcept +cxx::expected SubscriberPortUser::tryGetChunk() noexcept { return m_chunkReceiver.tryGet(); } diff --git a/iceoryx_posh/test/integrationtests/test_popo_chunk_building_blocks.cpp b/iceoryx_posh/test/integrationtests/test_popo_chunk_building_blocks.cpp index 7ecf2f87717..82cc8245668 100644 --- a/iceoryx_posh/test/integrationtests/test_popo_chunk_building_blocks.cpp +++ b/iceoryx_posh/test/integrationtests/test_popo_chunk_building_blocks.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -159,32 +160,34 @@ class ChunkBuildingBlocks_IntegrationTest : public Test while (!finished) { m_chunkReceiver.tryGet() - .and_then([&](iox::cxx::optional& maybeChunkHeader) { - if (maybeChunkHeader.has_value()) - { - auto chunkHeader = maybeChunkHeader.value(); - auto dummySample = *reinterpret_cast(chunkHeader->payload()); - // Check if monotonically increasing - EXPECT_THAT(dummySample.m_dummy, Eq(m_receiveCounter)); - m_receiveCounter++; - m_chunkReceiver.release(chunkHeader); - newChunkReceivedInLastIteration = true; - } - else if (!m_forwarderRun.load(std::memory_order_relaxed)) + .and_then([&](auto& chunkHeader) { + auto dummySample = *reinterpret_cast(chunkHeader->payload()); + // Check if monotonically increasing + EXPECT_THAT(dummySample.m_dummy, Eq(m_receiveCounter)); + m_receiveCounter++; + m_chunkReceiver.release(chunkHeader); + newChunkReceivedInLastIteration = true; + }) + .or_else([&](auto& result) { + if (result == ChunkReceiveResult::NO_CHUNK_AVAILABLE) { - if (newChunkReceivedInLastIteration) - { - newChunkReceivedInLastIteration = false; - } - else + if (!m_forwarderRun.load(std::memory_order_relaxed)) { - finished = true; + if (newChunkReceivedInLastIteration) + { + newChunkReceivedInLastIteration = false; + } + else + { + finished = true; + } } } - }) - .or_else([](ChunkReceiveResult) { - // Errors shall never occur - FAIL(); + else + { + // Errors shall never occur + FAIL(); + } }); } } @@ -242,4 +245,4 @@ TEST_F(ChunkBuildingBlocks_IntegrationTest, TwoHopsThreeThreadsNoSoFi) ASSERT_FALSE(m_popper.hasOverflown()); ASSERT_FALSE(m_chunkReceiver.hasOverflown()); EXPECT_EQ(m_sendCounter, m_receiveCounter); -} +} \ No newline at end of file diff --git a/iceoryx_posh/test/integrationtests/test_popo_port_user_building_blocks.cpp b/iceoryx_posh/test/integrationtests/test_popo_port_user_building_blocks.cpp index ed49e64894a..6931dccf28e 100644 --- a/iceoryx_posh/test/integrationtests/test_popo_port_user_building_blocks.cpp +++ b/iceoryx_posh/test/integrationtests/test_popo_port_user_building_blocks.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -205,14 +206,12 @@ class PortUser_IntegrationTest : public Test { // Try to receive chunk subscriberPortUser.tryGetChunk() - .and_then([&](optional& maybeChunkHeader) { - if (maybeChunkHeader.has_value()) - { - auto chunkHeader = maybeChunkHeader.value(); - m_receiveCounter++; - subscriberPortUser.releaseChunk(chunkHeader); - } - else + .and_then([&](auto& chunkHeader) { + m_receiveCounter++; + subscriberPortUser.releaseChunk(chunkHeader); + }) + .or_else([&](auto& result) { + if (result == ChunkReceiveResult::NO_CHUNK_AVAILABLE) { // Nothing received -> check if publisher(s) still running if (m_publisherRunFinished.load(std::memory_order_relaxed) == numberOfPublishers) @@ -220,10 +219,11 @@ class PortUser_IntegrationTest : public Test finished = true; } } - }) - .or_else([](auto error) { - // Errors shall never occur - FAIL() << "Error in tryGetChunk(): " << static_cast(error); + else + { + // Errors shall never occur + FAIL() << "Error in tryGetChunk(): " << static_cast(result); + } }); } } diff --git a/iceoryx_posh/test/mocks/subscriber_mock.hpp b/iceoryx_posh/test/mocks/subscriber_mock.hpp index d80d7d27a3f..a4c1260f29b 100644 --- a/iceoryx_posh/test/mocks/subscriber_mock.hpp +++ b/iceoryx_posh/test/mocks/subscriber_mock.hpp @@ -50,9 +50,7 @@ class MockSubscriberPortUser MOCK_METHOD0(subscribe, void()); MOCK_METHOD0(unsubscribe, void()); MOCK_CONST_METHOD0(getSubscriptionState, iox::SubscribeState()); - MOCK_METHOD0( - tryGetChunk, - iox::cxx::expected, iox::popo::ChunkReceiveResult>()); + MOCK_METHOD0(tryGetChunk, iox::cxx::expected()); MOCK_METHOD1(releaseChunk, void(iox::mepoo::ChunkHeader*)); MOCK_METHOD0(releaseQueuedChunks, void()); MOCK_CONST_METHOD0(hasNewChunks, bool()); diff --git a/iceoryx_posh/test/moduletests/test_popo_base_subscriber.cpp b/iceoryx_posh/test/moduletests/test_popo_base_subscriber.cpp index 55f8bc9d5f3..c7b54306898 100644 --- a/iceoryx_posh/test/moduletests/test_popo_base_subscriber.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_base_subscriber.cpp @@ -39,7 +39,6 @@ struct DummyData { uint64_t val = 42; }; -} template class StubbedBaseSubscriber : public iox::popo::BaseSubscriber @@ -122,7 +121,7 @@ TEST_F(BaseSubscriberTest, ReceiveReturnsAllocatedMemoryChunk) { // ===== Setup ===== // EXPECT_CALL(sut.port(), tryGetChunk) - .WillOnce(Return(ByMove(iox::cxx::success>( + .WillOnce(Return(ByMove(iox::cxx::success( const_cast(chunkMock.chunkHeader()))))); // ===== Test ===== // auto result = sut.takeChunk(); @@ -146,20 +145,6 @@ TEST_F(BaseSubscriberTest, ReceiveForwardsErrorsFromUnderlyingPort) // ===== Cleanup ===== // } -TEST_F(BaseSubscriberTest, ReceiveReturnsNoChunkAvailableIfUnderlyingPortReturnsEmptyOptional) -{ - // ===== Setup ===== // - EXPECT_CALL(sut.port(), tryGetChunk) - .WillOnce( - Return(ByMove(iox::cxx::success>(iox::cxx::nullopt)))); - // ===== Test ===== // - auto result = sut.takeChunk(); - // ===== Verify ===== // - ASSERT_EQ(true, result.has_error()); - EXPECT_EQ(iox::popo::ChunkReceiveResult::NO_CHUNK_AVAILABLE, result.get_error()); - // ===== Cleanup ===== // -} - TEST_F(BaseSubscriberTest, ClearReceiveBufferCallForwardedToUnderlyingSubscriberPort) { // ===== Setup ===== // @@ -255,3 +240,5 @@ TEST_F(BaseSubscriberTest, DestroysUnderlyingPortOnDestruction) // ===== Verify ===== // // ===== Cleanup ===== // } + +} // namespace diff --git a/iceoryx_posh/test/moduletests/test_popo_chunk_receiver.cpp b/iceoryx_posh/test/moduletests/test_popo_chunk_receiver.cpp index 411d3223522..dd10fd34800 100644 --- a/iceoryx_posh/test/moduletests/test_popo_chunk_receiver.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_chunk_receiver.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -80,8 +81,8 @@ class ChunkReceiver_test : public Test TEST_F(ChunkReceiver_test, getNoChunkFromEmptyQueue) { auto maybeChunkHeader = m_chunkReceiver.tryGet(); - EXPECT_FALSE(maybeChunkHeader.has_error()); - EXPECT_FALSE((*maybeChunkHeader).has_value()); + ASSERT_TRUE(maybeChunkHeader.has_error()); + EXPECT_EQ(maybeChunkHeader.get_error(), iox::popo::ChunkReceiveResult::NO_CHUNK_AVAILABLE); } TEST_F(ChunkReceiver_test, getAndReleaseOneChunk) @@ -94,11 +95,10 @@ TEST_F(ChunkReceiver_test, getAndReleaseOneChunk) m_chunkQueuePusher.push(sharedChunk); auto maybeChunkHeader = m_chunkReceiver.tryGet(); - EXPECT_FALSE(maybeChunkHeader.has_error()); - EXPECT_TRUE((*maybeChunkHeader).has_value()); + ASSERT_FALSE(maybeChunkHeader.has_error()); - EXPECT_TRUE(sharedChunk.getPayload() == (**maybeChunkHeader)->payload()); - m_chunkReceiver.release(**maybeChunkHeader); + EXPECT_TRUE(sharedChunk.getPayload() == (*maybeChunkHeader)->payload()); + m_chunkReceiver.release(*maybeChunkHeader); } EXPECT_THAT(m_memoryManager.getMemPoolInfo(0).m_usedChunks, Eq(0u)); @@ -119,9 +119,8 @@ TEST_F(ChunkReceiver_test, getAndReleaseMultipleChunks) m_chunkQueuePusher.push(sharedChunk); auto maybeChunkHeader = m_chunkReceiver.tryGet(); - EXPECT_FALSE(maybeChunkHeader.has_error()); - EXPECT_TRUE((*maybeChunkHeader).has_value()); - chunks.push_back(**maybeChunkHeader); + ASSERT_FALSE(maybeChunkHeader.has_error()); + chunks.push_back(*maybeChunkHeader); } EXPECT_THAT(m_memoryManager.getMemPoolInfo(0).m_usedChunks, Eq(iox::MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY)); @@ -150,8 +149,7 @@ TEST_F(ChunkReceiver_test, getTooMuchWithoutRelease) m_chunkQueuePusher.push(sharedChunk); auto maybeChunkHeader = m_chunkReceiver.tryGet(); - EXPECT_FALSE(maybeChunkHeader.has_error()); - EXPECT_TRUE((*maybeChunkHeader).has_value()); + ASSERT_FALSE(maybeChunkHeader.has_error()); } // but now it breaks @@ -161,7 +159,7 @@ TEST_F(ChunkReceiver_test, getTooMuchWithoutRelease) m_chunkQueuePusher.push(sharedChunk); auto maybeChunkHeader = m_chunkReceiver.tryGet(); - EXPECT_TRUE(maybeChunkHeader.has_error()); + ASSERT_TRUE(maybeChunkHeader.has_error()); EXPECT_THAT(maybeChunkHeader.get_error(), Eq(iox::popo::ChunkReceiveResult::TOO_MANY_CHUNKS_HELD_IN_PARALLEL)); } @@ -175,10 +173,8 @@ TEST_F(ChunkReceiver_test, releaseInvalidChunk) m_chunkQueuePusher.push(sharedChunk); auto maybeChunkHeader = m_chunkReceiver.tryGet(); - EXPECT_FALSE(maybeChunkHeader.has_error()); - EXPECT_TRUE((*maybeChunkHeader).has_value()); - - EXPECT_TRUE(sharedChunk.getPayload() == (**maybeChunkHeader)->payload()); + ASSERT_FALSE(maybeChunkHeader.has_error()); + EXPECT_TRUE(sharedChunk.getPayload() == (*maybeChunkHeader)->payload()); } auto errorHandlerCalled{false}; @@ -206,8 +202,7 @@ TEST_F(ChunkReceiver_test, Cleanup) if (i < iox::MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY) { auto maybeChunkHeader = m_chunkReceiver.tryGet(); - EXPECT_FALSE(maybeChunkHeader.has_error()); - EXPECT_TRUE((*maybeChunkHeader).has_value()); + ASSERT_FALSE(maybeChunkHeader.has_error()); } } diff --git a/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp b/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp index 26642a5a606..32898f6f78f 100644 --- a/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -75,10 +76,10 @@ TEST_F(SubscriberPortSingleProducer_test, initialStateNotSubscribed) TEST_F(SubscriberPortSingleProducer_test, initialStateNoChunksAvailable) { - auto maybeChunk = m_sutUserSideSingleProducer.tryGetChunk(); + auto maybeChunkHeader = m_sutUserSideSingleProducer.tryGetChunk(); - EXPECT_FALSE(maybeChunk.has_error()); - EXPECT_FALSE(maybeChunk.value().has_value()); + ASSERT_TRUE(maybeChunkHeader.has_error()); + EXPECT_EQ(maybeChunkHeader.get_error(), iox::popo::ChunkReceiveResult::NO_CHUNK_AVAILABLE); EXPECT_FALSE(m_sutUserSideSingleProducer.hasNewChunks()); } From 898cdc2da1bd71d404292dec53672ee4a3df6308 Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Thu, 25 Feb 2021 10:04:13 +0100 Subject: [PATCH 075/143] iox-#408 basic chunkheader test in c api Signed-off-by: Matthias Killat --- .../include/iceoryx_binding_c/chunk.h | 8 +++---- .../test/moduletests/test_publisher.cpp | 19 ++++++++++++++- .../test/moduletests/test_subscriber.cpp | 24 +++++++++++++++++-- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/chunk.h b/iceoryx_binding_c/include/iceoryx_binding_c/chunk.h index 3ce03458a37..43a7afb2b3f 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/chunk.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/chunk.h @@ -19,10 +19,10 @@ #include "iceoryx_binding_c/internal/c2cpp_binding.h" -///@todo: we will need a way to access the chunkheader properly, -/// define a structure for it and decide on functions operating on it -/// (cf. chunkheader.hpp) -/// otherwise you need C++ to do anything with the header safely +/// @note: currently we can only use this header safely with the corresponding +/// C++ ChunkHeader which defines the data layout +/// once the functionality of the header is stable we can +/// add free functions here to access its information /// consider to define void* payload_t as well diff --git a/iceoryx_binding_c/test/moduletests/test_publisher.cpp b/iceoryx_binding_c/test/moduletests/test_publisher.cpp index 6ad3bd22c7b..68bae31a53f 100644 --- a/iceoryx_binding_c/test/moduletests/test_publisher.cpp +++ b/iceoryx_binding_c/test/moduletests/test_publisher.cpp @@ -28,6 +28,7 @@ using namespace iox::cxx; using namespace iox::posix; extern "C" { +#include "iceoryx_binding_c/chunk.h" #include "iceoryx_binding_c/publisher.h" } @@ -160,6 +161,23 @@ TEST_F(iox_pub_test, allocateChunkForOneChunkIsSuccessful) EXPECT_EQ(AllocationResult_SUCCESS, iox_pub_loan_chunk(&m_sut, &chunk, sizeof(DummySample))); } +TEST_F(iox_pub_test, chunkHeaderCanBeObtainedFromChunk) +{ + void* chunk = nullptr; + ASSERT_EQ(AllocationResult_SUCCESS, iox_pub_loan_chunk(&m_sut, &chunk, sizeof(DummySample))); + auto header = iox_chunk_payload_to_header(chunk); + EXPECT_NE(header, nullptr); +} + +TEST_F(iox_pub_test, chunkHeaderCanBeConvertedBackToPayload) +{ + void* chunk = nullptr; + ASSERT_EQ(AllocationResult_SUCCESS, iox_pub_loan_chunk(&m_sut, &chunk, sizeof(DummySample))); + auto header = iox_chunk_payload_to_header(chunk); + auto payload = iox_chunk_header_to_payload(header); + EXPECT_EQ(payload, chunk); +} + TEST_F(iox_pub_test, allocate_chunkFailsWhenHoldingToManyChunksInParallel) { void* chunk = nullptr; @@ -234,4 +252,3 @@ TEST_F(iox_pub_test, sendDeliversChunk) EXPECT_TRUE(*maybeSharedChunk == chunk); EXPECT_TRUE(static_cast(maybeSharedChunk->getPayload())->dummy == 4711); } - diff --git a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp index 7d19a36ceac..2ed3d3b166a 100644 --- a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp +++ b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp @@ -31,6 +31,7 @@ using namespace iox::cxx; using namespace iox::posix; extern "C" { +#include "iceoryx_binding_c/chunk.h" #include "iceoryx_binding_c/subscriber.h" #include "iceoryx_binding_c/types.h" #include "iceoryx_binding_c/wait_set.h" @@ -187,6 +188,26 @@ TEST_F(iox_sub_test, receiveChunkWithContent) EXPECT_THAT(static_cast(chunk)->value, Eq(1234)); } +TEST_F(iox_sub_test, chunkHeaderCanBeObtainedFromChunkAfterTake) +{ + this->Subscribe(&m_portPtr); + struct data_t + { + int value; + }; + + auto sharedChunk = m_memoryManager.getChunk(100U); + m_chunkPusher.push(sharedChunk); + + const void* chunk = nullptr; + + ASSERT_EQ(iox_sub_take_chunk(m_sut, &chunk), ChunkReceiveResult_SUCCESS); + auto header = iox_chunk_payload_to_header(chunk); + ASSERT_NE(header, nullptr); + auto payload = iox_chunk_header_to_payload(header); + EXPECT_EQ(payload, chunk); +} + TEST_F(iox_sub_test, receiveChunkWhenToManyChunksAreHold) { this->Subscribe(&m_portPtr); @@ -295,8 +316,7 @@ TEST_F(iox_sub_test, hasDataTriggersWaitSetWithCorrectEventId) TEST_F(iox_sub_test, hasDataTriggersWaitSetWithCorrectCallback) { - iox_ws_attach_subscriber_event( - m_waitSet.get(), m_sut, SubscriberEvent_HAS_DATA, 0U, iox_sub_test::triggerCallback); + iox_ws_attach_subscriber_event(m_waitSet.get(), m_sut, SubscriberEvent_HAS_DATA, 0U, iox_sub_test::triggerCallback); this->Subscribe(&m_portPtr); m_chunkPusher.push(m_memoryManager.getChunk(100U)); From 900d3d67eed01bc72cf8131f2b23bbe98a072d87 Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Mon, 1 Mar 2021 11:24:10 +0100 Subject: [PATCH 076/143] iox-#408 fixed documentation and copyrights Signed-off-by: Matthias Killat --- iceoryx_binding_c/CMakeLists.txt | 3 ++- iceoryx_binding_c/include/iceoryx_binding_c/chunk.h | 11 ++--------- iceoryx_binding_c/include/iceoryx_binding_c/enums.h | 3 ++- .../include/iceoryx_binding_c/publisher.h | 4 ++-- .../include/iceoryx_binding_c/subscriber.h | 6 +++--- iceoryx_binding_c/source/c_publisher.cpp | 3 ++- iceoryx_binding_c/source/c_subscriber.cpp | 4 ++-- iceoryx_binding_c/source/cpp2c_enum_translation.cpp | 3 ++- .../test/moduletests/test_cpp2c_enum_translation.cpp | 3 ++- iceoryx_binding_c/test/moduletests/test_publisher.cpp | 3 ++- .../test/moduletests/test_subscriber.cpp | 3 ++- .../internal/popo/building_blocks/chunk_receiver.hpp | 1 + .../internal/popo/building_blocks/chunk_receiver.inl | 1 + .../source/popo/ports/subscriber_port_user.cpp | 1 + 14 files changed, 26 insertions(+), 23 deletions(-) diff --git a/iceoryx_binding_c/CMakeLists.txt b/iceoryx_binding_c/CMakeLists.txt index 72965cf965e..15fbf96e5cb 100644 --- a/iceoryx_binding_c/CMakeLists.txt +++ b/iceoryx_binding_c/CMakeLists.txt @@ -1,4 +1,5 @@ -# Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +# Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +# Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/chunk.h b/iceoryx_binding_c/include/iceoryx_binding_c/chunk.h index 43a7afb2b3f..936bb301ed9 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/chunk.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/chunk.h @@ -19,23 +19,16 @@ #include "iceoryx_binding_c/internal/c2cpp_binding.h" -/// @note: currently we can only use this header safely with the corresponding -/// C++ ChunkHeader which defines the data layout -/// once the functionality of the header is stable we can -/// add free functions here to access its information - -/// consider to define void* payload_t as well - /// @brief handle of the chunk header typedef void* iox_chunk_header_t; /// @brief gets the payload from the chunk header -/// @param[in] pointer to the chunk header +/// @param[in] header pointer to the chunk header /// @return pointer to the payload void* iox_chunk_header_to_payload(iox_chunk_header_t const header); /// @brief gets the chunk header from the payload -/// @param[in] pointer to the payload +/// @param[in] payload pointer to the payload /// @return pointer to the chunk header iox_chunk_header_t iox_chunk_payload_to_header(const void* const payload); diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/enums.h b/iceoryx_binding_c/include/iceoryx_binding_c/enums.h index 9f3e37b3367..e50691c3eec 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/enums.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/enums.h @@ -1,4 +1,5 @@ -// Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h index 77d04057300..e43d495f1ec 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h @@ -1,4 +1,5 @@ -// Copyright (c) 2020, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -41,7 +42,6 @@ typedef struct /// @param[in] event eventString /// @param[in] options publisher options set by the user /// @return handle of the publisher -/// @attention the options must be set to valid values iox_pub_t iox_pub_init(iox_pub_storage_t* self, const char* const service, const char* const instance, diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h index 0503e976016..5a4bd31956e 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h @@ -1,4 +1,5 @@ -// Copyright (c) 2020, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -42,9 +43,8 @@ typedef struct /// @param[in] service serviceString /// @param[in] instance instanceString /// @param[in] event eventString -/// @param[in] options publisher options set by the user +/// @param[in] options subscriber options set by the user /// @return handle of the subscriber -/// @attention the options must be set to valid values iox_sub_t iox_sub_init(iox_sub_storage_t* self, const char* const service, const char* const instance, diff --git a/iceoryx_binding_c/source/c_publisher.cpp b/iceoryx_binding_c/source/c_publisher.cpp index a0983e2b1cf..3ef85056568 100644 --- a/iceoryx_binding_c/source/c_publisher.cpp +++ b/iceoryx_binding_c/source/c_publisher.cpp @@ -1,4 +1,5 @@ -// Copyright (c) 2020, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_binding_c/source/c_subscriber.cpp b/iceoryx_binding_c/source/c_subscriber.cpp index 4f4e218f711..86a461a631b 100644 --- a/iceoryx_binding_c/source/c_subscriber.cpp +++ b/iceoryx_binding_c/source/c_subscriber.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2020, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. -// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_binding_c/source/cpp2c_enum_translation.cpp b/iceoryx_binding_c/source/cpp2c_enum_translation.cpp index 696b6deb82b..c5ee83032e0 100644 --- a/iceoryx_binding_c/source/cpp2c_enum_translation.cpp +++ b/iceoryx_binding_c/source/cpp2c_enum_translation.cpp @@ -1,4 +1,5 @@ -// Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_binding_c/test/moduletests/test_cpp2c_enum_translation.cpp b/iceoryx_binding_c/test/moduletests/test_cpp2c_enum_translation.cpp index 66b27266081..4973f253ecd 100644 --- a/iceoryx_binding_c/test/moduletests/test_cpp2c_enum_translation.cpp +++ b/iceoryx_binding_c/test/moduletests/test_cpp2c_enum_translation.cpp @@ -1,4 +1,5 @@ -// Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_binding_c/test/moduletests/test_publisher.cpp b/iceoryx_binding_c/test/moduletests/test_publisher.cpp index 68bae31a53f..c2e42919360 100644 --- a/iceoryx_binding_c/test/moduletests/test_publisher.cpp +++ b/iceoryx_binding_c/test/moduletests/test_publisher.cpp @@ -1,4 +1,5 @@ -// Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp index 2ed3d3b166a..900fe65a7ae 100644 --- a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp +++ b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp @@ -1,4 +1,5 @@ -// Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_receiver.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_receiver.hpp index db6203a842f..219f4ac2f72 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_receiver.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_receiver.hpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_receiver.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_receiver.inl index 97a27204132..4227f16195a 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_receiver.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_receiver.inl @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp b/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp index 88fb47036c9..6120130d337 100644 --- a/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp +++ b/iceoryx_posh/source/popo/ports/subscriber_port_user.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. From 51bdc8d148512c3ffca491b772890fe055159515 Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Mon, 1 Mar 2021 14:07:35 +0100 Subject: [PATCH 077/143] iox-#408 renaming of pub and sub options Signed-off-by: Matthias Killat --- iceoryx_binding_c/include/iceoryx_binding_c/publisher.h | 4 ++-- iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h | 4 ++-- iceoryx_binding_c/source/c_publisher.cpp | 2 +- iceoryx_binding_c/source/c_subscriber.cpp | 2 +- iceoryx_examples/icedelivery_in_c/README.md | 4 ++-- iceoryx_examples/icedelivery_in_c/ice_c_publisher.c | 2 +- iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c | 2 +- iceoryx_examples/iceperf/iceoryx_c.cpp | 4 ++-- iceoryx_examples/waitset_in_c/README.md | 6 +++--- iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c | 2 +- iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c | 2 +- iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c | 2 +- iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c | 2 +- 13 files changed, 19 insertions(+), 19 deletions(-) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h index e43d495f1ec..ca43e476f4a 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h @@ -33,7 +33,7 @@ typedef struct // name of the node the publisher belongs to const char* nodeName; -} iox_publisher_options_t; +} iox_pub_options_t; /// @brief creates a publisher handle /// @param[in] self pointer to preallocated memory of size = sizeof(iox_pub_storage_t) @@ -46,7 +46,7 @@ iox_pub_t iox_pub_init(iox_pub_storage_t* self, const char* const service, const char* const instance, const char* const event, - const iox_publisher_options_t options); + const iox_pub_options_t options); /// @brief removes a publisher handle /// @param[in] self the handle which should be removed diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h index 5a4bd31956e..706b1a3d447 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h @@ -36,7 +36,7 @@ typedef struct // name of the node the subscriber belongs to const char* nodeName; -} iox_subscriber_options_t; +} iox_sub_options_t; /// @brief initialize subscriber handle /// @param[in] self pointer to preallocated memory of size = sizeof(iox_sub_storage_t) @@ -49,7 +49,7 @@ iox_sub_t iox_sub_init(iox_sub_storage_t* self, const char* const service, const char* const instance, const char* const event, - const iox_subscriber_options_t options); + const iox_sub_options_t options); /// @brief deinitialize a subscriber handle /// @param[in] self the handle which should be removed diff --git a/iceoryx_binding_c/source/c_publisher.cpp b/iceoryx_binding_c/source/c_publisher.cpp index 3ef85056568..374d291905e 100644 --- a/iceoryx_binding_c/source/c_publisher.cpp +++ b/iceoryx_binding_c/source/c_publisher.cpp @@ -35,7 +35,7 @@ iox_pub_t iox_pub_init(iox_pub_storage_t* self, const char* const service, const char* const instance, const char* const event, - const iox_publisher_options_t options) + const iox_pub_options_t options) { new (self) cpp2c_Publisher(); iox_pub_t me = reinterpret_cast(self); diff --git a/iceoryx_binding_c/source/c_subscriber.cpp b/iceoryx_binding_c/source/c_subscriber.cpp index 86a461a631b..d75e8c8c2e8 100644 --- a/iceoryx_binding_c/source/c_subscriber.cpp +++ b/iceoryx_binding_c/source/c_subscriber.cpp @@ -40,7 +40,7 @@ iox_sub_t iox_sub_init(iox_sub_storage_t* self, const char* const service, const char* const instance, const char* const event, - const iox_subscriber_options_t options) + const iox_sub_options_t options) { new (self) cpp2c_Subscriber(); iox_sub_t me = reinterpret_cast(self); diff --git a/iceoryx_examples/icedelivery_in_c/README.md b/iceoryx_examples/icedelivery_in_c/README.md index 95415954011..a5d14738803 100644 --- a/iceoryx_examples/icedelivery_in_c/README.md +++ b/iceoryx_examples/icedelivery_in_c/README.md @@ -46,7 +46,7 @@ Let's take a look at the `receiving` function which comes with the The `subscriberStorage` is the place where the subscriber is stored in memory and `subscriber` is actually a pointer to that location. ```c - iox_subscriber_options_t options; + iox_sub_options_t options; options.historyRequest = 10U; options.queueCapacity = 5U; options.nodeName = "iox-c-subscriber-node"; @@ -118,7 +118,7 @@ Let's take a look at the `sending` function which comes with the 2. We create a publisher with the service {"Radar", "FrontLeft", "Counter"} ```c - iox_publisher_options_t options; + iox_pub_options_t options; options.historyCapacity = 10U; options.nodeName = "iox-c-publisher-node"; iox_pub_storage_t publisherStorage; diff --git a/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c b/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c index e6b841f5e6c..6cb2d074716 100644 --- a/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c +++ b/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c @@ -37,7 +37,7 @@ void sending() { iox_runtime_init("iox-c-publisher"); - iox_publisher_options_t options; + iox_pub_options_t options; options.historyCapacity = 10U; options.nodeName = "iox-c-publisher-node"; iox_pub_storage_t publisherStorage; diff --git a/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c b/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c index c51ad64be7a..c2b7f7e04ea 100644 --- a/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c +++ b/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c @@ -41,7 +41,7 @@ void receiving() // When starting the subscriber late it will miss the first samples which the // publisher has send. The history ensures that we at least get the last 10 // samples send by the publisher when we subscribe. - iox_subscriber_options_t options; + iox_sub_options_t options; options.historyRequest = 10U; options.queueCapacity = 5U; options.nodeName = "iox-c-subscriber-node"; diff --git a/iceoryx_examples/iceperf/iceoryx_c.cpp b/iceoryx_examples/iceperf/iceoryx_c.cpp index a514b1dd082..ba6fcc3809c 100644 --- a/iceoryx_examples/iceperf/iceoryx_c.cpp +++ b/iceoryx_examples/iceperf/iceoryx_c.cpp @@ -21,12 +21,12 @@ IceoryxC::IceoryxC(const iox::capro::IdString_t& publisherName, const iox::capro::IdString_t& subscriberName) noexcept { - iox_publisher_options_t publisherOptions; + iox_pub_options_t publisherOptions; publisherOptions.historyCapacity = 0U; publisherOptions.nodeName = "SlapStick"; m_publisher = iox_pub_init(&m_publisherStorage, "Comedians", publisherName.c_str(), "Duo", publisherOptions); - iox_subscriber_options_t subscriberOptions; + iox_sub_options_t subscriberOptions; subscriberOptions.queueCapacity = 10U; subscriberOptions.historyRequest = 0U; subscriberOptions.nodeName = "Slapstick"; diff --git a/iceoryx_examples/waitset_in_c/README.md b/iceoryx_examples/waitset_in_c/README.md index 194648b0835..8b8b16bb6d4 100644 --- a/iceoryx_examples/waitset_in_c/README.md +++ b/iceoryx_examples/waitset_in_c/README.md @@ -58,7 +58,7 @@ the `subscriberCallback` and an event id `1U`. ```c iox_sub_storage_t subscriberStorage[NUMBER_OF_SUBSCRIBERS]; -iox_subscriber_options_t options; +iox_sub_options_t options; options.historyRequest = 1U; options.queueCapacity = 256U; options.nodeName = "iox-c-ex-waitSet-gateway-node"; @@ -142,7 +142,7 @@ After that we can create a list of subscribers and subscribe them to our topic. iox_sub_storage_t subscriberStorage[NUMBER_OF_SUBSCRIBERS]; iox_sub_t subscriber[NUMBER_OF_SUBSCRIBERS]; -iox_subscriber_options_t options; +iox_sub_options_t options; options.historyRequest = 1U; options.queueCapacity = 256U; options.nodeName = "iox-c-ex-waitset-grouping-node"; @@ -254,7 +254,7 @@ iox_ws_attach_user_trigger_event(waitSet, shutdownTrigger, 0U, NULL); Now we create two subscriber, subscribe them to our topic and attach them to the waitset without a callback and with the same trigger id. ```c -iox_subscriber_options_t options1, options2; +iox_sub_options_t options1, options2; options1.historyRequest = 1U; options1.queueCapacity = 256U; options1.nodeName = "iox-c-ex-waitset-individual-node1"; diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c index 69cf1d54771..83892096404 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c @@ -76,7 +76,7 @@ int main() // create subscriber and subscribe them to our service - iox_subscriber_options_t options; + iox_sub_options_t options; options.historyRequest = 1U; options.queueCapacity = 256U; options.nodeName = "iox-c-ex-waitSet-gateway-node"; diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c index 01fce822f31..b408edb53c1 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c @@ -61,7 +61,7 @@ int main() iox_sub_t subscriber[NUMBER_OF_SUBSCRIBERS]; // create subscriber and subscribe them to our service - iox_subscriber_options_t options; + iox_sub_options_t options; options.historyRequest = 1U; options.queueCapacity = 256U; options.nodeName = "iox-c-ex-waitset-grouping-node"; diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c index 569e1eefa63..ba3bf2fc575 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c @@ -61,7 +61,7 @@ int main() iox_sub_t subscriber[NUMBER_OF_SUBSCRIBERS]; // create two subscribers, subscribe to the service and attach them to the waitset - iox_subscriber_options_t options1, options2; + iox_sub_options_t options1, options2; options1.historyRequest = 1U; options1.queueCapacity = 256U; options1.nodeName = "iox-c-ex-waitset-individual-node1"; diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c index fb02ea9a44d..26455fc6d5c 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c @@ -37,7 +37,7 @@ void sending() { iox_runtime_init("iox-c-ex-waitset-publisher"); - iox_publisher_options_t options; + iox_pub_options_t options; options.historyCapacity = 0U; options.nodeName = "iox-c-ex-waitset-publisher-node"; iox_pub_storage_t publisherStorage; From e9f3fef50225718008af98900bcac33703d7d3dd Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Mon, 1 Mar 2021 14:28:10 +0100 Subject: [PATCH 078/143] iox-#408 pub options init Signed-off-by: Matthias Killat --- .../include/iceoryx_binding_c/publisher.h | 6 +++++- iceoryx_binding_c/source/c_publisher.cpp | 17 ++++++++++++++--- iceoryx_examples/icedelivery_in_c/README.md | 3 ++- .../icedelivery_in_c/ice_c_publisher.c | 3 ++- iceoryx_examples/iceperf/iceoryx_c.cpp | 3 ++- .../waitset_in_c/ice_c_waitset_publisher.c | 3 ++- 6 files changed, 27 insertions(+), 8 deletions(-) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h index ca43e476f4a..0e269b688ed 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h @@ -35,6 +35,10 @@ typedef struct const char* nodeName; } iox_pub_options_t; +/// @brief initialize publisher options to default values +/// @param[in] options pointer to options to be initialized +void iox_pub_options_init(iox_pub_options_t* options); + /// @brief creates a publisher handle /// @param[in] self pointer to preallocated memory of size = sizeof(iox_pub_storage_t) /// @param[in] service serviceString @@ -46,7 +50,7 @@ iox_pub_t iox_pub_init(iox_pub_storage_t* self, const char* const service, const char* const instance, const char* const event, - const iox_pub_options_t options); + const iox_pub_options_t* const options); /// @brief removes a publisher handle /// @param[in] self the handle which should be removed diff --git a/iceoryx_binding_c/source/c_publisher.cpp b/iceoryx_binding_c/source/c_publisher.cpp index 374d291905e..5da225ddf98 100644 --- a/iceoryx_binding_c/source/c_publisher.cpp +++ b/iceoryx_binding_c/source/c_publisher.cpp @@ -31,17 +31,28 @@ extern "C" { #include "iceoryx_binding_c/publisher.h" } +void iox_pub_options_init(iox_pub_options_t* options) +{ + PublisherOptions publisherOptions; + options->historyCapacity = publisherOptions.historyCapacity; + options->nodeName = nullptr; +} + iox_pub_t iox_pub_init(iox_pub_storage_t* self, const char* const service, const char* const instance, const char* const event, - const iox_pub_options_t options) + const iox_pub_options_t* const options) { new (self) cpp2c_Publisher(); iox_pub_t me = reinterpret_cast(self); PublisherOptions publisherOptions; - publisherOptions.historyCapacity = options.historyCapacity; - publisherOptions.nodeName = NodeName_t(TruncateToCapacity, options.nodeName); + publisherOptions.historyCapacity = options->historyCapacity; + if (options->nodeName != nullptr) + { + publisherOptions.nodeName = NodeName_t(TruncateToCapacity, options->nodeName); + } + me->m_portData = PoshRuntime::getInstance().getMiddlewarePublisher( ServiceDescription{ IdString_t(TruncateToCapacity, service), diff --git a/iceoryx_examples/icedelivery_in_c/README.md b/iceoryx_examples/icedelivery_in_c/README.md index a5d14738803..31dfbd4a8a6 100644 --- a/iceoryx_examples/icedelivery_in_c/README.md +++ b/iceoryx_examples/icedelivery_in_c/README.md @@ -119,10 +119,11 @@ Let's take a look at the `sending` function which comes with the {"Radar", "FrontLeft", "Counter"} ```c iox_pub_options_t options; + iox_pub_options_init(&options); options.historyCapacity = 10U; options.nodeName = "iox-c-publisher-node"; iox_pub_storage_t publisherStorage; - iox_pub_t publisher = iox_pub_init(&publisherStorage, "Radar", "FrontLeft", "Object", options); + iox_pub_t publisher = iox_pub_init(&publisherStorage, "Radar", "FrontLeft", "Object", &options); ``` 3. We offer our service to the world. ```c diff --git a/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c b/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c index 6cb2d074716..2c10b9887dd 100644 --- a/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c +++ b/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c @@ -38,10 +38,11 @@ void sending() iox_runtime_init("iox-c-publisher"); iox_pub_options_t options; + iox_pub_options_init(&options); options.historyCapacity = 10U; options.nodeName = "iox-c-publisher-node"; iox_pub_storage_t publisherStorage; - iox_pub_t publisher = iox_pub_init(&publisherStorage, "Radar", "FrontLeft", "Object", options); + iox_pub_t publisher = iox_pub_init(&publisherStorage, "Radar", "FrontLeft", "Object", &options); iox_pub_offer(publisher); diff --git a/iceoryx_examples/iceperf/iceoryx_c.cpp b/iceoryx_examples/iceperf/iceoryx_c.cpp index ba6fcc3809c..78f2d011771 100644 --- a/iceoryx_examples/iceperf/iceoryx_c.cpp +++ b/iceoryx_examples/iceperf/iceoryx_c.cpp @@ -22,9 +22,10 @@ IceoryxC::IceoryxC(const iox::capro::IdString_t& publisherName, const iox::capro::IdString_t& subscriberName) noexcept { iox_pub_options_t publisherOptions; + iox_pub_options_init(&publisherOptions); publisherOptions.historyCapacity = 0U; publisherOptions.nodeName = "SlapStick"; - m_publisher = iox_pub_init(&m_publisherStorage, "Comedians", publisherName.c_str(), "Duo", publisherOptions); + m_publisher = iox_pub_init(&m_publisherStorage, "Comedians", publisherName.c_str(), "Duo", &publisherOptions); iox_sub_options_t subscriberOptions; subscriberOptions.queueCapacity = 10U; diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c index 26455fc6d5c..d766651624f 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c @@ -38,10 +38,11 @@ void sending() iox_runtime_init("iox-c-ex-waitset-publisher"); iox_pub_options_t options; + iox_pub_options_init(&options); options.historyCapacity = 0U; options.nodeName = "iox-c-ex-waitset-publisher-node"; iox_pub_storage_t publisherStorage; - iox_pub_t publisher = iox_pub_init(&publisherStorage, "Radar", "FrontLeft", "Counter", options); + iox_pub_t publisher = iox_pub_init(&publisherStorage, "Radar", "FrontLeft", "Counter", &options); iox_pub_offer(publisher); From 6d5ec2d08898ead6d37ff3f6bfd43d0292c77afa Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Mon, 1 Mar 2021 14:43:34 +0100 Subject: [PATCH 079/143] iox-#408 sub options init Signed-off-by: Matthias Killat --- .../include/iceoryx_binding_c/subscriber.h | 6 ++++- iceoryx_binding_c/source/c_subscriber.cpp | 20 ++++++++++++---- iceoryx_examples/icedelivery_in_c/README.md | 3 ++- .../icedelivery_in_c/ice_c_subscriber.c | 3 ++- iceoryx_examples/iceperf/iceoryx_c.cpp | 3 ++- iceoryx_examples/waitset_in_c/README.md | 24 +++++++++---------- .../waitset_in_c/ice_c_waitset_gateway.c | 3 ++- .../waitset_in_c/ice_c_waitset_grouping.c | 3 ++- .../waitset_in_c/ice_c_waitset_individual.c | 19 +++++++-------- 9 files changed, 52 insertions(+), 32 deletions(-) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h index 706b1a3d447..eb39f5a9f4b 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h @@ -38,6 +38,10 @@ typedef struct const char* nodeName; } iox_sub_options_t; +/// @brief initialize subscriber options to default values +/// @param[in] options pointer to options to be initialized +void iox_sub_options_init(iox_sub_options_t* const options); + /// @brief initialize subscriber handle /// @param[in] self pointer to preallocated memory of size = sizeof(iox_sub_storage_t) /// @param[in] service serviceString @@ -49,7 +53,7 @@ iox_sub_t iox_sub_init(iox_sub_storage_t* self, const char* const service, const char* const instance, const char* const event, - const iox_sub_options_t options); + const iox_sub_options_t* const options); /// @brief deinitialize a subscriber handle /// @param[in] self the handle which should be removed diff --git a/iceoryx_binding_c/source/c_subscriber.cpp b/iceoryx_binding_c/source/c_subscriber.cpp index d75e8c8c2e8..6743f6c1bed 100644 --- a/iceoryx_binding_c/source/c_subscriber.cpp +++ b/iceoryx_binding_c/source/c_subscriber.cpp @@ -36,18 +36,30 @@ extern "C" { #include "iceoryx_binding_c/subscriber.h" } +void iox_sub_options_init(iox_sub_options_t* options) +{ + SubscriberOptions subscriberOptions; + options->queueCapacity = subscriberOptions.queueCapacity; + options->historyRequest = subscriberOptions.historyRequest; + options->nodeName = nullptr; +} + iox_sub_t iox_sub_init(iox_sub_storage_t* self, const char* const service, const char* const instance, const char* const event, - const iox_sub_options_t options) + const iox_sub_options_t* const options) { new (self) cpp2c_Subscriber(); iox_sub_t me = reinterpret_cast(self); SubscriberOptions subscriberOptions; - subscriberOptions.queueCapacity = options.queueCapacity; - subscriberOptions.historyRequest = options.historyRequest; - subscriberOptions.nodeName = NodeName_t(TruncateToCapacity, options.nodeName); + subscriberOptions.queueCapacity = options->queueCapacity; + subscriberOptions.historyRequest = options->historyRequest; + if (options->nodeName != nullptr) + { + subscriberOptions.nodeName = NodeName_t(TruncateToCapacity, options->nodeName); + } + me->m_portData = PoshRuntime::getInstance().getMiddlewareSubscriber(ServiceDescription{IdString_t(TruncateToCapacity, service), IdString_t(TruncateToCapacity, instance), diff --git a/iceoryx_examples/icedelivery_in_c/README.md b/iceoryx_examples/icedelivery_in_c/README.md index 31dfbd4a8a6..228e4e1491e 100644 --- a/iceoryx_examples/icedelivery_in_c/README.md +++ b/iceoryx_examples/icedelivery_in_c/README.md @@ -47,12 +47,13 @@ Let's take a look at the `receiving` function which comes with the memory and `subscriber` is actually a pointer to that location. ```c iox_sub_options_t options; + iox_sub_options_init(&options); options.historyRequest = 10U; options.queueCapacity = 5U; options.nodeName = "iox-c-subscriber-node"; iox_sub_storage_t subscriberStorage; - iox_sub_t subscriber = iox_sub_init(&subscriberStorage, "Radar", "FrontLeft", "Object", options); + iox_sub_t subscriber = iox_sub_init(&subscriberStorage, "Radar", "FrontLeft", "Object", &options); ``` 3. We subscribe to the service. diff --git a/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c b/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c index c2b7f7e04ea..cd774c5fa86 100644 --- a/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c +++ b/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c @@ -42,13 +42,14 @@ void receiving() // publisher has send. The history ensures that we at least get the last 10 // samples send by the publisher when we subscribe. iox_sub_options_t options; + iox_sub_options_init(&options); options.historyRequest = 10U; options.queueCapacity = 5U; options.nodeName = "iox-c-subscriber-node"; iox_sub_storage_t subscriberStorage; iox_sub_t subscriber = - iox_sub_init(&subscriberStorage, "Radar", "FrontLeft", "Object", options); + iox_sub_init(&subscriberStorage, "Radar", "FrontLeft", "Object", &options); iox_sub_subscribe(subscriber); while (!killswitch) diff --git a/iceoryx_examples/iceperf/iceoryx_c.cpp b/iceoryx_examples/iceperf/iceoryx_c.cpp index 78f2d011771..306363a1cbf 100644 --- a/iceoryx_examples/iceperf/iceoryx_c.cpp +++ b/iceoryx_examples/iceperf/iceoryx_c.cpp @@ -28,10 +28,11 @@ IceoryxC::IceoryxC(const iox::capro::IdString_t& publisherName, const iox::capro m_publisher = iox_pub_init(&m_publisherStorage, "Comedians", publisherName.c_str(), "Duo", &publisherOptions); iox_sub_options_t subscriberOptions; + iox_sub_options_init(&subscriberOptions); subscriberOptions.queueCapacity = 10U; subscriberOptions.historyRequest = 0U; subscriberOptions.nodeName = "Slapstick"; - m_subscriber = iox_sub_init(&m_subscriberStorage, "Comedians", subscriberName.c_str(), "Duo", subscriberOptions); + m_subscriber = iox_sub_init(&m_subscriberStorage, "Comedians", subscriberName.c_str(), "Duo", &subscriberOptions); } IceoryxC::~IceoryxC() diff --git a/iceoryx_examples/waitset_in_c/README.md b/iceoryx_examples/waitset_in_c/README.md index 8b8b16bb6d4..1fb1e7e18ba 100644 --- a/iceoryx_examples/waitset_in_c/README.md +++ b/iceoryx_examples/waitset_in_c/README.md @@ -59,12 +59,13 @@ the `subscriberCallback` and an event id `1U`. iox_sub_storage_t subscriberStorage[NUMBER_OF_SUBSCRIBERS]; iox_sub_options_t options; +iox_sub_options_init(&options); options.historyRequest = 1U; options.queueCapacity = 256U; options.nodeName = "iox-c-ex-waitSet-gateway-node"; for (uint64_t i = 0U; i < NUMBER_OF_SUBSCRIBERS; ++i) { - iox_sub_t subscriber = iox_sub_init(&(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", options); + iox_sub_t subscriber = iox_sub_init(&(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", &options); iox_sub_subscribe(subscriber); iox_ws_attach_subscriber_event(waitSet, subscriber, SubscriberEvent_HAS_DATA, 1U, subscriberCallback); @@ -143,12 +144,13 @@ iox_sub_storage_t subscriberStorage[NUMBER_OF_SUBSCRIBERS]; iox_sub_t subscriber[NUMBER_OF_SUBSCRIBERS]; iox_sub_options_t options; +iox_sub_options_init(&options); options.historyRequest = 1U; options.queueCapacity = 256U; options.nodeName = "iox-c-ex-waitset-grouping-node"; for (uint64_t i = 0U; i < NUMBER_OF_SUBSCRIBERS; ++i) { - subscriber[i] = iox_sub_init(&(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", options); + subscriber[i] = iox_sub_init(&(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", &options); iox_sub_subscribe(subscriber[i]); } @@ -254,17 +256,15 @@ iox_ws_attach_user_trigger_event(waitSet, shutdownTrigger, 0U, NULL); Now we create two subscriber, subscribe them to our topic and attach them to the waitset without a callback and with the same trigger id. ```c -iox_sub_options_t options1, options2; -options1.historyRequest = 1U; -options1.queueCapacity = 256U; -options1.nodeName = "iox-c-ex-waitset-individual-node1"; +iox_sub_options_t options; +iox_sub_options_init(&options); +options.historyRequest = 1U; +options.queueCapacity = 256U; +options.nodeName = "iox-c-ex-waitset-individual-node1"; -options2.historyRequest = 1U; -options2.queueCapacity = 256U; -options2.nodeName = "iox-c-ex-waitset-individual-node2"; - -subscriber[0] = iox_sub_init(&(subscriberStorage[0]), "Radar", "FrontLeft", "Counter", options1); -subscriber[1] = iox_sub_init(&(subscriberStorage[1]), "Radar", "FrontLeft", "Counter", options2); +subscriber[0] = iox_sub_init(&(subscriberStorage[0]), "Radar", "FrontLeft", "Counter", &options); +options.nodeName = "iox-c-ex-waitset-individual-node2"; +subscriber[1] = iox_sub_init(&(subscriberStorage[1]), "Radar", "FrontLeft", "Counter", &options); iox_sub_subscribe(subscriber[0]); iox_sub_subscribe(subscriber[1]); diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c index 83892096404..697c5a3c451 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c @@ -77,13 +77,14 @@ int main() // create subscriber and subscribe them to our service iox_sub_options_t options; + iox_sub_options_init(&options); options.historyRequest = 1U; options.queueCapacity = 256U; options.nodeName = "iox-c-ex-waitSet-gateway-node"; for (uint64_t i = 0U; i < NUMBER_OF_SUBSCRIBERS; ++i) { iox_sub_t subscriber = iox_sub_init( - &(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", options); + &(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", &options); iox_sub_subscribe(subscriber); iox_ws_attach_subscriber_event(waitSet, subscriber, SubscriberEvent_HAS_DATA, 1U, subscriberCallback); diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c index b408edb53c1..2400fda6eec 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c @@ -62,13 +62,14 @@ int main() // create subscriber and subscribe them to our service iox_sub_options_t options; + iox_sub_options_init(&options); options.historyRequest = 1U; options.queueCapacity = 256U; options.nodeName = "iox-c-ex-waitset-grouping-node"; for (uint64_t i = 0U; i < NUMBER_OF_SUBSCRIBERS; ++i) { subscriber[i] = iox_sub_init( - &(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", options); + &(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", &options); iox_sub_subscribe(subscriber[i]); } diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c index ba3bf2fc575..47211e2afe6 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c @@ -61,19 +61,18 @@ int main() iox_sub_t subscriber[NUMBER_OF_SUBSCRIBERS]; // create two subscribers, subscribe to the service and attach them to the waitset - iox_sub_options_t options1, options2; - options1.historyRequest = 1U; - options1.queueCapacity = 256U; - options1.nodeName = "iox-c-ex-waitset-individual-node1"; - - options2.historyRequest = 1U; - options2.queueCapacity = 256U; - options2.nodeName = "iox-c-ex-waitset-individual-node2"; + iox_sub_options_t options; + iox_sub_options_init(&options); + options.historyRequest = 1U; + options.queueCapacity = 256U; + options.nodeName = "iox-c-ex-waitset-individual-node1"; subscriber[0] = iox_sub_init( - &(subscriberStorage[0]), "Radar", "FrontLeft", "Counter", options1); + &(subscriberStorage[0]), "Radar", "FrontLeft", "Counter", &options); + + options.nodeName = "iox-c-ex-waitset-individual-node2"; subscriber[1] = iox_sub_init( - &(subscriberStorage[1]), "Radar", "FrontLeft", "Counter", options2); + &(subscriberStorage[1]), "Radar", "FrontLeft", "Counter", &options); iox_sub_subscribe(subscriber[0]); iox_sub_subscribe(subscriber[1]); From 10a12add13e03d6cbe1dcfe68e4b5049792e97ba Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Mon, 1 Mar 2021 14:55:04 +0100 Subject: [PATCH 080/143] iox-#408 test option initialization Signed-off-by: Matthias Killat --- .../include/iceoryx_binding_c/publisher.h | 1 + .../include/iceoryx_binding_c/subscriber.h | 1 + .../test/moduletests/test_publisher.cpp | 13 +++++++++++++ .../test/moduletests/test_subscriber.cpp | 15 +++++++++++++++ 4 files changed, 30 insertions(+) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h index 0e269b688ed..dbf0b5fc049 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h @@ -32,6 +32,7 @@ typedef struct uint64_t historyCapacity; // name of the node the publisher belongs to + // nullptr indicates that the default node name is used const char* nodeName; } iox_pub_options_t; diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h index eb39f5a9f4b..4751f051f7b 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h @@ -32,6 +32,7 @@ typedef struct uint64_t queueCapacity; // number of chunks received after subscription if chunks are available + // nullptr indicates that the default node name is used uint64_t historyRequest; // name of the node the subscriber belongs to diff --git a/iceoryx_binding_c/test/moduletests/test_publisher.cpp b/iceoryx_binding_c/test/moduletests/test_publisher.cpp index c2e42919360..5756ce73ee4 100644 --- a/iceoryx_binding_c/test/moduletests/test_publisher.cpp +++ b/iceoryx_binding_c/test/moduletests/test_publisher.cpp @@ -253,3 +253,16 @@ TEST_F(iox_pub_test, sendDeliversChunk) EXPECT_TRUE(*maybeSharedChunk == chunk); EXPECT_TRUE(static_cast(maybeSharedChunk->getPayload())->dummy == 4711); } + +TEST_F(iox_pub_test, publisherOptionsAreInitializedCorrectly) +{ + iox_pub_options_t sut; + sut.historyCapacity = 37; + sut.nodeName = "DrGonzo"; + + PublisherOptions options; + + iox_pub_options_init(&sut); + EXPECT_EQ(sut.historyCapacity, options.historyCapacity); + EXPECT_EQ(sut.nodeName, nullptr); +} diff --git a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp index 900fe65a7ae..f21a2e422c5 100644 --- a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp +++ b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp @@ -343,3 +343,18 @@ TEST_F(iox_sub_test, deinitSubscriberDetachesTriggerFromWaitSet) free(subscriber); } + +TEST_F(iox_sub_test, subscriberOptionsAreInitializedCorrectly) +{ + iox_sub_options_t sut; + sut.queueCapacity = 37; + sut.historyRequest = 73; + sut.nodeName = "DrGonzo"; + + SubscriberOptions options; + + iox_sub_options_init(&sut); + EXPECT_EQ(sut.queueCapacity, options.queueCapacity); + EXPECT_EQ(sut.historyRequest, options.historyRequest); + EXPECT_EQ(sut.nodeName, nullptr); +} From a72c517bd7e323e4c7cc77b056ae10a7cce78a24 Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Mon, 1 Mar 2021 15:12:53 +0100 Subject: [PATCH 081/143] iox-#408 nullptr check in option initialization Signed-off-by: Matthias Killat --- iceoryx_binding_c/source/c_publisher.cpp | 5 +++++ iceoryx_binding_c/source/c_subscriber.cpp | 5 +++++ iceoryx_binding_c/test/moduletests/test_publisher.cpp | 6 ++++++ iceoryx_binding_c/test/moduletests/test_subscriber.cpp | 6 ++++++ 4 files changed, 22 insertions(+) diff --git a/iceoryx_binding_c/source/c_publisher.cpp b/iceoryx_binding_c/source/c_publisher.cpp index 5da225ddf98..d46a73a5e39 100644 --- a/iceoryx_binding_c/source/c_publisher.cpp +++ b/iceoryx_binding_c/source/c_publisher.cpp @@ -33,6 +33,11 @@ extern "C" { void iox_pub_options_init(iox_pub_options_t* options) { + if (options == nullptr) + { + return; + } + PublisherOptions publisherOptions; options->historyCapacity = publisherOptions.historyCapacity; options->nodeName = nullptr; diff --git a/iceoryx_binding_c/source/c_subscriber.cpp b/iceoryx_binding_c/source/c_subscriber.cpp index 6743f6c1bed..29aa6186d76 100644 --- a/iceoryx_binding_c/source/c_subscriber.cpp +++ b/iceoryx_binding_c/source/c_subscriber.cpp @@ -38,6 +38,11 @@ extern "C" { void iox_sub_options_init(iox_sub_options_t* options) { + if (options == nullptr) + { + return; + } + SubscriberOptions subscriberOptions; options->queueCapacity = subscriberOptions.queueCapacity; options->historyRequest = subscriberOptions.historyRequest; diff --git a/iceoryx_binding_c/test/moduletests/test_publisher.cpp b/iceoryx_binding_c/test/moduletests/test_publisher.cpp index 5756ce73ee4..0a236a38bf8 100644 --- a/iceoryx_binding_c/test/moduletests/test_publisher.cpp +++ b/iceoryx_binding_c/test/moduletests/test_publisher.cpp @@ -266,3 +266,9 @@ TEST_F(iox_pub_test, publisherOptionsAreInitializedCorrectly) EXPECT_EQ(sut.historyCapacity, options.historyCapacity); EXPECT_EQ(sut.nodeName, nullptr); } + +TEST_F(iox_sub_test, publisherOptionInitializationWithNullptrDoesNotCrash) +{ + // we can only check that it compiles and executes without crashing + iox_pub_options_init(nullptr); +} diff --git a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp index f21a2e422c5..55f948ce886 100644 --- a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp +++ b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp @@ -358,3 +358,9 @@ TEST_F(iox_sub_test, subscriberOptionsAreInitializedCorrectly) EXPECT_EQ(sut.historyRequest, options.historyRequest); EXPECT_EQ(sut.nodeName, nullptr); } + +TEST_F(iox_sub_test, subscriberOptionInitializationWithNullptrDoesNotCrash) +{ + // we can only check that it compiles and executes without crashing + iox_sub_options_init(nullptr); +} From d896d575213697576f9c84f208fd0ba7d50d0c5a Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Mon, 1 Mar 2021 15:50:00 +0100 Subject: [PATCH 082/143] iox-#408 nullptr no death test Signed-off-by: Matthias Killat --- .../test/moduletests/test_publisher.cpp | 13 +++++++++---- .../test/moduletests/test_subscriber.cpp | 13 +++++++++---- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/iceoryx_binding_c/test/moduletests/test_publisher.cpp b/iceoryx_binding_c/test/moduletests/test_publisher.cpp index 0a236a38bf8..4d9e26166ff 100644 --- a/iceoryx_binding_c/test/moduletests/test_publisher.cpp +++ b/iceoryx_binding_c/test/moduletests/test_publisher.cpp @@ -254,7 +254,7 @@ TEST_F(iox_pub_test, sendDeliversChunk) EXPECT_TRUE(static_cast(maybeSharedChunk->getPayload())->dummy == 4711); } -TEST_F(iox_pub_test, publisherOptionsAreInitializedCorrectly) +TEST(iox_pub_options_test, publisherOptionsAreInitializedCorrectly) { iox_pub_options_t sut; sut.historyCapacity = 37; @@ -267,8 +267,13 @@ TEST_F(iox_pub_test, publisherOptionsAreInitializedCorrectly) EXPECT_EQ(sut.nodeName, nullptr); } -TEST_F(iox_sub_test, publisherOptionInitializationWithNullptrDoesNotCrash) +TEST(iox_pub_options_test, publisherOptionInitializationWithNullptrDoesNotCrash) { - // we can only check that it compiles and executes without crashing - iox_pub_options_init(nullptr); + EXPECT_EXIT( + { + iox_pub_options_init(nullptr); + exit(0); + }, + ::testing::ExitedWithCode(0), + ".*"); } diff --git a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp index 55f948ce886..565b815ceb4 100644 --- a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp +++ b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp @@ -344,7 +344,7 @@ TEST_F(iox_sub_test, deinitSubscriberDetachesTriggerFromWaitSet) free(subscriber); } -TEST_F(iox_sub_test, subscriberOptionsAreInitializedCorrectly) +TEST(iox_sub_options_test, subscriberOptionsAreInitializedCorrectly) { iox_sub_options_t sut; sut.queueCapacity = 37; @@ -359,8 +359,13 @@ TEST_F(iox_sub_test, subscriberOptionsAreInitializedCorrectly) EXPECT_EQ(sut.nodeName, nullptr); } -TEST_F(iox_sub_test, subscriberOptionInitializationWithNullptrDoesNotCrash) +TEST(iox_sub_options_test, subscriberOptionInitializationWithNullptrDoesNotCrash) { - // we can only check that it compiles and executes without crashing - iox_sub_options_init(nullptr); + EXPECT_EXIT( + { + iox_sub_options_init(nullptr); + exit(0); + }, + ::testing::ExitedWithCode(0), + ".*"); } From e6c5a6b6fff04d1bfb986860743cf53cf0259de7 Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Mon, 1 Mar 2021 18:30:43 +0100 Subject: [PATCH 083/143] iox-#408 add releaseChunk to untyped publisher Signed-off-by: Matthias Killat --- .../internal/popo/untyped_publisher.inl | 7 +++++++ .../iceoryx_posh/popo/untyped_publisher.hpp | 10 +++++++++- .../moduletests/test_popo_untyped_publisher.cpp | 17 +++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_publisher.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_publisher.inl index 011385c05bc..54850000fcb 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_publisher.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_publisher.inl @@ -60,6 +60,13 @@ cxx::optional UntypedPublisherImpl::loanPreviousChunk() return cxx::nullopt; } +template +inline void UntypedPublisherImpl::releaseChunk(const void* chunk) noexcept +{ + auto header = mepoo::ChunkHeader::fromPayload(chunk); + port().releaseChunk(header); +} + } // namespace popo } // namespace iox diff --git a/iceoryx_posh/include/iceoryx_posh/popo/untyped_publisher.hpp b/iceoryx_posh/include/iceoryx_posh/popo/untyped_publisher.hpp index 061fe66ce19..f8c0d0318aa 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/untyped_publisher.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/untyped_publisher.hpp @@ -47,7 +47,7 @@ class UntypedPublisherImpl : public base_publisher_t cxx::expected loan(const uint32_t size) noexcept; /// - /// @brief loanPreviousChunk Get the previously loanded chunk if possible. + /// @brief loanPreviousChunk Get the previously loaned chunk if possible. /// @return A pointer to the previous chunk if available, nullopt otherwise. /// cxx::optional loanPreviousChunk() noexcept; @@ -59,6 +59,14 @@ class UntypedPublisherImpl : public base_publisher_t /// void publish(const void* chunk) noexcept; + /// + /// @brief Releases the chunk provided by its payload pointer. + /// @param chunk pointer to the payload of the chunk to be released + /// @details The chunk must have been previously provided by loan or loanPreviousChunk and + /// not have been already released. + /// + void releaseChunk(const void* chunk) noexcept; + protected: using base_publisher_t::port; }; diff --git a/iceoryx_posh/test/moduletests/test_popo_untyped_publisher.cpp b/iceoryx_posh/test/moduletests/test_popo_untyped_publisher.cpp index 0676be3263d..1ec9fc33a16 100644 --- a/iceoryx_posh/test/moduletests/test_popo_untyped_publisher.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_untyped_publisher.cpp @@ -94,6 +94,23 @@ TEST_F(UntypedPublisherTest, LoanPreviousChunkFails) // ===== Cleanup ===== // } +TEST_F(UntypedPublisherTest, ReleaseChunkDelegatesCallToPort) +{ + constexpr uint32_t ALLOCATION_SIZE = 7U; + EXPECT_CALL(portMock, tryAllocateChunk(ALLOCATION_SIZE)) + .WillOnce(Return(ByMove(iox::cxx::success(chunkMock.chunkHeader())))); + + auto result = sut.loan(ALLOCATION_SIZE); + ASSERT_FALSE(result.has_error()); + auto chunk = result.value(); + + // ===== Test ===== // + EXPECT_CALL(portMock, releaseChunk(chunkMock.chunkHeader())).Times(1); + sut.releaseChunk(chunk); + // ===== Verify ===== // + // ===== Cleanup ===== // +} + TEST_F(UntypedPublisherTest, PublishesPayloadViaUnderlyingPort) { // ===== Setup ===== // From 215b86612487394c26559082bc905c0704eb0f23 Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Tue, 2 Mar 2021 10:18:18 +0100 Subject: [PATCH 084/143] iox-#408 updated some description Signed-off-by: Matthias Killat --- iceoryx_binding_c/include/iceoryx_binding_c/publisher.h | 3 +++ iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h | 3 +++ .../iceoryx_posh/internal/popo/untyped_subscriber.inl | 4 ++-- .../include/iceoryx_posh/popo/untyped_publisher.hpp | 6 ++++-- .../include/iceoryx_posh/popo/untyped_subscriber.hpp | 8 +++++--- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h index dbf0b5fc049..7a2957b7861 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h @@ -38,6 +38,9 @@ typedef struct /// @brief initialize publisher options to default values /// @param[in] options pointer to options to be initialized +/// @attention This must always be called on a newly created options struct to +/// prevent uninitialized values. The options may get extended +/// in the future. void iox_pub_options_init(iox_pub_options_t* options); /// @brief creates a publisher handle diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h index 4751f051f7b..87f4520dac0 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h @@ -41,6 +41,9 @@ typedef struct /// @brief initialize subscriber options to default values /// @param[in] options pointer to options to be initialized +/// @attention This must always be called on a newly created options struct to +/// prevent uninitialized values. The options may get extended +/// in the future. void iox_sub_options_init(iox_sub_options_t* const options); /// @brief initialize subscriber handle diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_subscriber.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_subscriber.inl index cd468d10987..f09db9db0d9 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_subscriber.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_subscriber.inl @@ -41,9 +41,9 @@ inline cxx::expected UntypedSubscriberImpl -inline void UntypedSubscriberImpl::releaseChunk(const void* payload) noexcept +inline void UntypedSubscriberImpl::releaseChunk(const void* chunk) noexcept { - auto header = mepoo::ChunkHeader::fromPayload(payload); + auto header = mepoo::ChunkHeader::fromPayload(chunk); port().releaseChunk(header); } diff --git a/iceoryx_posh/include/iceoryx_posh/popo/untyped_publisher.hpp b/iceoryx_posh/include/iceoryx_posh/popo/untyped_publisher.hpp index f8c0d0318aa..e9287ed1843 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/untyped_publisher.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/untyped_publisher.hpp @@ -60,10 +60,12 @@ class UntypedPublisherImpl : public base_publisher_t void publish(const void* chunk) noexcept; /// - /// @brief Releases the chunk provided by its payload pointer. + /// @brief Releases the ownership of the chunk provided by the payload pointer. /// @param chunk pointer to the payload of the chunk to be released - /// @details The chunk must have been previously provided by loan or loanPreviousChunk and + /// @details The chunk must have been previously provided by take and /// not have been already released. + /// The chunk must not be accessed afterwards as its memory may have + /// been reclaimed. /// void releaseChunk(const void* chunk) noexcept; diff --git a/iceoryx_posh/include/iceoryx_posh/popo/untyped_subscriber.hpp b/iceoryx_posh/include/iceoryx_posh/popo/untyped_subscriber.hpp index f6e63c5714a..9a1fddbc367 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/untyped_subscriber.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/untyped_subscriber.hpp @@ -55,12 +55,14 @@ class UntypedSubscriberImpl : public base_subscriber_t cxx::expected take() noexcept; /// - /// @brief Releases the chunk provided by the payload pointer. - /// @param payload pointer to the payload of the chunk to be released + /// @brief Releases the ownership of the chunk provided by the payload pointer. + /// @param chunk pointer to the payload of the chunk to be released /// @details The chunk must have been previously provided by take and /// not have been already released. + /// The chunk must not be accessed afterwards as its memory may have + /// been reclaimed. /// - void releaseChunk(const void* payload) noexcept; + void releaseChunk(const void* chunk) noexcept; protected: using BaseSubscriber::port; From 418185c623f1ab7f6230b4afc76df4eb8005825f Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Tue, 2 Mar 2021 10:24:57 +0100 Subject: [PATCH 085/143] iox-#408 use default options if nullptr Signed-off-by: Matthias Killat --- .../include/iceoryx_binding_c/publisher.h | 3 ++- .../include/iceoryx_binding_c/subscriber.h | 3 ++- iceoryx_binding_c/source/c_publisher.cpp | 11 ++++++++--- iceoryx_binding_c/source/c_subscriber.cpp | 13 +++++++++---- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h index 7a2957b7861..0bd3149aad4 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h @@ -37,7 +37,8 @@ typedef struct } iox_pub_options_t; /// @brief initialize publisher options to default values -/// @param[in] options pointer to options to be initialized +/// @param[in] options pointer to options to be initialized, +/// if it is a null pointer default options are used /// @attention This must always be called on a newly created options struct to /// prevent uninitialized values. The options may get extended /// in the future. diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h index 87f4520dac0..1c72b8caef8 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h @@ -40,7 +40,8 @@ typedef struct } iox_sub_options_t; /// @brief initialize subscriber options to default values -/// @param[in] options pointer to options to be initialized +/// @param[in] options pointer to options to be initialized, +/// if it is a null pointer default options are used /// @attention This must always be called on a newly created options struct to /// prevent uninitialized values. The options may get extended /// in the future. diff --git a/iceoryx_binding_c/source/c_publisher.cpp b/iceoryx_binding_c/source/c_publisher.cpp index d46a73a5e39..7071b90941e 100644 --- a/iceoryx_binding_c/source/c_publisher.cpp +++ b/iceoryx_binding_c/source/c_publisher.cpp @@ -52,10 +52,15 @@ iox_pub_t iox_pub_init(iox_pub_storage_t* self, new (self) cpp2c_Publisher(); iox_pub_t me = reinterpret_cast(self); PublisherOptions publisherOptions; - publisherOptions.historyCapacity = options->historyCapacity; - if (options->nodeName != nullptr) + + // use default options otherwise + if (options != nullptr) { - publisherOptions.nodeName = NodeName_t(TruncateToCapacity, options->nodeName); + publisherOptions.historyCapacity = options->historyCapacity; + if (options->nodeName != nullptr) + { + publisherOptions.nodeName = NodeName_t(TruncateToCapacity, options->nodeName); + } } me->m_portData = PoshRuntime::getInstance().getMiddlewarePublisher( diff --git a/iceoryx_binding_c/source/c_subscriber.cpp b/iceoryx_binding_c/source/c_subscriber.cpp index 29aa6186d76..34c01176471 100644 --- a/iceoryx_binding_c/source/c_subscriber.cpp +++ b/iceoryx_binding_c/source/c_subscriber.cpp @@ -58,11 +58,16 @@ iox_sub_t iox_sub_init(iox_sub_storage_t* self, new (self) cpp2c_Subscriber(); iox_sub_t me = reinterpret_cast(self); SubscriberOptions subscriberOptions; - subscriberOptions.queueCapacity = options->queueCapacity; - subscriberOptions.historyRequest = options->historyRequest; - if (options->nodeName != nullptr) + + // use default options otherwise + if (options != nullptr) { - subscriberOptions.nodeName = NodeName_t(TruncateToCapacity, options->nodeName); + subscriberOptions.queueCapacity = options->queueCapacity; + subscriberOptions.historyRequest = options->historyRequest; + if (options->nodeName != nullptr) + { + subscriberOptions.nodeName = NodeName_t(TruncateToCapacity, options->nodeName); + } } me->m_portData = From acbf936771ddcde7df84e90300928077c4f9bb6d Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Tue, 2 Mar 2021 11:04:09 +0100 Subject: [PATCH 086/143] iox-#408 more precautions against unitialized options Signed-off-by: Matthias Killat --- .../include/iceoryx_binding_c/publisher.h | 9 +++++++++ .../include/iceoryx_binding_c/subscriber.h | 9 +++++++++ iceoryx_binding_c/source/c_publisher.cpp | 18 ++++++++++++++++++ iceoryx_binding_c/source/c_subscriber.cpp | 18 ++++++++++++++++++ .../test/moduletests/test_publisher.cpp | 16 +++++++++++++++- .../test/moduletests/test_subscriber.cpp | 14 ++++++++++++++ 6 files changed, 83 insertions(+), 1 deletion(-) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h index 0bd3149aad4..dcab5adc00a 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h @@ -34,6 +34,10 @@ typedef struct // name of the node the publisher belongs to // nullptr indicates that the default node name is used const char* nodeName; + + // this value will be set exclusively by iox_pub_options_init + // and is not supposed to modified otherwise + uint64_t initCheck; } iox_pub_options_t; /// @brief initialize publisher options to default values @@ -44,6 +48,11 @@ typedef struct /// in the future. void iox_pub_options_init(iox_pub_options_t* options); +/// @brief check whether the publisher options were initialized by iox_bub_options_init +/// @param[in] options pointer to options to be checked +/// @return true if options are not null and were initialized, false otherwise +bool iox_pub_options_is_initialized(const iox_pub_options_t* const options); + /// @brief creates a publisher handle /// @param[in] self pointer to preallocated memory of size = sizeof(iox_pub_storage_t) /// @param[in] service serviceString diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h index 1c72b8caef8..b8f361ac48e 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h @@ -37,6 +37,10 @@ typedef struct // name of the node the subscriber belongs to const char* nodeName; + + // this value will be set exclusively by iox_sub_options_init + // and is not supposed to modified otherwise + uint64_t initCheck; } iox_sub_options_t; /// @brief initialize subscriber options to default values @@ -47,6 +51,11 @@ typedef struct /// in the future. void iox_sub_options_init(iox_sub_options_t* const options); +/// @brief check whether the subscriber options were initialized by iox_sub_options_init +/// @param[in] options pointer to options to be checked +/// @return true if options are not null and were initialized, false otherwise +bool iox_sub_options_is_initialized(const iox_sub_options_t* const options); + /// @brief initialize subscriber handle /// @param[in] self pointer to preallocated memory of size = sizeof(iox_sub_storage_t) /// @param[in] service serviceString diff --git a/iceoryx_binding_c/source/c_publisher.cpp b/iceoryx_binding_c/source/c_publisher.cpp index 7071b90941e..03d164b6073 100644 --- a/iceoryx_binding_c/source/c_publisher.cpp +++ b/iceoryx_binding_c/source/c_publisher.cpp @@ -31,16 +31,30 @@ extern "C" { #include "iceoryx_binding_c/publisher.h" } +static uint64_t PUBLISHER_OPTIONS_INIT_CHECK_CONSTANT = 123454321; + void iox_pub_options_init(iox_pub_options_t* options) { if (options == nullptr) { + std::cerr << "Warning: publisher options initialization skipped - null pointer provided" << std::endl; return; } PublisherOptions publisherOptions; options->historyCapacity = publisherOptions.historyCapacity; options->nodeName = nullptr; + + options->initCheck = PUBLISHER_OPTIONS_INIT_CHECK_CONSTANT; +} + +bool iox_pub_options_is_initialized(const iox_pub_options_t* const options) +{ + if (options && options->initCheck == PUBLISHER_OPTIONS_INIT_CHECK_CONSTANT) + { + return true; + } + return false; } iox_pub_t iox_pub_init(iox_pub_storage_t* self, @@ -56,6 +70,10 @@ iox_pub_t iox_pub_init(iox_pub_storage_t* self, // use default options otherwise if (options != nullptr) { + if (!iox_pub_options_is_initialized(options)) + { + std::cerr << "Warning: publisher options may not have been initialized with iox_pub_init" << std::endl; + } publisherOptions.historyCapacity = options->historyCapacity; if (options->nodeName != nullptr) { diff --git a/iceoryx_binding_c/source/c_subscriber.cpp b/iceoryx_binding_c/source/c_subscriber.cpp index 34c01176471..38bf2906a2c 100644 --- a/iceoryx_binding_c/source/c_subscriber.cpp +++ b/iceoryx_binding_c/source/c_subscriber.cpp @@ -36,10 +36,13 @@ extern "C" { #include "iceoryx_binding_c/subscriber.h" } +static uint64_t SUBSCRIBER_OPTIONS_INIT_CHECK_CONSTANT = 543212345; + void iox_sub_options_init(iox_sub_options_t* options) { if (options == nullptr) { + std::cerr << "subscriber options initialization skipped - null pointer provided" << std::endl; return; } @@ -47,6 +50,17 @@ void iox_sub_options_init(iox_sub_options_t* options) options->queueCapacity = subscriberOptions.queueCapacity; options->historyRequest = subscriberOptions.historyRequest; options->nodeName = nullptr; + + options->initCheck = SUBSCRIBER_OPTIONS_INIT_CHECK_CONSTANT; +} + +bool iox_sub_options_is_initialized(const iox_sub_options_t* const options) +{ + if (options && options->initCheck == SUBSCRIBER_OPTIONS_INIT_CHECK_CONSTANT) + { + return true; + } + return false; } iox_sub_t iox_sub_init(iox_sub_storage_t* self, @@ -62,6 +76,10 @@ iox_sub_t iox_sub_init(iox_sub_storage_t* self, // use default options otherwise if (options != nullptr) { + if (!iox_sub_options_is_initialized(options)) + { + std::cerr << "Warning: subscriber options may not have been initialized with iox_sub_init" << std::endl; + } subscriberOptions.queueCapacity = options->queueCapacity; subscriberOptions.historyRequest = options->historyRequest; if (options->nodeName != nullptr) diff --git a/iceoryx_binding_c/test/moduletests/test_publisher.cpp b/iceoryx_binding_c/test/moduletests/test_publisher.cpp index 4d9e26166ff..70f1aa30ad7 100644 --- a/iceoryx_binding_c/test/moduletests/test_publisher.cpp +++ b/iceoryx_binding_c/test/moduletests/test_publisher.cpp @@ -258,13 +258,27 @@ TEST(iox_pub_options_test, publisherOptionsAreInitializedCorrectly) { iox_pub_options_t sut; sut.historyCapacity = 37; - sut.nodeName = "DrGonzo"; + sut.nodeName = "Dr.Gonzo"; PublisherOptions options; iox_pub_options_init(&sut); EXPECT_EQ(sut.historyCapacity, options.historyCapacity); EXPECT_EQ(sut.nodeName, nullptr); + EXPECT_TRUE(iox_pub_options_is_initialized(&sut)); +} + +TEST(iox_pub_options_test, publisherOptionsInitializationCheckReturnsTrueAfterDefaultInit) +{ + iox_pub_options_t sut; + iox_pub_options_init(&sut); + EXPECT_TRUE(iox_pub_options_is_initialized(&sut)); +} + +TEST(iox_pub_options_test, publisherOptionsInitializationCheckReturnsFalseWithoutDefaultInit) +{ + iox_pub_options_t sut; + EXPECT_FALSE(iox_pub_options_is_initialized(&sut)); } TEST(iox_pub_options_test, publisherOptionInitializationWithNullptrDoesNotCrash) diff --git a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp index 565b815ceb4..c854e175903 100644 --- a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp +++ b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp @@ -357,6 +357,20 @@ TEST(iox_sub_options_test, subscriberOptionsAreInitializedCorrectly) EXPECT_EQ(sut.queueCapacity, options.queueCapacity); EXPECT_EQ(sut.historyRequest, options.historyRequest); EXPECT_EQ(sut.nodeName, nullptr); + EXPECT_TRUE(iox_sub_options_is_initialized(&sut)); +} + +TEST(iox_sub_options_test, subscriberOptionsInitializationCheckReturnsTrueAfterDefaultInit) +{ + iox_sub_options_t sut; + iox_sub_options_init(&sut); + EXPECT_TRUE(iox_sub_options_is_initialized(&sut)); +} + +TEST(iox_sub_options_test, subscriberOptionsInitializationCheckReturnsFalseWithoutDefaultInit) +{ + iox_sub_options_t sut; + EXPECT_FALSE(iox_sub_options_is_initialized(&sut)); } TEST(iox_sub_options_test, subscriberOptionInitializationWithNullptrDoesNotCrash) From f57a86015d7314a75ac8687d7a82d9400829d9c6 Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Tue, 2 Mar 2021 12:02:29 +0100 Subject: [PATCH 087/143] iox-#408 use LogWarn and minor corrections Signed-off-by: Matthias Killat --- iceoryx_binding_c/include/iceoryx_binding_c/publisher.h | 2 +- iceoryx_binding_c/source/c_publisher.cpp | 4 ++-- iceoryx_binding_c/source/c_subscriber.cpp | 4 ++-- iceoryx_binding_c/test/moduletests/test_subscriber.cpp | 2 +- .../include/iceoryx_posh/internal/popo/untyped_publisher.inl | 3 ++- iceoryx_posh/test/moduletests/test_popo_untyped_publisher.cpp | 2 +- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h index dcab5adc00a..1d85c4b26ee 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h @@ -48,7 +48,7 @@ typedef struct /// in the future. void iox_pub_options_init(iox_pub_options_t* options); -/// @brief check whether the publisher options were initialized by iox_bub_options_init +/// @brief check whether the publisher options were initialized by iox_pub_options_init /// @param[in] options pointer to options to be checked /// @return true if options are not null and were initialized, false otherwise bool iox_pub_options_is_initialized(const iox_pub_options_t* const options); diff --git a/iceoryx_binding_c/source/c_publisher.cpp b/iceoryx_binding_c/source/c_publisher.cpp index 03d164b6073..81346a56baa 100644 --- a/iceoryx_binding_c/source/c_publisher.cpp +++ b/iceoryx_binding_c/source/c_publisher.cpp @@ -37,7 +37,7 @@ void iox_pub_options_init(iox_pub_options_t* options) { if (options == nullptr) { - std::cerr << "Warning: publisher options initialization skipped - null pointer provided" << std::endl; + LogWarn() << "publisher options initialization skipped - null pointer provided"; return; } @@ -72,7 +72,7 @@ iox_pub_t iox_pub_init(iox_pub_storage_t* self, { if (!iox_pub_options_is_initialized(options)) { - std::cerr << "Warning: publisher options may not have been initialized with iox_pub_init" << std::endl; + LogWarn() << "publisher options may not have been initialized with iox_pub_init"; } publisherOptions.historyCapacity = options->historyCapacity; if (options->nodeName != nullptr) diff --git a/iceoryx_binding_c/source/c_subscriber.cpp b/iceoryx_binding_c/source/c_subscriber.cpp index 38bf2906a2c..784f3ef56a5 100644 --- a/iceoryx_binding_c/source/c_subscriber.cpp +++ b/iceoryx_binding_c/source/c_subscriber.cpp @@ -42,7 +42,7 @@ void iox_sub_options_init(iox_sub_options_t* options) { if (options == nullptr) { - std::cerr << "subscriber options initialization skipped - null pointer provided" << std::endl; + LogWarn() << "subscriber options initialization skipped - null pointer provided"; return; } @@ -78,7 +78,7 @@ iox_sub_t iox_sub_init(iox_sub_storage_t* self, { if (!iox_sub_options_is_initialized(options)) { - std::cerr << "Warning: subscriber options may not have been initialized with iox_sub_init" << std::endl; + LogWarn() << "subscriber options may not have been initialized with iox_sub_init"; } subscriberOptions.queueCapacity = options->queueCapacity; subscriberOptions.historyRequest = options->historyRequest; diff --git a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp index c854e175903..08d03e8ec38 100644 --- a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp +++ b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp @@ -349,7 +349,7 @@ TEST(iox_sub_options_test, subscriberOptionsAreInitializedCorrectly) iox_sub_options_t sut; sut.queueCapacity = 37; sut.historyRequest = 73; - sut.nodeName = "DrGonzo"; + sut.nodeName = "Dr.Gonzo"; SubscriberOptions options; diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_publisher.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_publisher.inl index 54850000fcb..d2d6a1619fc 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_publisher.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_publisher.inl @@ -1,4 +1,5 @@ -// Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/test/moduletests/test_popo_untyped_publisher.cpp b/iceoryx_posh/test/moduletests/test_popo_untyped_publisher.cpp index 1ec9fc33a16..065f82777eb 100644 --- a/iceoryx_posh/test/moduletests/test_popo_untyped_publisher.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_untyped_publisher.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2021 by Apex.AI Inc. All rights reserved. -// Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. From 3d0f54c813ff8b7898de5622058937e7d6e63f88 Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Tue, 2 Mar 2021 12:45:32 +0100 Subject: [PATCH 088/143] iox-#408 rename releaseChunk Signed-off-by: Matthias Killat --- iceoryx_examples/icedelivery/iox_subscriber_untyped.cpp | 2 +- iceoryx_examples/iceperf/iceoryx.cpp | 2 +- iceoryx_examples/waitset/ice_waitset_grouping.cpp | 2 +- .../include/iceoryx_posh/internal/popo/untyped_publisher.inl | 2 +- .../include/iceoryx_posh/internal/popo/untyped_subscriber.inl | 2 +- iceoryx_posh/include/iceoryx_posh/popo/untyped_publisher.hpp | 2 +- iceoryx_posh/include/iceoryx_posh/popo/untyped_subscriber.hpp | 2 +- iceoryx_posh/test/moduletests/test_popo_untyped_publisher.cpp | 4 ++-- .../test/moduletests/test_popo_untyped_subscriber.cpp | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/iceoryx_examples/icedelivery/iox_subscriber_untyped.cpp b/iceoryx_examples/icedelivery/iox_subscriber_untyped.cpp index 110d01c0d5a..376437961db 100644 --- a/iceoryx_examples/icedelivery/iox_subscriber_untyped.cpp +++ b/iceoryx_examples/icedelivery/iox_subscriber_untyped.cpp @@ -58,7 +58,7 @@ int main() // note that we explicitly have to release the data // and afterwards the pointer access is undefined behavior - subscriber.releaseChunk(data); + subscriber.release(data); }) .or_else([](auto& result) { if (result != iox::popo::ChunkReceiveResult::NO_CHUNK_AVAILABLE) diff --git a/iceoryx_examples/iceperf/iceoryx.cpp b/iceoryx_examples/iceperf/iceoryx.cpp index 64a534d8c51..3d5ba4d3617 100644 --- a/iceoryx_examples/iceperf/iceoryx.cpp +++ b/iceoryx_examples/iceperf/iceoryx.cpp @@ -91,7 +91,7 @@ PerfTopic Iceoryx::receivePerfTopic() noexcept m_subscriber.take().and_then([&](const void* data) { receivedSample = *(static_cast(data)); hasReceivedSample = true; - m_subscriber.releaseChunk(data); + m_subscriber.release(data); }); } while (!hasReceivedSample); diff --git a/iceoryx_examples/waitset/ice_waitset_grouping.cpp b/iceoryx_examples/waitset/ice_waitset_grouping.cpp index 2f30710ec76..af7f70e7dae 100644 --- a/iceoryx_examples/waitset/ice_waitset_grouping.cpp +++ b/iceoryx_examples/waitset/ice_waitset_grouping.cpp @@ -90,7 +90,7 @@ int main() subscriber->take().and_then([&](auto& payload) { const CounterTopic* data = static_cast(payload); std::cout << "received: " << std::dec << data->counter << std::endl; - subscriber->releaseChunk(payload); + subscriber->release(payload); }); } // dismiss the received data for the second group diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_publisher.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_publisher.inl index d2d6a1619fc..e0393450428 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_publisher.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_publisher.inl @@ -62,7 +62,7 @@ cxx::optional UntypedPublisherImpl::loanPreviousChunk() } template -inline void UntypedPublisherImpl::releaseChunk(const void* chunk) noexcept +inline void UntypedPublisherImpl::release(const void* chunk) noexcept { auto header = mepoo::ChunkHeader::fromPayload(chunk); port().releaseChunk(header); diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_subscriber.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_subscriber.inl index f09db9db0d9..d118c458341 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_subscriber.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/untyped_subscriber.inl @@ -41,7 +41,7 @@ inline cxx::expected UntypedSubscriberImpl -inline void UntypedSubscriberImpl::releaseChunk(const void* chunk) noexcept +inline void UntypedSubscriberImpl::release(const void* chunk) noexcept { auto header = mepoo::ChunkHeader::fromPayload(chunk); port().releaseChunk(header); diff --git a/iceoryx_posh/include/iceoryx_posh/popo/untyped_publisher.hpp b/iceoryx_posh/include/iceoryx_posh/popo/untyped_publisher.hpp index e9287ed1843..28e3637a66c 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/untyped_publisher.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/untyped_publisher.hpp @@ -67,7 +67,7 @@ class UntypedPublisherImpl : public base_publisher_t /// The chunk must not be accessed afterwards as its memory may have /// been reclaimed. /// - void releaseChunk(const void* chunk) noexcept; + void release(const void* chunk) noexcept; protected: using base_publisher_t::port; diff --git a/iceoryx_posh/include/iceoryx_posh/popo/untyped_subscriber.hpp b/iceoryx_posh/include/iceoryx_posh/popo/untyped_subscriber.hpp index 9a1fddbc367..2aaee077340 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/untyped_subscriber.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/untyped_subscriber.hpp @@ -62,7 +62,7 @@ class UntypedSubscriberImpl : public base_subscriber_t /// The chunk must not be accessed afterwards as its memory may have /// been reclaimed. /// - void releaseChunk(const void* chunk) noexcept; + void release(const void* chunk) noexcept; protected: using BaseSubscriber::port; diff --git a/iceoryx_posh/test/moduletests/test_popo_untyped_publisher.cpp b/iceoryx_posh/test/moduletests/test_popo_untyped_publisher.cpp index 065f82777eb..92736c25c69 100644 --- a/iceoryx_posh/test/moduletests/test_popo_untyped_publisher.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_untyped_publisher.cpp @@ -94,7 +94,7 @@ TEST_F(UntypedPublisherTest, LoanPreviousChunkFails) // ===== Cleanup ===== // } -TEST_F(UntypedPublisherTest, ReleaseChunkDelegatesCallToPort) +TEST_F(UntypedPublisherTest, ReleaseDelegatesCallToPort) { constexpr uint32_t ALLOCATION_SIZE = 7U; EXPECT_CALL(portMock, tryAllocateChunk(ALLOCATION_SIZE)) @@ -106,7 +106,7 @@ TEST_F(UntypedPublisherTest, ReleaseChunkDelegatesCallToPort) // ===== Test ===== // EXPECT_CALL(portMock, releaseChunk(chunkMock.chunkHeader())).Times(1); - sut.releaseChunk(chunk); + sut.release(chunk); // ===== Verify ===== // // ===== Cleanup ===== // } diff --git a/iceoryx_posh/test/moduletests/test_popo_untyped_subscriber.cpp b/iceoryx_posh/test/moduletests/test_popo_untyped_subscriber.cpp index da85cbac0f6..7253d6cf99a 100644 --- a/iceoryx_posh/test/moduletests/test_popo_untyped_subscriber.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_untyped_subscriber.cpp @@ -139,7 +139,7 @@ TEST_F(UntypedSubscriberTest, TakeReturnsAllocatedMemoryChunk) ASSERT_FALSE(maybeChunk.has_error()); EXPECT_EQ(maybeChunk.value(), chunkMock.chunkHeader()->payload()); // ===== Cleanup ===== // - sut.releaseChunk(maybeChunk.value()); + sut.release(maybeChunk.value()); } TEST_F(UntypedSubscriberTest, ReleasesQueuedDataViaBaseSubscriber) From 0b03898e9771589f95d1e8cb37428483459e8458 Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Tue, 2 Mar 2021 12:59:12 +0100 Subject: [PATCH 089/143] iox-#408 fix findings Signed-off-by: Matthias Killat --- iceoryx_binding_c/include/iceoryx_binding_c/publisher.h | 2 +- iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h | 2 +- iceoryx_binding_c/source/c_publisher.cpp | 6 +----- iceoryx_binding_c/source/c_subscriber.cpp | 6 +----- .../include/iceoryx_posh/popo/untyped_publisher.hpp | 4 ++-- 5 files changed, 6 insertions(+), 14 deletions(-) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h index 1d85c4b26ee..b86b586e550 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h @@ -36,7 +36,7 @@ typedef struct const char* nodeName; // this value will be set exclusively by iox_pub_options_init - // and is not supposed to modified otherwise + // and is not supposed to be modified otherwise uint64_t initCheck; } iox_pub_options_t; diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h index b8f361ac48e..8d8ba1189e0 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h @@ -39,7 +39,7 @@ typedef struct const char* nodeName; // this value will be set exclusively by iox_sub_options_init - // and is not supposed to modified otherwise + // and is not supposed to be modified otherwise uint64_t initCheck; } iox_sub_options_t; diff --git a/iceoryx_binding_c/source/c_publisher.cpp b/iceoryx_binding_c/source/c_publisher.cpp index 81346a56baa..a9c7f8c730c 100644 --- a/iceoryx_binding_c/source/c_publisher.cpp +++ b/iceoryx_binding_c/source/c_publisher.cpp @@ -50,11 +50,7 @@ void iox_pub_options_init(iox_pub_options_t* options) bool iox_pub_options_is_initialized(const iox_pub_options_t* const options) { - if (options && options->initCheck == PUBLISHER_OPTIONS_INIT_CHECK_CONSTANT) - { - return true; - } - return false; + return options && options->initCheck == PUBLISHER_OPTIONS_INIT_CHECK_CONSTANT; } iox_pub_t iox_pub_init(iox_pub_storage_t* self, diff --git a/iceoryx_binding_c/source/c_subscriber.cpp b/iceoryx_binding_c/source/c_subscriber.cpp index 784f3ef56a5..ba8fb8cf898 100644 --- a/iceoryx_binding_c/source/c_subscriber.cpp +++ b/iceoryx_binding_c/source/c_subscriber.cpp @@ -56,11 +56,7 @@ void iox_sub_options_init(iox_sub_options_t* options) bool iox_sub_options_is_initialized(const iox_sub_options_t* const options) { - if (options && options->initCheck == SUBSCRIBER_OPTIONS_INIT_CHECK_CONSTANT) - { - return true; - } - return false; + return options && options->initCheck == SUBSCRIBER_OPTIONS_INIT_CHECK_CONSTANT; } iox_sub_t iox_sub_init(iox_sub_storage_t* self, diff --git a/iceoryx_posh/include/iceoryx_posh/popo/untyped_publisher.hpp b/iceoryx_posh/include/iceoryx_posh/popo/untyped_publisher.hpp index 28e3637a66c..3cd6d33872e 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/untyped_publisher.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/untyped_publisher.hpp @@ -62,8 +62,8 @@ class UntypedPublisherImpl : public base_publisher_t /// /// @brief Releases the ownership of the chunk provided by the payload pointer. /// @param chunk pointer to the payload of the chunk to be released - /// @details The chunk must have been previously provided by take and - /// not have been already released. + /// @details The chunk must have been previously provided by loan or loanPreviousChunk + /// and not have been already released. /// The chunk must not be accessed afterwards as its memory may have /// been reclaimed. /// From 94d9a959f31364b5aabc4d161a80d14e5d7e86aa Mon Sep 17 00:00:00 2001 From: Simon Hoinkis Date: Wed, 24 Feb 2021 18:37:12 +0100 Subject: [PATCH 090/143] iox-#549 Add requirement for 64-bit system and warning on 32-bit systems Signed-off-by: Simon Hoinkis --- doc/website/getting-started/installation.md | 3 ++- iceoryx_posh/source/roudi/roudi.cpp | 2 ++ iceoryx_posh/source/runtime/posh_runtime.cpp | 5 +++-- iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp | 9 +++++++++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/doc/website/getting-started/installation.md b/doc/website/getting-started/installation.md index 81005b48e4c..1d5f5a0e0b0 100644 --- a/doc/website/getting-started/installation.md +++ b/doc/website/getting-started/installation.md @@ -6,9 +6,10 @@ iceoryx_utils and iceoryx_posh are deployed as independent cmake packages. Posh ### Dependencies + - 64-bit hardware (e.g. x86_64 or aarch64) - [cmake](https://cmake.org), 3.5 or later - One of the following compilers: - - [gcc](https://gcc.gnu.org), 7.4 or later + - [gcc](https://gcc.gnu.org), 7.4 or later - [clang](https://clang.llvm.org), 9.0 or later - [msvc](https://visualstudio.microsoft.com/de/), part of Visual Studio 2019 or later - [libacl](http://download.savannah.gnu.org/releases/acl/), 2.2 or later. Only for Linux & QNX. diff --git a/iceoryx_posh/source/roudi/roudi.cpp b/iceoryx_posh/source/roudi/roudi.cpp index d02113644dc..1ed68ed6bd9 100644 --- a/iceoryx_posh/source/roudi/roudi.cpp +++ b/iceoryx_posh/source/roudi/roudi.cpp @@ -24,6 +24,7 @@ #include "iceoryx_posh/roudi/memory/roudi_memory_manager.hpp" #include "iceoryx_posh/runtime/port_config_info.hpp" #include "iceoryx_utils/cxx/convert.hpp" +#include "iceoryx_utils/cxx/helplets.hpp" #include "iceoryx_utils/posix_wrapper/thread.hpp" namespace iox @@ -46,6 +47,7 @@ RouDi::RouDi(RouDiMemoryInterface& roudiMemoryInterface, , m_monitoringMode(roudiStartupParameters.m_monitoringMode) , m_processKillDelay(roudiStartupParameters.m_processKillDelay) { + cxx::printWarningOn32BitSystems(); m_processIntrospection.registerPublisherPort(PublisherPortUserType( m_prcMgr.addIntrospectionPublisherPort(IntrospectionProcessService, IPC_CHANNEL_ROUDI_NAME))); m_prcMgr.initIntrospection(&m_processIntrospection); diff --git a/iceoryx_posh/source/runtime/posh_runtime.cpp b/iceoryx_posh/source/runtime/posh_runtime.cpp index a6c48a4e937..df5c4a03fff 100644 --- a/iceoryx_posh/source/runtime/posh_runtime.cpp +++ b/iceoryx_posh/source/runtime/posh_runtime.cpp @@ -22,6 +22,7 @@ #include "iceoryx_posh/runtime/node.hpp" #include "iceoryx_posh/runtime/port_config_info.hpp" #include "iceoryx_utils/cxx/convert.hpp" +#include "iceoryx_utils/cxx/helplets.hpp" #include "iceoryx_utils/internal/relocatable_pointer/relative_ptr.hpp" #include "iceoryx_utils/posix_wrapper/timer.hpp" @@ -81,6 +82,7 @@ PoshRuntime::PoshRuntime(cxx::optional name, const bool do m_ipcChannelInterface.getSegmentManagerAddressOffset()) , m_applicationPort(getMiddlewareApplication()) { + cxx::printWarningOn32BitSystems(); /// @todo here we could get the LogLevel and LogMode and set it on the LogManager } @@ -389,8 +391,7 @@ NodeData* PoshRuntime::createNode(const NodeProperty& nodeProperty) noexcept } LogError() << "Got wrong response from RouDi while creating node:'" << receiveBuffer.getMessage() << "'"; - errorHandler( - Error::kPOSH__RUNTIME_ROUDI_CREATE_NODE_WRONG_IPC_MESSAGE_RESPONSE, nullptr, iox::ErrorLevel::SEVERE); + errorHandler(Error::kPOSH__RUNTIME_ROUDI_CREATE_NODE_WRONG_IPC_MESSAGE_RESPONSE, nullptr, iox::ErrorLevel::SEVERE); return nullptr; } diff --git a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp index 704d63adc55..89250b7efdf 100644 --- a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp +++ b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp @@ -20,6 +20,7 @@ #include "iceoryx_utils/platform/platform_correction.hpp" #include +#include #include #include @@ -203,6 +204,14 @@ static constexpr uint64_t strlen2(char const (&/*notInterested*/)[SizeValue]) #define DISCARD_RESULT(expr) auto DISCARD_RESULT_VARIABLE(unusedOnLine, __LINE__) [[gnu::unused]] = expr // clang-format on +/// @brief Prints a warning to std::cerr if called on a 32-bit system +constexpr void printWarningOn32BitSystems() +{ +#if INTPTR_MAX == INT32_MAX + std::cerr << "Warning! 32-bit architectures are unsupported! Use at your own risk!" std::endl; +#endif +} + } // namespace cxx } // namespace iox From dc064f219eab7ac6bb5097fc76bfb02eb75928bf Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Tue, 2 Mar 2021 14:00:34 +0100 Subject: [PATCH 091/143] iox-#408 update dds gateway Signed-off-by: Matthias Killat --- iceoryx_dds/include/iceoryx_dds/internal/gateway/dds_to_iox.inl | 1 + iceoryx_dds/include/iceoryx_dds/internal/gateway/iox_to_dds.inl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/iceoryx_dds/include/iceoryx_dds/internal/gateway/dds_to_iox.inl b/iceoryx_dds/include/iceoryx_dds/internal/gateway/dds_to_iox.inl index 728beeb2ab7..12d03f2f3d7 100644 --- a/iceoryx_dds/include/iceoryx_dds/internal/gateway/dds_to_iox.inl +++ b/iceoryx_dds/include/iceoryx_dds/internal/gateway/dds_to_iox.inl @@ -68,6 +68,7 @@ inline void DDS2IceoryxGateway::forward(const channel_t& c reader->takeNext(static_cast(chunk), size) .and_then([&]() { publisher->publish(chunk); }) .or_else([&](DataReaderError err) { + publisher->release(chunk); LogWarn() << "[DDS2IceoryxGateway] Encountered error reading from DDS network: " << dds::DataReaderErrorString[static_cast(err)]; }); diff --git a/iceoryx_dds/include/iceoryx_dds/internal/gateway/iox_to_dds.inl b/iceoryx_dds/include/iceoryx_dds/internal/gateway/iox_to_dds.inl index bce07e3f315..5c123be4379 100644 --- a/iceoryx_dds/include/iceoryx_dds/internal/gateway/iox_to_dds.inl +++ b/iceoryx_dds/include/iceoryx_dds/internal/gateway/iox_to_dds.inl @@ -111,7 +111,7 @@ inline void Iceoryx2DDSGateway::forward(const channel_t& c auto dataWriter = channel.getExternalTerminal(); auto header = iox::mepoo::ChunkHeader::fromPayload(payload); dataWriter->write(static_cast(payload), header->payloadSize); - subscriber->releaseChunk(payload); + subscriber->release(payload); }); } } From c13a2a0226e840b2441728e52ee294f6c4ddb511 Mon Sep 17 00:00:00 2001 From: Simon Hoinkis Date: Thu, 25 Feb 2021 09:30:02 +0100 Subject: [PATCH 092/143] iox-#549 Update copyright header Signed-off-by: Simon Hoinkis --- iceoryx_posh/source/runtime/posh_runtime.cpp | 3 ++- iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/iceoryx_posh/source/runtime/posh_runtime.cpp b/iceoryx_posh/source/runtime/posh_runtime.cpp index df5c4a03fff..8c17e12fd9c 100644 --- a/iceoryx_posh/source/runtime/posh_runtime.cpp +++ b/iceoryx_posh/source/runtime/posh_runtime.cpp @@ -1,4 +1,5 @@ -// Copyright (c) 2019, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2019 - 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp index 89250b7efdf..6cbe1f68430 100644 --- a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp +++ b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp @@ -1,4 +1,5 @@ // Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. From 8d9aa300c17d35645cad93bb182d4a15c76deddf Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Tue, 2 Mar 2021 14:12:46 +0100 Subject: [PATCH 093/143] iox-#408 terminate if options are not initialized Signed-off-by: Matthias Killat --- iceoryx_binding_c/source/c_publisher.cpp | 7 +++++-- iceoryx_binding_c/source/c_subscriber.cpp | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/iceoryx_binding_c/source/c_publisher.cpp b/iceoryx_binding_c/source/c_publisher.cpp index a9c7f8c730c..f050a740c8d 100644 --- a/iceoryx_binding_c/source/c_publisher.cpp +++ b/iceoryx_binding_c/source/c_publisher.cpp @@ -31,7 +31,7 @@ extern "C" { #include "iceoryx_binding_c/publisher.h" } -static uint64_t PUBLISHER_OPTIONS_INIT_CHECK_CONSTANT = 123454321; +constexpr uint64_t PUBLISHER_OPTIONS_INIT_CHECK_CONSTANT = 123454321; void iox_pub_options_init(iox_pub_options_t* options) { @@ -68,7 +68,10 @@ iox_pub_t iox_pub_init(iox_pub_storage_t* self, { if (!iox_pub_options_is_initialized(options)) { - LogWarn() << "publisher options may not have been initialized with iox_pub_init"; + // note that they may have been initialized but the initCheck + // pattern overwritten afterwards, we cannot be sure but it is a misuse + LogError() << "publisher options may not have been initialized with iox_pub_init"; + std::terminate(); } publisherOptions.historyCapacity = options->historyCapacity; if (options->nodeName != nullptr) diff --git a/iceoryx_binding_c/source/c_subscriber.cpp b/iceoryx_binding_c/source/c_subscriber.cpp index ba8fb8cf898..8e405ce673a 100644 --- a/iceoryx_binding_c/source/c_subscriber.cpp +++ b/iceoryx_binding_c/source/c_subscriber.cpp @@ -36,7 +36,7 @@ extern "C" { #include "iceoryx_binding_c/subscriber.h" } -static uint64_t SUBSCRIBER_OPTIONS_INIT_CHECK_CONSTANT = 543212345; +constexpr uint64_t SUBSCRIBER_OPTIONS_INIT_CHECK_CONSTANT = 543212345; void iox_sub_options_init(iox_sub_options_t* options) { @@ -74,7 +74,10 @@ iox_sub_t iox_sub_init(iox_sub_storage_t* self, { if (!iox_sub_options_is_initialized(options)) { - LogWarn() << "subscriber options may not have been initialized with iox_sub_init"; + // note that they may have been initialized but the initCheck + // pattern overwritten afterwards, we cannot be sure but it is a misuse + LogError() << "subscriber options may not have been initialized with iox_sub_init"; + std::terminate(); } subscriberOptions.queueCapacity = options->queueCapacity; subscriberOptions.historyRequest = options->historyRequest; From 5c4f5f79fcd54b61c70f519aeb1fb06764ba4e53 Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Tue, 2 Mar 2021 14:49:17 +0100 Subject: [PATCH 094/143] iox-#408 death test for uninitialized options Signed-off-by: Matthias Killat --- iceoryx_binding_c/source/c_publisher.cpp | 1 + iceoryx_binding_c/test/moduletests/test_publisher.cpp | 8 ++++++++ iceoryx_binding_c/test/moduletests/test_subscriber.cpp | 9 +++++++++ 3 files changed, 18 insertions(+) diff --git a/iceoryx_binding_c/source/c_publisher.cpp b/iceoryx_binding_c/source/c_publisher.cpp index f050a740c8d..85c5ed6a0a5 100644 --- a/iceoryx_binding_c/source/c_publisher.cpp +++ b/iceoryx_binding_c/source/c_publisher.cpp @@ -68,6 +68,7 @@ iox_pub_t iox_pub_init(iox_pub_storage_t* self, { if (!iox_pub_options_is_initialized(options)) { + std::cout << "******* terminate" << std::endl; // note that they may have been initialized but the initCheck // pattern overwritten afterwards, we cannot be sure but it is a misuse LogError() << "publisher options may not have been initialized with iox_pub_init"; diff --git a/iceoryx_binding_c/test/moduletests/test_publisher.cpp b/iceoryx_binding_c/test/moduletests/test_publisher.cpp index 70f1aa30ad7..41ba667d8d7 100644 --- a/iceoryx_binding_c/test/moduletests/test_publisher.cpp +++ b/iceoryx_binding_c/test/moduletests/test_publisher.cpp @@ -291,3 +291,11 @@ TEST(iox_pub_options_test, publisherOptionInitializationWithNullptrDoesNotCrash) ::testing::ExitedWithCode(0), ".*"); } + +TEST(iox_pub_options_test, publisherInitializationTerminatesIfOptionsAreNotInitialized) +{ + iox_pub_options_t options; + iox_pub_storage_t storage; + + EXPECT_DEATH({ iox_pub_init(&storage, "a", "b", "c", &options); }, ".*"); +} diff --git a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp index 08d03e8ec38..b48bd4db289 100644 --- a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp +++ b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp @@ -33,6 +33,7 @@ using namespace iox::posix; extern "C" { #include "iceoryx_binding_c/chunk.h" +#include "iceoryx_binding_c/runtime.h" #include "iceoryx_binding_c/subscriber.h" #include "iceoryx_binding_c/types.h" #include "iceoryx_binding_c/wait_set.h" @@ -383,3 +384,11 @@ TEST(iox_sub_options_test, subscriberOptionInitializationWithNullptrDoesNotCrash ::testing::ExitedWithCode(0), ".*"); } + +TEST(iox_sub_options_test, subscriberInitializationTerminatesIfOptionsAreNotInitialized) +{ + iox_sub_options_t options; + iox_sub_storage_t storage; + + EXPECT_DEATH({ iox_sub_init(&storage, "a", "b", "c", &options); }, ".*"); +} From 0aba80c6b3a0f96d5be5fdbd3824e2452ffc6e95 Mon Sep 17 00:00:00 2001 From: Simon Hoinkis Date: Thu, 25 Feb 2021 20:47:05 +0100 Subject: [PATCH 095/143] iox-#549 Create error enum for PoshRuntime::findService Signed-off-by: Simon Hoinkis --- .../include/iceoryx_posh/runtime/posh_runtime.hpp | 15 ++++++++++++--- iceoryx_posh/source/runtime/posh_runtime.cpp | 6 +++--- .../error_handling/error_handling.hpp | 1 - 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp b/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp index 7a5e52e28e6..e6cde9760a0 100644 --- a/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp +++ b/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp @@ -51,6 +51,14 @@ namespace runtime class Node; class NodeData; +enum class FindServiceError +{ + INVALID_STATE, + UNABLE_TO_WRITE_TO_ROUDI_CHANNEL, + INSTANCE_CONTAINER_OVERFLOW + +}; + /// @brief The runtime that is needed for each application to communicate with the RouDi daemon class PoshRuntime { @@ -76,9 +84,10 @@ class PoshRuntime /// @return cxx::expected /// InstanceContainer: on success, container that is filled with all matching instances /// Error: if any, encountered during the operation - /// Error::kPOSH__SERVICE_DISCOVERY_INSTANCE_CONTAINER_OVERFLOW : Number of instances can't fit in instanceContainer - /// Error::kIPC_INTERFACE__REG_UNABLE_TO_WRITE_TO_ROUDI_CHANNEL : Find Service Request could not be sent to RouDi - cxx::expected findService(const capro::ServiceDescription& serviceDescription) noexcept; + /// FindServiceError::INSTANCE_CONTAINER_OVERFLOW : Number of instances can't fit in instanceContainer + /// FindServiceError::UNABLE_TO_WRITE_TO_ROUDI_CHANNEL : Find Service Request could not be sent to RouDi + cxx::expected + findService(const capro::ServiceDescription& serviceDescription) noexcept; /// @brief offer the provided service, sends the offer from application to RouDi daemon /// @param[in] serviceDescription service to offer diff --git a/iceoryx_posh/source/runtime/posh_runtime.cpp b/iceoryx_posh/source/runtime/posh_runtime.cpp index 8c17e12fd9c..87178402412 100644 --- a/iceoryx_posh/source/runtime/posh_runtime.cpp +++ b/iceoryx_posh/source/runtime/posh_runtime.cpp @@ -396,7 +396,7 @@ NodeData* PoshRuntime::createNode(const NodeProperty& nodeProperty) noexcept return nullptr; } -cxx::expected +cxx::expected PoshRuntime::findService(const capro::ServiceDescription& serviceDescription) noexcept { IpcMessage sendBuffer; @@ -409,7 +409,7 @@ PoshRuntime::findService(const capro::ServiceDescription& serviceDescription) no { LogError() << "Could not send FIND_SERVICE request to RouDi\n"; errorHandler(Error::kIPC_INTERFACE__REG_UNABLE_TO_WRITE_TO_ROUDI_CHANNEL, nullptr, ErrorLevel::MODERATE); - return cxx::error(Error::kIPC_INTERFACE__REG_UNABLE_TO_WRITE_TO_ROUDI_CHANNEL); + return cxx::error(FindServiceError::UNABLE_TO_WRITE_TO_ROUDI_CHANNEL); } InstanceContainer instanceContainer; @@ -429,7 +429,7 @@ PoshRuntime::findService(const capro::ServiceDescription& serviceDescription) no LogWarn() << numberOfElements << " instances found for service \"" << serviceDescription.getServiceIDString() << "\" which is more than supported number of instances(" << MAX_NUMBER_OF_INSTANCES << "\n"; errorHandler(Error::kPOSH__SERVICE_DISCOVERY_INSTANCE_CONTAINER_OVERFLOW, nullptr, ErrorLevel::MODERATE); - return cxx::error(Error::kPOSH__SERVICE_DISCOVERY_INSTANCE_CONTAINER_OVERFLOW); + return cxx::error(FindServiceError::INSTANCE_CONTAINER_OVERFLOW); } return {cxx::success(instanceContainer)}; } diff --git a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp index e783744dbb3..f0e6ec91b7e 100644 --- a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp +++ b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp @@ -137,7 +137,6 @@ namespace iox enum class Error : uint32_t { - INVALID_STATE, ICEORYX_ERRORS(CREATE_ICEORYX_ERROR_ENUM) }; From 13ed8fe2b32506fc50d0b74ea9b67678319228bf Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Tue, 2 Mar 2021 18:15:17 +0100 Subject: [PATCH 096/143] iox-#408 use error handler for fatal option errors Signed-off-by: Matthias Killat --- iceoryx_binding_c/source/c_publisher.cpp | 5 ++--- iceoryx_binding_c/source/c_subscriber.cpp | 4 ++-- .../include/iceoryx_utils/error_handling/error_handling.hpp | 4 +++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/iceoryx_binding_c/source/c_publisher.cpp b/iceoryx_binding_c/source/c_publisher.cpp index 85c5ed6a0a5..4986e9e1cf0 100644 --- a/iceoryx_binding_c/source/c_publisher.cpp +++ b/iceoryx_binding_c/source/c_publisher.cpp @@ -68,11 +68,10 @@ iox_pub_t iox_pub_init(iox_pub_storage_t* self, { if (!iox_pub_options_is_initialized(options)) { - std::cout << "******* terminate" << std::endl; // note that they may have been initialized but the initCheck // pattern overwritten afterwards, we cannot be sure but it is a misuse - LogError() << "publisher options may not have been initialized with iox_pub_init"; - std::terminate(); + LogFatal() << "publisher options may not have been initialized with iox_pub_init"; + errorHandler(Error::kBINDING_C__PUBLISHER_OPTIONS_NOT_INITIALIZED); } publisherOptions.historyCapacity = options->historyCapacity; if (options->nodeName != nullptr) diff --git a/iceoryx_binding_c/source/c_subscriber.cpp b/iceoryx_binding_c/source/c_subscriber.cpp index 8e405ce673a..0a83d044ae5 100644 --- a/iceoryx_binding_c/source/c_subscriber.cpp +++ b/iceoryx_binding_c/source/c_subscriber.cpp @@ -76,8 +76,8 @@ iox_sub_t iox_sub_init(iox_sub_storage_t* self, { // note that they may have been initialized but the initCheck // pattern overwritten afterwards, we cannot be sure but it is a misuse - LogError() << "subscriber options may not have been initialized with iox_sub_init"; - std::terminate(); + LogFatal() << "subscriber options may not have been initialized with iox_sub_init"; + errorHandler(Error::kBINDING_C__SUBSCRIBER_OPTIONS_NOT_INITIALIZED); } subscriberOptions.queueCapacity = options->queueCapacity; subscriberOptions.historyRequest = options->historyRequest; diff --git a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp index f0e6ec91b7e..35655f41eeb 100644 --- a/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp +++ b/iceoryx_utils/include/iceoryx_utils/error_handling/error_handling.hpp @@ -127,7 +127,9 @@ namespace iox error(POSIX_TIMER__TIMERPOOL_OVERFLOW) \ error(POSIX_TIMER__INCONSISTENT_STATE) \ error(POSIX_TIMER__CALLBACK_RUNTIME_EXCEEDS_RETRIGGER_TIME) \ - error(VARIANT_QUEUE__UNSUPPORTED_QUEUE_TYPE) + error(VARIANT_QUEUE__UNSUPPORTED_QUEUE_TYPE) \ + error(BINDING_C__PUBLISHER_OPTIONS_NOT_INITIALIZED) \ + error(BINDING_C__SUBSCRIBER_OPTIONS_NOT_INITIALIZED) // clang-format on From bd4294d2f4b541e189ab002f8fa6577e77a6cc4a Mon Sep 17 00:00:00 2001 From: Simon Hoinkis Date: Mon, 1 Mar 2021 19:27:18 +0100 Subject: [PATCH 097/143] iox-#549 Make helplets implementation generic and print warning in log Signed-off-by: Simon Hoinkis --- doc/website/getting-started/installation.md | 2 +- iceoryx_posh/source/roudi/roudi.cpp | 5 ++++- iceoryx_posh/source/runtime/posh_runtime.cpp | 5 ++++- iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp | 9 ++++----- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/doc/website/getting-started/installation.md b/doc/website/getting-started/installation.md index 1d5f5a0e0b0..d8ca0002fe7 100644 --- a/doc/website/getting-started/installation.md +++ b/doc/website/getting-started/installation.md @@ -6,7 +6,7 @@ iceoryx_utils and iceoryx_posh are deployed as independent cmake packages. Posh ### Dependencies - - 64-bit hardware (e.g. x86_64 or aarch64) + - 64-bit hardware (e.g. x86_64 or aarch64; 32-bit hardware might work, but is not supported) - [cmake](https://cmake.org), 3.5 or later - One of the following compilers: - [gcc](https://gcc.gnu.org), 7.4 or later diff --git a/iceoryx_posh/source/roudi/roudi.cpp b/iceoryx_posh/source/roudi/roudi.cpp index 1ed68ed6bd9..241231a6c8b 100644 --- a/iceoryx_posh/source/roudi/roudi.cpp +++ b/iceoryx_posh/source/roudi/roudi.cpp @@ -47,7 +47,10 @@ RouDi::RouDi(RouDiMemoryInterface& roudiMemoryInterface, , m_monitoringMode(roudiStartupParameters.m_monitoringMode) , m_processKillDelay(roudiStartupParameters.m_processKillDelay) { - cxx::printWarningOn32BitSystems(); + if (cxx::isCompiledOn32BitSystem()) + { + LogWarn() << "Warning! Runnning RouDi on 32-bit architectures is not supported! Use at your own risk!"; + } m_processIntrospection.registerPublisherPort(PublisherPortUserType( m_prcMgr.addIntrospectionPublisherPort(IntrospectionProcessService, IPC_CHANNEL_ROUDI_NAME))); m_prcMgr.initIntrospection(&m_processIntrospection); diff --git a/iceoryx_posh/source/runtime/posh_runtime.cpp b/iceoryx_posh/source/runtime/posh_runtime.cpp index 87178402412..ae779655907 100644 --- a/iceoryx_posh/source/runtime/posh_runtime.cpp +++ b/iceoryx_posh/source/runtime/posh_runtime.cpp @@ -83,7 +83,10 @@ PoshRuntime::PoshRuntime(cxx::optional name, const bool do m_ipcChannelInterface.getSegmentManagerAddressOffset()) , m_applicationPort(getMiddlewareApplication()) { - cxx::printWarningOn32BitSystems(); + if (cxx::isCompiledOn32BitSystem()) + { + LogWarn() << "Warning! Running applications on 32-bit architectures is not supported! Use at your own risk!"; + } /// @todo here we could get the LogLevel and LogMode and set it on the LogManager } diff --git a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp index 6cbe1f68430..7f5437e6dde 100644 --- a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp +++ b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp @@ -205,12 +205,11 @@ static constexpr uint64_t strlen2(char const (&/*notInterested*/)[SizeValue]) #define DISCARD_RESULT(expr) auto DISCARD_RESULT_VARIABLE(unusedOnLine, __LINE__) [[gnu::unused]] = expr // clang-format on -/// @brief Prints a warning to std::cerr if called on a 32-bit system -constexpr void printWarningOn32BitSystems() +/// @brief Returns info whether called on a 32-bit system +/// @return True if called on 32-bit, false if not 32-bit system +constexpr bool isCompiledOn32BitSystem() { -#if INTPTR_MAX == INT32_MAX - std::cerr << "Warning! 32-bit architectures are unsupported! Use at your own risk!" std::endl; -#endif + return INTPTR_MAX == INT32_MAX; } } // namespace cxx From 694146ddde9108e0f1b3cbe6cb67e86499fec008 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Mon, 1 Mar 2021 13:58:56 +0100 Subject: [PATCH 098/143] iox-#349 add process column Signed-off-by: Marika Lehmann --- tools/introspection/source/introspection_app.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/introspection/source/introspection_app.cpp b/tools/introspection/source/introspection_app.cpp index 97af0ba3210..d0e81cde4f9 100644 --- a/tools/introspection/source/introspection_app.cpp +++ b/tools/introspection/source/introspection_app.cpp @@ -415,6 +415,7 @@ void IntrospectionApp::printPortIntrospectionData(const std::vectorm_caproServiceID).c_str()); wprintw(pad, " %s |", printEntry(instanceWidth, subscriber.portData->m_caproInstanceID).c_str()); wprintw(pad, " %s |", printEntry(eventWidth, subscriber.portData->m_caproEventMethodID).c_str()); + wprintw(pad, " %s |", printEntry(processNameWidth, subscriber.portData->m_name).c_str()); wprintw(pad, " %s |", printEntry(nodeNameWidth, subscriber.portData->m_node).c_str()); wprintw(pad, " %s |", @@ -490,6 +493,7 @@ void IntrospectionApp::printPortIntrospectionData(const std::vector Date: Wed, 3 Mar 2021 09:07:38 +0100 Subject: [PATCH 099/143] iox-#408 rename free_chunk in C-API Signed-off-by: Matthias Killat --- iceoryx_binding_c/include/iceoryx_binding_c/publisher.h | 2 +- iceoryx_binding_c/source/c_publisher.cpp | 2 +- iceoryx_binding_c/test/moduletests/test_publisher.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h index b86b586e550..a19d0aa2486 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h @@ -81,7 +81,7 @@ ENUM iox_AllocationResult iox_pub_loan_chunk(iox_pub_t const self, void** const /// @brief frees a previously allocated chunk without sending it /// @param[in] self handle of the publisher /// @param[in] chunk chunk which should be free'd -void iox_pub_free_chunk(iox_pub_t const self, void* const chunk); +void iox_pub_release_chunk(iox_pub_t const self, void* const chunk); /// @brief sends a previously allocated chunk /// @param[in] self handle of the publisher diff --git a/iceoryx_binding_c/source/c_publisher.cpp b/iceoryx_binding_c/source/c_publisher.cpp index 4986e9e1cf0..458565b4538 100644 --- a/iceoryx_binding_c/source/c_publisher.cpp +++ b/iceoryx_binding_c/source/c_publisher.cpp @@ -109,7 +109,7 @@ iox_AllocationResult iox_pub_loan_chunk(iox_pub_t const self, void** const chunk return AllocationResult_SUCCESS; } -void iox_pub_free_chunk(iox_pub_t const self, void* const chunk) +void iox_pub_release_chunk(iox_pub_t const self, void* const chunk) { PublisherPortUser(self->m_portData).releaseChunk(ChunkHeader::fromPayload(chunk)); } diff --git a/iceoryx_binding_c/test/moduletests/test_publisher.cpp b/iceoryx_binding_c/test/moduletests/test_publisher.cpp index 41ba667d8d7..134cae13990 100644 --- a/iceoryx_binding_c/test/moduletests/test_publisher.cpp +++ b/iceoryx_binding_c/test/moduletests/test_publisher.cpp @@ -217,7 +217,7 @@ TEST_F(iox_pub_test, freeingAnAllocatedChunkReleasesTheMemory) { void* chunk = nullptr; iox_pub_loan_chunk(&m_sut, &chunk, 100); - iox_pub_free_chunk(&m_sut, chunk); + iox_pub_release_chunk(&m_sut, chunk); EXPECT_THAT(m_memoryManager.getMemPoolInfo(0).m_usedChunks, Eq(0u)); } From 55a6f79c0e4c00523b4eab46ab01bafd97f9421a Mon Sep 17 00:00:00 2001 From: Simon Hoinkis Date: Tue, 2 Mar 2021 12:22:48 +0100 Subject: [PATCH 100/143] iox-#549 Remove superfluous warning Signed-off-by: Simon Hoinkis --- iceoryx_posh/source/roudi/roudi.cpp | 2 +- iceoryx_posh/source/runtime/posh_runtime.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/iceoryx_posh/source/roudi/roudi.cpp b/iceoryx_posh/source/roudi/roudi.cpp index 241231a6c8b..f44a3944840 100644 --- a/iceoryx_posh/source/roudi/roudi.cpp +++ b/iceoryx_posh/source/roudi/roudi.cpp @@ -49,7 +49,7 @@ RouDi::RouDi(RouDiMemoryInterface& roudiMemoryInterface, { if (cxx::isCompiledOn32BitSystem()) { - LogWarn() << "Warning! Runnning RouDi on 32-bit architectures is not supported! Use at your own risk!"; + LogWarn() << "Runnning RouDi on 32-bit architectures is not supported! Use at your own risk!"; } m_processIntrospection.registerPublisherPort(PublisherPortUserType( m_prcMgr.addIntrospectionPublisherPort(IntrospectionProcessService, IPC_CHANNEL_ROUDI_NAME))); diff --git a/iceoryx_posh/source/runtime/posh_runtime.cpp b/iceoryx_posh/source/runtime/posh_runtime.cpp index ae779655907..cf6dc47e098 100644 --- a/iceoryx_posh/source/runtime/posh_runtime.cpp +++ b/iceoryx_posh/source/runtime/posh_runtime.cpp @@ -85,7 +85,7 @@ PoshRuntime::PoshRuntime(cxx::optional name, const bool do { if (cxx::isCompiledOn32BitSystem()) { - LogWarn() << "Warning! Running applications on 32-bit architectures is not supported! Use at your own risk!"; + LogWarn() << "Running applications on 32-bit architectures is not supported! Use at your own risk!"; } /// @todo here we could get the LogLevel and LogMode and set it on the LogManager } From 93c28296d5c8665e6af4bd92525f349acd668cd0 Mon Sep 17 00:00:00 2001 From: Mathias Kraus Date: Mon, 1 Mar 2021 17:01:59 +0100 Subject: [PATCH 101/143] iox-#14 rename test_mepoo_handler.cpp to test_mepoo_memory_manager.cpp Signed-off-by: Mathias Kraus --- .../{test_mepoo_handler.cpp => test_mepoo_memory_manager.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename iceoryx_posh/test/moduletests/{test_mepoo_handler.cpp => test_mepoo_memory_manager.cpp} (100%) diff --git a/iceoryx_posh/test/moduletests/test_mepoo_handler.cpp b/iceoryx_posh/test/moduletests/test_mepoo_memory_manager.cpp similarity index 100% rename from iceoryx_posh/test/moduletests/test_mepoo_handler.cpp rename to iceoryx_posh/test/moduletests/test_mepoo_memory_manager.cpp From 9d0e9c17426b417b7b6ac700b8b8e79997199d95 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Mon, 1 Mar 2021 14:17:57 +0100 Subject: [PATCH 102/143] iox-#349 remove FiFo column Signed-off-by: Marika Lehmann --- .../source/introspection_app.cpp | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/tools/introspection/source/introspection_app.cpp b/tools/introspection/source/introspection_app.cpp index d0e81cde4f9..4289930babb 100644 --- a/tools/introspection/source/introspection_app.cpp +++ b/tools/introspection/source/introspection_app.cpp @@ -312,7 +312,7 @@ void IntrospectionApp::printPortIntrospectionData(const std::vectorsubscriptionState)) .c_str()); - if (currentLine == 0) - { - std::string fifoSize{"n/a"}; // std::to_string(subscriber.subscriberPortChangingData->fifoSize)) - std::string fifoCapacity{"n/a"}; // std::to_string(subscriber.subscriberPortChangingData->fifoCapacity)) - wprintw(pad, - " %s / %s |", - printEntry(((fifoWidth / 2) - 1), fifoSize).c_str(), - printEntry(((fifoWidth / 2) - 1), fifoCapacity).c_str()); - } - else - { - wprintw(pad, " %*s |", fifoWidth, ""); - } + // uncomment once this information is needed + // if (currentLine == 0) + //{ + // std::string fifoSize{"n/a"}; // std::to_string(subscriber.subscriberPortChangingData->fifoSize)) + // std::string fifoCapacity{"n/a"}; // std::to_string(subscriber.subscriberPortChangingData->fifoCapacity)) + // wprintw(pad, + //" %s / %s |", + // printEntry(((fifoWidth / 2) - 1), fifoSize).c_str(), + // printEntry(((fifoWidth / 2) - 1), fifoCapacity).c_str()); + //} + // else + //{ + // wprintw(pad, " %*s |", fifoWidth, ""); + //} wprintw(pad, " %s\n", printEntry(scopeWidth, @@ -496,7 +497,7 @@ void IntrospectionApp::printPortIntrospectionData(const std::vector Date: Tue, 2 Mar 2021 12:27:30 +0100 Subject: [PATCH 103/143] iox-#549 Address review findings by updating the documentation Signed-off-by: Simon Hoinkis --- iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp b/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp index e6cde9760a0..be72e2ae2a2 100644 --- a/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp +++ b/iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp @@ -56,7 +56,6 @@ enum class FindServiceError INVALID_STATE, UNABLE_TO_WRITE_TO_ROUDI_CHANNEL, INSTANCE_CONTAINER_OVERFLOW - }; /// @brief The runtime that is needed for each application to communicate with the RouDi daemon @@ -81,11 +80,9 @@ class PoshRuntime /// @brief find all services that match the provided service description /// @param[in] serviceDescription service to search for - /// @return cxx::expected + /// @return cxx::expected /// InstanceContainer: on success, container that is filled with all matching instances - /// Error: if any, encountered during the operation - /// FindServiceError::INSTANCE_CONTAINER_OVERFLOW : Number of instances can't fit in instanceContainer - /// FindServiceError::UNABLE_TO_WRITE_TO_ROUDI_CHANNEL : Find Service Request could not be sent to RouDi + /// FindServiceError: if any, encountered during the operation cxx::expected findService(const capro::ServiceDescription& serviceDescription) noexcept; From 7543f1fc90d0b7c06210ee38d30266679a1c7533 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Mon, 1 Mar 2021 14:29:59 +0100 Subject: [PATCH 104/143] iox-#349 remove columns in which entries are not calculated Signed-off-by: Marika Lehmann --- .../source/introspection_app.cpp | 47 ++++++++++--------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/tools/introspection/source/introspection_app.cpp b/tools/introspection/source/introspection_app.cpp index 4289930babb..1ab55295d5e 100644 --- a/tools/introspection/source/introspection_app.cpp +++ b/tools/introspection/source/introspection_app.cpp @@ -307,10 +307,11 @@ void IntrospectionApp::printPortIntrospectionData(const std::vectorm_caproEventMethodID).c_str()); wprintw(pad, " %s |", printEntry(processNameWidth, publisherPort.portData->m_name).c_str()); wprintw(pad, " %s |", printEntry(nodeNameWidth, publisherPort.portData->m_node).c_str()); - wprintw(pad, " %s |", printEntry(sampleSizeWidth, m_sampleSize).c_str()); - wprintw(pad, " %s |", printEntry(chunkSizeWidth, m_chunkSize).c_str()); - wprintw(pad, " %s |", printEntry(chunksWidth, m_chunksPerMinute).c_str()); - wprintw(pad, " %s |", printEntry(intervalWidth, sendInterval).c_str()); + // uncomment once this information is needed + // wprintw(pad, " %s |", printEntry(sampleSizeWidth, m_sampleSize).c_str()); + // wprintw(pad, " %s |", printEntry(chunkSizeWidth, m_chunkSize).c_str()); + // wprintw(pad, " %s |", printEntry(chunksWidth, m_chunksPerMinute).c_str()); + // wprintw(pad, " %s |", printEntry(intervalWidth, sendInterval).c_str()); wprintw( pad, " %s\n", From adbe8dd79757f327f8f0a8065f4c8cc538e31897 Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Wed, 3 Mar 2021 18:37:25 +0100 Subject: [PATCH 105/143] iox-#408 corrected documentation Signed-off-by: Matthias Killat --- iceoryx_binding_c/include/iceoryx_binding_c/publisher.h | 7 ++++--- iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h | 5 +++-- iceoryx_binding_c/test/moduletests/test_subscriber.cpp | 5 ----- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h index a19d0aa2486..dc2155c79c7 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h @@ -42,7 +42,7 @@ typedef struct /// @brief initialize publisher options to default values /// @param[in] options pointer to options to be initialized, -/// if it is a null pointer default options are used +/// emit warning if it is a null pointer /// @attention This must always be called on a newly created options struct to /// prevent uninitialized values. The options may get extended /// in the future. @@ -58,7 +58,8 @@ bool iox_pub_options_is_initialized(const iox_pub_options_t* const options); /// @param[in] service serviceString /// @param[in] instance instanceString /// @param[in] event eventString -/// @param[in] options publisher options set by the user +/// @param[in] options publisher options set by the user, +/// if it is a null pointer default options are used /// @return handle of the publisher iox_pub_t iox_pub_init(iox_pub_storage_t* self, const char* const service, @@ -78,7 +79,7 @@ void iox_pub_deinit(iox_pub_t const self); /// describes the error ENUM iox_AllocationResult iox_pub_loan_chunk(iox_pub_t const self, void** const chunk, const uint32_t payloadSize); -/// @brief frees a previously allocated chunk without sending it +/// @brief releases ownership of a previously allocated chunk without sending it /// @param[in] self handle of the publisher /// @param[in] chunk chunk which should be free'd void iox_pub_release_chunk(iox_pub_t const self, void* const chunk); diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h index 8d8ba1189e0..321e969e09f 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h @@ -45,7 +45,7 @@ typedef struct /// @brief initialize subscriber options to default values /// @param[in] options pointer to options to be initialized, -/// if it is a null pointer default options are used +/// emit warning if it is a null pointer /// @attention This must always be called on a newly created options struct to /// prevent uninitialized values. The options may get extended /// in the future. @@ -61,7 +61,8 @@ bool iox_sub_options_is_initialized(const iox_sub_options_t* const options); /// @param[in] service serviceString /// @param[in] instance instanceString /// @param[in] event eventString -/// @param[in] options subscriber options set by the user +/// @param[in] options subscriber options set by the user, +/// if it is a null pointer default options are used /// @return handle of the subscriber iox_sub_t iox_sub_init(iox_sub_storage_t* self, const char* const service, diff --git a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp index b48bd4db289..904c92a3097 100644 --- a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp +++ b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp @@ -193,11 +193,6 @@ TEST_F(iox_sub_test, receiveChunkWithContent) TEST_F(iox_sub_test, chunkHeaderCanBeObtainedFromChunkAfterTake) { this->Subscribe(&m_portPtr); - struct data_t - { - int value; - }; - auto sharedChunk = m_memoryManager.getChunk(100U); m_chunkPusher.push(sharedChunk); From 3e586970c8289202c52bc19479228eeddb512d5c Mon Sep 17 00:00:00 2001 From: Michael Poehnl Date: Sat, 27 Feb 2021 21:42:39 +0100 Subject: [PATCH 106/143] iox-#408 added on create in CPP options Signed-off-by: Michael Poehnl --- .../include/iceoryx_posh/popo/publisher_options.hpp | 4 ++++ .../include/iceoryx_posh/popo/subscriber_options.hpp | 6 +++++- iceoryx_posh/source/roudi/roudi.cpp | 11 +++++++---- iceoryx_posh/source/runtime/posh_runtime.cpp | 8 ++++---- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/popo/publisher_options.hpp b/iceoryx_posh/include/iceoryx_posh/popo/publisher_options.hpp index 9d76afaf4c4..174900bb126 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/publisher_options.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/publisher_options.hpp @@ -32,6 +32,10 @@ struct PublisherOptions /// @brief The name of the node where the publisher should belong to iox::NodeName_t nodeName{""}; + + /// @brief The option whether the publisher should already be offered when creating it + bool offerOnCreate = {true}; + }; } // namespace popo diff --git a/iceoryx_posh/include/iceoryx_posh/popo/subscriber_options.hpp b/iceoryx_posh/include/iceoryx_posh/popo/subscriber_options.hpp index 4f67b7f0cad..5b3ec8e2180 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/subscriber_options.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/subscriber_options.hpp @@ -35,8 +35,12 @@ struct SubscriberOptions /// @brief The max number of chunks received after subscription if chunks are available uint64_t historyRequest{0U}; - /// @ brief The name of the node where the subscriber should belong to + /// @brief The name of the node where the subscriber should belong to iox::NodeName_t nodeName{""}; + + /// @brief The option whether the subscriber shall try to subscribe when creating it + bool subscribeOnCreate = {true}; + }; } // namespace popo diff --git a/iceoryx_posh/source/roudi/roudi.cpp b/iceoryx_posh/source/roudi/roudi.cpp index d02113644dc..d7318ed6b32 100644 --- a/iceoryx_posh/source/roudi/roudi.cpp +++ b/iceoryx_posh/source/roudi/roudi.cpp @@ -181,7 +181,7 @@ void RouDi::processMessage(const runtime::IpcMessage& message, } case runtime::IpcMessageType::CREATE_PUBLISHER: { - if (message.getNumberOfElements() != 6) + if (message.getNumberOfElements() != 7) { LogError() << "Wrong number of parameters for \"IpcMessageType::CREATE_PUBLISHER\" from \"" << processName << "\"received!"; @@ -189,11 +189,12 @@ void RouDi::processMessage(const runtime::IpcMessage& message, else { capro::ServiceDescription service(cxx::Serialization(message.getElementAtIndex(2))); - cxx::Serialization portConfigInfoSerialization(message.getElementAtIndex(5)); + cxx::Serialization portConfigInfoSerialization(message.getElementAtIndex(6)); popo::PublisherOptions options; options.historyCapacity = std::stoull(message.getElementAtIndex(3)); options.nodeName = NodeName_t(cxx::TruncateToCapacity, message.getElementAtIndex(4)); + options.offerOnCreate = (0U == std::stoull(message.getElementAtIndex(5))) ? false : true; m_prcMgr.addPublisherForProcess( processName, service, options, iox::runtime::PortConfigInfo(portConfigInfoSerialization)); @@ -202,7 +203,7 @@ void RouDi::processMessage(const runtime::IpcMessage& message, } case runtime::IpcMessageType::CREATE_SUBSCRIBER: { - if (message.getNumberOfElements() != 7) + if (message.getNumberOfElements() != 8) { LogError() << "Wrong number of parameters for \"IpcMessageType::CREATE_SUBSCRIBER\" from \"" << processName << "\"received!"; @@ -210,13 +211,15 @@ void RouDi::processMessage(const runtime::IpcMessage& message, else { capro::ServiceDescription service(cxx::Serialization(message.getElementAtIndex(2))); - cxx::Serialization portConfigInfoSerialization(message.getElementAtIndex(6)); + cxx::Serialization portConfigInfoSerialization(message.getElementAtIndex(7)); popo::SubscriberOptions options; options.historyRequest = std::stoull(message.getElementAtIndex(3)); options.queueCapacity = std::stoull(message.getElementAtIndex(4)); options.nodeName = NodeName_t(cxx::TruncateToCapacity, message.getElementAtIndex(5)); + options.subscribeOnCreate = (0U == std::stoull(message.getElementAtIndex(6))) ? false : true; + m_prcMgr.addSubscriberForProcess( processName, service, options, iox::runtime::PortConfigInfo(portConfigInfoSerialization)); diff --git a/iceoryx_posh/source/runtime/posh_runtime.cpp b/iceoryx_posh/source/runtime/posh_runtime.cpp index a6c48a4e937..8587675bee0 100644 --- a/iceoryx_posh/source/runtime/posh_runtime.cpp +++ b/iceoryx_posh/source/runtime/posh_runtime.cpp @@ -166,7 +166,8 @@ PublisherPortUserType::MemberType_t* PoshRuntime::getMiddlewarePublisher(const c IpcMessage sendBuffer; sendBuffer << IpcMessageTypeToString(IpcMessageType::CREATE_PUBLISHER) << m_appName << static_cast(service).toString() << std::to_string(options.historyCapacity) - << options.nodeName << static_cast(portConfigInfo).toString(); + << options.nodeName << std::to_string(options.offerOnCreate) + << static_cast(portConfigInfo).toString(); auto maybePublisher = requestPublisherFromRoudi(sendBuffer); if (maybePublisher.has_error()) @@ -264,7 +265,7 @@ PoshRuntime::getMiddlewareSubscriber(const capro::ServiceDescription& service, IpcMessage sendBuffer; sendBuffer << IpcMessageTypeToString(IpcMessageType::CREATE_SUBSCRIBER) << m_appName << static_cast(service).toString() << std::to_string(options.historyRequest) - << std::to_string(options.queueCapacity) << options.nodeName + << std::to_string(options.queueCapacity) << options.nodeName << std::to_string(options.subscribeOnCreate) << static_cast(portConfigInfo).toString(); auto maybeSubscriber = requestSubscriberFromRoudi(sendBuffer); @@ -389,8 +390,7 @@ NodeData* PoshRuntime::createNode(const NodeProperty& nodeProperty) noexcept } LogError() << "Got wrong response from RouDi while creating node:'" << receiveBuffer.getMessage() << "'"; - errorHandler( - Error::kPOSH__RUNTIME_ROUDI_CREATE_NODE_WRONG_IPC_MESSAGE_RESPONSE, nullptr, iox::ErrorLevel::SEVERE); + errorHandler(Error::kPOSH__RUNTIME_ROUDI_CREATE_NODE_WRONG_IPC_MESSAGE_RESPONSE, nullptr, iox::ErrorLevel::SEVERE); return nullptr; } From b4f08a56395d5b15d960a45f35d3bbddf7b182ca Mon Sep 17 00:00:00 2001 From: "Hintz Martin (XC-AD/ESW1-J1)" Date: Wed, 3 Mar 2021 14:47:04 +0100 Subject: [PATCH 107/143] iox-#591 Added void_t to type_traits Signed-off-by: Hintz Martin (XC-AD/ESW1-J1) --- .../include/iceoryx_utils/cxx/type_traits.hpp | 3 ++ .../iceoryx_utils/internal/cxx/expected.inl | 2 +- .../test/moduletests/test_cxx_type_traits.cpp | 38 +++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/iceoryx_utils/include/iceoryx_utils/cxx/type_traits.hpp b/iceoryx_utils/include/iceoryx_utils/cxx/type_traits.hpp index 2cfd0701e4f..f0e180d4e0e 100644 --- a/iceoryx_utils/include/iceoryx_utils/cxx/type_traits.hpp +++ b/iceoryx_utils/include/iceoryx_utils/cxx/type_traits.hpp @@ -72,6 +72,9 @@ template using not_same = typename std:: integral_constant::type, typename std::decay::type>::value)>; +/// @brief Maps a sequence of any types to the type void +template +using void_t = void; } // namespace cxx } // namespace iox diff --git a/iceoryx_utils/include/iceoryx_utils/internal/cxx/expected.inl b/iceoryx_utils/include/iceoryx_utils/internal/cxx/expected.inl index d9168657d35..a9495d17294 100644 --- a/iceoryx_utils/include/iceoryx_utils/internal/cxx/expected.inl +++ b/iceoryx_utils/include/iceoryx_utils/internal/cxx/expected.inl @@ -29,7 +29,7 @@ struct HasInvalidStateMember : std::false_type { }; template -struct HasInvalidStateMember> : std::true_type +struct HasInvalidStateMember> : std::true_type { }; template diff --git a/iceoryx_utils/test/moduletests/test_cxx_type_traits.cpp b/iceoryx_utils/test/moduletests/test_cxx_type_traits.cpp index 8609d1e36e8..5f7e0c2ff80 100644 --- a/iceoryx_utils/test/moduletests/test_cxx_type_traits.cpp +++ b/iceoryx_utils/test/moduletests/test_cxx_type_traits.cpp @@ -59,3 +59,41 @@ TEST(TypeTraitsTest, NotSameIsFalse) auto sut = not_same::value; EXPECT_FALSE(sut); } + +namespace iox +{ +namespace cxx +{ +namespace test +{ +template +struct has_mytype_as_member : std::false_type +{ +}; + +template +struct has_mytype_as_member> : std::true_type +{ +}; +} // namespace test +} // namespace cxx +} // namespace iox + +TEST(TypeTraitsTest, NoTypeAsMemberIsFalse) +{ + struct Sut + { + }; + + EXPECT_FALSE(iox::cxx::test::has_mytype_as_member::value); +} + +TEST(TypeTraitsTest, MyTypeAsMemberIsTrue) +{ + struct Sut + { + using myType = int; + }; + + EXPECT_TRUE(iox::cxx::test::has_mytype_as_member::value); +} From e7b48eafe45cef352c99831814008822162a8cc0 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Mon, 1 Mar 2021 19:02:50 +0100 Subject: [PATCH 108/143] iox-#349 update icecrystal readme Signed-off-by: Marika Lehmann --- iceoryx_examples/icecrystal/Readme.md | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/iceoryx_examples/icecrystal/Readme.md b/iceoryx_examples/icecrystal/Readme.md index 97a300cfb59..805cb8da790 100644 --- a/iceoryx_examples/icecrystal/Readme.md +++ b/iceoryx_examples/icecrystal/Readme.md @@ -50,15 +50,10 @@ The process view will show you the processes (incl. PID), which are currently re --port Subscribe to port introspection data. -The port view shows both publisher and subscriber ports that are created by RouDi in the shared memory. Their respective -service description (service, instance, event) is shown to identify them uniquely. The columns `Process` and -`used by process` display to which process the ports belong and how they are currently connected. Size in bytes of -both sample size and chunk size (sample size + meta data) and statistical data of `Chunks [/Minute]` is provided as -well. When a publisher port instantly provides data to a subscriber with the `subscribe()` call, the `Field` column is -ticked. The service discovery protocol allows you to define the `Propagation scope` of the data. This can enable -data forwarding to other machines e.g. over network or just consume them internally. When a `Callback` is -registered on subscriber side, the box is ticked accordingly. `FiFo size / capacity` shows the consumption of chunks -on the subscriber side and is a useful column to debug potential memleaks. +The port view shows both publisher and subscriber ports that are created by RouDi in the shared memory. Their respective service +description (service, instance, event) is shown to identify them uniquely. The columns `Process` and `Node` display to which +process and node the ports belong. The service discovery protocol allows you to define the `Propagation scope` of the data. This +can enable data forwarding to other machines e.g. over network or just consume them internally. --all Subscribe to all available introspection data. From 053d895c71b4d63ab671fb7365e61e1d60490199 Mon Sep 17 00:00:00 2001 From: Matthias Killat Date: Thu, 4 Mar 2021 14:02:52 +0100 Subject: [PATCH 109/143] iox-#408 fix findings Signed-off-by: Matthias Killat --- iceoryx_binding_c/include/iceoryx_binding_c/chunk.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/chunk.h b/iceoryx_binding_c/include/iceoryx_binding_c/chunk.h index 936bb301ed9..04990ea321c 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/chunk.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/chunk.h @@ -32,4 +32,4 @@ void* iox_chunk_header_to_payload(iox_chunk_header_t const header); /// @return pointer to the chunk header iox_chunk_header_t iox_chunk_payload_to_header(const void* const payload); -#endif \ No newline at end of file +#endif From cc17fe497876659055422d1ee961e52db7530432 Mon Sep 17 00:00:00 2001 From: Michael Poehnl Date: Sat, 27 Feb 2021 23:44:40 +0100 Subject: [PATCH 110/143] iox-#408 update of ports Signed-off-by: Michael Poehnl --- .../source/popo/ports/publisher_port_data.cpp | 1 + .../popo/ports/subscriber_port_data.cpp | 1 + .../moduletests/test_popo_publisher_port.cpp | 177 ++++++++++-------- .../moduletests/test_popo_subscriber_port.cpp | 30 ++- 4 files changed, 128 insertions(+), 81 deletions(-) diff --git a/iceoryx_posh/source/popo/ports/publisher_port_data.cpp b/iceoryx_posh/source/popo/ports/publisher_port_data.cpp index 8151f9e3b55..463d4798b0d 100644 --- a/iceoryx_posh/source/popo/ports/publisher_port_data.cpp +++ b/iceoryx_posh/source/popo/ports/publisher_port_data.cpp @@ -27,6 +27,7 @@ PublisherPortData::PublisherPortData(const capro::ServiceDescription& serviceDes const mepoo::MemoryInfo& memoryInfo) noexcept : BasePortData(serviceDescription, processName, publisherOptions.nodeName) , m_chunkSenderData(memoryManager, publisherOptions.historyCapacity, memoryInfo) + , m_offeringRequested(publisherOptions.offerOnCreate) { } diff --git a/iceoryx_posh/source/popo/ports/subscriber_port_data.cpp b/iceoryx_posh/source/popo/ports/subscriber_port_data.cpp index 44cdea33323..8d26cab727b 100644 --- a/iceoryx_posh/source/popo/ports/subscriber_port_data.cpp +++ b/iceoryx_posh/source/popo/ports/subscriber_port_data.cpp @@ -29,6 +29,7 @@ SubscriberPortData::SubscriberPortData(const capro::ServiceDescription& serviceD : BasePortData(serviceDescription, processName, subscriberOptions.nodeName) , m_chunkReceiverData(queueType, memoryInfo) , m_historyRequest(subscriberOptions.historyRequest) + , m_subscribeRequested(subscriberOptions.subscribeOnCreate) { m_chunkReceiverData.m_queue.setCapacity(subscriberOptions.queueCapacity); } diff --git a/iceoryx_posh/test/moduletests/test_popo_publisher_port.cpp b/iceoryx_posh/test/moduletests/test_popo_publisher_port.cpp index 2b309be7e59..ebec8dd928c 100644 --- a/iceoryx_posh/test/moduletests/test_popo_publisher_port.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_publisher_port.cpp @@ -72,51 +72,74 @@ class PublisherPort_test : public Test iox::posix::Allocator m_memoryAllocator{m_memory, MEMORY_SIZE}; iox::mepoo::MePooConfig m_mempoolconf; iox::mepoo::MemoryManager m_memoryManager; - iox::popo::PublisherOptions m_publisherOptions; + iox::popo::PublisherOptions m_noOfferOnCreatePublisherOptions{0U, "", false};; - // publisher port w/o history + // publisher port w/o offer on create iox::popo::PublisherPortData m_publisherPortData{ - iox::capro::ServiceDescription("a", "b", "c"), "myApp", &m_memoryManager, m_publisherOptions}; - iox::popo::PublisherPortRouDi m_sutRouDiSide{&m_publisherPortData}; - iox::popo::PublisherPortUser m_sutUserSide{&m_publisherPortData}; + iox::capro::ServiceDescription("a", "b", "c"), "myApp", &m_memoryManager, m_noOfferOnCreatePublisherOptions}; + iox::popo::PublisherPortRouDi m_sutNoOfferOnCreateRouDiSide{&m_publisherPortData}; + iox::popo::PublisherPortUser m_sutNoOfferOnCreateUserSide{&m_publisherPortData}; - // publisher port w/ history - iox::popo::PublisherOptions m_publisherPortOptions{iox::MAX_PUBLISHER_HISTORY}; + // publisher port w/ history + iox::popo::PublisherOptions m_withHistoryPublisherOptions{iox::MAX_PUBLISHER_HISTORY, "", true}; iox::popo::PublisherPortData m_publisherPortDataHistory{ - iox::capro::ServiceDescription("x", "y", "z"), "myApp", &m_memoryManager, m_publisherPortOptions}; - iox::popo::PublisherPortUser m_sutWithHistoryUseriSide{&m_publisherPortDataHistory}; + iox::capro::ServiceDescription("x", "y", "z"), "myApp", &m_memoryManager, m_withHistoryPublisherOptions}; + iox::popo::PublisherPortUser m_sutWithHistoryUserSide{&m_publisherPortDataHistory}; iox::popo::PublisherPortRouDi m_sutWithHistoryRouDiSide{&m_publisherPortDataHistory}; + + // publisher port w/ default options + iox::popo::PublisherOptions m_withDefaultPublisherOptions{}; + iox::popo::PublisherPortData m_publisherPortDataDefault{ + iox::capro::ServiceDescription("x", "y", "z"), "myApp", &m_memoryManager, m_withDefaultPublisherOptions}; + iox::popo::PublisherPortUser m_sutWithDefaultOptionsUseriSide{&m_publisherPortDataDefault}; + iox::popo::PublisherPortRouDi m_sutWithDefaultOptionsRouDiSide{&m_publisherPortDataDefault}; }; -TEST_F(PublisherPort_test, initialStateIsNotOffered) +TEST_F(PublisherPort_test, initialStateIsOfferedWithDefaultOptions) +{ + EXPECT_TRUE(m_sutWithDefaultOptionsUseriSide.isOffered()); +} + +TEST_F(PublisherPort_test, initialStateIsNotOfferedWhenNoOfferOnCreate) { - EXPECT_FALSE(m_sutUserSide.isOffered()); + EXPECT_FALSE(m_sutNoOfferOnCreateUserSide.isOffered()); } + TEST_F(PublisherPort_test, initialStateIsNoSubscribers) { - EXPECT_FALSE(m_sutUserSide.hasSubscribers()); + EXPECT_FALSE(m_sutNoOfferOnCreateUserSide.hasSubscribers()); } -TEST_F(PublisherPort_test, initialStateReturnsNoCaProMessage) +TEST_F(PublisherPort_test, initialStateReturnsOfferCaProMessageWithDefaultOptions) { - auto maybeCaproMessage = m_sutRouDiSide.tryGetCaProMessage(); + auto maybeCaproMessage = m_sutWithDefaultOptionsRouDiSide.tryGetCaProMessage(); + + EXPECT_TRUE(maybeCaproMessage.has_value()); + auto caproMessage = maybeCaproMessage.value(); + EXPECT_THAT(caproMessage.m_type, Eq(iox::capro::CaproMessageType::OFFER)); +} + +TEST_F(PublisherPort_test, initialStateReturnsNoCaProMessageWhenNoOfferOnCreate) +{ + auto maybeCaproMessage = m_sutNoOfferOnCreateRouDiSide.tryGetCaProMessage(); EXPECT_FALSE(maybeCaproMessage.has_value()); } + TEST_F(PublisherPort_test, offerCallResultsInOfferedState) { - m_sutUserSide.offer(); + m_sutNoOfferOnCreateUserSide.offer(); - EXPECT_TRUE(m_sutUserSide.isOffered()); + EXPECT_TRUE(m_sutNoOfferOnCreateUserSide.isOffered()); } TEST_F(PublisherPort_test, offerCallResultsInOfferCaProMessage) { - m_sutUserSide.offer(); + m_sutNoOfferOnCreateUserSide.offer(); - auto maybeCaproMessage = m_sutRouDiSide.tryGetCaProMessage(); + auto maybeCaproMessage = m_sutNoOfferOnCreateRouDiSide.tryGetCaProMessage(); EXPECT_TRUE(maybeCaproMessage.has_value()); auto caproMessage = maybeCaproMessage.value(); @@ -128,22 +151,22 @@ TEST_F(PublisherPort_test, offerCallResultsInOfferCaProMessage) TEST_F(PublisherPort_test, stopOfferCallResultsInNotOfferedState) { - m_sutUserSide.offer(); + m_sutNoOfferOnCreateUserSide.offer(); - m_sutUserSide.stopOffer(); + m_sutNoOfferOnCreateUserSide.stopOffer(); - EXPECT_FALSE(m_sutUserSide.isOffered()); + EXPECT_FALSE(m_sutNoOfferOnCreateUserSide.isOffered()); } TEST_F(PublisherPort_test, stopOfferCallResultsInStopOfferCaProMessage) { // arrange, we need a transition from offer to stop offer, also form a RouDi point of view // therefore we must also get the offer CapPro message (but ignore it here) - m_sutUserSide.offer(); - m_sutRouDiSide.tryGetCaProMessage(); - m_sutUserSide.stopOffer(); + m_sutNoOfferOnCreateUserSide.offer(); + m_sutNoOfferOnCreateRouDiSide.tryGetCaProMessage(); + m_sutNoOfferOnCreateUserSide.stopOffer(); - auto maybeCaproMessage = m_sutRouDiSide.tryGetCaProMessage(); + auto maybeCaproMessage = m_sutNoOfferOnCreateRouDiSide.tryGetCaProMessage(); EXPECT_TRUE(maybeCaproMessage.has_value()); auto caproMessage = maybeCaproMessage.value(); @@ -153,10 +176,10 @@ TEST_F(PublisherPort_test, stopOfferCallResultsInStopOfferCaProMessage) TEST_F(PublisherPort_test, offerStateChangesThatEndUpInTheSameStateDoNotReturnACaProMessage) { - m_sutUserSide.offer(); - m_sutUserSide.stopOffer(); + m_sutNoOfferOnCreateUserSide.offer(); + m_sutNoOfferOnCreateUserSide.stopOffer(); - auto maybeCaproMessage = m_sutRouDiSide.tryGetCaProMessage(); + auto maybeCaproMessage = m_sutNoOfferOnCreateRouDiSide.tryGetCaProMessage(); EXPECT_FALSE(maybeCaproMessage.has_value()); } @@ -164,7 +187,7 @@ TEST_F(PublisherPort_test, offerStateChangesThatEndUpInTheSameStateDoNotReturnAC TEST_F(PublisherPort_test, offerCallWhenHavingHistoryResultsInOfferCaProMessageWithSubTypeFieldAndCorrectHistoryCapacity) { - m_sutWithHistoryUseriSide.offer(); + m_sutWithHistoryUserSide.offer(); auto maybeCaproMessage = m_sutWithHistoryRouDiSide.tryGetCaProMessage(); EXPECT_TRUE(maybeCaproMessage.has_value()); @@ -177,7 +200,7 @@ TEST_F(PublisherPort_test, TEST_F(PublisherPort_test, allocatingAChunk) { - auto maybeChunkHeader = m_sutUserSide.tryAllocateChunk(10u); + auto maybeChunkHeader = m_sutNoOfferOnCreateUserSide.tryAllocateChunk(10u); EXPECT_FALSE(maybeChunkHeader.has_error()); EXPECT_THAT(m_memoryManager.getMemPoolInfo(0).m_usedChunks, Eq(1u)); @@ -185,10 +208,10 @@ TEST_F(PublisherPort_test, allocatingAChunk) TEST_F(PublisherPort_test, releasingAnAllocatedChunkReleasesTheMemory) { - auto maybeChunkHeader = m_sutUserSide.tryAllocateChunk(10u); + auto maybeChunkHeader = m_sutNoOfferOnCreateUserSide.tryAllocateChunk(10u); auto chunkHeader = maybeChunkHeader.value(); - m_sutUserSide.releaseChunk(chunkHeader); + m_sutNoOfferOnCreateUserSide.releaseChunk(chunkHeader); // this one is not stored in the last chunk, so all chunks must be free again EXPECT_THAT(m_memoryManager.getMemPoolInfo(0).m_usedChunks, Eq(0u)); @@ -196,19 +219,19 @@ TEST_F(PublisherPort_test, releasingAnAllocatedChunkReleasesTheMemory) TEST_F(PublisherPort_test, allocatedChunkContainsPublisherIdAsOriginId) { - auto maybeChunkHeader = m_sutUserSide.tryAllocateChunk(10u); + auto maybeChunkHeader = m_sutNoOfferOnCreateUserSide.tryAllocateChunk(10u); auto chunkHeader = maybeChunkHeader.value(); - EXPECT_THAT(chunkHeader->originId, Eq(m_sutUserSide.getUniqueID())); - m_sutUserSide.releaseChunk(chunkHeader); + EXPECT_THAT(chunkHeader->originId, Eq(m_sutNoOfferOnCreateUserSide.getUniqueID())); + m_sutNoOfferOnCreateUserSide.releaseChunk(chunkHeader); } TEST_F(PublisherPort_test, allocateAndSendAChunkWithoutSubscriberHoldsTheLast) { - auto maybeChunkHeader = m_sutUserSide.tryAllocateChunk(10u); + auto maybeChunkHeader = m_sutNoOfferOnCreateUserSide.tryAllocateChunk(10u); auto chunkHeader = maybeChunkHeader.value(); - m_sutUserSide.sendChunk(chunkHeader); + m_sutNoOfferOnCreateUserSide.sendChunk(chunkHeader); // this one is stored in the last chunk, so this chunk is still in use EXPECT_THAT(m_memoryManager.getMemPoolInfo(0).m_usedChunks, Eq(1u)); @@ -216,15 +239,15 @@ TEST_F(PublisherPort_test, allocateAndSendAChunkWithoutSubscriberHoldsTheLast) TEST_F(PublisherPort_test, allocateAndSendMultipleChunksWithoutSubscriberHoldsOnlyTheLast) { - auto maybeChunkHeader = m_sutUserSide.tryAllocateChunk(10u); + auto maybeChunkHeader = m_sutNoOfferOnCreateUserSide.tryAllocateChunk(10u); auto chunkHeader = maybeChunkHeader.value(); - m_sutUserSide.sendChunk(chunkHeader); - maybeChunkHeader = m_sutUserSide.tryAllocateChunk(10u); + m_sutNoOfferOnCreateUserSide.sendChunk(chunkHeader); + maybeChunkHeader = m_sutNoOfferOnCreateUserSide.tryAllocateChunk(10u); chunkHeader = maybeChunkHeader.value(); - m_sutUserSide.sendChunk(chunkHeader); - maybeChunkHeader = m_sutUserSide.tryAllocateChunk(10u); + m_sutNoOfferOnCreateUserSide.sendChunk(chunkHeader); + maybeChunkHeader = m_sutNoOfferOnCreateUserSide.tryAllocateChunk(10u); chunkHeader = maybeChunkHeader.value(); - m_sutUserSide.sendChunk(chunkHeader); + m_sutNoOfferOnCreateUserSide.sendChunk(chunkHeader); // the last is stored in the last chunk, so one chunk is still in use EXPECT_THAT(m_memoryManager.getMemPoolInfo(0).m_usedChunks, Eq(1u)); @@ -238,7 +261,7 @@ TEST_F(PublisherPort_test, subscribeWhenNotOfferedReturnsNACK) caproMessage.m_chunkQueueData = &m_chunkQueueData; caproMessage.m_historyCapacity = 0u; - auto maybeCaProMessage = m_sutRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); + auto maybeCaProMessage = m_sutNoOfferOnCreateRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); EXPECT_TRUE(maybeCaProMessage.has_value()); auto caproMessageResponse = maybeCaProMessage.value(); @@ -247,15 +270,15 @@ TEST_F(PublisherPort_test, subscribeWhenNotOfferedReturnsNACK) TEST_F(PublisherPort_test, unsubscribeWhenNotSubscribedReturnsNACK) { - m_sutUserSide.offer(); - m_sutRouDiSide.tryGetCaProMessage(); + m_sutNoOfferOnCreateUserSide.offer(); + m_sutNoOfferOnCreateRouDiSide.tryGetCaProMessage(); ChunkQueueData_t m_chunkQueueData{iox::cxx::VariantQueueTypes::SoFi_SingleProducerSingleConsumer}; iox::capro::CaproMessage caproMessage(iox::capro::CaproMessageType::UNSUB, iox::capro::ServiceDescription("a", "b", "c")); caproMessage.m_chunkQueueData = &m_chunkQueueData; caproMessage.m_historyCapacity = 0u; - auto maybeCaproMessage = m_sutRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); + auto maybeCaproMessage = m_sutNoOfferOnCreateRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); EXPECT_TRUE(maybeCaproMessage.has_value()); auto caproMessageResponse = maybeCaproMessage.value(); @@ -264,47 +287,47 @@ TEST_F(PublisherPort_test, unsubscribeWhenNotSubscribedReturnsNACK) TEST_F(PublisherPort_test, subscribeWhenOfferedReturnsACKAndWeHaveSubscribers) { - m_sutUserSide.offer(); - m_sutRouDiSide.tryGetCaProMessage(); + m_sutNoOfferOnCreateUserSide.offer(); + m_sutNoOfferOnCreateRouDiSide.tryGetCaProMessage(); ChunkQueueData_t m_chunkQueueData{iox::cxx::VariantQueueTypes::SoFi_SingleProducerSingleConsumer}; iox::capro::CaproMessage caproMessage(iox::capro::CaproMessageType::SUB, iox::capro::ServiceDescription("a", "b", "c")); caproMessage.m_chunkQueueData = &m_chunkQueueData; caproMessage.m_historyCapacity = 0u; - auto maybeCaProMessage = m_sutRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); + auto maybeCaProMessage = m_sutNoOfferOnCreateRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); EXPECT_TRUE(maybeCaProMessage.has_value()); auto caproMessageResponse = maybeCaProMessage.value(); EXPECT_THAT(caproMessageResponse.m_type, Eq(iox::capro::CaproMessageType::ACK)); - EXPECT_TRUE(m_sutUserSide.hasSubscribers()); + EXPECT_TRUE(m_sutNoOfferOnCreateUserSide.hasSubscribers()); } TEST_F(PublisherPort_test, unsubscribeWhenSubscribedReturnsACKAndWeHaveNoMoreSubscribers) { - m_sutUserSide.offer(); - m_sutRouDiSide.tryGetCaProMessage(); + m_sutNoOfferOnCreateUserSide.offer(); + m_sutNoOfferOnCreateRouDiSide.tryGetCaProMessage(); ChunkQueueData_t m_chunkQueueData{iox::cxx::VariantQueueTypes::SoFi_SingleProducerSingleConsumer}; iox::capro::CaproMessage caproMessage(iox::capro::CaproMessageType::SUB, iox::capro::ServiceDescription("a", "b", "c")); caproMessage.m_chunkQueueData = &m_chunkQueueData; caproMessage.m_historyCapacity = 0u; - auto maybeCaProMessage = m_sutRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); + auto maybeCaProMessage = m_sutNoOfferOnCreateRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); // set CaPro message to UNSUB, the other members are reused caproMessage.m_type = iox::capro::CaproMessageType::UNSUB; - maybeCaProMessage = m_sutRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); + maybeCaProMessage = m_sutNoOfferOnCreateRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); EXPECT_TRUE(maybeCaProMessage.has_value()); auto caproMessageResponse = maybeCaProMessage.value(); EXPECT_THAT(caproMessageResponse.m_type, Eq(iox::capro::CaproMessageType::ACK)); - EXPECT_FALSE(m_sutUserSide.hasSubscribers()); + EXPECT_FALSE(m_sutNoOfferOnCreateUserSide.hasSubscribers()); } TEST_F(PublisherPort_test, subscribeManyIsFine) { - m_sutUserSide.offer(); - m_sutRouDiSide.tryGetCaProMessage(); + m_sutNoOfferOnCreateUserSide.offer(); + m_sutNoOfferOnCreateRouDiSide.tryGetCaProMessage(); // using dummy pointers for the provided chunk queue data uint64_t dummy; uint64_t* dummyPtr = &dummy; @@ -316,7 +339,7 @@ TEST_F(PublisherPort_test, subscribeManyIsFine) for (size_t i = 0; i < iox::MAX_SUBSCRIBERS_PER_PUBLISHER; i++) { - auto maybeCaProMessage = m_sutRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); + auto maybeCaProMessage = m_sutNoOfferOnCreateRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); EXPECT_TRUE(maybeCaProMessage.has_value()); auto caproMessageResponse = maybeCaProMessage.value(); EXPECT_THAT(caproMessageResponse.m_type, Eq(iox::capro::CaproMessageType::ACK)); @@ -327,8 +350,8 @@ TEST_F(PublisherPort_test, subscribeManyIsFine) TEST_F(PublisherPort_test, subscribeTillOverflowReturnsNACK) { - m_sutUserSide.offer(); - m_sutRouDiSide.tryGetCaProMessage(); + m_sutNoOfferOnCreateUserSide.offer(); + m_sutNoOfferOnCreateRouDiSide.tryGetCaProMessage(); // using dummy pointers for the provided chunk queue data uint64_t dummy; uint64_t* dummyPtr = &dummy; @@ -339,12 +362,12 @@ TEST_F(PublisherPort_test, subscribeTillOverflowReturnsNACK) caproMessage.m_historyCapacity = 0u; for (size_t i = 0; i < iox::MAX_SUBSCRIBERS_PER_PUBLISHER; i++) { - m_sutRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); + m_sutNoOfferOnCreateRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); dummyPtr++; caproMessage.m_chunkQueueData = reinterpret_cast(dummyPtr); } - auto maybeCaProMessage = m_sutRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); + auto maybeCaProMessage = m_sutNoOfferOnCreateRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); EXPECT_TRUE(maybeCaProMessage.has_value()); auto caproMessageResponse = maybeCaProMessage.value(); @@ -353,20 +376,20 @@ TEST_F(PublisherPort_test, subscribeTillOverflowReturnsNACK) TEST_F(PublisherPort_test, sendWhenSubscribedDeliversAChunk) { - m_sutUserSide.offer(); - m_sutRouDiSide.tryGetCaProMessage(); + m_sutNoOfferOnCreateUserSide.offer(); + m_sutNoOfferOnCreateRouDiSide.tryGetCaProMessage(); ChunkQueueData_t m_chunkQueueData{iox::cxx::VariantQueueTypes::SoFi_SingleProducerSingleConsumer}; iox::capro::CaproMessage caproMessage(iox::capro::CaproMessageType::SUB, iox::capro::ServiceDescription("a", "b", "c")); caproMessage.m_chunkQueueData = &m_chunkQueueData; caproMessage.m_historyCapacity = 0u; - m_sutRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); - auto maybeChunkHeader = m_sutUserSide.tryAllocateChunk(sizeof(DummySample)); + m_sutNoOfferOnCreateRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); + auto maybeChunkHeader = m_sutNoOfferOnCreateUserSide.tryAllocateChunk(sizeof(DummySample)); auto chunkHeader = maybeChunkHeader.value(); auto sample = chunkHeader->payload(); new (sample) DummySample(); static_cast(sample)->dummy = 17; - m_sutUserSide.sendChunk(chunkHeader); + m_sutNoOfferOnCreateUserSide.sendChunk(chunkHeader); iox::popo::ChunkQueuePopper m_chunkQueuePopper(&m_chunkQueueData); auto maybeSharedChunk = m_chunkQueuePopper.tryPop(); @@ -416,19 +439,19 @@ TEST_F(PublisherPort_test, subscribeWithHistoryLikeTheARAField) TEST_F(PublisherPort_test, noLastChunkWhenNothingSent) { - auto maybeLastChunkHeader = m_sutUserSide.tryGetPreviousChunk(); + auto maybeLastChunkHeader = m_sutNoOfferOnCreateUserSide.tryGetPreviousChunk(); EXPECT_FALSE(maybeLastChunkHeader.has_value()); } TEST_F(PublisherPort_test, lastChunkAvailableAfterSend) { - auto maybeChunkHeader = m_sutUserSide.tryAllocateChunk(10u); + auto maybeChunkHeader = m_sutNoOfferOnCreateUserSide.tryAllocateChunk(10u); auto chunkHeader = maybeChunkHeader.value(); auto firstPayloadPtr = chunkHeader->payload(); - m_sutUserSide.sendChunk(chunkHeader); + m_sutNoOfferOnCreateUserSide.sendChunk(chunkHeader); - auto maybeLastChunkHeader = m_sutUserSide.tryGetPreviousChunk(); + auto maybeLastChunkHeader = m_sutNoOfferOnCreateUserSide.tryGetPreviousChunk(); EXPECT_TRUE(maybeLastChunkHeader.has_value()); EXPECT_THAT(maybeLastChunkHeader.value()->payload(), Eq(firstPayloadPtr)); @@ -439,14 +462,14 @@ TEST_F(PublisherPort_test, cleanupReleasesAllChunks) // push some chunks to history for (size_t i = 0; i < iox::MAX_PUBLISHER_HISTORY; i++) { - auto maybeChunkHeader = m_sutWithHistoryUseriSide.tryAllocateChunk(sizeof(DummySample)); + auto maybeChunkHeader = m_sutWithHistoryUserSide.tryAllocateChunk(sizeof(DummySample)); auto chunkHeader = maybeChunkHeader.value(); - m_sutWithHistoryUseriSide.sendChunk(chunkHeader); + m_sutWithHistoryUserSide.sendChunk(chunkHeader); } // allocate some samples - auto maybeChunkHeader1 = m_sutWithHistoryUseriSide.tryAllocateChunk(sizeof(DummySample)); - auto maybeChunkHeader2 = m_sutWithHistoryUseriSide.tryAllocateChunk(sizeof(DummySample)); - auto maybeChunkHeader3 = m_sutWithHistoryUseriSide.tryAllocateChunk(sizeof(DummySample)); + auto maybeChunkHeader1 = m_sutWithHistoryUserSide.tryAllocateChunk(sizeof(DummySample)); + auto maybeChunkHeader2 = m_sutWithHistoryUserSide.tryAllocateChunk(sizeof(DummySample)); + auto maybeChunkHeader3 = m_sutWithHistoryUserSide.tryAllocateChunk(sizeof(DummySample)); m_sutWithHistoryRouDiSide.releaseAllChunks(); diff --git a/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp b/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp index 26642a5a606..f7650d7dd05 100644 --- a/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp @@ -57,13 +57,24 @@ class SubscriberPortSingleProducer_test : public Test iox::cxx::GenericRAII m_uniqueRouDiId{[] { iox::popo::internal::setUniqueRouDiId(0); }, [] { iox::popo::internal::unsetUniqueRouDiId(); }}; + + iox::popo::SubscriberOptions m_noSubscribeOnCreateOptions {iox::popo::SubscriberPortData::ChunkQueueData_t::MAX_CAPACITY, 0U, "", false}; iox::popo::SubscriberPortData m_subscriberPortDataSingleProducer{ TEST_SERVICE_DESCRIPTION, "myApp", iox::cxx::VariantQueueTypes::SoFi_SingleProducerSingleConsumer, - iox::popo::SubscriberOptions()}; + m_noSubscribeOnCreateOptions}; iox::popo::SubscriberPortUser m_sutUserSideSingleProducer{&m_subscriberPortDataSingleProducer}; iox::popo::SubscriberPortSingleProducer m_sutRouDiSideSingleProducer{&m_subscriberPortDataSingleProducer}; + + iox::popo::SubscriberOptions m_defaultSubscriberOptions{}; + iox::popo::SubscriberPortData m_subscriberPortDataDefaultOptions{ + TEST_SERVICE_DESCRIPTION, + "myApp", + iox::cxx::VariantQueueTypes::SoFi_SingleProducerSingleConsumer, + m_defaultSubscriberOptions}; + iox::popo::SubscriberPortUser m_sutUserSideDefaultOptions{&m_subscriberPortDataDefaultOptions}; + iox::popo::SubscriberPortSingleProducer m_sutRouDiSideDefaultOptions{&m_subscriberPortDataDefaultOptions}; }; const iox::capro::ServiceDescription SubscriberPortSingleProducer_test::TEST_SERVICE_DESCRIPTION("x", "y", "z"); @@ -87,13 +98,22 @@ TEST_F(SubscriberPortSingleProducer_test, initialStateNoChunksLost) EXPECT_FALSE(m_sutUserSideSingleProducer.hasLostChunksSinceLastCall()); } -TEST_F(SubscriberPortSingleProducer_test, initialStateReturnsNoCaProMessage) +TEST_F(SubscriberPortSingleProducer_test, initialStateReturnsNoCaProMessageWhenNoSubOnCreate) { auto maybeCaproMessage = m_sutRouDiSideSingleProducer.tryGetCaProMessage(); EXPECT_FALSE(maybeCaproMessage.has_value()); } +TEST_F(SubscriberPortSingleProducer_test, initialStateReturnsSubCaProMessageWithDefaultOptions) +{ + auto maybeCaproMessage = m_sutRouDiSideDefaultOptions.tryGetCaProMessage(); + + EXPECT_TRUE(maybeCaproMessage.has_value()); + auto caproMessage = maybeCaproMessage.value(); + EXPECT_THAT(caproMessage.m_type, Eq(iox::capro::CaproMessageType::SUB)); +} + TEST_F(SubscriberPortSingleProducer_test, subscribeCallResultsInSubCaProMessage) { m_sutUserSideSingleProducer.subscribe(); @@ -360,11 +380,13 @@ TEST_F(SubscriberPortMultiProducer_test, initialStateNotSubscribed) EXPECT_THAT(m_sutUserSideMultiProducer.getSubscriptionState(), Eq(iox::SubscribeState::NOT_SUBSCRIBED)); } -TEST_F(SubscriberPortMultiProducer_test, initialStateReturnsNoCaProMessage) +TEST_F(SubscriberPortMultiProducer_test, initialStateReturnsSubCaProMessageWithDefaultOptions) { auto maybeCaproMessage = m_sutRouDiSideMultiProducer.tryGetCaProMessage(); - EXPECT_FALSE(maybeCaproMessage.has_value()); + EXPECT_TRUE(maybeCaproMessage.has_value()); + auto caproMessage = maybeCaproMessage.value(); + EXPECT_THAT(caproMessage.m_type, Eq(iox::capro::CaproMessageType::SUB)); } TEST_F(SubscriberPortMultiProducer_test, subscribeCallResultsInSubCaProMessage) From 0fc9530fc17759cb89ffa5482d6dfcfcac41fb31 Mon Sep 17 00:00:00 2001 From: Michael Poehnl Date: Sun, 28 Feb 2021 00:21:05 +0100 Subject: [PATCH 111/143] iox-#408 update of port manager Signed-off-by: Michael Poehnl --- .../test/moduletests/test_publisher.cpp | 4 +- .../internal/roudi/port_manager.hpp | 12 +- iceoryx_posh/source/roudi/port_manager.cpp | 113 ++++++++++-------- .../moduletests/test_roudi_portmanager.cpp | 94 +++++++++++++-- 4 files changed, 160 insertions(+), 63 deletions(-) diff --git a/iceoryx_binding_c/test/moduletests/test_publisher.cpp b/iceoryx_binding_c/test/moduletests/test_publisher.cpp index 574a0748b24..349a367ce44 100644 --- a/iceoryx_binding_c/test/moduletests/test_publisher.cpp +++ b/iceoryx_binding_c/test/moduletests/test_publisher.cpp @@ -116,9 +116,9 @@ class iox_pub_test : public Test cpp2c_Publisher m_sut; }; -TEST_F(iox_pub_test, initialStateIsNotOffered) +TEST_F(iox_pub_test, initialStateIsOffered) { - EXPECT_FALSE(iox_pub_is_offered(&m_sut)); + EXPECT_TRUE(iox_pub_is_offered(&m_sut)); } TEST_F(iox_pub_test, is_offeredAfterOffer) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp b/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp index 57ab23e799e..1fd159f6cdc 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp @@ -91,18 +91,22 @@ class PortManager void deletePortsOfProcess(const ProcessName_t& processName) noexcept; - void destroyPublisherPort(PublisherPortRouDiType::MemberType_t* const publisherPortData) noexcept; - - void destroySubscriberPort(SubscriberPortType::MemberType_t* const subscriberPortData) noexcept; - const std::atomic* serviceRegistryChangeCounter() noexcept; runtime::IpcMessage findService(const capro::ServiceDescription& service) noexcept; protected: + void destroyPublisherPort(PublisherPortRouDiType::MemberType_t* const publisherPortData) noexcept; + + void destroySubscriberPort(SubscriberPortType::MemberType_t* const subscriberPortData) noexcept; + void handlePublisherPorts() noexcept; + void doDiscoveryForPublisherPort(PublisherPortRouDiType& publisherPort) noexcept; + void handleSubscriberPorts() noexcept; + void doDiscoveryForSubscriberPort(SubscriberPortType& subscriberPort) noexcept; + void handleInterfaces() noexcept; void handleApplications() noexcept; diff --git a/iceoryx_posh/source/roudi/port_manager.cpp b/iceoryx_posh/source/roudi/port_manager.cpp index 16a6b6bdb0f..873f2b83419 100644 --- a/iceoryx_posh/source/roudi/port_manager.cpp +++ b/iceoryx_posh/source/roudi/port_manager.cpp @@ -138,30 +138,7 @@ void PortManager::handlePublisherPorts() noexcept { PublisherPortRouDiType publisherPort(publisherPortData); - publisherPort.tryGetCaProMessage().and_then([this, &publisherPort](auto caproMessage) { - m_portIntrospection.reportMessage(caproMessage); - if (capro::CaproMessageType::OFFER == caproMessage.m_type) - { - this->addEntryToServiceRegistry(caproMessage.m_serviceDescription.getServiceIDString(), - caproMessage.m_serviceDescription.getInstanceIDString()); - } - else if (capro::CaproMessageType::STOP_OFFER == caproMessage.m_type) - { - this->removeEntryFromServiceRegistry(caproMessage.m_serviceDescription.getServiceIDString(), - caproMessage.m_serviceDescription.getInstanceIDString()); - } - else - { - // protocol error - errorHandler(Error::kPORT_MANAGER__HANDLE_PUBLISHER_PORTS_INVALID_CAPRO_MESSAGE, - nullptr, - iox::ErrorLevel::MODERATE); - } - - this->sendToAllMatchingSubscriberPorts(caproMessage, publisherPort); - // forward to interfaces - this->sendToAllMatchingInterfacePorts(caproMessage); - }); + doDiscoveryForPublisherPort(publisherPort); // check if we have to destroy this publisher port if (publisherPort.toBeDestroyed()) @@ -171,6 +148,34 @@ void PortManager::handlePublisherPorts() noexcept } } +void PortManager::doDiscoveryForPublisherPort(PublisherPortRouDiType& publisherPort) noexcept +{ + publisherPort.tryGetCaProMessage().and_then([this, &publisherPort](auto caproMessage) { + m_portIntrospection.reportMessage(caproMessage); + if (capro::CaproMessageType::OFFER == caproMessage.m_type) + { + this->addEntryToServiceRegistry(caproMessage.m_serviceDescription.getServiceIDString(), + caproMessage.m_serviceDescription.getInstanceIDString()); + } + else if (capro::CaproMessageType::STOP_OFFER == caproMessage.m_type) + { + this->removeEntryFromServiceRegistry(caproMessage.m_serviceDescription.getServiceIDString(), + caproMessage.m_serviceDescription.getInstanceIDString()); + } + else + { + // protocol error + errorHandler(Error::kPORT_MANAGER__HANDLE_PUBLISHER_PORTS_INVALID_CAPRO_MESSAGE, + nullptr, + iox::ErrorLevel::MODERATE); + } + + this->sendToAllMatchingSubscriberPorts(caproMessage, publisherPort); + // forward to interfaces + this->sendToAllMatchingInterfacePorts(caproMessage); + }); +} + void PortManager::handleSubscriberPorts() noexcept { // get requests for change of subscription state of subscribers @@ -178,29 +183,7 @@ void PortManager::handleSubscriberPorts() noexcept { SubscriberPortType subscriberPort(subscriberPortData); - subscriberPort.tryGetCaProMessage().and_then([this, &subscriberPort](auto caproMessage) { - if ((capro::CaproMessageType::SUB == caproMessage.m_type) - || (capro::CaproMessageType::UNSUB == caproMessage.m_type)) - { - m_portIntrospection.reportMessage(caproMessage, subscriberPort.getUniqueID()); - if (!this->sendToAllMatchingPublisherPorts(caproMessage, subscriberPort)) - { - LogDebug() << "capro::SUB/UNSUB, no matching publisher!!"; - capro::CaproMessage nackMessage(capro::CaproMessageType::NACK, - subscriberPort.getCaProServiceDescription()); - auto returnMessage = subscriberPort.dispatchCaProMessageAndGetPossibleResponse(nackMessage); - // No response on NACK messages - cxx::Ensures(!returnMessage.has_value()); - } - } - else - { - // protocol error - errorHandler(Error::kPORT_MANAGER__HANDLE_SUBSCRIBER_PORTS_INVALID_CAPRO_MESSAGE, - nullptr, - iox::ErrorLevel::MODERATE); - } - }); + doDiscoveryForSubscriberPort(subscriberPort); // check if we have to destroy this subscriber port if (subscriberPort.toBeDestroyed()) @@ -210,6 +193,34 @@ void PortManager::handleSubscriberPorts() noexcept } } +void PortManager::doDiscoveryForSubscriberPort(SubscriberPortType& subscriberPort) noexcept +{ + subscriberPort.tryGetCaProMessage().and_then([this, &subscriberPort](auto caproMessage) { + if ((capro::CaproMessageType::SUB == caproMessage.m_type) + || (capro::CaproMessageType::UNSUB == caproMessage.m_type)) + { + m_portIntrospection.reportMessage(caproMessage, subscriberPort.getUniqueID()); + if (!this->sendToAllMatchingPublisherPorts(caproMessage, subscriberPort)) + { + LogDebug() << "capro::SUB/UNSUB, no matching publisher!!"; + capro::CaproMessage nackMessage(capro::CaproMessageType::NACK, + subscriberPort.getCaProServiceDescription()); + auto returnMessage = subscriberPort.dispatchCaProMessageAndGetPossibleResponse(nackMessage); + // No response on NACK messages + cxx::Ensures(!returnMessage.has_value()); + } + } + else + { + // protocol error + errorHandler(Error::kPORT_MANAGER__HANDLE_SUBSCRIBER_PORTS_INVALID_CAPRO_MESSAGE, + nullptr, + iox::ErrorLevel::MODERATE); + } + }); +} + + void PortManager::handleInterfaces() noexcept { // check if there are new interfaces that must get an initial offer information @@ -600,6 +611,10 @@ PortManager::acquirePublisherPortData(const capro::ServiceDescription& service, if (publisherPortData) { m_portIntrospection.addPublisher(*publisherPortData); + + // we do discovery here for trying to connect the waiting subscribers if offer on create is desired + PublisherPortRouDiType publisherPort(publisherPortData); + doDiscoveryForPublisherPort(publisherPort); } } @@ -620,6 +635,10 @@ PortManager::acquireSubscriberPortData(const capro::ServiceDescription& service, if (subscriberPortData) { m_portIntrospection.addSubscriber(*subscriberPortData); + + // we do discovery here for trying to connect with publishers if subscribe on create is desired + SubscriberPortType subscriberPort(subscriberPortData); + doDiscoveryForSubscriberPort(subscriberPort); } } diff --git a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp index 40420e297fe..cb49debd640 100644 --- a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp +++ b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp @@ -209,8 +209,8 @@ void setDestroyFlagAndClearContainer(vector& container) TEST_F(PortManager_test, doDiscovery_singleShotPublisherFirst) { - PublisherOptions publisherOptions{1, "node"}; - SubscriberOptions subscriberOptions{1, 1, "node"}; + PublisherOptions publisherOptions{1, "node", false}; + SubscriberOptions subscriberOptions{1, 1, "node", false}; PublisherPortUser publisher( m_portManager @@ -234,8 +234,8 @@ TEST_F(PortManager_test, doDiscovery_singleShotPublisherFirst) TEST_F(PortManager_test, doDiscovery_singleShotSubscriberFirst) { - PublisherOptions publisherOptions{1, "node"}; - SubscriberOptions subscriberOptions{1, 1, "node"}; + PublisherOptions publisherOptions{1, "node", false}; + SubscriberOptions subscriberOptions{1, 1, "node", false}; SubscriberPortUser subscriber( m_portManager->acquireSubscriberPortData({1, 1, 1}, subscriberOptions, "schlomo", PortConfigInfo()).value()); @@ -259,8 +259,8 @@ TEST_F(PortManager_test, doDiscovery_singleShotSubscriberFirst) TEST_F(PortManager_test, doDiscovery_singleShotSubscriberFirstWithDiscovery) { - PublisherOptions publisherOptions{1, "node"}; - SubscriberOptions subscriberOptions{1, 1, "node"}; + PublisherOptions publisherOptions{1, "node", false}; + SubscriberOptions subscriberOptions{1, 1, "node", false}; SubscriberPortUser subscriber( m_portManager->acquireSubscriberPortData({1, 1, 1}, subscriberOptions, "schlomo", PortConfigInfo()).value()); @@ -284,8 +284,8 @@ TEST_F(PortManager_test, doDiscovery_singleShotSubscriberFirstWithDiscovery) TEST_F(PortManager_test, doDiscovery_rightOrdering) { - PublisherOptions publisherOptions{1, "node"}; - SubscriberOptions subscriberOptions{1, 1, "node"}; + PublisherOptions publisherOptions{1, "node", false}; + SubscriberOptions subscriberOptions{1, 1, "node", false}; SubscriberPortUser subscriber1( m_portManager->acquireSubscriberPortData({1, 1, 1}, subscriberOptions, "schlomo", PortConfigInfo()).value()); @@ -314,6 +314,80 @@ TEST_F(PortManager_test, doDiscovery_rightOrdering) EXPECT_THAT(subscriber2.getSubscriptionState(), Eq(iox::SubscribeState::SUBSCRIBED)); } +TEST_F(PortManager_test, subscribeOnCreate_subscribesWithoutDiscoveryLoopWhenPublisherAvailable) +{ + PublisherOptions publisherOptions{1, "node", false}; + SubscriberOptions subscriberOptions{1, 1, "node", true}; + PublisherPortUser publisher( + m_portManager + ->acquirePublisherPortData( + {1, 1, 1}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) + .value()); + publisher.offer(); + m_portManager->doDiscovery(); + + SubscriberPortUser subscriber( + m_portManager->acquireSubscriberPortData({1, 1, 1}, subscriberOptions, "schlomo", PortConfigInfo()).value()); + + ASSERT_TRUE(publisher.hasSubscribers()); + EXPECT_THAT(subscriber.getSubscriptionState(), Eq(iox::SubscribeState::SUBSCRIBED)); +} + +TEST_F(PortManager_test, offerOnCreate_subscribesWithoutDiscoveryLoopWhenSubscriberAvailable) +{ + PublisherOptions publisherOptions{1, "node", true}; + SubscriberOptions subscriberOptions{1, 1, "node", false}; + SubscriberPortUser subscriber( + m_portManager->acquireSubscriberPortData({1, 1, 1}, subscriberOptions, "schlomo", PortConfigInfo()).value()); + subscriber.subscribe(); + m_portManager->doDiscovery(); + + PublisherPortUser publisher( + m_portManager + ->acquirePublisherPortData( + {1, 1, 1}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) + .value()); + + ASSERT_TRUE(publisher.hasSubscribers()); + EXPECT_THAT(subscriber.getSubscriptionState(), Eq(iox::SubscribeState::SUBSCRIBED)); +} + +TEST_F(PortManager_test, offerOnCreateAndSubscribeOnCreate_needsNoMoreDiscoveryLoopSubscriberFirst) +{ + PublisherOptions publisherOptions{1, "node", true}; + SubscriberOptions subscriberOptions{1, 1, "node", true}; + SubscriberPortUser subscriber( + m_portManager->acquireSubscriberPortData({1, 1, 1}, subscriberOptions, "schlomo", PortConfigInfo()).value()); + + PublisherPortUser publisher( + m_portManager + ->acquirePublisherPortData( + {1, 1, 1}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) + .value()); + + ASSERT_TRUE(publisher.hasSubscribers()); + EXPECT_THAT(subscriber.getSubscriptionState(), Eq(iox::SubscribeState::SUBSCRIBED)); +} + +TEST_F(PortManager_test, offerOnCreateAndSubscribeOnCreate_needsNoMoreDiscoveryLoopPublisherFirst) +{ + PublisherOptions publisherOptions{1, "node", true}; + SubscriberOptions subscriberOptions{1, 1, "node", true}; + PublisherPortUser publisher( + m_portManager + ->acquirePublisherPortData( + {1, 1, 1}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) + .value()); + + SubscriberPortUser subscriber( + m_portManager->acquireSubscriberPortData({1, 1, 1}, subscriberOptions, "schlomo", PortConfigInfo()).value()); + + + ASSERT_TRUE(publisher.hasSubscribers()); + EXPECT_THAT(subscriber.getSubscriptionState(), Eq(iox::SubscribeState::SUBSCRIBED)); +} + + TEST_F(PortManager_test, AcquiringOneMoreThanMaximumNumberOfPublishersFails) { iox::ProcessName_t processName = "test1"; @@ -623,8 +697,8 @@ TEST_F(PortManager_test, PortsDestroyInProcess2ChangeStatesOfPortsInProcess1) iox::ProcessName_t processName2 = "myProcess2"; iox::capro::ServiceDescription cap1(1, 1, 1); iox::capro::ServiceDescription cap2(2, 2, 2); - PublisherOptions publisherOptions{1, "node"}; - SubscriberOptions subscriberOptions{1, 1, "node"}; + PublisherOptions publisherOptions{1, "node", false}; + SubscriberOptions subscriberOptions{1, 1, "node", false}; // two processes process1 and process2 each with a publisher and subscriber that match to the other process auto publisherData1 = From 0f2324eea64869c98fac926d2faf4f506a76475a Mon Sep 17 00:00:00 2001 From: Michael Poehnl Date: Sun, 28 Feb 2021 00:59:45 +0100 Subject: [PATCH 112/143] iox-#408 adaptation of cpp examples Signed-off-by: Michael Poehnl --- iceoryx_examples/ice_multi_publisher/README.md | 14 ++------------ .../ice_multi_publisher/ice_multi_publisher.cpp | 1 - .../ice_multi_publisher/ice_subscriber.cpp | 3 --- iceoryx_examples/icecrystal/Readme.md | 8 +++----- iceoryx_examples/icedelivery/README.md | 8 +------- iceoryx_examples/icedelivery/iox_publisher.cpp | 1 - .../icedelivery/iox_publisher_untyped.cpp | 1 - .../icedelivery/iox_publisher_with_history.cpp | 3 +++ iceoryx_examples/icedelivery/iox_subscriber.cpp | 3 --- .../icedelivery/iox_subscriber_untyped.cpp | 3 --- .../icedelivery/iox_subscriber_with_history.cpp | 4 ++++ iceoryx_examples/iceperf/iceoryx.cpp | 3 --- iceoryx_examples/singleprocess/README.md | 8 ++------ iceoryx_examples/singleprocess/single_process.cpp | 3 --- iceoryx_examples/waitset/README.md | 12 +++--------- iceoryx_examples/waitset/ice_waitset_gateway.cpp | 1 - iceoryx_examples/waitset/ice_waitset_grouping.cpp | 1 - .../waitset/ice_waitset_individual.cpp | 3 --- iceoryx_examples/waitset/ice_waitset_publisher.cpp | 1 - 19 files changed, 18 insertions(+), 63 deletions(-) diff --git a/iceoryx_examples/ice_multi_publisher/README.md b/iceoryx_examples/ice_multi_publisher/README.md index fd94d411de8..2142b70655c 100644 --- a/iceoryx_examples/ice_multi_publisher/README.md +++ b/iceoryx_examples/ice_multi_publisher/README.md @@ -113,10 +113,8 @@ iox::capro::IdString instance{iox::cxx::TruncateToCapacity, instanceName}; iox::popo::Publisher publisher({"Group", instance, "Counter"}); ``` -After construction, we immediately offer the topic and start sending data. +After construction, we immediately start sending data. ```cpp -publisher.offer(); - for (uint32_t counter = 0U; !killswitch; ++counter) { CounterTopic data{counter, id}; @@ -150,11 +148,6 @@ We create a subscriber via iox::popo::Subscriber subscriber({"Group", "Instance", "Counter"}); ``` -and immediately subscribe. -```cpp -subscriber.subscribe(); -``` - Notice that all identifiers match the ones provided by the two publishers. We periodically wake up @@ -184,10 +177,7 @@ and wait for some time before looking for data again. std::cout << "Waiting for data ... " << std::endl; ``` -When Ctrl+C is pressed we exit the loop and unsubscribe -```cpp -subscriber.unsubscribe(); -``` +When Ctrl+C is pressed we exit the loop before joining the receiver thread ```cpp diff --git a/iceoryx_examples/ice_multi_publisher/ice_multi_publisher.cpp b/iceoryx_examples/ice_multi_publisher/ice_multi_publisher.cpp index cf67da4f979..0322cc427d2 100644 --- a/iceoryx_examples/ice_multi_publisher/ice_multi_publisher.cpp +++ b/iceoryx_examples/ice_multi_publisher/ice_multi_publisher.cpp @@ -42,7 +42,6 @@ void send(uint32_t id, const char* instanceName, std::chrono::milliseconds delay // All three of the string identifiers together uniquely identify a topic // and can also depend on values known only at runtime (like instance in this case). iox::popo::Publisher publisher({"Group", instance, "Counter"}, publisherOptions); - publisher.offer(); for (uint32_t counter = 0U; !killswitch; ++counter) { diff --git a/iceoryx_examples/ice_multi_publisher/ice_subscriber.cpp b/iceoryx_examples/ice_multi_publisher/ice_subscriber.cpp index 9a35260f7d2..35617263f2f 100644 --- a/iceoryx_examples/ice_multi_publisher/ice_subscriber.cpp +++ b/iceoryx_examples/ice_multi_publisher/ice_subscriber.cpp @@ -36,8 +36,6 @@ void receive() iox::popo::Subscriber subscriber({"Group", "Instance", "Counter"}, subscriberOptions); - subscriber.subscribe(); - while (!killswitch) { std::this_thread::sleep_for(std::chrono::seconds(1)); @@ -50,7 +48,6 @@ void receive() }; std::cout << "Waiting for data ... " << std::endl; } - subscriber.unsubscribe(); } int main() diff --git a/iceoryx_examples/icecrystal/Readme.md b/iceoryx_examples/icecrystal/Readme.md index 97a300cfb59..1cfd679d90a 100644 --- a/iceoryx_examples/icecrystal/Readme.md +++ b/iceoryx_examples/icecrystal/Readme.md @@ -51,11 +51,9 @@ The process view will show you the processes (incl. PID), which are currently re --port Subscribe to port introspection data. The port view shows both publisher and subscriber ports that are created by RouDi in the shared memory. Their respective -service description (service, instance, event) is shown to identify them uniquely. The columns `Process` and -`used by process` display to which process the ports belong and how they are currently connected. Size in bytes of -both sample size and chunk size (sample size + meta data) and statistical data of `Chunks [/Minute]` is provided as -well. When a publisher port instantly provides data to a subscriber with the `subscribe()` call, the `Field` column is -ticked. The service discovery protocol allows you to define the `Propagation scope` of the data. This can enable +service description (service, instance, event) is shown to identify them uniquely. The columns `Process` displays to which process the ports. +Size in bytes of both sample size and chunk size (sample size + meta data) and statistical data of `Chunks [/Minute]` is provided as +well. The service discovery protocol allows you to define the `Propagation scope` of the data. This can enable data forwarding to other machines e.g. over network or just consume them internally. When a `Callback` is registered on subscriber side, the box is ticked accordingly. `FiFo size / capacity` shows the consumption of chunks on the subscriber side and is a useful column to debug potential memleaks. diff --git a/iceoryx_examples/icedelivery/README.md b/iceoryx_examples/icedelivery/README.md index 099eff2c46e..96342add371 100644 --- a/iceoryx_examples/icedelivery/README.md +++ b/iceoryx_examples/icedelivery/README.md @@ -73,11 +73,10 @@ unique string identifier for this publisher. iox::runtime::PoshRuntime::initRuntime("iox-ex-publisher"); ``` -Now that RouDi knows our publisher application is existing, let's create a publisher instance and offer our charming struct +Now that RouDi knows our publisher application is existing, let's create a publisher instance for our charming struct to everyone: ```cpp iox::popo::UntypedPublisher untypedPublisher({"Radar", "FrontLeft", "Object"}); -untypedPublisher.offer(); ``` The strings inside the first parameter of the constructor of `iox::popo::Publisher` are of the type @@ -184,11 +183,6 @@ are created, a default value will be used which sets the queueCapacity to the ma iox::popo::UntypedSubscriber untypedSubscriber({"Radar", "FrontLeft", "Object"}, subscriberOptions); ``` -After the creation, the subscriber object subscribes to the offered data -```cpp -untypedSubscriber.subscribe(); -``` - When using the default n:m communication philosophy, the `SubscriptionState` is immediately `SUBSCRIBED`. However, when restricting iceoryx to the 1:n communication philosophy before being in the state `SUBSCRIBED`, the state is change to `SUBSCRIBE_REQUESTED`. diff --git a/iceoryx_examples/icedelivery/iox_publisher.cpp b/iceoryx_examples/icedelivery/iox_publisher.cpp index 96cfe2a1f91..24eaf469db7 100644 --- a/iceoryx_examples/icedelivery/iox_publisher.cpp +++ b/iceoryx_examples/icedelivery/iox_publisher.cpp @@ -45,7 +45,6 @@ int main() iox::runtime::PoshRuntime::initRuntime("iox-ex-publisher"); iox::popo::Publisher publisher({"Radar", "FrontLeft", "Object"}); - publisher.offer(); double ct = 0.0; while (!killswitch) diff --git a/iceoryx_examples/icedelivery/iox_publisher_untyped.cpp b/iceoryx_examples/icedelivery/iox_publisher_untyped.cpp index 8fd1c21067c..f1238def6e9 100644 --- a/iceoryx_examples/icedelivery/iox_publisher_untyped.cpp +++ b/iceoryx_examples/icedelivery/iox_publisher_untyped.cpp @@ -40,7 +40,6 @@ int main() iox::runtime::PoshRuntime::initRuntime("iox-ex-publisher-untyped"); iox::popo::UntypedPublisher publisher({"Radar", "FrontLeft", "Object"}); - publisher.offer(); double ct = 0.0; while (!killswitch) diff --git a/iceoryx_examples/icedelivery/iox_publisher_with_history.cpp b/iceoryx_examples/icedelivery/iox_publisher_with_history.cpp index 1616a43eca3..15fbd155047 100644 --- a/iceoryx_examples/icedelivery/iox_publisher_with_history.cpp +++ b/iceoryx_examples/icedelivery/iox_publisher_with_history.cpp @@ -41,8 +41,11 @@ int main() // create publisher options to set a historyCapacity of 10U iox::popo::PublisherOptions publisherOptions; publisherOptions.historyCapacity = 10U; + publisherOptions.offerOnCreate = false; iox::popo::Publisher publisher({"Radar", "FrontLeft", "Object"}, publisherOptions); + + // we have to explicitely offer the publisher for making it visible to subscribers publisher.offer(); double ct = 0.0; diff --git a/iceoryx_examples/icedelivery/iox_subscriber.cpp b/iceoryx_examples/icedelivery/iox_subscriber.cpp index 82f69bf517c..80ae720e461 100644 --- a/iceoryx_examples/icedelivery/iox_subscriber.cpp +++ b/iceoryx_examples/icedelivery/iox_subscriber.cpp @@ -44,7 +44,6 @@ int main() iox::popo::SubscriberOptions subscriberOptions; subscriberOptions.queueCapacity = 10U; iox::popo::Subscriber subscriber({"Radar", "FrontLeft", "Object"}, subscriberOptions); - subscriber.subscribe(); // run until interrupted by Ctrl-C while (!killswitch) @@ -71,7 +70,5 @@ int main() std::this_thread::sleep_for(std::chrono::milliseconds(100)); } - subscriber.unsubscribe(); - return (EXIT_SUCCESS); } diff --git a/iceoryx_examples/icedelivery/iox_subscriber_untyped.cpp b/iceoryx_examples/icedelivery/iox_subscriber_untyped.cpp index 110d01c0d5a..e3581fd44af 100644 --- a/iceoryx_examples/icedelivery/iox_subscriber_untyped.cpp +++ b/iceoryx_examples/icedelivery/iox_subscriber_untyped.cpp @@ -44,7 +44,6 @@ int main() iox::popo::SubscriberOptions subscriberOptions; subscriberOptions.queueCapacity = 10U; iox::popo::UntypedSubscriber subscriber({"Radar", "FrontLeft", "Object"}, subscriberOptions); - subscriber.subscribe(); // run until interrupted by Ctrl-C while (!killswitch) @@ -75,7 +74,5 @@ int main() std::this_thread::sleep_for(std::chrono::milliseconds(100)); } - subscriber.unsubscribe(); - return (EXIT_SUCCESS); } diff --git a/iceoryx_examples/icedelivery/iox_subscriber_with_history.cpp b/iceoryx_examples/icedelivery/iox_subscriber_with_history.cpp index dec41a33970..feb9b407466 100644 --- a/iceoryx_examples/icedelivery/iox_subscriber_with_history.cpp +++ b/iceoryx_examples/icedelivery/iox_subscriber_with_history.cpp @@ -46,7 +46,11 @@ int main() // publisher has send. The history ensures that we at least get the last 5 // samples sent by the publisher when we subscribe (if at least 5 were already sent). subscriberOptions.historyRequest = 5U; + subscriberOptions.subscribeOnCreate = false; + iox::popo::Subscriber subscriber({"Radar", "FrontLeft", "Object"}, subscriberOptions); + + // We have to explicitly call subscribe() otherwise the subscriber will not try to connect to publishers subscriber.subscribe(); // run until interrupted by Ctrl-C diff --git a/iceoryx_examples/iceperf/iceoryx.cpp b/iceoryx_examples/iceperf/iceoryx.cpp index 64a534d8c51..13b35f37e2b 100644 --- a/iceoryx_examples/iceperf/iceoryx.cpp +++ b/iceoryx_examples/iceperf/iceoryx.cpp @@ -37,9 +37,6 @@ void Iceoryx::initFollower() noexcept void Iceoryx::init() noexcept { - m_publisher.offer(); - m_subscriber.subscribe(); - std::cout << "Waiting for: subscription" << std::flush; while (m_subscriber.getSubscriptionState() != iox::SubscribeState::SUBSCRIBED) { diff --git a/iceoryx_examples/singleprocess/README.md b/iceoryx_examples/singleprocess/README.md index e994d1b7621..c0eea7b4f3f 100644 --- a/iceoryx_examples/singleprocess/README.md +++ b/iceoryx_examples/singleprocess/README.md @@ -104,13 +104,11 @@ you here with a short overview. #### Publisher We create a typed publisher with the following service description -(Service = `Single`, Instance = `Process`, Event = `Demo`) and offer our service -to the world. +(Service = `Single`, Instance = `Process`, Event = `Demo`) ```cpp iox::popo::PublisherOptions publisherOptions; publisherOptions.historyCapacity = 10U; iox::popo::Publisher publisher({"Single", "Process", "Demo"}, publisherOptions); -publisher.offer(); ``` After that we are sending numbers in ascending order with an 100ms interval in a `while` loop till the variable `keepRunning` is false. @@ -131,14 +129,12 @@ while (keepRunning.load()) #### Subscriber Like with the publisher we are creating a corresponding subscriber port with the -same service description and subscribe to our service. +same service description. ```cpp iox::popo::SubscriberOptions options; options.queueCapacity = 10U; options.historyRequest = 5U; iox::popo::Subscriber subscriber({"Single", "Process", "Demo"}, options); - - subscriber.subscribe(); ``` Now we can receive the data in a while loop till `keepRunning` is false. But we only try to acquire data if our `SubscribeState` is `SUBSCRIBED`. diff --git a/iceoryx_examples/singleprocess/single_process.cpp b/iceoryx_examples/singleprocess/single_process.cpp index ad38e179cc7..9674b036817 100644 --- a/iceoryx_examples/singleprocess/single_process.cpp +++ b/iceoryx_examples/singleprocess/single_process.cpp @@ -51,7 +51,6 @@ void publisher() iox::popo::PublisherOptions publisherOptions; publisherOptions.historyCapacity = 10U; iox::popo::Publisher publisher({"Single", "Process", "Demo"}, publisherOptions); - publisher.offer(); uint64_t counter{0}; std::string greenRightArrow("\033[32m->\033[m "); @@ -74,8 +73,6 @@ void subscriber() options.historyRequest = 5U; iox::popo::Subscriber subscriber({"Single", "Process", "Demo"}, options); - subscriber.subscribe(); - std::string orangeLeftArrow("\033[33m<-\033[m "); while (keepRunning.load()) { diff --git a/iceoryx_examples/waitset/README.md b/iceoryx_examples/waitset/README.md index 541281353af..6c18525933a 100644 --- a/iceoryx_examples/waitset/README.md +++ b/iceoryx_examples/waitset/README.md @@ -145,7 +145,7 @@ iox::popo::WaitSet waitset; waitset.attachEvent(shutdownTrigger); ``` -After that we create a vector to hold our subscribers, we create, subscribe and then +After that we create a vector to hold our subscribers, we create and then attach them to a _WaitSet_ with the `HAS_DATA` event and the `subscriberCallback`. Everytime one of the subscribers is receiving a new sample it will trigger the _WaitSet_. @@ -156,7 +156,6 @@ for (auto i = 0; i < NUMBER_OF_SUBSCRIBERS; ++i) subscriberVector.emplace_back(iox::capro::ServiceDescription{"Radar", "FrontLeft", "Counter"}); auto& subscriber = subscriberVector.back(); - subscriber.subscribe(); waitset.attachEvent(subscriber, iox::popo::SubscriberEvent::HAS_DATA, &subscriberCallback); } ``` @@ -202,15 +201,13 @@ iox::popo::WaitSet waitset; waitset.attachEvent(shutdownTrigger); ``` -Now we create a vector of 4 subscribers and subscribe them to our topic. +Now we create a vector of 4 subscribers. ```cpp iox::cxx::vector subscriberVector; for (auto i = 0; i < NUMBER_OF_SUBSCRIBERS; ++i) { subscriberVector.emplace_back(iox::capro::ServiceDescription{"Radar", "FrontLeft", "Counter"}); auto& subscriber = subscriberVector.back(); - - subscriber.subscribe(); } ``` @@ -282,15 +279,12 @@ iox::popo::WaitSet waitset<>; waitset.attachEvent(shutdownTrigger); ``` -Additionally, we create two subscribers, subscribe them to our topic and attach +Additionally, we create two subscribers and attach them to the waitset to let them inform us whenever they receive a new sample. ```cpp iox::popo::Subscriber subscriber1({"Radar", "FrontLeft", "Counter"}); iox::popo::Subscriber subscriber2({"Radar", "FrontLeft", "Counter"}); -subscriber1.subscribe(); -subscriber2.subscribe(); - waitset.attachEvent(subscriber1, iox::popo::SubscriberEvent::HAS_DATA); waitset.attachEvent(subscriber2, iox::popo::SubscriberEvent::HAS_DATA); ``` diff --git a/iceoryx_examples/waitset/ice_waitset_gateway.cpp b/iceoryx_examples/waitset/ice_waitset_gateway.cpp index d7c0e1483a6..768e05dd072 100644 --- a/iceoryx_examples/waitset/ice_waitset_gateway.cpp +++ b/iceoryx_examples/waitset/ice_waitset_gateway.cpp @@ -66,7 +66,6 @@ int main() subscriberVector.emplace_back(iox::capro::ServiceDescription{"Radar", "FrontLeft", "Counter"}); auto& subscriber = subscriberVector.back(); - subscriber.subscribe(); waitset.attachEvent(subscriber, iox::popo::SubscriberEvent::HAS_DATA, 0, &subscriberCallback); } diff --git a/iceoryx_examples/waitset/ice_waitset_grouping.cpp b/iceoryx_examples/waitset/ice_waitset_grouping.cpp index 2f30710ec76..53958139883 100644 --- a/iceoryx_examples/waitset/ice_waitset_grouping.cpp +++ b/iceoryx_examples/waitset/ice_waitset_grouping.cpp @@ -53,7 +53,6 @@ int main() subscriberVector.emplace_back(iox::capro::ServiceDescription{"Radar", "FrontLeft", "Counter"}); auto& subscriber = subscriberVector.back(); - subscriber.subscribe(); } constexpr uint64_t FIRST_GROUP_ID = 123U; diff --git a/iceoryx_examples/waitset/ice_waitset_individual.cpp b/iceoryx_examples/waitset/ice_waitset_individual.cpp index a6eea07c89c..c5c609e073f 100644 --- a/iceoryx_examples/waitset/ice_waitset_individual.cpp +++ b/iceoryx_examples/waitset/ice_waitset_individual.cpp @@ -48,9 +48,6 @@ int main() iox::popo::Subscriber subscriber1({"Radar", "FrontLeft", "Counter"}); iox::popo::Subscriber subscriber2({"Radar", "FrontLeft", "Counter"}); - subscriber1.subscribe(); - subscriber2.subscribe(); - waitset.attachEvent(subscriber1, iox::popo::SubscriberEvent::HAS_DATA); waitset.attachEvent(subscriber2, iox::popo::SubscriberEvent::HAS_DATA); diff --git a/iceoryx_examples/waitset/ice_waitset_publisher.cpp b/iceoryx_examples/waitset/ice_waitset_publisher.cpp index 9ec1e8f4659..41ff2417f4a 100644 --- a/iceoryx_examples/waitset/ice_waitset_publisher.cpp +++ b/iceoryx_examples/waitset/ice_waitset_publisher.cpp @@ -33,7 +33,6 @@ void sending() { iox::runtime::PoshRuntime::initRuntime("iox-ex-publisher-waitset"); iox::popo::Publisher myPublisher({"Radar", "FrontLeft", "Counter"}); - myPublisher.offer(); for (uint32_t counter = 0U; !killswitch; ++counter) { From 50d6b1ae5fff6c05388bc7c8d4c76b2e2bbb0bea Mon Sep 17 00:00:00 2001 From: Michael Poehnl Date: Sun, 28 Feb 2021 01:22:12 +0100 Subject: [PATCH 113/143] iox-#408 renaming of history example Signed-off-by: Michael Poehnl --- iceoryx_examples/icedelivery/CMakeLists.txt | 16 ++++++++-------- ...istory.cpp => iox_publisher_with_options.cpp} | 13 ++++++++++--- ...story.cpp => iox_subscriber_with_options.cpp} | 15 ++++++++++++--- 3 files changed, 30 insertions(+), 14 deletions(-) rename iceoryx_examples/icedelivery/{iox_publisher_with_history.cpp => iox_publisher_with_options.cpp} (83%) rename iceoryx_examples/icedelivery/{iox_subscriber_with_history.cpp => iox_subscriber_with_options.cpp} (83%) diff --git a/iceoryx_examples/icedelivery/CMakeLists.txt b/iceoryx_examples/icedelivery/CMakeLists.txt index 9df83c2cd4a..082b2b1f340 100644 --- a/iceoryx_examples/icedelivery/CMakeLists.txt +++ b/iceoryx_examples/icedelivery/CMakeLists.txt @@ -34,11 +34,11 @@ target_link_libraries(iox-ex-publisher ) target_compile_options(iox-ex-publisher PRIVATE ${ICEORYX_WARNINGS} ${ICEORYX_SANITIZER_FLAGS}) -add_executable(iox-ex-publisher-with-history ./iox_publisher_with_history.cpp) -target_link_libraries(iox-ex-publisher-with-history +add_executable(iox-ex-publisher-with-options ./iox_publisher_with_options.cpp) +target_link_libraries(iox-ex-publisher-with-options iceoryx_posh::iceoryx_posh ) -target_compile_options(iox-ex-publisher-with-history PRIVATE ${ICEORYX_WARNINGS} ${ICEORYX_SANITIZER_FLAGS}) +target_compile_options(iox-ex-publisher-with-options PRIVATE ${ICEORYX_WARNINGS} ${ICEORYX_SANITIZER_FLAGS}) add_executable(iox-ex-publisher-untyped ./iox_publisher_untyped.cpp) target_link_libraries(iox-ex-publisher-untyped @@ -52,11 +52,11 @@ target_link_libraries(iox-ex-subscriber ) target_compile_options(iox-ex-subscriber PRIVATE ${ICEORYX_WARNINGS} ${ICEORYX_SANITIZER_FLAGS}) -add_executable(iox-ex-subscriber-with-history ./iox_subscriber_with_history.cpp) -target_link_libraries(iox-ex-subscriber-with-history +add_executable(iox-ex-subscriber-with-options ./iox_subscriber_with_options.cpp) +target_link_libraries(iox-ex-subscriber-with-options iceoryx_posh::iceoryx_posh ) -target_compile_options(iox-ex-subscriber-with-history PRIVATE ${ICEORYX_WARNINGS} ${ICEORYX_SANITIZER_FLAGS}) +target_compile_options(iox-ex-subscriber-with-options PRIVATE ${ICEORYX_WARNINGS} ${ICEORYX_SANITIZER_FLAGS}) add_executable(iox-ex-subscriber-untyped ./iox_subscriber_untyped.cpp) target_link_libraries(iox-ex-subscriber-untyped @@ -65,7 +65,7 @@ target_link_libraries(iox-ex-subscriber-untyped target_compile_options(iox-ex-subscriber-untyped PRIVATE ${ICEORYX_WARNINGS} ${ICEORYX_SANITIZER_FLAGS}) set_target_properties(iox-ex-subscriber iox-ex-subscriber-untyped - iox-ex-publisher-with-history iox-ex-subscriber-with-history + iox-ex-publisher-with-options iox-ex-subscriber-with-options iox-ex-publisher iox-ex-publisher-untyped PROPERTIES CXX_STANDARD_REQUIRED ON @@ -76,6 +76,6 @@ set_target_properties(iox-ex-subscriber iox-ex-subscriber-untyped # ========================================================== // install(TARGETS iox-ex-publisher-untyped iox-ex-publisher - iox-ex-publisher-with-history iox-ex-subscriber-with-history + iox-ex-publisher-with-options iox-ex-subscriber-with-options iox-ex-subscriber-untyped iox-ex-subscriber RUNTIME DESTINATION bin) diff --git a/iceoryx_examples/icedelivery/iox_publisher_with_history.cpp b/iceoryx_examples/icedelivery/iox_publisher_with_options.cpp similarity index 83% rename from iceoryx_examples/icedelivery/iox_publisher_with_history.cpp rename to iceoryx_examples/icedelivery/iox_publisher_with_options.cpp index 15fbd155047..93e5798a989 100644 --- a/iceoryx_examples/icedelivery/iox_publisher_with_history.cpp +++ b/iceoryx_examples/icedelivery/iox_publisher_with_options.cpp @@ -38,10 +38,17 @@ int main() iox::runtime::PoshRuntime::initRuntime("iox-ex-publisher-with-history"); - // create publisher options to set a historyCapacity of 10U + // create publisher with some options set iox::popo::PublisherOptions publisherOptions; - publisherOptions.historyCapacity = 10U; - publisherOptions.offerOnCreate = false; + + // the publishers stores the last 10 samples for possible late joiners + publisherOptions.historyCapacity = 10U; + + // when the publisher is created, it is not yet visible + publisherOptions.offerOnCreate = false; + + // grouping of publishers and subscribers within a process + publisherOptions.nodeName = "Pub_Node_With_Options" iox::popo::Publisher publisher({"Radar", "FrontLeft", "Object"}, publisherOptions); diff --git a/iceoryx_examples/icedelivery/iox_subscriber_with_history.cpp b/iceoryx_examples/icedelivery/iox_subscriber_with_options.cpp similarity index 83% rename from iceoryx_examples/icedelivery/iox_subscriber_with_history.cpp rename to iceoryx_examples/icedelivery/iox_subscriber_with_options.cpp index feb9b407466..c40636435ba 100644 --- a/iceoryx_examples/icedelivery/iox_subscriber_with_history.cpp +++ b/iceoryx_examples/icedelivery/iox_subscriber_with_options.cpp @@ -39,15 +39,24 @@ int main() // initialize runtime iox::runtime::PoshRuntime::initRuntime("iox-ex-subscriber-with-history"); - // initialized subscriber + // create subscriber with some options set iox::popo::SubscriberOptions subscriberOptions; + + // the queue can hold 10 samples, on overflow the oldest sample will be replaced with the new arriving one subscriberOptions.queueCapacity = 10U; + // When starting the subscriber late it will miss the first samples which the - // publisher has send. The history ensures that we at least get the last 5 - // samples sent by the publisher when we subscribe (if at least 5 were already sent). + // publisher has send. The history request ensures that we at least get the last 5 + // samples sent by the publisher when we subscribe (if at least 5 were already sent + // and the publisher has history enabled). subscriberOptions.historyRequest = 5U; + + // when the subscriber is created, no attempts are made to connect to any publishers that may exist subscriberOptions.subscribeOnCreate = false; + // grouping of publishers and subscribers within a process + publisherOptions.nodeName = "Sub_Node_With_Options" + iox::popo::Subscriber subscriber({"Radar", "FrontLeft", "Object"}, subscriberOptions); // We have to explicitly call subscribe() otherwise the subscriber will not try to connect to publishers From 7cddd8e4d88ff39d08b9f9915556bffc09b7abd5 Mon Sep 17 00:00:00 2001 From: Michael Poehnl Date: Sun, 28 Feb 2021 01:35:20 +0100 Subject: [PATCH 114/143] iox-#408 fixes in options example Signed-off-by: Michael Poehnl --- iceoryx_examples/icedelivery/iox_publisher_with_options.cpp | 4 ++-- iceoryx_examples/icedelivery/iox_subscriber_with_options.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iceoryx_examples/icedelivery/iox_publisher_with_options.cpp b/iceoryx_examples/icedelivery/iox_publisher_with_options.cpp index 93e5798a989..5b01db6b259 100644 --- a/iceoryx_examples/icedelivery/iox_publisher_with_options.cpp +++ b/iceoryx_examples/icedelivery/iox_publisher_with_options.cpp @@ -36,7 +36,7 @@ int main() auto signalIntGuard = iox::posix::registerSignalHandler(iox::posix::Signal::INT, sigHandler); auto signalTermGuard = iox::posix::registerSignalHandler(iox::posix::Signal::TERM, sigHandler); - iox::runtime::PoshRuntime::initRuntime("iox-ex-publisher-with-history"); + iox::runtime::PoshRuntime::initRuntime("iox-ex-publisher-with-options"); // create publisher with some options set iox::popo::PublisherOptions publisherOptions; @@ -48,7 +48,7 @@ int main() publisherOptions.offerOnCreate = false; // grouping of publishers and subscribers within a process - publisherOptions.nodeName = "Pub_Node_With_Options" + publisherOptions.nodeName = "Pub_Node_With_Options"; iox::popo::Publisher publisher({"Radar", "FrontLeft", "Object"}, publisherOptions); diff --git a/iceoryx_examples/icedelivery/iox_subscriber_with_options.cpp b/iceoryx_examples/icedelivery/iox_subscriber_with_options.cpp index c40636435ba..cba05ec6ab2 100644 --- a/iceoryx_examples/icedelivery/iox_subscriber_with_options.cpp +++ b/iceoryx_examples/icedelivery/iox_subscriber_with_options.cpp @@ -37,7 +37,7 @@ int main() auto signalTermGuard = iox::posix::registerSignalHandler(iox::posix::Signal::TERM, sigHandler); // initialize runtime - iox::runtime::PoshRuntime::initRuntime("iox-ex-subscriber-with-history"); + iox::runtime::PoshRuntime::initRuntime("iox-ex-subscriber-with-options"); // create subscriber with some options set iox::popo::SubscriberOptions subscriberOptions; @@ -55,7 +55,7 @@ int main() subscriberOptions.subscribeOnCreate = false; // grouping of publishers and subscribers within a process - publisherOptions.nodeName = "Sub_Node_With_Options" + subscriberOptions.nodeName = "Sub_Node_With_Options"; iox::popo::Subscriber subscriber({"Radar", "FrontLeft", "Object"}, subscriberOptions); From 53914c02c61f27e527b912af67a40537d23ddaac Mon Sep 17 00:00:00 2001 From: Michael Poehnl Date: Mon, 1 Mar 2021 10:34:23 +0100 Subject: [PATCH 115/143] iox-#408 new tests for runtime Signed-off-by: Michael Poehnl --- .../test/moduletests/test_posh_runtime.cpp | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp index 7c2c9ca9a5a..3317478ca0e 100644 --- a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp +++ b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp @@ -356,6 +356,27 @@ TEST_F(PoshRuntime_test, GetMiddlewarePublisherWithSameServiceDescriptionsAndOne } } +TEST_F(PoshRuntime_test, GetMiddlewarePublisherWithoutOfferOnCreate) +{ + iox::popo::PublisherOptions publisherOptions; + publisherOptions.offerOnCreate = false; + + const auto publisherPortData = m_runtime->getMiddlewarePublisher( + iox::capro::ServiceDescription(99U, 1U, 20U), publisherOptions, iox::runtime::PortConfigInfo(11U, 22U, 33U)); + + EXPECT_FALSE(publisherPortData->m_offeringRequested); +} + +TEST_F(PoshRuntime_test, GetMiddlewarePublisherWithOfferOnCreate) +{ + iox::popo::PublisherOptions publisherOptions; + publisherOptions.offerOnCreate = true; + + const auto publisherPortData = m_runtime->getMiddlewarePublisher( + iox::capro::ServiceDescription(99U, 1U, 20U), publisherOptions, iox::runtime::PortConfigInfo(11U, 22U, 33U)); + + EXPECT_TRUE(publisherPortData->m_offeringRequested); +} TEST_F(PoshRuntime_test, GetMiddlewareSubscriberIsSuccessful) { @@ -417,6 +438,28 @@ TEST_F(PoshRuntime_test, GetMiddlewareSubscriberSubscriberlistOverflow) EXPECT_TRUE(subscriberlistOverflowDetected); } +TEST_F(PoshRuntime_test, GetMiddlewareSubscriberWithoutSubscribeOnCreate) +{ + iox::popo::SubscriberOptions subscriberOptions; + subscriberOptions.subscribeOnCreate = false; + + auto subscriberPortData = m_runtime->getMiddlewareSubscriber( + iox::capro::ServiceDescription(99U, 1U, 20U), subscriberOptions, iox::runtime::PortConfigInfo(11U, 22U, 33U)); + + EXPECT_FALSE(subscriberPortData->m_subscribeRequested); +} + +TEST_F(PoshRuntime_test, GetMiddlewareSubscriberWithSubscribeOnCreate) +{ + iox::popo::SubscriberOptions subscriberOptions; + subscriberOptions.subscribeOnCreate = true; + + auto subscriberPortData = m_runtime->getMiddlewareSubscriber( + iox::capro::ServiceDescription(99U, 1U, 20U), subscriberOptions, iox::runtime::PortConfigInfo(11U, 22U, 33U)); + + EXPECT_TRUE(subscriberPortData->m_subscribeRequested); +} + TEST_F(PoshRuntime_test, GetMiddlewareConditionVariableIsSuccessful) { auto conditionVariable = m_runtime->getMiddlewareConditionVariable(); From cd055f5dba0384eaa32e3834bbb7b74656644073 Mon Sep 17 00:00:00 2001 From: Michael Poehnl Date: Mon, 1 Mar 2021 11:26:20 +0100 Subject: [PATCH 116/143] iox-#408 review findings and clang-format Signed-off-by: Michael Poehnl --- .../test/moduletests/test_publisher.cpp | 2 +- .../icedelivery/iox_publisher_with_options.cpp | 6 +++--- .../iox_subscriber_with_options.cpp | 18 +++++++++--------- iceoryx_examples/iceperf/iceoryx.cpp | 1 + .../waitset/ice_waitset_grouping.cpp | 1 - .../internal/roudi/port_manager.hpp | 4 ++-- .../iceoryx_posh/popo/publisher_options.hpp | 3 +-- .../iceoryx_posh/popo/subscriber_options.hpp | 3 +-- .../source/popo/ports/publisher_port_data.cpp | 1 + .../source/popo/ports/publisher_port_roudi.cpp | 1 + .../source/popo/ports/subscriber_port_data.cpp | 1 + iceoryx_posh/source/roudi/port_manager.cpp | 13 ++++++------- iceoryx_posh/source/runtime/posh_runtime.cpp | 1 + .../moduletests/test_popo_publisher_port.cpp | 8 +++++--- .../moduletests/test_popo_subscriber_port.cpp | 6 ++++-- .../moduletests/test_roudi_portmanager.cpp | 4 ++-- 16 files changed, 39 insertions(+), 34 deletions(-) diff --git a/iceoryx_binding_c/test/moduletests/test_publisher.cpp b/iceoryx_binding_c/test/moduletests/test_publisher.cpp index 349a367ce44..b9e85a864cc 100644 --- a/iceoryx_binding_c/test/moduletests/test_publisher.cpp +++ b/iceoryx_binding_c/test/moduletests/test_publisher.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -234,4 +235,3 @@ TEST_F(iox_pub_test, sendDeliversChunk) EXPECT_TRUE(*maybeSharedChunk == chunk); EXPECT_TRUE(static_cast(maybeSharedChunk->getPayload())->dummy == 4711); } - diff --git a/iceoryx_examples/icedelivery/iox_publisher_with_options.cpp b/iceoryx_examples/icedelivery/iox_publisher_with_options.cpp index 5b01db6b259..b93defbb622 100644 --- a/iceoryx_examples/icedelivery/iox_publisher_with_options.cpp +++ b/iceoryx_examples/icedelivery/iox_publisher_with_options.cpp @@ -42,13 +42,13 @@ int main() iox::popo::PublisherOptions publisherOptions; // the publishers stores the last 10 samples for possible late joiners - publisherOptions.historyCapacity = 10U; + publisherOptions.historyCapacity = 10U; - // when the publisher is created, it is not yet visible + // when the publisher is created, it is not yet visible publisherOptions.offerOnCreate = false; // grouping of publishers and subscribers within a process - publisherOptions.nodeName = "Pub_Node_With_Options"; + publisherOptions.nodeName = "Pub_Node_With_Options"; iox::popo::Publisher publisher({"Radar", "FrontLeft", "Object"}, publisherOptions); diff --git a/iceoryx_examples/icedelivery/iox_subscriber_with_options.cpp b/iceoryx_examples/icedelivery/iox_subscriber_with_options.cpp index cba05ec6ab2..d7d0eefa92d 100644 --- a/iceoryx_examples/icedelivery/iox_subscriber_with_options.cpp +++ b/iceoryx_examples/icedelivery/iox_subscriber_with_options.cpp @@ -41,24 +41,24 @@ int main() // create subscriber with some options set iox::popo::SubscriberOptions subscriberOptions; - - // the queue can hold 10 samples, on overflow the oldest sample will be replaced with the new arriving one + + // the queue can hold 10 samples, on overflow the oldest sample will be replaced with the new arriving one subscriberOptions.queueCapacity = 10U; - + // When starting the subscriber late it will miss the first samples which the // publisher has send. The history request ensures that we at least get the last 5 // samples sent by the publisher when we subscribe (if at least 5 were already sent // and the publisher has history enabled). subscriberOptions.historyRequest = 5U; - - // when the subscriber is created, no attempts are made to connect to any publishers that may exist + + // when the subscriber is created, no attempts are made to connect to any publishers that may exist subscriberOptions.subscribeOnCreate = false; - - // grouping of publishers and subscribers within a process - subscriberOptions.nodeName = "Sub_Node_With_Options"; + + // grouping of publishers and subscribers within a process + subscriberOptions.nodeName = "Sub_Node_With_Options"; iox::popo::Subscriber subscriber({"Radar", "FrontLeft", "Object"}, subscriberOptions); - + // We have to explicitly call subscribe() otherwise the subscriber will not try to connect to publishers subscriber.subscribe(); diff --git a/iceoryx_examples/iceperf/iceoryx.cpp b/iceoryx_examples/iceperf/iceoryx.cpp index 13b35f37e2b..eebfee75d0c 100644 --- a/iceoryx_examples/iceperf/iceoryx.cpp +++ b/iceoryx_examples/iceperf/iceoryx.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_examples/waitset/ice_waitset_grouping.cpp b/iceoryx_examples/waitset/ice_waitset_grouping.cpp index 53958139883..906222ced4a 100644 --- a/iceoryx_examples/waitset/ice_waitset_grouping.cpp +++ b/iceoryx_examples/waitset/ice_waitset_grouping.cpp @@ -52,7 +52,6 @@ int main() { subscriberVector.emplace_back(iox::capro::ServiceDescription{"Radar", "FrontLeft", "Counter"}); auto& subscriber = subscriberVector.back(); - } constexpr uint64_t FIRST_GROUP_ID = 123U; diff --git a/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp b/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp index 1fd159f6cdc..6f4909432cf 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/roudi/port_manager.hpp @@ -127,8 +127,8 @@ class PortManager void removeEntryFromServiceRegistry(const capro::IdString_t& service, const capro::IdString_t& instance) noexcept; template ::value>* = nullptr> - cxx::optional doesViolateCommunicationPolicy(const capro::ServiceDescription& service) const - noexcept; + cxx::optional + doesViolateCommunicationPolicy(const capro::ServiceDescription& service) const noexcept; template ::value>* = nullptr> cxx::optional doesViolateCommunicationPolicy(const capro::ServiceDescription& service diff --git a/iceoryx_posh/include/iceoryx_posh/popo/publisher_options.hpp b/iceoryx_posh/include/iceoryx_posh/popo/publisher_options.hpp index 174900bb126..e6bd024c001 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/publisher_options.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/publisher_options.hpp @@ -34,8 +34,7 @@ struct PublisherOptions iox::NodeName_t nodeName{""}; /// @brief The option whether the publisher should already be offered when creating it - bool offerOnCreate = {true}; - + bool offerOnCreate{true}; }; } // namespace popo diff --git a/iceoryx_posh/include/iceoryx_posh/popo/subscriber_options.hpp b/iceoryx_posh/include/iceoryx_posh/popo/subscriber_options.hpp index 5b3ec8e2180..0c448b50659 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/subscriber_options.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/subscriber_options.hpp @@ -39,8 +39,7 @@ struct SubscriberOptions iox::NodeName_t nodeName{""}; /// @brief The option whether the subscriber shall try to subscribe when creating it - bool subscribeOnCreate = {true}; - + bool subscribeOnCreate{true}; }; } // namespace popo diff --git a/iceoryx_posh/source/popo/ports/publisher_port_data.cpp b/iceoryx_posh/source/popo/ports/publisher_port_data.cpp index 463d4798b0d..1f804a71f28 100644 --- a/iceoryx_posh/source/popo/ports/publisher_port_data.cpp +++ b/iceoryx_posh/source/popo/ports/publisher_port_data.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2020, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/source/popo/ports/publisher_port_roudi.cpp b/iceoryx_posh/source/popo/ports/publisher_port_roudi.cpp index e05c685760c..5fa87dcbb69 100644 --- a/iceoryx_posh/source/popo/ports/publisher_port_roudi.cpp +++ b/iceoryx_posh/source/popo/ports/publisher_port_roudi.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/source/popo/ports/subscriber_port_data.cpp b/iceoryx_posh/source/popo/ports/subscriber_port_data.cpp index 8d26cab727b..41d4d185d36 100644 --- a/iceoryx_posh/source/popo/ports/subscriber_port_data.cpp +++ b/iceoryx_posh/source/popo/ports/subscriber_port_data.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2020, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/source/roudi/port_manager.cpp b/iceoryx_posh/source/roudi/port_manager.cpp index 873f2b83419..bf5db4a99f6 100644 --- a/iceoryx_posh/source/roudi/port_manager.cpp +++ b/iceoryx_posh/source/roudi/port_manager.cpp @@ -160,14 +160,13 @@ void PortManager::doDiscoveryForPublisherPort(PublisherPortRouDiType& publisherP else if (capro::CaproMessageType::STOP_OFFER == caproMessage.m_type) { this->removeEntryFromServiceRegistry(caproMessage.m_serviceDescription.getServiceIDString(), - caproMessage.m_serviceDescription.getInstanceIDString()); + caproMessage.m_serviceDescription.getInstanceIDString()); } else { // protocol error - errorHandler(Error::kPORT_MANAGER__HANDLE_PUBLISHER_PORTS_INVALID_CAPRO_MESSAGE, - nullptr, - iox::ErrorLevel::MODERATE); + errorHandler( + Error::kPORT_MANAGER__HANDLE_PUBLISHER_PORTS_INVALID_CAPRO_MESSAGE, nullptr, iox::ErrorLevel::MODERATE); } this->sendToAllMatchingSubscriberPorts(caproMessage, publisherPort); @@ -214,8 +213,8 @@ void PortManager::doDiscoveryForSubscriberPort(SubscriberPortType& subscriberPor { // protocol error errorHandler(Error::kPORT_MANAGER__HANDLE_SUBSCRIBER_PORTS_INVALID_CAPRO_MESSAGE, - nullptr, - iox::ErrorLevel::MODERATE); + nullptr, + iox::ErrorLevel::MODERATE); } }); } @@ -635,7 +634,7 @@ PortManager::acquireSubscriberPortData(const capro::ServiceDescription& service, if (subscriberPortData) { m_portIntrospection.addSubscriber(*subscriberPortData); - + // we do discovery here for trying to connect with publishers if subscribe on create is desired SubscriberPortType subscriberPort(subscriberPortData); doDiscoveryForSubscriberPort(subscriberPort); diff --git a/iceoryx_posh/source/runtime/posh_runtime.cpp b/iceoryx_posh/source/runtime/posh_runtime.cpp index 8587675bee0..a662f07a9e8 100644 --- a/iceoryx_posh/source/runtime/posh_runtime.cpp +++ b/iceoryx_posh/source/runtime/posh_runtime.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2019, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/test/moduletests/test_popo_publisher_port.cpp b/iceoryx_posh/test/moduletests/test_popo_publisher_port.cpp index ebec8dd928c..42234bd6d91 100644 --- a/iceoryx_posh/test/moduletests/test_popo_publisher_port.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_publisher_port.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -72,7 +73,8 @@ class PublisherPort_test : public Test iox::posix::Allocator m_memoryAllocator{m_memory, MEMORY_SIZE}; iox::mepoo::MePooConfig m_mempoolconf; iox::mepoo::MemoryManager m_memoryManager; - iox::popo::PublisherOptions m_noOfferOnCreatePublisherOptions{0U, "", false};; + iox::popo::PublisherOptions m_noOfferOnCreatePublisherOptions{0U, "", false}; + ; // publisher port w/o offer on create iox::popo::PublisherPortData m_publisherPortData{ @@ -80,14 +82,14 @@ class PublisherPort_test : public Test iox::popo::PublisherPortRouDi m_sutNoOfferOnCreateRouDiSide{&m_publisherPortData}; iox::popo::PublisherPortUser m_sutNoOfferOnCreateUserSide{&m_publisherPortData}; - // publisher port w/ history + // publisher port w/ history iox::popo::PublisherOptions m_withHistoryPublisherOptions{iox::MAX_PUBLISHER_HISTORY, "", true}; iox::popo::PublisherPortData m_publisherPortDataHistory{ iox::capro::ServiceDescription("x", "y", "z"), "myApp", &m_memoryManager, m_withHistoryPublisherOptions}; iox::popo::PublisherPortUser m_sutWithHistoryUserSide{&m_publisherPortDataHistory}; iox::popo::PublisherPortRouDi m_sutWithHistoryRouDiSide{&m_publisherPortDataHistory}; - // publisher port w/ default options + // publisher port w/ default options iox::popo::PublisherOptions m_withDefaultPublisherOptions{}; iox::popo::PublisherPortData m_publisherPortDataDefault{ iox::capro::ServiceDescription("x", "y", "z"), "myApp", &m_memoryManager, m_withDefaultPublisherOptions}; diff --git a/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp b/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp index f7650d7dd05..078cfc4e022 100644 --- a/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -57,8 +58,9 @@ class SubscriberPortSingleProducer_test : public Test iox::cxx::GenericRAII m_uniqueRouDiId{[] { iox::popo::internal::setUniqueRouDiId(0); }, [] { iox::popo::internal::unsetUniqueRouDiId(); }}; - - iox::popo::SubscriberOptions m_noSubscribeOnCreateOptions {iox::popo::SubscriberPortData::ChunkQueueData_t::MAX_CAPACITY, 0U, "", false}; + + iox::popo::SubscriberOptions m_noSubscribeOnCreateOptions{ + iox::popo::SubscriberPortData::ChunkQueueData_t::MAX_CAPACITY, 0U, "", false}; iox::popo::SubscriberPortData m_subscriberPortDataSingleProducer{ TEST_SERVICE_DESCRIPTION, "myApp", diff --git a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp index cb49debd640..60fcec38386 100644 --- a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp +++ b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp @@ -378,10 +378,10 @@ TEST_F(PortManager_test, offerOnCreateAndSubscribeOnCreate_needsNoMoreDiscoveryL ->acquirePublisherPortData( {1, 1, 1}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) .value()); - + SubscriberPortUser subscriber( m_portManager->acquireSubscriberPortData({1, 1, 1}, subscriberOptions, "schlomo", PortConfigInfo()).value()); - + ASSERT_TRUE(publisher.hasSubscribers()); EXPECT_THAT(subscriber.getSubscriptionState(), Eq(iox::SubscribeState::SUBSCRIBED)); From dfec6dcf538566d8ef09e2c0d71e5d95ba083149 Mon Sep 17 00:00:00 2001 From: Michael Poehnl Date: Mon, 1 Mar 2021 16:32:31 +0100 Subject: [PATCH 117/143] iox-#408 header fun Signed-off-by: Michael Poehnl --- iceoryx_binding_c/test/moduletests/test_publisher.cpp | 4 ++-- iceoryx_posh/include/iceoryx_posh/popo/subscriber_options.hpp | 2 +- iceoryx_posh/source/popo/ports/publisher_port_data.cpp | 2 +- iceoryx_posh/source/popo/ports/subscriber_port_data.cpp | 2 +- iceoryx_posh/source/runtime/posh_runtime.cpp | 2 +- iceoryx_posh/test/moduletests/test_popo_publisher_port.cpp | 4 ++-- iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/iceoryx_binding_c/test/moduletests/test_publisher.cpp b/iceoryx_binding_c/test/moduletests/test_publisher.cpp index b9e85a864cc..0bbf0a8ecf6 100644 --- a/iceoryx_binding_c/test/moduletests/test_publisher.cpp +++ b/iceoryx_binding_c/test/moduletests/test_publisher.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. -// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/include/iceoryx_posh/popo/subscriber_options.hpp b/iceoryx_posh/include/iceoryx_posh/popo/subscriber_options.hpp index 0c448b50659..d2e31cd8693 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/subscriber_options.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/subscriber_options.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020, 2021 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/source/popo/ports/publisher_port_data.cpp b/iceoryx_posh/source/popo/ports/publisher_port_data.cpp index 1f804a71f28..3e8d4dd0c11 100644 --- a/iceoryx_posh/source/popo/ports/publisher_port_data.cpp +++ b/iceoryx_posh/source/popo/ports/publisher_port_data.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. // Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/iceoryx_posh/source/popo/ports/subscriber_port_data.cpp b/iceoryx_posh/source/popo/ports/subscriber_port_data.cpp index 41d4d185d36..ff73c427faa 100644 --- a/iceoryx_posh/source/popo/ports/subscriber_port_data.cpp +++ b/iceoryx_posh/source/popo/ports/subscriber_port_data.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. // Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/iceoryx_posh/source/runtime/posh_runtime.cpp b/iceoryx_posh/source/runtime/posh_runtime.cpp index a662f07a9e8..c05d1b0dc69 100644 --- a/iceoryx_posh/source/runtime/posh_runtime.cpp +++ b/iceoryx_posh/source/runtime/posh_runtime.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2019, 2021 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. +// Copyright (c) 2019 - 2021 by Robert Bosch GmbH. All rights reserved. // Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/iceoryx_posh/test/moduletests/test_popo_publisher_port.cpp b/iceoryx_posh/test/moduletests/test_popo_publisher_port.cpp index 42234bd6d91..23f8b38b7fc 100644 --- a/iceoryx_posh/test/moduletests/test_popo_publisher_port.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_publisher_port.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2020 by Robert Bosch GmbH, Apex.AI Inc. All rights reserved. -// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp index 60fcec38386..518268ac02f 100644 --- a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp +++ b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2019, 2021 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2019 - 2021 by Robert Bosch GmbH. All rights reserved. // Copyright (c) 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); From 4833184302961c8241d87782afeac767274d781b Mon Sep 17 00:00:00 2001 From: Michael Poehnl Date: Mon, 1 Mar 2021 20:32:58 +0100 Subject: [PATCH 118/143] iox-#408 review findings Signed-off-by: Michael Poehnl --- iceoryx_examples/icecrystal/Readme.md | 2 +- .../moduletests/test_popo_publisher_port.cpp | 24 +++++++++---------- .../moduletests/test_popo_subscriber_port.cpp | 16 ++++++------- .../test/moduletests/test_posh_runtime.cpp | 16 ++++++------- .../moduletests/test_roudi_portmanager.cpp | 16 ++++++------- 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/iceoryx_examples/icecrystal/Readme.md b/iceoryx_examples/icecrystal/Readme.md index 1cfd679d90a..74e6abdf628 100644 --- a/iceoryx_examples/icecrystal/Readme.md +++ b/iceoryx_examples/icecrystal/Readme.md @@ -51,7 +51,7 @@ The process view will show you the processes (incl. PID), which are currently re --port Subscribe to port introspection data. The port view shows both publisher and subscriber ports that are created by RouDi in the shared memory. Their respective -service description (service, instance, event) is shown to identify them uniquely. The columns `Process` displays to which process the ports. +service description (service, instance, event) is shown to identify them uniquely. The columns `Process` displays to which process the ports belong. Size in bytes of both sample size and chunk size (sample size + meta data) and statistical data of `Chunks [/Minute]` is provided as well. The service discovery protocol allows you to define the `Propagation scope` of the data. This can enable data forwarding to other machines e.g. over network or just consume them internally. When a `Callback` is diff --git a/iceoryx_posh/test/moduletests/test_popo_publisher_port.cpp b/iceoryx_posh/test/moduletests/test_popo_publisher_port.cpp index 23f8b38b7fc..5434dfa8283 100644 --- a/iceoryx_posh/test/moduletests/test_popo_publisher_port.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_publisher_port.cpp @@ -117,7 +117,7 @@ TEST_F(PublisherPort_test, initialStateReturnsOfferCaProMessageWithDefaultOption { auto maybeCaproMessage = m_sutWithDefaultOptionsRouDiSide.tryGetCaProMessage(); - EXPECT_TRUE(maybeCaproMessage.has_value()); + ASSERT_TRUE(maybeCaproMessage.has_value()); auto caproMessage = maybeCaproMessage.value(); EXPECT_THAT(caproMessage.m_type, Eq(iox::capro::CaproMessageType::OFFER)); } @@ -143,7 +143,7 @@ TEST_F(PublisherPort_test, offerCallResultsInOfferCaProMessage) auto maybeCaproMessage = m_sutNoOfferOnCreateRouDiSide.tryGetCaProMessage(); - EXPECT_TRUE(maybeCaproMessage.has_value()); + ASSERT_TRUE(maybeCaproMessage.has_value()); auto caproMessage = maybeCaproMessage.value(); EXPECT_THAT(caproMessage.m_type, Eq(iox::capro::CaproMessageType::OFFER)); EXPECT_THAT(caproMessage.m_serviceDescription, Eq(iox::capro::ServiceDescription("a", "b", "c"))); @@ -170,7 +170,7 @@ TEST_F(PublisherPort_test, stopOfferCallResultsInStopOfferCaProMessage) auto maybeCaproMessage = m_sutNoOfferOnCreateRouDiSide.tryGetCaProMessage(); - EXPECT_TRUE(maybeCaproMessage.has_value()); + ASSERT_TRUE(maybeCaproMessage.has_value()); auto caproMessage = maybeCaproMessage.value(); EXPECT_THAT(caproMessage.m_type, Eq(iox::capro::CaproMessageType::STOP_OFFER)); EXPECT_THAT(caproMessage.m_serviceDescription, Eq(iox::capro::ServiceDescription("a", "b", "c"))); @@ -192,7 +192,7 @@ TEST_F(PublisherPort_test, m_sutWithHistoryUserSide.offer(); auto maybeCaproMessage = m_sutWithHistoryRouDiSide.tryGetCaProMessage(); - EXPECT_TRUE(maybeCaproMessage.has_value()); + ASSERT_TRUE(maybeCaproMessage.has_value()); auto caproMessage = maybeCaproMessage.value(); EXPECT_THAT(caproMessage.m_type, Eq(iox::capro::CaproMessageType::OFFER)); EXPECT_THAT(caproMessage.m_serviceDescription, Eq(iox::capro::ServiceDescription("x", "y", "z"))); @@ -265,7 +265,7 @@ TEST_F(PublisherPort_test, subscribeWhenNotOfferedReturnsNACK) auto maybeCaProMessage = m_sutNoOfferOnCreateRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); - EXPECT_TRUE(maybeCaProMessage.has_value()); + ASSERT_TRUE(maybeCaProMessage.has_value()); auto caproMessageResponse = maybeCaProMessage.value(); EXPECT_THAT(caproMessageResponse.m_type, Eq(iox::capro::CaproMessageType::NACK)); } @@ -282,7 +282,7 @@ TEST_F(PublisherPort_test, unsubscribeWhenNotSubscribedReturnsNACK) auto maybeCaproMessage = m_sutNoOfferOnCreateRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); - EXPECT_TRUE(maybeCaproMessage.has_value()); + ASSERT_TRUE(maybeCaproMessage.has_value()); auto caproMessageResponse = maybeCaproMessage.value(); EXPECT_THAT(caproMessageResponse.m_type, Eq(iox::capro::CaproMessageType::NACK)); } @@ -320,7 +320,7 @@ TEST_F(PublisherPort_test, unsubscribeWhenSubscribedReturnsACKAndWeHaveNoMoreSub maybeCaProMessage = m_sutNoOfferOnCreateRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); - EXPECT_TRUE(maybeCaProMessage.has_value()); + ASSERT_TRUE(maybeCaProMessage.has_value()); auto caproMessageResponse = maybeCaProMessage.value(); EXPECT_THAT(caproMessageResponse.m_type, Eq(iox::capro::CaproMessageType::ACK)); EXPECT_FALSE(m_sutNoOfferOnCreateUserSide.hasSubscribers()); @@ -342,7 +342,7 @@ TEST_F(PublisherPort_test, subscribeManyIsFine) for (size_t i = 0; i < iox::MAX_SUBSCRIBERS_PER_PUBLISHER; i++) { auto maybeCaProMessage = m_sutNoOfferOnCreateRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); - EXPECT_TRUE(maybeCaProMessage.has_value()); + ASSERT_TRUE(maybeCaProMessage.has_value()); auto caproMessageResponse = maybeCaProMessage.value(); EXPECT_THAT(caproMessageResponse.m_type, Eq(iox::capro::CaproMessageType::ACK)); dummyPtr++; @@ -371,7 +371,7 @@ TEST_F(PublisherPort_test, subscribeTillOverflowReturnsNACK) auto maybeCaProMessage = m_sutNoOfferOnCreateRouDiSide.dispatchCaProMessageAndGetPossibleResponse(caproMessage); - EXPECT_TRUE(maybeCaProMessage.has_value()); + ASSERT_TRUE(maybeCaProMessage.has_value()); auto caproMessageResponse = maybeCaProMessage.value(); EXPECT_THAT(caproMessageResponse.m_type, Eq(iox::capro::CaproMessageType::NACK)); } @@ -396,7 +396,7 @@ TEST_F(PublisherPort_test, sendWhenSubscribedDeliversAChunk) auto maybeSharedChunk = m_chunkQueuePopper.tryPop(); - EXPECT_TRUE(maybeSharedChunk.has_value()); + ASSERT_TRUE(maybeSharedChunk.has_value()); auto sharedChunk = maybeSharedChunk.value(); auto dummySample = *reinterpret_cast(sharedChunk.getPayload()); EXPECT_THAT(dummySample.dummy, Eq(17U)); @@ -433,7 +433,7 @@ TEST_F(PublisherPort_test, subscribeWithHistoryLikeTheARAField) // 4. We get the history value on subscribe auto maybeSharedChunk = m_chunkQueuePopper.tryPop(); - EXPECT_TRUE(maybeSharedChunk.has_value()); + ASSERT_TRUE(maybeSharedChunk.has_value()); auto sharedChunk = maybeSharedChunk.value(); auto dummySample = *reinterpret_cast(sharedChunk.getPayload()); EXPECT_THAT(dummySample.dummy, Eq(17U)); @@ -455,7 +455,7 @@ TEST_F(PublisherPort_test, lastChunkAvailableAfterSend) auto maybeLastChunkHeader = m_sutNoOfferOnCreateUserSide.tryGetPreviousChunk(); - EXPECT_TRUE(maybeLastChunkHeader.has_value()); + ASSERT_TRUE(maybeLastChunkHeader.has_value()); EXPECT_THAT(maybeLastChunkHeader.value()->payload(), Eq(firstPayloadPtr)); } diff --git a/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp b/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp index 078cfc4e022..d0fc312bc00 100644 --- a/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp @@ -111,7 +111,7 @@ TEST_F(SubscriberPortSingleProducer_test, initialStateReturnsSubCaProMessageWith { auto maybeCaproMessage = m_sutRouDiSideDefaultOptions.tryGetCaProMessage(); - EXPECT_TRUE(maybeCaproMessage.has_value()); + ASSERT_TRUE(maybeCaproMessage.has_value()); auto caproMessage = maybeCaproMessage.value(); EXPECT_THAT(caproMessage.m_type, Eq(iox::capro::CaproMessageType::SUB)); } @@ -122,7 +122,7 @@ TEST_F(SubscriberPortSingleProducer_test, subscribeCallResultsInSubCaProMessage) auto maybeCaproMessage = m_sutRouDiSideSingleProducer.tryGetCaProMessage(); - EXPECT_TRUE(maybeCaproMessage.has_value()); + ASSERT_TRUE(maybeCaproMessage.has_value()); auto caproMessage = maybeCaproMessage.value(); EXPECT_THAT(caproMessage.m_type, Eq(iox::capro::CaproMessageType::SUB)); EXPECT_THAT(caproMessage.m_serviceDescription, Eq(SubscriberPortSingleProducer_test::TEST_SERVICE_DESCRIPTION)); @@ -176,7 +176,7 @@ TEST_F(SubscriberPortSingleProducer_test, offerInWaitForOfferTriggersSubMessage) auto maybeCaproMessage = m_sutRouDiSideSingleProducer.dispatchCaProMessageAndGetPossibleResponse(caproMessage); - EXPECT_TRUE(maybeCaproMessage.has_value()); + ASSERT_TRUE(maybeCaproMessage.has_value()); auto caproMessageResponse = maybeCaproMessage.value(); EXPECT_THAT(caproMessageResponse.m_type, Eq(iox::capro::CaproMessageType::SUB)); EXPECT_THAT(caproMessageResponse.m_serviceDescription, @@ -240,7 +240,7 @@ TEST_F(SubscriberPortSingleProducer_test, unsubscribeInSubscribedTriggersUnsubMe auto maybeCaproMessage = m_sutRouDiSideSingleProducer.tryGetCaProMessage(); - EXPECT_TRUE(maybeCaproMessage.has_value()); + ASSERT_TRUE(maybeCaproMessage.has_value()); auto caproMessageResponse = maybeCaproMessage.value(); EXPECT_THAT(caproMessageResponse.m_type, Eq(iox::capro::CaproMessageType::UNSUB)); EXPECT_THAT(caproMessageResponse.m_serviceDescription, @@ -386,7 +386,7 @@ TEST_F(SubscriberPortMultiProducer_test, initialStateReturnsSubCaProMessageWithD { auto maybeCaproMessage = m_sutRouDiSideMultiProducer.tryGetCaProMessage(); - EXPECT_TRUE(maybeCaproMessage.has_value()); + ASSERT_TRUE(maybeCaproMessage.has_value()); auto caproMessage = maybeCaproMessage.value(); EXPECT_THAT(caproMessage.m_type, Eq(iox::capro::CaproMessageType::SUB)); } @@ -397,7 +397,7 @@ TEST_F(SubscriberPortMultiProducer_test, subscribeCallResultsInSubCaProMessage) auto maybeCaproMessage = m_sutRouDiSideMultiProducer.tryGetCaProMessage(); - EXPECT_TRUE(maybeCaproMessage.has_value()); + ASSERT_TRUE(maybeCaproMessage.has_value()); auto caproMessage = maybeCaproMessage.value(); EXPECT_THAT(caproMessage.m_type, Eq(iox::capro::CaproMessageType::SUB)); EXPECT_THAT(caproMessage.m_serviceDescription, Eq(SubscriberPortSingleProducer_test::TEST_SERVICE_DESCRIPTION)); @@ -449,7 +449,7 @@ TEST_F(SubscriberPortMultiProducer_test, offerInSubscribedTriggersSubMessage) auto maybeCaproMessage = m_sutRouDiSideMultiProducer.dispatchCaProMessageAndGetPossibleResponse(caproMessage); - EXPECT_TRUE(maybeCaproMessage.has_value()); + ASSERT_TRUE(maybeCaproMessage.has_value()); auto caproMessageResponse = maybeCaproMessage.value(); EXPECT_THAT(caproMessageResponse.m_type, Eq(iox::capro::CaproMessageType::SUB)); EXPECT_THAT(caproMessageResponse.m_serviceDescription, @@ -495,7 +495,7 @@ TEST_F(SubscriberPortMultiProducer_test, unsubscribeInSubscribedTriggersUnsubMes auto maybeCaproMessage = m_sutRouDiSideMultiProducer.tryGetCaProMessage(); - EXPECT_TRUE(maybeCaproMessage.has_value()); + ASSERT_TRUE(maybeCaproMessage.has_value()); auto caproMessageResponse = maybeCaproMessage.value(); EXPECT_THAT(caproMessageResponse.m_type, Eq(iox::capro::CaproMessageType::UNSUB)); EXPECT_THAT(caproMessageResponse.m_serviceDescription, diff --git a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp index 3317478ca0e..28cbee32228 100644 --- a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp +++ b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp @@ -356,24 +356,24 @@ TEST_F(PoshRuntime_test, GetMiddlewarePublisherWithSameServiceDescriptionsAndOne } } -TEST_F(PoshRuntime_test, GetMiddlewarePublisherWithoutOfferOnCreate) +TEST_F(PoshRuntime_test, GetMiddlewarePublisherWithoutOfferOnCreateLeadsToNotOfferedSubscriberBeingCreated) { iox::popo::PublisherOptions publisherOptions; publisherOptions.offerOnCreate = false; const auto publisherPortData = m_runtime->getMiddlewarePublisher( - iox::capro::ServiceDescription(99U, 1U, 20U), publisherOptions, iox::runtime::PortConfigInfo(11U, 22U, 33U)); + iox::capro::ServiceDescription(69U, 96U, 1893U), publisherOptions, iox::runtime::PortConfigInfo(11U, 22U, 33U)); EXPECT_FALSE(publisherPortData->m_offeringRequested); } -TEST_F(PoshRuntime_test, GetMiddlewarePublisherWithOfferOnCreate) +TEST_F(PoshRuntime_test, GetMiddlewarePublisherWithOfferOnCreateLeadsToOfferedSubscriberBeingCreated) { iox::popo::PublisherOptions publisherOptions; publisherOptions.offerOnCreate = true; const auto publisherPortData = m_runtime->getMiddlewarePublisher( - iox::capro::ServiceDescription(99U, 1U, 20U), publisherOptions, iox::runtime::PortConfigInfo(11U, 22U, 33U)); + iox::capro::ServiceDescription(17U, 4U, 21U), publisherOptions, iox::runtime::PortConfigInfo(11U, 22U, 33U)); EXPECT_TRUE(publisherPortData->m_offeringRequested); } @@ -438,24 +438,24 @@ TEST_F(PoshRuntime_test, GetMiddlewareSubscriberSubscriberlistOverflow) EXPECT_TRUE(subscriberlistOverflowDetected); } -TEST_F(PoshRuntime_test, GetMiddlewareSubscriberWithoutSubscribeOnCreate) +TEST_F(PoshRuntime_test, GetMiddlewareSubscriberWithoutSubscribeOnCreateLeadsToSubscriberThatDoesNotWantToBeSubscribed) { iox::popo::SubscriberOptions subscriberOptions; subscriberOptions.subscribeOnCreate = false; auto subscriberPortData = m_runtime->getMiddlewareSubscriber( - iox::capro::ServiceDescription(99U, 1U, 20U), subscriberOptions, iox::runtime::PortConfigInfo(11U, 22U, 33U)); + iox::capro::ServiceDescription(17U, 17U, 17U), subscriberOptions, iox::runtime::PortConfigInfo(11U, 22U, 33U)); EXPECT_FALSE(subscriberPortData->m_subscribeRequested); } -TEST_F(PoshRuntime_test, GetMiddlewareSubscriberWithSubscribeOnCreate) +TEST_F(PoshRuntime_test, GetMiddlewareSubscriberWithSubscribeOnCreateLeadsToSubscriberThatWantsToBeSubscribed) { iox::popo::SubscriberOptions subscriberOptions; subscriberOptions.subscribeOnCreate = true; auto subscriberPortData = m_runtime->getMiddlewareSubscriber( - iox::capro::ServiceDescription(99U, 1U, 20U), subscriberOptions, iox::runtime::PortConfigInfo(11U, 22U, 33U)); + iox::capro::ServiceDescription(1U, 2U, 3U), subscriberOptions, iox::runtime::PortConfigInfo(11U, 22U, 33U)); EXPECT_TRUE(subscriberPortData->m_subscribeRequested); } diff --git a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp index 518268ac02f..85551a67117 100644 --- a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp +++ b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp @@ -207,7 +207,7 @@ void setDestroyFlagAndClearContainer(vector& container) container.clear(); } -TEST_F(PortManager_test, doDiscovery_singleShotPublisherFirst) +TEST_F(PortManager_test, DoDiscoveryWithSingleShotPublisherFirst) { PublisherOptions publisherOptions{1, "node", false}; SubscriberOptions subscriberOptions{1, 1, "node", false}; @@ -232,7 +232,7 @@ TEST_F(PortManager_test, doDiscovery_singleShotPublisherFirst) EXPECT_THAT(subscriber.getSubscriptionState(), Eq(iox::SubscribeState::SUBSCRIBED)); } -TEST_F(PortManager_test, doDiscovery_singleShotSubscriberFirst) +TEST_F(PortManager_test, DoDiscoveryWithSingleShotSubscriberFirst) { PublisherOptions publisherOptions{1, "node", false}; SubscriberOptions subscriberOptions{1, 1, "node", false}; @@ -257,7 +257,7 @@ TEST_F(PortManager_test, doDiscovery_singleShotSubscriberFirst) EXPECT_THAT(subscriber.getSubscriptionState(), Eq(iox::SubscribeState::SUBSCRIBED)); } -TEST_F(PortManager_test, doDiscovery_singleShotSubscriberFirstWithDiscovery) +TEST_F(PortManager_test, DoDiscoveryWithDiscoveryLoopInBetweenCreationOfSubscriberAndPublisher) { PublisherOptions publisherOptions{1, "node", false}; SubscriberOptions subscriberOptions{1, 1, "node", false}; @@ -282,7 +282,7 @@ TEST_F(PortManager_test, doDiscovery_singleShotSubscriberFirstWithDiscovery) EXPECT_THAT(subscriber.getSubscriptionState(), Eq(iox::SubscribeState::SUBSCRIBED)); } -TEST_F(PortManager_test, doDiscovery_rightOrdering) +TEST_F(PortManager_test, DoDiscoveryWithSubscribersCreatedBeforeAndAfterCreationOfPublisher) { PublisherOptions publisherOptions{1, "node", false}; SubscriberOptions subscriberOptions{1, 1, "node", false}; @@ -314,7 +314,7 @@ TEST_F(PortManager_test, doDiscovery_rightOrdering) EXPECT_THAT(subscriber2.getSubscriptionState(), Eq(iox::SubscribeState::SUBSCRIBED)); } -TEST_F(PortManager_test, subscribeOnCreate_subscribesWithoutDiscoveryLoopWhenPublisherAvailable) +TEST_F(PortManager_test, SubscribeOnCreateSubscribesWithoutDiscoveryLoopWhenPublisherAvailable) { PublisherOptions publisherOptions{1, "node", false}; SubscriberOptions subscriberOptions{1, 1, "node", true}; @@ -333,7 +333,7 @@ TEST_F(PortManager_test, subscribeOnCreate_subscribesWithoutDiscoveryLoopWhenPub EXPECT_THAT(subscriber.getSubscriptionState(), Eq(iox::SubscribeState::SUBSCRIBED)); } -TEST_F(PortManager_test, offerOnCreate_subscribesWithoutDiscoveryLoopWhenSubscriberAvailable) +TEST_F(PortManager_test, OfferOnCreateSubscribesWithoutDiscoveryLoopWhenSubscriberAvailable) { PublisherOptions publisherOptions{1, "node", true}; SubscriberOptions subscriberOptions{1, 1, "node", false}; @@ -352,7 +352,7 @@ TEST_F(PortManager_test, offerOnCreate_subscribesWithoutDiscoveryLoopWhenSubscri EXPECT_THAT(subscriber.getSubscriptionState(), Eq(iox::SubscribeState::SUBSCRIBED)); } -TEST_F(PortManager_test, offerOnCreateAndSubscribeOnCreate_needsNoMoreDiscoveryLoopSubscriberFirst) +TEST_F(PortManager_test, OfferOnCreateAndSubscribeOnCreateNeedsNoMoreDiscoveryLoopSubscriberFirst) { PublisherOptions publisherOptions{1, "node", true}; SubscriberOptions subscriberOptions{1, 1, "node", true}; @@ -369,7 +369,7 @@ TEST_F(PortManager_test, offerOnCreateAndSubscribeOnCreate_needsNoMoreDiscoveryL EXPECT_THAT(subscriber.getSubscriptionState(), Eq(iox::SubscribeState::SUBSCRIBED)); } -TEST_F(PortManager_test, offerOnCreateAndSubscribeOnCreate_needsNoMoreDiscoveryLoopPublisherFirst) +TEST_F(PortManager_test, OfferOnCreateAndSubscribeOnCreateNeedsNoMoreDiscoveryLoopPublisherFirst) { PublisherOptions publisherOptions{1, "node", true}; SubscriberOptions subscriberOptions{1, 1, "node", true}; From e3b1dd2d54a1cbc62ba9c73c9144222f21de76ad Mon Sep 17 00:00:00 2001 From: Michael Poehnl Date: Tue, 2 Mar 2021 20:14:33 +0100 Subject: [PATCH 119/143] iox-#408 dedicated review findings Signed-off-by: Michael Poehnl --- .../moduletests/test_popo_subscriber_port.cpp | 58 ++++++------- .../test/moduletests/test_posh_runtime.cpp | 4 +- .../moduletests/test_roudi_portmanager.cpp | 82 +++++++++---------- 3 files changed, 72 insertions(+), 72 deletions(-) diff --git a/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp b/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp index d0fc312bc00..cc3f4392e24 100644 --- a/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_subscriber_port.cpp @@ -81,12 +81,12 @@ class SubscriberPortSingleProducer_test : public Test const iox::capro::ServiceDescription SubscriberPortSingleProducer_test::TEST_SERVICE_DESCRIPTION("x", "y", "z"); -TEST_F(SubscriberPortSingleProducer_test, initialStateNotSubscribed) +TEST_F(SubscriberPortSingleProducer_test, InitialStateNotSubscribed) { EXPECT_THAT(m_sutUserSideSingleProducer.getSubscriptionState(), Eq(iox::SubscribeState::NOT_SUBSCRIBED)); } -TEST_F(SubscriberPortSingleProducer_test, initialStateNoChunksAvailable) +TEST_F(SubscriberPortSingleProducer_test, InitialStateNoChunksAvailable) { auto maybeChunk = m_sutUserSideSingleProducer.tryGetChunk(); @@ -95,19 +95,19 @@ TEST_F(SubscriberPortSingleProducer_test, initialStateNoChunksAvailable) EXPECT_FALSE(m_sutUserSideSingleProducer.hasNewChunks()); } -TEST_F(SubscriberPortSingleProducer_test, initialStateNoChunksLost) +TEST_F(SubscriberPortSingleProducer_test, InitialStateNoChunksLost) { EXPECT_FALSE(m_sutUserSideSingleProducer.hasLostChunksSinceLastCall()); } -TEST_F(SubscriberPortSingleProducer_test, initialStateReturnsNoCaProMessageWhenNoSubOnCreate) +TEST_F(SubscriberPortSingleProducer_test, InitialStateReturnsNoCaProMessageWhenNoSubOnCreate) { auto maybeCaproMessage = m_sutRouDiSideSingleProducer.tryGetCaProMessage(); EXPECT_FALSE(maybeCaproMessage.has_value()); } -TEST_F(SubscriberPortSingleProducer_test, initialStateReturnsSubCaProMessageWithDefaultOptions) +TEST_F(SubscriberPortSingleProducer_test, InitialStateReturnsSubCaProMessageWithDefaultOptions) { auto maybeCaproMessage = m_sutRouDiSideDefaultOptions.tryGetCaProMessage(); @@ -116,7 +116,7 @@ TEST_F(SubscriberPortSingleProducer_test, initialStateReturnsSubCaProMessageWith EXPECT_THAT(caproMessage.m_type, Eq(iox::capro::CaproMessageType::SUB)); } -TEST_F(SubscriberPortSingleProducer_test, subscribeCallResultsInSubCaProMessage) +TEST_F(SubscriberPortSingleProducer_test, SubscribeCallResultsInSubCaProMessage) { m_sutUserSideSingleProducer.subscribe(); @@ -129,7 +129,7 @@ TEST_F(SubscriberPortSingleProducer_test, subscribeCallResultsInSubCaProMessage) EXPECT_THAT(caproMessage.m_historyCapacity, Eq(0u)); } -TEST_F(SubscriberPortSingleProducer_test, subscribeRequestedWhenCallingSubscribe) +TEST_F(SubscriberPortSingleProducer_test, SubscribeRequestedWhenCallingSubscribe) { m_sutUserSideSingleProducer.subscribe(); m_sutRouDiSideSingleProducer.tryGetCaProMessage(); // only RouDi changes state @@ -139,7 +139,7 @@ TEST_F(SubscriberPortSingleProducer_test, subscribeRequestedWhenCallingSubscribe EXPECT_THAT(subscriptionState, Eq(iox::SubscribeState::SUBSCRIBE_REQUESTED)); } -TEST_F(SubscriberPortSingleProducer_test, nackResponseOnSubResultsInWaitForOffer) +TEST_F(SubscriberPortSingleProducer_test, NackResponseOnSubResultsInWaitForOffer) { m_sutUserSideSingleProducer.subscribe(); m_sutRouDiSideSingleProducer.tryGetCaProMessage(); // only RouDi changes state @@ -152,7 +152,7 @@ TEST_F(SubscriberPortSingleProducer_test, nackResponseOnSubResultsInWaitForOffer EXPECT_THAT(subscriptionState, Eq(iox::SubscribeState::WAIT_FOR_OFFER)); } -TEST_F(SubscriberPortSingleProducer_test, ackResponseOnSubResultsInSubscribed) +TEST_F(SubscriberPortSingleProducer_test, AckResponseOnSubResultsInSubscribed) { m_sutUserSideSingleProducer.subscribe(); m_sutRouDiSideSingleProducer.tryGetCaProMessage(); // only RouDi changes state @@ -165,7 +165,7 @@ TEST_F(SubscriberPortSingleProducer_test, ackResponseOnSubResultsInSubscribed) EXPECT_THAT(subscriptionState, Eq(iox::SubscribeState::SUBSCRIBED)); } -TEST_F(SubscriberPortSingleProducer_test, offerInWaitForOfferTriggersSubMessage) +TEST_F(SubscriberPortSingleProducer_test, OfferInWaitForOfferTriggersSubMessage) { m_sutUserSideSingleProducer.subscribe(); m_sutRouDiSideSingleProducer.tryGetCaProMessage(); // only RouDi changes state @@ -184,7 +184,7 @@ TEST_F(SubscriberPortSingleProducer_test, offerInWaitForOfferTriggersSubMessage) EXPECT_THAT(caproMessageResponse.m_historyCapacity, Eq(0u)); } -TEST_F(SubscriberPortSingleProducer_test, offerInWaitForOfferResultsInSubscribeRequested) +TEST_F(SubscriberPortSingleProducer_test, OfferInWaitForOfferResultsInSubscribeRequested) { m_sutUserSideSingleProducer.subscribe(); m_sutRouDiSideSingleProducer.tryGetCaProMessage(); // only RouDi changes state @@ -199,7 +199,7 @@ TEST_F(SubscriberPortSingleProducer_test, offerInWaitForOfferResultsInSubscribeR EXPECT_THAT(subscriptionState, Eq(iox::SubscribeState::SUBSCRIBE_REQUESTED)); } -TEST_F(SubscriberPortSingleProducer_test, unsubscribeInWaitForOfferResultsInNotSubscribed) +TEST_F(SubscriberPortSingleProducer_test, UnsubscribeInWaitForOfferResultsInNotSubscribed) { m_sutUserSideSingleProducer.subscribe(); m_sutRouDiSideSingleProducer.tryGetCaProMessage(); // only RouDi changes state @@ -229,7 +229,7 @@ TEST_F(SubscriberPortSingleProducer_test, StopOfferInSubscribedResultsInWaitForO EXPECT_THAT(subscriptionState, Eq(iox::SubscribeState::WAIT_FOR_OFFER)); } -TEST_F(SubscriberPortSingleProducer_test, unsubscribeInSubscribedTriggersUnsubMessage) +TEST_F(SubscriberPortSingleProducer_test, UnsubscribeInSubscribedTriggersUnsubMessage) { m_sutUserSideSingleProducer.subscribe(); m_sutRouDiSideSingleProducer.tryGetCaProMessage(); // only RouDi changes state @@ -247,7 +247,7 @@ TEST_F(SubscriberPortSingleProducer_test, unsubscribeInSubscribedTriggersUnsubMe Eq(SubscriberPortSingleProducer_test::TEST_SERVICE_DESCRIPTION)); } -TEST_F(SubscriberPortSingleProducer_test, unsubscribeInSubscribedResultsInUnsubscribeRequested) +TEST_F(SubscriberPortSingleProducer_test, UnsubscribeInSubscribedResultsInUnsubscribeRequested) { m_sutUserSideSingleProducer.subscribe(); m_sutRouDiSideSingleProducer.tryGetCaProMessage(); // only RouDi changes state @@ -262,7 +262,7 @@ TEST_F(SubscriberPortSingleProducer_test, unsubscribeInSubscribedResultsInUnsubs EXPECT_THAT(subscriptionState, Eq(iox::SubscribeState::UNSUBSCRIBE_REQUESTED)); } -TEST_F(SubscriberPortSingleProducer_test, ackInUnsubscribeRequestedResultsInNotSubscribed) +TEST_F(SubscriberPortSingleProducer_test, AckInUnsubscribeRequestedResultsInNotSubscribed) { m_sutUserSideSingleProducer.subscribe(); m_sutRouDiSideSingleProducer.tryGetCaProMessage(); // only RouDi changes state @@ -278,7 +278,7 @@ TEST_F(SubscriberPortSingleProducer_test, ackInUnsubscribeRequestedResultsInNotS EXPECT_THAT(subscriptionState, Eq(iox::SubscribeState::NOT_SUBSCRIBED)); } -TEST_F(SubscriberPortSingleProducer_test, nackInUnsubscribeRequestedResultsInNotSubscribed) +TEST_F(SubscriberPortSingleProducer_test, NackInUnsubscribeRequestedResultsInNotSubscribed) { m_sutUserSideSingleProducer.subscribe(); m_sutRouDiSideSingleProducer.tryGetCaProMessage(); // only RouDi changes state @@ -295,7 +295,7 @@ TEST_F(SubscriberPortSingleProducer_test, nackInUnsubscribeRequestedResultsInNot EXPECT_THAT(subscriptionState, Eq(iox::SubscribeState::NOT_SUBSCRIBED)); } -TEST_F(SubscriberPortSingleProducer_test, invalidMessageResultsInError) +TEST_F(SubscriberPortSingleProducer_test, InvalidMessageResultsInError) { auto errorHandlerCalled{false}; auto errorHandlerGuard = iox::ErrorHandler::SetTemporaryErrorHandler( @@ -311,7 +311,7 @@ TEST_F(SubscriberPortSingleProducer_test, invalidMessageResultsInError) EXPECT_TRUE(errorHandlerCalled); } -TEST_F(SubscriberPortSingleProducer_test, ackWhenNotWaitingForResultsInError) +TEST_F(SubscriberPortSingleProducer_test, AckWhenNotWaitingForResultsInError) { auto errorHandlerCalled{false}; auto errorHandlerGuard = iox::ErrorHandler::SetTemporaryErrorHandler( @@ -327,7 +327,7 @@ TEST_F(SubscriberPortSingleProducer_test, ackWhenNotWaitingForResultsInError) EXPECT_TRUE(errorHandlerCalled); } -TEST_F(SubscriberPortSingleProducer_test, nackWhenNotWaitingForResultsInError) +TEST_F(SubscriberPortSingleProducer_test, NackWhenNotWaitingForResultsInError) { auto errorHandlerCalled{false}; iox::Error receivedError; @@ -377,12 +377,12 @@ class SubscriberPortMultiProducer_test : public Test iox::popo::SubscriberPortMultiProducer m_sutRouDiSideMultiProducer{&m_subscriberPortDataMultiProducer}; }; -TEST_F(SubscriberPortMultiProducer_test, initialStateNotSubscribed) +TEST_F(SubscriberPortMultiProducer_test, InitialStateNotSubscribed) { EXPECT_THAT(m_sutUserSideMultiProducer.getSubscriptionState(), Eq(iox::SubscribeState::NOT_SUBSCRIBED)); } -TEST_F(SubscriberPortMultiProducer_test, initialStateReturnsSubCaProMessageWithDefaultOptions) +TEST_F(SubscriberPortMultiProducer_test, InitialStateReturnsSubCaProMessageWithDefaultOptions) { auto maybeCaproMessage = m_sutRouDiSideMultiProducer.tryGetCaProMessage(); @@ -391,7 +391,7 @@ TEST_F(SubscriberPortMultiProducer_test, initialStateReturnsSubCaProMessageWithD EXPECT_THAT(caproMessage.m_type, Eq(iox::capro::CaproMessageType::SUB)); } -TEST_F(SubscriberPortMultiProducer_test, subscribeCallResultsInSubCaProMessage) +TEST_F(SubscriberPortMultiProducer_test, SubscribeCallResultsInSubCaProMessage) { m_sutUserSideMultiProducer.subscribe(); @@ -404,7 +404,7 @@ TEST_F(SubscriberPortMultiProducer_test, subscribeCallResultsInSubCaProMessage) EXPECT_THAT(caproMessage.m_historyCapacity, Eq(0u)); } -TEST_F(SubscriberPortMultiProducer_test, subscribedWhenCallingSubscribe) +TEST_F(SubscriberPortMultiProducer_test, SubscribedWhenCallingSubscribe) { m_sutUserSideMultiProducer.subscribe(); m_sutRouDiSideMultiProducer.tryGetCaProMessage(); // only RouDi changes state @@ -414,7 +414,7 @@ TEST_F(SubscriberPortMultiProducer_test, subscribedWhenCallingSubscribe) EXPECT_THAT(subscriptionState, Eq(iox::SubscribeState::SUBSCRIBED)); } -TEST_F(SubscriberPortMultiProducer_test, nackResponseOnSubStillSubscribed) +TEST_F(SubscriberPortMultiProducer_test, NackResponseOnSubStillSubscribed) { m_sutUserSideMultiProducer.subscribe(); m_sutRouDiSideMultiProducer.tryGetCaProMessage(); // only RouDi changes state @@ -427,7 +427,7 @@ TEST_F(SubscriberPortMultiProducer_test, nackResponseOnSubStillSubscribed) EXPECT_THAT(subscriptionState, Eq(iox::SubscribeState::SUBSCRIBED)); } -TEST_F(SubscriberPortMultiProducer_test, ackResponseOnSubStillSubscribed) +TEST_F(SubscriberPortMultiProducer_test, AckResponseOnSubStillSubscribed) { m_sutUserSideMultiProducer.subscribe(); m_sutRouDiSideMultiProducer.tryGetCaProMessage(); // only RouDi changes state @@ -440,7 +440,7 @@ TEST_F(SubscriberPortMultiProducer_test, ackResponseOnSubStillSubscribed) EXPECT_THAT(subscriptionState, Eq(iox::SubscribeState::SUBSCRIBED)); } -TEST_F(SubscriberPortMultiProducer_test, offerInSubscribedTriggersSubMessage) +TEST_F(SubscriberPortMultiProducer_test, OfferInSubscribedTriggersSubMessage) { m_sutUserSideMultiProducer.subscribe(); m_sutRouDiSideMultiProducer.tryGetCaProMessage(); // only RouDi changes state @@ -457,7 +457,7 @@ TEST_F(SubscriberPortMultiProducer_test, offerInSubscribedTriggersSubMessage) EXPECT_THAT(caproMessageResponse.m_historyCapacity, Eq(0u)); } -TEST_F(SubscriberPortMultiProducer_test, unsubscribeInSubscribedResultsInNotSubscribed) +TEST_F(SubscriberPortMultiProducer_test, UnsubscribeInSubscribedResultsInNotSubscribed) { m_sutUserSideMultiProducer.subscribe(); m_sutRouDiSideMultiProducer.tryGetCaProMessage(); // only RouDi changes state @@ -484,7 +484,7 @@ TEST_F(SubscriberPortMultiProducer_test, StopOfferInSubscribedRemainsInSubscribe EXPECT_THAT(subscriptionState, Eq(iox::SubscribeState::SUBSCRIBED)); } -TEST_F(SubscriberPortMultiProducer_test, unsubscribeInSubscribedTriggersUnsubMessage) +TEST_F(SubscriberPortMultiProducer_test, UnsubscribeInSubscribedTriggersUnsubMessage) { m_sutUserSideMultiProducer.subscribe(); m_sutRouDiSideMultiProducer.tryGetCaProMessage(); // only RouDi changes state @@ -502,7 +502,7 @@ TEST_F(SubscriberPortMultiProducer_test, unsubscribeInSubscribedTriggersUnsubMes Eq(SubscriberPortSingleProducer_test::TEST_SERVICE_DESCRIPTION)); } -TEST_F(SubscriberPortMultiProducer_test, invalidMessageResultsInError) +TEST_F(SubscriberPortMultiProducer_test, InvalidMessageResultsInError) { auto errorHandlerCalled{false}; iox::Error receivedError; diff --git a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp index 28cbee32228..8eea3493d4b 100644 --- a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp +++ b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp @@ -356,7 +356,7 @@ TEST_F(PoshRuntime_test, GetMiddlewarePublisherWithSameServiceDescriptionsAndOne } } -TEST_F(PoshRuntime_test, GetMiddlewarePublisherWithoutOfferOnCreateLeadsToNotOfferedSubscriberBeingCreated) +TEST_F(PoshRuntime_test, GetMiddlewarePublisherWithoutOfferOnCreateLeadsToNotOfferedPublisherBeingCreated) { iox::popo::PublisherOptions publisherOptions; publisherOptions.offerOnCreate = false; @@ -367,7 +367,7 @@ TEST_F(PoshRuntime_test, GetMiddlewarePublisherWithoutOfferOnCreateLeadsToNotOff EXPECT_FALSE(publisherPortData->m_offeringRequested); } -TEST_F(PoshRuntime_test, GetMiddlewarePublisherWithOfferOnCreateLeadsToOfferedSubscriberBeingCreated) +TEST_F(PoshRuntime_test, GetMiddlewarePublisherWithOfferOnCreateLeadsToOfferedPublisherBeingCreated) { iox::popo::PublisherOptions publisherOptions; publisherOptions.offerOnCreate = true; diff --git a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp index 85551a67117..414095f1d6b 100644 --- a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp +++ b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp @@ -70,7 +70,7 @@ class PortManager_test : public Test void SetUp() override { testing::internal::CaptureStderr(); - m_instIdCounter = m_sIdCounter = 1; + m_instIdCounter = m_sIdCounter = 1U; m_eventIdCounter = 0; // starting at {1,1,1} @@ -108,11 +108,11 @@ class PortManager_test : public Test m_eventIdCounter++; if (m_eventIdCounter == std::numeric_limits::max()) { - m_eventIdCounter = 1; + m_eventIdCounter = 1U; m_instIdCounter++; // not using max (wildcard) if (m_instIdCounter == std::numeric_limits::max()) { - m_instIdCounter = 1; + m_instIdCounter = 1U; m_sIdCounter++; if (m_sIdCounter == std::numeric_limits::max()) { @@ -209,20 +209,20 @@ void setDestroyFlagAndClearContainer(vector& container) TEST_F(PortManager_test, DoDiscoveryWithSingleShotPublisherFirst) { - PublisherOptions publisherOptions{1, "node", false}; - SubscriberOptions subscriberOptions{1, 1, "node", false}; + PublisherOptions publisherOptions{1U, "node", false}; + SubscriberOptions subscriberOptions{1U, 1U, "node", false}; PublisherPortUser publisher( m_portManager ->acquirePublisherPortData( - {1, 1, 1}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) + {1U, 1U, 1U}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) .value()); ASSERT_TRUE(publisher); publisher.offer(); // no doDiscovery() at this position is intentional SubscriberPortUser subscriber( - m_portManager->acquireSubscriberPortData({1, 1, 1}, subscriberOptions, "schlomo", PortConfigInfo()).value()); + m_portManager->acquireSubscriberPortData({1U, 1U, 1U}, subscriberOptions, "schlomo", PortConfigInfo()).value()); ASSERT_TRUE(subscriber); subscriber.subscribe(); @@ -234,11 +234,11 @@ TEST_F(PortManager_test, DoDiscoveryWithSingleShotPublisherFirst) TEST_F(PortManager_test, DoDiscoveryWithSingleShotSubscriberFirst) { - PublisherOptions publisherOptions{1, "node", false}; - SubscriberOptions subscriberOptions{1, 1, "node", false}; + PublisherOptions publisherOptions{1U, "node", false}; + SubscriberOptions subscriberOptions{1U, 1U, "node", false}; SubscriberPortUser subscriber( - m_portManager->acquireSubscriberPortData({1, 1, 1}, subscriberOptions, "schlomo", PortConfigInfo()).value()); + m_portManager->acquireSubscriberPortData({1U, 1U, 1U}, subscriberOptions, "schlomo", PortConfigInfo()).value()); ASSERT_TRUE(subscriber); subscriber.subscribe(); // no doDiscovery() at this position is intentional @@ -246,7 +246,7 @@ TEST_F(PortManager_test, DoDiscoveryWithSingleShotSubscriberFirst) PublisherPortUser publisher( m_portManager ->acquirePublisherPortData( - {1, 1, 1}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) + {1U, 1U, 1U}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) .value()); ASSERT_TRUE(publisher); publisher.offer(); @@ -259,11 +259,11 @@ TEST_F(PortManager_test, DoDiscoveryWithSingleShotSubscriberFirst) TEST_F(PortManager_test, DoDiscoveryWithDiscoveryLoopInBetweenCreationOfSubscriberAndPublisher) { - PublisherOptions publisherOptions{1, "node", false}; - SubscriberOptions subscriberOptions{1, 1, "node", false}; + PublisherOptions publisherOptions{1U, "node", false}; + SubscriberOptions subscriberOptions{1U, 1U, "node", false}; SubscriberPortUser subscriber( - m_portManager->acquireSubscriberPortData({1, 1, 1}, subscriberOptions, "schlomo", PortConfigInfo()).value()); + m_portManager->acquireSubscriberPortData({1U, 1U, 1U}, subscriberOptions, "schlomo", PortConfigInfo()).value()); ASSERT_TRUE(subscriber); subscriber.subscribe(); m_portManager->doDiscovery(); @@ -271,7 +271,7 @@ TEST_F(PortManager_test, DoDiscoveryWithDiscoveryLoopInBetweenCreationOfSubscrib PublisherPortUser publisher( m_portManager ->acquirePublisherPortData( - {1, 1, 1}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) + {1U, 1U, 1U}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) .value()); ASSERT_TRUE(publisher); publisher.offer(); @@ -284,11 +284,11 @@ TEST_F(PortManager_test, DoDiscoveryWithDiscoveryLoopInBetweenCreationOfSubscrib TEST_F(PortManager_test, DoDiscoveryWithSubscribersCreatedBeforeAndAfterCreationOfPublisher) { - PublisherOptions publisherOptions{1, "node", false}; - SubscriberOptions subscriberOptions{1, 1, "node", false}; + PublisherOptions publisherOptions{1U, "node", false}; + SubscriberOptions subscriberOptions{1U, 1U, "node", false}; SubscriberPortUser subscriber1( - m_portManager->acquireSubscriberPortData({1, 1, 1}, subscriberOptions, "schlomo", PortConfigInfo()).value()); + m_portManager->acquireSubscriberPortData({1U, 1U, 1U}, subscriberOptions, "schlomo", PortConfigInfo()).value()); ASSERT_TRUE(subscriber1); subscriber1.subscribe(); @@ -297,13 +297,13 @@ TEST_F(PortManager_test, DoDiscoveryWithSubscribersCreatedBeforeAndAfterCreation PublisherPortUser publisher( m_portManager ->acquirePublisherPortData( - {1, 1, 1}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) + {1U, 1U, 1U}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) .value()); ASSERT_TRUE(publisher); publisher.offer(); SubscriberPortUser subscriber2( - m_portManager->acquireSubscriberPortData({1, 1, 1}, subscriberOptions, "ingnatz", PortConfigInfo()).value()); + m_portManager->acquireSubscriberPortData({1U, 1U, 1U}, subscriberOptions, "ingnatz", PortConfigInfo()).value()); ASSERT_TRUE(subscriber2); subscriber2.subscribe(); @@ -316,18 +316,18 @@ TEST_F(PortManager_test, DoDiscoveryWithSubscribersCreatedBeforeAndAfterCreation TEST_F(PortManager_test, SubscribeOnCreateSubscribesWithoutDiscoveryLoopWhenPublisherAvailable) { - PublisherOptions publisherOptions{1, "node", false}; - SubscriberOptions subscriberOptions{1, 1, "node", true}; + PublisherOptions publisherOptions{1U, "node", false}; + SubscriberOptions subscriberOptions{1U, 1U, "node", true}; PublisherPortUser publisher( m_portManager ->acquirePublisherPortData( - {1, 1, 1}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) + {1U, 1U, 1U}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) .value()); publisher.offer(); m_portManager->doDiscovery(); SubscriberPortUser subscriber( - m_portManager->acquireSubscriberPortData({1, 1, 1}, subscriberOptions, "schlomo", PortConfigInfo()).value()); + m_portManager->acquireSubscriberPortData({1U, 1U, 1U}, subscriberOptions, "schlomo", PortConfigInfo()).value()); ASSERT_TRUE(publisher.hasSubscribers()); EXPECT_THAT(subscriber.getSubscriptionState(), Eq(iox::SubscribeState::SUBSCRIBED)); @@ -335,17 +335,17 @@ TEST_F(PortManager_test, SubscribeOnCreateSubscribesWithoutDiscoveryLoopWhenPubl TEST_F(PortManager_test, OfferOnCreateSubscribesWithoutDiscoveryLoopWhenSubscriberAvailable) { - PublisherOptions publisherOptions{1, "node", true}; - SubscriberOptions subscriberOptions{1, 1, "node", false}; + PublisherOptions publisherOptions{1U, "node", true}; + SubscriberOptions subscriberOptions{1U, 1U, "node", false}; SubscriberPortUser subscriber( - m_portManager->acquireSubscriberPortData({1, 1, 1}, subscriberOptions, "schlomo", PortConfigInfo()).value()); + m_portManager->acquireSubscriberPortData({1U, 1U, 1U}, subscriberOptions, "schlomo", PortConfigInfo()).value()); subscriber.subscribe(); m_portManager->doDiscovery(); PublisherPortUser publisher( m_portManager ->acquirePublisherPortData( - {1, 1, 1}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) + {1U, 1U, 1U}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) .value()); ASSERT_TRUE(publisher.hasSubscribers()); @@ -354,15 +354,15 @@ TEST_F(PortManager_test, OfferOnCreateSubscribesWithoutDiscoveryLoopWhenSubscrib TEST_F(PortManager_test, OfferOnCreateAndSubscribeOnCreateNeedsNoMoreDiscoveryLoopSubscriberFirst) { - PublisherOptions publisherOptions{1, "node", true}; - SubscriberOptions subscriberOptions{1, 1, "node", true}; + PublisherOptions publisherOptions{1U, "node", true}; + SubscriberOptions subscriberOptions{1U, 1U, "node", true}; SubscriberPortUser subscriber( - m_portManager->acquireSubscriberPortData({1, 1, 1}, subscriberOptions, "schlomo", PortConfigInfo()).value()); + m_portManager->acquireSubscriberPortData({1U, 1U, 1U}, subscriberOptions, "schlomo", PortConfigInfo()).value()); PublisherPortUser publisher( m_portManager ->acquirePublisherPortData( - {1, 1, 1}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) + {1U, 1U, 1U}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) .value()); ASSERT_TRUE(publisher.hasSubscribers()); @@ -371,16 +371,16 @@ TEST_F(PortManager_test, OfferOnCreateAndSubscribeOnCreateNeedsNoMoreDiscoveryLo TEST_F(PortManager_test, OfferOnCreateAndSubscribeOnCreateNeedsNoMoreDiscoveryLoopPublisherFirst) { - PublisherOptions publisherOptions{1, "node", true}; - SubscriberOptions subscriberOptions{1, 1, "node", true}; + PublisherOptions publisherOptions{1U, "node", true}; + SubscriberOptions subscriberOptions{1U, 1U, "node", true}; PublisherPortUser publisher( m_portManager ->acquirePublisherPortData( - {1, 1, 1}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) + {1U, 1U, 1U}, publisherOptions, "guiseppe", m_payloadMemoryManager, PortConfigInfo()) .value()); SubscriberPortUser subscriber( - m_portManager->acquireSubscriberPortData({1, 1, 1}, subscriberOptions, "schlomo", PortConfigInfo()).value()); + m_portManager->acquireSubscriberPortData({1U, 1U, 1U}, subscriberOptions, "schlomo", PortConfigInfo()).value()); ASSERT_TRUE(publisher.hasSubscribers()); @@ -391,7 +391,7 @@ TEST_F(PortManager_test, OfferOnCreateAndSubscribeOnCreateNeedsNoMoreDiscoveryLo TEST_F(PortManager_test, AcquiringOneMoreThanMaximumNumberOfPublishersFails) { iox::ProcessName_t processName = "test1"; - PublisherOptions publisherOptions{1, "run1"}; + PublisherOptions publisherOptions{1U, "run1"}; for (unsigned int i = 0; i < iox::MAX_PUBLISHERS; i++) { @@ -420,7 +420,7 @@ TEST_F(PortManager_test, AcquiringOneMoreThanMaximumNumberOfPublishersFails) TEST_F(PortManager_test, AcquiringOneMoreThanMaximumNumberOfSubscribersFails) { iox::ProcessName_t processName1 = "test1"; - SubscriberOptions subscriberOptions{1, 1, "run1"}; + SubscriberOptions subscriberOptions{1U, 1U, "run1"}; for (unsigned int i = 0; i < iox::MAX_SUBSCRIBERS; i++) { @@ -697,8 +697,8 @@ TEST_F(PortManager_test, PortsDestroyInProcess2ChangeStatesOfPortsInProcess1) iox::ProcessName_t processName2 = "myProcess2"; iox::capro::ServiceDescription cap1(1, 1, 1); iox::capro::ServiceDescription cap2(2, 2, 2); - PublisherOptions publisherOptions{1, "node", false}; - SubscriberOptions subscriberOptions{1, 1, "node", false}; + PublisherOptions publisherOptions{1U, "node", false}; + SubscriberOptions subscriberOptions{1U, 1U, "node", false}; // two processes process1 and process2 each with a publisher and subscriber that match to the other process auto publisherData1 = @@ -817,7 +817,7 @@ TEST_F(PortManager_test, OfferPublisherServiceUpdatesServiceRegistryChangeCounte PublisherOptions publisherOptions{1}; auto publisherPortData = m_portManager->acquirePublisherPortData( - {1, 1, 1}, publisherOptions, m_ProcessName, m_payloadMemoryManager, PortConfigInfo()); + {1U, 1U, 1U}, publisherOptions, m_ProcessName, m_payloadMemoryManager, PortConfigInfo()); ASSERT_FALSE(publisherPortData.has_error()); PublisherPortUser publisher(publisherPortData.value()); From c4ce52b8fa0f83515cd7278fcef846870d0dccd1 Mon Sep 17 00:00:00 2001 From: Michael Poehnl Date: Thu, 4 Mar 2021 10:22:22 +0100 Subject: [PATCH 120/143] iox-#408 additional capacity check for posh_runtime GetMiddlewareSubscriber Signed-off-by: Michael Poehnl --- iceoryx_posh/source/runtime/posh_runtime.cpp | 6 ++++++ iceoryx_posh/test/moduletests/test_posh_runtime.cpp | 11 +++++++++++ 2 files changed, 17 insertions(+) diff --git a/iceoryx_posh/source/runtime/posh_runtime.cpp b/iceoryx_posh/source/runtime/posh_runtime.cpp index 74b2ed3c158..87e2b26739f 100644 --- a/iceoryx_posh/source/runtime/posh_runtime.cpp +++ b/iceoryx_posh/source/runtime/posh_runtime.cpp @@ -262,6 +262,12 @@ PoshRuntime::getMiddlewareSubscriber(const capro::ServiceDescription& service, << ", limiting from " << subscriberOptions.queueCapacity << " to " << MAX_QUEUE_CAPACITY; options.queueCapacity = MAX_QUEUE_CAPACITY; } + else if (0U == options.queueCapacity) + { + LogWarn() << "Requested queue capacity of 0 doesn't make sense as no data would be received," + << " the capacyity is set to 1"; + options.queueCapacity = 1U; + } if (options.nodeName.empty()) { diff --git a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp index 8eea3493d4b..d2cb891e105 100644 --- a/iceoryx_posh/test/moduletests/test_posh_runtime.cpp +++ b/iceoryx_posh/test/moduletests/test_posh_runtime.cpp @@ -406,6 +406,17 @@ TEST_F(PoshRuntime_test, GetMiddlewareSubscriberWithQueueGreaterMaxCapacityClamp EXPECT_EQ(MAX_QUEUE_CAPACITY, subscriberPort->m_chunkReceiverData.m_queue.capacity()); } +TEST_F(PoshRuntime_test, GetMiddlewareSubscriberWithQueueCapacityZeroClampsQueueCapacityTo1) +{ + iox::popo::SubscriberOptions subscriberOptions; + subscriberOptions.queueCapacity = 0U; + + auto subscriberPort = m_runtime->getMiddlewareSubscriber( + iox::capro::ServiceDescription(34U, 4U, 4U), subscriberOptions, iox::runtime::PortConfigInfo(11U, 22U, 33U)); + + EXPECT_EQ(1U, subscriberPort->m_chunkReceiverData.m_queue.capacity()); +} + TEST_F(PoshRuntime_test, GetMiddlewareSubscriberDefaultArgs) { auto subscriberPort = m_runtime->getMiddlewareSubscriber(iox::capro::ServiceDescription(99U, 1U, 20U)); From c175901b2721227492979c7e232175a0bde684be Mon Sep 17 00:00:00 2001 From: Michael Poehnl Date: Thu, 4 Mar 2021 12:36:17 +0100 Subject: [PATCH 121/143] iox-#408 typo Signed-off-by: Michael Poehnl --- iceoryx_posh/source/runtime/posh_runtime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iceoryx_posh/source/runtime/posh_runtime.cpp b/iceoryx_posh/source/runtime/posh_runtime.cpp index 87e2b26739f..ca1c58877b6 100644 --- a/iceoryx_posh/source/runtime/posh_runtime.cpp +++ b/iceoryx_posh/source/runtime/posh_runtime.cpp @@ -265,7 +265,7 @@ PoshRuntime::getMiddlewareSubscriber(const capro::ServiceDescription& service, else if (0U == options.queueCapacity) { LogWarn() << "Requested queue capacity of 0 doesn't make sense as no data would be received," - << " the capacyity is set to 1"; + << " the capacity is set to 1"; options.queueCapacity = 1U; } From e0a0d9a5550c16b8febc8d17da3ab2e3920e9b31 Mon Sep 17 00:00:00 2001 From: Michael Poehnl Date: Thu, 4 Mar 2021 20:23:50 +0100 Subject: [PATCH 122/143] iox-#408 offerOnCreate and SubscribeOnCreate for C API Signed-off-by: Michael Poehnl --- .../include/iceoryx_binding_c/publisher.h | 3 +++ .../include/iceoryx_binding_c/subscriber.h | 3 +++ iceoryx_binding_c/source/c_publisher.cpp | 2 ++ iceoryx_binding_c/source/c_subscriber.cpp | 2 ++ .../test/moduletests/test_publisher.cpp | 10 +++++-- .../test/moduletests/test_subscriber.cpp | 4 +++ iceoryx_examples/icedelivery_in_c/README.md | 27 +++---------------- .../icedelivery_in_c/ice_c_publisher.c | 3 --- .../icedelivery_in_c/ice_c_subscriber.c | 2 -- iceoryx_examples/waitset_in_c/README.md | 8 ------ .../waitset_in_c/ice_c_waitset_gateway.c | 2 -- .../waitset_in_c/ice_c_waitset_grouping.c | 3 --- .../waitset_in_c/ice_c_waitset_individual.c | 4 --- .../waitset_in_c/ice_c_waitset_publisher.c | 3 --- 14 files changed, 26 insertions(+), 50 deletions(-) diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h index dc2155c79c7..e35ec594c43 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/publisher.h @@ -35,6 +35,9 @@ typedef struct // nullptr indicates that the default node name is used const char* nodeName; + // The option whether the publisher should already be offered when creating it + bool offerOnCreate; + // this value will be set exclusively by iox_pub_options_init // and is not supposed to be modified otherwise uint64_t initCheck; diff --git a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h index 321e969e09f..81948f2f000 100644 --- a/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h +++ b/iceoryx_binding_c/include/iceoryx_binding_c/subscriber.h @@ -38,6 +38,9 @@ typedef struct // name of the node the subscriber belongs to const char* nodeName; + // The option whether the subscriber shall try to subscribe when creating it + bool subscribeOnCreate; + // this value will be set exclusively by iox_sub_options_init // and is not supposed to be modified otherwise uint64_t initCheck; diff --git a/iceoryx_binding_c/source/c_publisher.cpp b/iceoryx_binding_c/source/c_publisher.cpp index 458565b4538..d68029e3e73 100644 --- a/iceoryx_binding_c/source/c_publisher.cpp +++ b/iceoryx_binding_c/source/c_publisher.cpp @@ -44,6 +44,7 @@ void iox_pub_options_init(iox_pub_options_t* options) PublisherOptions publisherOptions; options->historyCapacity = publisherOptions.historyCapacity; options->nodeName = nullptr; + options->offerOnCreate = publisherOptions.offerOnCreate; options->initCheck = PUBLISHER_OPTIONS_INIT_CHECK_CONSTANT; } @@ -78,6 +79,7 @@ iox_pub_t iox_pub_init(iox_pub_storage_t* self, { publisherOptions.nodeName = NodeName_t(TruncateToCapacity, options->nodeName); } + publisherOptions.offerOnCreate = options->offerOnCreate; } me->m_portData = PoshRuntime::getInstance().getMiddlewarePublisher( diff --git a/iceoryx_binding_c/source/c_subscriber.cpp b/iceoryx_binding_c/source/c_subscriber.cpp index 0a83d044ae5..6618ffddb2c 100644 --- a/iceoryx_binding_c/source/c_subscriber.cpp +++ b/iceoryx_binding_c/source/c_subscriber.cpp @@ -50,6 +50,7 @@ void iox_sub_options_init(iox_sub_options_t* options) options->queueCapacity = subscriberOptions.queueCapacity; options->historyRequest = subscriberOptions.historyRequest; options->nodeName = nullptr; + options->subscribeOnCreate = subscriberOptions.subscribeOnCreate; options->initCheck = SUBSCRIBER_OPTIONS_INIT_CHECK_CONSTANT; } @@ -85,6 +86,7 @@ iox_sub_t iox_sub_init(iox_sub_storage_t* self, { subscriberOptions.nodeName = NodeName_t(TruncateToCapacity, options->nodeName); } + subscriberOptions.subscribeOnCreate = options->subscribeOnCreate; } me->m_portData = diff --git a/iceoryx_binding_c/test/moduletests/test_publisher.cpp b/iceoryx_binding_c/test/moduletests/test_publisher.cpp index 344f13a2715..b25853f9f5c 100644 --- a/iceoryx_binding_c/test/moduletests/test_publisher.cpp +++ b/iceoryx_binding_c/test/moduletests/test_publisher.cpp @@ -118,9 +118,11 @@ class iox_pub_test : public Test cpp2c_Publisher m_sut; }; -TEST_F(iox_pub_test, initialStateIsOffered) +TEST_F(iox_pub_test, initialStateOfIsOfferedIsAsExpected) { - EXPECT_TRUE(iox_pub_is_offered(&m_sut)); + PublisherOptions iGotOptions; + auto expectedIsOffered = iGotOptions.offerOnCreate; + EXPECT_EQ(expectedIsOffered, iox_pub_is_offered(&m_sut)); } TEST_F(iox_pub_test, is_offeredAfterOffer) @@ -259,12 +261,16 @@ TEST(iox_pub_options_test, publisherOptionsAreInitializedCorrectly) iox_pub_options_t sut; sut.historyCapacity = 37; sut.nodeName = "Dr.Gonzo"; + sut.offerOnCreate = false; PublisherOptions options; + // set offerOnCreate to the opposite of the expected default to check if it gets overwritten to default + sut.offerOnCreate = (options.offerOnCreate == false) ? true : false; iox_pub_options_init(&sut); EXPECT_EQ(sut.historyCapacity, options.historyCapacity); EXPECT_EQ(sut.nodeName, nullptr); + EXPECT_EQ(sut.offerOnCreate, options.offerOnCreate); EXPECT_TRUE(iox_pub_options_is_initialized(&sut)); } diff --git a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp index 904c92a3097..68d15fbd58f 100644 --- a/iceoryx_binding_c/test/moduletests/test_subscriber.cpp +++ b/iceoryx_binding_c/test/moduletests/test_subscriber.cpp @@ -346,13 +346,17 @@ TEST(iox_sub_options_test, subscriberOptionsAreInitializedCorrectly) sut.queueCapacity = 37; sut.historyRequest = 73; sut.nodeName = "Dr.Gonzo"; + sut.subscribeOnCreate = false; SubscriberOptions options; + // set subscribeOnCreate to the opposite of the expected default to check if it gets overwritten to default + sut.subscribeOnCreate = (options.subscribeOnCreate == false) ? true : false; iox_sub_options_init(&sut); EXPECT_EQ(sut.queueCapacity, options.queueCapacity); EXPECT_EQ(sut.historyRequest, options.historyRequest); EXPECT_EQ(sut.nodeName, nullptr); + EXPECT_EQ(sut.subscribeOnCreate, options.subscribeOnCreate); EXPECT_TRUE(iox_sub_options_is_initialized(&sut)); } diff --git a/iceoryx_examples/icedelivery_in_c/README.md b/iceoryx_examples/icedelivery_in_c/README.md index 228e4e1491e..e820e9fa55b 100644 --- a/iceoryx_examples/icedelivery_in_c/README.md +++ b/iceoryx_examples/icedelivery_in_c/README.md @@ -56,12 +56,7 @@ Let's take a look at the `receiving` function which comes with the iox_sub_t subscriber = iox_sub_init(&subscriberStorage, "Radar", "FrontLeft", "Object", &options); ``` - 3. We subscribe to the service. - ```c - iox_sub_subscribe(subscriber); - ``` - - 4. In this loop we receive samples as long the `killswitch` is not + 3. In this loop we receive samples as long the `killswitch` is not set to `true` by an external signal and then print the counter value to the console. ```c @@ -85,13 +80,8 @@ Let's take a look at the `receiving` function which comes with the sleep_for(1000); } ``` - - 5. After we stop receiving samples we would like to unsubscribe. - ```c - iox_sub_unsubscribe(subscriber); - ``` - 6. When using the C API we have to cleanup the subscriber after + 4. When using the C API we have to cleanup the subscriber after its usage. ```c iox_sub_deinit(subscriber); @@ -126,12 +116,8 @@ Let's take a look at the `sending` function which comes with the iox_pub_storage_t publisherStorage; iox_pub_t publisher = iox_pub_init(&publisherStorage, "Radar", "FrontLeft", "Object", &options); ``` - 3. We offer our service to the world. - ```c - iox_pub_offer(publisher); - ``` - 4. Till an external signal sets `killswitch` to `true` we will send an + 3. Till an external signal sets `killswitch` to `true` we will send an incrementing number to all subscribers every send and print the value of this number to the console. ```c @@ -163,12 +149,7 @@ Let's take a look at the `sending` function which comes with the } ``` - 5. We stop offering our service. - ```c - iox_pub_stop_offer(publisher); - ``` - - 6. And we cleanup our publisher port. + 5. And we cleanup our publisher port. ```c iox_pub_destroy(publisher); ``` diff --git a/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c b/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c index 2c10b9887dd..ad08ea0e87c 100644 --- a/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c +++ b/iceoryx_examples/icedelivery_in_c/ice_c_publisher.c @@ -44,8 +44,6 @@ void sending() iox_pub_storage_t publisherStorage; iox_pub_t publisher = iox_pub_init(&publisherStorage, "Radar", "FrontLeft", "Object", &options); - iox_pub_offer(publisher); - double ct = 0.0; while (!killswitch) @@ -73,7 +71,6 @@ void sending() } } - iox_pub_stop_offer(publisher); iox_pub_deinit(publisher); } diff --git a/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c b/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c index cd774c5fa86..f8dfad8d569 100644 --- a/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c +++ b/iceoryx_examples/icedelivery_in_c/ice_c_subscriber.c @@ -50,7 +50,6 @@ void receiving() iox_sub_t subscriber = iox_sub_init(&subscriberStorage, "Radar", "FrontLeft", "Object", &options); - iox_sub_subscribe(subscriber); while (!killswitch) { @@ -75,7 +74,6 @@ void receiving() sleep_for(1000); } - iox_sub_unsubscribe(subscriber); iox_sub_deinit(subscriber); } diff --git a/iceoryx_examples/waitset_in_c/README.md b/iceoryx_examples/waitset_in_c/README.md index 1fb1e7e18ba..2bb9378c89b 100644 --- a/iceoryx_examples/waitset_in_c/README.md +++ b/iceoryx_examples/waitset_in_c/README.md @@ -67,7 +67,6 @@ for (uint64_t i = 0U; i < NUMBER_OF_SUBSCRIBERS; ++i) { iox_sub_t subscriber = iox_sub_init(&(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", &options); - iox_sub_subscribe(subscriber); iox_ws_attach_subscriber_event(waitSet, subscriber, SubscriberEvent_HAS_DATA, 1U, subscriberCallback); } ``` @@ -113,7 +112,6 @@ Before we can close the program we cleanup all resources. ```c for (uint64_t i = 0U; i < NUMBER_OF_SUBSCRIBERS; ++i) { - iox_sub_unsubscribe((iox_sub_t) & (subscriberStorage[i])); iox_sub_deinit((iox_sub_t) & (subscriberStorage[i])); } @@ -152,7 +150,6 @@ for (uint64_t i = 0U; i < NUMBER_OF_SUBSCRIBERS; ++i) { subscriber[i] = iox_sub_init(&(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", &options); - iox_sub_subscribe(subscriber[i]); } ``` @@ -227,7 +224,6 @@ The last thing we have to do is to cleanup all the acquired resources. ```c for (uint64_t i = 0U; i < NUMBER_OF_SUBSCRIBERS; ++i) { - iox_sub_unsubscribe((iox_sub_t) & (subscriberStorage[i])); iox_sub_deinit((iox_sub_t) & (subscriberStorage[i])); } @@ -266,9 +262,6 @@ subscriber[0] = iox_sub_init(&(subscriberStorage[0]), "Radar", "FrontLeft", "Cou options.nodeName = "iox-c-ex-waitset-individual-node2"; subscriber[1] = iox_sub_init(&(subscriberStorage[1]), "Radar", "FrontLeft", "Counter", &options); -iox_sub_subscribe(subscriber[0]); -iox_sub_subscribe(subscriber[1]); - iox_ws_attach_subscriber_event(waitSet, subscriber[0U], SubscriberEvent_HAS_DATA, 0U, NULL); iox_ws_attach_subscriber_event(waitSet, subscriber[1U], SubscriberEvent_HAS_DATA, 0U, NULL); ``` @@ -319,7 +312,6 @@ We conclude the example as always, be cleaning up the resources. ```c for (uint64_t i = 0U; i < NUMBER_OF_SUBSCRIBERS; ++i) { - iox_sub_unsubscribe((iox_sub_t) & (subscriberStorage[i])); iox_sub_deinit((iox_sub_t) & (subscriberStorage[i])); } diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c index 697c5a3c451..208540ea9a7 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_gateway.c @@ -86,7 +86,6 @@ int main() iox_sub_t subscriber = iox_sub_init( &(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", &options); - iox_sub_subscribe(subscriber); iox_ws_attach_subscriber_event(waitSet, subscriber, SubscriberEvent_HAS_DATA, 1U, subscriberCallback); } @@ -123,7 +122,6 @@ int main() // cleanup all resources for (uint64_t i = 0U; i < NUMBER_OF_SUBSCRIBERS; ++i) { - iox_sub_unsubscribe((iox_sub_t) & (subscriberStorage[i])); iox_sub_deinit((iox_sub_t) & (subscriberStorage[i])); } diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c index 2400fda6eec..aefee06a29d 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_grouping.c @@ -70,8 +70,6 @@ int main() { subscriber[i] = iox_sub_init( &(subscriberStorage[i]), "Radar", "FrontLeft", "Counter", &options); - - iox_sub_subscribe(subscriber[i]); } const uint64_t FIRST_GROUP_ID = 123U; @@ -139,7 +137,6 @@ int main() // cleanup all resources for (uint64_t i = 0U; i < NUMBER_OF_SUBSCRIBERS; ++i) { - iox_sub_unsubscribe((iox_sub_t) & (subscriberStorage[i])); iox_sub_deinit((iox_sub_t) & (subscriberStorage[i])); } diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c index 47211e2afe6..6de6edfe845 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_individual.c @@ -74,9 +74,6 @@ int main() subscriber[1] = iox_sub_init( &(subscriberStorage[1]), "Radar", "FrontLeft", "Counter", &options); - iox_sub_subscribe(subscriber[0]); - iox_sub_subscribe(subscriber[1]); - iox_ws_attach_subscriber_event(waitSet, subscriber[0U], SubscriberEvent_HAS_DATA, 0U, NULL); iox_ws_attach_subscriber_event(waitSet, subscriber[1U], SubscriberEvent_HAS_DATA, 0U, NULL); @@ -128,7 +125,6 @@ int main() // cleanup all resources for (uint64_t i = 0U; i < NUMBER_OF_SUBSCRIBERS; ++i) { - iox_sub_unsubscribe((iox_sub_t) & (subscriberStorage[i])); iox_sub_deinit((iox_sub_t) & (subscriberStorage[i])); } diff --git a/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c b/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c index d766651624f..a738c3171ad 100644 --- a/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c +++ b/iceoryx_examples/waitset_in_c/ice_c_waitset_publisher.c @@ -44,8 +44,6 @@ void sending() iox_pub_storage_t publisherStorage; iox_pub_t publisher = iox_pub_init(&publisherStorage, "Radar", "FrontLeft", "Counter", &options); - iox_pub_offer(publisher); - for (uint32_t counter = 0U; !killswitch; ++counter) { void* chunk = NULL; @@ -66,7 +64,6 @@ void sending() } } - iox_pub_stop_offer(publisher); iox_pub_deinit(publisher); } From a2dfc4accfaa86ee40cbe9c791f33630bce89bad Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Wed, 24 Feb 2021 16:06:21 +0100 Subject: [PATCH 123/143] iox-#350 refined some more unit tests Signed-off-by: Christian Eltzschig --- .../moduletests/test_popo_active_call_set.cpp | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index b75d3a55251..5caa89998aa 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -627,25 +627,25 @@ TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacks, Repeat(5 AttachEvent::doIt( *m_sut, events, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty); - m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; + blockTriggerCallback(); events[0U].triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2U)); - - // we triggered events[0] with a long runtime to safely trigger all events again - // while the callback is still running. to verify that events[0] is called again - // we reset the m_triggerCallbackArg[0] to nullptr (which is again set by the - // event[0] callback) and set the runtime of the callbacks to zero - m_triggerCallbackArg[0U].m_source = nullptr; - m_triggerCallbackRuntimeInMs = 0U; + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); for (auto& e : events) + { e.triggerStoepsel(); + } + // 10 times more callback runs allowed to allow potential overtriggering + unblockTriggerCallback(10U * iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - for (uint64_t i = 0U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0].m_source == &events[0U]); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0].m_count == 2U); + for (uint64_t i = 1U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) { TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i].m_source == &events[i]); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i].m_count == 1U); } }); @@ -655,27 +655,28 @@ TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacksOnce, Repe AttachEvent::doIt( *m_sut, events, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty); - m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; + blockTriggerCallback(); events[0U].triggerStoepsel(); - std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2U)); - m_triggerCallbackRuntimeInMs = 0U; + std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); for (auto& e : events) + { e.triggerStoepsel(); + } + // 10 times more callback runs allowed to allow potential overtriggering + unblockTriggerCallback(10U * iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - for (auto& t : m_triggerCallbackArg) - { - t.m_source = nullptr; - } events[0U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0].m_source == &events[0U]); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0].m_count == 3U); for (uint64_t i = 1U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) { - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i].m_source == nullptr); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i].m_source == &events[i]); + TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i].m_count == 1U); } }); From c5107a0890a124682e0ea80a09e250a097879141 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Wed, 24 Feb 2021 16:19:58 +0100 Subject: [PATCH 124/143] iox-#350 added some more unit test and use the trigger handle remove to remove an event from the active call set Signed-off-by: Christian Eltzschig --- .../internal/popo/active_call_set.inl | 4 +- .../iceoryx_posh/popo/active_call_set.hpp | 2 - iceoryx_posh/source/popo/active_call_set.cpp | 19 -------- .../moduletests/test_popo_active_call_set.cpp | 43 +++++++++++++++++++ 4 files changed, 45 insertions(+), 23 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl index 92471d6a371..2e62255b1fa 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl @@ -65,13 +65,13 @@ ActiveCallSet::attachEvent(T& eventOrigin, const EventType eventType, CallbackRe template inline void ActiveCallSet::detachEvent(T& eventOrigin, const EventType eventType) noexcept { - removeEvent(&eventOrigin, static_cast(eventType), typeid(EventType).hash_code()); + EventAttorney::disableEvent(eventOrigin, eventType); } template inline void ActiveCallSet::detachEvent(T& eventOrigin) noexcept { - detachEvent(eventOrigin, NoEnumUsed::PLACEHOLDER); + EventAttorney::disableEvent(eventOrigin); } inline constexpr uint64_t ActiveCallSet::capacity() noexcept diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp index 8ab65a8e1dd..1f3d80b72f7 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -123,7 +123,6 @@ class ActiveCallSet CallbackRef_t callback, TranslationCallbackRef_t translationCallback, const cxx::MethodCallback invalidationCallback) noexcept; - void removeEvent(void* const origin, const uint64_t eventType, const uint64_t eventTypeHash) noexcept; void removeTrigger(const uint64_t index) noexcept; @@ -139,7 +138,6 @@ class ActiveCallSet ~Event_t(); bool isEqualTo(const void* const origin, const uint64_t eventType, const uint64_t eventTypeHash) const noexcept; - bool resetIfEqualTo(const void* const origin, const uint64_t eventType, const uint64_t eventTypeHash) noexcept; bool reset() noexcept; void init(const uint64_t eventId, void* const origin, diff --git a/iceoryx_posh/source/popo/active_call_set.cpp b/iceoryx_posh/source/popo/active_call_set.cpp index 767585642c4..4eed87e5657 100644 --- a/iceoryx_posh/source/popo/active_call_set.cpp +++ b/iceoryx_posh/source/popo/active_call_set.cpp @@ -73,18 +73,6 @@ ActiveCallSet::addEvent(void* const origin, return cxx::success(index); } -void ActiveCallSet::removeEvent(void* const origin, const uint64_t eventType, const uint64_t eventTypeHash) noexcept -{ - for (uint32_t index = 0U; index < MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++index) - { - if (m_events[index]->resetIfEqualTo(origin, eventType, eventTypeHash)) - { - m_indexManager.push(index); - break; - } - } -} - uint64_t ActiveCallSet::size() const noexcept { return m_indexManager.indicesInUse(); @@ -155,13 +143,6 @@ bool ActiveCallSet::Event_t::isEqualTo(const void* const origin, return (m_origin == origin && m_eventType == eventType && m_eventTypeHash == eventTypeHash); } -bool ActiveCallSet::Event_t::resetIfEqualTo(const void* const origin, - const uint64_t eventType, - const uint64_t eventTypeHash) noexcept -{ - return (isEqualTo(origin, eventType, eventTypeHash)) ? reset() : false; -} - bool ActiveCallSet::Event_t::reset() noexcept { if (isInitialized()) diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index 5caa89998aa..d8e667455e6 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -482,6 +482,49 @@ TEST_F(ActiveCallSet_test, AttachedEventDTorDetachesItself) EXPECT_THAT(m_sut->size(), Eq(0U)); } +TEST_F(ActiveCallSet_test, AttachingSimpleEventSetsTriggerHandle) +{ + SimpleEventClass fuu; + m_sut->attachEvent(fuu, ActiveCallSet_test::triggerCallback<0U>); + + EXPECT_TRUE(static_cast(fuu.m_handleHypnotoad)); +} + +TEST_F(ActiveCallSet_test, DetachingSimpleEventResetsTriggerHandle) +{ + SimpleEventClass fuu; + m_sut->attachEvent(fuu, ActiveCallSet_test::triggerCallback<0U>); + m_sut->detachEvent(fuu); + + EXPECT_FALSE(static_cast(fuu.m_handleHypnotoad)); +} + +TEST_F(ActiveCallSet_test, AttachingEventWithEnumSetsTriggerHandle) +{ + SimpleEventClass fuu; + m_sut->attachEvent(fuu, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); + + EXPECT_TRUE(static_cast(fuu.m_handleStoepsel)); +} + +TEST_F(ActiveCallSet_test, DetachingEventWithEnumResetsTriggerHandle) +{ + SimpleEventClass fuu; + m_sut->attachEvent(fuu, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); + m_sut->detachEvent(fuu, SimpleEvent::StoepselBachelorParty); + + EXPECT_FALSE(static_cast(fuu.m_handleStoepsel)); +} + +TEST_F(ActiveCallSet_test, DetachingNonAttachedEventResetsNothing) +{ + SimpleEventClass fuu; + m_sut->attachEvent(fuu, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); + m_sut->detachEvent(fuu, SimpleEvent::Hypnotoad); + + EXPECT_TRUE(static_cast(fuu.m_handleStoepsel)); +} + /////////////////////////////////// // calling callbacks /////////////////////////////////// From e7b71046b4ca967727e56c51bf98c92aa0d06f9e Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Wed, 24 Feb 2021 16:40:22 +0100 Subject: [PATCH 125/143] iox-#350 using nice abstraction method in unit test and added a concurrency race condition warning in the active call set which can be caused by an error in the user algorithm Signed-off-by: Christian Eltzschig --- .../iceoryx_posh/popo/active_call_set.hpp | 18 ++++++ .../moduletests/test_roudi_portmanager.cpp | 61 ++++++++++++++++++- 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp index 1f3d80b72f7..cb66367e695 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -43,6 +43,24 @@ enum class ActiveCallSetError /// @brief The ActiveCallSet is a class which reacts to registered events by /// executing a corresponding callback concurrently. This is achieved via /// an encapsulated thread inside this class. +/// @note The ActiveCallSet is threadsafe and can be used without any restrictions concurrently. +/// @attention Calling detachEvent for the same event from multiple threads is supported but +/// can cause a race conditions if you attach the same event again concurrently from +/// another thread. +/// Example: +/// 1. One calls detachEvent [1] from thread A, B and C +/// 2. thread B wins and detaches event [1] +/// 3. A new thread D spawns and would like to attach event [1] again while thread A and C are +/// still waiting to detach [1]. +/// 4. Thread A wins but cannot detach event [1] since it is not attached. +/// 5. Thread D wins and attaches event [1]. +/// 6. Finally thread C can continue and detaches event [1] again. +/// +/// If thread D is executed last then the event is attached. So depending on the operating +/// system defined execution order the event is either attached or detached. +/// +/// Best practice: Detach a specific event only from one specific thread and not +/// from multiple contexts. class ActiveCallSet { public: diff --git a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp index 40420e297fe..4bc70fa8273 100644 --- a/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp +++ b/iceoryx_posh/test/moduletests/test_roudi_portmanager.cpp @@ -543,7 +543,66 @@ TEST_F(PortManager_test, AcquireConditionVariablesDataAfterDestroyingPreviouslyA acquireMaxNumberOfConditionVariables(processName); } -TEST_F(PortManager_test, AcquireMaxNumberOfNodePorts) +TEST_F(PortManager_test, AcquiringMaximumNumberOfEventVariablesWorks) +{ + std::string process = "BuddyHolly"; + + acquireMaxNumberOfEventVariables(process); +} + +TEST_F(PortManager_test, AcquiringOneMoreThanMaximumNumberOfEventVariableFails) +{ + std::string process = "BuddyHollysBrille"; + + // first acquire all possible event variables + acquireMaxNumberOfEventVariables(process); + + // test if overflow errors get hit + auto errorHandlerCalled{false}; + auto errorHandlerGuard = iox::ErrorHandler::SetTemporaryErrorHandler( + [&errorHandlerCalled](const iox::Error, const std::function, const iox::ErrorLevel) { + errorHandlerCalled = true; + }); + + auto eventVariableDataResult = m_portManager->acquireEventVariableData("AnotherBrille"); + EXPECT_THAT(eventVariableDataResult.has_error(), Eq(true)); + EXPECT_THAT(errorHandlerCalled, Eq(true)); + EXPECT_THAT(eventVariableDataResult.get_error(), Eq(PortPoolError::EVENT_VARIABLE_LIST_FULL)); +} + +TEST_F(PortManager_test, DeletingEventVariableWorks) +{ + std::string process = "BudSpencer"; + + // first acquire all possible event variables + acquireMaxNumberOfEventVariables(process); + + // delete one and add one eventVariableDataResult should be possible now + unsigned int i = 0U; + iox::ProcessName_t newProcessName(iox::cxx::TruncateToCapacity, process + std::to_string(i)); + m_portManager->deletePortsOfProcess(newProcessName); + + auto eventVariableDataResult = m_portManager->acquireEventVariableData(newProcessName); + EXPECT_THAT(eventVariableDataResult.has_error(), Eq(false)); +} + +TEST_F(PortManager_test, DestroyEventVariableAndAddNewOneSucceeds) +{ + iox::ProcessName_t process = "Terence Hill"; + std::vector eventVariableContainer; + + // first acquire all possible event variables + acquireMaxNumberOfEventVariables( + process, [&](auto eventVariableData) { eventVariableContainer.push_back(eventVariableData); }); + + setDestroyFlagAndClearContainer(eventVariableContainer); + m_portManager->doDiscovery(); + + // we should be able to get some more now + acquireMaxNumberOfEventVariables(process); +} + +TEST_F(PortManager_test, AcquiringMaximumNumberOfNodesWorks) { std::string processName = "Process"; std::string nodeName = "Node"; From 11dbb7fa34053d071da03b242d092d469f4fb9ef Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Thu, 25 Feb 2021 16:53:09 +0100 Subject: [PATCH 126/143] iox-#350 added INVALID_STATE in ActiveCallSetError Signed-off-by: Christian Eltzschig --- iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp index cb66367e695..67b49ca11fb 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -36,6 +36,7 @@ namespace popo { enum class ActiveCallSetError { + INVALID_STATE, ACTIVE_CALL_SET_FULL, EVENT_ALREADY_ATTACHED, }; From d53fafa9f16f93fa08bbb28d0049f14e3bb4aaf2 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Thu, 25 Feb 2021 16:58:46 +0100 Subject: [PATCH 127/143] iox-#350 adjusted doxygen comments and renamed function for better understanding Signed-off-by: Christian Eltzschig --- .../include/iceoryx_posh/internal/popo/active_call_set.inl | 6 +++--- iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl index 2e62255b1fa..bd1ed3f81a4 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/active_call_set.inl @@ -23,7 +23,7 @@ namespace popo namespace internal { template -inline void callsetCallback(void* const origin, void (*underlyingCallback)(void* const)) +inline void translateAndCallTypelessCallback(void* const origin, void (*underlyingCallback)(void* const)) { reinterpret_cast(underlyingCallback)(static_cast(origin)); } @@ -37,7 +37,7 @@ inline cxx::expected ActiveCallSet::attachEvent(T& eventOrig static_cast(NoEnumUsed::PLACEHOLDER), typeid(NoEnumUsed).hash_code(), reinterpret_cast>(eventCallback), - internal::callsetCallback, + internal::translateAndCallTypelessCallback, EventAttorney::getInvalidateTriggerMethod(eventOrigin)) .and_then([&](auto& eventId) { EventAttorney::enableEvent( @@ -53,7 +53,7 @@ ActiveCallSet::attachEvent(T& eventOrigin, const EventType eventType, CallbackRe static_cast(eventType), typeid(EventType).hash_code(), reinterpret_cast>(eventCallback), - internal::callsetCallback, + internal::translateAndCallTypelessCallback, EventAttorney::getInvalidateTriggerMethod(eventOrigin)) .and_then([&](auto& eventId) { EventAttorney::enableEvent(eventOrigin, diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp index 67b49ca11fb..b2ce59b73f5 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -87,7 +87,7 @@ class ActiveCallSet /// @tparam[in] T type of the class which will signal the event /// @param[in] eventOrigin the object which will signal the event (the origin) /// @param[in] eventCallback callback which will be executed concurrently when the event occurs - /// @return If an error occurs the enum which describes the error. + /// @return If an error occurs the enum packed inside an expected which describes the error. template cxx::expected attachEvent(T& eventOrigin, CallbackRef_t eventCallback) noexcept; @@ -99,7 +99,7 @@ class ActiveCallSet /// @param[in] eventOrigin the object which will signal the event (the origin) /// @param[in] eventType enum required to specify the type of event inside of eventOrigin /// @param[in] eventCallback callback which will be executed concurrently when the event occurs - /// @return If an error occurs the enum which describes the error. + /// @return If an error occurs the enum packed inside an expected which describes the error. template ::value>> cxx::expected attachEvent(T& eventOrigin, const EventType eventType, CallbackRef_t eventCallback) noexcept; @@ -116,7 +116,6 @@ class ActiveCallSet /// @brief Detaches an event. Hereby, the event is defined as a class T, the eventOrigin. /// @note This method can be called from any thread concurrently without any restrictions! /// @tparam[in] T type of the class which will signal the event - /// @param[in] eventType enum required to specify the type of event inside of eventOrigin template void detachEvent(T& eventOrigin) noexcept; From 1331a0a0f0143cbfcb631417799ff3e6185461dd Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Mon, 1 Mar 2021 15:03:15 +0100 Subject: [PATCH 128/143] iox-#350 tested BestFittingType_t, restructered active call set test, renamed Seppuku class in Watchdog class, replaced variables with constexpr uint64_t in waitset test Signed-off-by: Christian Eltzschig --- .../popo/building_blocks/event_listener.hpp | 7 +- iceoryx_posh/source/popo/active_call_set.cpp | 2 +- .../popo/building_blocks/event_listener.cpp | 3 +- iceoryx_posh/source/runtime/posh_runtime.cpp | 3 - .../moduletests/test_popo_active_call_set.cpp | 512 +++++++++--------- .../moduletests/test_popo_event_variable.cpp | 29 +- .../test/moduletests/test_popo_waitset.cpp | 44 +- .../include/iceoryx_utils/cxx/helplets.hpp | 56 +- .../test/moduletests/test_cxx_helplets.cpp | 53 ++ .../testutils/{seppuku.hpp => watch_dog.hpp} | 8 +- 10 files changed, 381 insertions(+), 336 deletions(-) rename iceoryx_utils/testutils/{seppuku.hpp => watch_dog.hpp} (91%) diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp index 18e3d322705..80752c8216c 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_listener.hpp @@ -33,6 +33,9 @@ namespace popo class EventListener { public: + using NotificationVector_t = cxx::vector, + MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET>; + /// @brief creates new EventListener /// /// @param[in] dataRef reference to EventVariableData @@ -43,9 +46,7 @@ class EventListener /// never empty unless destroy() was called, then it's always empty. /// /// @return vector of active notifications - cxx::vector, - MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET> - wait() noexcept; + NotificationVector_t wait() noexcept; /// @brief Used in classes to signal a thread which waits in wait() to return /// and stop working. Destroy will send an empty notification to wait() and diff --git a/iceoryx_posh/source/popo/active_call_set.cpp b/iceoryx_posh/source/popo/active_call_set.cpp index 4eed87e5657..4f03f02c9b0 100644 --- a/iceoryx_posh/source/popo/active_call_set.cpp +++ b/iceoryx_posh/source/popo/active_call_set.cpp @@ -190,7 +190,7 @@ bool ActiveCallSet::IndexManager_t::pop(uint32_t& value) noexcept void ActiveCallSet::IndexManager_t::push(const uint32_t index) noexcept { - m_loffli.push(index); + cxx::Expects(m_loffli.push(index)); --m_indicesInUse; } diff --git a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp index 997ee106713..b358975afca 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp @@ -35,8 +35,7 @@ void EventListener::destroy() noexcept } } -cxx::vector, MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET> -EventListener::wait() noexcept +EventListener::NotificationVector_t EventListener::wait() noexcept { cxx::vector, MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET> diff --git a/iceoryx_posh/source/runtime/posh_runtime.cpp b/iceoryx_posh/source/runtime/posh_runtime.cpp index dc74052db41..d1dc3d89da5 100644 --- a/iceoryx_posh/source/runtime/posh_runtime.cpp +++ b/iceoryx_posh/source/runtime/posh_runtime.cpp @@ -599,17 +599,14 @@ popo::EventVariableData* PoshRuntime::getMiddlewareEventVariable() noexcept switch (maybeEventVariable.get_error()) { case IpcMessageErrorType::EVENT_VARIABLE_LIST_FULL: - LogWarn() << "Could not create event variable as we are out of memory for event variables."; errorHandler(Error::kPOSH__RUNTIME_ROUDI_EVENT_VARIABLE_LIST_FULL, nullptr, iox::ErrorLevel::SEVERE); break; case IpcMessageErrorType::REQUEST_EVENT_VARIABLE_WRONG_IPC_MESSAGE_RESPONSE: - LogWarn() << "Could not create event variables; received wrong message queue response."; errorHandler(Error::kPOSH__RUNTIME_ROUDI_REQUEST_EVENT_VARIABLE_WRONG_MESSAGE_QUEUE_RESPONSE, nullptr, iox::ErrorLevel::SEVERE); break; default: - LogWarn() << "Undefined behavior occurred while creating event variable"; errorHandler(Error::kPOSH__RUNTIME_ROUDI_EVENT_VARIABLE_CREATION_UNDEFINED_BEHAVIOR, nullptr, iox::ErrorLevel::SEVERE); diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index d8e667455e6..9c135c6efcf 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -36,139 +36,158 @@ using namespace iox::popo; using namespace iox::cxx; using namespace iox::units::duration_literals; -class ActiveCallSet_test : public Test +namespace { - public: - enum SimpleEvent - { - StoepselBachelorParty, - Hypnotoad - }; +enum SimpleEvent +{ + StoepselBachelorParty, + Hypnotoad +}; - class SimpleEventClass - { - public: - SimpleEventClass() = default; - SimpleEventClass(const SimpleEventClass&) = delete; - SimpleEventClass(SimpleEventClass&&) = delete; +uint64_t g_invalidateTriggerId = 0U; +class SimpleEventClass +{ + public: + SimpleEventClass() = default; + SimpleEventClass(const SimpleEventClass&) = delete; + SimpleEventClass(SimpleEventClass&&) = delete; - SimpleEventClass& operator=(const SimpleEventClass&) = delete; - SimpleEventClass& operator=(SimpleEventClass&&) = delete; + SimpleEventClass& operator=(const SimpleEventClass&) = delete; + SimpleEventClass& operator=(SimpleEventClass&&) = delete; - ~SimpleEventClass() - { - m_handleStoepsel.reset(); - m_handleHypnotoad.reset(); - } - - void enableEvent(iox::popo::TriggerHandle&& handle, const SimpleEvent event) noexcept - { - if (event == SimpleEvent::StoepselBachelorParty) - { - m_handleStoepsel = std::move(handle); - } - else - { - m_handleHypnotoad = std::move(handle); - } - } + ~SimpleEventClass() + { + m_handleStoepsel.reset(); + m_handleHypnotoad.reset(); + } - void enableEvent(iox::popo::TriggerHandle&& handle) noexcept + void enableEvent(iox::popo::TriggerHandle&& handle, const SimpleEvent event) noexcept + { + switch (event) { + case SimpleEvent::StoepselBachelorParty: + m_handleStoepsel = std::move(handle); + break; + case SimpleEvent::Hypnotoad: m_handleHypnotoad = std::move(handle); + break; } + } + + void enableEvent(iox::popo::TriggerHandle&& handle) noexcept + { + m_handleHypnotoad = std::move(handle); + } - void invalidateTrigger(const uint64_t id) noexcept + void invalidateTrigger(const uint64_t id) noexcept + { + g_invalidateTriggerId = id; + if (m_handleHypnotoad.getUniqueId() == id) { - m_invalidateTriggerId = id; - if (m_handleHypnotoad.getUniqueId() == id) - { - m_handleHypnotoad.invalidate(); - } - else if (m_handleStoepsel.getUniqueId() == id) - { - m_handleStoepsel.invalidate(); - } + m_handleHypnotoad.invalidate(); } - - void disableEvent(const SimpleEvent event) noexcept + else if (m_handleStoepsel.getUniqueId() == id) { - if (event == SimpleEvent::StoepselBachelorParty) - { - m_handleStoepsel.reset(); - } - else - { - m_handleHypnotoad.reset(); - } + m_handleStoepsel.invalidate(); } + } - void disableEvent() noexcept + void disableEvent(const SimpleEvent event) noexcept + { + switch (event) { + case SimpleEvent::StoepselBachelorParty: + m_handleStoepsel.reset(); + break; + case SimpleEvent::Hypnotoad: m_handleHypnotoad.reset(); + break; } + } - void triggerStoepsel() noexcept - { - m_hasTriggered.store(true); - m_handleStoepsel.trigger(); - } + void disableEvent() noexcept + { + m_handleHypnotoad.reset(); + } - void resetTrigger() noexcept - { - m_hasTriggered.store(false); - } + void triggerStoepsel() noexcept + { + m_hasTriggered.store(true); + m_handleStoepsel.trigger(); + } - iox::popo::TriggerHandle m_handleHypnotoad; - iox::popo::TriggerHandle m_handleStoepsel; - mutable std::atomic_bool m_hasTriggered{false}; - static uint64_t m_invalidateTriggerId; - }; + void resetTrigger() noexcept + { + m_hasTriggered.store(false); + } - class ActiveCallSetMock : public ActiveCallSet + iox::popo::TriggerHandle m_handleHypnotoad; + iox::popo::TriggerHandle m_handleStoepsel; + mutable std::atomic_bool m_hasTriggered{false}; +}; + +class TestActiveCallSet : public ActiveCallSet +{ + public: + TestActiveCallSet(EventVariableData* data) noexcept + : ActiveCallSet(data) { - public: - ActiveCallSetMock(EventVariableData* data) noexcept - : ActiveCallSet(data) - { - } - }; + } +}; + +struct EventAndSutPair_t +{ + SimpleEventClass* object; + TestActiveCallSet* sut; +}; - EventVariableData m_eventVarData{"Maulbeerblatt"}; - iox::cxx::optional m_sut; +struct TriggerSourceAndCount +{ + std::atomic m_source{nullptr}; + std::atomic m_count{0U}; +}; + +std::vector g_toBeAttached; +std::vector g_toBeDetached; +std::array g_triggerCallbackArg; +uint64_t g_triggerCallbackRuntimeInMs = 0U; +iox::cxx::optional g_callbackBlocker; +class ActiveCallSet_test : public Test +{ + public: template - static void triggerCallback(ActiveCallSet_test::SimpleEventClass* const event) noexcept + static void triggerCallback(SimpleEventClass* const event) noexcept { - ActiveCallSet_test::m_triggerCallbackArg[N].m_source = event; - ++ActiveCallSet_test::m_triggerCallbackArg[N].m_count; + g_triggerCallbackArg[N].m_source = event; + ++g_triggerCallbackArg[N].m_count; - if (m_callbackBlocker) + if (g_callbackBlocker) { - m_callbackBlocker->wait(); + g_callbackBlocker->wait(); } - std::this_thread::sleep_for(std::chrono::milliseconds(m_triggerCallbackRuntimeInMs)); + std::this_thread::sleep_for(std::chrono::milliseconds(g_triggerCallbackRuntimeInMs)); } - static void attachCallback(ActiveCallSet_test::SimpleEventClass* const) noexcept + static void attachCallback(SimpleEventClass* const) noexcept { - for (auto& e : m_toBeAttached) + for (auto& e : g_toBeAttached) { e.sut->attachEvent(*e.object, SimpleEvent::StoepselBachelorParty, triggerCallback<0U>); } } - static void detachCallback(ActiveCallSet_test::SimpleEventClass* const) noexcept + static void detachCallback(SimpleEventClass* const) noexcept { - for (auto& e : m_toBeDetached) + for (auto& e : g_toBeDetached) { e.sut->detachEvent(*e.object, SimpleEvent::StoepselBachelorParty); } } - static void notifyAndThenDetachCallback(ActiveCallSet_test::SimpleEventClass* const) noexcept + static void notifyAndThenDetachStoepselCallback(SimpleEventClass* const) noexcept { - for (auto& e : m_toBeDetached) + for (auto& e : g_toBeDetached) { e.object->triggerStoepsel(); e.sut->detachEvent(*e.object, SimpleEvent::StoepselBachelorParty); @@ -178,22 +197,22 @@ class ActiveCallSet_test : public Test void SetUp() { - m_callbackBlocker.reset(); - for (auto& e : m_triggerCallbackArg) + g_callbackBlocker.reset(); + for (auto& e : g_triggerCallbackArg) { e.m_source = nullptr; e.m_count = 0U; } m_sut.emplace(&m_eventVarData); - ActiveCallSet_test::SimpleEventClass::m_invalidateTriggerId = 0U; - ActiveCallSet_test::m_triggerCallbackRuntimeInMs = 0U; - ActiveCallSet_test::m_toBeAttached.clear(); - ActiveCallSet_test::m_toBeDetached.clear(); + g_invalidateTriggerId = 0U; + g_triggerCallbackRuntimeInMs = 0U; + g_toBeAttached.clear(); + g_toBeDetached.clear(); }; - void blockTriggerCallback() noexcept + void activateTriggerCallbackBlocker() noexcept { - ActiveCallSet_test::m_callbackBlocker.emplace( + g_callbackBlocker.emplace( iox::posix::Semaphore::create(iox::posix::CreateUnnamedSingleProcessSemaphore, 0U).value()); } @@ -201,51 +220,31 @@ class ActiveCallSet_test : public Test { for (uint64_t i = 0U; i < numberOfUnblocks; ++i) { - m_callbackBlocker->post(); + ASSERT_TRUE(static_cast(g_callbackBlocker)); + g_callbackBlocker->post(); } } void TearDown(){}; - struct ToBeAttached_t - { - SimpleEventClass* object; - ActiveCallSetMock* sut; - }; - - // + 1U to test the maximum capacity - using eventVector_t = iox::cxx::vector; - eventVector_t m_simpleEvents{iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET + 1U}; - struct TriggerSourceAndCount - { - SimpleEventClass* m_source = nullptr; - uint64_t m_count = 0U; - }; + static constexpr uint64_t OVERFLOW_TEST_APPENDIX = 1U; + using eventArray_t = SimpleEventClass[iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET + OVERFLOW_TEST_APPENDIX]; + eventArray_t m_simpleEvents; + EventVariableData m_eventVarData{"Maulbeerblättle"}; + iox::cxx::optional m_sut; - static std::vector m_toBeAttached; - static std::vector m_toBeDetached; - static std::array m_triggerCallbackArg; static constexpr uint64_t CALLBACK_WAIT_IN_MS = 100U; - static uint64_t m_triggerCallbackRuntimeInMs; - static iox::cxx::optional m_callbackBlocker; }; -uint64_t ActiveCallSet_test::SimpleEventClass::m_invalidateTriggerId = 0U; -std::array - ActiveCallSet_test::m_triggerCallbackArg; + constexpr uint64_t ActiveCallSet_test::CALLBACK_WAIT_IN_MS; -uint64_t ActiveCallSet_test::m_triggerCallbackRuntimeInMs; -std::vector ActiveCallSet_test::m_toBeAttached; -std::vector ActiveCallSet_test::m_toBeDetached; -iox::cxx::optional ActiveCallSet_test::m_callbackBlocker; +constexpr uint64_t ActiveCallSet_test::OVERFLOW_TEST_APPENDIX; template struct AttachEvent { template - static void doIt(ActiveCallSet_test::ActiveCallSetMock& sut, - std::vector& events, - const EventType event) + static void doIt(TestActiveCallSet& sut, std::vector& events, const EventType event) { EXPECT_THAT(sut.attachEvent(events[N], event, ActiveCallSet_test::triggerCallback).has_error(), Eq(false)); AttachEvent::doIt(sut, events, event); @@ -256,18 +255,22 @@ template <> struct AttachEvent<0U> { template - static void doIt(ActiveCallSet_test::ActiveCallSetMock& sut, - std::vector& events, - const EventType event) + static void doIt(TestActiveCallSet& sut, std::vector& events, const EventType event) { EXPECT_THAT(sut.attachEvent(events[0U], event, ActiveCallSet_test::triggerCallback<0U>).has_error(), Eq(false)); } }; +} // namespace ////////////////////////////////// -// attach / detach +// BEGIN attach / detach ////////////////////////////////// +TEST_F(ActiveCallSet_test, CapacityIsEqualToMAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET) +{ + EXPECT_THAT(m_sut->capacity(), Eq(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET)); +} + TEST_F(ActiveCallSet_test, IsEmptyWhenConstructed) { EXPECT_THAT(m_sut->size(), Eq(0U)); @@ -284,6 +287,7 @@ TEST_F(ActiveCallSet_test, AttachWithoutEnumTillCapacityIsFullWorks) for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { EXPECT_FALSE(m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>).has_error()); + EXPECT_THAT(m_sut->size(), Eq(i + 1)); } EXPECT_THAT(m_sut->size(), Eq(m_sut->capacity())); } @@ -303,6 +307,7 @@ TEST_F(ActiveCallSet_test, AttachWithoutEnumOneMoreThanCapacityFails) for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>); + EXPECT_THAT(m_sut->size(), Eq(i + 1)); } auto result = m_sut->attachEvent(m_simpleEvents[m_sut->capacity()], ActiveCallSet_test::triggerCallback<0U>); @@ -312,22 +317,19 @@ TEST_F(ActiveCallSet_test, AttachWithoutEnumOneMoreThanCapacityFails) TEST_F(ActiveCallSet_test, AttachingWithEnumIfEnoughSpaceAvailableWorks) { - EXPECT_FALSE(m_sut - ->attachEvent(m_simpleEvents[0U], - ActiveCallSet_test::SimpleEvent::Hypnotoad, - ActiveCallSet_test::triggerCallback<0U>) + EXPECT_FALSE(m_sut->attachEvent(m_simpleEvents[0U], SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>) .has_error()); + EXPECT_THAT(m_sut->size(), Eq(1)); } TEST_F(ActiveCallSet_test, AttachWithEnumTillCapacityIsFullWorks) { for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { - EXPECT_FALSE(m_sut - ->attachEvent(m_simpleEvents[i], - ActiveCallSet_test::SimpleEvent::Hypnotoad, - ActiveCallSet_test::triggerCallback<0U>) - .has_error()); + EXPECT_FALSE( + m_sut->attachEvent(m_simpleEvents[i], SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>) + .has_error()); + EXPECT_THAT(m_sut->size(), Eq(i + 1)); } } @@ -335,12 +337,10 @@ TEST_F(ActiveCallSet_test, AttachWithEnumOneMoreThanCapacityFails) { for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { - m_sut->attachEvent( - m_simpleEvents[i], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); + m_sut->attachEvent(m_simpleEvents[i], SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); } - auto result = m_sut->attachEvent(m_simpleEvents[m_sut->capacity()], - ActiveCallSet_test::SimpleEvent::Hypnotoad, - ActiveCallSet_test::triggerCallback<0U>); + auto result = m_sut->attachEvent( + m_simpleEvents[m_sut->capacity()], SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); ASSERT_TRUE(result.has_error()); EXPECT_THAT(result.get_error(), Eq(ActiveCallSetError::ACTIVE_CALL_SET_FULL)); @@ -350,14 +350,13 @@ TEST_F(ActiveCallSet_test, DetachMakesSpaceForAnotherAttachWithEventEnum) { for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { - m_sut->attachEvent( - m_simpleEvents[i], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); + m_sut->attachEvent(m_simpleEvents[i], SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); } - m_sut->detachEvent(m_simpleEvents[0U], ActiveCallSet_test::SimpleEvent::Hypnotoad); + m_sut->detachEvent(m_simpleEvents[0U], SimpleEvent::Hypnotoad); EXPECT_FALSE(m_sut ->attachEvent(m_simpleEvents[m_sut->capacity()], - ActiveCallSet_test::SimpleEvent::Hypnotoad, + SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>) .has_error()); } @@ -370,11 +369,8 @@ TEST_F(ActiveCallSet_test, DetachMakesSpaceForAnotherAttachWithoutEventEnum) } m_sut->detachEvent(m_simpleEvents[0U]); - EXPECT_FALSE(m_sut - ->attachEvent(m_simpleEvents[m_sut->capacity()], - ActiveCallSet_test::SimpleEvent::Hypnotoad, - ActiveCallSet_test::triggerCallback<0U>) - .has_error()); + EXPECT_FALSE( + m_sut->attachEvent(m_simpleEvents[m_sut->capacity()], ActiveCallSet_test::triggerCallback<0U>).has_error()); } TEST_F(ActiveCallSet_test, AttachingEventWithoutEventTypeLeadsToAttachedTriggerHandle) @@ -385,21 +381,16 @@ TEST_F(ActiveCallSet_test, AttachingEventWithoutEventTypeLeadsToAttachedTriggerH TEST_F(ActiveCallSet_test, AttachingEventWithEventTypeLeadsToAttachedTriggerHandle) { - m_sut->attachEvent(m_simpleEvents[0U], - ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, - ActiveCallSet_test::triggerCallback<0U>); + m_sut->attachEvent(m_simpleEvents[0U], SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); EXPECT_TRUE(m_simpleEvents[0U].m_handleStoepsel.isValid()); } TEST_F(ActiveCallSet_test, AttachingSameEventWithEventEnumTwiceFails) { - m_sut->attachEvent(m_simpleEvents[0U], - ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, - ActiveCallSet_test::triggerCallback<0U>); + m_sut->attachEvent(m_simpleEvents[0U], SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); - auto result = m_sut->attachEvent(m_simpleEvents[0U], - ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, - ActiveCallSet_test::triggerCallback<0U>); + auto result = m_sut->attachEvent( + m_simpleEvents[0U], SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); ASSERT_TRUE(result.has_error()); EXPECT_THAT(result.get_error(), Eq(ActiveCallSetError::EVENT_ALREADY_ATTACHED)); } @@ -415,31 +406,28 @@ TEST_F(ActiveCallSet_test, AttachingSameEventWithoutEventEnumTwiceFails) TEST_F(ActiveCallSet_test, AttachingSameClassWithTwoDifferentEventsWorks) { - m_sut->attachEvent( - m_simpleEvents[0U], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); + m_sut->attachEvent(m_simpleEvents[0U], SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); EXPECT_FALSE(m_sut ->attachEvent(m_simpleEvents[0U], - ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, + SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>) .has_error()); } TEST_F(ActiveCallSet_test, DetachingSameClassWithDifferentEventEnumChangesNothing) { - m_sut->attachEvent( - m_simpleEvents[0U], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); + m_sut->attachEvent(m_simpleEvents[0U], SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); - m_sut->detachEvent(m_simpleEvents[0U], ActiveCallSet_test::SimpleEvent::StoepselBachelorParty); + m_sut->detachEvent(m_simpleEvents[0U], SimpleEvent::StoepselBachelorParty); EXPECT_THAT(m_sut->size(), Eq(1U)); } TEST_F(ActiveCallSet_test, DetachingDifferentClassWithSameEventEnumChangesNothing) { - m_sut->attachEvent( - m_simpleEvents[0U], ActiveCallSet_test::SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); + m_sut->attachEvent(m_simpleEvents[0U], SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); - m_sut->detachEvent(m_simpleEvents[1U], ActiveCallSet_test::SimpleEvent::Hypnotoad); + m_sut->detachEvent(m_simpleEvents[1U], SimpleEvent::Hypnotoad); EXPECT_THAT(m_sut->size(), Eq(1U)); } @@ -526,47 +514,47 @@ TEST_F(ActiveCallSet_test, DetachingNonAttachedEventResetsNothing) } /////////////////////////////////// -// calling callbacks +// END +/////////////////////////////////// + +/////////////////////////////////// +// BEGIN calling callbacks /////////////////////////////////// TIMING_TEST_F(ActiveCallSet_test, CallbackIsCalledAfterNotify, Repeat(5), [&] { SimpleEventClass fuu; - m_sut->attachEvent( - fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); + m_sut->attachEvent(fuu, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); fuu.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_source == &fuu); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_count == 1U); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_source == &fuu); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_count == 1U); }); TIMING_TEST_F(ActiveCallSet_test, CallbackIsCalledOnlyOnceWhenTriggered, Repeat(5), [&] { SimpleEventClass fuu1; SimpleEventClass fuu2; - m_sut->attachEvent( - fuu1, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); - m_sut->attachEvent( - fuu2, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<1U>); + m_sut->attachEvent(fuu1, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); + m_sut->attachEvent(fuu2, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<1U>); fuu1.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); fuu2.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_source == &fuu1); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_count == 1U); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U].m_source == &fuu2); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U].m_count == 1U); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_source == &fuu1); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_count == 1U); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[1U].m_source == &fuu2); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[1U].m_count == 1U); }); TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherCallback, Repeat(5), [&] { SimpleEventClass fuu; - m_sut->attachEvent( - fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); + m_sut->attachEvent(fuu, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); constexpr uint64_t NUMBER_OF_TRIGGER_UNBLOCKS = 10U; - blockTriggerCallback(); + activateTriggerCallbackBlocker(); fuu.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); @@ -574,21 +562,19 @@ TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherCallback, unblockTriggerCallback(NUMBER_OF_TRIGGER_UNBLOCKS); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_source == &fuu); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_count == 2U); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_source == &fuu); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_count == 2U); }); TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherCallbackOnce, Repeat(5), [&] { SimpleEventClass fuu; SimpleEventClass bar; - m_sut->attachEvent( - fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); - m_sut->attachEvent( - bar, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<1U>); + m_sut->attachEvent(fuu, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); + m_sut->attachEvent(bar, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<1U>); constexpr uint64_t NUMBER_OF_TRIGGER_UNBLOCKS = 10U; - blockTriggerCallback(); + activateTriggerCallbackBlocker(); fuu.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); @@ -597,20 +583,19 @@ TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherCallbackOn unblockTriggerCallback(NUMBER_OF_TRIGGER_UNBLOCKS); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_source == &fuu); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_count == 2U); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U].m_source == &bar); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U].m_count == 1U); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_source == &fuu); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_count == 2U); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[1U].m_source == &bar); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[1U].m_count == 1U); }); TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnotherCallback, Repeat(5), [&] { SimpleEventClass fuu; - m_sut->attachEvent( - fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); + m_sut->attachEvent(fuu, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); constexpr uint64_t NUMBER_OF_RETRIGGERS = 10U; - blockTriggerCallback(); + activateTriggerCallbackBlocker(); fuu.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); @@ -621,21 +606,19 @@ TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnot unblockTriggerCallback(NUMBER_OF_RETRIGGERS); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_source == &fuu); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_count == 2U); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_source == &fuu); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_count == 2U); }); TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnotherCallbackOnce, Repeat(5), [&] { SimpleEventClass fuu; SimpleEventClass bar; - m_sut->attachEvent( - fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); - m_sut->attachEvent( - bar, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<1U>); + m_sut->attachEvent(fuu, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); + m_sut->attachEvent(bar, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<1U>); constexpr uint64_t NUMBER_OF_RETRIGGERS = 10U; - blockTriggerCallback(); + activateTriggerCallbackBlocker(); fuu.triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); @@ -647,30 +630,29 @@ TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnot unblockTriggerCallback(NUMBER_OF_RETRIGGERS + 1); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_source == &fuu); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_count == 2U); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U].m_source == &bar); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U].m_count == 1U); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_source == &fuu); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_count == 2U); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[1U].m_source == &bar); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[1U].m_count == 1U); }); TIMING_TEST_F(ActiveCallSet_test, NoTriggerLeadsToNoCallback, Repeat(5), [&] { SimpleEventClass fuu; - m_sut->attachEvent( - fuu, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); + m_sut->attachEvent(fuu, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_source == nullptr); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_count == 0U); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_source == nullptr); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_count == 0U); }); TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacks, Repeat(5), [&] { std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); AttachEvent::doIt( - *m_sut, events, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty); + *m_sut, events, SimpleEvent::StoepselBachelorParty); - blockTriggerCallback(); + activateTriggerCallbackBlocker(); events[0U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); @@ -683,12 +665,12 @@ TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacks, Repeat(5 unblockTriggerCallback(10U * iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0].m_source == &events[0U]); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0].m_count == 2U); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0].m_source == &events[0U]); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0].m_count == 2U); for (uint64_t i = 1U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) { - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i].m_source == &events[i]); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i].m_count == 1U); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[i].m_source == &events[i]); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[i].m_count == 1U); } }); @@ -696,9 +678,9 @@ TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacksOnce, Repe std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); AttachEvent::doIt( - *m_sut, events, ActiveCallSet_test::SimpleEvent::StoepselBachelorParty); + *m_sut, events, SimpleEvent::StoepselBachelorParty); - blockTriggerCallback(); + activateTriggerCallbackBlocker(); events[0U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); @@ -714,24 +696,27 @@ TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacksOnce, Repe events[0U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0].m_source == &events[0U]); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0].m_count == 3U); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0].m_source == &events[0U]); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0].m_count == 3U); for (uint64_t i = 1U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) { - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i].m_source == &events[i]); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i].m_count == 1U); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[i].m_source == &events[i]); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[i].m_count == 1U); } }); +////////////////////////////////// +// END +////////////////////////////////// ////////////////////////////////// -// concurrent attach / detach +// BEGIN concurrent attach / detach ////////////////////////////////// TIMING_TEST_F(ActiveCallSet_test, AttachingWhileCallbackIsRunningWorks, Repeat(5), [&] { std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, triggerCallback<0U>); - m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; + g_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; events[0U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); @@ -739,7 +724,7 @@ TIMING_TEST_F(ActiveCallSet_test, AttachingWhileCallbackIsRunningWorks, Repeat(5 events[1U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS * 2U)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U].m_source == &events[1U]); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[1U].m_source == &events[1U]); }); TIMING_TEST_F(ActiveCallSet_test, AttachingMultipleWhileCallbackIsRunningWorks, Repeat(5), [&] { @@ -749,14 +734,14 @@ TIMING_TEST_F(ActiveCallSet_test, AttachingMultipleWhileCallbackIsRunningWorks, SimpleEvent::StoepselBachelorParty, triggerCallback); - m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; + g_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; events[iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); AttachEvent::doIt( *m_sut, events, SimpleEvent::StoepselBachelorParty); - m_triggerCallbackRuntimeInMs = 0U; + g_triggerCallbackRuntimeInMs = 0U; for (uint64_t i = 0U; i + 1U < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) { events[i].triggerStoepsel(); @@ -765,7 +750,7 @@ TIMING_TEST_F(ActiveCallSet_test, AttachingMultipleWhileCallbackIsRunningWorks, for (uint64_t i = 0U; i + 1U < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) { - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i].m_source == &events[i]); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[i].m_source == &events[i]); } }); @@ -774,22 +759,22 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingWhileCallbackIsRunningWorks, Repeat(5 m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, triggerCallback<0U>); - m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; + g_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; events[0U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - m_triggerCallbackArg[0U].m_source = nullptr; + g_triggerCallbackArg[0U].m_source = nullptr; m_sut->detachEvent(events[0U], SimpleEvent::StoepselBachelorParty); events[0U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_source == nullptr); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_source == nullptr); }); TIMING_TEST_F(ActiveCallSet_test, DetachingWhileCallbackIsRunningBlocksDetach, Repeat(5), [&] { std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, triggerCallback<0U>); - m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; + g_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; events[0U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 4U)); @@ -804,7 +789,7 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingWhileCallbackIsRunningBlocksDetach, R TIMING_TEST_F(ActiveCallSet_test, EventDestructorBlocksWhenCallbackIsRunning, Repeat(5), [&] { SimpleEventClass* event = new SimpleEventClass(); m_sut->attachEvent(*event, SimpleEvent::StoepselBachelorParty, triggerCallback<0U>); - m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; + g_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; event->triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 4U)); @@ -822,18 +807,18 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingMultipleWhileCallbackIsRunningWorks, AttachEvent::doIt( *m_sut, events, SimpleEvent::StoepselBachelorParty); - m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; + g_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; events[0U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - m_triggerCallbackRuntimeInMs = 0U; + g_triggerCallbackRuntimeInMs = 0U; for (auto& e : events) { m_sut->detachEvent(e, SimpleEvent::StoepselBachelorParty); } std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - for (auto& t : m_triggerCallbackArg) + for (auto& t : g_triggerCallbackArg) { t.m_source = nullptr; } @@ -845,7 +830,7 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingMultipleWhileCallbackIsRunningWorks, for (uint64_t i = 0U; i < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) { - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[i].m_source == nullptr); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[i].m_source == nullptr); } }); @@ -854,7 +839,7 @@ TIMING_TEST_F(ActiveCallSet_test, AttachingDetachingRunsIndependentOfCallback, R m_sut->attachEvent(events[iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U], SimpleEvent::StoepselBachelorParty, triggerCallback); - m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; + g_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; events[iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2U)); @@ -871,15 +856,18 @@ TIMING_TEST_F(ActiveCallSet_test, AttachingDetachingRunsIndependentOfCallback, R AttachEvent::doIt( *m_sut, events, SimpleEvent::StoepselBachelorParty); }); +////////////////////////////////// +// END +////////////////////////////////// ////////////////////////////////// -// attach / detach in callbacks +// BEGIN attach / detach in callbacks ////////////////////////////////// TIMING_TEST_F(ActiveCallSet_test, DetachingSelfInCallbackWorks, Repeat(5), [&] { - m_toBeDetached.clear(); + g_toBeDetached.clear(); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - m_toBeDetached.push_back({&events[0U], &*m_sut}); + g_toBeDetached.push_back({&events[0U], &*m_sut}); m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, detachCallback); events[0U].triggerStoepsel(); @@ -890,10 +878,10 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingSelfInCallbackWorks, Repeat(5), [&] { }); TIMING_TEST_F(ActiveCallSet_test, DetachingNonSelfEventInCallbackWorks, Repeat(5), [&] { - m_toBeDetached.clear(); + g_toBeDetached.clear(); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - m_toBeDetached.push_back({&events[1U], &*m_sut}); + g_toBeDetached.push_back({&events[1U], &*m_sut}); m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, detachCallback); m_sut->attachEvent(events[1U], SimpleEvent::StoepselBachelorParty, triggerCallback<1U>); @@ -905,32 +893,32 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingNonSelfEventInCallbackWorks, Repeat(5 }); TIMING_TEST_F(ActiveCallSet_test, DetachedCallbacksAreNotBeingCalledWhenTriggeredBefore, Repeat(5), [&] { - m_toBeDetached.clear(); + g_toBeDetached.clear(); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - m_toBeDetached.push_back({&events[1U], &*m_sut}); - m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, notifyAndThenDetachCallback); + g_toBeDetached.push_back({&events[1U], &*m_sut}); + m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, notifyAndThenDetachStoepselCallback); m_sut->attachEvent(events[1U], SimpleEvent::StoepselBachelorParty, triggerCallback<1U>); - m_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; + g_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; events[1U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2U)); - m_triggerCallbackArg[1U].m_source = nullptr; - m_triggerCallbackRuntimeInMs = 0U; + g_triggerCallbackArg[1U].m_source = nullptr; + g_triggerCallbackRuntimeInMs = 0U; events[0U].triggerStoepsel(); events[1U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[1U].m_source == nullptr); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[1U].m_source == nullptr); }); TIMING_TEST_F(ActiveCallSet_test, AttachingInCallbackWorks, Repeat(1), [&] { - m_toBeAttached.clear(); + g_toBeAttached.clear(); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - m_toBeAttached.push_back({&events[1U], &*m_sut}); + g_toBeAttached.push_back({&events[1U], &*m_sut}); m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, attachCallback); events[0U].triggerStoepsel(); @@ -939,5 +927,9 @@ TIMING_TEST_F(ActiveCallSet_test, AttachingInCallbackWorks, Repeat(1), [&] { std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2U)); - TIMING_TEST_EXPECT_TRUE(m_triggerCallbackArg[0U].m_source == &events[1U]); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_source == &events[1U]); }); +////////////////////////////////// +// END +////////////////////////////////// + diff --git a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp index c9b61ebc6b6..8e3fcc9dd4e 100644 --- a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp @@ -19,8 +19,8 @@ #include "iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp" #include "test.hpp" -#include "testutils/seppuku.hpp" #include "testutils/timing_test.hpp" +#include "testutils/watch_dog.hpp" #include @@ -118,6 +118,9 @@ TEST_F(EventVariable_test, DestroyWakesUpWaitWhichReturnsEmptyVector) NotificationVector_t activeNotifications; + Watchdog seppuku(m_timeToWait); + seppuku.watchAndActOnFailure([] { std::terminate(); }); + std::thread waiter([&] { activeNotifications = sut.wait(); EXPECT_THAT(activeNotifications.size(), Eq(0U)); @@ -133,8 +136,8 @@ TEST_F(EventVariable_test, GetCorrectNotificationVectorAfterNotifyAndWait) EventNotifier notifier(m_eventVarData, EVENT_INDEX); EventListener listener(m_eventVarData); - Seppuku seppuku(m_timeToWait); - seppuku.doSeppuku([&] { listener.destroy(); }); + Watchdog seppuku(m_timeToWait); + seppuku.watchAndActOnFailure([&] { listener.destroy(); }); notifier.notify(); const auto& activeNotifications = listener.wait(); @@ -151,8 +154,8 @@ TEST_F(EventVariable_test, GetCorrectNotificationVectorAfterMultipleNotifyAndWai EventNotifier notifier2(m_eventVarData, SECOND_EVENT_INDEX); EventListener listener(m_eventVarData); - Seppuku seppuku(m_timeToWait); - seppuku.doSeppuku([&] { listener.destroy(); }); + Watchdog seppuku(m_timeToWait); + seppuku.watchAndActOnFailure([&] { listener.destroy(); }); notifier1.notify(); notifier2.notify(); @@ -170,8 +173,8 @@ TEST_F(EventVariable_test, WaitAndNotifyResultsInCorrectNotificationVector) EventListener listener(m_eventVarData); NotificationVector_t activeNotifications; - Seppuku seppuku(m_timeToWait); - seppuku.doSeppuku([&] { listener.destroy(); }); + Watchdog seppuku(m_timeToWait); + seppuku.watchAndActOnFailure([&] { listener.destroy(); }); std::thread waiter([&] { activeNotifications = listener.wait(); @@ -192,8 +195,8 @@ TIMING_TEST_F(EventVariable_test, WaitBlocks, Repeat(5), [&] { iox::posix::Semaphore::create(iox::posix::CreateUnnamedSingleProcessSemaphore, 0U).value(); std::atomic_bool hasWaited{false}; - Seppuku seppuku(m_timeToWait); - seppuku.doSeppuku([&] { listener.destroy(); }); + Watchdog seppuku(m_timeToWait); + seppuku.watchAndActOnFailure([&] { listener.destroy(); }); std::thread waiter([&] { threadSetupSemaphore.post(); @@ -222,8 +225,8 @@ TIMING_TEST_F(EventVariable_test, SecondWaitBlocksUntilNewNotification, Repeat(5 iox::posix::Semaphore::create(iox::posix::CreateUnnamedSingleProcessSemaphore, 0U).value(); std::atomic_bool hasWaited{false}; - Seppuku seppukuFirstWait(m_timeToWait); - seppukuFirstWait.doSeppuku([&] { listener.destroy(); }); + Watchdog seppukuFirstWait(m_timeToWait); + seppukuFirstWait.watchAndActOnFailure([&] { listener.destroy(); }); notifier1.notify(); notifier2.notify(); @@ -233,8 +236,8 @@ TIMING_TEST_F(EventVariable_test, SecondWaitBlocksUntilNewNotification, Repeat(5 EXPECT_THAT(activeNotifications[0], Eq(SECOND_EVENT_INDEX)); EXPECT_THAT(activeNotifications[1], Eq(FIRST_EVENT_INDEX)); - Seppuku seppukuSecondWait(m_timeToWait); - seppukuSecondWait.doSeppuku([&] { listener.destroy(); }); + Watchdog seppukuSecondWait(m_timeToWait); + seppukuSecondWait.watchAndActOnFailure([&] { listener.destroy(); }); std::thread waiter([&] { threadSetupSemaphore.post(); diff --git a/iceoryx_posh/test/moduletests/test_popo_waitset.cpp b/iceoryx_posh/test/moduletests/test_popo_waitset.cpp index d8cf75ccfeb..d7f8315577f 100644 --- a/iceoryx_posh/test/moduletests/test_popo_waitset.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_waitset.cpp @@ -165,9 +165,9 @@ TEST_F(WaitSet_test, AcquireMaximumAllowedPlusOneTriggerFails) TEST_F(WaitSet_test, AcquireSameTriggerTwiceResultsInError) { - uint64_t userDefinedEventId = 0U; - m_sut.attachEvent(m_simpleEvents[0], userDefinedEventId); - auto result2 = m_sut.attachEvent(m_simpleEvents[0], userDefinedEventId); + constexpr uint64_t USER_DEFINED_EVENT_ID = 0U; + m_sut.attachEvent(m_simpleEvents[0], USER_DEFINED_EVENT_ID); + auto result2 = m_sut.attachEvent(m_simpleEvents[0], USER_DEFINED_EVENT_ID); ASSERT_TRUE(result2.has_error()); EXPECT_THAT(result2.get_error(), Eq(WaitSetError::EVENT_ALREADY_ATTACHED)); @@ -175,9 +175,9 @@ TEST_F(WaitSet_test, AcquireSameTriggerTwiceResultsInError) TEST_F(WaitSet_test, AcquireSameTriggerWithNonNullIdTwiceResultsInError) { - uint64_t userDefinedEventId = 121U; - m_sut.attachEvent(m_simpleEvents[0], userDefinedEventId); - auto result2 = m_sut.attachEvent(m_simpleEvents[0], userDefinedEventId); + constexpr uint64_t USER_DEFINED_EVENT_ID = 121U; + m_sut.attachEvent(m_simpleEvents[0], USER_DEFINED_EVENT_ID); + auto result2 = m_sut.attachEvent(m_simpleEvents[0], USER_DEFINED_EVENT_ID); ASSERT_TRUE(result2.has_error()); EXPECT_THAT(result2.get_error(), Eq(WaitSetError::EVENT_ALREADY_ATTACHED)); @@ -185,10 +185,10 @@ TEST_F(WaitSet_test, AcquireSameTriggerWithNonNullIdTwiceResultsInError) TEST_F(WaitSet_test, AcquireSameTriggerWithDifferentIdResultsInError) { - uint64_t userDefinedEventId = 2101U; - uint64_t anotherUserDefinedEventId = 9121U; - m_sut.attachEvent(m_simpleEvents[0], userDefinedEventId); - auto result2 = m_sut.attachEvent(m_simpleEvents[0], anotherUserDefinedEventId); + constexpr uint64_t USER_DEFINED_EVENT_ID = 2101U; + constexpr uint64_t ANOTHER_USER_DEFINED_EVENT_ID = 9121U; + m_sut.attachEvent(m_simpleEvents[0], USER_DEFINED_EVENT_ID); + auto result2 = m_sut.attachEvent(m_simpleEvents[0], ANOTHER_USER_DEFINED_EVENT_ID); ASSERT_TRUE(result2.has_error()); EXPECT_THAT(result2.get_error(), Eq(WaitSetError::EVENT_ALREADY_ATTACHED)); @@ -200,8 +200,8 @@ TEST_F(WaitSet_test, ResetCallbackIsCalledWhenWaitsetGoesOutOfScope) SimpleEventClass simpleEvent; { WaitSetMock sut{&m_condVarData}; - uint64_t userDefinedEventId = 421337U; - sut.attachEvent(simpleEvent, userDefinedEventId); + constexpr uint64_t USER_DEFINED_EVENT_ID = 421337U; + sut.attachEvent(simpleEvent, USER_DEFINED_EVENT_ID); uniqueTriggerId = simpleEvent.getUniqueId(); } EXPECT_THAT(SimpleEventClass::m_invalidateTriggerId, Eq(uniqueTriggerId)); @@ -215,16 +215,16 @@ TEST_F(WaitSet_test, TriggerRemovesItselfFromWaitsetWhenGoingOutOfScope) m_sut.attachEvent(m_simpleEvents[i], 100U + i); } - uint64_t userDefinedEventId = 0U; + constexpr uint64_t USER_DEFINED_EVENT_ID = 0U; { SimpleEventClass temporaryTrigger; - m_sut.attachEvent(temporaryTrigger, userDefinedEventId); + m_sut.attachEvent(temporaryTrigger, USER_DEFINED_EVENT_ID); // goes out of scope here and creates space again for an additional trigger // if this doesn't work we are unable to acquire another trigger since the // waitset is already full } - auto result = m_sut.attachEvent(m_simpleEvents.back(), userDefinedEventId); + auto result = m_sut.attachEvent(m_simpleEvents.back(), USER_DEFINED_EVENT_ID); EXPECT_FALSE(result.has_error()); } @@ -236,21 +236,21 @@ TEST_F(WaitSet_test, MultipleTimerRemovingThemselfFromWaitsetWhenGoingOutOfScope m_sut.attachEvent(m_simpleEvents[i], 100U + i); } - uint64_t userDefinedEventId = 0U; + constexpr uint64_t USER_DEFINED_EVENT_ID = 0U; { SimpleEventClass temporaryTrigger1, temporaryTrigger2, temporaryTrigger3; - m_sut.attachEvent(temporaryTrigger1, userDefinedEventId); - m_sut.attachEvent(temporaryTrigger2, userDefinedEventId); - m_sut.attachEvent(temporaryTrigger3, userDefinedEventId); + m_sut.attachEvent(temporaryTrigger1, USER_DEFINED_EVENT_ID); + m_sut.attachEvent(temporaryTrigger2, USER_DEFINED_EVENT_ID); + m_sut.attachEvent(temporaryTrigger3, USER_DEFINED_EVENT_ID); // goes out of scope here and creates space again for an additional trigger // if this doesn't work we are unable to acquire another trigger since the // waitset is already full } - auto result0 = m_sut.attachEvent(m_simpleEvents[0], userDefinedEventId); - auto result1 = m_sut.attachEvent(m_simpleEvents[1], userDefinedEventId); - auto result2 = m_sut.attachEvent(m_simpleEvents[2], userDefinedEventId); + auto result0 = m_sut.attachEvent(m_simpleEvents[0], USER_DEFINED_EVENT_ID); + auto result1 = m_sut.attachEvent(m_simpleEvents[1], USER_DEFINED_EVENT_ID); + auto result2 = m_sut.attachEvent(m_simpleEvents[2], USER_DEFINED_EVENT_ID); EXPECT_FALSE(result0.has_error()); EXPECT_FALSE(result1.has_error()); EXPECT_FALSE(result2.has_error()); diff --git a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp index b5c5aeddfd2..ca3e449af87 100644 --- a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp +++ b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp @@ -41,6 +41,31 @@ Require(const bool condition, const char* file, const int line, const char* func std::terminate(); } } + +/// @brief struct to find the best fitting unsigned integer type +template +struct bestFittingTypeImpl +{ + using Type_t = uint64_t; +}; + +template <> +struct bestFittingTypeImpl +{ + using Type_t = uint8_t; +}; + +template <> +struct bestFittingTypeImpl +{ + using Type_t = uint16_t; +}; + +template <> +struct bestFittingTypeImpl +{ + using Type_t = uint32_t; +}; } // namespace internal // implementing C++ Core Guideline, I.6. Prefer Expects @@ -206,38 +231,13 @@ static constexpr uint64_t strlen2(char const (&/*notInterested*/)[SizeValue]) return SizeValue - 1; } -/// @brief struct to find the best fitting unsigned integer type -template -struct bestFittingTypeImpl -{ - using Type_t = uint64_t; -}; - -template <> -struct bestFittingTypeImpl -{ - using Type_t = uint8_t; -}; - -template <> -struct bestFittingTypeImpl -{ - using Type_t = uint16_t; -}; - -template <> -struct bestFittingTypeImpl -{ - using Type_t = uint32_t; -}; - /// @brief get the best fitting unsigned integer type for a given value at compile time template struct bestFittingType { - using Type_t = typename bestFittingTypeImpl<(Value > std::numeric_limits::max()), - (Value > std::numeric_limits::max()), - (Value > std::numeric_limits::max())>::Type_t; + using Type_t = typename internal::bestFittingTypeImpl<(Value > std::numeric_limits::max()), + (Value > std::numeric_limits::max()), + (Value > std::numeric_limits::max())>::Type_t; }; template diff --git a/iceoryx_utils/test/moduletests/test_cxx_helplets.cpp b/iceoryx_utils/test/moduletests/test_cxx_helplets.cpp index ae912e95763..9d421425705 100644 --- a/iceoryx_utils/test/moduletests/test_cxx_helplets.cpp +++ b/iceoryx_utils/test/moduletests/test_cxx_helplets.cpp @@ -17,7 +17,10 @@ #include "iceoryx_utils/cxx/helplets.hpp" #include "test.hpp" +#include + using namespace ::testing; +using namespace iox::cxx; namespace { @@ -80,3 +83,53 @@ TEST_F(Helplets_test, maxAlignment) EXPECT_THAT(alignof(FooBar), Eq(alignof(FuBar))); EXPECT_THAT((iox::cxx::maxAlignment()), Eq(alignof(FooBar))); } + +TEST_F(Helplets_test, bestFittingTypeUsesUint8WhenValueSmaller256) +{ + EXPECT_TRUE((std::is_same, uint8_t>::value)); +} + +TEST_F(Helplets_test, bestFittingTypeUsesUint8WhenValueEqualTo255) +{ + EXPECT_TRUE((std::is_same, uint8_t>::value)); +} + +TEST_F(Helplets_test, bestFittingTypeUsesUint16WhenValueEqualTo256) +{ + EXPECT_TRUE((std::is_same, uint16_t>::value)); +} + +TEST_F(Helplets_test, bestFittingTypeUsesUint16WhenValueBetween256And65535) +{ + EXPECT_TRUE((std::is_same, uint16_t>::value)); +} + +TEST_F(Helplets_test, bestFittingTypeUsesUint16WhenValueEqualTo65535) +{ + EXPECT_TRUE((std::is_same, uint16_t>::value)); +} + +TEST_F(Helplets_test, bestFittingTypeUsesUint32WhenValueEqualTo65536) +{ + EXPECT_TRUE((std::is_same, uint32_t>::value)); +} + +TEST_F(Helplets_test, bestFittingTypeUsesUint32WhenValueBetween2p16And2p32) +{ + EXPECT_TRUE((std::is_same, uint32_t>::value)); +} + +TEST_F(Helplets_test, bestFittingTypeUsesUint32WhenValueEqualTo4294967295) +{ + EXPECT_TRUE((std::is_same, uint32_t>::value)); +} + +TEST_F(Helplets_test, bestFittingTypeUsesUint64WhenValueEqualTo4294967296) +{ + EXPECT_TRUE((std::is_same, uint64_t>::value)); +} + +TEST_F(Helplets_test, bestFittingTypeUsesUint32WhenValueGreater2p32) +{ + EXPECT_TRUE((std::is_same, uint64_t>::value)); +} diff --git a/iceoryx_utils/testutils/seppuku.hpp b/iceoryx_utils/testutils/watch_dog.hpp similarity index 91% rename from iceoryx_utils/testutils/seppuku.hpp rename to iceoryx_utils/testutils/watch_dog.hpp index 4f545eeb1b6..910c0f699f6 100644 --- a/iceoryx_utils/testutils/seppuku.hpp +++ b/iceoryx_utils/testutils/watch_dog.hpp @@ -27,21 +27,21 @@ using namespace iox::units::duration_literals; // class for killing the application if a test takes too much time to finish -class Seppuku +class Watchdog { public: - Seppuku(const iox::units::Duration& timeToWait) noexcept + Watchdog(const iox::units::Duration& timeToWait) noexcept : m_timeToWait(timeToWait) { } - ~Seppuku() noexcept + ~Watchdog() noexcept { m_seppukuSemaphore.post(); m_seppuku.join(); } - void doSeppuku(std::function f) noexcept + void watchAndActOnFailure(std::function f) noexcept { m_seppuku = std::thread([=] { m_seppukuSemaphore.timedWait(m_timeToWait, false) From 7263e0329aeaeb62f62e444e392fa44454c28513 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Mon, 1 Mar 2021 15:49:10 +0100 Subject: [PATCH 129/143] iox-#350 fixed copy and move assignment in smart lock and added GetCopy to acquire a copy of the underlying type Signed-off-by: Christian Eltzschig --- .../internal/concurrent/smart_lock.hpp | 33 +++++---- .../internal/concurrent/smart_lock.inl | 68 ++++++++++++------- 2 files changed, 60 insertions(+), 41 deletions(-) diff --git a/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.hpp b/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.hpp index bc11627bc33..1e0d4507c10 100644 --- a/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.hpp +++ b/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.hpp @@ -54,11 +54,11 @@ class smart_lock class Proxy { public: - Proxy(T* base, MutexType* lock); - ~Proxy(); + Proxy(T* base, MutexType* lock) noexcept; + ~Proxy() noexcept; - T* operator->(); - T* operator->() const; + T* operator->() noexcept; + T* operator->() const noexcept; private: T* base; @@ -66,13 +66,13 @@ class smart_lock }; public: - smart_lock(); - smart_lock(const T& t); - smart_lock(const smart_lock& rhs); - smart_lock(smart_lock&& rhs); - smart_lock& operator=(const smart_lock& rhs); - smart_lock& operator=(smart_lock&& rhs); - ~smart_lock() = default; + smart_lock() noexcept; + smart_lock(const T& t) noexcept; + smart_lock(const smart_lock& rhs) noexcept; + smart_lock(smart_lock&& rhs) noexcept; + smart_lock& operator=(const smart_lock& rhs) noexcept; + smart_lock& operator=(smart_lock&& rhs) noexcept; + ~smart_lock() noexcept = default; /// @brief The arrow operator returns a proxy object which locks the mutex /// of smart_lock and has another arrow operator defined which @@ -83,7 +83,7 @@ class smart_lock /// iox::concurrent::smart_lock> threadSafeVector; /// threadSafeVector->push_back(123); // this call is secured by a mutex /// @endcode - Proxy operator->(); + Proxy operator->() noexcept; /// @brief The arrow operator returns a proxy object which locks the mutex /// of smart_lock and has another arrow operator defined which @@ -94,7 +94,7 @@ class smart_lock /// iox::concurrent::smart_lock> threadSafeVector; /// threadSafeVector->push_back(123); // this call is secured by a mutex /// @endcode - Proxy operator->() const; + Proxy operator->() const noexcept; /// @brief If you need to lock your object over multiple method calls you /// acquire a scope guard which locks the object as long as this @@ -117,7 +117,7 @@ class smart_lock /// if ( iter != vectorGuard->end() ) /// vectorGuard->erase(iter); /// } - Proxy GetScopeGuard(); + Proxy GetScopeGuard() noexcept; /// @brief If you need to lock your object over multiple method calls you /// acquire a scope guard which locks the object as long as this @@ -140,7 +140,10 @@ class smart_lock /// if ( iter != vectorGuard->end() ) /// vectorGuard->erase(iter); /// } - Proxy GetScopeGuard() const; + Proxy GetScopeGuard() const noexcept; + + /// @brief Returns a copy of the underlying object + T GetCopy() const noexcept; private: T base; diff --git a/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.inl b/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.inl index 816b4a004bf..21c0b10ec2e 100644 --- a/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.inl +++ b/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.inl @@ -23,82 +23,98 @@ namespace iox namespace concurrent { template -smart_lock make_smart_lock(Targs&&... args) +smart_lock make_smart_lock(Targs&&... args) noexcept { return smart_lock(T(std::forward(args)...)); } template -smart_lock::smart_lock() +smart_lock::smart_lock() noexcept { } template -smart_lock::smart_lock(const T& t) +smart_lock::smart_lock(const T& t) noexcept : base(t) { } template -smart_lock::smart_lock(const smart_lock& rhs) +smart_lock::smart_lock(const smart_lock& rhs) noexcept { - std::lock_guard guard(rhs.lock); + std::lock_guard guard(rhs.lock); base = rhs.base; } template -smart_lock::smart_lock(smart_lock&& rhs) +smart_lock::smart_lock(smart_lock&& rhs) noexcept { - std::lock_guard guard(rhs.lock); + std::lock_guard guard(rhs.lock); base = std::move(rhs.base); } template -smart_lock& smart_lock::operator=(const smart_lock& rhs) +smart_lock& smart_lock::operator=(const smart_lock& rhs) noexcept { - std::lock(lock, rhs.lock); - std::lock_guard guard(lock, std::adopt_lock); - std::lock_guard guardRhs(rhs.lock, std::adopt_lock); - base = rhs.base; + if (this != rhs) + { + std::lock(lock, rhs.lock); + std::lock_guard guard(lock, std::adopt_lock); + std::lock_guard guardRhs(rhs.lock, std::adopt_lock); + base = rhs.base; + } + + return *this; } template -smart_lock& smart_lock::operator=(smart_lock&& rhs) -{ - std::lock(lock, rhs.lock); - std::lock_guard guard(lock, std::adopt_lock); - std::lock_guard guardRhs(rhs.lock, std::adopt_lock); - base = std::move(rhs.base); +smart_lock& smart_lock::operator=(smart_lock&& rhs) noexcept +{ + if (this != &rhs) + { + std::lock(lock, rhs.lock); + std::lock_guard guard(lock, std::adopt_lock); + std::lock_guard guardRhs(rhs.lock, std::adopt_lock); + base = std::move(rhs.base); + } + return *this; } template -typename smart_lock::Proxy smart_lock::operator->() +typename smart_lock::Proxy smart_lock::operator->() noexcept { return Proxy(&base, &lock); } template -typename smart_lock::Proxy smart_lock::operator->() const +typename smart_lock::Proxy smart_lock::operator->() const noexcept { return const_cast*>(this)->operator->(); } template -typename smart_lock::Proxy smart_lock::GetScopeGuard() +typename smart_lock::Proxy smart_lock::GetScopeGuard() noexcept { return Proxy(&base, &lock); } template -typename smart_lock::Proxy smart_lock::GetScopeGuard() const +typename smart_lock::Proxy smart_lock::GetScopeGuard() const noexcept { return const_cast*>(this)->GetScopeGuard(); } +template +inline T smart_lock::GetCopy() const noexcept +{ + std::lock_guard guard(lock); + return base; +} + // PROXY OBJECT template -smart_lock::Proxy::Proxy(T* base, MutexType* lock) +smart_lock::Proxy::Proxy(T* base, MutexType* lock) noexcept : base(base) , lock(lock) { @@ -106,19 +122,19 @@ smart_lock::Proxy::Proxy(T* base, MutexType* lock) } template -smart_lock::Proxy::~Proxy() +smart_lock::Proxy::~Proxy() noexcept { lock->unlock(); } template -T* smart_lock::Proxy::operator->() +T* smart_lock::Proxy::operator->() noexcept { return base; } template -T* smart_lock::Proxy::operator->() const +T* smart_lock::Proxy::operator->() const noexcept { return const_cast::Proxy*>(this)->operator->(); } From af1dc4daae3cb36b4ea707c9ef7d4c4fac97b637 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Mon, 1 Mar 2021 16:43:41 +0100 Subject: [PATCH 130/143] iox-#350 cleaned up tests and use smart_lock to fix race conditions in test Signed-off-by: Christian Eltzschig --- .../moduletests/test_popo_active_call_set.cpp | 53 ++++++++++--------- .../internal/concurrent/smart_lock.hpp | 4 +- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index 9c135c6efcf..bab6be519b2 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -21,6 +21,7 @@ #include "iceoryx_posh/popo/user_trigger.hpp" #include "iceoryx_utils/cxx/optional.hpp" #include "iceoryx_utils/cxx/vector.hpp" +#include "iceoryx_utils/internal/concurrent/smart_lock.hpp" #include "iceoryx_utils/posix_wrapper/semaphore.hpp" #include "mocks/wait_set_mock.hpp" #include "test.hpp" @@ -76,7 +77,7 @@ class SimpleEventClass void enableEvent(iox::popo::TriggerHandle&& handle) noexcept { - m_handleHypnotoad = std::move(handle); + m_handleNoEventEnum = std::move(handle); } void invalidateTrigger(const uint64_t id) noexcept @@ -90,6 +91,10 @@ class SimpleEventClass { m_handleStoepsel.invalidate(); } + else if (m_handleNoEventEnum.getUniqueId() == id) + { + m_handleNoEventEnum.invalidate(); + } } void disableEvent(const SimpleEvent event) noexcept @@ -107,9 +112,8 @@ class SimpleEventClass void disableEvent() noexcept { - m_handleHypnotoad.reset(); + m_handleNoEventEnum.reset(); } - void triggerStoepsel() noexcept { m_hasTriggered.store(true); @@ -123,6 +127,7 @@ class SimpleEventClass iox::popo::TriggerHandle m_handleHypnotoad; iox::popo::TriggerHandle m_handleStoepsel; + iox::popo::TriggerHandle m_handleNoEventEnum; mutable std::atomic_bool m_hasTriggered{false}; }; @@ -147,8 +152,8 @@ struct TriggerSourceAndCount std::atomic m_count{0U}; }; -std::vector g_toBeAttached; -std::vector g_toBeDetached; +iox::concurrent::smart_lock> g_toBeAttached; +iox::concurrent::smart_lock> g_toBeDetached; std::array g_triggerCallbackArg; uint64_t g_triggerCallbackRuntimeInMs = 0U; iox::cxx::optional g_callbackBlocker; @@ -171,7 +176,7 @@ class ActiveCallSet_test : public Test static void attachCallback(SimpleEventClass* const) noexcept { - for (auto& e : g_toBeAttached) + for (auto& e : g_toBeAttached.GetCopy()) { e.sut->attachEvent(*e.object, SimpleEvent::StoepselBachelorParty, triggerCallback<0U>); } @@ -179,7 +184,7 @@ class ActiveCallSet_test : public Test static void detachCallback(SimpleEventClass* const) noexcept { - for (auto& e : g_toBeDetached) + for (auto& e : g_toBeDetached.GetCopy()) { e.sut->detachEvent(*e.object, SimpleEvent::StoepselBachelorParty); } @@ -187,7 +192,7 @@ class ActiveCallSet_test : public Test static void notifyAndThenDetachStoepselCallback(SimpleEventClass* const) noexcept { - for (auto& e : g_toBeDetached) + for (auto& e : g_toBeDetached.GetCopy()) { e.object->triggerStoepsel(); e.sut->detachEvent(*e.object, SimpleEvent::StoepselBachelorParty); @@ -206,8 +211,8 @@ class ActiveCallSet_test : public Test m_sut.emplace(&m_eventVarData); g_invalidateTriggerId = 0U; g_triggerCallbackRuntimeInMs = 0U; - g_toBeAttached.clear(); - g_toBeDetached.clear(); + g_toBeAttached->clear(); + g_toBeDetached->clear(); }; void activateTriggerCallbackBlocker() noexcept @@ -373,10 +378,10 @@ TEST_F(ActiveCallSet_test, DetachMakesSpaceForAnotherAttachWithoutEventEnum) m_sut->attachEvent(m_simpleEvents[m_sut->capacity()], ActiveCallSet_test::triggerCallback<0U>).has_error()); } -TEST_F(ActiveCallSet_test, AttachingEventWithoutEventTypeLeadsToAttachedTriggerHandle) +TEST_F(ActiveCallSet_test, AttachingEventWithoutEventTypeLeadsToAttachedNoEventEnumTriggerHandle) { m_sut->attachEvent(m_simpleEvents[0U], ActiveCallSet_test::triggerCallback<0U>); - EXPECT_TRUE(m_simpleEvents[0U].m_handleHypnotoad.isValid()); + EXPECT_TRUE(m_simpleEvents[0U].m_handleNoEventEnum.isValid()); } TEST_F(ActiveCallSet_test, AttachingEventWithEventTypeLeadsToAttachedTriggerHandle) @@ -431,7 +436,7 @@ TEST_F(ActiveCallSet_test, DetachingDifferentClassWithSameEventEnumChangesNothin EXPECT_THAT(m_sut->size(), Eq(1U)); } -TEST_F(ActiveCallSet_test, AttachingTillCapacityFilledSetsUpTriggerHandle) +TEST_F(ActiveCallSet_test, AttachingWithoutEnumTillCapacityFilledSetsUpNoEventEnumTriggerHandle) { for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { @@ -440,7 +445,7 @@ TEST_F(ActiveCallSet_test, AttachingTillCapacityFilledSetsUpTriggerHandle) for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { - EXPECT_TRUE(m_simpleEvents[i].m_handleHypnotoad.isValid()); + EXPECT_TRUE(m_simpleEvents[i].m_handleNoEventEnum.isValid()); } } @@ -470,12 +475,12 @@ TEST_F(ActiveCallSet_test, AttachedEventDTorDetachesItself) EXPECT_THAT(m_sut->size(), Eq(0U)); } -TEST_F(ActiveCallSet_test, AttachingSimpleEventSetsTriggerHandle) +TEST_F(ActiveCallSet_test, AttachingSimpleEventWithoutEnumSetsNoEventEnumTriggerHandle) { SimpleEventClass fuu; m_sut->attachEvent(fuu, ActiveCallSet_test::triggerCallback<0U>); - EXPECT_TRUE(static_cast(fuu.m_handleHypnotoad)); + EXPECT_TRUE(static_cast(fuu.m_handleNoEventEnum)); } TEST_F(ActiveCallSet_test, DetachingSimpleEventResetsTriggerHandle) @@ -864,10 +869,10 @@ TIMING_TEST_F(ActiveCallSet_test, AttachingDetachingRunsIndependentOfCallback, R // BEGIN attach / detach in callbacks ////////////////////////////////// TIMING_TEST_F(ActiveCallSet_test, DetachingSelfInCallbackWorks, Repeat(5), [&] { - g_toBeDetached.clear(); + g_toBeDetached->clear(); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - g_toBeDetached.push_back({&events[0U], &*m_sut}); + g_toBeDetached->push_back({&events[0U], &*m_sut}); m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, detachCallback); events[0U].triggerStoepsel(); @@ -878,10 +883,10 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingSelfInCallbackWorks, Repeat(5), [&] { }); TIMING_TEST_F(ActiveCallSet_test, DetachingNonSelfEventInCallbackWorks, Repeat(5), [&] { - g_toBeDetached.clear(); + g_toBeDetached->clear(); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - g_toBeDetached.push_back({&events[1U], &*m_sut}); + g_toBeDetached->push_back({&events[1U], &*m_sut}); m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, detachCallback); m_sut->attachEvent(events[1U], SimpleEvent::StoepselBachelorParty, triggerCallback<1U>); @@ -893,10 +898,10 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingNonSelfEventInCallbackWorks, Repeat(5 }); TIMING_TEST_F(ActiveCallSet_test, DetachedCallbacksAreNotBeingCalledWhenTriggeredBefore, Repeat(5), [&] { - g_toBeDetached.clear(); + g_toBeDetached->clear(); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - g_toBeDetached.push_back({&events[1U], &*m_sut}); + g_toBeDetached->push_back({&events[1U], &*m_sut}); m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, notifyAndThenDetachStoepselCallback); m_sut->attachEvent(events[1U], SimpleEvent::StoepselBachelorParty, triggerCallback<1U>); @@ -915,10 +920,10 @@ TIMING_TEST_F(ActiveCallSet_test, DetachedCallbacksAreNotBeingCalledWhenTriggere }); TIMING_TEST_F(ActiveCallSet_test, AttachingInCallbackWorks, Repeat(1), [&] { - g_toBeAttached.clear(); + g_toBeAttached->clear(); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); - g_toBeAttached.push_back({&events[1U], &*m_sut}); + g_toBeAttached->push_back({&events[1U], &*m_sut}); m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, attachCallback); events[0U].triggerStoepsel(); diff --git a/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.hpp b/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.hpp index 1e0d4507c10..e6511a2e0b6 100644 --- a/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.hpp +++ b/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.hpp @@ -47,7 +47,7 @@ namespace concurrent /// } /// } /// @endcode -template +template class smart_lock { private: @@ -147,7 +147,7 @@ class smart_lock private: T base; - MutexType lock; + mutable MutexType lock; }; } // namespace concurrent } // namespace iox From ab231e3c49278d8ed7a2731b11e82448ad8e4edc Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Mon, 1 Mar 2021 16:50:29 +0100 Subject: [PATCH 131/143] iox-#350 renaming tests so that it is described more clearly what the intention is Signed-off-by: Christian Eltzschig --- iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index bab6be519b2..b8143c17653 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -400,7 +400,7 @@ TEST_F(ActiveCallSet_test, AttachingSameEventWithEventEnumTwiceFails) EXPECT_THAT(result.get_error(), Eq(ActiveCallSetError::EVENT_ALREADY_ATTACHED)); } -TEST_F(ActiveCallSet_test, AttachingSameEventWithoutEventEnumTwiceFails) +TEST_F(ActiveCallSet_test, OverridingAlreadyAttachedEventWithoutEnumFails) { m_sut->attachEvent(m_simpleEvents[0U], ActiveCallSet_test::triggerCallback<0U>); @@ -409,7 +409,7 @@ TEST_F(ActiveCallSet_test, AttachingSameEventWithoutEventEnumTwiceFails) EXPECT_THAT(result.get_error(), Eq(ActiveCallSetError::EVENT_ALREADY_ATTACHED)); } -TEST_F(ActiveCallSet_test, AttachingSameClassWithTwoDifferentEventsWorks) +TEST_F(ActiveCallSet_test, OverridingAlreadyAttachedEventWithEnumFails) { m_sut->attachEvent(m_simpleEvents[0U], SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); From 311f6cf03b8672c1338fd33a4fb67f40f7bf7a9e Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 2 Mar 2021 09:53:27 +0100 Subject: [PATCH 132/143] iox-#350 rename seppuku to watchdog Signed-off-by: Marika Lehmann --- .../moduletests/test_popo_event_variable.cpp | 28 +++++++++---------- iceoryx_utils/testutils/watch_dog.hpp | 18 ++++++------ 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp index 8e3fcc9dd4e..2cc80ea57b8 100644 --- a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp @@ -118,8 +118,8 @@ TEST_F(EventVariable_test, DestroyWakesUpWaitWhichReturnsEmptyVector) NotificationVector_t activeNotifications; - Watchdog seppuku(m_timeToWait); - seppuku.watchAndActOnFailure([] { std::terminate(); }); + Watchdog watchdog(m_timeToWait); + watchdog.watchAndActOnFailure([] { std::terminate(); }); std::thread waiter([&] { activeNotifications = sut.wait(); @@ -136,8 +136,8 @@ TEST_F(EventVariable_test, GetCorrectNotificationVectorAfterNotifyAndWait) EventNotifier notifier(m_eventVarData, EVENT_INDEX); EventListener listener(m_eventVarData); - Watchdog seppuku(m_timeToWait); - seppuku.watchAndActOnFailure([&] { listener.destroy(); }); + Watchdog watchdog(m_timeToWait); + watchdog.watchAndActOnFailure([&] { listener.destroy(); }); notifier.notify(); const auto& activeNotifications = listener.wait(); @@ -154,8 +154,8 @@ TEST_F(EventVariable_test, GetCorrectNotificationVectorAfterMultipleNotifyAndWai EventNotifier notifier2(m_eventVarData, SECOND_EVENT_INDEX); EventListener listener(m_eventVarData); - Watchdog seppuku(m_timeToWait); - seppuku.watchAndActOnFailure([&] { listener.destroy(); }); + Watchdog watchdog(m_timeToWait); + watchdog.watchAndActOnFailure([&] { listener.destroy(); }); notifier1.notify(); notifier2.notify(); @@ -173,8 +173,8 @@ TEST_F(EventVariable_test, WaitAndNotifyResultsInCorrectNotificationVector) EventListener listener(m_eventVarData); NotificationVector_t activeNotifications; - Watchdog seppuku(m_timeToWait); - seppuku.watchAndActOnFailure([&] { listener.destroy(); }); + Watchdog watchdog(m_timeToWait); + watchdog.watchAndActOnFailure([&] { listener.destroy(); }); std::thread waiter([&] { activeNotifications = listener.wait(); @@ -195,8 +195,8 @@ TIMING_TEST_F(EventVariable_test, WaitBlocks, Repeat(5), [&] { iox::posix::Semaphore::create(iox::posix::CreateUnnamedSingleProcessSemaphore, 0U).value(); std::atomic_bool hasWaited{false}; - Watchdog seppuku(m_timeToWait); - seppuku.watchAndActOnFailure([&] { listener.destroy(); }); + Watchdog watchdog(m_timeToWait); + watchdog.watchAndActOnFailure([&] { listener.destroy(); }); std::thread waiter([&] { threadSetupSemaphore.post(); @@ -225,8 +225,8 @@ TIMING_TEST_F(EventVariable_test, SecondWaitBlocksUntilNewNotification, Repeat(5 iox::posix::Semaphore::create(iox::posix::CreateUnnamedSingleProcessSemaphore, 0U).value(); std::atomic_bool hasWaited{false}; - Watchdog seppukuFirstWait(m_timeToWait); - seppukuFirstWait.watchAndActOnFailure([&] { listener.destroy(); }); + Watchdog watchdogFirstWait(m_timeToWait); + watchdogFirstWait.watchAndActOnFailure([&] { listener.destroy(); }); notifier1.notify(); notifier2.notify(); @@ -236,8 +236,8 @@ TIMING_TEST_F(EventVariable_test, SecondWaitBlocksUntilNewNotification, Repeat(5 EXPECT_THAT(activeNotifications[0], Eq(SECOND_EVENT_INDEX)); EXPECT_THAT(activeNotifications[1], Eq(FIRST_EVENT_INDEX)); - Watchdog seppukuSecondWait(m_timeToWait); - seppukuSecondWait.watchAndActOnFailure([&] { listener.destroy(); }); + Watchdog watchdogSecondWait(m_timeToWait); + watchdogSecondWait.watchAndActOnFailure([&] { listener.destroy(); }); std::thread waiter([&] { threadSetupSemaphore.post(); diff --git a/iceoryx_utils/testutils/watch_dog.hpp b/iceoryx_utils/testutils/watch_dog.hpp index 910c0f699f6..1f2c058e5e4 100644 --- a/iceoryx_utils/testutils/watch_dog.hpp +++ b/iceoryx_utils/testutils/watch_dog.hpp @@ -14,8 +14,8 @@ // // SPDX-License-Identifier: Apache-2.0 -#ifndef IOX_UTILS_TESTUTILS_SEPPUKU_HPP -#define IOX_UTILS_TESTUTILS_SEPPUKU_HPP +#ifndef IOX_UTILS_TESTUTILS_WATCH_DOG_HPP +#define IOX_UTILS_TESTUTILS_WATCH_DOG_HPP #include "iceoryx_utils/internal/units/duration.hpp" #include "iceoryx_utils/posix_wrapper/semaphore.hpp" @@ -37,14 +37,14 @@ class Watchdog ~Watchdog() noexcept { - m_seppukuSemaphore.post(); - m_seppuku.join(); + m_watchdogSemaphore.post(); + m_watchdog.join(); } void watchAndActOnFailure(std::function f) noexcept { - m_seppuku = std::thread([=] { - m_seppukuSemaphore.timedWait(m_timeToWait, false) + m_watchdog = std::thread([=] { + m_watchdogSemaphore.timedWait(m_timeToWait, false) .and_then([&](auto& result) { if (result == iox::posix::SemaphoreWaitState::TIMEOUT) { @@ -58,9 +58,9 @@ class Watchdog private: iox::units::Duration m_timeToWait{0_s}; - iox::posix::Semaphore m_seppukuSemaphore{ + iox::posix::Semaphore m_watchdogSemaphore{ iox::posix::Semaphore::create(iox::posix::CreateUnnamedSingleProcessSemaphore, 0U).value()}; - std::thread m_seppuku; + std::thread m_watchdog; }; -#endif // IOX_UTILS_TESTUTILS_SEPPUKU_HPP +#endif // IOX_UTILS_TESTUTILS_WATCH_DOG_HPP From bfd91a28b69853989dc1c3399f5898aa3fec6b7e Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 2 Mar 2021 10:20:28 +0100 Subject: [PATCH 133/143] iox-#350 use NotificationVector_t alias Signed-off-by: Marika Lehmann --- .../source/popo/building_blocks/event_listener.cpp | 7 +++---- iceoryx_posh/test/moduletests/test_popo_event_variable.cpp | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp index b358975afca..eea12ced958 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp @@ -37,14 +37,13 @@ void EventListener::destroy() noexcept EventListener::NotificationVector_t EventListener::wait() noexcept { - cxx::vector, - MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET> - activeNotifications; + using Type_t = iox::cxx::BestFittingType_t; + NotificationVector_t activeNotifications; resetSemaphore(); while (!m_toBeDestroyed.load(std::memory_order_relaxed)) { - for (uint8_t i = 0U; i < MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; i++) + for (Type_t i = 0U; i < MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; i++) { if (m_pointerToEventVariableData->m_activeNotifications[i].load(std::memory_order_relaxed)) { diff --git a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp index 2cc80ea57b8..d84078968de 100644 --- a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp @@ -32,7 +32,7 @@ class EventVariable_test : public Test { public: using Type_t = iox::cxx::BestFittingType_t; - using NotificationVector_t = iox::cxx::vector; + using NotificationVector_t = EventListener::NotificationVector_t; const iox::ProcessName_t m_process{"Ferdinand"}; EventVariableData m_eventVarData{m_process}; From 8141aa2ed121c118841a7b55a94cd0c0639a4018 Mon Sep 17 00:00:00 2001 From: Marika Lehmann Date: Tue, 2 Mar 2021 15:29:44 +0100 Subject: [PATCH 134/143] iox-#350 ignore warnings for comparisons in bestFittingType implementation Signed-off-by: Marika Lehmann --- iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp index ca3e449af87..9662d470791 100644 --- a/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp +++ b/iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp @@ -235,9 +235,13 @@ static constexpr uint64_t strlen2(char const (&/*notInterested*/)[SizeValue]) template struct bestFittingType { +/// ignore the warnings because we need the comparisons to find the best fitting type +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wtype-limits" using Type_t = typename internal::bestFittingTypeImpl<(Value > std::numeric_limits::max()), (Value > std::numeric_limits::max()), (Value > std::numeric_limits::max())>::Type_t; +#pragma GCC diagnostic pop }; template From bf3fc43f80c589bb41ec3c44b46dfa9d3671cbdf Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 2 Mar 2021 19:27:19 +0100 Subject: [PATCH 135/143] iox-#350 uniqueTriggerId is set to INVALID_TRIGGER_ID when the Trigger / TriggerHandle is not valid Signed-off-by: Christian Eltzschig --- .../include/iceoryx_posh/popo/trigger.hpp | 2 +- .../iceoryx_posh/popo/trigger_handle.hpp | 3 +- iceoryx_posh/source/popo/trigger.cpp | 2 ++ iceoryx_posh/source/popo/trigger_handle.cpp | 2 +- .../test/moduletests/test_popo_trigger.cpp | 36 +++++++++++++++++-- .../moduletests/test_popo_trigger_handle.cpp | 5 +++ 6 files changed, 44 insertions(+), 6 deletions(-) diff --git a/iceoryx_posh/include/iceoryx_posh/popo/trigger.hpp b/iceoryx_posh/include/iceoryx_posh/popo/trigger.hpp index a3712b3e080..13c44a91521 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/trigger.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/trigger.hpp @@ -107,7 +107,7 @@ class Trigger cxx::ConstMethodCallback m_hasTriggeredCallback; cxx::MethodCallback m_resetCallback; - uint64_t m_uniqueId = 0U; + uint64_t m_uniqueId = INVALID_TRIGGER_ID; static std::atomic uniqueIdCounter; // = 0U; }; diff --git a/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp b/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp index 6e70ac247e1..d915579fc81 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp @@ -22,6 +22,7 @@ #include "iceoryx_posh/popo/trigger.hpp" #include "iceoryx_utils/cxx/method_callback.hpp" +#include #include namespace iox @@ -92,7 +93,7 @@ class TriggerHandle private: ConditionVariableData* m_conditionVariableDataPtr = nullptr; cxx::MethodCallback m_resetCallback; - uint64_t m_uniqueTriggerId = 0U; + uint64_t m_uniqueTriggerId = Trigger::INVALID_TRIGGER_ID; bool m_doesContainEventVariable = false; mutable std::recursive_mutex m_mutex; }; diff --git a/iceoryx_posh/source/popo/trigger.cpp b/iceoryx_posh/source/popo/trigger.cpp index e5ed5cba2ae..8dff1a108f3 100644 --- a/iceoryx_posh/source/popo/trigger.cpp +++ b/iceoryx_posh/source/popo/trigger.cpp @@ -22,6 +22,7 @@ namespace iox namespace popo { std::atomic Trigger::uniqueIdCounter{0U}; +constexpr uint64_t Trigger::INVALID_TRIGGER_ID; Trigger::~Trigger() { @@ -57,6 +58,7 @@ void Trigger::invalidate() noexcept { m_hasTriggeredCallback = cxx::ConstMethodCallback(); m_resetCallback = cxx::MethodCallback(); + m_uniqueId = INVALID_TRIGGER_ID; } Trigger::operator bool() const noexcept diff --git a/iceoryx_posh/source/popo/trigger_handle.cpp b/iceoryx_posh/source/popo/trigger_handle.cpp index 7594b4e3da9..4bf97bdc15c 100644 --- a/iceoryx_posh/source/popo/trigger_handle.cpp +++ b/iceoryx_posh/source/popo/trigger_handle.cpp @@ -120,7 +120,7 @@ void TriggerHandle::invalidate() noexcept m_conditionVariableDataPtr = nullptr; m_resetCallback = cxx::MethodCallback(); - m_uniqueTriggerId = 0U; + m_uniqueTriggerId = Trigger::INVALID_TRIGGER_ID; } ConditionVariableData* TriggerHandle::getConditionVariableData() noexcept diff --git a/iceoryx_posh/test/moduletests/test_popo_trigger.cpp b/iceoryx_posh/test/moduletests/test_popo_trigger.cpp index f99f9bd1de1..369ec4c0d0b 100644 --- a/iceoryx_posh/test/moduletests/test_popo_trigger.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_trigger.cpp @@ -119,6 +119,25 @@ TEST_F(Trigger_test, MovedAssignedValidTriggerIsValid) EXPECT_TRUE(static_cast(sut)); } +TEST_F(Trigger_test, MovedConstructedOriginIsInvalidTriggerAfterMove) +{ + Trigger trigger = createValidTrigger(); + Trigger sut{std::move(trigger)}; + + EXPECT_FALSE(trigger.isValid()); + EXPECT_THAT(trigger.getUniqueId(), Eq(Trigger::INVALID_TRIGGER_ID)); +} + +TEST_F(Trigger_test, MovedAssignedOriginIsInvalidTriggerAfterMove) +{ + Trigger sut; + Trigger trigger = createValidTrigger(); + sut = std::move(trigger); + + EXPECT_FALSE(trigger.isValid()); + EXPECT_THAT(trigger.getUniqueId(), Eq(Trigger::INVALID_TRIGGER_ID)); +} + TEST_F(Trigger_test, TriggerWithNullptrOriginIsValid) { uint64_t eventId = 0U; @@ -177,11 +196,20 @@ TEST_F(Trigger_test, InvalidateInvalidatesTrigger) } TEST_F(Trigger_test, ResetCallsResetcallbackWithCorrectTriggerOrigin) +{ + Trigger sut = createValidTrigger(); + auto uniqueId = sut.getUniqueId(); + sut.reset(); + + EXPECT_EQ(m_triggerClass.m_resetCallTriggerArg, uniqueId); +} + +TEST_F(Trigger_test, ResetSetsTriggerIdToInvalid) { Trigger sut = createValidTrigger(); sut.reset(); - EXPECT_EQ(m_triggerClass.m_resetCallTriggerArg, sut.getUniqueId()); + EXPECT_EQ(sut.getUniqueId(), Trigger::INVALID_TRIGGER_ID); } TEST_F(Trigger_test, TriggerWithEmptyResetInvalidatesTriggerWhenBeingResetted) @@ -255,9 +283,10 @@ TEST_F(Trigger_test, UpdateOriginLeadsToDifferentResetCallback) TriggerClass secondTriggerClass; sut.updateOrigin(&secondTriggerClass); + auto uniqueId = sut.getUniqueId(); sut.reset(); - EXPECT_EQ(secondTriggerClass.m_resetCallTriggerArg, sut.getUniqueId()); + EXPECT_EQ(secondTriggerClass.m_resetCallTriggerArg, uniqueId); } TEST_F(Trigger_test, UpdateOriginDoesNotUpdateResetIfItsNotOriginatingFromOrigin) @@ -271,9 +300,10 @@ TEST_F(Trigger_test, UpdateOriginDoesNotUpdateResetIfItsNotOriginatingFromOrigin TriggerClass::callback); sut.updateOrigin(&secondTriggerClass); + auto uniqueId = sut.getUniqueId(); sut.reset(); - EXPECT_EQ(thirdTriggerClass.m_resetCallTriggerArg, sut.getUniqueId()); + EXPECT_EQ(thirdTriggerClass.m_resetCallTriggerArg, uniqueId); } TEST_F(Trigger_test, UpdateOriginUpdatesOriginOfEventInfo) diff --git a/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp b/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp index 9c6767ed2cd..58cd0c08a1c 100644 --- a/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp @@ -51,6 +51,7 @@ TEST_F(TriggerHandle_test, defaultCTorConstructsInvalidHandle) TriggerHandle sut2; EXPECT_FALSE(sut2.isValid()); + EXPECT_THAT(sut2.getUniqueId(), Eq(Trigger::INVALID_TRIGGER_ID)); EXPECT_FALSE(sut2); } @@ -60,6 +61,7 @@ TEST_F(TriggerHandle_test, InvalidateCreatesInvalidTriggerHandle) EXPECT_FALSE(m_sut.isValid()); EXPECT_FALSE(m_sut); + EXPECT_THAT(m_sut.getUniqueId(), Eq(Trigger::INVALID_TRIGGER_ID)); } TEST_F(TriggerHandle_test, ResetCreatesInvalidTriggerHandle) @@ -68,12 +70,14 @@ TEST_F(TriggerHandle_test, ResetCreatesInvalidTriggerHandle) EXPECT_FALSE(m_sut.isValid()); EXPECT_FALSE(m_sut); + EXPECT_THAT(m_sut.getUniqueId(), Eq(Trigger::INVALID_TRIGGER_ID)); } TEST_F(TriggerHandle_test, ResetCallsResetCallbackWhenHandleIsValid) { m_sut.reset(); EXPECT_EQ(m_resetCallbackId, 12); + EXPECT_THAT(m_sut.getUniqueId(), Eq(Trigger::INVALID_TRIGGER_ID)); } TEST_F(TriggerHandle_test, ResetDoesNotCallResetCallbackWhenHandleIsInvalid) @@ -81,6 +85,7 @@ TEST_F(TriggerHandle_test, ResetDoesNotCallResetCallbackWhenHandleIsInvalid) m_sut.invalidate(); m_sut.reset(); EXPECT_EQ(m_resetCallbackId, 0); + EXPECT_THAT(m_sut.getUniqueId(), Eq(Trigger::INVALID_TRIGGER_ID)); } TEST_F(TriggerHandle_test, getConditionVariableDataReturnsCorrectVar) From 59e999b02684129bfdf6fca98a6d9e4f14d0d886 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Thu, 4 Mar 2021 14:00:56 +0100 Subject: [PATCH 136/143] iox-#350 restructured tests, added a detailed explanation with some test intentions, reduced code duplication Signed-off-by: Christian Eltzschig --- .../moduletests/test_popo_active_call_set.cpp | 137 ++++++++++++------ iceoryx_utils/testutils/watch_dog.hpp | 7 +- 2 files changed, 96 insertions(+), 48 deletions(-) diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index b8143c17653..ce3ff050154 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -26,6 +26,7 @@ #include "mocks/wait_set_mock.hpp" #include "test.hpp" #include "testutils/timing_test.hpp" +#include "testutils/watch_dog.hpp" #include #include @@ -230,6 +231,38 @@ class ActiveCallSet_test : public Test } } + bool fillUpWithSimpleEvents() + { + for (uint64_t i = 0U; i < m_sut->capacity(); ++i) + { + bool hasError = m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>).has_error(); + EXPECT_FALSE(hasError); + if (hasError) + { + return false; + } + EXPECT_THAT(m_sut->size(), Eq(i + 1)); + } + return true; + } + bool fillUpWithSimpleEventsWithEnum(const SimpleEvent eventType) + { + for (uint64_t i = 0U; i < m_sut->capacity(); ++i) + { + bool hasError = + m_sut->attachEvent(m_simpleEvents[i], eventType, ActiveCallSet_test::triggerCallback<0U>).has_error(); + EXPECT_FALSE(hasError); + if (hasError) + { + return false; + } + + EXPECT_THAT(m_sut->size(), Eq(i + 1)); + } + return true; + } + + void TearDown(){}; @@ -239,6 +272,8 @@ class ActiveCallSet_test : public Test EventVariableData m_eventVarData{"Maulbeerblättle"}; iox::cxx::optional m_sut; + const iox::units::Duration m_fatalTimeout = 2_s; + Watchdog m_watchdog{m_fatalTimeout}; static constexpr uint64_t CALLBACK_WAIT_IN_MS = 100U; }; @@ -289,31 +324,20 @@ TEST_F(ActiveCallSet_test, AttachingWithoutEnumIfEnoughSpaceAvailableWorks) TEST_F(ActiveCallSet_test, AttachWithoutEnumTillCapacityIsFullWorks) { - for (uint64_t i = 0U; i < m_sut->capacity(); ++i) - { - EXPECT_FALSE(m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>).has_error()); - EXPECT_THAT(m_sut->size(), Eq(i + 1)); - } + fillUpWithSimpleEvents(); EXPECT_THAT(m_sut->size(), Eq(m_sut->capacity())); } TEST_F(ActiveCallSet_test, DetachDecreasesSize) { - for (uint64_t i = 0U; i < m_sut->capacity(); ++i) - { - m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>); - } + fillUpWithSimpleEvents(); m_sut->detachEvent(m_simpleEvents[0U]); EXPECT_THAT(m_sut->size(), Eq(m_sut->capacity() - 1U)); } TEST_F(ActiveCallSet_test, AttachWithoutEnumOneMoreThanCapacityFails) { - for (uint64_t i = 0U; i < m_sut->capacity(); ++i) - { - m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>); - EXPECT_THAT(m_sut->size(), Eq(i + 1)); - } + fillUpWithSimpleEvents(); auto result = m_sut->attachEvent(m_simpleEvents[m_sut->capacity()], ActiveCallSet_test::triggerCallback<0U>); ASSERT_TRUE(result.has_error()); @@ -329,21 +353,12 @@ TEST_F(ActiveCallSet_test, AttachingWithEnumIfEnoughSpaceAvailableWorks) TEST_F(ActiveCallSet_test, AttachWithEnumTillCapacityIsFullWorks) { - for (uint64_t i = 0U; i < m_sut->capacity(); ++i) - { - EXPECT_FALSE( - m_sut->attachEvent(m_simpleEvents[i], SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>) - .has_error()); - EXPECT_THAT(m_sut->size(), Eq(i + 1)); - } + EXPECT_TRUE(fillUpWithSimpleEventsWithEnum(SimpleEvent::Hypnotoad)); } TEST_F(ActiveCallSet_test, AttachWithEnumOneMoreThanCapacityFails) { - for (uint64_t i = 0U; i < m_sut->capacity(); ++i) - { - m_sut->attachEvent(m_simpleEvents[i], SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); - } + fillUpWithSimpleEventsWithEnum(SimpleEvent::Hypnotoad); auto result = m_sut->attachEvent( m_simpleEvents[m_sut->capacity()], SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); @@ -353,10 +368,7 @@ TEST_F(ActiveCallSet_test, AttachWithEnumOneMoreThanCapacityFails) TEST_F(ActiveCallSet_test, DetachMakesSpaceForAnotherAttachWithEventEnum) { - for (uint64_t i = 0U; i < m_sut->capacity(); ++i) - { - m_sut->attachEvent(m_simpleEvents[i], SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); - } + fillUpWithSimpleEventsWithEnum(SimpleEvent::Hypnotoad); m_sut->detachEvent(m_simpleEvents[0U], SimpleEvent::Hypnotoad); EXPECT_FALSE(m_sut @@ -368,10 +380,7 @@ TEST_F(ActiveCallSet_test, DetachMakesSpaceForAnotherAttachWithEventEnum) TEST_F(ActiveCallSet_test, DetachMakesSpaceForAnotherAttachWithoutEventEnum) { - for (uint64_t i = 0U; i < m_sut->capacity(); ++i) - { - m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>); - } + fillUpWithSimpleEvents(); m_sut->detachEvent(m_simpleEvents[0U]); EXPECT_FALSE( @@ -390,7 +399,7 @@ TEST_F(ActiveCallSet_test, AttachingEventWithEventTypeLeadsToAttachedTriggerHand EXPECT_TRUE(m_simpleEvents[0U].m_handleStoepsel.isValid()); } -TEST_F(ActiveCallSet_test, AttachingSameEventWithEventEnumTwiceFails) +TEST_F(ActiveCallSet_test, OverridingAlreadyAttachedEventWithEnumFails) { m_sut->attachEvent(m_simpleEvents[0U], SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); @@ -409,7 +418,7 @@ TEST_F(ActiveCallSet_test, OverridingAlreadyAttachedEventWithoutEnumFails) EXPECT_THAT(result.get_error(), Eq(ActiveCallSetError::EVENT_ALREADY_ATTACHED)); } -TEST_F(ActiveCallSet_test, OverridingAlreadyAttachedEventWithEnumFails) +TEST_F(ActiveCallSet_test, AttachingSameClassWithTwoDifferentEventsWorks) { m_sut->attachEvent(m_simpleEvents[0U], SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>); @@ -438,10 +447,7 @@ TEST_F(ActiveCallSet_test, DetachingDifferentClassWithSameEventEnumChangesNothin TEST_F(ActiveCallSet_test, AttachingWithoutEnumTillCapacityFilledSetsUpNoEventEnumTriggerHandle) { - for (uint64_t i = 0U; i < m_sut->capacity(); ++i) - { - m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>); - } + fillUpWithSimpleEvents(); for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { @@ -451,15 +457,11 @@ TEST_F(ActiveCallSet_test, AttachingWithoutEnumTillCapacityFilledSetsUpNoEventEn TEST_F(ActiveCallSet_test, DTorDetachesAllAttachedEvents) { - auto capacity = m_sut->capacity(); - for (uint64_t i = 0U; i < capacity; ++i) - { - m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>); - } + fillUpWithSimpleEvents(); m_sut.reset(); - for (uint64_t i = 0U; i < capacity; ++i) + for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { EXPECT_FALSE(m_simpleEvents[i].m_handleHypnotoad.isValid()); } @@ -526,6 +528,7 @@ TEST_F(ActiveCallSet_test, DetachingNonAttachedEventResetsNothing) // BEGIN calling callbacks /////////////////////////////////// TIMING_TEST_F(ActiveCallSet_test, CallbackIsCalledAfterNotify, Repeat(5), [&] { + m_sut.emplace(&m_eventVarData); SimpleEventClass fuu; m_sut->attachEvent(fuu, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); @@ -537,6 +540,7 @@ TIMING_TEST_F(ActiveCallSet_test, CallbackIsCalledAfterNotify, Repeat(5), [&] { }); TIMING_TEST_F(ActiveCallSet_test, CallbackIsCalledOnlyOnceWhenTriggered, Repeat(5), [&] { + m_sut.emplace(&m_eventVarData); SimpleEventClass fuu1; SimpleEventClass fuu2; m_sut->attachEvent(fuu1, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); @@ -554,6 +558,7 @@ TIMING_TEST_F(ActiveCallSet_test, CallbackIsCalledOnlyOnceWhenTriggered, Repeat( }); TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherCallback, Repeat(5), [&] { + m_sut.emplace(&m_eventVarData); SimpleEventClass fuu; m_sut->attachEvent(fuu, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); @@ -564,6 +569,7 @@ TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherCallback, std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); fuu.triggerStoepsel(); + m_watchdog.watchAndActOnFailure([] { std::terminate(); }); unblockTriggerCallback(NUMBER_OF_TRIGGER_UNBLOCKS); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); @@ -572,6 +578,7 @@ TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherCallback, }); TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherCallbackOnce, Repeat(5), [&] { + m_sut.emplace(&m_eventVarData); SimpleEventClass fuu; SimpleEventClass bar; m_sut->attachEvent(fuu, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); @@ -585,6 +592,7 @@ TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherCallbackOn fuu.triggerStoepsel(); bar.triggerStoepsel(); + m_watchdog.watchAndActOnFailure([] { std::terminate(); }); unblockTriggerCallback(NUMBER_OF_TRIGGER_UNBLOCKS); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); @@ -595,6 +603,7 @@ TIMING_TEST_F(ActiveCallSet_test, TriggerWhileInCallbackLeadsToAnotherCallbackOn }); TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnotherCallback, Repeat(5), [&] { + m_sut.emplace(&m_eventVarData); SimpleEventClass fuu; m_sut->attachEvent(fuu, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); @@ -608,6 +617,7 @@ TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnot { fuu.triggerStoepsel(); } + m_watchdog.watchAndActOnFailure([] { std::terminate(); }); unblockTriggerCallback(NUMBER_OF_RETRIGGERS); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); @@ -616,6 +626,7 @@ TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnot }); TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnotherCallbackOnce, Repeat(5), [&] { + m_sut.emplace(&m_eventVarData); SimpleEventClass fuu; SimpleEventClass bar; m_sut->attachEvent(fuu, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); @@ -632,6 +643,7 @@ TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnot fuu.triggerStoepsel(); } bar.triggerStoepsel(); + m_watchdog.watchAndActOnFailure([] { std::terminate(); }); unblockTriggerCallback(NUMBER_OF_RETRIGGERS + 1); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); @@ -642,6 +654,7 @@ TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnot }); TIMING_TEST_F(ActiveCallSet_test, NoTriggerLeadsToNoCallback, Repeat(5), [&] { + m_sut.emplace(&m_eventVarData); SimpleEventClass fuu; m_sut->attachEvent(fuu, SimpleEvent::StoepselBachelorParty, ActiveCallSet_test::triggerCallback<0U>); @@ -652,6 +665,7 @@ TIMING_TEST_F(ActiveCallSet_test, NoTriggerLeadsToNoCallback, Repeat(5), [&] { }); TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacks, Repeat(5), [&] { + m_sut.emplace(&m_eventVarData); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); AttachEvent::doIt( @@ -667,6 +681,7 @@ TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacks, Repeat(5 } // 10 times more callback runs allowed to allow potential overtriggering + m_watchdog.watchAndActOnFailure([] { std::terminate(); }); unblockTriggerCallback(10U * iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); @@ -680,6 +695,7 @@ TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacks, Repeat(5 }); TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacksOnce, Repeat(5), [&] { + m_sut.emplace(&m_eventVarData); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); AttachEvent::doIt( @@ -695,6 +711,7 @@ TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacksOnce, Repe } // 10 times more callback runs allowed to allow potential overtriggering + m_watchdog.watchAndActOnFailure([] { std::terminate(); }); unblockTriggerCallback(10U * iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); @@ -717,6 +734,7 @@ TIMING_TEST_F(ActiveCallSet_test, TriggeringAllEventsCallsAllCallbacksOnce, Repe // BEGIN concurrent attach / detach ////////////////////////////////// TIMING_TEST_F(ActiveCallSet_test, AttachingWhileCallbackIsRunningWorks, Repeat(5), [&] { + m_sut.emplace(&m_eventVarData); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, triggerCallback<0U>); @@ -730,9 +748,11 @@ TIMING_TEST_F(ActiveCallSet_test, AttachingWhileCallbackIsRunningWorks, Repeat(5 std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS * 2U)); TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[1U].m_source == &events[1U]); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[1U].m_count == 1U); }); TIMING_TEST_F(ActiveCallSet_test, AttachingMultipleWhileCallbackIsRunningWorks, Repeat(5), [&] { + m_sut.emplace(&m_eventVarData); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); m_sut->attachEvent(events[iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U], @@ -756,10 +776,12 @@ TIMING_TEST_F(ActiveCallSet_test, AttachingMultipleWhileCallbackIsRunningWorks, for (uint64_t i = 0U; i + 1U < iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET; ++i) { TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[i].m_source == &events[i]); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[i].m_count == 1U); } }); TIMING_TEST_F(ActiveCallSet_test, DetachingWhileCallbackIsRunningWorks, Repeat(5), [&] { + m_sut.emplace(&m_eventVarData); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, triggerCallback<0U>); @@ -773,10 +795,12 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingWhileCallbackIsRunningWorks, Repeat(5 events[0U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_count == 1U); TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_source == nullptr); }); TIMING_TEST_F(ActiveCallSet_test, DetachingWhileCallbackIsRunningBlocksDetach, Repeat(5), [&] { + m_sut.emplace(&m_eventVarData); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); m_sut->attachEvent(events[0U], SimpleEvent::StoepselBachelorParty, triggerCallback<0U>); g_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; @@ -792,6 +816,7 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingWhileCallbackIsRunningBlocksDetach, R }); TIMING_TEST_F(ActiveCallSet_test, EventDestructorBlocksWhenCallbackIsRunning, Repeat(5), [&] { + m_sut.emplace(&m_eventVarData); SimpleEventClass* event = new SimpleEventClass(); m_sut->attachEvent(*event, SimpleEvent::StoepselBachelorParty, triggerCallback<0U>); g_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; @@ -808,6 +833,7 @@ TIMING_TEST_F(ActiveCallSet_test, EventDestructorBlocksWhenCallbackIsRunning, Re TIMING_TEST_F(ActiveCallSet_test, DetachingMultipleWhileCallbackIsRunningWorks, Repeat(5), [&] { + m_sut.emplace(&m_eventVarData); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); AttachEvent::doIt( *m_sut, events, SimpleEvent::StoepselBachelorParty); @@ -840,6 +866,7 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingMultipleWhileCallbackIsRunningWorks, }); TIMING_TEST_F(ActiveCallSet_test, AttachingDetachingRunsIndependentOfCallback, Repeat(5), [&] { + m_sut.emplace(&m_eventVarData); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); m_sut->attachEvent(events[iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U], SimpleEvent::StoepselBachelorParty, @@ -869,6 +896,7 @@ TIMING_TEST_F(ActiveCallSet_test, AttachingDetachingRunsIndependentOfCallback, R // BEGIN attach / detach in callbacks ////////////////////////////////// TIMING_TEST_F(ActiveCallSet_test, DetachingSelfInCallbackWorks, Repeat(5), [&] { + m_sut.emplace(&m_eventVarData); g_toBeDetached->clear(); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); @@ -883,6 +911,7 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingSelfInCallbackWorks, Repeat(5), [&] { }); TIMING_TEST_F(ActiveCallSet_test, DetachingNonSelfEventInCallbackWorks, Repeat(5), [&] { + m_sut.emplace(&m_eventVarData); g_toBeDetached->clear(); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); @@ -898,6 +927,17 @@ TIMING_TEST_F(ActiveCallSet_test, DetachingNonSelfEventInCallbackWorks, Repeat(5 }); TIMING_TEST_F(ActiveCallSet_test, DetachedCallbacksAreNotBeingCalledWhenTriggeredBefore, Repeat(5), [&] { + // idea of the test is that an event which was detached but is technically still attached + // since the detach blocks cannot be retriggered again so that the callback is called again. + // once detach is called either the callback is currently running and detach is blocked or + // the callback is removed and can never be called again. + // + // To test this we attach two events. events[0] detaches events[1] in his callback. + // events[1] is triggered and the callback has a certain runtime so that we make sure that the callback is + // running while we retrigger events[0] and events[1]. + // Now events[0] remove events[1] before its trigger callback is executed and therefore the + // callback is not allowed to be called even so that the trigger came before the detach occurred + m_sut.emplace(&m_eventVarData); g_toBeDetached->clear(); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); @@ -911,15 +951,19 @@ TIMING_TEST_F(ActiveCallSet_test, DetachedCallbacksAreNotBeingCalledWhenTriggere g_triggerCallbackArg[1U].m_source = nullptr; g_triggerCallbackRuntimeInMs = 0U; - events[0U].triggerStoepsel(); events[1U].triggerStoepsel(); + events[0U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_source == nullptr); TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[1U].m_source == nullptr); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_count == 0U); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[1U].m_count == 1U); }); TIMING_TEST_F(ActiveCallSet_test, AttachingInCallbackWorks, Repeat(1), [&] { + m_sut.emplace(&m_eventVarData); g_toBeAttached->clear(); std::vector events(iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET); @@ -933,6 +977,7 @@ TIMING_TEST_F(ActiveCallSet_test, AttachingInCallbackWorks, Repeat(1), [&] { std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS / 2U)); TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_source == &events[1U]); + TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_count == 1U); }); ////////////////////////////////// // END diff --git a/iceoryx_utils/testutils/watch_dog.hpp b/iceoryx_utils/testutils/watch_dog.hpp index 1f2c058e5e4..b809b21a0d5 100644 --- a/iceoryx_utils/testutils/watch_dog.hpp +++ b/iceoryx_utils/testutils/watch_dog.hpp @@ -37,8 +37,11 @@ class Watchdog ~Watchdog() noexcept { - m_watchdogSemaphore.post(); - m_watchdog.join(); + if (m_watchdog.joinable()) + { + m_watchdogSemaphore.post(); + m_watchdog.join(); + } } void watchAndActOnFailure(std::function f) noexcept From 8f24cab865a8fe47f93cc41842a5568c98000ca7 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Thu, 4 Mar 2021 14:51:33 +0100 Subject: [PATCH 137/143] iox-#350 fixed undefined behavior Signed-off-by: Christian Eltzschig --- iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index ce3ff050154..6858432c939 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -459,9 +459,10 @@ TEST_F(ActiveCallSet_test, DTorDetachesAllAttachedEvents) { fillUpWithSimpleEvents(); + auto capacity = m_sut->capacity(); m_sut.reset(); - for (uint64_t i = 0U; i < m_sut->capacity(); ++i) + for (uint64_t i = 0U; i < capacity; ++i) { EXPECT_FALSE(m_simpleEvents[i].m_handleHypnotoad.isValid()); } From 446960383eab16a4890726c4bda7ae4bf459bfa7 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Thu, 4 Mar 2021 18:23:51 +0100 Subject: [PATCH 138/143] iox-#350 fixed types, copyright headers and removed unused code Signed-off-by: Christian Eltzschig --- iceoryx_meta/CMakeLists.txt | 2 +- .../internal/popo/building_blocks/event_variable_data.hpp | 2 +- iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp | 2 +- iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp | 2 +- iceoryx_posh/source/roudi/port_pool.cpp | 2 +- .../test/moduletests/test_popo_active_call_set.cpp | 7 ------- iceoryx_posh/test/moduletests/test_popo_event_variable.cpp | 5 +++++ iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp | 4 ++-- iceoryx_posh/test/moduletests/test_popo_waitset.cpp | 2 +- .../iceoryx_utils/internal/concurrent/smart_lock.hpp | 1 + .../iceoryx_utils/internal/concurrent/smart_lock.inl | 1 + iceoryx_utils/test/moduletests/test_cxx_helplets.cpp | 1 + 12 files changed, 16 insertions(+), 15 deletions(-) diff --git a/iceoryx_meta/CMakeLists.txt b/iceoryx_meta/CMakeLists.txt index 56d9bbf3adb..7f21ff519af 100644 --- a/iceoryx_meta/CMakeLists.txt +++ b/iceoryx_meta/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (c) 2019, 2020 by Robert Bosch GmbH. All rights reserved. -# Copyright (c) 2020, 2021 by Apex.AI Inc. All rights reserved. +# Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp index 0310c7741b5..14fac6a1f2f 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/event_variable_data.hpp @@ -32,7 +32,7 @@ struct EventVariableData : public ConditionVariableData /// @brief sets all entries of notification array to false and sets process name /// - /// @param process name of process + /// @param[in] process name of process EventVariableData(const ProcessName_t& process) noexcept; std::atomic_bool m_activeNotifications[MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET]; diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp index b2ce59b73f5..c6fa21fd3c6 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -46,7 +46,7 @@ enum class ActiveCallSetError /// an encapsulated thread inside this class. /// @note The ActiveCallSet is threadsafe and can be used without any restrictions concurrently. /// @attention Calling detachEvent for the same event from multiple threads is supported but -/// can cause a race conditions if you attach the same event again concurrently from +/// can cause a race condition if you attach the same event again concurrently from /// another thread. /// Example: /// 1. One calls detachEvent [1] from thread A, B and C diff --git a/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp b/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp index d915579fc81..e6cb47e8c2c 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/trigger_handle.hpp @@ -41,7 +41,7 @@ class TriggerHandle TriggerHandle() = default; /// @brief Creates a TriggerHandle /// @param[in] eventVariableDataRef reference to a event variable data struct - /// @param[in] resetCallback callback which will be called it goes out of scope or reset is called + /// @param[in] resetCallback callback which will be called when it goes out of scope or reset is called /// @param[in] uniqueTriggerId the unique trigger id of the Trigger which corresponds to the TriggerHandle. Usually /// stored in a Notifyable. It is required for the resetCallback TriggerHandle(EventVariableData& eventVariableDataRef, diff --git a/iceoryx_posh/source/roudi/port_pool.cpp b/iceoryx_posh/source/roudi/port_pool.cpp index 206db39e49a..a5cbcb86fc3 100644 --- a/iceoryx_posh/source/roudi/port_pool.cpp +++ b/iceoryx_posh/source/roudi/port_pool.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. -// Copyright (c) 2020, 2021 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index 6858432c939..bcc22384f9d 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -117,19 +117,12 @@ class SimpleEventClass } void triggerStoepsel() noexcept { - m_hasTriggered.store(true); m_handleStoepsel.trigger(); } - void resetTrigger() noexcept - { - m_hasTriggered.store(false); - } - iox::popo::TriggerHandle m_handleHypnotoad; iox::popo::TriggerHandle m_handleStoepsel; iox::popo::TriggerHandle m_handleNoEventEnum; - mutable std::atomic_bool m_hasTriggered{false}; }; class TestActiveCallSet : public ActiveCallSet diff --git a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp index d84078968de..5cdf692d5f2 100644 --- a/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_event_variable.cpp @@ -94,6 +94,9 @@ TEST_F(EventVariable_test, NotifyActivatesNoIndexIfIndexIsTooLarge) TEST_F(EventVariable_test, WaitIsNonBlockingAfterDestroyAndReturnsEmptyVector) { EventListener sut(m_eventVarData); + Watchdog watchdog(m_timeToWait); + watchdog.watchAndActOnFailure([&] { std::terminate(); }); + sut.destroy(); const auto& activeNotifications = sut.wait(); @@ -103,6 +106,8 @@ TEST_F(EventVariable_test, WaitIsNonBlockingAfterDestroyAndReturnsEmptyVector) TEST_F(EventVariable_test, WaitIsNonBlockingAfterDestroyAndNotifyAndReturnsEmptyVector) { EventListener sut(m_eventVarData); + Watchdog watchdog(m_timeToWait); + watchdog.watchAndActOnFailure([&] { std::terminate(); }); sut.destroy(); EventNotifier notifier(m_eventVarData, 0U); diff --git a/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp b/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp index 58cd0c08a1c..cf9196a5fd7 100644 --- a/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp @@ -40,13 +40,13 @@ class TriggerHandle_test : public Test }; -TEST_F(TriggerHandle_test, isValidWhenConditionVariableIsNotNull) +TEST_F(TriggerHandle_test, IsValidWhenConditionVariableIsNotNull) { EXPECT_TRUE(m_sut.isValid()); EXPECT_TRUE(m_sut); } -TEST_F(TriggerHandle_test, defaultCTorConstructsInvalidHandle) +TEST_F(TriggerHandle_test, DefaultCTorConstructsInvalidHandle) { TriggerHandle sut2; diff --git a/iceoryx_posh/test/moduletests/test_popo_waitset.cpp b/iceoryx_posh/test/moduletests/test_popo_waitset.cpp index d7f8315577f..40b17adab65 100644 --- a/iceoryx_posh/test/moduletests/test_popo_waitset.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_waitset.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. -// Copyright (c) 2020, 2021 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.hpp b/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.hpp index e6511a2e0b6..47784752ec3 100644 --- a/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.hpp +++ b/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.hpp @@ -1,4 +1,5 @@ // Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.inl b/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.inl index 21c0b10ec2e..57f2e5f01fa 100644 --- a/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.inl +++ b/iceoryx_utils/include/iceoryx_utils/internal/concurrent/smart_lock.inl @@ -1,4 +1,5 @@ // Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/iceoryx_utils/test/moduletests/test_cxx_helplets.cpp b/iceoryx_utils/test/moduletests/test_cxx_helplets.cpp index 9d421425705..a619be9a6f0 100644 --- a/iceoryx_utils/test/moduletests/test_cxx_helplets.cpp +++ b/iceoryx_utils/test/moduletests/test_cxx_helplets.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex AI Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. From c2546611c96b8923cb6988e3440d59c4a79c2d1d Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Thu, 4 Mar 2021 21:19:27 +0100 Subject: [PATCH 139/143] iox-#350 wrong trigger handle tested in test Signed-off-by: Christian Eltzschig --- .../moduletests/test_popo_active_call_set.cpp | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index bcc22384f9d..8a4a36c3ecf 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -224,19 +224,13 @@ class ActiveCallSet_test : public Test } } - bool fillUpWithSimpleEvents() + void fillUpWithSimpleEvents() { for (uint64_t i = 0U; i < m_sut->capacity(); ++i) { - bool hasError = m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>).has_error(); - EXPECT_FALSE(hasError); - if (hasError) - { - return false; - } - EXPECT_THAT(m_sut->size(), Eq(i + 1)); + EXPECT_FALSE(m_sut->attachEvent(m_simpleEvents[i], ActiveCallSet_test::triggerCallback<0U>).has_error()); + EXPECT_THAT(m_sut->size(), Eq(i + 1U)); } - return true; } bool fillUpWithSimpleEventsWithEnum(const SimpleEvent eventType) { @@ -250,7 +244,7 @@ class ActiveCallSet_test : public Test return false; } - EXPECT_THAT(m_sut->size(), Eq(i + 1)); + EXPECT_THAT(m_sut->size(), Eq(i + 1U)); } return true; } @@ -341,7 +335,7 @@ TEST_F(ActiveCallSet_test, AttachingWithEnumIfEnoughSpaceAvailableWorks) { EXPECT_FALSE(m_sut->attachEvent(m_simpleEvents[0U], SimpleEvent::Hypnotoad, ActiveCallSet_test::triggerCallback<0U>) .has_error()); - EXPECT_THAT(m_sut->size(), Eq(1)); + EXPECT_THAT(m_sut->size(), Eq(1U)); } TEST_F(ActiveCallSet_test, AttachWithEnumTillCapacityIsFullWorks) @@ -448,13 +442,26 @@ TEST_F(ActiveCallSet_test, AttachingWithoutEnumTillCapacityFilledSetsUpNoEventEn } } -TEST_F(ActiveCallSet_test, DTorDetachesAllAttachedEvents) +TEST_F(ActiveCallSet_test, DTorDetachesAllAttachedEventsWithoutEnum) { fillUpWithSimpleEvents(); auto capacity = m_sut->capacity(); m_sut.reset(); + for (uint64_t i = 0U; i < capacity; ++i) + { + EXPECT_FALSE(m_simpleEvents[i].m_handleNoEventEnum.isValid()); + } +} + +TEST_F(ActiveCallSet_test, DTorDetachesAllAttachedEventsWithEnum) +{ + fillUpWithSimpleEventsWithEnum(SimpleEvent::Hypnotoad); + + auto capacity = m_sut->capacity(); + m_sut.reset(); + for (uint64_t i = 0U; i < capacity; ++i) { EXPECT_FALSE(m_simpleEvents[i].m_handleHypnotoad.isValid()); @@ -485,7 +492,7 @@ TEST_F(ActiveCallSet_test, DetachingSimpleEventResetsTriggerHandle) m_sut->attachEvent(fuu, ActiveCallSet_test::triggerCallback<0U>); m_sut->detachEvent(fuu); - EXPECT_FALSE(static_cast(fuu.m_handleHypnotoad)); + EXPECT_FALSE(static_cast(fuu.m_handleNoEventEnum)); } TEST_F(ActiveCallSet_test, AttachingEventWithEnumSetsTriggerHandle) From 50df45d3619b492b2324de8973544ce07cd29fbd Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Fri, 5 Mar 2021 10:21:13 +0100 Subject: [PATCH 140/143] iox-#350 adjusted some copyright headers, using iceoryx cxx typetraits, removing unused includes, returning when errorHandler is called, adding Us and adjusted timing test parameters Signed-off-by: Christian Eltzschig --- iceoryx_meta/CMakeLists.txt | 2 +- .../iceoryx_posh/popo/active_call_set.hpp | 3 +-- iceoryx_posh/source/popo/active_call_set.cpp | 1 - .../popo/building_blocks/event_listener.cpp | 16 ++++++++++------ .../moduletests/test_popo_active_call_set.cpp | 6 +++--- .../moduletests/test_popo_trigger_handle.cpp | 10 +++++----- .../test/moduletests/test_cxx_helplets.cpp | 2 +- 7 files changed, 21 insertions(+), 19 deletions(-) diff --git a/iceoryx_meta/CMakeLists.txt b/iceoryx_meta/CMakeLists.txt index 7f21ff519af..4ba927468fe 100644 --- a/iceoryx_meta/CMakeLists.txt +++ b/iceoryx_meta/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2019, 2020 by Robert Bosch GmbH. All rights reserved. +# Copyright (c) 2019 - 2020 by Robert Bosch GmbH. All rights reserved. # Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp index c6fa21fd3c6..da5fa936eca 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/active_call_set.hpp @@ -23,12 +23,11 @@ #include "iceoryx_posh/popo/trigger_handle.hpp" #include "iceoryx_utils/cxx/expected.hpp" #include "iceoryx_utils/cxx/method_callback.hpp" -#include "iceoryx_utils/cxx/types.hpp" +#include "iceoryx_utils/cxx/type_traits.hpp" #include "iceoryx_utils/internal/concurrent/loffli.hpp" #include "iceoryx_utils/internal/concurrent/smart_lock.hpp" #include -#include namespace iox { diff --git a/iceoryx_posh/source/popo/active_call_set.cpp b/iceoryx_posh/source/popo/active_call_set.cpp index 4f03f02c9b0..d9883ec2e05 100644 --- a/iceoryx_posh/source/popo/active_call_set.cpp +++ b/iceoryx_posh/source/popo/active_call_set.cpp @@ -15,7 +15,6 @@ // SPDX-License-Identifier: Apache-2.0 #include "iceoryx_posh/popo/active_call_set.hpp" -#include "iceoryx_posh/internal/popo/building_blocks/event_listener.hpp" #include "iceoryx_posh/internal/popo/building_blocks/event_notifier.hpp" #include "iceoryx_posh/runtime/posh_runtime.hpp" #include "iceoryx_utils/cxx/helplets.hpp" diff --git a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp index eea12ced958..f475f2256ce 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp @@ -59,6 +59,7 @@ EventListener::NotificationVector_t EventListener::wait() noexcept if (m_pointerToEventVariableData->m_semaphore.wait().has_error()) { errorHandler(Error::kPOPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_WAIT, nullptr, ErrorLevel::FATAL); + break; } } @@ -76,12 +77,15 @@ void EventListener::reset(const uint64_t index) noexcept void EventListener::resetSemaphore() noexcept { // Count the semaphore down to zero - while (m_pointerToEventVariableData->m_semaphore.tryWait() - .or_else([](posix::SemaphoreError) { - errorHandler( - Error::kPOPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_RESET, nullptr, ErrorLevel::FATAL); - }) - .value()) + bool hasFatalError = false; + while (!hasFatalError + || m_pointerToEventVariableData->m_semaphore.tryWait() + .or_else([&](posix::SemaphoreError) { + errorHandler( + Error::kPOPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_RESET, nullptr, ErrorLevel::FATAL); + hasFatalError = true; + }) + .value()) { } } diff --git a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp index 8a4a36c3ecf..0f136477859 100644 --- a/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_active_call_set.cpp @@ -645,7 +645,7 @@ TIMING_TEST_F(ActiveCallSet_test, TriggerMultipleTimesWhileInCallbackLeadsToAnot } bar.triggerStoepsel(); m_watchdog.watchAndActOnFailure([] { std::terminate(); }); - unblockTriggerCallback(NUMBER_OF_RETRIGGERS + 1); + unblockTriggerCallback(NUMBER_OF_RETRIGGERS + 1U); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[0U].m_source == &fuu); @@ -761,7 +761,7 @@ TIMING_TEST_F(ActiveCallSet_test, AttachingMultipleWhileCallbackIsRunningWorks, triggerCallback); g_triggerCallbackRuntimeInMs = 3U * CALLBACK_WAIT_IN_MS / 2U; - events[iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1].triggerStoepsel(); + events[iox::MAX_NUMBER_OF_EVENTS_PER_ACTIVE_CALL_SET - 1U].triggerStoepsel(); std::this_thread::sleep_for(std::chrono::milliseconds(CALLBACK_WAIT_IN_MS)); AttachEvent::doIt( @@ -963,7 +963,7 @@ TIMING_TEST_F(ActiveCallSet_test, DetachedCallbacksAreNotBeingCalledWhenTriggere TIMING_TEST_EXPECT_TRUE(g_triggerCallbackArg[1U].m_count == 1U); }); -TIMING_TEST_F(ActiveCallSet_test, AttachingInCallbackWorks, Repeat(1), [&] { +TIMING_TEST_F(ActiveCallSet_test, AttachingInCallbackWorks, Repeat(5), [&] { m_sut.emplace(&m_eventVarData); g_toBeAttached->clear(); diff --git a/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp b/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp index cf9196a5fd7..75ab8752901 100644 --- a/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_trigger_handle.cpp @@ -36,7 +36,7 @@ class TriggerHandle_test : public Test ConditionVariableData m_condVar{"Horscht"}; TriggerHandle_test* m_self = this; - TriggerHandle m_sut{m_condVar, {*this, &TriggerHandle_test::resetCallback}, 12}; + TriggerHandle m_sut{m_condVar, {*this, &TriggerHandle_test::resetCallback}, 12U}; }; @@ -76,7 +76,7 @@ TEST_F(TriggerHandle_test, ResetCreatesInvalidTriggerHandle) TEST_F(TriggerHandle_test, ResetCallsResetCallbackWhenHandleIsValid) { m_sut.reset(); - EXPECT_EQ(m_resetCallbackId, 12); + EXPECT_EQ(m_resetCallbackId, 12U); EXPECT_THAT(m_sut.getUniqueId(), Eq(Trigger::INVALID_TRIGGER_ID)); } @@ -84,7 +84,7 @@ TEST_F(TriggerHandle_test, ResetDoesNotCallResetCallbackWhenHandleIsInvalid) { m_sut.invalidate(); m_sut.reset(); - EXPECT_EQ(m_resetCallbackId, 0); + EXPECT_EQ(m_resetCallbackId, 0U); EXPECT_THAT(m_sut.getUniqueId(), Eq(Trigger::INVALID_TRIGGER_ID)); } @@ -95,8 +95,8 @@ TEST_F(TriggerHandle_test, getConditionVariableDataReturnsCorrectVar) TEST_F(TriggerHandle_test, getUniqueIdReturnsCorrectId) { - TriggerHandle sut2{m_condVar, {*m_self, &TriggerHandle_test::resetCallback}, 8912}; - EXPECT_EQ(sut2.getUniqueId(), 8912); + TriggerHandle sut2{m_condVar, {*m_self, &TriggerHandle_test::resetCallback}, 8912U}; + EXPECT_EQ(sut2.getUniqueId(), 8912U); } TEST_F(TriggerHandle_test, triggerNotifiesConditionVariable) diff --git a/iceoryx_utils/test/moduletests/test_cxx_helplets.cpp b/iceoryx_utils/test/moduletests/test_cxx_helplets.cpp index a619be9a6f0..963996a12bb 100644 --- a/iceoryx_utils/test/moduletests/test_cxx_helplets.cpp +++ b/iceoryx_utils/test/moduletests/test_cxx_helplets.cpp @@ -132,5 +132,5 @@ TEST_F(Helplets_test, bestFittingTypeUsesUint64WhenValueEqualTo4294967296) TEST_F(Helplets_test, bestFittingTypeUsesUint32WhenValueGreater2p32) { - EXPECT_TRUE((std::is_same, uint64_t>::value)); + EXPECT_TRUE((std::is_same, uint64_t>::value)); } From b9d0828feac37f1462540ae433d0a5a9ff74a880 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Fri, 5 Mar 2021 11:05:04 +0100 Subject: [PATCH 141/143] iox-#350 wrong logical connection Signed-off-by: Christian Eltzschig --- iceoryx_examples/icedelivery_in_c/CMakeLists.txt | 2 -- iceoryx_examples/waitset_in_c/CMakeLists.txt | 5 ----- iceoryx_posh/source/popo/building_blocks/event_listener.cpp | 2 +- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/iceoryx_examples/icedelivery_in_c/CMakeLists.txt b/iceoryx_examples/icedelivery_in_c/CMakeLists.txt index ae35ede662d..acb0b410a6b 100644 --- a/iceoryx_examples/icedelivery_in_c/CMakeLists.txt +++ b/iceoryx_examples/icedelivery_in_c/CMakeLists.txt @@ -31,7 +31,6 @@ endif () add_executable(iox-c-publisher ./ice_c_publisher.c) set_source_files_properties(./ice_c_publisher.c PROPERTIES LANGUAGE C) target_link_libraries(iox-c-publisher - iceoryx_posh::iceoryx_posh iceoryx_binding_c::iceoryx_binding_c ) set_target_properties(iox-c-publisher PROPERTIES @@ -42,7 +41,6 @@ target_compile_options(iox-c-publisher PRIVATE ${ICEORYX_WARNINGS} ${ICEORYX_SAN add_executable(iox-c-subscriber ./ice_c_subscriber.c) set_source_files_properties(./ice_c_subscriber.c PROPERTIES LANGUAGE C) target_link_libraries(iox-c-subscriber - iceoryx_posh::iceoryx_posh iceoryx_binding_c::iceoryx_binding_c ) set_target_properties(iox-c-subscriber PROPERTIES diff --git a/iceoryx_examples/waitset_in_c/CMakeLists.txt b/iceoryx_examples/waitset_in_c/CMakeLists.txt index 6808a51e61b..32a822838a8 100644 --- a/iceoryx_examples/waitset_in_c/CMakeLists.txt +++ b/iceoryx_examples/waitset_in_c/CMakeLists.txt @@ -28,35 +28,30 @@ endif () add_executable(iox-ex-c-waitset-publisher ./ice_c_waitset_publisher.c) target_link_libraries(iox-ex-c-waitset-publisher - iceoryx_posh::iceoryx_posh iceoryx_binding_c::iceoryx_binding_c ) target_compile_options(iox-ex-c-waitset-publisher PRIVATE ${ICEORYX_WARNINGS} ${ICEORYX_SANITIZER_FLAGS}) add_executable(iox-ex-c-waitset-gateway ./ice_c_waitset_gateway.c) target_link_libraries(iox-ex-c-waitset-gateway - iceoryx_posh::iceoryx_posh iceoryx_binding_c::iceoryx_binding_c ) target_compile_options(iox-ex-c-waitset-gateway PRIVATE ${ICEORYX_WARNINGS} ${ICEORYX_SANITIZER_FLAGS}) add_executable(iox-ex-c-waitset-grouping ./ice_c_waitset_grouping.c) target_link_libraries(iox-ex-c-waitset-grouping - iceoryx_posh::iceoryx_posh iceoryx_binding_c::iceoryx_binding_c ) target_compile_options(iox-ex-c-waitset-grouping PRIVATE ${ICEORYX_WARNINGS} ${ICEORYX_SANITIZER_FLAGS}) add_executable(iox-ex-c-waitset-individual ./ice_c_waitset_individual.c) target_link_libraries(iox-ex-c-waitset-individual - iceoryx_posh::iceoryx_posh iceoryx_binding_c::iceoryx_binding_c ) target_compile_options(iox-ex-c-waitset-individual PRIVATE ${ICEORYX_WARNINGS} ${ICEORYX_SANITIZER_FLAGS}) add_executable(iox-ex-c-waitset-sync ./ice_c_waitset_sync.c) target_link_libraries(iox-ex-c-waitset-sync - iceoryx_posh::iceoryx_posh iceoryx_binding_c::iceoryx_binding_c ) target_compile_options(iox-ex-c-waitset-sync PRIVATE ${ICEORYX_WARNINGS} ${ICEORYX_SANITIZER_FLAGS}) diff --git a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp index f475f2256ce..ac9b0e86863 100644 --- a/iceoryx_posh/source/popo/building_blocks/event_listener.cpp +++ b/iceoryx_posh/source/popo/building_blocks/event_listener.cpp @@ -79,7 +79,7 @@ void EventListener::resetSemaphore() noexcept // Count the semaphore down to zero bool hasFatalError = false; while (!hasFatalError - || m_pointerToEventVariableData->m_semaphore.tryWait() + && m_pointerToEventVariableData->m_semaphore.tryWait() .or_else([&](posix::SemaphoreError) { errorHandler( Error::kPOPO__EVENT_VARIABLE_WAITER_SEMAPHORE_CORRUPTED_IN_RESET, nullptr, ErrorLevel::FATAL); From 12f6e58f2d0674ef6a98b70abb123f58af69373a Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Fri, 5 Mar 2021 11:15:44 +0100 Subject: [PATCH 142/143] iox-#350 added pthread dependency to c binding Signed-off-by: Christian Eltzschig --- iceoryx_binding_c/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iceoryx_binding_c/CMakeLists.txt b/iceoryx_binding_c/CMakeLists.txt index 11f4f6b62cf..2ff13e45e73 100644 --- a/iceoryx_binding_c/CMakeLists.txt +++ b/iceoryx_binding_c/CMakeLists.txt @@ -71,6 +71,8 @@ target_include_directories(${PROJECT_NAME} $ ) target_link_libraries(${PROJECT_NAME} + PUBLIC + pthread PRIVATE iceoryx_posh::iceoryx_posh iceoryx_utils::iceoryx_utils From 2c747a0e61bd51701ca0afb0627adf9fbab1f28e Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Fri, 5 Mar 2021 11:29:58 +0100 Subject: [PATCH 143/143] iox-#350 fixed windows cmake issue Signed-off-by: Christian Eltzschig --- iceoryx_binding_c/CMakeLists.txt | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/iceoryx_binding_c/CMakeLists.txt b/iceoryx_binding_c/CMakeLists.txt index 2ff13e45e73..db2fb3dac21 100644 --- a/iceoryx_binding_c/CMakeLists.txt +++ b/iceoryx_binding_c/CMakeLists.txt @@ -70,13 +70,22 @@ target_include_directories(${PROJECT_NAME} $ $ ) -target_link_libraries(${PROJECT_NAME} - PUBLIC - pthread - PRIVATE - iceoryx_posh::iceoryx_posh - iceoryx_utils::iceoryx_utils -) + +if(NOT WIN32) + target_link_libraries(${PROJECT_NAME} + PUBLIC + pthread + PRIVATE + iceoryx_posh::iceoryx_posh + iceoryx_utils::iceoryx_utils + ) +else() + target_link_libraries(${PROJECT_NAME} + PRIVATE + iceoryx_posh::iceoryx_posh + iceoryx_utils::iceoryx_utils + ) +endif() target_compile_options(${PROJECT_NAME} PRIVATE ${ICEORYX_WARNINGS} ${ICEORYX_SANITIZER_FLAGS})