Skip to content

[#390] waitset #424

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 40 commits into from
Oct 6, 2024
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
c5aa6da
[#390] Create waitset skeleton
elfenpiff Sep 23, 2024
371ca8e
[#390] Implement and document WaitSet
elfenpiff Sep 30, 2024
38e4b32
[#390] Add waitset example
elfenpiff Sep 30, 2024
88e1f06
[#390] Fix examples
elfenpiff Oct 1, 2024
f601858
[#390] Add example description
elfenpiff Oct 1, 2024
f3873d0
[#390] Remove UNIX_DATAGRAM support flag since every platform support…
elfenpiff Oct 1, 2024
ea0785a
[#390] Ensure that the reactor cannot attach the same attachment twice
elfenpiff Oct 1, 2024
b2b4d04
[#390] FileDescriptorSet, Reactor and WaitSet return number of notifi…
elfenpiff Oct 1, 2024
d47eb44
[#390] Replace NodeEvent with WaitEvent
elfenpiff Oct 1, 2024
b4a1189
[#390] Update documentation
elfenpiff Oct 1, 2024
8f63cd3
[#390] Add WaitSet tests
elfenpiff Oct 1, 2024
c33d897
[#390] Add release note
elfenpiff Oct 1, 2024
c57ab2a
[#390] Fix clippy warnings
elfenpiff Oct 1, 2024
5e07685
[#390] Fix invalid doc links
elfenpiff Oct 1, 2024
fa70640
[#390] Fix example loop
elfenpiff Oct 1, 2024
1c31797
[#390] Fixing first batch of review comments
elfenpiff Oct 1, 2024
116ca4f
[#390] Integrate tick and deadline events to waitset
elfenpiff Oct 2, 2024
513de2d
[#390] Finalize refactored waitset version
elfenpiff Oct 3, 2024
bb3a872
[#390] Add documentation to the waitset
elfenpiff Oct 3, 2024
0811057
[#390] Rename Timer into DeadlineQueue
elfenpiff Oct 3, 2024
1aed934
[#390] Correct capacity handling in waitset
elfenpiff Oct 3, 2024
cb49b47
[#390] Distinguish between deadline and tick attachments
elfenpiff Oct 3, 2024
83d2f14
[#390] DeadlineQueue returns Duration::ZERO when deadlines are alread…
elfenpiff Oct 3, 2024
2a03b77
[#390] Collect test cases
elfenpiff Oct 3, 2024
c86cc87
[#390] Fix issue where missed deadline could not be acquired when dur…
elfenpiff Oct 3, 2024
0c7ca92
[#390] Use temporarily uds in process local; add waitset tests
elfenpiff Oct 4, 2024
f19c6f4
[#390] Finalize waitset tests
elfenpiff Oct 4, 2024
46dd04a
[#390] Remove WaitEvent and handle everything via result; finish wait…
elfenpiff Oct 4, 2024
b7d91f2
[#390] Sync WaitEvent adjustments with c API
elfenpiff Oct 4, 2024
098b362
[#390] Fix clippy warnings and doc code issues
elfenpiff Oct 4, 2024
d02a1c3
[#390] Fix clippy warnings
elfenpiff Oct 4, 2024
cd48e01
[#390] Fix windows reactor, just call nanosleep wait when reactor is …
elfenpiff Oct 4, 2024
02eb3a4
[#390] Fix mac os upper timeout limit
elfenpiff Oct 5, 2024
dac914b
[#390] Address review comments
elfenpiff Oct 5, 2024
d2b433a
[#390] Fix typo
elfenpiff Oct 5, 2024
b23b40c
[#390] Add blocking_wait to FileDescriptorSet and use it in reactor
elfenpiff Oct 5, 2024
b8efdbd
[#390] Use blocking_wait when there are no time attachments
elfenpiff Oct 5, 2024
764ceee
[#390] Fix deadline queue test
elfenpiff Oct 5, 2024
3a93052
[#390] Fix spurious wakeups in windows select; restore corrupted fdse…
elfenpiff Oct 5, 2024
5904a48
[#390] Address review comments
elfenpiff Oct 6, 2024
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
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

let publisher = service.publisher_builder().create()?;

while let NodeEvent::Tick = node.wait(CYCLE_TIME) {
while node.wait(CYCLE_TIME) != WaitEvent::TerminationRequest {
let sample = publisher.loan_uninit()?;
let sample = sample.write_payload(1234);
sample.send()?;
Expand All @@ -150,7 +150,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

let subscriber = service.subscriber_builder().create()?;

while let NodeEvent::Tick = node.wait(CYCLE_TIME) {
while node.wait(CYCLE_TIME) != WaitEvent::TerminationRequest {
while let Some(sample) = subscriber.receive()? {
println!("received: {:?}", *sample);
}
Expand Down Expand Up @@ -200,7 +200,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let notifier = event.notifier_builder().create()?;

let id = EventId::new(12);
while let NodeEvent::Tick = node.wait(CYCLE_TIME) {
while node.wait(CYCLE_TIME) != WaitEvent::TerminationRequest {
notifier.notify_with_custom_event_id(id)?;

println!("Trigger event with id {:?} ...", id);
Expand All @@ -227,7 +227,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

let listener = event.listener_builder().create()?;

while let NodeEvent::Tick = node.wait(Duration::ZERO) {
while node.wait(Duration::ZERO) != WaitEvent::TerminationRequest {
if let Ok(Some(event_id)) = listener.timed_wait_one(CYCLE_TIME) {
println!("event was triggered with id: {:?}", event_id);
}
Expand All @@ -254,7 +254,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

let listener = event.listener_builder().create()?;

while let NodeEvent::Tick = node.wait(Duration::ZERO) {
while node.wait(Duration::ZERO) != WaitEvent::TerminationRequest {
listener.timed_wait_all(
|event_id| {
println!("event was triggered with id: {:?}", event_id);
Expand Down
13 changes: 9 additions & 4 deletions doc/release-notes/iceoryx2-unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
conflicts when merging.
-->

* Add Event-Multiplexer `WaitSet` [#390](https://github.com/eclipse-iceoryx/iceoryx2/issues/390)
* Add `PeriodicTimer` into POSIX building blocks [#425](https://github.com/eclipse-iceoryx/iceoryx2/issues/425)

### Bugfixes
Expand All @@ -29,7 +30,7 @@
conflicts when merging.
-->

* Example text [#1](https://github.com/eclipse-iceoryx/iceoryx2/issues/1)
* Rename `NodeEvent` into `WaitEvent` [#390](https://github.com/eclipse-iceoryx/iceoryx2/issues/390)

### Workflow

Expand All @@ -51,12 +52,16 @@

### API Breaking Changes

1. Example
1. Renamed `NodeEvent` into `WaitEvent`

```rust
// old
let fuu = hello().is_it_me_you_re_looking_for()
while node.wait(CYCLE_TIME) != NodeEvent::TerminationRequest {
// ...
}

// new
let fuu = hypnotoad().all_glory_to_the_hypnotoad()
while node.wait(CYCLE_TIME) != WaitEvent::TerminationRequest {
// ...
}
```
10 changes: 10 additions & 0 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ path = "rust/event/listener.rs"
name = "event_notifier"
path = "rust/event/notifier.rs"

# event multiplexing

[[example]]
name = "event_multiplexing_notifier"
path = "rust/event_multiplexing/notifier.rs"

[[example]]
name = "event_multiplexing_wait"
path = "rust/event_multiplexing/wait.rs"

# publish_subscribe

[[example]]
Expand Down
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ and exchange data.
| docker | [all](rust/docker) | Communicate between different docker containers and the host. |
| domains | [C](c/domains) [C++](cxx/domains) [Rust](rust/domains) | Establish separate domains that operate independently from one another. |
| event | [C](c/event) [C++](cxx/event) [Rust](rust/event) | Push notifications - send event signals to wakeup processes that are waiting for them. |
| event multiplexing | [Rust](rust/event_multiplexing) | Wait on multiple listeners or sockets with a single call. The WaitSet demultiplexes incoming events and notifies the user. |
| publish subscribe | [C](c/publish_subscribe) [C++](cxx/publish_subscribe) [Rust](rust/publish_subscribe) | Communication between multiple processes with a [publish subscribe messaging pattern](https://en.wikipedia.org/wiki/Publish–subscribe_pattern). |
| publish subscribe dynamic data | [Rust](rust/publish_subscribe_dynamic_data) | Communication between multiple processes with a [publish subscribe messaging pattern](https://en.wikipedia.org/wiki/Publish–subscribe_pattern) and payload data that has a dynamic size. |
| publish subscribe with user header | [C](c/publish_subscribe_with_user_header) [C++](cxx/publish_subscribe_with_user_header) [Rust](rust/publish_subscribe_with_user_header) | Add a user header to the payload (samples) to transfer additional information. |
Expand Down
2 changes: 1 addition & 1 deletion examples/c/domains/src/publisher.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ int main(int argc, char** argv) {
}

int32_t counter = 0;
while (iox2_node_wait(&node_handle, 1, 0) == iox2_node_event_e_TICK) {
while (iox2_node_wait(&node_handle, 1, 0) == IOX2_OK) {
counter += 1;

// loan sample
Expand Down
2 changes: 1 addition & 1 deletion examples/c/domains/src/subscriber.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ int main(int argc, char** argv) {

uint64_t counter = 0;
printf("subscribed to: [domain: \"%s\", service: \"%s\"]\n", argv[1], argv[2]);
while (iox2_node_wait(&node_handle, 1, 0) == iox2_node_event_e_TICK) {
while (iox2_node_wait(&node_handle, 1, 0) == IOX2_OK) {
counter += 1;

// receive sample
Expand Down
2 changes: 1 addition & 1 deletion examples/c/event/src/listener.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ int main(void) {
}
iox2_event_id_t event_id;

while (iox2_node_wait(&node_handle, 0, 0) == iox2_node_event_e_TICK) {
while (iox2_node_wait(&node_handle, 0, 0) == IOX2_OK) {
bool has_received_one = false;
if (iox2_listener_timed_wait_one(&listener, &event_id, &has_received_one, 1, 0) != IOX2_OK) {
printf("Unable to wait for notification!\n");
Expand Down
2 changes: 1 addition & 1 deletion examples/c/event/src/notifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ int main(void) {
}

uint64_t counter = 0;
while (iox2_node_wait(&node_handle, 0, 0) == iox2_node_event_e_TICK) {
while (iox2_node_wait(&node_handle, 0, 0) == IOX2_OK) {
counter += 1;
iox2_event_id_t event_id = { .value = counter % 12 }; // NOLINT
if (iox2_notifier_notify_with_custom_event_id(&notifier, &event_id, NULL) != IOX2_OK) {
Expand Down
2 changes: 1 addition & 1 deletion examples/c/publish_subscribe/src/publisher.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ int main(void) {
}

int32_t counter = 0;
while (iox2_node_wait(&node_handle, 1, 0) == iox2_node_event_e_TICK) {
while (iox2_node_wait(&node_handle, 1, 0) == IOX2_OK) {
counter += 1;

// loan sample
Expand Down
2 changes: 1 addition & 1 deletion examples/c/publish_subscribe/src/subscriber.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ int main(void) {
}

uint64_t counter = 0;
while (iox2_node_wait(&node_handle, 1, 0) == iox2_node_event_e_TICK) {
while (iox2_node_wait(&node_handle, 1, 0) == IOX2_OK) {
counter += 1;

// receive sample
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ int main(void) {
}

int32_t counter = 0;
while (iox2_node_wait(&node_handle, 1, 0) == iox2_node_event_e_TICK) {
while (iox2_node_wait(&node_handle, 1, 0) == IOX2_OK) {
counter += 1;

// loan sample
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ int main(void) {
}

uint64_t counter = 0;
while (iox2_node_wait(&node_handle, 1, 0) == iox2_node_event_e_TICK) {
while (iox2_node_wait(&node_handle, 1, 0) == IOX2_OK) {
counter += 1;

// receive sample
Expand Down
2 changes: 1 addition & 1 deletion examples/cxx/complex_data_types/src/complex_data_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ auto main() -> int {
auto subscriber = service.subscriber_builder().create().expect("successful subscriber creation");

auto counter = 0;
while (node.wait(CYCLE_TIME) == NodeEvent::Tick) {
while (node.wait(CYCLE_TIME).has_value()) {
counter += 1;
auto sample = publisher.loan_uninit().expect("acquire sample");
new (&sample.payload_mut()) ComplexDataType {};
Expand Down
2 changes: 1 addition & 1 deletion examples/cxx/domains/src/publisher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ auto main(int argc, char** argv) -> int {
auto publisher = service.publisher_builder().create().expect("successful publisher creation");

auto counter = 0;
while (node.wait(CYCLE_TIME) == NodeEvent::Tick) {
while (node.wait(CYCLE_TIME).has_value()) {
counter += 1;

auto sample = publisher.loan_uninit().expect("acquire sample");
Expand Down
2 changes: 1 addition & 1 deletion examples/cxx/domains/src/subscriber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ auto main(int argc, char** argv) -> int {

std::cout << "subscribed to: [domain: \"" << args.domain() << "\", service: \"" << args.service() << "\"]"
<< std::endl;
while (node.wait(CYCLE_TIME) == NodeEvent::Tick) {
while (node.wait(CYCLE_TIME).has_value()) {
auto sample = subscriber.receive().expect("receive succeeds");
while (sample.has_value()) {
std::cout << "received: " << sample->payload() << std::endl;
Expand Down
2 changes: 1 addition & 1 deletion examples/cxx/event/src/listener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ auto main() -> int {

auto listener = service.listener_builder().create().expect("successful listener creation");

while (node.wait(iox::units::Duration::zero()) == NodeEvent::Tick) {
while (node.wait(iox::units::Duration::zero()).has_value()) {
listener.timed_wait_one(CYCLE_TIME).and_then([](auto maybe_event_id) {
maybe_event_id.and_then(
[](auto event_id) { std::cout << "event was triggered with id: " << event_id << std::endl; });
Expand Down
2 changes: 1 addition & 1 deletion examples/cxx/event/src/notifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ auto main() -> int {
auto notifier = service.notifier_builder().create().expect("successful notifier creation");

auto counter = 0;
while (node.wait(CYCLE_TIME) == NodeEvent::Tick) {
while (node.wait(CYCLE_TIME).has_value()) {
counter += 1;
const auto event_id = EventId(counter % max_event_id);
notifier.notify_with_custom_event_id(event_id).expect("notification");
Expand Down
2 changes: 1 addition & 1 deletion examples/cxx/publish_subscribe/src/publisher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ auto main() -> int {
auto publisher = service.publisher_builder().create().expect("successful publisher creation");

auto counter = 0;
while (node.wait(CYCLE_TIME) == NodeEvent::Tick) {
while (node.wait(CYCLE_TIME).has_value()) {
counter += 1;

auto sample = publisher.loan_uninit().expect("acquire sample");
Expand Down
2 changes: 1 addition & 1 deletion examples/cxx/publish_subscribe/src/subscriber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ auto main() -> int {

auto subscriber = service.subscriber_builder().create().expect("successful subscriber creation");

while (node.wait(CYCLE_TIME) == NodeEvent::Tick) {
while (node.wait(CYCLE_TIME).has_value()) {
auto sample = subscriber.receive().expect("receive succeeds");
while (sample.has_value()) {
std::cout << "received: " << sample->payload() << std::endl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ auto main() -> int {

auto counter = 1;

while (node.wait(CYCLE_TIME) == NodeEvent::Tick) {
while (node.wait(CYCLE_TIME).has_value()) {
counter += 1;

auto required_memory_size = (8 + counter) % 16; // NOLINT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ auto main() -> int {

auto subscriber = service.subscriber_builder().create().expect("successful subscriber creation");

while (node.wait(CYCLE_TIME) == NodeEvent::Tick) {
while (node.wait(CYCLE_TIME).has_value()) {
auto sample = subscriber.receive().expect("receive succeeds");
while (sample.has_value()) {
std::cout << "received " << sample->payload().size() << " bytes: ";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ auto main() -> int {
auto publisher = service.publisher_builder().create().expect("successful publisher creation");

auto counter = 0;
while (node.wait(CYCLE_TIME) == NodeEvent::Tick) {
while (node.wait(CYCLE_TIME).has_value()) {
counter += 1;
auto sample = publisher.loan_uninit().expect("acquire sample");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ auto main() -> int {

auto subscriber = service.subscriber_builder().create().expect("successful subscriber creation");

while (node.wait(CYCLE_TIME) == NodeEvent::Tick) {
while (node.wait(CYCLE_TIME).has_value()) {
auto sample = subscriber.receive().expect("receive succeeds");
while (sample.has_value()) {
std::cout << "received: " << sample->payload() << ", user_header: " << sample->user_header() << std::endl;
Expand Down
2 changes: 1 addition & 1 deletion examples/cxx/service_attributes/src/creator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ auto main() -> int {

std::cout << "defined service attributes: " << service.attributes() << std::endl;

while (node.wait(CYCLE_TIME) == NodeEvent::Tick) {
while (node.wait(CYCLE_TIME).has_value()) {
auto sample = publisher.loan().expect("acquire sample");
sample.payload_mut() = 0;
send(std::move(sample)).expect("send successful");
Expand Down
2 changes: 1 addition & 1 deletion examples/cxx/service_attributes/src/opener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ auto main() -> int {

std::cout << "defined service attributes: " << service.attributes() << std::endl;

while (node.wait(CYCLE_TIME) == NodeEvent::Tick) {
while (node.wait(CYCLE_TIME).has_value()) {
auto sample = subscriber.receive().expect("receive succeeds");
while (sample.has_value()) {
std::cout << "received: " << sample->payload() << std::endl;
Expand Down
2 changes: 1 addition & 1 deletion examples/rust/complex_data_types/complex_data_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let subscriber = service.subscriber_builder().create()?;
let mut counter = 0;

while let NodeEvent::Tick = node.wait(CYCLE_TIME) {
while node.wait(CYCLE_TIME).is_ok() {
// 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
Expand Down
2 changes: 1 addition & 1 deletion examples/rust/domains/publisher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

let mut counter: u64 = 0;

while let NodeEvent::Tick = node.wait(CYCLE_TIME) {
while node.wait(CYCLE_TIME).is_ok() {
counter += 1;
let sample = publisher.loan_uninit()?;

Expand Down
2 changes: 1 addition & 1 deletion examples/rust/domains/subscriber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
"subscribed to: [domain: \"{}\", service: \"{}\"]",
args.domain, args.service
);
while let NodeEvent::Tick = node.wait(CYCLE_TIME) {
while node.wait(CYCLE_TIME).is_ok() {
while let Some(sample) = subscriber.receive()? {
println!("received: {:?}", *sample);
}
Expand Down
2 changes: 1 addition & 1 deletion examples/rust/event/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

let listener = event.listener_builder().create()?;

while let NodeEvent::Tick = node.wait(Duration::ZERO) {
while node.wait(Duration::ZERO).is_ok() {
if let Ok(Some(event_id)) = listener.timed_wait_one(CYCLE_TIME) {
println!("event was triggered with id: {:?}", event_id);
}
Expand Down
2 changes: 1 addition & 1 deletion examples/rust/event/notifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let notifier = event.notifier_builder().create()?;

let mut counter: usize = 0;
while let NodeEvent::Tick = node.wait(CYCLE_TIME) {
while node.wait(CYCLE_TIME).is_ok() {
counter += 1;
notifier.notify_with_custom_event_id(EventId::new(counter % max_event_id))?;

Expand Down
53 changes: 53 additions & 0 deletions examples/rust/event_multiplexing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Event Multiplexing

## Running The Example

This example demonstrates iceoryx2's event multiplexing mechanism,
called the `WaitSet`. It allows waiting, with a single call, on
multiple `Listener` ports as well as external file descriptor-based
events such as `sockets`.

In this setup, the `wait` process monitors an arbitrary number of
services, which the user can specify via the command line option `-s`.
The `notifier` can define the service to which it will send event
notifications using the `-s` option and specify the event ID with
the `-e` option.

In the example below, we are waiting for events on the services `fuu` and
`bar`. Service `fuu` is notified with event ID `123`, and service `bar` is
notified with event ID `456`.

### Terminal 1

```sh
cargo run --example event_multiplexing_wait -- -s "fuu" -s "bar"
```

### Terminal 2

```sh
cargo run --example event_multiplexing_notifier -- -s "fuu" -e 123
```

### Terminal 3

```sh
cargo run --example event_multiplexing_notifier -- -s "bar" -e 456
```

Feel free to instantiate multiple notifiers for the same service with the same
or different event id's. Or to for different services.

## Technical Details

The `WaitSet` utilizes `epoll`, `select`, or other event-multiplexing
mechanisms. Before the `WaitSet` can monitor a specific event, it must first be
attached using `WaitSet::attach()`, which returns a RAII `Guard`. This `Guard`
automatically detaches the attachment when it goes out of scope.

The `WaitSet::**_wait()` calls require a closure that is invoked for each
triggered attachment and provides the `AttachmentId`. The user can either use
`AttachmentId::originates_from($ATTACHED_OBJECT$)` to identify the object
associated with the `AttachmentId`, or set up a
`HashMap::<AttachmentId, Listener<ipc::Service>>` to quickly access the
corresponding object.
Loading
Loading