Skip to content
Tech News
← Back to articles

IPC medley: message-queue peeking, io_uring, and bus1

read original get io_uring Toolkit → more articles
Why This Matters

This article highlights ongoing developments in Linux's IPC mechanisms, specifically enhancements to message queue APIs and the introduction of io_uring and bus1. These advancements aim to improve system performance, extensibility, and developer control, which are crucial for optimizing both consumer applications and the broader tech ecosystem.

Key Takeaways

Benefits for LWN subscribers The primary benefit from subscribing to LWN is helping to keep us publishing, but, beyond that, subscribers get immediate access to all site content and access to a number of extra site features. Please sign up today!

Peeking at message queues

The POSIX message-queue API is not heavily used, but there are users out there who care about how well it works. Message queues are named objects that, by default, all share a global namespace, though IPC namespaces can be used to separate them. There is a whole set of system calls for the creation, configuration, use, and destruction of message queues; see the mq_overview man page for an introduction to this subsystem.

Of interest here is mq_timedreceive() , which can be used to receive messages from a message queue:

ssize_t mq_timedreceive(size_t msg_len; mqd_t mqdes, char msg_ptr[msg_len], size_t msg_len, unsigned int *msg_prio, const struct timespec abs_timeout);

This call will receive the highest-priority message pending in the queue described by mqdes (which is a file descriptor on Linux systems) into the buffer pointed to by msg_ptr , which must be at least msg_len bytes in length. If abs_timeout is not null, it specifies how long the call should block before returning a timeout error. On successful receipt of a message, the location pointed to by msg_prio (if non-null) will be set to the priority of the received message.

That system call has a fair number of parameters, but Mathura Kumar would like to add some more. Since mq_timedreceive() was not designed for extensibility, that means adding a new system call. Thus, Kumar's patch set adding mq_timedreceive2() . But there is an additional constraint here: there are architecture-imposed limits on the number of arguments that can be passed to system calls, and Kumar's plans would exceed those limits. As a result, the new system call is defined as:

struct mq_timedreceive2_args { size_t msg_len; unsigned int *msg_prio; char *msg_ptr; }; ssize_t mq_timedreceive2(mqd_t mqdes, struct mq_timedreceive2_args *uargs, unsigned int flags, unsigned long index, const struct timespec *abs_timeout);

The msg_len , msg_prio , and msg_ptr arguments have been moved into the new mq_timedreceive2_args structure, freeing up two slots for new parameters to the system call. That structure is passed by pointer, without using the common pattern of passing its length, which would make future additions easier; that may change if this patch series moves forward.

The new arguments are flags and index . In this series, only one flag ( MQ_PEEK ) is defined; if it is present, the message will be returned as usual, but without removing it from the queue, meaning that it will still be there the next time a receive operation is performed. The index argument indicates which message is of interest; a value of zero will return the highest-priority message, and higher values will return messages further back in the queue.

... continue reading