diff --git a/examples/rust/service_variant_customization/custom_service_variant.rs b/examples/rust/service_variant_customization/custom_service_variant.rs index a37b36d948..586964f7c4 100644 --- a/examples/rust/service_variant_customization/custom_service_variant.rs +++ b/examples/rust/service_variant_customization/custom_service_variant.rs @@ -23,6 +23,7 @@ impl iceoryx2::service::Service for CustomServiceVariant { type ConfigSerializer = iceoryx2_cal::serialize::recommended::Recommended; type PersistentDynamicStorage = iceoryx2_cal::dynamic_storage::recommended::PersistentIpc; + type Bag = iceoryx2_cal::bag::recommended::Recommended; // use a dynamic storage based on a file type DynamicStorage = iceoryx2_cal::dynamic_storage::file::Storage; diff --git a/iceoryx2-bb/elementary-traits/src/zero_copy_send.rs b/iceoryx2-bb/elementary-traits/src/zero_copy_send.rs index e3bf9b3279..fdd09352c2 100644 --- a/iceoryx2-bb/elementary-traits/src/zero_copy_send.rs +++ b/iceoryx2-bb/elementary-traits/src/zero_copy_send.rs @@ -75,6 +75,7 @@ unsafe impl ZeroCopySend for () {} unsafe impl ZeroCopySend for [T] {} unsafe impl ZeroCopySend for [T; N] {} unsafe impl ZeroCopySend for core::mem::MaybeUninit {} +unsafe impl ZeroCopySend for core::marker::PhantomData {} // Note: `ZeroCopySend` cannot be implemented for tuples because `#[repr(C)]` can only be applied // to structs, enums, and unions. diff --git a/iceoryx2-cal/src/bag/default_bag.rs b/iceoryx2-cal/src/bag/default_bag.rs new file mode 100644 index 0000000000..eb1f30486c --- /dev/null +++ b/iceoryx2-cal/src/bag/default_bag.rs @@ -0,0 +1,73 @@ +// Copyright (c) 2026 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache Software License 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license +// which is available at https://opensource.org/licenses/MIT. +// +// SPDX-License-Identifier: Apache-2.0 OR MIT + +//! The default implementation for the [`BagFamily`] concept and the [`Bag`] trait. + +use crate::bag::{Bag, BagAddFailure, BagFamily, BagHandle, BagRemoveError, BagState, BagType}; + +use iceoryx2_bb_lock_free::mpmc::container::Container; +use iceoryx2_bb_lock_free::mpmc::robust_unique_index_set::OwnerId; +use iceoryx2_bb_lock_free::mpmc::unique_index_set_enums::{ReleaseMode, ReleaseState}; + +#[derive(Debug)] +pub struct DefaultBag; + +impl BagFamily for DefaultBag { + type Bag = Container; +} + +impl Bag for Container { + fn capacity(&self) -> usize { + self.capacity() + } + + fn len(&self) -> usize { + self.len() + } + + fn is_empty(&self) -> bool { + self.is_empty() + } + + unsafe fn add( + &self, + value: T, + owner_id: OwnerId, + ) -> Result<(*const T, BagHandle), BagAddFailure> { + unsafe { self.add(value, owner_id) } + } + + unsafe fn remove( + &self, + handle: BagHandle, + mode: ReleaseMode, + ) -> Result { + unsafe { self.remove(handle, mode) } + } + + unsafe fn get_state(&self) -> BagState { + unsafe { self.get_state() } + } + + unsafe fn recover bool>( + &self, + dead_owner_id: OwnerId, + predicate: F, + mode: ReleaseMode, + ) -> ReleaseState { + unsafe { self.recover(dead_owner_id, predicate, mode) } + } + + unsafe fn update_state(&self, previous_state: &mut BagState) -> bool { + unsafe { self.update_state(previous_state) } + } +} diff --git a/iceoryx2-cal/src/bag/mod.rs b/iceoryx2-cal/src/bag/mod.rs new file mode 100644 index 0000000000..ea057ee691 --- /dev/null +++ b/iceoryx2-cal/src/bag/mod.rs @@ -0,0 +1,149 @@ +// Copyright (c) 2026 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache Software License 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license +// which is available at https://opensource.org/licenses/MIT. +// +// SPDX-License-Identifier: Apache-2.0 OR MIT + +//! Offers an interface to a container to concurrently add, remove and access +//! values with a fixed position for the lifetime of the data. The data in the +//! container is not necessarily ordered. +//! +//! # Example +//! +//! ``` +//! use core::ptr::NonNull; +//! +//! use iceoryx2_bb_container::queue::RelocatableContainer; +//! use iceoryx2_bb_elementary_traits::allocator::{Allocate, AllocationError}; +//! use iceoryx2_cal::bag::*; +//! +//! fn create_bag>>( +//! capacity: usize, +//! allocator: A, +//! ) -> Result, AllocationError> { +//! let mut bag = unsafe { B::Bag::::new_uninit(capacity) }; +//! unsafe { +//! bag.init(&allocator)?; +//! } +//! Ok(bag) +//! } +//! ``` + +pub mod default_bag; +pub mod recommended; + +use core::fmt::Debug; + +use iceoryx2_bb_container::queue::RelocatableContainer; +use iceoryx2_bb_elementary_traits::zero_copy_send::ZeroCopySend; + +use iceoryx2_bb_lock_free::mpmc::container::{ + ContainerAddFailure, ContainerHandle, ContainerRemoveError, ContainerState, +}; +use iceoryx2_bb_lock_free::mpmc::robust_unique_index_set::OwnerId; +use iceoryx2_bb_lock_free::mpmc::unique_index_set_enums::{ReleaseMode, ReleaseState}; + +pub type BagHandle = ContainerHandle; +pub type BagState = ContainerState; +pub type BagAddFailure = ContainerAddFailure; +pub type BagRemoveError = ContainerRemoveError; + +/// A super trait defining the trait bounds of a [`Bag`] type +pub trait BagType: Copy + Debug + ZeroCopySend {} +impl BagType for T {} + +/// The [`BagFamily`] provides the associated type for the concrete type implementing the concept +pub trait BagFamily: Debug + 'static { + type Bag: Debug + Send + Sync + ZeroCopySend + RelocatableContainer + Bag; +} + +/// The [`Bag`] trait provides access to an unordered container with fix position for the data +/// during its lifetime +pub trait Bag: Debug { + /// Returns the capacity of the bag. + fn capacity(&self) -> usize; + + /// Returns the current len of the bag + fn len(&self) -> usize; + + /// Returns true if the container is empty, otherwise false + fn is_empty(&self) -> bool; + + /// Adds a new element to the [`Bag`]. If there is no more space available it returns + /// [`None`], otherwise [`Some`] containing the the index value to the underlying element. + /// + /// Must be released with [`Bag::remove()`]. + /// + /// # Safety + /// + /// * Ensure that [`Bag::init()`](RelocatableContainer::init()) was called before calling this method + /// + unsafe fn add( + &self, + value: T, + owner_id: OwnerId, + ) -> Result<(*const T, BagHandle), BagAddFailure>; + + /// Useful in IPC context when an application holding the UniqueIndex has died. + /// + /// # Safety + /// + /// * Ensure that [`Bag::init()`](RelocatableContainer::init()) was called before calling this method + /// * Ensure that no one else possesses the [`BagHandle`] and the index was unrecoverable + /// lost + /// * Ensure that the `handle` was acquired by the same [`Bag`] + /// with [`Bag::add()`], otherwise the method will panic. + /// + /// **Important:** If the [`BagHandle`] still exists it causes double frees or freeing an index + /// which was allocated afterwards + /// + unsafe fn remove( + &self, + handle: BagHandle, + mode: ReleaseMode, + ) -> Result; + + /// Returns [`BagState`] which contains all elements of this bag. Be aware that + /// this state can be out of date as soon as it is returned from this function. + /// + /// # Safety + /// + /// * Ensure that [`Bag::init()`](RelocatableContainer::init()) was called before calling this method + /// + unsafe fn get_state(&self) -> BagState; + + /// Recovers and releases all entries the dead [`OwnerId`] owned. It assumes that the dead owner + /// maybe died while adding some entry, therefore it removes all entries where the + /// [`OwnerId`] does not contain any data or where there was data and the provided predicate + /// returned [`true`]. + /// + /// # Safety + /// + /// * Ensure that [`Bag::init()`](RelocatableContainer::init()) was called before calling this method + /// * All existing [`BagHandle`] that belong to the [`OwnerId`] must never be removed with + /// [`Bag::remove()`] otherwise we corrupt the state. + /// + unsafe fn recover bool>( + &self, + dead_owner_id: OwnerId, + predicate: F, + mode: ReleaseMode, + ) -> ReleaseState; + + /// Syncs the [`BagState`] with the current state of the [`Bag`]. If the state has + /// changed it returns true, otherwise false. + /// + /// # Safety + /// + /// * Ensure that [`Bag::init()`](RelocatableContainer::init()) was called before calling this method + /// * Ensure that the input argument `previous_state` was acquired by the same [`Bag`] + /// with [`Bag::get_state()`], otherwise the method will panic. + /// + unsafe fn update_state(&self, previous_state: &mut BagState) -> bool; +} diff --git a/iceoryx2-cal/src/bag/recommended.rs b/iceoryx2-cal/src/bag/recommended.rs new file mode 100644 index 0000000000..70b1b6e0c3 --- /dev/null +++ b/iceoryx2-cal/src/bag/recommended.rs @@ -0,0 +1,16 @@ +// Copyright (c) 2026 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache Software License 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license +// which is available at https://opensource.org/licenses/MIT. +// +// SPDX-License-Identifier: Apache-2.0 OR MIT + +/// Provides the recommended +/// [`BagFamily`](crate::bag::BagFamily) concept implementation +/// for the target. +pub type Recommended = crate::bag::default_bag::DefaultBag; diff --git a/iceoryx2-cal/src/lib.rs b/iceoryx2-cal/src/lib.rs index 325f506312..880d302292 100644 --- a/iceoryx2-cal/src/lib.rs +++ b/iceoryx2-cal/src/lib.rs @@ -22,6 +22,7 @@ extern crate alloc; extern crate iceoryx2_bb_loggers; pub mod arc_sync_policy; +pub mod bag; pub mod communication_channel; pub mod dynamic_storage; pub mod event; diff --git a/iceoryx2/conformance-tests/src/node_death.rs b/iceoryx2/conformance-tests/src/node_death.rs index bf87741116..ab597f4134 100644 --- a/iceoryx2/conformance-tests/src/node_death.rs +++ b/iceoryx2/conformance-tests/src/node_death.rs @@ -40,8 +40,8 @@ pub mod node_death { fn does_support_persistency() -> bool { ::DynamicStorage::< - iceoryx2::service::dynamic_config::DynamicConfig, - >::does_support_persistency() + iceoryx2::service::dynamic_config::DynamicConfig, + >::does_support_persistency() } #[conformance_test] diff --git a/iceoryx2/src/node/mod.rs b/iceoryx2/src/node/mod.rs index f73cffb169..445937a588 100644 --- a/iceoryx2/src/node/mod.rs +++ b/iceoryx2/src/node/mod.rs @@ -165,7 +165,6 @@ use iceoryx2_bb_elementary::CallbackProgression; use iceoryx2_bb_elementary::scope_guard::ScopeGuardBuilder; use iceoryx2_bb_elementary_traits::testing::abandonable::Abandonable; use iceoryx2_bb_elementary_traits::zero_copy_send::ZeroCopySend; -use iceoryx2_bb_lock_free::mpmc::container::ContainerHandle; use iceoryx2_bb_posix::adaptive_wait::{AdaptiveWaitBuilder, AdaptiveWaitStrategy}; use iceoryx2_bb_posix::clock::Time; use iceoryx2_bb_posix::clock::{NanosleepError, nanosleep}; @@ -177,6 +176,7 @@ use iceoryx2_bb_posix::mutex::MutexType; use iceoryx2_bb_posix::process::Process; use iceoryx2_bb_posix::signal::SignalHandler; use iceoryx2_bb_system_types::file_name::FileName; +use iceoryx2_cal::bag::BagHandle; use iceoryx2_cal::named_concept::{NamedConceptPathHintRemoveError, NamedConceptRemoveError}; use iceoryx2_cal::{ monitoring::*, named_concept::NamedConceptListError, serialize::*, static_storage::*, @@ -842,7 +842,7 @@ fn remove_node( #[derive(Debug)] pub(crate) struct RegisteredServices { - handle: MutexHandle>, + handle: MutexHandle>, } impl RegisteredServices { @@ -863,9 +863,9 @@ impl RegisteredServices { } fn insert( - services: &mut BTreeMap, + services: &mut BTreeMap, service_hash: ServiceHash, - handle: ContainerHandle, + handle: BagHandle, ) { if services.insert(service_hash, (handle, 1)).is_some() { fatal_panic!(from "RegisteredServices::insert()", @@ -874,7 +874,7 @@ impl RegisteredServices { } } - pub(crate) fn add(&self, service_hash: &ServiceHash, handle: ContainerHandle) { + pub(crate) fn add(&self, service_hash: &ServiceHash, handle: BagHandle) { let mut guard = fatal_panic!( from self, when self.mutex().lock(), @@ -884,7 +884,7 @@ impl RegisteredServices { Self::insert(&mut guard, *service_hash, handle); } - pub(crate) fn add_or Result>( + pub(crate) fn add_or Result>( &self, service_hash: &ServiceHash, mut or_callback: F, @@ -907,7 +907,7 @@ impl RegisteredServices { Ok(()) } - pub(crate) fn remove( + pub(crate) fn remove( &self, service_hash: &ServiceHash, mut cleanup_call: F, @@ -929,7 +929,7 @@ impl RegisteredServices { drop(guard); } - fn mutex(&self) -> Mutex<'_, '_, BTreeMap> { + fn mutex(&self) -> Mutex<'_, '_, BTreeMap> { // Safe - the mutex is initialized when constructing the struct and // not interacted with by anything else. unsafe { Mutex::from_handle(&self.handle) } diff --git a/iceoryx2/src/port/client.rs b/iceoryx2/src/port/client.rs index f8e8bdee69..9e6081ad36 100644 --- a/iceoryx2/src/port/client.rs +++ b/iceoryx2/src/port/client.rs @@ -110,8 +110,9 @@ use iceoryx2_bb_elementary_traits::allocator::{AllocationGrowError, ContentPlace use iceoryx2_bb_elementary_traits::iceoryx_send::IceoryxSend; use iceoryx2_bb_elementary_traits::testing::abandonable::Abandonable; use iceoryx2_bb_elementary_traits::zero_copy_send::ZeroCopySend; -use iceoryx2_bb_lock_free::mpmc::container::{ContainerHandle, ContainerState}; use iceoryx2_bb_memory::heap_allocator::HeapAllocator; +use iceoryx2_cal::bag::Bag; +use iceoryx2_cal::bag::{BagHandle, BagState}; use iceoryx2_cal::shared_memory::ShmPointer; use iceoryx2_cal::shm_allocator::PointerOffset; use iceoryx2_cal::zero_copy_connection::{CHANNEL_STATE_CLOSED, CHANNEL_STATE_OPEN}; @@ -176,8 +177,8 @@ pub struct ClientSharedState { pub(crate) config: LocalClientConfig, pub(crate) request_sender: Sender>, pub(crate) response_receiver: Receiver>, - client_handle: UnsafeCell>, - server_list_state: UnsafeCell>, + client_handle: UnsafeCell>, + server_list_state: UnsafeCell>, pub(crate) available_channel_ids: UnsafeCell>, pub(crate) active_request_counter: AtomicUsize, pub(crate) max_active_requests: usize, @@ -661,7 +662,7 @@ impl< .dynamic_storage() .get() .request_response() - .add_client_id(client_details) + .register_client_id(client_details) { Some(v) => v, None => { diff --git a/iceoryx2/src/port/listener.rs b/iceoryx2/src/port/listener.rs index fe62709d78..3bef453a02 100644 --- a/iceoryx2/src/port/listener.rs +++ b/iceoryx2/src/port/listener.rs @@ -72,11 +72,11 @@ use core::ptr::NonNull; use core::time::Duration; use iceoryx2_bb_concurrency::atomic::Ordering; use iceoryx2_bb_elementary_traits::testing::abandonable::Abandonable; -use iceoryx2_bb_lock_free::mpmc::container::ContainerHandle; use iceoryx2_bb_lock_free::mpmc::counting_bit_set::RelocatableCountingBitSet; use iceoryx2_bb_posix::file_descriptor::{FileDescriptor, FileDescriptorBased}; use iceoryx2_bb_posix::file_descriptor_set::SynchronousMultiplexing; use iceoryx2_cal::arc_sync_policy::ArcSyncPolicy; +use iceoryx2_cal::bag::BagHandle; use iceoryx2_cal::dynamic_storage::DynamicStorage; use iceoryx2_cal::event::event_state::EventActivation; use iceoryx2_cal::event::{EventId, ListenerBuilder, NamedConceptMgmt}; @@ -115,7 +115,7 @@ impl core::error::Error for ListenerCreateError {} /// Represents the receiving endpoint of an event based communication. #[derive(Debug)] pub struct Listener { - dynamic_listener_handle: ContainerHandle, + dynamic_listener_handle: BagHandle, listener: Service::ArcThreadSafetyPolicy< >::Listener, >, @@ -229,13 +229,15 @@ impl Listener { // !MUST! be the last task otherwise a listener is added to the dynamic config without // the creation of all required channels - let (details, handle) = match service.dynamic_storage().get().event().add_listener_id( - ListenerDetails { + let (details, handle) = match service + .dynamic_storage() + .get() + .event() + .register_listener_id(ListenerDetails { listener_id, listener_name: config.port_name, node_id: *service.shared_node().id(), - }, - ) { + }) { Some(v) => v, None => { fail!(from origin, with ListenerCreateError::ExceedsMaxSupportedListeners, diff --git a/iceoryx2/src/port/notifier.rs b/iceoryx2/src/port/notifier.rs index 9710c78434..a771b9922f 100644 --- a/iceoryx2/src/port/notifier.rs +++ b/iceoryx2/src/port/notifier.rs @@ -45,8 +45,9 @@ use iceoryx2_bb_concurrency::atomic::Ordering; use iceoryx2_bb_concurrency::cell::UnsafeCell; use iceoryx2_bb_elementary::CallbackProgression; use iceoryx2_bb_elementary_traits::testing::abandonable::Abandonable; -use iceoryx2_bb_lock_free::mpmc::container::{ContainerHandle, ContainerState}; use iceoryx2_bb_lock_free::mpmc::counting_bit_set::RelocatableCountingBitSet; +use iceoryx2_cal::bag::Bag; +use iceoryx2_cal::bag::{BagHandle, BagState}; use iceoryx2_cal::{ arc_sync_policy::ArcSyncPolicy, dynamic_storage::DynamicStorage, event::NotifierBuilder, }; @@ -134,7 +135,7 @@ struct ListenerConnections { #[allow(clippy::type_complexity)] connections: Vec>>>, service_state: SharedServiceState, - list_state: UnsafeCell>, + list_state: UnsafeCell>, } impl Abandonable for ListenerConnections { @@ -148,7 +149,7 @@ impl ListenerConnections { fn new( size: usize, service_state: SharedServiceState, - list_state: UnsafeCell>, + list_state: UnsafeCell>, ) -> Self { let mut new_self = Self { connections: vec![], @@ -315,7 +316,7 @@ pub struct Notifier { listener_connections: Service::ArcThreadSafetyPolicy>, default_event_id: EventId, event_id_max_value: usize, - dynamic_notifier_handle: ContainerHandle, + dynamic_notifier_handle: BagHandle, notifier_details: &'static NotifierDetails, on_drop_notification: Option, // IMPORTANT! @@ -460,7 +461,7 @@ impl Notifier { .dynamic_storage() .get() .event() - .add_notifier_id(NotifierDetails { + .register_notifier_id(NotifierDetails { notifier_id, node_id, notifier_name: config.port_name, diff --git a/iceoryx2/src/port/publisher.rs b/iceoryx2/src/port/publisher.rs index f8f845a692..95cbdd3d57 100644 --- a/iceoryx2/src/port/publisher.rs +++ b/iceoryx2/src/port/publisher.rs @@ -120,8 +120,9 @@ use iceoryx2_bb_elementary_traits::allocator::{AllocationGrowError, ContentPlace use iceoryx2_bb_elementary_traits::iceoryx_send::IceoryxSend; use iceoryx2_bb_elementary_traits::testing::abandonable::Abandonable; use iceoryx2_bb_elementary_traits::zero_copy_send::ZeroCopySend; -use iceoryx2_bb_lock_free::mpmc::container::{ContainerHandle, ContainerState}; use iceoryx2_cal::arc_sync_policy::ArcSyncPolicy; +use iceoryx2_cal::bag::Bag; +use iceoryx2_cal::bag::{BagHandle, BagState}; use iceoryx2_cal::dynamic_storage::DynamicStorage; use iceoryx2_cal::shared_memory::ShmPointer; use iceoryx2_cal::shm_allocator::PointerOffset; @@ -198,7 +199,7 @@ impl OffsetAndSize { pub struct PublisherSharedState { config: LocalPublisherConfig, pub(crate) sender: Sender>, - subscriber_list_state: UnsafeCell>, + subscriber_list_state: UnsafeCell>, history: Option>>, is_active: AtomicBool, // IMPORTANT! @@ -390,7 +391,7 @@ pub struct Publisher< > { pub(crate) publisher_shared_state: Service::ArcThreadSafetyPolicy>, - dynamic_publisher_handle: ContainerHandle, + dynamic_publisher_handle: BagHandle, publisher_details: &'static PublisherDetails, _payload: PhantomData, _user_header: PhantomData, @@ -609,7 +610,7 @@ impl< .dynamic_storage() .get() .publish_subscribe() - .add_publisher_id(publisher_details) + .register_publisher_id(publisher_details) { Some(v) => v, None => { diff --git a/iceoryx2/src/port/reader.rs b/iceoryx2/src/port/reader.rs index a49b173eab..729c9f6b8b 100644 --- a/iceoryx2/src/port/reader.rs +++ b/iceoryx2/src/port/reader.rs @@ -55,11 +55,11 @@ use iceoryx2_bb_concurrency::atomic::Ordering; use iceoryx2_bb_elementary::math::align; use iceoryx2_bb_elementary_traits::testing::abandonable::Abandonable; use iceoryx2_bb_elementary_traits::zero_copy_send::ZeroCopySend; -use iceoryx2_bb_lock_free::mpmc::container::ContainerHandle; use iceoryx2_bb_lock_free::spmc::unrestricted_atomic::{ UnrestrictedAtomic, UnrestrictedAtomicMgmt, }; use iceoryx2_cal::arc_sync_policy::ArcSyncPolicy; +use iceoryx2_cal::bag::BagHandle; use iceoryx2_cal::dynamic_storage::DynamicStorage; use iceoryx2_cal::shared_memory::SharedMemory; use iceoryx2_log::{fail, fatal_panic}; @@ -161,7 +161,7 @@ pub struct Reader< KeyType: Send + Sync + Eq + Clone + Copy + Debug + 'static + Hash + ZeroCopySend, > { shared_state: Service::ArcThreadSafetyPolicy>, - dynamic_reader_handle: ContainerHandle, + dynamic_reader_handle: BagHandle, reader_details: &'static ReaderDetails, } @@ -240,13 +240,15 @@ impl< // !MUST! be the last task otherwise a reader is added to the dynamic config without the // creation of all required resources - let (details, handle) = match service.dynamic_storage().get().blackboard().add_reader_id( - ReaderDetails { + let (details, handle) = match service + .dynamic_storage() + .get() + .blackboard() + .register_reader_id(ReaderDetails { reader_id, reader_name: config.port_name, node_id: *service.shared_node().id(), - }, - ) { + }) { Some(v) => v, None => { fail!(from origin, with ReaderCreateError::ExceedsMaxSupportedReaders, diff --git a/iceoryx2/src/port/server.rs b/iceoryx2/src/port/server.rs index 773cc3f774..0abd7324d5 100644 --- a/iceoryx2/src/port/server.rs +++ b/iceoryx2/src/port/server.rs @@ -106,9 +106,10 @@ use iceoryx2_bb_elementary_traits::iceoryx_send::IceoryxSend; use iceoryx2_bb_elementary_traits::testing::abandonable::Abandonable; use iceoryx2_bb_elementary_traits::zero_copy_send::ZeroCopySend; use iceoryx2_bb_flatbuffers::AllocationStrategy; -use iceoryx2_bb_lock_free::mpmc::container::{ContainerHandle, ContainerState}; use iceoryx2_bb_memory::heap_allocator::HeapAllocator; use iceoryx2_cal::arc_sync_policy::ArcSyncPolicy; +use iceoryx2_cal::bag::Bag; +use iceoryx2_cal::bag::{BagHandle, BagState}; use iceoryx2_cal::dynamic_storage::DynamicStorage; use iceoryx2_cal::shared_memory::ShmPointer; use iceoryx2_cal::shm_allocator::PointerOffset; @@ -139,9 +140,9 @@ pub(crate) const INVALID_CONNECTION_ID: usize = usize::MAX; pub struct SharedServerState { pub(crate) config: LocalServerConfig, pub(crate) response_sender: Sender>, - server_handle: UnsafeCell>, + server_handle: UnsafeCell>, pub(crate) request_receiver: Receiver>, - client_list_state: UnsafeCell>, + client_list_state: UnsafeCell>, service_state: SharedServiceState>, // IMPORTANT! // Fields of a rust struct are dropped in declaration order. Since this tag is our marker that the @@ -540,7 +541,7 @@ impl< .dynamic_storage() .get() .request_response() - .add_server_id(ServerDetails { + .register_server_id(ServerDetails { server_id, node_id: *service.shared_node().id(), request_buffer_size: static_config.max_active_requests_per_client, diff --git a/iceoryx2/src/port/subscriber.rs b/iceoryx2/src/port/subscriber.rs index bdc51fb7a3..8ea1378f36 100644 --- a/iceoryx2/src/port/subscriber.rs +++ b/iceoryx2/src/port/subscriber.rs @@ -44,9 +44,10 @@ use iceoryx2_bb_elementary::cyclic_tagger::CyclicTagger; use iceoryx2_bb_elementary_traits::iceoryx_send::IceoryxSend; use iceoryx2_bb_elementary_traits::testing::abandonable::Abandonable; use iceoryx2_bb_elementary_traits::zero_copy_send::ZeroCopySend; -use iceoryx2_bb_lock_free::mpmc::container::{ContainerHandle, ContainerState}; use iceoryx2_bb_memory::heap_allocator::HeapAllocator; use iceoryx2_cal::arc_sync_policy::ArcSyncPolicy; +use iceoryx2_cal::bag::Bag; +use iceoryx2_cal::bag::{BagHandle, BagState}; use iceoryx2_cal::dynamic_storage::DynamicStorage; use iceoryx2_cal::zero_copy_connection::{CHANNEL_STATE_OPEN, ChannelId}; use iceoryx2_log::{fail, warn}; @@ -102,7 +103,7 @@ impl core::error::Error for SubscriberCreateError {} #[derive(Debug)] pub(crate) struct SubscriberSharedState { pub(crate) receiver: Receiver>, - pub(crate) publisher_list_state: UnsafeCell>, + pub(crate) publisher_list_state: UnsafeCell>, // IMPORTANT! // Fields of a rust struct are dropped in declaration order. Since this tag is our marker that the // port exists and might require cleanup after a crash, the tag must be defined as last member of @@ -127,7 +128,7 @@ pub struct Subscriber< Payload: IceoryxSend + Debug + ?Sized + 'static, UserHeader: ZeroCopySend + Debug, > { - dynamic_subscriber_handle: ContainerHandle, + dynamic_subscriber_handle: BagHandle, subscriber_details: &'static SubscriberDetails, subscriber_shared_state: Service::ArcThreadSafetyPolicy>, @@ -329,7 +330,7 @@ impl< .dynamic_storage() .get() .publish_subscribe() - .add_subscriber_id(SubscriberDetails { + .register_subscriber_id(SubscriberDetails { subscriber_id, buffer_size, history_request, diff --git a/iceoryx2/src/port/writer.rs b/iceoryx2/src/port/writer.rs index 99736b7e45..0f68e69afa 100644 --- a/iceoryx2/src/port/writer.rs +++ b/iceoryx2/src/port/writer.rs @@ -61,11 +61,11 @@ use iceoryx2_bb_concurrency::cell::UnsafeCell; use iceoryx2_bb_elementary::math::align; use iceoryx2_bb_elementary_traits::testing::abandonable::Abandonable; use iceoryx2_bb_elementary_traits::zero_copy_send::ZeroCopySend; -use iceoryx2_bb_lock_free::mpmc::container::ContainerHandle; use iceoryx2_bb_lock_free::spmc::unrestricted_atomic::{ Producer, UnrestrictedAtomic, UnrestrictedAtomicMgmt, }; use iceoryx2_cal::arc_sync_policy::ArcSyncPolicy; +use iceoryx2_cal::bag::BagHandle; use iceoryx2_cal::dynamic_storage::DynamicStorage; use iceoryx2_cal::shared_memory::SharedMemory; use iceoryx2_log::{fail, fatal_panic}; @@ -76,7 +76,7 @@ struct WriterSharedState< KeyType: Send + Sync + Eq + Clone + Debug + 'static + Hash + ZeroCopySend, > { service_state: SharedServiceState>, - dynamic_writer_handle: UnsafeCell>, + dynamic_writer_handle: UnsafeCell>, _key: PhantomData, } @@ -216,13 +216,15 @@ impl< // !MUST! be the last task otherwise a writer is added to the dynamic config without the // creation of all required resources - let (details, handle) = match service.dynamic_storage().get().blackboard().add_writer_id( - WriterDetails { + let (details, handle) = match service + .dynamic_storage() + .get() + .blackboard() + .register_writer_id(WriterDetails { writer_id, writer_name: config.port_name, node_id: *service.shared_node().id(), - }, - ) { + }) { Some(unique_index) => unique_index, None => { fail!(from origin, with WriterCreateError::ExceedsMaxSupportedWriters, diff --git a/iceoryx2/src/service/builder/blackboard.rs b/iceoryx2/src/service/builder/blackboard.rs index 80b18a2dfd..a35f7973f0 100644 --- a/iceoryx2/src/service/builder/blackboard.rs +++ b/iceoryx2/src/service/builder/blackboard.rs @@ -549,9 +549,10 @@ impl< messaging_pattern_settings: MessagingPatternSettings::Blackboard( dynamic_config_setting, ), - additional_size: dynamic_config::blackboard::DynamicConfig::memory_size( - &dynamic_config_setting, - ), + additional_size: + dynamic_config::blackboard::DynamicConfig::::memory_size( + &dynamic_config_setting, + ), max_number_of_nodes: blackboard_config.max_nodes, } }; diff --git a/iceoryx2/src/service/builder/event.rs b/iceoryx2/src/service/builder/event.rs index 54549b8338..b26e19e80f 100644 --- a/iceoryx2/src/service/builder/event.rs +++ b/iceoryx2/src/service/builder/event.rs @@ -533,9 +533,10 @@ impl Builder { DynamicConfigCreationArgs { messaging_pattern_settings: MessagingPatternSettings::Event(dynamic_config_setting), - additional_size: dynamic_config::event::DynamicConfig::memory_size( - &dynamic_config_setting, - ), + additional_size: + dynamic_config::event::DynamicConfig::::memory_size( + &dynamic_config_setting, + ), max_number_of_nodes: event_config.max_nodes, } }; diff --git a/iceoryx2/src/service/builder/mod.rs b/iceoryx2/src/service/builder/mod.rs index 7abc9b5e7c..acb3912fb6 100644 --- a/iceoryx2/src/service/builder/mod.rs +++ b/iceoryx2/src/service/builder/mod.rs @@ -40,13 +40,13 @@ use iceoryx2_bb_elementary::enum_gen; use iceoryx2_bb_elementary::package_version::PackageVersion; use iceoryx2_bb_elementary_traits::iceoryx_send::IceoryxSend; use iceoryx2_bb_elementary_traits::zero_copy_send::ZeroCopySend; -use iceoryx2_bb_lock_free::mpmc::container::ContainerHandle; use iceoryx2_bb_memory::bump_allocator::BumpAllocator; use iceoryx2_bb_posix::adaptive_wait::AdaptiveWaitBuilder; use iceoryx2_bb_posix::adaptive_wait::AdaptiveWaitError; use iceoryx2_bb_posix::clock::NanosleepError; use iceoryx2_bb_posix::clock::Time; use iceoryx2_bb_posix::file::AccessMode; +use iceoryx2_cal::bag::BagHandle; use iceoryx2_cal::dynamic_storage::DynamicStorageCreateError; use iceoryx2_cal::dynamic_storage::DynamicStorageOpenError; use iceoryx2_cal::dynamic_storage::{DynamicStorage, DynamicStorageBuilder}; @@ -287,6 +287,9 @@ pub struct BuilderWithServiceType { _phantom_data: PhantomData, } +type DynanmicConfigStorage = + ::DynamicStorage::Bag>>; + impl BuilderWithServiceType { fn new(service_config: StaticConfig, shared_node: SharedNode) -> Self { Self { @@ -880,7 +883,7 @@ impl BuilderWithServiceType { } fn config_init_call( - config: &mut MaybeUninit, + config: &mut MaybeUninit>, allocator: &mut BumpAllocator, args: &DynamicConfigCreationArgs, ) -> bool { @@ -896,17 +899,15 @@ impl BuilderWithServiceType { &self, args: DynamicConfigCreationArgs, node_id: UniqueNodeId, - ) -> Result< - (ContainerHandle, ServiceType::DynamicStorage), - DynamicStorageCreateError, - > { - let required_memory_size = DynamicConfig::memory_size(args.max_number_of_nodes); + ) -> Result<(BagHandle, DynanmicConfigStorage), DynamicStorageCreateError> { + let required_memory_size = + DynamicConfig::::memory_size(args.max_number_of_nodes); let segment_name = dynamic_config_name(self.service_config.unique_service_id()); let mut handle = None; - match < as DynamicStorage< - DynamicConfig, + match <> as DynamicStorage< + DynamicConfig, >>::Builder<'_> as NamedConceptBuilder< - ServiceType::DynamicStorage, + ServiceType::DynamicStorage>, >>::new(&segment_name) .config(&dynamic_config_storage_config::(self.shared_node.config())) .supplementary_size(args.additional_size + required_memory_size) @@ -936,10 +937,7 @@ impl BuilderWithServiceType { &self, args: DynamicConfigCreationArgs, node_id: UniqueNodeId, - ) -> Result< - (ContainerHandle, ServiceType::DynamicStorage), - DynamicStorageCreateError, - > { + ) -> Result<(BagHandle, DynanmicConfigStorage), DynamicStorageCreateError> { let msg = "Failed to create dynamic storage for service"; match self.create_dynamic_config_storage_resource(args, node_id) { Ok((node_handle, storage)) => Ok((node_handle, storage)), @@ -957,14 +955,17 @@ impl BuilderWithServiceType { fn open_dynamic_config_storage( &self, unique_service_id: UniqueServiceId, - ) -> Result, OpenDynamicStorageFailure> { + ) -> Result< + ServiceType::DynamicStorage>, + OpenDynamicStorageFailure, + > { let msg = "Failed to open dynamic service information"; let segment_name = dynamic_config_name(unique_service_id); let storage = fail!(from self, when - < as DynamicStorage< - DynamicConfig, + <> as DynamicStorage< + DynamicConfig, >>::Builder<'_> as NamedConceptBuilder< - ServiceType::DynamicStorage, + ServiceType::DynamicStorage>, >>::new(&segment_name) .timeout(self.shared_node.config().global.creation_timeout) .config(&dynamic_config_storage_config::(self.shared_node.config())) diff --git a/iceoryx2/src/service/builder/publish_subscribe.rs b/iceoryx2/src/service/builder/publish_subscribe.rs index 23fa0d922a..b10938158b 100644 --- a/iceoryx2/src/service/builder/publish_subscribe.rs +++ b/iceoryx2/src/service/builder/publish_subscribe.rs @@ -724,9 +724,9 @@ impl< messaging_pattern_settings: MessagingPatternSettings::PublishSubscribe( dynamic_config_setting, ), - additional_size: dynamic_config::publish_subscribe::DynamicConfig::memory_size( - &dynamic_config_setting, - ), + additional_size: dynamic_config::publish_subscribe::DynamicConfig::< + ServiceType::Bag, + >::memory_size(&dynamic_config_setting), max_number_of_nodes: pubsub_config.max_nodes, } }; diff --git a/iceoryx2/src/service/builder/request_response.rs b/iceoryx2/src/service/builder/request_response.rs index 71e5da1342..4fd9ee09aa 100644 --- a/iceoryx2/src/service/builder/request_response.rs +++ b/iceoryx2/src/service/builder/request_response.rs @@ -870,9 +870,10 @@ impl< messaging_pattern_settings: MessagingPatternSettings::RequestResponse( dynamic_config_setting, ), - additional_size: dynamic_config::request_response::DynamicConfig::memory_size( - &dynamic_config_setting, - ), + additional_size: + dynamic_config::request_response::DynamicConfig::::memory_size( + &dynamic_config_setting, + ), max_number_of_nodes: reqres_config.max_nodes, } }; diff --git a/iceoryx2/src/service/config_scheme.rs b/iceoryx2/src/service/config_scheme.rs index 25d94c8d38..080a61bc58 100644 --- a/iceoryx2/src/service/config_scheme.rs +++ b/iceoryx2/src/service/config_scheme.rs @@ -18,8 +18,8 @@ use iceoryx2_log::fatal_panic; pub(crate) fn dynamic_config_storage_config( global_config: &config::Config, -) -> as NamedConceptMgmt>::Configuration { - < as NamedConceptMgmt>::Configuration>::default() +) -> > as NamedConceptMgmt>::Configuration { + <> as NamedConceptMgmt>::Configuration>::default() .prefix(&global_config.global.prefix) .suffix(&global_config.global.service.dynamic_config_storage_suffix) .path_hint(global_config.global.root_path()) diff --git a/iceoryx2/src/service/dynamic_config/blackboard.rs b/iceoryx2/src/service/dynamic_config/blackboard.rs index 5818298284..2056e43c63 100644 --- a/iceoryx2/src/service/dynamic_config/blackboard.rs +++ b/iceoryx2/src/service/dynamic_config/blackboard.rs @@ -32,9 +32,12 @@ use crate::identifiers::{UniqueNodeId, UniquePortId, UniqueReaderId, UniqueWrite use crate::port::port_name::PortName; use iceoryx2_bb_container::queue::RelocatableContainer; use iceoryx2_bb_derive_macros::ZeroCopySend; +use iceoryx2_bb_elementary::CallbackProgression; use iceoryx2_bb_elementary_traits::zero_copy_send::ZeroCopySend; -use iceoryx2_bb_lock_free::mpmc::{container::*, unique_index_set_enums::ReleaseMode}; +use iceoryx2_bb_lock_free::mpmc::unique_index_set_enums::ReleaseMode; use iceoryx2_bb_memory::bump_allocator::BumpAllocator; +use iceoryx2_cal::bag::BagHandle; +use iceoryx2_cal::bag::{Bag, BagFamily}; use iceoryx2_log::{error, fatal_panic}; use super::PortCleanupAction; @@ -79,16 +82,16 @@ pub struct WriterDetails { /// based service. Contains dynamic parameters like the connected endpoints etc.. #[repr(C)] #[derive(Debug, ZeroCopySend)] -pub struct DynamicConfig { - pub(crate) readers: Container, - pub(crate) writers: Container, +pub struct DynamicConfig { + pub(crate) readers: B::Bag, + pub(crate) writers: B::Bag, } -impl DynamicConfig { +impl DynamicConfig { pub(crate) fn new(config: &DynamicConfigSettings) -> Self { Self { - readers: unsafe { Container::new_uninit(config.number_of_readers) }, - writers: unsafe { Container::new_uninit(config.number_of_writers) }, + readers: unsafe { B::Bag::new_uninit(config.number_of_readers) }, + writers: unsafe { B::Bag::new_uninit(config.number_of_writers) }, } } @@ -104,8 +107,8 @@ impl DynamicConfig { } pub(crate) fn memory_size(config: &DynamicConfigSettings) -> usize { - Container::::memory_size(config.number_of_readers) - + Container::::memory_size(config.number_of_writers) + B::Bag::::memory_size(config.number_of_readers) + + B::Bag::::memory_size(config.number_of_writers) } /// Returns how many [`Reader`](crate::port::reader::Reader) ports are currently connected. @@ -170,27 +173,27 @@ impl DynamicConfig { } } - pub(crate) fn add_reader_id( + pub(crate) fn register_reader_id( &self, details: ReaderDetails, - ) -> Option<(*const ReaderDetails, ContainerHandle)> { + ) -> Option<(*const ReaderDetails, BagHandle)> { unsafe { self.readers.add(details, details.node_id.owner_id()).ok() } } - pub(crate) fn release_reader_handle(&self, handle: ContainerHandle) { + pub(crate) fn release_reader_handle(&self, handle: BagHandle) { if let Err(e) = unsafe { self.readers.remove(handle, ReleaseMode::Default) } { error!(from self, "Unable to deregister reader from service. This could indicate a corrupted system! [{e:?}]"); } } - pub(crate) fn add_writer_id( + pub(crate) fn register_writer_id( &self, details: WriterDetails, - ) -> Option<(*const WriterDetails, ContainerHandle)> { + ) -> Option<(*const WriterDetails, BagHandle)> { unsafe { self.writers.add(details, details.node_id.owner_id()).ok() } } - pub(crate) fn release_writer_handle(&self, handle: ContainerHandle) { + pub(crate) fn release_writer_handle(&self, handle: BagHandle) { if let Err(e) = unsafe { self.writers.remove(handle, ReleaseMode::Default) } { error!(from self, "Unable to deregister writer from service. This could indicate a corrupted system! [{e:?}]"); } diff --git a/iceoryx2/src/service/dynamic_config/event.rs b/iceoryx2/src/service/dynamic_config/event.rs index c4630d10b6..d4d6e238de 100644 --- a/iceoryx2/src/service/dynamic_config/event.rs +++ b/iceoryx2/src/service/dynamic_config/event.rs @@ -29,10 +29,13 @@ use iceoryx2_bb_concurrency::atomic::AtomicU64; use iceoryx2_bb_derive_macros::ZeroCopySend; +use iceoryx2_bb_elementary::CallbackProgression; use iceoryx2_bb_elementary_traits::relocatable_container::RelocatableContainer; use iceoryx2_bb_elementary_traits::zero_copy_send::ZeroCopySend; -use iceoryx2_bb_lock_free::mpmc::{container::*, unique_index_set_enums::ReleaseMode}; +use iceoryx2_bb_lock_free::mpmc::unique_index_set_enums::ReleaseMode; use iceoryx2_bb_memory::bump_allocator::BumpAllocator; +use iceoryx2_cal::bag::BagHandle; +use iceoryx2_cal::bag::{Bag, BagFamily}; use iceoryx2_log::{error, fatal_panic}; use crate::identifiers::{UniqueListenerId, UniqueNodeId, UniqueNotifierId, UniquePortId}; @@ -51,9 +54,9 @@ pub(crate) struct DynamicConfigSettings { /// based service. Contains dynamic parameters like the connected endpoints etc.. #[repr(C)] #[derive(Debug, ZeroCopySend)] -pub struct DynamicConfig { - pub(crate) listeners: Container, - pub(crate) notifiers: Container, +pub struct DynamicConfig { + pub(crate) listeners: B::Bag, + pub(crate) notifiers: B::Bag, pub(crate) elapsed_time_since_last_notification: AtomicU64, } @@ -85,11 +88,11 @@ pub struct NotifierDetails { pub node_id: UniqueNodeId, } -impl DynamicConfig { +impl DynamicConfig { pub(crate) fn new(config: &DynamicConfigSettings) -> Self { Self { - listeners: unsafe { Container::new_uninit(config.number_of_listeners) }, - notifiers: unsafe { Container::new_uninit(config.number_of_notifiers) }, + listeners: unsafe { B::Bag::new_uninit(config.number_of_listeners) }, + notifiers: unsafe { B::Bag::new_uninit(config.number_of_notifiers) }, elapsed_time_since_last_notification: AtomicU64::new(0), } } @@ -106,8 +109,8 @@ impl DynamicConfig { } pub(crate) fn memory_size(config: &DynamicConfigSettings) -> usize { - Container::::memory_size(config.number_of_listeners) - + Container::::memory_size(config.number_of_notifiers) + B::Bag::::memory_size(config.number_of_listeners) + + B::Bag::::memory_size(config.number_of_notifiers) } /// Returns how many [`Listener`](crate::port::listener::Listener) ports are currently connected. @@ -180,27 +183,27 @@ impl DynamicConfig { } } - pub(crate) fn add_listener_id( + pub(crate) fn register_listener_id( &self, details: ListenerDetails, - ) -> Option<(*const ListenerDetails, ContainerHandle)> { + ) -> Option<(*const ListenerDetails, BagHandle)> { unsafe { self.listeners.add(details, details.node_id.owner_id()).ok() } } - pub(crate) fn release_listener_handle(&self, handle: ContainerHandle) { + pub(crate) fn release_listener_handle(&self, handle: BagHandle) { if let Err(e) = unsafe { self.listeners.remove(handle, ReleaseMode::Default) } { error!(from self, "Unable to deregister listener from service. This could indicate a corrupted system! [{e:?}]"); } } - pub(crate) fn add_notifier_id( + pub(crate) fn register_notifier_id( &self, details: NotifierDetails, - ) -> Option<(*const NotifierDetails, ContainerHandle)> { + ) -> Option<(*const NotifierDetails, BagHandle)> { unsafe { self.notifiers.add(details, details.node_id.owner_id()).ok() } } - pub(crate) fn release_notifier_handle(&self, handle: ContainerHandle) { + pub(crate) fn release_notifier_handle(&self, handle: BagHandle) { if let Err(e) = unsafe { self.notifiers.remove(handle, ReleaseMode::Default) } { error!(from self, "Unable to deregister notifier from service. This could indicate a corrupted system! [{e:?}]"); } diff --git a/iceoryx2/src/service/dynamic_config/mod.rs b/iceoryx2/src/service/dynamic_config/mod.rs index 4ffe9b9b11..f2c268290c 100644 --- a/iceoryx2/src/service/dynamic_config/mod.rs +++ b/iceoryx2/src/service/dynamic_config/mod.rs @@ -35,11 +35,10 @@ use iceoryx2_bb_container::queue::RelocatableContainer; use iceoryx2_bb_derive_macros::ZeroCopySend; use iceoryx2_bb_elementary::CallbackProgression; use iceoryx2_bb_elementary_traits::zero_copy_send::ZeroCopySend; -use iceoryx2_bb_lock_free::mpmc::{ - container::{Container, ContainerAddFailure, ContainerHandle, ContainerRemoveError}, - unique_index_set_enums::{ReleaseMode, ReleaseState}, -}; +use iceoryx2_bb_lock_free::mpmc::unique_index_set_enums::{ReleaseMode, ReleaseState}; use iceoryx2_bb_memory::bump_allocator::BumpAllocator; +use iceoryx2_cal::bag::{Bag, BagFamily}; +use iceoryx2_cal::bag::{BagAddFailure, BagHandle, BagRemoveError}; use iceoryx2_log::{fail, fatal_panic}; use crate::identifiers::{UniqueNodeId, UniquePortId}; @@ -71,14 +70,14 @@ pub(crate) enum MessagingPatternSettings { #[derive(Debug, ZeroCopySend)] #[repr(C)] -pub(crate) enum MessagingPattern { - RequestResponse(request_response::DynamicConfig), - PublishSubscribe(publish_subscribe::DynamicConfig), - Event(event::DynamicConfig), - Blackboard(blackboard::DynamicConfig), +pub(crate) enum MessagingPattern { + RequestResponse(request_response::DynamicConfig), + PublishSubscribe(publish_subscribe::DynamicConfig), + Event(event::DynamicConfig), + Blackboard(blackboard::DynamicConfig), } -impl MessagingPattern { +impl MessagingPattern { pub(crate) fn new(settings: &MessagingPatternSettings) -> Self { match settings { MessagingPatternSettings::RequestResponse(v) => { @@ -100,12 +99,12 @@ impl MessagingPattern { #[doc(hidden)] #[derive(Debug, ZeroCopySend)] #[repr(C)] -pub struct DynamicConfig { - messaging_pattern: MessagingPattern, - nodes: Container, +pub struct DynamicConfig { + messaging_pattern: MessagingPattern, + nodes: B::Bag, } -impl Display for DynamicConfig { +impl Display for DynamicConfig { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!( f, @@ -115,19 +114,19 @@ impl Display for DynamicConfig { } } -impl DynamicConfig { +impl DynamicConfig { pub(crate) fn new_uninit( - messaging_pattern: MessagingPattern, + messaging_pattern: MessagingPattern, max_number_of_nodes: usize, ) -> Self { Self { messaging_pattern, - nodes: unsafe { Container::new_uninit(max_number_of_nodes) }, + nodes: unsafe { B::Bag::new_uninit(max_number_of_nodes) }, } } pub(crate) fn memory_size(max_number_of_nodes: usize) -> usize { - Container::::memory_size(max_number_of_nodes) + B::Bag::::memory_size(max_number_of_nodes) } pub(crate) unsafe fn init(&mut self, allocator: &BumpAllocator) { @@ -183,15 +182,15 @@ impl DynamicConfig { pub(crate) fn register_node_id( &self, node_id: UniqueNodeId, - ) -> Result { + ) -> Result { let msg = "Unable to register NodeId in service"; match unsafe { self.nodes.add(node_id, node_id.owner_id()) } { Ok(handle) => Ok(handle.1), - Err(ContainerAddFailure::IsLocked) => { + Err(BagAddFailure::IsLocked) => { fail!(from self, with RegisterNodeResult::MarkedForDestruction, "{msg} since the service is already marked for destruction."); } - Err(ContainerAddFailure::OutOfSpace) => { + Err(BagAddFailure::OutOfSpace) => { fail!(from self, with RegisterNodeResult::ExceedsMaxNumberOfNodes, "{msg} since it would exceed the maximum supported nodes of {}.", self.nodes.capacity()); } @@ -208,19 +207,19 @@ impl DynamicConfig { pub(crate) fn deregister_node_id( &self, - handle: ContainerHandle, - ) -> Result { + handle: BagHandle, + ) -> Result { match unsafe { self.nodes.remove(handle, ReleaseMode::LockIfLastIndex) } { Ok(ReleaseState::Locked) => Ok(DeregisterNodeState::NoMoreOwners), Ok(ReleaseState::Unlocked) => Ok(DeregisterNodeState::HasOwners), - Err(ContainerRemoveError::ContainerHandleNotOwnedByContainer) => { - fail!(from self, with ContainerRemoveError::ContainerHandleNotOwnedByContainer, + Err(BagRemoveError::ContainerHandleNotOwnedByContainer) => { + fail!(from self, with BagRemoveError::ContainerHandleNotOwnedByContainer, "Unable to deregister the node since it was not registered."); } } } - pub(crate) fn request_response(&self) -> &request_response::DynamicConfig { + pub(crate) fn request_response(&self) -> &request_response::DynamicConfig { match &self.messaging_pattern { MessagingPattern::RequestResponse(v) => v, m => { @@ -229,7 +228,7 @@ impl DynamicConfig { } } - pub(crate) fn publish_subscribe(&self) -> &publish_subscribe::DynamicConfig { + pub(crate) fn publish_subscribe(&self) -> &publish_subscribe::DynamicConfig { match &self.messaging_pattern { MessagingPattern::PublishSubscribe(v) => v, m => { @@ -238,7 +237,7 @@ impl DynamicConfig { } } - pub(crate) fn event(&self) -> &event::DynamicConfig { + pub(crate) fn event(&self) -> &event::DynamicConfig { match &self.messaging_pattern { MessagingPattern::Event(v) => v, m => { @@ -247,7 +246,7 @@ impl DynamicConfig { } } - pub(crate) fn blackboard(&self) -> &blackboard::DynamicConfig { + pub(crate) fn blackboard(&self) -> &blackboard::DynamicConfig { match &self.messaging_pattern { MessagingPattern::Blackboard(v) => v, m => { diff --git a/iceoryx2/src/service/dynamic_config/publish_subscribe.rs b/iceoryx2/src/service/dynamic_config/publish_subscribe.rs index 27770884a4..bd01835d59 100644 --- a/iceoryx2/src/service/dynamic_config/publish_subscribe.rs +++ b/iceoryx2/src/service/dynamic_config/publish_subscribe.rs @@ -26,16 +26,20 @@ //! # Ok(()) //! # } //! ``` + use crate::{ identifiers::{UniqueNodeId, UniquePortId, UniquePublisherId, UniqueSubscriberId}, port::details::data_segment::DataSegmentType, port::port_name::PortName, }; use iceoryx2_bb_derive_macros::ZeroCopySend; +use iceoryx2_bb_elementary::CallbackProgression; use iceoryx2_bb_elementary_traits::relocatable_container::RelocatableContainer; use iceoryx2_bb_elementary_traits::zero_copy_send::ZeroCopySend; -use iceoryx2_bb_lock_free::mpmc::{container::*, unique_index_set_enums::ReleaseMode}; +use iceoryx2_bb_lock_free::mpmc::unique_index_set_enums::ReleaseMode; use iceoryx2_bb_memory::bump_allocator::BumpAllocator; +use iceoryx2_cal::bag::BagHandle; +use iceoryx2_cal::bag::{Bag, BagFamily}; use iceoryx2_log::{error, fatal_panic}; use super::PortCleanupAction; @@ -96,16 +100,19 @@ pub struct SubscriberDetails { /// based service. Contains dynamic parameters like the connected endpoints etc.. #[repr(C)] #[derive(Debug, ZeroCopySend)] -pub struct DynamicConfig { - pub(crate) subscribers: Container, - pub(crate) publishers: Container, +pub struct DynamicConfig +where + B: BagFamily, +{ + pub(crate) subscribers: B::Bag, + pub(crate) publishers: B::Bag, } -impl DynamicConfig { +impl DynamicConfig { pub(crate) fn new(config: &DynamicConfigSettings) -> Self { Self { - subscribers: unsafe { Container::new_uninit(config.number_of_subscribers) }, - publishers: unsafe { Container::new_uninit(config.number_of_publishers) }, + subscribers: unsafe { B::Bag::new_uninit(config.number_of_subscribers) }, + publishers: unsafe { B::Bag::new_uninit(config.number_of_publishers) }, } } @@ -121,8 +128,8 @@ impl DynamicConfig { } pub(crate) fn memory_size(config: &DynamicConfigSettings) -> usize { - Container::::memory_size(config.number_of_subscribers) - + Container::::memory_size(config.number_of_publishers) + B::Bag::::memory_size(config.number_of_subscribers) + + B::Bag::::memory_size(config.number_of_publishers) } pub(crate) unsafe fn remove_dead_node_id< @@ -195,10 +202,10 @@ impl DynamicConfig { state.for_each(|_, details| callback(details)); } - pub(crate) fn add_subscriber_id( + pub(crate) fn register_subscriber_id( &self, details: SubscriberDetails, - ) -> Option<(*const SubscriberDetails, ContainerHandle)> { + ) -> Option<(*const SubscriberDetails, BagHandle)> { unsafe { self.subscribers .add(details, details.node_id.owner_id()) @@ -206,16 +213,16 @@ impl DynamicConfig { } } - pub(crate) fn release_subscriber_handle(&self, handle: ContainerHandle) { + pub(crate) fn release_subscriber_handle(&self, handle: BagHandle) { if let Err(e) = unsafe { self.subscribers.remove(handle, ReleaseMode::Default) } { error!(from self, "Unable to deregister subscriber from service. This could indicate a corrupted system! [{e:?}]"); } } - pub(crate) fn add_publisher_id( + pub(crate) fn register_publisher_id( &self, details: PublisherDetails, - ) -> Option<(*const PublisherDetails, ContainerHandle)> { + ) -> Option<(*const PublisherDetails, BagHandle)> { unsafe { self.publishers .add(details, details.node_id.owner_id()) @@ -223,7 +230,7 @@ impl DynamicConfig { } } - pub(crate) fn release_publisher_handle(&self, handle: ContainerHandle) { + pub(crate) fn release_publisher_handle(&self, handle: BagHandle) { if let Err(e) = unsafe { self.publishers.remove(handle, ReleaseMode::Default) } { error!(from self, "Unable to deregister publisher from service. This could indicate a corrupted system! [{e:?}]"); } diff --git a/iceoryx2/src/service/dynamic_config/request_response.rs b/iceoryx2/src/service/dynamic_config/request_response.rs index cc03068397..15a20cea82 100644 --- a/iceoryx2/src/service/dynamic_config/request_response.rs +++ b/iceoryx2/src/service/dynamic_config/request_response.rs @@ -14,11 +14,10 @@ use iceoryx2_bb_container::queue::RelocatableContainer; use iceoryx2_bb_derive_macros::ZeroCopySend; use iceoryx2_bb_elementary::CallbackProgression; use iceoryx2_bb_elementary_traits::zero_copy_send::ZeroCopySend; -use iceoryx2_bb_lock_free::mpmc::{ - container::{Container, ContainerHandle}, - unique_index_set_enums::ReleaseMode, -}; +use iceoryx2_bb_lock_free::mpmc::unique_index_set_enums::ReleaseMode; use iceoryx2_bb_memory::bump_allocator::BumpAllocator; +use iceoryx2_cal::bag::BagHandle; +use iceoryx2_cal::bag::{Bag, BagFamily}; use iceoryx2_log::{error, fatal_panic}; use crate::{ @@ -100,16 +99,16 @@ pub(crate) struct DynamicConfigSettings { /// based service. Contains dynamic parameters like the connected endpoints etc.. #[repr(C)] #[derive(Debug, ZeroCopySend)] -pub struct DynamicConfig { - pub(crate) servers: Container, - pub(crate) clients: Container, +pub struct DynamicConfig { + pub(crate) servers: B::Bag, + pub(crate) clients: B::Bag, } -impl DynamicConfig { +impl DynamicConfig { pub(crate) fn new(config: &DynamicConfigSettings) -> Self { Self { - servers: unsafe { Container::new_uninit(config.number_of_servers) }, - clients: unsafe { Container::new_uninit(config.number_of_clients) }, + servers: unsafe { B::Bag::new_uninit(config.number_of_servers) }, + clients: unsafe { B::Bag::new_uninit(config.number_of_clients) }, } } @@ -125,8 +124,8 @@ impl DynamicConfig { } pub(crate) fn memory_size(config: &DynamicConfigSettings) -> usize { - Container::::memory_size(config.number_of_servers) - + Container::::memory_size(config.number_of_clients) + B::Bag::::memory_size(config.number_of_servers) + + B::Bag::::memory_size(config.number_of_clients) } /// Returns how many [`crate::port::client::Client`] ports are currently connected. @@ -171,27 +170,27 @@ impl DynamicConfig { } } - pub(crate) fn add_client_id( + pub(crate) fn register_client_id( &self, details: ClientDetails, - ) -> Option<(*const ClientDetails, ContainerHandle)> { + ) -> Option<(*const ClientDetails, BagHandle)> { unsafe { self.clients.add(details, details.node_id.owner_id()).ok() } } - pub(crate) fn release_client_handle(&self, handle: ContainerHandle) { + pub(crate) fn release_client_handle(&self, handle: BagHandle) { if let Err(e) = unsafe { self.clients.remove(handle, ReleaseMode::Default) } { error!(from self, "Unable to deregister client from service. This could indicate a corrupted system! [{e:?}]"); } } - pub(crate) fn add_server_id( + pub(crate) fn register_server_id( &self, details: ServerDetails, - ) -> Option<(*const ServerDetails, ContainerHandle)> { + ) -> Option<(*const ServerDetails, BagHandle)> { unsafe { self.servers.add(details, details.node_id.owner_id()).ok() } } - pub(crate) fn release_server_handle(&self, handle: ContainerHandle) { + pub(crate) fn release_server_handle(&self, handle: BagHandle) { if let Err(e) = unsafe { self.servers.remove(handle, ReleaseMode::Default) } { error!(from self, "Unable to deregister server from service. This could indicate a corrupted system! [{e:?}]"); } diff --git a/iceoryx2/src/service/ipc.rs b/iceoryx2/src/service/ipc.rs index d574686a20..e83cb9551d 100644 --- a/iceoryx2/src/service/ipc.rs +++ b/iceoryx2/src/service/ipc.rs @@ -48,6 +48,7 @@ impl crate::service::Service for Service { type ConfigSerializer = serialize::recommended::Recommended; type PersistentDynamicStorage = dynamic_storage::recommended::PersistentIpc; + type Bag = bag::recommended::Recommended; type DynamicStorage = dynamic_storage::recommended::Ipc; type ServiceNameHasher = hash::recommended::Recommended; diff --git a/iceoryx2/src/service/ipc_threadsafe.rs b/iceoryx2/src/service/ipc_threadsafe.rs index 38d9855051..18b676a19f 100644 --- a/iceoryx2/src/service/ipc_threadsafe.rs +++ b/iceoryx2/src/service/ipc_threadsafe.rs @@ -49,6 +49,7 @@ impl crate::service::Service for Service { type ConfigSerializer = serialize::recommended::Recommended; type PersistentDynamicStorage = dynamic_storage::recommended::PersistentIpc; + type Bag = bag::recommended::Recommended; type DynamicStorage = dynamic_storage::recommended::Ipc; type ServiceNameHasher = hash::recommended::Recommended; diff --git a/iceoryx2/src/service/local.rs b/iceoryx2/src/service/local.rs index 6c5f1b9850..7e7e456b6e 100644 --- a/iceoryx2/src/service/local.rs +++ b/iceoryx2/src/service/local.rs @@ -49,6 +49,7 @@ impl crate::service::Service for Service { type ConfigSerializer = serialize::recommended::Recommended; type PersistentDynamicStorage = dynamic_storage::recommended::PersistentLocal; + type Bag = bag::recommended::Recommended; type DynamicStorage = dynamic_storage::recommended::Local; type ServiceNameHasher = hash::recommended::Recommended; diff --git a/iceoryx2/src/service/local_threadsafe.rs b/iceoryx2/src/service/local_threadsafe.rs index dfed2944d4..c15a337305 100644 --- a/iceoryx2/src/service/local_threadsafe.rs +++ b/iceoryx2/src/service/local_threadsafe.rs @@ -49,6 +49,7 @@ impl crate::service::Service for Service { type ConfigSerializer = serialize::recommended::Recommended; type PersistentDynamicStorage = dynamic_storage::recommended::PersistentLocal; + type Bag = bag::recommended::Recommended; type DynamicStorage = dynamic_storage::recommended::Local; type ServiceNameHasher = hash::recommended::Recommended; diff --git a/iceoryx2/src/service/mod.rs b/iceoryx2/src/service/mod.rs index d394d7963d..07bab05d88 100644 --- a/iceoryx2/src/service/mod.rs +++ b/iceoryx2/src/service/mod.rs @@ -299,6 +299,7 @@ use builder::event::EventOpenError; use dynamic_config::PortCleanupAction; use iceoryx2_bb_elementary::CallbackProgression; use iceoryx2_cal::arc_sync_policy::ArcSyncPolicy; +use iceoryx2_cal::bag::BagFamily; use iceoryx2_cal::dynamic_storage::{ DynamicStorage, DynamicStorageBuilder, DynamicStorageOpenError, }; @@ -450,7 +451,7 @@ pub struct ServiceDetails { /// Represents the [`Service`]s state. #[derive(Debug)] pub struct ServiceState { - pub(crate) dynamic_storage: S::DynamicStorage, + pub(crate) dynamic_storage: S::DynamicStorage>, pub(crate) additional_resource: R, pub(crate) static_config: StaticConfig, pub(crate) shared_node: SharedNode, @@ -502,7 +503,7 @@ impl SharedServiceState { &self.state.static_config } - pub(crate) fn dynamic_storage(&self) -> &S::DynamicStorage { + pub(crate) fn dynamic_storage(&self) -> &S::DynamicStorage> { &self.state.dynamic_storage } @@ -519,7 +520,7 @@ impl ServiceState { pub(crate) fn new( static_config: StaticConfig, shared_node: SharedNode, - dynamic_storage: S::DynamicStorage, + dynamic_storage: S::DynamicStorage>, static_storage: S::StaticStorage, additional_resource: R, ) -> Self { @@ -729,7 +730,7 @@ pub mod internal { let segment_name = dynamic_config_name(unique_service_id); match unsafe { - as NamedConceptMgmt>::remove_cfg( + > as NamedConceptMgmt>::remove_cfg( &segment_name, &dynamic_config_storage_config::(config), ) @@ -951,6 +952,9 @@ pub trait Service: Debug + Sized + internal::ServiceInternal + Clone + Sen T, >; + /// Defines the construct containing unordered data at fixed positions use to track resource ownership + type Bag: BagFamily; + /// Defines the construct used to store the [`Service`]s dynamic configuration. This /// contains for instance all endpoints and other dynamic details. type DynamicStorage: DynamicStorage; @@ -1213,10 +1217,11 @@ fn read_static_service_config( Ok(Some(service_config)) } +type DynanmicConfigStorage = ::DynamicStorage::Bag>>; fn open_dynamic_config( config: &config::Config, service_id: UniqueServiceId, -) -> Result>, ServiceDetailsError> { +) -> Result>, ServiceDetailsError> { let origin = format!( "Service::open_dynamic_details<{}>({:?})", core::any::type_name::(), @@ -1225,10 +1230,10 @@ fn open_dynamic_config( let msg = "Unable to open the services dynamic config"; let segment_name = dynamic_config_name(service_id); match - < as DynamicStorage< - DynamicConfig, + < as DynamicStorage< + DynamicConfig, >>::Builder<'_> as NamedConceptBuilder< - S::DynamicStorage, + DynanmicConfigStorage, >>::new(&segment_name) .config(&dynamic_config_storage_config::(config)) .has_ownership(false) diff --git a/iceoryx2/src/service/port_factory/blackboard.rs b/iceoryx2/src/service/port_factory/blackboard.rs index ab6426ee22..de595dd713 100644 --- a/iceoryx2/src/service/port_factory/blackboard.rs +++ b/iceoryx2/src/service/port_factory/blackboard.rs @@ -91,7 +91,7 @@ impl< { type Service = Service; type StaticConfig = static_config::blackboard::StaticConfig; - type DynamicConfig = dynamic_config::blackboard::DynamicConfig; + type DynamicConfig = dynamic_config::blackboard::DynamicConfig; fn name(&self) -> &ServiceName { self.service.static_config().name() @@ -113,7 +113,7 @@ impl< self.service.static_config().blackboard() } - fn dynamic_config(&self) -> &dynamic_config::blackboard::DynamicConfig { + fn dynamic_config(&self) -> &dynamic_config::blackboard::DynamicConfig { self.service.dynamic_storage().get().blackboard() } diff --git a/iceoryx2/src/service/port_factory/event.rs b/iceoryx2/src/service/port_factory/event.rs index 7d31bc9a4c..85e9c006b1 100644 --- a/iceoryx2/src/service/port_factory/event.rs +++ b/iceoryx2/src/service/port_factory/event.rs @@ -75,7 +75,7 @@ impl Abandonable for PortFactory { impl crate::service::port_factory::PortFactory for PortFactory { type Service = Service; type StaticConfig = static_config::event::StaticConfig; - type DynamicConfig = dynamic_config::event::DynamicConfig; + type DynamicConfig = dynamic_config::event::DynamicConfig; fn name(&self) -> &ServiceName { self.service.static_config().name() @@ -97,7 +97,7 @@ impl crate::service::port_factory::PortFactory for Po self.service.static_config().event() } - fn dynamic_config(&self) -> &dynamic_config::event::DynamicConfig { + fn dynamic_config(&self) -> &dynamic_config::event::DynamicConfig { self.service.dynamic_storage().get().event() } diff --git a/iceoryx2/src/service/port_factory/mod.rs b/iceoryx2/src/service/port_factory/mod.rs index ce83f88501..9ffafb111c 100644 --- a/iceoryx2/src/service/port_factory/mod.rs +++ b/iceoryx2/src/service/port_factory/mod.rs @@ -169,7 +169,7 @@ pub(crate) fn nodes< Service: crate::service::Service, F: FnMut(NodeState) -> CallbackProgression, >( - dynamic_config: &DynamicConfig, + dynamic_config: &DynamicConfig, config: &Config, mut callback: F, ) -> Result<(), NodeListFailure> { diff --git a/iceoryx2/src/service/port_factory/publish_subscribe.rs b/iceoryx2/src/service/port_factory/publish_subscribe.rs index c699227224..732a638edd 100644 --- a/iceoryx2/src/service/port_factory/publish_subscribe.rs +++ b/iceoryx2/src/service/port_factory/publish_subscribe.rs @@ -111,7 +111,7 @@ impl< { type Service = Service; type StaticConfig = static_config::publish_subscribe::StaticConfig; - type DynamicConfig = dynamic_config::publish_subscribe::DynamicConfig; + type DynamicConfig = dynamic_config::publish_subscribe::DynamicConfig; fn name(&self) -> &ServiceName { self.service.static_config().name() @@ -133,7 +133,7 @@ impl< self.service.static_config().publish_subscribe() } - fn dynamic_config(&self) -> &dynamic_config::publish_subscribe::DynamicConfig { + fn dynamic_config(&self) -> &dynamic_config::publish_subscribe::DynamicConfig { self.service.dynamic_storage().get().publish_subscribe() } diff --git a/iceoryx2/src/service/port_factory/request_response.rs b/iceoryx2/src/service/port_factory/request_response.rs index 331db1fc04..9c9a5fad75 100644 --- a/iceoryx2/src/service/port_factory/request_response.rs +++ b/iceoryx2/src/service/port_factory/request_response.rs @@ -144,7 +144,7 @@ impl< { type Service = Service; type StaticConfig = static_config::request_response::StaticConfig; - type DynamicConfig = dynamic_config::request_response::DynamicConfig; + type DynamicConfig = dynamic_config::request_response::DynamicConfig; fn name(&self) -> &ServiceName { self.service.static_config().name() diff --git a/iceoryx2/src/testing.rs b/iceoryx2/src/testing.rs index e8cf856dec..1f3a9b78c5 100644 --- a/iceoryx2/src/testing.rs +++ b/iceoryx2/src/testing.rs @@ -206,7 +206,10 @@ pub unsafe fn remove_dynamic_config( let dyn_conf = dynamic_config_storage_config::(config); unsafe { - as NamedConceptMgmt>::remove_cfg(&segment_name, &dyn_conf) - .unwrap() + > as NamedConceptMgmt>::remove_cfg( + &segment_name, + &dyn_conf, + ) + .unwrap() }; }