Synchronous Interprocess Messaging Project for LINUX (SIMPL) is a free and open-source project that allows QNX-style synchronous message passing by adding a Linux library using user space techniques like shared memory and Unix pipes[3] to implement SendMssg/ReceiveMssg/ReplyMssg inter-process messaging mechanisms.
QNX itself implements pipes via messaging.
https://github.com/martinhaefner/qnxcomm
Can't immediately find any more information about it though, so don't know the maturity.
Having done a fair amount of IPC through shared memory, you'll have to explain this one. One process crashing doesn't destroy a memory mapped file on Linux, OS X, or Windows.
What's a good open alternative, or starting point for new innovation, given current investments in microservice architecture?
- ZeroMQ (and nanomsg)
- gRPC (Google)
- Apache Thrift (Facebook)
- Finagle (Twitter)
- L4/seL4 IPCNot necessarily. QNX messaging is old enough that patents related to the interface may have expired.
"An asynchronous message passing mechanism that allows for multiple messages to be batched for delivery between processes, while allowing for full memory protection during data transfers and a lockless mechanism for speeding up queue operation and queuing and delivering messages simultaneously."
Maybe there are older patents that have expired?
Does this run into security corner cases around pid reuse? (Or race conditions like a process dropping it's privileges after sending?) I remember the kdbus authors talking about making a lot of security metadata attach to the message itself, rather than indirecting through a pid, maybe for these reasons?
So QNX messaging is implemented in kernel space?
I never really understood why kdbus was rejected from Linux, it seems to only have advantages compared to a user space message bus. The only disadvantage I can come up with is security.
How do they implement this securely? I can't immediately think of a POSIX-y way for Process A to prove its pid to Process B without involving the kernel.
[1] https://developer.apple.com/library/content/documentation/Da...
If they've gone that far, they may as well implement QNX messaging, which is known to work well. QNX has an entire POSIX implementation based on QNX's messaging system, so it's known to work. Plus it does hard real time.
The basic primitives work like a subroutine call. There's MsgSend (send and wait for reply), MsgReceive (wait for a request), and MsgReply (reply to a request). There's also MsgSendPulse (send a message, no reply, no wait) but it's seldom used. Messages are just arrays of bytes; the messaging system has no interest in content. Receivers can tell the process ID of the sender, so they can do security checks. All I/O is done through this mechanism; when you call "write()", the library does a MsgSend.
Services can give their endpoint a pathname, so callers can find them.
The call/reply approach makes the hard cases work right. If the receiver isn't there or has exited, the sender gets an error return. There's a timeout mechanism for sending; in QNX, anything that blocks can have a timeout. If a sender exits while waiting for a reply, that doesn't hurt the receiver. So the "cancellation" problem is solved. If you wan to do something else in a process while waiting for a reply, you can use more threads in the sender. On the receive side, you can have multiple threads taking requests via MsgReceive, handling the requests, and replying via MsgReply, so the system scales.
CPU scheduling is integrated with messaging. On a MsgSend, CPU control is usually transferred from sender to receiver immediately, without a pass through the scheduler. The sending thread blocks and the receiving thread unblocks.
With unidirectional messaging (Mach, etc.) and async systems, it's usually necessary to build some protocol on top of messaging to handle errors. It's easy to get stall situations. ("He didn't call back! He said he'd call back! He promised he'd call back!") There's also a scheduling problem - A sends to B but doesn't block, B unblocks, A waits on a pipe/queue for B and blocks, B sends to A and doesn't block, A unblocks. This usually results in several trips through the scheduler and bad scheduling behavior when there's heavy traffic.
There's years (decades, even) of success behind QNX messaging, yet people keep re-inventing the wheel and coming up with inferior designs.