Is shared memory access naturally async like IO/io_uring? If not, asking for async is misplaced and any implementation would be synonymous with wrapping sync calls in `async fn` wrappers.
I think it's as naturally async as anything else here actually. If you're calling a function via IPC over shared memory, you're sending a message, signalling it's there to the other process, and waiting for a response message with the result.
The only thing needed to turn this async is to change the "get result over IPC" function from "block until result is available" to "check if result is available, return TRY_AGAIN if it's not"
In practice it's not desirable to go without an explicit wake feature, we need some way to know that now it's likely to succeed. The mechanism needn't be 100% reliable but "Always try again" is essentially exactly as useless as blocking.
I work on a widely deployed (~11,000 servers and growing) piece of software that does not use any OS sleep/wake primitive for our MPSC queues -- just polling. It works really well with the right overall design.
The core primitive for IPC isn't "request and wait for a response," it's "send a single message and return immediately." Sure, if you want an RPC framework over IPC, maybe you want async blocking, but that's sort of a higher level concern than basic IPC.
It seems that iceoryx2 intends to support request-response in the future, but doesn't today:
Even with fire and forget, your send queue might become full. So you either drop the message of you have to wait for it to empty. Similarly on the receiving end you have to block waiting for the queue to become non empty.
In fact that's exactly the reason that async exists for networking.
In iceoryx2, we use something that we call event concept, which can either use unix-domain sockets so that you have something to select/wake/epoll on or a variant where we use a semaphore stored in shared memory. See: https://github.com/eclipse-iceoryx/iceoryx2/tree/main/iceory...
The unix-domain socket has the advantage that you can combine it with external non-iceoryx events, but you pay with a small performance hit. The semaphore event is usually faster.
As a user, you can configure your IPC service architecture and use the mechanism that suits you best (but I have to admit that we have not yet documented this in detail). For the zero_copy service variants, it is done here: https://github.com/eclipse-iceoryx/iceoryx2/blob/main/iceory....
I believe you could do something with e.g. Linux futexes to support this kind of thing. But in general, polling at the receiver is going to be lower latency / higher throughput.
With this sort of thing you'd typically wrap the underlying IPC channel in a system thread and redirect messages to/from it within the local process via an async channel.
The dedicated system thread for the channel means the local process will never block on the incoming IPC events and the redirected messages will be buffered/enqueded as determined by the async runtime.
If you want to use push notifications to wake up processes, iceoryx2 has the event messaging pattern where a listener waits for incoming events, and a notifier in another process can send specific events to all waiting listeners. See this example: https://github.com/eclipse-iceoryx/iceoryx2/tree/main/exampl...
What... its shared memory? What is asynchronous about touching a few atomic vars and shared memory (shared pages) exactly? You could absolutely poll on this sort of thing in a non blocking manner, but there is not OS primitive here to trigger a Waker
build an Event Count on top of eventfd and you can get fast pathed blocking behavior on your shared memory queue that it is also async awaitable on top of your event loop of choice.