diff --git a/iceoryx2/src/port/details/publisher_connections.rs b/iceoryx2/src/port/details/publisher_connections.rs index a427be3ec..17e1c8a0d 100644 --- a/iceoryx2/src/port/details/publisher_connections.rs +++ b/iceoryx2/src/port/details/publisher_connections.rs @@ -59,7 +59,7 @@ impl Connection { .receiver_max_borrowed_samples(this.static_config.subscriber_max_borrowed_samples) .enable_safe_overflow(this.static_config.enable_safe_overflow) .number_of_samples(number_of_samples) - .create_receiver(this.static_config.type_size), + .create_receiver(this.static_config.type_details().layout().size()), "{} since the zero copy connection could not be established.", msg); let data_segment = fail!(from this, diff --git a/iceoryx2/src/port/details/subscriber_connections.rs b/iceoryx2/src/port/details/subscriber_connections.rs index 5d4c9966e..d1f24e8c2 100644 --- a/iceoryx2/src/port/details/subscriber_connections.rs +++ b/iceoryx2/src/port/details/subscriber_connections.rs @@ -57,7 +57,7 @@ impl Connection { .receiver_max_borrowed_samples(this.static_config.subscriber_max_borrowed_samples) .enable_safe_overflow(this.static_config.enable_safe_overflow) .number_of_samples(number_of_samples) - .create_sender(this.static_config.type_size), + .create_sender(this.static_config.type_details().layout().size()), "{}.", msg); Ok(Self { diff --git a/iceoryx2/src/port/publisher.rs b/iceoryx2/src/port/publisher.rs index 0c1cf6503..bec795d56 100644 --- a/iceoryx2/src/port/publisher.rs +++ b/iceoryx2/src/port/publisher.rs @@ -552,24 +552,15 @@ impl Publisher Result { - let allocator_config = shm_allocator::pool_allocator::Config { - bucket_layout: - // # SAFETY: type_size and type_alignment are acquired via - // core::mem::{size_of|align_of} - unsafe { - Layout::from_size_align_unchecked( - static_config.type_size, - static_config.type_alignment, - ) - }, - }; + let l = static_config.type_details.layout(); + let allocator_config = shm_allocator::pool_allocator::Config { bucket_layout: l }; Ok(fail!(from "Publisher::create_data_segment()", when <>::Builder as NamedConceptBuilder< Service::SharedMemory, >>::new(&data_segment_name(port_id)) .config(&data_segment_config::(global_config)) - .size(static_config.type_size * number_of_samples + static_config.type_alignment - 1) + .size(l.size() * number_of_samples + l.align() - 1) .create(&allocator_config), "Unable to create the data segment.")) } diff --git a/iceoryx2/src/service/builder/publish_subscribe.rs b/iceoryx2/src/service/builder/publish_subscribe.rs index 5bab3f6bb..477c1987c 100644 --- a/iceoryx2/src/service/builder/publish_subscribe.rs +++ b/iceoryx2/src/service/builder/publish_subscribe.rs @@ -16,7 +16,6 @@ //! use std::marker::PhantomData; -use crate::message::Message; use crate::service; use crate::service::dynamic_config::publish_subscribe::DynamicConfigSettings; use crate::service::header::publish_subscribe::Header; @@ -30,6 +29,8 @@ use iceoryx2_cal::dynamic_storage::DynamicStorageCreateError; use iceoryx2_cal::serialize::Serialize; use iceoryx2_cal::static_storage::StaticStorageLocked; +use self::static_config::publish_subscribe::TypeDetails; + use super::ServiceState; /// Errors that can occur when an existing [`MessagingPattern::PublishSubscribe`] [`Service`] shall be opened. @@ -165,10 +166,10 @@ impl Builder { ) -> Result, ServiceAvailabilityState> { match self.base.is_service_available() { Ok(Some((config, storage))) => { - if config.publish_subscribe().type_name != self.config_details().type_name { + if config.publish_subscribe().type_details != self.config_details().type_details { fail!(from self, with ServiceAvailabilityState::IncompatibleTypes, - "{} since the service offers the type \"{}\" but the requested type is \"{}\".", - error_msg, &config.publish_subscribe().type_name , self.config_details().type_name); + "{} since the service offers the type \"{:?}\" but the requested type is \"{:?}\".", + error_msg, &config.publish_subscribe().type_details , self.config_details().type_details); } Ok(Some((config, storage))) @@ -178,13 +179,6 @@ impl Builder { } } - fn finalize_config(&mut self) { - self.config_details_mut().type_name = std::any::type_name::().to_string(); - self.config_details_mut().type_size = core::mem::size_of::>(); - self.config_details_mut().type_alignment = - core::mem::align_of::>(); - } - /// If the [`Service`] is created, defines the overflow behavior of the service. If an existing /// [`Service`] is opened it requires the service to have the defined overflow behavior. pub fn enable_safe_overflow(mut self, value: bool) -> Self { @@ -359,7 +353,8 @@ impl TypedBuilder { let msg = "Unable to open or create publish subscribe service"; - self.builder.finalize_config::(); + self.builder.config_details_mut().type_details = + TypeDetails::from_type::(); match self.builder.is_service_available(msg) { Ok(Some(_)) => Ok(self.open()?), @@ -401,7 +396,8 @@ impl TypedBuilder Result, PublishSubscribeOpenError> { let msg = "Unable to open publish subscribe service"; - self.builder.finalize_config::(); + self.builder.config_details_mut().type_details = + TypeDetails::from_type::(); let mut adaptive_wait = fail!(from self, when AdaptiveWaitBuilder::new().create(), with PublishSubscribeOpenError::InternalFailure, @@ -484,7 +480,8 @@ impl TypedBuilder(); + self.builder.config_details_mut().type_details = + TypeDetails::from_type::(); if !self.builder.config_details().enable_safe_overflow && (self.builder.config_details().subscriber_max_buffer_size diff --git a/iceoryx2/src/service/static_config/publish_subscribe.rs b/iceoryx2/src/service/static_config/publish_subscribe.rs index 6ee3d8f7d..85c479001 100644 --- a/iceoryx2/src/service/static_config/publish_subscribe.rs +++ b/iceoryx2/src/service/static_config/publish_subscribe.rs @@ -34,7 +34,9 @@ //! # } //! ``` -use crate::config; +use std::alloc::Layout; + +use crate::{config, message::Message}; use serde::{Deserialize, Serialize}; /// The static configuration of an @@ -49,9 +51,40 @@ pub struct StaticConfig { pub(crate) subscriber_max_buffer_size: usize, pub(crate) subscriber_max_borrowed_samples: usize, pub(crate) enable_safe_overflow: bool, - pub(crate) type_name: String, - pub(crate) type_size: usize, - pub(crate) type_alignment: usize, + pub(crate) type_details: TypeDetails, +} + +#[derive(Debug, Clone, Eq, Hash, PartialEq, Serialize, Deserialize)] +pub struct Typed { + pub type_name: String, + pub type_size: usize, + pub type_alignment: usize, +} + +#[derive(Debug, Clone, Eq, Hash, PartialEq, Serialize, Deserialize)] +#[serde(untagged)] +pub enum TypeDetails { + Typed { typed: Typed }, +} + +impl TypeDetails { + pub fn from_type() -> Self { + Self::Typed { + typed: Typed { + type_name: core::any::type_name::().to_string(), + type_size: core::mem::size_of::>(), + type_alignment: core::mem::align_of::>(), + }, + } + } + + pub fn layout(&self) -> Layout { + match self { + Self::Typed { typed: d } => unsafe { + Layout::from_size_align_unchecked(d.type_size, d.type_alignment) + }, + } + } } impl StaticConfig { @@ -69,9 +102,13 @@ impl StaticConfig { .publish_subscribe .subscriber_max_borrowed_samples, enable_safe_overflow: config.defaults.publish_subscribe.enable_safe_overflow, - type_name: String::new(), - type_size: 0, - type_alignment: 0, + type_details: TypeDetails::Typed { + typed: Typed { + type_name: String::new(), + type_size: 0, + type_alignment: 0, + }, + }, } } @@ -109,16 +146,8 @@ impl StaticConfig { self.enable_safe_overflow } - /// Returns the type name of the [`crate::service::Service`]. - pub fn type_name(&self) -> &str { - &self.type_name - } - - pub fn type_size(&self) -> usize { - self.type_size - } - - pub fn type_alignment(&self) -> usize { - self.type_alignment + /// Returns the type details of the [`crate::service::Service`]. + pub fn type_details(&self) -> &TypeDetails { + &self.type_details } } diff --git a/iceoryx2/tests/service_publish_subscribe_tests.rs b/iceoryx2/tests/service_publish_subscribe_tests.rs index af12c4110..e2901be59 100644 --- a/iceoryx2/tests/service_publish_subscribe_tests.rs +++ b/iceoryx2/tests/service_publish_subscribe_tests.rs @@ -25,6 +25,7 @@ mod service_publish_subscribe { use iceoryx2::service::builder::publish_subscribe::PublishSubscribeCreateError; use iceoryx2::service::builder::publish_subscribe::PublishSubscribeOpenError; use iceoryx2::service::port_factory::publisher::UnableToDeliverStrategy; + use iceoryx2::service::static_config::publish_subscribe::TypeDetails; use iceoryx2::service::static_config::StaticConfig; use iceoryx2::service::Service; use iceoryx2_bb_posix::unique_system_id::UniqueSystemId; @@ -499,9 +500,13 @@ mod service_publish_subscribe { type MessageType = Message; - assert_that!(sut.static_config().type_name(), eq "u64"); - assert_that!(sut.static_config().type_size(), eq std::mem::size_of::()); - assert_that!(sut.static_config().type_alignment(), eq std::mem::align_of::()); + if let TypeDetails::Typed { typed: d } = sut.static_config().type_details() { + assert_that!(d.type_name, eq "u64"); + assert_that!(d.type_size, eq std::mem::size_of::()); + assert_that!(d.type_alignment, eq std::mem::align_of::()); + } else { + assert_that!(true, eq false); + } } #[test]