Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 9 additions & 15 deletions src/feo-com/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -17,53 +17,47 @@ rust_library(
name = "libfeo_com_rust_mw_com",
srcs = [
"src/interface.rs",
# Disabled due to compilation error of iceoryx2
# "src/iox2/mod.rs",
"src/iox2/mod.rs",
"src/lib.rs",
"src/linux_shm/mod.rs",
"src/linux_shm/shared_memory.rs",
"src/mw_com/mod.rs",
],
crate_features = [
# Disabled due to compilation error of iceoryx2
# "ipc_iceoryx2",
"ipc_iceoryx2",
"ipc_linux_shm",
"ipc_mw_com",
],
crate_name = "feo_com",
visibility = ["//visibility:public"],
deps = [
# Disabled due to compilation error of iceoryx2
# "@score_crates//:iceoryx2",
"@score_crates//:nix",
"@score_crates//:rand",
"@score_baselibs_rust//src/log/score_log",
"@score_communication//score/mw/com/impl/rust/com-api/com-api",
"@score_crates//:iceoryx2",
"@score_crates//:nix",
"@score_crates//:rand",
],
)

rust_library(
name = "libfeo_com_rust",
srcs = [
"src/interface.rs",
# Disabled due to compilation error of iceoryx2
# "src/iox2/mod.rs",
"src/iox2/mod.rs",
"src/lib.rs",
"src/linux_shm/mod.rs",
"src/linux_shm/shared_memory.rs",
],
crate_features = [
# Disabled due to compilation error of iceoryx2
# "ipc_iceoryx2",
"ipc_iceoryx2",
"ipc_linux_shm",
],
crate_name = "feo_com",
visibility = ["//visibility:public"],
deps = [
# Disabled due to compilation error of iceoryx2
# "@score_crates//:iceoryx2",
"@score_baselibs_rust//src/log/score_log",
"@score_crates//:iceoryx2",
"@score_crates//:nix",
"@score_crates//:rand",
"@score_baselibs_rust//src/log/score_log",
],
)
76 changes: 50 additions & 26 deletions src/feo-com/src/iox2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@

//! iceoryx2 com backend

use crate::interface::FeoComData;
use crate::interface::FeoComDefault;
use crate::interface::{
ActivityInput, ActivityOutput, ActivityOutputDefault, Error, InputGuard, OutputGuard, OutputUninitGuard, Topic,
TopicHandle,
};
use alloc::boxed::Box;
use alloc::format;
use core::fmt;
use core::mem::MaybeUninit;
use core::ops::{Deref, DerefMut};
use feo_log::{error, info};
use iceoryx2::config::Config;
use iceoryx2::node::{Node, NodeBuilder, NodeState};
use iceoryx2::port::publisher::Publisher;
Expand All @@ -32,11 +32,15 @@ use iceoryx2::sample::Sample;
use iceoryx2::sample_mut::SampleMut;
use iceoryx2::sample_mut_uninit::SampleMutUninit;
use iceoryx2::service::ipc;
use score_log::{error, info};
use std::process;

/// Initialize topic with the given number of writers (publishers) and readers (subscribers).
pub fn init_topic<T: core::fmt::Debug + 'static>(topic: Topic, writers: usize, readers: usize) -> TopicHandle {
info!("Initializing topic {topic} (Iceoryx2, {writers} writers and {readers} readers)");
pub fn init_topic<T: FeoComData + 'static>(topic: Topic, writers: usize, readers: usize) -> TopicHandle {
info!(
"Initializing topic {} (Iceoryx2, {} writers and {} readers)",
topic, writers, readers
);
let port_factory = ipc_node()
.service_builder(&(*topic).try_into().unwrap_or_else(|_| panic!("invalid topic {topic}")))
.publish_subscribe::<T>()
Expand All @@ -53,14 +57,14 @@ pub fn init_topic<T: core::fmt::Debug + 'static>(topic: Topic, writers: usize, r
#[derive(Debug)]
pub struct Iox2Input<T>
where
T: fmt::Debug + 'static,
T: FeoComData + 'static,
{
subscriber: Subscriber<ipc::Service, T, ()>,
}

impl<T> Iox2Input<T>
where
T: fmt::Debug + 'static,
T: FeoComData + 'static,
{
// Create a new instance for the given `topic`
pub fn new(topic: &str) -> Self {
Expand All @@ -78,9 +82,9 @@ where

impl<T> ActivityInput<T> for Iox2Input<T>
where
T: fmt::Debug + 'static,
T: FeoComData + 'static,
{
fn read(&self) -> Result<InputGuard<T>, Error> {
fn read(&self) -> Result<InputGuard<'_, T>, Error> {
match self.subscriber.receive() {
Ok(Some(sample)) => Ok(InputGuard::Iox2(Iox2InputGuard { sample })),
Ok(None) | Err(_) => Err(Error::NoEmptyBuffer),
Expand All @@ -92,14 +96,14 @@ where
#[derive(Debug)]
pub struct Iox2Output<T>
where
T: fmt::Debug + 'static,
T: FeoComData + 'static,
{
publisher: Publisher<ipc::Service, T, ()>,
}

impl<T> Iox2Output<T>
where
T: fmt::Debug + 'static,
T: FeoComData + 'static,
{
// Create a new instance for the given `topic`
pub fn new(topic: &str) -> Self {
Expand All @@ -117,10 +121,10 @@ where

impl<T> ActivityOutput<T> for Iox2Output<T>
where
T: fmt::Debug + 'static,
T: FeoComData + 'static,
{
/// Get a handle to an uninitialized buffer
fn write_uninit(&mut self) -> Result<OutputUninitGuard<T>, Error> {
fn write_uninit(&mut self) -> Result<OutputUninitGuard<'_, T>, Error> {
self.publisher
.loan_uninit()
.map(|sample| OutputUninitGuard::Iox2(Iox2OutputUninitGuard { sample }))
Expand All @@ -130,10 +134,10 @@ where

impl<T> ActivityOutputDefault<T> for Iox2Output<T>
where
T: fmt::Debug + Default + 'static,
T: FeoComData + FeoComDefault + 'static,
{
/// Get a handle to a buffer initialized with the [Default] trait
fn write_init(&mut self) -> Result<OutputGuard<T>, Error> {
fn write_init(&mut self) -> Result<OutputGuard<'_, T>, Error> {
self.publisher
.loan()
.map(|sample| OutputGuard::Iox2(Iox2OutputGuard { sample }))
Expand All @@ -142,11 +146,11 @@ where
}

/// Handle to an input buffer
pub struct Iox2InputGuard<T: fmt::Debug> {
pub struct Iox2InputGuard<T: FeoComData> {
sample: Sample<ipc::Service, T, ()>,
}

impl<T: fmt::Debug> Deref for Iox2InputGuard<T> {
impl<T: FeoComData> Deref for Iox2InputGuard<T> {
type Target = T;

fn deref(&self) -> &Self::Target {
Expand All @@ -155,42 +159,42 @@ impl<T: fmt::Debug> Deref for Iox2InputGuard<T> {
}

/// Handle to an initialized output buffer
pub struct Iox2OutputGuard<T: fmt::Debug> {
pub struct Iox2OutputGuard<T: FeoComData> {
sample: SampleMut<ipc::Service, T, ()>,
}

impl<T> Iox2OutputGuard<T>
where
T: fmt::Debug,
T: FeoComData,
{
/// Send this buffer, making it receivable as input and consuming the buffer
pub(crate) fn send(self) -> Result<(), Error> {
self.sample.send().map(|_| {}).map_err(|_| Error::SendFailed)
}
}

impl<T: fmt::Debug> Deref for Iox2OutputGuard<T> {
impl<T: FeoComData> Deref for Iox2OutputGuard<T> {
type Target = T;

fn deref(&self) -> &Self::Target {
self.sample.payload()
}
}

impl<T: fmt::Debug> DerefMut for Iox2OutputGuard<T> {
impl<T: FeoComData> DerefMut for Iox2OutputGuard<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.sample.payload_mut()
}
}

/// Handle to an uninitialized output buffer
pub struct Iox2OutputUninitGuard<T: fmt::Debug> {
pub struct Iox2OutputUninitGuard<T: FeoComData> {
sample: SampleMutUninit<ipc::Service, MaybeUninit<T>, ()>,
}

impl<T> Iox2OutputUninitGuard<T>
where
T: fmt::Debug,
T: FeoComData,
{
/// Assume the backing buffer is initialized
///
Expand All @@ -211,7 +215,7 @@ where

impl<T> Iox2OutputUninitGuard<T>
where
T: fmt::Debug + Default,
T: FeoComData + FeoComDefault,
{
/// Initialize this buffer with its [Default] implementation
pub(crate) fn init(self) -> Iox2OutputGuard<T> {
Expand All @@ -220,15 +224,15 @@ where
}
}

impl<T: fmt::Debug> Deref for Iox2OutputUninitGuard<T> {
impl<T: FeoComData> Deref for Iox2OutputUninitGuard<T> {
type Target = MaybeUninit<T>;

fn deref(&self) -> &Self::Target {
self.sample.payload()
}
}

impl<T: fmt::Debug> DerefMut for Iox2OutputUninitGuard<T> {
impl<T: FeoComData> DerefMut for Iox2OutputUninitGuard<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.sample.payload_mut()
}
Expand All @@ -249,7 +253,10 @@ fn ipc_node() -> &'static Node<ipc::Service> {
Node::<ipc::Service>::list(&config, |node_state| {
if let NodeState::<ipc::Service>::Dead(view) = node_state {
if let Err(e) = view.remove_stale_resources() {
error!("Failed to clean iceoryx2 resources: {:?}", e);
error!(
"Failed to clean iceoryx2 resources: {:?}",
NodeCleanupFailureScoreDebug(e)
);
}
}
CallbackProgression::Continue
Expand All @@ -265,3 +272,20 @@ fn ipc_node() -> &'static Node<ipc::Service> {
.expect("failed to create ipc node")
})
}

struct NodeCleanupFailureScoreDebug(iceoryx2::node::NodeCleanupFailure);

impl score_log::fmt::ScoreDebug for NodeCleanupFailureScoreDebug {
fn fmt(
&self,
w: &mut dyn score_log::fmt::ScoreWrite,
spec: &score_log::fmt::FormatSpec,
) -> Result<(), score_log::fmt::Error> {
use iceoryx2::node::NodeCleanupFailure;
match self.0 {
NodeCleanupFailure::Interrupt => w.write_str("interrupt", spec),
NodeCleanupFailure::InternalError => w.write_str("internal error", spec),
NodeCleanupFailure::InsufficientPermissions => w.write_str("insufficient permissions", spec),
}
}
}
Loading