============================== Named Message Queue Interfaces ============================== NuttX supports POSIX named message queues for inter-task communication. Any task may send or receive messages on named message queues. Interrupt handlers may send messages via named message queues. - :c:func:`mq_open` - :c:func:`mq_close` - :c:func:`mq_unlink` - :c:func:`mq_send` - :c:func:`mq_timedsend` - :c:func:`mq_receive` - :c:func:`mq_timedreceive` - :c:func:`mq_notify` - :c:func:`mq_setattr` - :c:func:`mq_getattr` .. c:function:: mqd_t mq_open(const char *mqName, int oflags, ...) Establishes a connection between a named message queue and the calling task. After a successful call of mq_open(), the task can reference the message queue using the address returned by the call. The message queue remains usable until it is closed by a successful call to mq_close(). :param mqName: Name of the queue to open :param oflags: Open flags. These may be any combination of: - ``O_RDONLY``. Open for read access. - ``O_WRONLY``. Open for write access. - ``O_RDWR``. Open for both read & write access. - ``O_CREAT``. Create message queue if it does not already exist. - ``O_EXCL``. Name must not exist when opened. - ``O_NONBLOCK``. Don't wait for data. :param ``...``: **Optional parameters**. When the O_CREAT flag is specified, POSIX requires that a third and fourth parameter be supplied: - ``mode``. The mode parameter is of type mode_t. In the POSIX specification, this mode value provides file permission bits for the message queue. This parameter is required but not used in the present implementation. - ``attr``. A pointer to an mq_attr that is provided to initialize. the message queue. If attr is NULL, then the messages queue is created with implementation-defined default message queue attributes. If attr is non-NULL, then the message queue mq_maxmsg attribute is set to the corresponding value when the queue is created. The mq_maxmsg attribute determines the maximum number of messages that can be queued before addition attempts to send messages on the message queue fail or cause the sender to block; the mq_msgsize attribute determines the maximum size of a message that can be sent or received. Other elements of attr are ignored (i.e, set to default message queue attributes). :return: A message queue descriptor or -1 (``ERROR``) **POSIX Compatibility:** Comparable to the POSIX interface of the same name. Differences from the full POSIX implementation include: - The mq_msgsize attributes determines the maximum size of a message that may be sent or received. In the present implementation, this maximum message size is limited at 22 bytes. .. c:function:: int mq_close(mqd_t mqdes) Used to indicate that the calling task is finished with the specified message queued ``mqdes``. The ``mq_close()`` deallocates any system resources allocated by the system for use by this task for its message queue. If the calling task has attached a notification request to the message queue via this ``mqdes`` (see ``mq_notify()``), this attachment will be removed and the message queue is available for another task to attach for notification. :param mqdes: Message queue descriptor. :return: 0 (``OK``) if the message queue is closed successfully, otherwise, -1 (``ERROR``). **Assumptions/Limitations:** - The behavior of a task that is blocked on either a ``mq_send()`` or ``mq_receive()`` is undefined when ``mq_close()`` is called. - The result of using this message queue descriptor after successful return from ``mq_close()`` is undefined. **POSIX Compatibility:** Comparable to the POSIX interface of the same name. .. c:function:: int mq_unlink(const char *mqName) Removes the message queue named by "mqName." If one or more tasks have the message queue open when ``mq_unlink()`` is called, removal of the message queue is postponed until all references to the message queue have been closed. :param mqName: Name of the message queue **POSIX Compatibility:** Comparable to the POSIX interface of the same name. .. c:function:: int mq_send(mqd_t mqdes, const void *msg, size_t msglen, int prio) Adds the specified message, ``msg``, to the message queue, ``mqdes``. The ``msglen`` parameter specifies the length of the message in bytes pointed to by ``msg``. This length must not exceed the maximum message length from the ``mq_getattr()``. If the message queue is not full, ``mq_send()`` will place the ``msg`` in the message queue at the position indicated by the ``prio`` argument. Messages with higher priority will be inserted before lower priority messages The value of ``prio`` must not exceed ``MQ_PRIO_MAX``. If the specified message queue is full and ``O_NONBLOCK`` is not set in the message queue, then ``mq_send()`` will block until space becomes available to the queue the message. If the message queue is full and ``NON_BLOCK`` is set, the message is not queued and ``ERROR`` is returned. **NOTE**: ``mq_send()`` may be called from an interrupt handler. However, it behaves differently when called from the interrupt level: - It does not check the size of the queue. It will always post the message, even if there are already too many messages in queue. This is because the interrupt handler does not have the option of waiting for the message queue to become non-full. - It doesn't allocate new memory (because you cannot allocate memory from an interrupt handler). Instead, there is a pool of pre-allocated message structures that may be used just for sending messages from interrupt handlers. The number of such pre-allocated messages is set by the ``PREALLOC_MQ_IRQ_MSGS`` configuration parameter. :param mqdes: Message queue descriptor. :param msg: Message to send. :param msglen: The length of the message in bytes. :param prio: The priority of the message. :return: On success, ``mq_send()`` returns 0 (``OK``); on error, -1 (``ERROR``) is returned, with ```errno`` <#ErrnoAccess>`__ set to indicate the error: - ``EAGAIN``. The queue was empty, and the ``O_NONBLOCK`` flag was set for the message queue description referred to by ``mqdes``. - ``EINVAL``. Either ``msg`` or ``mqdes`` is ``NULL`` or the value of ``prio`` is invalid. - ``EPERM``. Message queue opened not opened for writing. - ``EMSGSIZE``. ``msglen`` was greater than the ``maxmsgsize`` attribute of the message queue. - ``EINTR``. The call was interrupted by a signal handler. **POSIX Compatibility:** Comparable to the POSIX interface of the same name. .. c:function:: int mq_timedsend(mqd_t mqdes, const char *msg, size_t msglen, int prio, \ const struct timespec *abstime); Adds the specified message, ``msg``, to the message queue, ``mqdes``. The ``msglen`` parameter specifies the length of the message in bytes pointed to by ``msg``. This length must not exceed the maximum message length from the ``mq_getattr()``. If the message queue is not full, ``mq_timedsend()`` will place the ``msg`` in the message queue at the position indicated by the ``prio`` argument. Messages with higher priority will be inserted before lower priority messages The value of ``prio`` must not exceed ``MQ_PRIO_MAX``. If the specified message queue is full and ``O_NONBLOCK`` is not set in the message queue, then ``mq_send()`` will block until space becomes available to the queue the message or until a timeout occurs. ``mq_timedsend()`` behaves just like ``mq_send()``, except that if the queue is full and the ``O_NONBLOCK`` flag is not enabled for the message queue description, then ``abstime`` points to a structure which specifies a ceiling on the time for which the call will block. This ceiling is an absolute timeout in seconds and nanoseconds since the Epoch (midnight on the morning of 1 January 1970). If the message queue is full, and the timeout has already expired by the time of the call, ``mq_timedsend()`` returns immediately. :param mqdes: Message queue descriptor. :param msg: Message to send. :param msglen: The length of the message in bytes. :param prio: The priority of the message. :return: On success, ``mq_send()`` returns 0 (``OK``); on error, -1 (``ERROR``) is returned, with ```errno`` <#ErrnoAccess>`__ set to indicate the error: - ``EAGAIN``. The queue was empty, and the ``O_NONBLOCK`` flag was set for the message queue description referred to by ``mqdes``. - ``EINVAL``. Either ``msg`` or ``mqdes`` is ``NULL`` or the value of ``prio`` is invalid. - ``EPERM``. Message queue opened not opened for writing. - ``EMSGSIZE``. ``msglen`` was greater than the ``maxmsgsize`` attribute of the message queue. - ``EINTR``. The call was interrupted by a signal handler. **POSIX Compatibility:** Comparable to the POSIX interface of the same name. .. c:function:: ssize_t mq_receive(mqd_t mqdes, void *msg, size_t msglen, int *prio) Receives the oldest of the highest priority messages from the message queue specified by ``mqdes``. If the size of the buffer in bytes, ``msgLen``, is less than the ``mq_msgsize`` attribute of the message queue, ``mq_receive()`` will return an error. Otherwise, the selected message is removed from the queue and copied to ``msg``. If the message queue is empty and ``O_NONBLOCK`` was not set, ``mq_receive()`` will block until a message is added to the message queue. If more than one task is waiting to receive a message, only the task with the highest priority that has waited the longest will be unblocked. If the queue is empty and ``O_NONBLOCK`` is set, ``ERROR`` will be returned. :param mqdes: Message Queue Descriptor. :param msg: Buffer to receive the message. :param msglen: Size of the buffer in bytes. :param prio: If not NULL, the location to store message priority. :return: On success, the length of the selected message in bytes is returned. On failure, -1 (``ERROR``) is returned and the ```errno`` <#ErrnoAccess>`__ is set appropriately: - ``EAGAIN`` The queue was empty and the ``O_NONBLOCK`` flag was set for the message queue description referred to by ``mqdes``. - ``EPERM`` Message queue opened not opened for reading. - ``EMSGSIZE`` ``msglen`` was less than the ``maxmsgsize`` attribute of the message queue. - ``EINTR`` The call was interrupted by a signal handler. - ``EINVAL`` Invalid ``msg`` or ``mqdes`` **POSIX Compatibility:** Comparable to the POSIX interface of the same name. .. c:function:: ssize_t mq_timedreceive(mqd_t mqdes, void *msg, size_t msglen, \ int *prio, const struct timespec *abstime); Receives the oldest of the highest priority messages from the message queue specified by ``mqdes``. If the size of the buffer in bytes, ``msgLen``, is less than the ``mq_msgsize`` attribute of the message queue, ``mq_timedreceive()`` will return an error. Otherwise, the selected message is removed from the queue and copied to ``msg``. If the message queue is empty and ``O_NONBLOCK`` was not set, ``mq_timedreceive()`` will block until a message is added to the message queue (or until a timeout occurs). If more than one task is waiting to receive a message, only the task with the highest priority that has waited the longest will be unblocked. ``mq_timedreceive()`` behaves just like ``mq_receive()``, except that if the queue is empty and the ``O_NONBLOCK`` flag is not enabled for the message queue description, then ``abstime`` points to a structure which specifies a ceiling on the time for which the call will block. This ceiling is an absolute timeout in seconds and nanoseconds since the Epoch (midnight on the morning of 1 January 1970). If no message is available, and the timeout has already expired by the time of the call, ``mq_timedreceive()`` returns immediately. :param mqdes: Message Queue Descriptor. :param msg: Buffer to receive the message. :param msglen: Size of the buffer in bytes. :param prio: If not NULL, the location to store message priority. :param abstime: The absolute time to wait until a timeout is declared. :return: On success, the length of the selected message in bytes is returned. On failure, -1 (``ERROR``) is returned and the ```errno`` <#ErrnoAccess>`__ is set appropriately: - ``EAGAIN``: The queue was empty and the ``O_NONBLOCK`` flag was set for the message queue description referred to by ``mqdes``. - ``EPERM``: Message queue opened not opened for reading. - ``EMSGSIZE``: ``msglen`` was less than the ``maxmsgsize`` attribute of the message queue. - ``EINTR``: The call was interrupted by a signal handler. - ``EINVAL``: Invalid ``msg`` or ``mqdes`` or ``abstime`` - ``ETIMEDOUT``: The call timed out before a message could be transferred. **POSIX Compatibility:** Comparable to the POSIX interface of the same name. .. c:function:: int mq_notify(mqd_t mqdes, FAR const struct sigevent *notification) If the ``notification`` input parameter is not ``NULL``, this function connects the task with the message queue such that the specified signal will be sent to the task whenever the message queue changes from empty to non-empty. One notification can be attached to a message queue. If ``notification``; is ``NULL``, the attached notification is detached (if it was held by the calling task) and the queue is available to attach another notification. When the notification is sent to the registered task, its registration will be removed. The message queue will then be available for registration. :param mqdes: Message queue descriptor :param notification: Real-time signal structure containing: - ``sigev_notify``. Should be SIGEV_SIGNAL (but actually ignored) - ``sigev_signo``. The signo to use for the notification - ``sigev_value``. Value associated with the signal :return: On success ``mq_notify()`` returns 0; on error, -1 is returned, with ``errno`` set to indicate the error: - ``EBADF``. The descriptor specified in ``mqdes`` is invalid. - ``EBUSY``. Another process has already registered to receive notification for this message queue. - ``EINVAL``. ``sevp->sigev_notify`` is not one of the permitted values; or ``sevp->sigev_notify`` is ``SIGEV_SIGNAL`` and ``sevp->sigev_signo`` is not a valid signal number. - ``ENOMEM``. Insufficient memory. **POSIX Compatibility:** Comparable to the POSIX interface of the same name. Differences from the full POSIX implementation include: - The notification signal will be sent to the registered task even if another task is waiting for the message queue to become non-empty. This is inconsistent with the POSIX specification which states, "If a process has registered for notification of message arrival at a message queue and some process is blocked in ``mq_receive`` waiting to receive a message when a message arrives at the queue, the arriving message will satisfy the appropriate ``mq_receive()`` ... The resulting behavior is as if the message queue remains empty, and no notification will be sent." .. c:function:: int mq_setattr(mqd_t mqdes, const struct mq_attr *mqStat, \ struct mq_attr *oldMqStat); Sets the attributes associated with the specified message queue "mqdes." Only the "O_NONBLOCK" bit of the "mq_flags" can be changed. If ``oldMqStat`` is non-null, mq_setattr() will store the previous message queue attributes at that location (just as would have been returned by mq_getattr()). :param mqdes: Message queue descriptor :param mqStat: New attributes :param oldMqState: Old attributes :return: 0 (``OK``) if attributes are set successfully, otherwise -1 (``ERROR``). **POSIX Compatibility:** Comparable to the POSIX interface of the same name. .. c:function:: int mq_getattr(mqd_t mqdes, struct mq_attr *mqStat) Gets status information and attributes associated with the specified message queue. :param mqdes: Message queue descriptor :param mqStat: Buffer in which to return attributes. The returned attributes include: - ``mq_maxmsg``. Max number of messages in queue. - ``mq_msgsize``. Max message size. - ``mq_flags``. Queue flags. - ``mq_curmsgs``. Number of messages currently in queue. :return: 0 (``OK``) if attributes provided, -1 (``ERROR``) otherwise. **POSIX Compatibility:** Comparable to the POSIX interface of the same name.