Skip to content

Commit

Permalink
WIP: Propagate error cause to CXX API
Browse files Browse the repository at this point in the history
  • Loading branch information
orecham committed Oct 23, 2024
1 parent d9c976f commit 664214b
Show file tree
Hide file tree
Showing 9 changed files with 542 additions and 21 deletions.
1 change: 1 addition & 0 deletions iceoryx2-ffi/cxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ target_include_directories(includes-only-cxx

add_library(iceoryx2-cxx-object-lib OBJECT
src/config.cpp
src/error_as_string.cpp
src/event_id.cpp
src/file_descriptor.cpp
src/header_publish_subscribe.cpp
Expand Down
235 changes: 227 additions & 8 deletions iceoryx2-ffi/cxx/include/iox2/enum_translation.hpp

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions iceoryx2-ffi/cxx/include/iox2/service_builder_event_error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,12 @@ enum class EventOpenOrCreateError : uint8_t {
/// [`SampleMut`] in use.
CreateOldConnectionsStillActive,
};


auto as_string(const iox2::EventOpenError& error) -> const char*;
auto as_string(const iox2::EventCreateError& error) -> const char*;
auto as_string(const iox2::EventOpenOrCreateError& error) -> const char*;

} // namespace iox2

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#ifndef IOX2_SERVICE_BUILDER_PUBLISH_SUBSCRIBE_ERROR_HPP
#define IOX2_SERVICE_BUILDER_PUBLISH_SUBSCRIBE_ERROR_HPP

#include "iox2/iceoryx2.h"
#include <cstdint>

namespace iox2 {
Expand Down Expand Up @@ -87,13 +88,6 @@ enum class PublishSubscribeCreateError : uint8_t {
InternalFailure,
/// Multiple processes are trying to create the same [`Service`].
IsBeingCreatedByAnotherInstance,
/// The system has cleaned up the [`Service`] but there are still endpoints
/// like
/// [`Publisher`] or
/// [`Subscriber`] alive or
/// [`Sample`] or
/// [`SampleMut`] in use.
OldConnectionsStillActive,
/// The [`Service`]s creation timeout has passed and it is still not
/// initialized. Can be caused
/// by a process that crashed during [`Service`] creation.
Expand Down Expand Up @@ -181,6 +175,11 @@ enum class PublishSubscribeOpenOrCreateError : uint8_t {
/// by a process that crashed during [`Service`] creation.
CreateHangsInCreation,
};

auto as_string(const iox2::PublishSubscribeOpenError& error) -> const char*;
auto as_string(const iox2::PublishSubscribeCreateError& error) -> const char*;
auto as_string(const iox2::PublishSubscribeOpenOrCreateError& error) -> const char*;

} // namespace iox2

#endif
43 changes: 43 additions & 0 deletions iceoryx2-ffi/cxx/src/error_as_string.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) 2024 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

#include "iox2/enum_translation.hpp"
#include "iox2/service_builder_event_error.hpp"
#include "iox2/service_builder_publish_subscribe_error.hpp"

namespace iox2 {

auto as_string(const iox2::PublishSubscribeOpenError& error) -> const char* {
return iox2_pub_sub_open_or_create_error_string(iox::into<iox2_pub_sub_open_or_create_error_e>(error));
}

auto as_string(const iox2::PublishSubscribeCreateError& error) -> const char* {
return iox2_pub_sub_open_or_create_error_string(iox::into<iox2_pub_sub_open_or_create_error_e>(error));
}

auto as_string(const iox2::PublishSubscribeOpenOrCreateError& error) -> const char* {
return iox2_pub_sub_open_or_create_error_string(iox::into<iox2_pub_sub_open_or_create_error_e>(error));
}

auto as_string(const iox2::EventOpenError& error) -> const char* {
return iox2_event_open_or_create_error_string(iox::into<iox2_event_open_or_create_error_e>(error));
}

auto as_string(const iox2::EventCreateError& error) -> const char* {
return iox2_event_open_or_create_error_string(iox::into<iox2_event_open_or_create_error_e>(error));
}

auto as_string(const iox2::EventOpenOrCreateError& error) -> const char* {
return iox2_event_open_or_create_error_string(iox::into<iox2_event_open_or_create_error_e>(error));
}

} // namespace iox2
144 changes: 144 additions & 0 deletions iceoryx2-ffi/ffi/src/api/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
// Copyright (c) 2024 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

use std::os::raw::c_char;

use iceoryx2::service::builder::{
event::{EventCreateError, EventOpenError, EventOpenOrCreateError},
publish_subscribe::{
PublishSubscribeCreateError, PublishSubscribeOpenError, PublishSubscribeOpenOrCreateError,
},
};

pub trait ErrorAsString {
fn as_str(&self) -> &'static str;
fn as_cstr(&self) -> *const c_char {
self.as_str().as_ptr() as *const c_char
}
}

impl ErrorAsString for PublishSubscribeCreateError {
fn as_str(&self) -> &'static str {
match self {
PublishSubscribeCreateError::ServiceInCorruptedState => "ServiceInCorruptedState",
PublishSubscribeCreateError::SubscriberBufferMustBeLargerThanHistorySize => {
"SubscriberBufferMustBeLargerThanHistorySize"
}
PublishSubscribeCreateError::AlreadyExists => "AlreadyExists",
PublishSubscribeCreateError::InsufficientPermissions => "InsufficientPermissions",
PublishSubscribeCreateError::InternalFailure => "InternalFailure",
PublishSubscribeCreateError::IsBeingCreatedByAnotherInstance => {
"IsBeingCreatedByAnotherInstance"
}
PublishSubscribeCreateError::HangsInCreation => "HangsInCreation",
}
}
}

impl ErrorAsString for PublishSubscribeOpenError {
fn as_str(&self) -> &'static str {
match self {
PublishSubscribeOpenError::DoesNotExist => "DoesNotExist",
PublishSubscribeOpenError::InternalFailure => "InternalFailure",
PublishSubscribeOpenError::IncompatibleTypes => "IncompatibleTypes",
PublishSubscribeOpenError::IncompatibleMessagingPattern => {
"IncompatibleMessagingPattern"
}
PublishSubscribeOpenError::IncompatibleAttributes => "IncompatibleAttributes",
PublishSubscribeOpenError::DoesNotSupportRequestedMinBufferSize => {
"DoesNotSupportRequestedMinBufferSize"
}
PublishSubscribeOpenError::DoesNotSupportRequestedMinHistorySize => {
"DoesNotSupportRequestedMinHistorySize"
}
PublishSubscribeOpenError::DoesNotSupportRequestedMinSubscriberBorrowedSamples => {
"DoesNotSupportRequestedMinSubscriberBorrowedSamples"
}
PublishSubscribeOpenError::DoesNotSupportRequestedAmountOfPublishers => {
"DoesNotSupportRequestedAmountOfPublishers"
}
PublishSubscribeOpenError::DoesNotSupportRequestedAmountOfSubscribers => {
"DoesNotSupportRequestedAmountOfSubscribers"
}
PublishSubscribeOpenError::DoesNotSupportRequestedAmountOfNodes => {
"DoesNotSupportRequestedAmountOfNodes"
}
PublishSubscribeOpenError::IncompatibleOverflowBehavior => {
"IncompatibleOverflowBehavior"
}
PublishSubscribeOpenError::InsufficientPermissions => "InsufficientPermissions",
PublishSubscribeOpenError::ServiceInCorruptedState => "ServiceInCorruptedState",
PublishSubscribeOpenError::HangsInCreation => "HangsInCreation",
PublishSubscribeOpenError::ExceedsMaxNumberOfNodes => "ExceedsMaxNumberOfNodes",
PublishSubscribeOpenError::IsMarkedForDestruction => "IsMarkedForDestruction",
}
}
}

impl ErrorAsString for PublishSubscribeOpenOrCreateError {
fn as_str(&self) -> &'static str {
match self {
PublishSubscribeOpenOrCreateError::PublishSubscribeOpenError(_) => todo!(),
PublishSubscribeOpenOrCreateError::PublishSubscribeCreateError(_) => todo!(),
}
}
}

impl ErrorAsString for EventOpenError {
fn as_str(&self) -> &'static str {
match self {
EventOpenError::DoesNotExist => "DoesNotExist",
EventOpenError::InsufficientPermissions => "InsufficientPermissions",
EventOpenError::ServiceInCorruptedState => "ServiceInCorruptedState",
EventOpenError::IncompatibleMessagingPattern => "IncompatibleMessagingPattern",
EventOpenError::IncompatibleAttributes => "IncompatibleAttributes",
EventOpenError::InternalFailure => "InternalFailure",
EventOpenError::HangsInCreation => "HangsInCreation",
EventOpenError::DoesNotSupportRequestedAmountOfNotifiers => {
"DoesNotSupportRequestedAmountOfNotifiers"
}
EventOpenError::DoesNotSupportRequestedAmountOfListeners => {
"DoesNotSupportRequestedAmountOfListeners"
}
EventOpenError::DoesNotSupportRequestedMaxEventId => {
"DoesNotSupportRequestedMaxEventId"
}
EventOpenError::DoesNotSupportRequestedAmountOfNodes => {
"DoesNotSupportRequestedAmountOfNodes"
}
EventOpenError::ExceedsMaxNumberOfNodes => "ExceedsMaxNumberOfNodes",
EventOpenError::IsMarkedForDestruction => "IsMarkedForDestruction",
}
}
}

impl ErrorAsString for EventCreateError {
fn as_str(&self) -> &'static str {
match self {
EventCreateError::ServiceInCorruptedState => "ServiceInCorruptedState",
EventCreateError::InternalFailure => "InternalFailure",
EventCreateError::IsBeingCreatedByAnotherInstance => "IsBeingCreatedByAnotherInstance",
EventCreateError::AlreadyExists => "AlreadyExists",
EventCreateError::HangsInCreation => "HangsInCreation",
EventCreateError::InsufficientPermissions => "InsufficientPermissions",
}
}
}

impl ErrorAsString for EventOpenOrCreateError {
fn as_str(&self) -> &'static str {
match self {
EventOpenOrCreateError::EventOpenError(e) => e.as_str(),
EventOpenOrCreateError::EventCreateError(e) => e.as_str(),
}
}
}
2 changes: 2 additions & 0 deletions iceoryx2-ffi/ffi/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use iceoryx2_bb_container::semantic_string::SemanticStringError;
use core::ffi::{c_int, c_void};

mod config;
mod error;
mod event_id;
mod file_descriptor;
mod iceoryx2_settings;
Expand Down Expand Up @@ -58,6 +59,7 @@ mod waitset_builder;
mod waitset_guard;

pub use config::*;
pub use error::*;
pub use event_id::*;
pub use file_descriptor::*;
pub use iceoryx2_settings::*;
Expand Down
78 changes: 74 additions & 4 deletions iceoryx2-ffi/ffi/src/api/service_builder_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@

use crate::api::{
c_size_t, iox2_port_factory_event_h, iox2_port_factory_event_t, iox2_service_builder_event_h,
iox2_service_builder_event_h_ref, iox2_service_type_e, AssertNonNullHandle, HandleToType,
IntoCInt, PortFactoryEventUnion, ServiceBuilderUnion, IOX2_OK,
iox2_service_builder_event_h_ref, iox2_service_type_e, AssertNonNullHandle, ErrorAsString,
HandleToType, IntoCInt, PortFactoryEventUnion, ServiceBuilderUnion, IOX2_OK,
};

use iceoryx2::prelude::*;
Expand All @@ -24,7 +24,7 @@ use iceoryx2::service::builder::event::{
};
use iceoryx2::service::port_factory::event::PortFactory;

use core::ffi::c_int;
use core::ffi::{c_char, c_int};
use core::mem::ManuallyDrop;

// BEGIN types definition
Expand All @@ -51,7 +51,70 @@ pub enum iox2_event_open_or_create_error_e {
C_ALREADY_EXISTS,
C_HANGS_IN_CREATION,
C_INSUFFICIENT_PERMISSIONS,
C_OLD_CONNECTION_STILL_ACTIVE,
}

impl ErrorAsString for iox2_event_open_or_create_error_e {
fn as_str(&self) -> &'static str {
match self {
iox2_event_open_or_create_error_e::O_DOES_NOT_EXIST => {
EventOpenError::DoesNotExist.as_str()
}
iox2_event_open_or_create_error_e::O_INSUFFICIENT_PERMISSIONS => {
EventOpenError::InsufficientPermissions.as_str()
}
iox2_event_open_or_create_error_e::O_SERVICE_IN_CORRUPTED_STATE => {
EventOpenError::ServiceInCorruptedState.as_str()
}
iox2_event_open_or_create_error_e::O_INCOMPATIBLE_MESSAGING_PATTERN => {
EventOpenError::IncompatibleMessagingPattern.as_str()
}
iox2_event_open_or_create_error_e::O_INCOMPATIBLE_ATTRIBUTES => {
EventOpenError::IncompatibleAttributes.as_str()
}
iox2_event_open_or_create_error_e::O_INTERNAL_FAILURE => {
EventOpenError::InternalFailure.as_str()
}
iox2_event_open_or_create_error_e::O_HANGS_IN_CREATION => {
EventOpenError::HangsInCreation.as_str()
}
iox2_event_open_or_create_error_e::O_DOES_NOT_SUPPORT_REQUESTED_AMOUNT_OF_NOTIFIERS => {
EventOpenError::DoesNotSupportRequestedAmountOfNotifiers.as_str()
}
iox2_event_open_or_create_error_e::O_DOES_NOT_SUPPORT_REQUESTED_AMOUNT_OF_LISTENERS => {
EventOpenError::DoesNotSupportRequestedAmountOfListeners.as_str()
}
iox2_event_open_or_create_error_e::O_DOES_NOT_SUPPORT_REQUESTED_MAX_EVENT_ID => {
EventOpenError::DoesNotSupportRequestedMaxEventId.as_str()
}
iox2_event_open_or_create_error_e::O_DOES_NOT_SUPPORT_REQUESTED_AMOUNT_OF_NODES => {
EventOpenError::DoesNotSupportRequestedAmountOfNodes.as_str()
}
iox2_event_open_or_create_error_e::O_EXCEEDS_MAX_NUMBER_OF_NODES => {
EventOpenError::ExceedsMaxNumberOfNodes.as_str()
}
iox2_event_open_or_create_error_e::O_IS_MARKED_FOR_DESTRUCTION => {
EventOpenError::IsMarkedForDestruction.as_str()
}
iox2_event_open_or_create_error_e::C_SERVICE_IN_CORRUPTED_STATE => {
EventCreateError::ServiceInCorruptedState.as_str()
}
iox2_event_open_or_create_error_e::C_INTERNAL_FAILURE => {
EventCreateError::InternalFailure.as_str()
}
iox2_event_open_or_create_error_e::C_IS_BEING_CREATED_BY_ANOTHER_INSTANCE => {
EventCreateError::IsBeingCreatedByAnotherInstance.as_str()
}
iox2_event_open_or_create_error_e::C_ALREADY_EXISTS => {
EventCreateError::AlreadyExists.as_str()
}
iox2_event_open_or_create_error_e::C_HANGS_IN_CREATION => {
EventCreateError::HangsInCreation.as_str()
}
iox2_event_open_or_create_error_e::C_INSUFFICIENT_PERMISSIONS => {
EventCreateError::InsufficientPermissions.as_str()
}
}
}
}

impl IntoCInt for EventOpenError {
Expand Down Expand Up @@ -135,6 +198,13 @@ impl IntoCInt for EventOpenOrCreateError {

// BEGIN C API

#[no_mangle]
pub unsafe extern "C" fn iox2_event_open_or_create_error_string(
error: iox2_event_open_or_create_error_e,
) -> *const c_char {
error.as_cstr()
}

/// Sets the max notifiers for the builder
///
/// # Arguments
Expand Down
Loading

0 comments on commit 664214b

Please sign in to comment.