diff --git a/README.md b/README.md index 5b9852c21..9fe0e4516 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ fn main() -> Result<(), Box> { let publisher = service.publisher_builder().create()?; - while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { + while let NodeEvent::Tick = node.wait(CYCLE_TIME) { let sample = publisher.loan_uninit()?; let sample = sample.write_payload(1234); sample.send()?; @@ -123,7 +123,7 @@ fn main() -> Result<(), Box> { let subscriber = service.subscriber_builder().create()?; - while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { + while let NodeEvent::Tick = node.wait(CYCLE_TIME) { while let Some(sample) = subscriber.receive()? { println!("received: {:?}", *sample); } @@ -172,7 +172,7 @@ fn main() -> Result<(), Box> { let notifier = event.notifier_builder().create()?; let id = EventId::new(12); - while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { + while let NodeEvent::Tick = node.wait(CYCLE_TIME) { notifier.notify_with_custom_event_id(id)?; println!("Trigger event with id {:?} ...", id); @@ -199,7 +199,7 @@ fn main() -> Result<(), Box> { let listener = event.listener_builder().create()?; - while let Iox2Event::Tick = Iox2::wait(Duration::ZERO) { + while let NodeEvent::Tick = node.wait(Duration::ZERO) { if let Ok(Some(event_id)) = listener.timed_wait_one(CYCLE_TIME) { println!("event was triggered with id: {:?}", event_id); } @@ -226,7 +226,7 @@ fn main() -> Result<(), Box> { let listener = event.listener_builder().create()?; - while let Iox2Event::Tick = Iox2::wait(Duration::ZERO) { + while let NodeEvent::Tick = node.wait(Duration::ZERO) { listener.timed_wait_all( |event_id| { println!("event was triggered with id: {:?}", event_id); diff --git a/doc/release-notes/iceoryx2-unreleased.md b/doc/release-notes/iceoryx2-unreleased.md index d585bc607..4c1b530c0 100644 --- a/doc/release-notes/iceoryx2-unreleased.md +++ b/doc/release-notes/iceoryx2-unreleased.md @@ -76,6 +76,7 @@ * Updated all dependencies and increased MSRV to 1.75 [#221](https://github.com/eclipse-iceoryx/iceoryx2/issues/221) * Remove `Service::does_exist_with_custom_config` and `Service::list_with_custom_config` [#238](https://github.com/eclipse-iceoryx/iceoryx2/issues/238) * Renamed `PortFactory::{publisher|subscriber|listener|notifier}` to `PortFactory::{publisher|subscriber|listener|notifier}_builder` [#244](https://github.com/eclipse-iceoryx/iceoryx2/issues/244) + * Merged `Iox2::wait` with new `Node` and removed `Iox2` [#270](https://github.com/eclipse-iceoryx/iceoryx2/issues/270) ### Workflow @@ -355,3 +356,18 @@ pubsub_service.static_config().max_subscriber(); ``` +17. `Iox2::wait()` is part of the `Node`, `Iox2Event` renamed to `NodeEvent` + + ```rust + // old + while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { + // main loop stuff + } + + // new + let node = NodeBuilder::new().create::()?; + while let NodeEvent::Tick = node.wait(CYCLE_TIME) { + // main loop stuff + } + ``` + diff --git a/examples/rust/complex_data_types/complex_data_types.rs b/examples/rust/complex_data_types/complex_data_types.rs index 50f693551..cab77c331 100644 --- a/examples/rust/complex_data_types/complex_data_types.rs +++ b/examples/rust/complex_data_types/complex_data_types.rs @@ -54,7 +54,7 @@ fn main() -> Result<(), Box> { let subscriber = service.subscriber_builder().create()?; let mut counter = 0; - while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { + while let NodeEvent::Tick = node.wait(CYCLE_TIME) { // ComplexDataType as a size of over 30MB, we need to perform a placement new // otherwise we will encounter a stack overflow in debug builds. // Therefore, we acquire an uninitialized sample, use the PlacementDefault diff --git a/examples/rust/event/listener.rs b/examples/rust/event/listener.rs index 6418ae3db..3e6c23e25 100644 --- a/examples/rust/event/listener.rs +++ b/examples/rust/event/listener.rs @@ -25,7 +25,7 @@ fn main() -> Result<(), Box> { let listener = event.listener_builder().create()?; - while let Iox2Event::Tick = Iox2::wait(Duration::ZERO) { + while let NodeEvent::Tick = node.wait(Duration::ZERO) { if let Ok(Some(event_id)) = listener.timed_wait_one(CYCLE_TIME) { println!("event was triggered with id: {:?}", event_id); } diff --git a/examples/rust/event/notifier.rs b/examples/rust/event/notifier.rs index 67449a603..2488cad77 100644 --- a/examples/rust/event/notifier.rs +++ b/examples/rust/event/notifier.rs @@ -26,7 +26,7 @@ fn main() -> Result<(), Box> { let notifier = event.notifier_builder().create()?; let mut counter: usize = 0; - while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { + while let NodeEvent::Tick = node.wait(CYCLE_TIME) { counter += 1; notifier.notify_with_custom_event_id(EventId::new(counter))?; diff --git a/examples/rust/publish_subscribe/publisher.rs b/examples/rust/publish_subscribe/publisher.rs index 7711e3ace..59c32327c 100644 --- a/examples/rust/publish_subscribe/publisher.rs +++ b/examples/rust/publish_subscribe/publisher.rs @@ -28,7 +28,7 @@ fn main() -> Result<(), Box> { let mut counter: u64 = 0; - while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { + while let NodeEvent::Tick = node.wait(CYCLE_TIME) { counter += 1; let sample = publisher.loan_uninit()?; diff --git a/examples/rust/publish_subscribe/subscriber.rs b/examples/rust/publish_subscribe/subscriber.rs index 4a76353ed..97b556061 100644 --- a/examples/rust/publish_subscribe/subscriber.rs +++ b/examples/rust/publish_subscribe/subscriber.rs @@ -26,7 +26,7 @@ fn main() -> Result<(), Box> { let subscriber = service.subscriber_builder().create()?; - while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { + while let NodeEvent::Tick = node.wait(CYCLE_TIME) { while let Some(sample) = subscriber.receive()? { println!("received: {:?}", *sample); } diff --git a/examples/rust/publish_subscribe_dynamic_data/publisher.rs b/examples/rust/publish_subscribe_dynamic_data/publisher.rs index 15cec1206..33a238fdf 100644 --- a/examples/rust/publish_subscribe_dynamic_data/publisher.rs +++ b/examples/rust/publish_subscribe_dynamic_data/publisher.rs @@ -31,7 +31,7 @@ fn main() -> Result<(), Box> { let mut counter = 1; - while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { + while let NodeEvent::Tick = node.wait(CYCLE_TIME) { counter += 1; let required_memory_size = (8 + counter) % 16; diff --git a/examples/rust/publish_subscribe_dynamic_data/subscriber.rs b/examples/rust/publish_subscribe_dynamic_data/subscriber.rs index 548aa7f13..6167041ba 100644 --- a/examples/rust/publish_subscribe_dynamic_data/subscriber.rs +++ b/examples/rust/publish_subscribe_dynamic_data/subscriber.rs @@ -25,7 +25,7 @@ fn main() -> Result<(), Box> { let subscriber = service.subscriber_builder().create()?; - while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { + while let NodeEvent::Tick = node.wait(CYCLE_TIME) { while let Some(sample) = subscriber.receive()? { print!("received {} bytes: ", sample.payload().len()); for byte in sample.payload() { diff --git a/examples/rust/publish_subscribe_with_user_header/publisher.rs b/examples/rust/publish_subscribe_with_user_header/publisher.rs index 71279f3bc..f6bbc98bd 100644 --- a/examples/rust/publish_subscribe_with_user_header/publisher.rs +++ b/examples/rust/publish_subscribe_with_user_header/publisher.rs @@ -31,7 +31,7 @@ fn main() -> Result<(), Box> { let mut counter: u64 = 0; - while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { + while let NodeEvent::Tick = node.wait(CYCLE_TIME) { counter += 1; let mut sample = publisher.loan_uninit()?; diff --git a/examples/rust/publish_subscribe_with_user_header/subscriber.rs b/examples/rust/publish_subscribe_with_user_header/subscriber.rs index 4a4ac16f0..f538f64d4 100644 --- a/examples/rust/publish_subscribe_with_user_header/subscriber.rs +++ b/examples/rust/publish_subscribe_with_user_header/subscriber.rs @@ -27,7 +27,7 @@ fn main() -> Result<(), Box> { let subscriber = service.subscriber_builder().create()?; - while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { + while let NodeEvent::Tick = node.wait(CYCLE_TIME) { while let Some(sample) = subscriber.receive()? { println!( "received: {:?}, user_header: {:?}", diff --git a/examples/rust/service_attributes/creator.rs b/examples/rust/service_attributes/creator.rs index bb090b3e1..3373a293a 100644 --- a/examples/rust/service_attributes/creator.rs +++ b/examples/rust/service_attributes/creator.rs @@ -38,7 +38,7 @@ fn main() -> Result<(), Box> { println!("{} = {}", attribute.key(), attribute.value()); } - while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { + while let NodeEvent::Tick = node.wait(CYCLE_TIME) { let sample = publisher.loan_uninit()?; let sample = sample.write_payload(0); sample.send()?; diff --git a/examples/rust/service_attributes/opener.rs b/examples/rust/service_attributes/opener.rs index 627fa236e..8acd16bf7 100644 --- a/examples/rust/service_attributes/opener.rs +++ b/examples/rust/service_attributes/opener.rs @@ -33,7 +33,7 @@ fn main() -> Result<(), Box> { println!("defined service attributes: {:?}", service.attributes()); - while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { + while let NodeEvent::Tick = node.wait(CYCLE_TIME) { while let Some(sample) = subscriber.receive()? { println!("received: {:?}", *sample); } diff --git a/iceoryx2-ffi/ffi/src/publisher.rs b/iceoryx2-ffi/ffi/src/publisher.rs index cb0f11203..0c9e5a191 100644 --- a/iceoryx2-ffi/ffi/src/publisher.rs +++ b/iceoryx2-ffi/ffi/src/publisher.rs @@ -53,7 +53,7 @@ pub extern "C" fn run_publisher(seconds: u32) -> i32 { let mut remaining_seconds = seconds; - while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { + while let NodeEvent::Tick = node.wait(CYCLE_TIME) { counter += 1; let sample = publisher.loan_uninit(); diff --git a/iceoryx2-ffi/ffi/src/subscriber.rs b/iceoryx2-ffi/ffi/src/subscriber.rs index 8e5c74656..9ef1c56a9 100644 --- a/iceoryx2-ffi/ffi/src/subscriber.rs +++ b/iceoryx2-ffi/ffi/src/subscriber.rs @@ -51,7 +51,7 @@ pub extern "C" fn run_subscriber(seconds: u32) -> i32 { let mut remaining_seconds = seconds; - while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { + while let NodeEvent::Tick = node.wait(CYCLE_TIME) { loop { match subscriber.receive() { Ok(Some(sample)) => println!("received: {:?}", *sample), diff --git a/iceoryx2/src/iox2.rs b/iceoryx2/src/iox2.rs deleted file mode 100644 index d5de763ac..000000000 --- a/iceoryx2/src/iox2.rs +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2023 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 - -//! # Example -//! -//! ## Simple Event Loop -//! -//! ```no_run -//! use core::time::Duration; -//! use iceoryx2::prelude::*; -//! -//! # fn main() -> Result<(), Box> { -//! const CYCLE_TIME: Duration = Duration::from_secs(1); -//! -//! while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { -//! // your algorithm in here -//! } -//! # Ok(()) -//! # } -//! ``` -//! -//! ## Advanced Event Loop -//! -//! ```no_run -//! use core::time::Duration; -//! use iceoryx2::prelude::*; -//! -//! # fn main() -> Result<(), Box> { -//! const CYCLE_TIME: Duration = Duration::from_secs(1); -//! -//! loop { -//! match Iox2::wait(CYCLE_TIME) { -//! Iox2Event::Tick => { -//! println!("entered next cycle"); -//! } -//! Iox2Event::TerminationRequest => { -//! println!("User pressed CTRL+c, terminating"); -//! break; -//! } -//! Iox2Event::InterruptSignal => { -//! println!("Someone send an interrupt signal ..."); -//! } -//! } -//! } -//! # Ok(()) -//! # } -//! ``` - -use core::time::Duration; -use iceoryx2_bb_log::fatal_panic; -use iceoryx2_bb_posix::clock::{nanosleep, NanosleepError}; -use iceoryx2_bb_posix::signal::SignalHandler; - -/// A complete list of all events that can occur in the main event loop, [`Iox2::wait()`]. -pub enum Iox2Event { - /// The timeout passed. - Tick, - /// SIGTERM signal was received - TerminationRequest, - /// SIGINT signal was received - InterruptSignal, -} - -/// The main event loop handling mechanism. -#[derive(Debug)] -#[non_exhaustive] -pub struct Iox2 {} - -impl Iox2 { - fn get_instance() -> &'static Self { - static INSTANCE: Iox2 = Iox2 {}; - &INSTANCE - } - - fn wait_impl(&self, cycle_time: Duration) -> Iox2Event { - if SignalHandler::termination_requested() { - return Iox2Event::TerminationRequest; - } - - match nanosleep(cycle_time) { - Ok(()) => { - if SignalHandler::termination_requested() { - Iox2Event::TerminationRequest - } else { - Iox2Event::Tick - } - } - Err(NanosleepError::InterruptedBySignal(_)) => Iox2Event::InterruptSignal, - Err(v) => { - fatal_panic!(from self, - "Failed to wait with cycle time {:?} in main event look, caused by ({:?}).", - cycle_time, v); - } - } - } - - /// Waits until an event was received. It returns - /// [`Iox2Event::Tick`] when the `cycle_time` has passed, otherwise event that occurred. - pub fn wait(cycle_time: Duration) -> Iox2Event { - Self::get_instance().wait_impl(cycle_time) - } -} diff --git a/iceoryx2/src/lib.rs b/iceoryx2/src/lib.rs index ddec85d3e..c26516c4e 100644 --- a/iceoryx2/src/lib.rs +++ b/iceoryx2/src/lib.rs @@ -75,7 +75,7 @@ //! //! let subscriber = service.subscriber_builder().create()?; //! -//! while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { +//! while let NodeEvent::Tick = node.wait(CYCLE_TIME) { //! while let Some(sample) = subscriber.receive()? { //! println!("received: {:?}", *sample); //! } @@ -102,7 +102,7 @@ //! //! let publisher = service.publisher_builder().create()?; //! -//! while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { +//! while let NodeEvent::Tick = node.wait(CYCLE_TIME) { //! let sample = publisher.loan_uninit()?; //! let sample = sample.write_payload(1234); //! sample.send()?; @@ -135,7 +135,7 @@ //! //! let mut listener = event.listener_builder().create()?; //! -//! while let Iox2Event::Tick = Iox2::wait(Duration::ZERO) { +//! while let NodeEvent::Tick = node.wait(Duration::ZERO) { //! if let Ok(Some(event_id)) = listener.timed_wait_one(CYCLE_TIME) { //! println!("event was triggered with id: {:?}", event_id); //! } @@ -163,7 +163,7 @@ //! let notifier = event.notifier_builder().create()?; //! //! let mut counter: usize = 0; -//! while let Iox2Event::Tick = Iox2::wait(CYCLE_TIME) { +//! while let NodeEvent::Tick = node.wait(CYCLE_TIME) { //! counter += 1; //! notifier.notify_with_custom_event_id(EventId::new(counter))?; //! @@ -289,9 +289,6 @@ mod compiletests; /// Handles iceoryx2s global configuration pub mod config; -/// Central instance that handles all incoming events, the event loop -pub mod iox2; - /// Central instance that owns all service entities and can handle incoming event in an event loop pub mod node; diff --git a/iceoryx2/src/node/mod.rs b/iceoryx2/src/node/mod.rs index acdf456c0..4673cf61e 100644 --- a/iceoryx2/src/node/mod.rs +++ b/iceoryx2/src/node/mod.rs @@ -61,6 +61,55 @@ //! # Ok(()) //! # } //! ``` +//! +//! ## Simple Event Loop +//! +//! ```no_run +//! use core::time::Duration; +//! use iceoryx2::prelude::*; +//! +//! # fn main() -> Result<(), Box> { +//! const CYCLE_TIME: Duration = Duration::from_secs(1); +//! let node = NodeBuilder::new() +//! .name("my_little_node".try_into()?) +//! .create::()?; +//! +//! while let NodeEvent::Tick = node.wait(CYCLE_TIME) { +//! // your algorithm in here +//! } +//! # Ok(()) +//! # } +//! ``` +//! +//! ## Advanced Event Loop +//! +//! ```no_run +//! use core::time::Duration; +//! use iceoryx2::prelude::*; +//! +//! # fn main() -> Result<(), Box> { +//! const CYCLE_TIME: Duration = Duration::from_secs(1); +//! let node = NodeBuilder::new() +//! .name("my_little_node".try_into()?) +//! .create::()?; +//! +//! loop { +//! match node.wait(CYCLE_TIME) { +//! NodeEvent::Tick => { +//! println!("entered next cycle"); +//! } +//! NodeEvent::TerminationRequest => { +//! println!("User pressed CTRL+c, terminating"); +//! break; +//! } +//! NodeEvent::InterruptSignal => { +//! println!("Someone send an interrupt signal ..."); +//! } +//! } +//! } +//! # Ok(()) +//! # } +//! ``` /// The name for a node. pub mod node_name; @@ -78,6 +127,8 @@ use iceoryx2_bb_container::semantic_string::SemanticString; use iceoryx2_bb_elementary::CallbackProgression; use iceoryx2_bb_lock_free::mpmc::container::ContainerHandle; use iceoryx2_bb_log::{fail, fatal_panic, warn}; +use iceoryx2_bb_posix::clock::{nanosleep, NanosleepError}; +use iceoryx2_bb_posix::signal::SignalHandler; use iceoryx2_bb_posix::unique_system_id::UniqueSystemId; use iceoryx2_bb_system_types::file_name::FileName; use iceoryx2_cal::named_concept::{NamedConceptPathHintRemoveError, NamedConceptRemoveError}; @@ -88,6 +139,18 @@ use std::cell::UnsafeCell; use std::collections::HashMap; use std::marker::PhantomData; use std::sync::{Arc, Mutex}; +use std::time::Duration; + +/// A complete list of all events that can occur in the main event loop, [`Node::wait()`]. +#[derive(Debug, Eq, Hash, PartialEq, Clone, Copy)] +pub enum NodeEvent { + /// The timeout passed. + Tick, + /// SIGTERM signal was received + TerminationRequest, + /// SIGINT signal was received + InterruptSignal, +} /// The system-wide unique id of a [`Node`] #[derive(Debug, Eq, Hash, PartialEq, Clone, Copy, serde::Serialize, serde::Deserialize)] @@ -559,6 +622,30 @@ impl Node { (*self.shared.monitoring_token.get()).take().unwrap() } + /// Waits until an event was received. It returns + /// [`NodeEvent::Tick`] when the `cycle_time` has passed, otherwise event that occurred. + pub fn wait(&self, cycle_time: Duration) -> NodeEvent { + if SignalHandler::termination_requested() { + return NodeEvent::TerminationRequest; + } + + match nanosleep(cycle_time) { + Ok(()) => { + if SignalHandler::termination_requested() { + NodeEvent::TerminationRequest + } else { + NodeEvent::Tick + } + } + Err(NanosleepError::InterruptedBySignal(_)) => NodeEvent::InterruptSignal, + Err(v) => { + fatal_panic!(from self, + "Failed to wait with cycle time {:?} in main event look, caused by ({:?}).", + cycle_time, v); + } + } + } + fn list_all_nodes( config: &::Configuration, ) -> Result, NodeListFailure> { diff --git a/iceoryx2/src/prelude.rs b/iceoryx2/src/prelude.rs index bc1863565..393759171 100644 --- a/iceoryx2/src/prelude.rs +++ b/iceoryx2/src/prelude.rs @@ -11,9 +11,7 @@ // SPDX-License-Identifier: Apache-2.0 OR MIT pub use crate::config::Config; -pub use crate::iox2::Iox2; -pub use crate::iox2::Iox2Event; -pub use crate::node::{node_name::NodeName, Node, NodeBuilder, NodeState}; +pub use crate::node::{node_name::NodeName, Node, NodeBuilder, NodeEvent, NodeState}; pub use crate::port::event_id::EventId; pub use crate::service::messaging_pattern::MessagingPattern; pub use crate::service::{