Skip to content

Commit

Permalink
Merge pull request eclipse-iceoryx#499 from elfenpiff/iox2-498-cleanu…
Browse files Browse the repository at this point in the history
…p-message-type-details

[eclipse-iceoryx#498] cleanup message type details
  • Loading branch information
elfenpiff authored Nov 6, 2024
2 parents 29c71af + 6deb81b commit e7d1f59
Show file tree
Hide file tree
Showing 16 changed files with 330 additions and 102 deletions.
3 changes: 3 additions & 0 deletions doc/release-notes/iceoryx2-unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
* Rename `NodeEvent` into `WaitEvent` [#390](https://github.com/eclipse-iceoryx/iceoryx2/issues/390)
* Bazel support for the Rust crates [#349](https://github.com/eclipse-iceoryx/iceoryx2/issues/349)
* Remove ACL dependency [#457](https://github.com/eclipse-iceoryx/iceoryx2/issues/457)
* Publish Subscribe Header contains number of elements contained in a `Sample` [#498](https://github.com/eclipse-iceoryx/iceoryx2/issues/498)

### Workflow

Expand Down Expand Up @@ -72,3 +73,5 @@
// ...
}
```

2. Removed `payload_type_layout()` from `publish_subscribe::Header`.
1 change: 0 additions & 1 deletion iceoryx2-bb/posix/tests/unix_datagram_socket_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use iceoryx2_bb_container::semantic_string::SemanticString;
use iceoryx2_bb_posix::barrier::*;
use iceoryx2_bb_posix::config::*;
use iceoryx2_bb_posix::creation_mode::*;
use iceoryx2_bb_posix::directory::Directory;
use iceoryx2_bb_posix::file::*;
use iceoryx2_bb_posix::file_descriptor::*;
use iceoryx2_bb_posix::socket_ancillary::*;
Expand Down
4 changes: 2 additions & 2 deletions iceoryx2-ffi/cxx/include/iox2/header_publish_subscribe.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ class HeaderPublishSubscribe {
/// Returns the [`UniquePublisherId`] of the source [`Publisher`].
auto publisher_id() const -> UniquePublisherId;

/// Returns the [`Layout`] of the corresponding payload.
auto payload_type_layout() const -> iox::Layout;
/// Returns the number of [`Payload`] elements in the received [`Sample`].
auto number_of_elements() const -> uint64_t;

private:
template <ServiceType, typename, typename>
Expand Down
7 changes: 2 additions & 5 deletions iceoryx2-ffi/cxx/src/header_publish_subscribe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,7 @@ auto HeaderPublishSubscribe::publisher_id() const -> UniquePublisherId {
return UniquePublisherId { id_handle };
}

auto HeaderPublishSubscribe::payload_type_layout() const -> iox::Layout {
auto size = iox2_publish_subscribe_header_payload_type_size(&m_handle);
auto alignment = iox2_publish_subscribe_header_payload_type_alignment(&m_handle);

return iox::Layout::create(size, alignment).expect("Payload layout is always valid.");
auto HeaderPublishSubscribe::number_of_elements() const -> uint64_t {
return iox2_publish_subscribe_header_number_of_elements(&m_handle);
}
} // namespace iox2
35 changes: 9 additions & 26 deletions iceoryx2-ffi/ffi/src/api/publish_subscribe_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,12 @@ pub unsafe extern "C" fn iox2_publish_subscribe_header_publisher_id(
*id_handle_ptr = (*storage_ptr).as_handle();
}

/// Returns the payloads type size.
/// Returns the number of elements of the payload.
/// The element size is defined via this call when creating a new service
/// [`crate::iox2_service_builder_pub_sub_set_payload_type_details()`].
/// So if the payload is defined with alignment 8 and size 16 and this function returns 5. It
/// means that the payload consists of 5 elements of size 16 and every element is 8 byte aligned.
/// Therefore, the payload pointer points to a memory region with 5 * 16 = 80 bytes.
///
/// # Arguments
///
Expand All @@ -165,35 +170,13 @@ pub unsafe extern "C" fn iox2_publish_subscribe_header_publisher_id(
///
/// * `header_handle` is valid and non-null
#[no_mangle]
pub unsafe extern "C" fn iox2_publish_subscribe_header_payload_type_size(
pub unsafe extern "C" fn iox2_publish_subscribe_header_number_of_elements(
header_handle: iox2_publish_subscribe_header_h_ref,
) -> usize {
) -> u64 {
header_handle.assert_non_null();

let header = &mut *header_handle.as_type();

header.value.as_ref().payload_type_layout().size()
header.value.as_ref().number_of_elements()
}

/// Returns the payloads type alignment.
///
/// # Arguments
///
/// * `handle` is valid, non-null and was initialized with
/// [`iox2_sample_header()`](crate::iox2_sample_header)
///
/// # Safety
///
/// * `header_handle` is valid and non-null
#[no_mangle]
pub unsafe extern "C" fn iox2_publish_subscribe_header_payload_type_alignment(
header_handle: iox2_publish_subscribe_header_h_ref,
) -> usize {
header_handle.assert_non_null();

let header = &mut *header_handle.as_type();

header.value.as_ref().payload_type_layout().align()
}

// END C API
6 changes: 3 additions & 3 deletions iceoryx2-ffi/ffi/src/api/publisher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ unsafe fn send_copy<S: Service>(
// loan_slice_uninit(1) <= 1 is correct here since it defines the number of
// slice elements not bytes. The element was set via TypeDetails and has a
// defined size and alignment.
let mut sample = match publisher.loan_slice_uninit(1) {
let mut sample = match publisher.loan_custom_payload(1) {
Ok(sample) => sample,
Err(e) => return e.into_c_int(),
};
Expand Down Expand Up @@ -383,7 +383,7 @@ pub unsafe extern "C" fn iox2_publisher_loan(
let publisher = &mut *publisher_handle.as_type();

match publisher.service_type {
iox2_service_type_e::IPC => match publisher.value.as_ref().ipc.loan_slice_uninit(1) {
iox2_service_type_e::IPC => match publisher.value.as_ref().ipc.loan_custom_payload(1) {
Ok(sample) => {
let (sample_struct_ptr, deleter) = init_sample_struct_ptr(sample_struct_ptr);
(*sample_struct_ptr).init(
Expand All @@ -396,7 +396,7 @@ pub unsafe extern "C" fn iox2_publisher_loan(
}
Err(error) => error.into_c_int(),
},
iox2_service_type_e::LOCAL => match publisher.value.as_ref().local.loan_slice_uninit(1) {
iox2_service_type_e::LOCAL => match publisher.value.as_ref().local.loan_custom_payload(1) {
Ok(sample) => {
let (sample_struct_ptr, deleter) = init_sample_struct_ptr(sample_struct_ptr);
(*sample_struct_ptr).init(
Expand Down
6 changes: 3 additions & 3 deletions iceoryx2-ffi/ffi/src/api/service_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use crate::api::{iox2_service_type_e, AssertNonNullHandle, HandleToType};

use iceoryx2::prelude::*;
use iceoryx2::service::builder::publish_subscribe::CustomHeaderMarker;
use iceoryx2::service::builder::publish_subscribe::{CustomHeaderMarker, CustomPayloadMarker};
use iceoryx2::service::builder::{
event::Builder as ServiceBuilderEvent, publish_subscribe::Builder as ServiceBuilderPubSub,
Builder as ServiceBuilderBase,
Expand All @@ -29,8 +29,8 @@ use core::mem::MaybeUninit;
// BEGIN types definition

pub(super) type UserHeaderFfi = CustomHeaderMarker;
pub(super) type PayloadFfi = [u8];
pub(super) type UninitPayloadFfi = [MaybeUninit<u8>];
pub(super) type PayloadFfi = [CustomPayloadMarker];
pub(super) type UninitPayloadFfi = [MaybeUninit<CustomPayloadMarker>];

pub(super) union ServiceBuilderUnionNested<S: Service> {
pub(super) base: ManuallyDrop<ServiceBuilderBase<S>>,
Expand Down
28 changes: 15 additions & 13 deletions iceoryx2-ffi/ffi/src/api/subscriber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ pub unsafe extern "C" fn iox2_subscriber_receive(
let subscriber = &mut *subscriber_handle.as_type();

match subscriber.service_type {
iox2_service_type_e::IPC => match subscriber.value.as_ref().ipc.receive() {
iox2_service_type_e::IPC => match subscriber.value.as_ref().ipc.receive_custom_payload() {
Ok(Some(sample)) => {
let (sample_struct_ptr, deleter) = init_sample_struct_ptr(sample_struct_ptr);
(*sample_struct_ptr).init(
Expand All @@ -286,19 +286,21 @@ pub unsafe extern "C" fn iox2_subscriber_receive(
Ok(None) => (),
Err(error) => return error.into_c_int(),
},
iox2_service_type_e::LOCAL => match subscriber.value.as_ref().local.receive() {
Ok(Some(sample)) => {
let (sample_struct_ptr, deleter) = init_sample_struct_ptr(sample_struct_ptr);
(*sample_struct_ptr).init(
subscriber.service_type,
SampleUnion::new_local(sample),
deleter,
);
*sample_handle_ptr = (*sample_struct_ptr).as_handle();
iox2_service_type_e::LOCAL => {
match subscriber.value.as_ref().local.receive_custom_payload() {
Ok(Some(sample)) => {
let (sample_struct_ptr, deleter) = init_sample_struct_ptr(sample_struct_ptr);
(*sample_struct_ptr).init(
subscriber.service_type,
SampleUnion::new_local(sample),
deleter,
);
*sample_handle_ptr = (*sample_struct_ptr).as_handle();
}
Ok(None) => (),
Err(error) => return error.into_c_int(),
}
Ok(None) => (),
Err(error) => return error.into_c_int(),
},
}
}

IOX2_OK
Expand Down
83 changes: 56 additions & 27 deletions iceoryx2/src/port/publisher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,15 @@ use crate::port::update_connections::{ConnectionFailure, UpdateConnections};
use crate::port::DegrationAction;
use crate::raw_sample::RawSampleMut;
use crate::sample_mut_uninit::SampleMutUninit;
use crate::service::builder::publish_subscribe::CustomPayloadMarker;
use crate::service::config_scheme::{connection_config, data_segment_config};
use crate::service::dynamic_config::publish_subscribe::{PublisherDetails, SubscriberDetails};
use crate::service::header::publish_subscribe::Header;
use crate::service::naming_scheme::{
data_segment_name, extract_publisher_id_from_connection, extract_subscriber_id_from_connection,
};
use crate::service::port_factory::publisher::{LocalPublisherConfig, UnableToDeliverStrategy};
use crate::service::static_config::message_type_details::TypeVariant;
use crate::service::static_config::publish_subscribe::{self};
use crate::service::{self, ServiceState};
use crate::{config, sample_mut::SampleMut};
Expand All @@ -138,6 +140,7 @@ use iceoryx2_cal::zero_copy_connection::{
ZeroCopyConnection, ZeroCopyCreationError, ZeroCopySendError, ZeroCopySender,
};
use iceoryx2_pal_concurrency_sync::iox_atomic::{IoxAtomicBool, IoxAtomicU64, IoxAtomicUsize};
use std::any::TypeId;
use std::cell::UnsafeCell;
use std::fmt::Debug;
use std::sync::atomic::Ordering;
Expand Down Expand Up @@ -528,7 +531,11 @@ impl<Service: service::Service> DataSegment<Service> {

/// Sending endpoint of a publish-subscriber based communication.
#[derive(Debug)]
pub struct Publisher<Service: service::Service, Payload: Debug + ?Sized, UserHeader: Debug> {
pub struct Publisher<
Service: service::Service,
Payload: Debug + ?Sized + 'static,
UserHeader: Debug,
> {
pub(crate) data_segment: Arc<DataSegment<Service>>,
dynamic_publisher_handle: Option<ContainerHandle>,
payload_size: usize,
Expand Down Expand Up @@ -738,30 +745,31 @@ impl<Service: service::Service, Payload: Debug + ?Sized, UserHeader: Debug>
.sample_layout(number_of_elements)
}

fn payload_layout(&self, number_of_elements: usize) -> Layout {
fn user_header_ptr(&self, header: *const Header) -> *const u8 {
self.data_segment
.subscriber_connections
.static_config
.message_type_details
.payload_layout(number_of_elements)
.user_header_ptr_from_header(header.cast())
.cast()
}

fn user_header_ptr(&self, header: *const Header) -> *const u8 {
fn payload_ptr(&self, header: *const Header) -> *const u8 {
self.data_segment
.subscriber_connections
.static_config
.message_type_details
.user_header_ptr_from_header(header.cast())
.payload_ptr_from_header(header.cast())
.cast()
}

fn payload_ptr(&self, header: *const Header) -> *const u8 {
fn payload_type_variant(&self) -> TypeVariant {
self.data_segment
.subscriber_connections
.static_config
.message_type_details
.payload_ptr_from_header(header.cast())
.cast()
.payload
.variant
}
}

Expand Down Expand Up @@ -837,12 +845,7 @@ impl<Service: service::Service, Payload: Debug + Sized, UserHeader: Debug>
let user_header_ptr = self.user_header_ptr(header_ptr) as *mut UserHeader;
let payload_ptr = self.payload_ptr(header_ptr) as *mut MaybeUninit<Payload>;

unsafe {
header_ptr.write(Header::new(
self.data_segment.port_id,
Layout::new::<Payload>(),
))
};
unsafe { header_ptr.write(Header::new(self.data_segment.port_id, 1)) };

let sample =
unsafe { RawSampleMut::new_unchecked(header_ptr, user_header_ptr, payload_ptr) };
Expand Down Expand Up @@ -974,6 +977,18 @@ impl<Service: service::Service, Payload: Debug, UserHeader: Debug>
&self,
slice_len: usize,
) -> Result<SampleMutUninit<Service, [MaybeUninit<Payload>], UserHeader>, PublisherLoanError>
{
// required since Rust does not support generic specializations or negative traits
debug_assert!(TypeId::of::<Payload>() != TypeId::of::<CustomPayloadMarker>());

unsafe { self.loan_slice_uninit_impl(slice_len, slice_len) }
}

unsafe fn loan_slice_uninit_impl(
&self,
slice_len: usize,
underlying_number_of_slice_elements: usize,
) -> Result<SampleMutUninit<Service, [MaybeUninit<Payload>], UserHeader>, PublisherLoanError>
{
let max_slice_len = self.data_segment.config.max_slice_len;
if max_slice_len < slice_len {
Expand All @@ -988,24 +1003,13 @@ impl<Service: service::Service, Payload: Debug, UserHeader: Debug>
let user_header_ptr = self.user_header_ptr(header_ptr) as *mut UserHeader;
let payload_ptr = self.payload_ptr(header_ptr) as *mut MaybeUninit<Payload>;

unsafe {
header_ptr.write(Header::new(
self.data_segment.port_id,
self.payload_layout(slice_len),
))
};

let slice_len_adjusted_to_payload_type_details =
self.payload_size * slice_len / core::mem::size_of::<Payload>();
unsafe { header_ptr.write(Header::new(self.data_segment.port_id, slice_len as _)) };

let sample = unsafe {
RawSampleMut::new_unchecked(
header_ptr,
user_header_ptr,
core::slice::from_raw_parts_mut(
payload_ptr,
slice_len_adjusted_to_payload_type_details,
),
core::slice::from_raw_parts_mut(payload_ptr, underlying_number_of_slice_elements),
)
};

Expand All @@ -1018,6 +1022,31 @@ impl<Service: service::Service, Payload: Debug, UserHeader: Debug>
)
}
}

impl<Service: service::Service, UserHeader: Debug>
Publisher<Service, [CustomPayloadMarker], UserHeader>
{
/// # Safety
///
/// * slice_len != 1 only when payload TypeVariant == Dynamic
/// * The number_of_elements in the [`Header`](crate::service::header::publish_subscribe::Header)
/// is set to `slice_len`
/// * The [`SampleMutUninit`] will contain `slice_len` * `MessageTypeDetails::payload.size`
/// elements of type [`CustomPayloadMarker`].
#[doc(hidden)]
pub unsafe fn loan_custom_payload(
&self,
slice_len: usize,
) -> Result<
SampleMutUninit<Service, [MaybeUninit<CustomPayloadMarker>], UserHeader>,
PublisherLoanError,
> {
// TypeVariant::Dynamic == slice and only here it makes sense to loan more than one element
debug_assert!(slice_len == 1 || self.payload_type_variant() == TypeVariant::Dynamic);

self.loan_slice_uninit_impl(slice_len, self.payload_size * slice_len)
}
}
////////////////////////
// END: sliced API
////////////////////////
Expand Down
Loading

0 comments on commit e7d1f59

Please sign in to comment.