Message Queue

https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/mqueue.h.html

Defines

MQ_PRIO_MAX (32u)

Priority levels; valid msg_prio is [0, MQ_PRIO_MAX-1].

Typedefs

typedef void *mqd_t

Message queue descriptor.

Functions

mqd_t mq_open(const char *name, int oflag, mode_t mode, struct mq_attr *attr)

Open an existing message queue or create a new one, returning a descriptor for subsequent send and receive operations.

Queues are looked up by name and allocated on demand from the kernel heap. A new queue uses a default attribute set (10 messages of 256 bytes) when attr is NULL. Storage for all mq_maxmsg messages is reserved when the queue is created, so a call with attributes within the ranges below can still fail with ENOMEM. A failed call allocates nothing.

Error numbers:

  • EINVAL if the name is NULL.

  • EINVAL if the oflag is invalid.

  • EINVAL if O_CREAT is specified, attr is not NULL, and mq_maxmsg is outside [1, 255] or mq_msgsize is outside [1, 16777215].

  • ENAMETOOLONG if O_CREAT is specified and the name is longer than 16 characters. Without O_CREAT such a name reports ENOENT.

  • EEXIST if the queue exists and both O_CREAT and O_EXCL are specified.

  • ENOMEM if there is insufficient memory for the descriptor, message queue, or name.

  • ENOENT if the queue does not exist and O_CREAT is not specified.

Note

Name resolution is O(N) in the number of message queues that currently exist. This is a setup-time operation and is NOT part of the kernel’s O(1) operational guarantee. The operational calls - mq_send(), mq_receive(), mq_getattr(), mq_close() - are O(1), independent of the number of queues or threads in the system.

Parameters:
  • name – Name of the message queue.

  • oflag – One of the access mode flags:

    • O_RDONLY : Open the queue to receive messages only.

    • O_WRONLY : Open the queue to send messages only.

    • O_RDWR : Open the queue for reading and writing. And optionally OR’ed with:

    • O_CREAT : Create the queue if it does not exist.

    • O_EXCL : If O_CREAT is also specified, and a queue with the given name already exists, then mq_open() will fail.

    • O_NONBLOCK : Open this descriptor in non-blocking mode.

  • mode – Not supported.

  • attr – Attributes of a new queue; only mq_maxmsg and mq_msgsize are used. NULL for default attributes.

Returns:

mqd_t Message queue descriptor on success, (mqd_t)-1 on error and errno set.

void *producer(void *arg)
{
    struct mq_attr attr  = { .mq_maxmsg  = 8,
                             .mq_msgsize = sizeof(uint32_t) };
    uint32_t       value = 0u;
    mqd_t          mq;

    (void)arg;
    mq = mq_open("/data", O_CREAT | O_WRONLY, 0, &attr);
    if (mq != (mqd_t)-1)
    {
        for (;;)
        {
            value++;
            (void)mq_send(mq, (const char *)&value, sizeof(value), 0u);
        }
    }
    return NULL;
}

int mq_notify(mqd_t mqdes, const struct sigevent *notification)

Not supported.

Returns:

-1 and sets errno to ENOSYS.

int mq_setattr(mqd_t mqdes, const struct mq_attr *mqstat, struct mq_attr *omqstat)

Update the per-descriptor flags of an open message queue.

Only the O_NONBLOCK bit of mq_flags is honored; the other fields of mqstat are ignored. The change applies to mqdes only, not to other descriptors of the same queue. When omqstat is non-NULL it receives the attributes as mq_getattr() reported them before the update, so its mq_flags is the descriptor’s previous O_NONBLOCK setting.

Error numbers:

  • EBADF if the descriptor is invalid.

  • EINVAL if mqstat is NULL.

Parameters:
  • mqdes – Message queue descriptor.

  • mqstat – New message queue attributes.

  • omqstat – Old message queue attributes.

Returns:

0 on success, -1 on error and errno set.

int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat)

Copy the attributes of an open message queue into mqstat.

mq_maxmsg, mq_msgsize and mq_curmsgs are those of the queue. mq_flags is that of the descriptor: O_NONBLOCK when mqdes is non-blocking (set by mq_open() or mq_setattr()) and 0 otherwise. No other flag is reported.

Error numbers:

  • EBADF if the descriptor is invalid.

  • EINVAL if mqstat is NULL.

Parameters:
  • mqdes – Message queue descriptor.

  • mqstat – Message queue attributes.

Returns:

0 on success, -1 on error and errno set.

int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio)

Append a message to a queue, waiting indefinitely if the queue is full and the descriptor is in blocking mode.

Equivalent to mq_timedsend() with a NULL deadline. When QRT_CFG_DEFER_ENABLE is enabled the call may also be made from a deferred function or a timer callback (see qrt_defer_call()), on a descriptor with O_NONBLOCK set.

Error numbers:

  • EAGAIN if the queue is full and O_NONBLOCK is set.

  • EINVAL if msg_ptr is NULL.

  • EINVAL if msg_prio is not less than MQ_PRIO_MAX.

  • EMSGSIZE if msg_len is 0 or exceeds the queue’s message size.

  • EBADF if the descriptor is invalid or not opened for writing, or the call is made from a deferred function or a timer callback without O_NONBLOCK set (a debug build asserts instead).

Parameters:
  • mqdes – Message queue descriptor.

  • msg_ptr – Pointer to the message to be sent.

  • msg_len – Length of the message.

  • msg_prio – Message priority in [0, MQ_PRIO_MAX-1]. Higher-priority messages are received first; equal priorities stay FIFO.

Returns:

0 on success, -1 on error and errno set.

int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio, const struct timespec *abstime)

Append a message to a queue, waiting at most until abstime (CLOCK_REALTIME) when the queue is full.

If the descriptor has O_NONBLOCK set the call never blocks regardless of abstime. When QRT_CFG_DEFER_ENABLE is enabled the call may also be made from a deferred function or a timer callback (see qrt_defer_call()), on a descriptor with O_NONBLOCK set. This and mq_send() are the only message queue services available there.

Error numbers:

  • EAGAIN if the queue is full and O_NONBLOCK is set.

  • EINVAL if msg_ptr is NULL.

  • EINVAL if msg_prio is not less than MQ_PRIO_MAX.

  • EINVAL if the thread would have to wait and abstime has nanoseconds outside [0, 999’999’999].

  • EMSGSIZE if msg_len is 0 or exceeds the queue’s message size.

  • EBADF if the descriptor is invalid or not opened for writing, or the call is made from a deferred function or a timer callback without O_NONBLOCK set (a debug build asserts instead).

  • ETIMEDOUT if the queue is full and abstime has passed (negative seconds lie before the epoch, and {0, 0} is the epoch), or passes before a slot frees.

Parameters:
  • mqdes – Message queue descriptor.

  • msg_ptr – Pointer to the message to be sent.

  • msg_len – Length of the message.

  • msg_prio – Message priority in [0, MQ_PRIO_MAX-1]. Higher-priority messages are received first; equal priorities stay FIFO.

  • abstime – Pointer to the absolute time (CLOCK_REALTIME) to wait until when the queue is full.

Returns:

0 on success, -1 on error and errno set.

ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio)

Remove the highest-priority message (the oldest of equal priority) from a queue, waiting indefinitely if it is empty and the descriptor is in blocking mode.

Equivalent to mq_timedreceive() with a NULL deadline, so the call must likewise be made from a thread.

Error numbers:

  • EAGAIN if the queue is empty and O_NONBLOCK is set.

  • EINVAL if msg_ptr is NULL.

  • EMSGSIZE if msg_len is smaller than the queue’s message size.

  • EBADF if the descriptor is invalid or not opened for reading.

Parameters:
  • mqdes – Message queue descriptor.

  • msg_ptr – Pointer to the buffer that will receive the message.

  • msg_len – Size of the receive buffer.

  • msg_prio – If non-NULL, set to the priority of the received message.

Returns:

Message length in bytes on success, -1 on error and errno set.

ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio, const struct timespec *abstime)

Remove the highest-priority message (the oldest of equal priority) from a queue, waiting at most until abstime (CLOCK_REALTIME) when the queue is empty.

If the descriptor has O_NONBLOCK set the call never blocks regardless of abstime. Unlike mq_timedsend(), the call must be made from a thread, never from a deferred function or a timer callback, even on a descriptor with O_NONBLOCK set.

Error numbers:

  • EAGAIN if the queue is empty and O_NONBLOCK is set.

  • EINVAL if msg_ptr is NULL.

  • EINVAL if the thread would have to wait and abstime has nanoseconds outside [0, 999’999’999].

  • EMSGSIZE if msg_len is smaller than the queue’s message size.

  • EBADF if the descriptor is invalid or not opened for reading.

  • ETIMEDOUT if the queue is empty and abstime has passed (negative seconds lie before the epoch, and {0, 0} is the epoch), or passes before a message arrives.

Parameters:
  • mqdes – Message queue descriptor.

  • msg_ptr – Pointer to the buffer that will receive the message.

  • msg_len – Size of the receive buffer.

  • msg_prio – If non-NULL, set to the priority of the received message.

  • abstime – Pointer to the absolute time (CLOCK_REALTIME) to wait until when the queue is empty.

Returns:

Message length in bytes on success, -1 on error and errno set.

static uint32_t     total;
static unsigned int timeouts;

void *consumer(void *arg)
{
    struct timespec deadline;
    uint32_t        value;
    mqd_t           mq;

    (void)arg;
    mq = mq_open("/data", O_RDONLY, 0, NULL);
    if (mq != (mqd_t)-1)
    {
        for (;;)
        {
            (void)clock_gettime(CLOCK_REALTIME, &deadline);
            deadline.tv_sec += 1;

            if (mq_timedreceive(mq, (char *)&value, sizeof(value),
                                NULL, &deadline) > 0)
            {
                total += value;
            }
            else if (errno == ETIMEDOUT)
            {
                timeouts++;
            }
        }
    }
    return NULL;
}

Remove a message queue’s name from the registry, deferring deletion until the last descriptor is closed.

If no descriptors remain at the time of the call the queue and its backing memory are released immediately; otherwise the queue is marked unlinked and destroyed when mq_close() drops the last reference. Until then the descriptors still open keep working as before, and the unlink does not change the attributes mq_getattr() reports for them.

Error numbers:

  • EINVAL if name is NULL.

  • ENAMETOOLONG if name is longer than 16 characters.

  • ENOENT if the message queue does not exist.

Parameters:
  • name – Name of the message queue.

Returns:

0 on success, -1 on error and errno set.

int mq_close(mqd_t mqdes)

Drop a descriptor and, if it was the last reference to an unlinked queue, release the queue itself.

Error numbers:

  • EBADF if the descriptor is invalid.

Parameters:
  • mqdes – Message queue descriptor.

Returns:

0 on success, -1 on error and errno set.

struct mq_attr
#include <mqueue.h>

Message queue attributes.

Public Members

long mq_flags

Message queue flags.

long mq_maxmsg

Maximum number of messages.

long mq_msgsize

Maximum message size.

long mq_curmsgs

Number of messages currently queued.