| ============================== |
| 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_timedsend()`` 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 full, 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. |