summaryrefslogtreecommitdiffstats
path: root/posix_users/message_passing.rst
diff options
context:
space:
mode:
Diffstat (limited to 'posix_users/message_passing.rst')
-rw-r--r--posix_users/message_passing.rst665
1 files changed, 665 insertions, 0 deletions
diff --git a/posix_users/message_passing.rst b/posix_users/message_passing.rst
new file mode 100644
index 0000000..6192587
--- /dev/null
+++ b/posix_users/message_passing.rst
@@ -0,0 +1,665 @@
+Message Passing Manager
+#######################
+
+Introduction
+============
+
+The message passing manager is the means to provide communication and
+synchronization capabilities using POSIX message queues.
+
+The directives provided by the message passing manager are:
+
+- ``mq_open`` - Open a Message Queue
+
+- ``mq_close`` - Close a Message Queue
+
+- ``mq_unlink`` - Remove a Message Queue
+
+- ``mq_send`` - Send a Message to a Message Queue
+
+- ``mq_receive`` - Receive a Message from a Message Queue
+
+- ``mq_notify`` - Notify Process that a Message is Available
+
+- ``mq_setattr`` - Set Message Queue Attributes
+
+- ``mq_getattr`` - Get Message Queue Attributes
+
+Background
+==========
+
+Theory
+------
+
+Message queues are named objects that operate with readers and writers.
+In addition, a message queue is a priority queue of discrete messages.
+POSIX message queues offer a certain, basic amount of application access
+to, and control over, the message queue geometry that can be changed.
+
+Messages
+--------
+
+A message is a variable length buffer where information can be stored to
+support communication. The length of the message and the information
+stored in that message are user-defined and can be actual data,
+pointer(s), or empty. There is a maximum acceptable length for a message
+that is associated with each message queue.
+
+Message Queues
+--------------
+
+Message queues are named objects similar to the pipes of POSIX. They are
+a means of communicating data between multiple processes and for passing
+messages among tasks and ISRs. Message queues can contain a variable
+number of messages from 0 to an upper limit that is user defined. The
+maximum length of the message can be set on a per message queue basis.
+Normally messages are sent and received from the message queue in FIFO
+order. However, messages can also be prioritized and a priority queue
+established for the passing of messages. Synchronization is needed when a
+task waits for a message to arrive at a queue. Also, a task may poll a
+queue for the arrival of a message... index:: mqd_t
+
+The message queue descriptor ``mqd_t`` represents the message queue. It is
+passed as an argument to all of the message queue functions.
+
+Building a Message Queue Attribute Set
+--------------------------------------
+
+The mq_attr structure is used to define the characteristics of the message
+queue... index:: mq_attr
+
+.. code:: c
+
+ typedef struct mq_attr{
+ long mq_flags;
+ long mq_maxmsg;
+ long mq_msgsize;
+ long mq_curmsgs;
+ };
+
+All of these attributes are set when the message queue is created using
+mq_open. The mq_flags field is not used in the creation of a message
+queue, it is only used by mq_setattr and mq_getattr. The structure
+mq_attr is passed as an argument to mq_setattr and mq_getattr.
+
+The mq_flags contain information affecting the behavior of the message
+queue. The O_NONBLOCK mq_flag is the only flag that is defined. In
+mq_setattr, the mq_flag can be set to dynamically change the blocking and
+non-blocking behavior of the message queue. If the non-block flag is set
+then the message queue is non-blocking, and requests to send and receive
+messages do not block waiting for resources. For a blocking message
+queue, a request to send might have to wait for an empty message queue,
+and a request to receive might have to wait for a message to arrive on the
+queue. Both mq_maxmsg and mq_msgsize affect the sizing of the message
+queue. mq_maxmsg specifies how many messages the queue can hold at any
+one time. mq_msgsize specifies the size of any one message on the queue.
+If either of these limits is exceeded, an error message results.
+
+Upon return from mq_getattr, the mq_curmsgs is set according to the
+current state of the message queue. This specifies the number of messages
+currently on the queue.
+
+Notification of a Message on the Queue
+--------------------------------------
+
+Every message queue has the ability to notify one (and only one) process
+whenever the queue’s state changes from empty (0 messages) to nonempty.
+This means that the process does not have to block or constantly poll
+while it waits for a message. By calling mq_notify, you can attach a
+notification request to a message queue. When a message is received by an
+empty queue, if there are no processes blocked and waiting for the
+message, then the queue notifies the requesting process of a message
+arrival. There is only one signal sent by the message queue, after that
+the notification request is de-registered and another process can attach
+its notification request. After receipt of a notification, a process must
+re-register if it wishes to be notified again.
+
+If there is a process blocked and waiting for the message, that process
+gets the message, and notification is not sent. It is also possible for
+another process to receive the message after the notification is sent but
+before the notified process has sent its receive request.
+
+Only one process can have a notification request attached to a message
+queue at any one time. If another process attempts to register a
+notification request, it fails. You can de-register for a message queue
+by passing a NULL to mq_notify, this removes any notification request
+attached to the queue. Whenever the message queue is closed, all
+notification attachments are removed.
+
+POSIX Interpretation Issues
+---------------------------
+
+There is one significant point of interpretation related to
+the RTEMS implementation of POSIX message queues:
+
+*What happens to threads already blocked on a message queue when the
+mode of that same message queue is changed from blocking to non-blocking?*
+
+The RTEMS POSIX implementation decided to unblock all waiting tasks
+with an ``EAGAIN`` status just as if a non-blocking version of
+the same operation had returned unsatisfied. This case is not
+discussed in the POSIX standard and other implementations may have
+chosen alternative behaviors.
+
+Operations
+==========
+
+Opening or Creating a Message Queue
+-----------------------------------
+
+If the message queue already exists, mq_open() opens it, if the message
+queue does not exist, mq_open() creates it. When a message queue is
+created, the geometry of the message queue is contained in the attribute
+structure that is passed in as an argument. This includes mq_msgsize that
+dictates the maximum size of a single message, and the mq_maxmsg that
+dictates the maximum number of messages the queue can hold at one time.
+The blocking or non-blocking behavior of the queue can also specified.
+
+Closing a Message Queue
+-----------------------
+
+The mq_close() function is used to close the connection made to a message
+queue that was made during mq_open. The message queue itself and the
+messages on the queue are persistent and remain after the queue is closed.
+
+Removing a Message Queue
+------------------------
+
+The mq_unlink() function removes the named message queue. If the message
+queue is not open when mq_unlink is called, then the queue is immediately
+eliminated. Any messages that were on the queue are lost, and the queue
+can not be opened again. If processes have the queue open when mq_unlink
+is called, the removal of the queue is delayed until the last process
+using the queue has finished. However, the name of the message queue is
+removed so that no other process can open it.
+
+Sending a Message to a Message Queue
+------------------------------------
+
+The mq_send() function adds the message in priority order to the message
+queue. Each message has an assigned a priority. The highest priority
+message is be at the front of the queue.
+
+The maximum number of messages that a message queue may accept is
+specified at creation by the mq_maxmsg field of the attribute structure.
+If this amount is exceeded, the behavior of the process is determined
+according to what oflag was used when the message queue was opened. If
+the queue was opened with O_NONBLOCK flag set, the process does not block,
+and an error is returned. If the O_NONBLOCK flag was not set, the process
+does block and wait for space on the queue.
+
+Receiving a Message from a Message Queue
+----------------------------------------
+
+The mq_receive() function is used to receive the oldest of the highest
+priority message(s) from the message queue specified by mqdes. The
+messages are received in FIFO order within the priorities. The received
+message’s priority is stored in the location referenced by the msg_prio.
+If the msg_prio is a NULL, the priority is discarded. The message is
+removed and stored in an area pointed to by msg_ptr whose length is of
+msg_len. The msg_len must be at least equal to the mq_msgsize attribute
+of the message queue.
+
+The blocking behavior of the message queue is set by O_NONBLOCK at mq_open
+or by setting O_NONBLOCK in mq_flags in a call to mq_setattr. If this is
+a blocking queue, the process does block and wait on an empty queue. If
+this a non-blocking queue, the process does not block. Upon successful
+completion, mq_receive returns the length of the selected message in bytes
+and the message is removed from the queue.
+
+Notification of Receipt of a Message on an Empty Queue
+------------------------------------------------------
+
+The mq_notify() function registers the calling process to be notified of
+message arrival at an empty message queue. Every message queue has the
+ability to notify one (and only one) process whenever the queue’s state
+changes from empty (0 messages) to nonempty. This means that the process
+does not have to block or constantly poll while it waits for a message.
+By calling mq_notify, a notification request is attached to a message
+queue. When a message is received by an empty queue, if there are no
+processes blocked and waiting for the message, then the queue notifies the
+requesting process of a message arrival. There is only one signal sent by
+the message queue, after that the notification request is de-registered
+and another process can attach its notification request. After receipt of
+a notification, a process must re-register if it wishes to be notified
+again.
+
+If there is a process blocked and waiting for the message, that process
+gets the message, and notification is not sent. Only one process can have
+a notification request attached to a message queue at any one time. If
+another process attempts to register a notification request, it fails.
+You can de-register for a message queue by passing a NULL to mq_notify,
+this removes any notification request attached to the queue. Whenever the
+message queue is closed, all notification attachments are removed.
+
+Setting the Attributes of a Message Queue
+-----------------------------------------
+
+The mq_setattr() function is used to set attributes associated with the
+open message queue description referenced by the message queue descriptor
+specified by mqdes. The \*omqstat represents the old or previous
+attributes. If omqstat is non-NULL, the function mq_setattr() stores, in
+the location referenced by omqstat, the previous message queue attributes
+and the current queue status. These values are the same as would be
+returned by a call to mq_getattr() at that point.
+
+There is only one mq_attr.mq_flag that can be altered by this call. This
+is the flag that deals with the blocking and non-blocking behavior of the
+message queue. If the flag is set then the message queue is non-blocking,
+and requests to send or receive do not block while waiting for resources.
+If the flag is not set, then message send and receive may involve waiting
+for an empty queue or waiting for a message to arrive.
+
+Getting the Attributes of a Message Queue
+-----------------------------------------
+
+The mq_getattr() function is used to get status information and attributes
+of the message queue associated with the message queue descriptor. The
+results are returned in the mq_attr structure referenced by the mqstat
+argument. All of these attributes are set at create time, except the
+blocking/non-blocking behavior of the message queue which can be
+dynamically set by using mq_setattr. The attribute mq_curmsg is set to
+reflect the number of messages on the queue at the time that mq_getattr
+was called.
+
+Directives
+==========
+
+This section details the message passing manager’s directives. A
+subsection is dedicated to each of this manager’s directives and describes
+the calling sequence, related constants, usage, and status codes.
+
+mq_open - Open a Message Queue
+------------------------------
+.. index:: mq_open
+.. index:: open a message queue
+
+**CALLING SEQUENCE:**
+
+.. code:: c
+
+ #include <mqueue.h>
+ mqd_t mq_open(
+ const char \*name,
+ int oflag,
+ mode_t mode,
+ struct mq_attr \*attr
+ );
+
+**STATUS CODES:**
+
+``EACCES`` - Either the message queue exists and the permissions
+requested in oflags were denied, or the message does not exist and
+permission to create one is denied.
+
+``EEXIST`` - You tried to create a message queue that already exists.
+
+``EINVAL`` - An inappropriate name was given for the message queue, or
+the values of mq-maxmsg or mq_msgsize were less than 0.
+
+``ENOENT`` - The message queue does not exist, and you did not specify
+to create it.
+
+``EINTR`` - The call to mq_open was interrupted by a signal.
+
+``EMFILE`` - The process has too many files or message queues open.
+This is a process limit error.
+
+``ENFILE`` - The system has run out of resources to support more open
+message queues. This is a system error.
+
+``ENAMETOOLONG`` - mq_name is too long.
+
+**DESCRIPTION:**
+
+The mq_open () function establishes the connection between a process and a
+message queue with a message queue descriptor. If the message queue
+already exists, mq_open opens it, if the message queue does not exist,
+mq_open creates it. Message queues can have multiple senders and
+receivers. If mq_open is successful, the function returns a message queue
+descriptor. Otherwise, the function returns a -1 and sets ’errno’ to
+indicate the error.
+
+The name of the message queue is used as an argument. For the best of
+portability, the name of the message queue should begin with a "/" and no
+other "/" should be in the name. Different systems interpret the name in
+different ways.
+
+The oflags contain information on how the message is opened if the queue
+already exists. This may be O_RDONLY for read only, O_WRONLY for write
+only, of O_RDWR, for read and write.
+
+In addition, the oflags contain information needed in the creation of a
+message queue. ``O_NONBLOCK`` - If the non-block flag is set then the
+message queue is non-blocking, and requests to send and receive messages
+do not block waiting for resources. If the flag is not set then the
+message queue is blocking, and a request to send might have to wait for an
+empty message queue. Similarly, a request to receive might have to wait
+for a message to arrive on the queue. ``O_CREAT`` - This call specifies
+that the call the mq_open is to create a new message queue. In this case
+the mode and attribute arguments of the function call are utilized. The
+message queue is created with a mode similar to the creation of a file,
+read and write permission creator, group, and others.
+
+The geometry of the message queue is contained in the attribute structure.
+This includes mq_msgsize that dictates the maximum size of a single
+message, and the mq_maxmsg that dictates the maximum number of messages
+the queue can hold at one time. If a NULL is used in the mq_attr
+argument, then the message queue is created with implementation defined
+defaults. ``O_EXCL`` - is always set if O_CREAT flag is set. If the
+message queue already exists, O_EXCL causes an error message to be
+returned, otherwise, the new message queue fails and appends to the
+existing one.
+
+**NOTES:**
+
+The mq_open () function does not add or remove messages from the queue.
+When a new message queue is being created, the mq_flag field of the
+attribute structure is not used.
+
+mq_close - Close a Message Queue
+--------------------------------
+.. index:: mq_close
+.. index:: close a message queue
+
+**CALLING SEQUENCE:**
+
+.. code:: c
+
+ #include <mqueue.h>
+ int mq_close(
+ mqd_t mqdes
+ );
+
+**STATUS CODES:**
+
+``EINVAL`` - The descriptor does not represent a valid open message
+queue
+
+**DESCRIPTION:**
+
+The mq_close function removes the association between the message queue
+descriptor, mqdes, and its message queue. If mq_close() is successfully
+completed, the function returns a value of zero; otherwise, the function
+returns a value of -1 and sets errno to indicate the error.
+
+**NOTES:**
+
+If the process had successfully attached a notification request to the
+message queue via mq_notify, this attachment is removed, and the message
+queue is available for another process to attach for notification.
+mq_close has no effect on the contents of the message queue, all the
+messages that were in the queue remain in the queue.
+
+mq_unlink - Remove a Message Queue
+----------------------------------
+.. index:: mq_unlink
+.. index:: remove a message queue
+
+**CALLING SEQUENCE:**
+
+.. code:: c
+
+ #include <mqueue.h>
+ int mq_unlink(
+ const char \*name
+ );
+
+**STATUS CODES:**
+
+``EINVAL`` - The descriptor does not represent a valid message queue
+
+**DESCRIPTION:**
+
+The mq_unlink() function removes the named message queue. If the message
+queue is not open when mq_unlink is called, then the queue is immediately
+eliminated. Any messages that were on the queue are lost, and the queue
+can not be opened again. If processes have the queue open when mq_unlink
+is called, the removal of the queue is delayed until the last process
+using the queue has finished. However, the name of the message queue is
+removed so that no other process can open it. Upon successful completion,
+the function returns a value of zero. Otherwise, the named message queue
+is not changed by this function call, and the function returns a value of
+-1 and sets errno to indicate the error.
+
+**NOTES:**
+
+Calls to mq_open() to re-create the message queue may fail until the
+message queue is actually removed. However, the mq_unlink() call need not
+block until all references have been closed; it may return immediately.
+
+mq_send - Send a Message to a Message Queue
+-------------------------------------------
+.. index:: mq_send
+.. index:: send a message to a message queue
+
+**CALLING SEQUENCE:**
+
+.. code:: c
+
+ #include<mqueue.h>
+ int mq_send(
+ mqd_t mqdes,
+ const char \*msg_ptr,
+ size_t msg_len,
+ unsigned int msg_prio
+ );
+
+**STATUS CODES:**
+
+``EBADF`` - The descriptor does not represent a valid message queue, or the queue was opened for read only O_RDONLY``EINVAL`` - The value of msg_prio was greater than the MQ_PRIO_MAX.``EMSGSIZE`` - The msg_len is greater than the mq_msgsize attribute of the message queue``EAGAIN`` - The message queue is non-blocking, and there is no room on the queue for another message as specified by the mq_maxmsg.``EINTR`` - The message queue is blocking. While the process was waiting for free space on the queue, a signal arrived that interrupted the wait.
+
+**DESCRIPTION:**
+
+The mq_send() function adds the message pointed to by the argument msg_ptr
+to the message queue specified by mqdes. Each message is assigned a
+priority , from 0 to MQ_PRIO_MAX. MQ_PRIO_MAX is defined in <limits.h> and
+must be at least 32. Messages are added to the queue in order of their
+priority. The highest priority message is at the front of the queue.
+
+The maximum number of messages that a message queue may accept is
+specified at creation by the mq_maxmsg field of the attribute structure.
+If this amount is exceeded, the behavior of the process is determined
+according to what oflag was used when the message queue was opened. If
+the queue was opened with O_NONBLOCK flag set, then the EAGAIN error is
+returned. If the O_NONBLOCK flag was not set, the process blocks and
+waits for space on the queue, unless it is interrupted by a signal.
+
+Upon successful completion, the mq_send () function returns a value of
+zero. Otherwise, no message is enqueued, the function returns -1, and
+errno is set to indicate the error.
+
+**NOTES:**
+
+If the specified message queue is not full, mq_send inserts the message at
+the position indicated by the msg_prio argument.
+
+mq_receive - Receive a Message from a Message Queue
+---------------------------------------------------
+.. index:: mq_receive
+.. index:: receive a message from a message queue
+
+**CALLING SEQUENCE:**
+
+.. code:: c
+
+ #include <mqueue.h>
+ size_t mq_receive(
+ mqd_t mqdes,
+ char \*msg_ptr,
+ size_t msg_len,
+ unsigned int \*msg_prio
+ );
+
+**STATUS CODES:**
+
+``EBADF`` - The descriptor does not represent a valid message queue, or the queue was opened for write only O_WRONLY``EMSGSIZE`` - The msg_len is less than the mq_msgsize attribute of the message queue``EAGAIN`` - The message queue is non-blocking, and the queue is empty``EINTR`` - The message queue is blocking. While the process was waiting for a message to arrive on the queue, a signal arrived that interrupted the wait.
+
+**DESCRIPTION:**
+
+The mq_receive function is used to receive the oldest of the highest
+priority message(s) from the message queue specified by mqdes. The
+messages are received in FIFO order within the priorities. The received
+message’s priority is stored in the location referenced by the msg_prio.
+If the msg_prio is a NULL, the priority is discarded. The message is
+removed and stored in an area pointed to by msg_ptr whose length is of
+msg_len. The msg_len must be at least equal to the mq_msgsize attribute
+of the message queue.
+
+The blocking behavior of the message queue is set by O_NONBLOCK at mq_open
+or by setting O_NONBLOCK in mq_flags in a call to mq_setattr. If this is
+a blocking queue, the process blocks and waits on an empty queue. If this
+a non-blocking queue, the process does not block.
+
+Upon successful completion, mq_receive returns the length of the selected
+message in bytes and the message is removed from the queue. Otherwise, no
+message is removed from the queue, the function returns a value of -1, and
+sets errno to indicate the error.
+
+**NOTES:**
+
+If the size of the buffer in bytes, specified by the msg_len argument, is
+less than the mq_msgsize attribute of the message queue, the function
+fails and returns an error
+
+mq_notify - Notify Process that a Message is Available
+------------------------------------------------------
+.. index:: mq_notify
+.. index:: notify process that a message is available
+
+**CALLING SEQUENCE:**
+
+.. code:: c
+
+ #include <mqueue.h>
+ int mq_notify(
+ mqd_t mqdes,
+ const struct sigevent \*notification
+ );
+
+**STATUS CODES:**
+
+``EBADF`` - The descriptor does not refer to a valid message queue``EBUSY`` - A notification request is already attached to the queue
+
+**DESCRIPTION:**
+
+If the argument notification is not NULL, this function registers the
+calling process to be notified of message arrival at an empty message
+queue associated with the specified message queue descriptor, mqdes.
+
+Every message queue has the ability to notify one (and only one) process
+whenever the queue’s state changes from empty (0 messages) to nonempty.
+This means that the process does not have to block or constantly poll
+while it waits for a message. By calling mq_notify, a notification
+request is attached to a message queue. When a message is received by an
+empty queue, if there are no processes blocked and waiting for the
+message, then the queue notifies the requesting process of a message
+arrival. There is only one signal sent by the message queue, after that
+the notification request is de-registered and another process can attach
+its notification request. After receipt of a notification, a process must
+re-register if it wishes to be notified again.
+
+If there is a process blocked and waiting for the message, that process
+gets the message, and notification is not be sent. Only one process can
+have a notification request attached to a message queue at any one time.
+If another process attempts to register a notification request, it fails.
+You can de-register for a message queue by passing a NULL to mq_notify;
+this removes any notification request attached to the queue. Whenever the
+message queue is closed, all notification attachments are removed.
+
+Upon successful completion, mq_notify returns a value of zero; otherwise,
+the function returns a value of -1 and sets errno to indicate the error.
+
+**NOTES:**
+
+It is possible for another process to receive the message after the notification is sent but before the notified process has sent its receive request.
+
+mq_setattr - Set Message Queue Attributes
+-----------------------------------------
+.. index:: mq_setattr
+.. index:: set message queue attributes
+
+**CALLING SEQUENCE:**
+
+.. code:: c
+
+ #include <mqueue.h>
+ int mq_setattr(
+ mqd_t mqdes,
+ const struct mq_attr \*mqstat,
+ struct mq_attr \*omqstat
+ );
+
+**STATUS CODES:**
+
+``EBADF`` - The message queue descriptor does not refer to a valid, open queue.``EINVAL`` - The mq_flag value is invalid.
+
+**DESCRIPTION:**
+
+The mq_setattr function is used to set attributes associated with the open
+message queue description referenced by the message queue descriptor
+specified by mqdes. The \*omqstat represents the old or previous
+attributes. If omqstat is non-NULL, the function mq_setattr() stores, in
+the location referenced by omqstat, the previous message queue attributes
+and the current queue status. These values are the same as would be
+returned by a call to mq_getattr() at that point.
+
+There is only one mq_attr.mq_flag which can be altered by this call.
+This is the flag that deals with the blocking and non-blocking behavior of
+the message queue. If the flag is set then the message queue is
+non-blocking, and requests to send or receive do not block while waiting
+for resources. If the flag is not set, then message send and receive may
+involve waiting for an empty queue or waiting for a message to arrive.
+
+Upon successful completion, the function returns a value of zero and the
+attributes of the message queue have been changed as specified.
+Otherwise, the message queue attributes is unchanged, and the function
+returns a value of -1 and sets errno to indicate the error.
+
+**NOTES:**
+
+All other fields in the mq_attr are ignored by this call.
+
+mq_getattr - Get Message Queue Attributes
+-----------------------------------------
+.. index:: mq_getattr
+.. index:: get message queue attributes
+
+**CALLING SEQUENCE:**
+
+.. code:: c
+
+ #include <mqueue.h>
+ int mq_getattr(
+ mqd_t mqdes,
+ struct mq_attr \*mqstat
+ );
+
+**STATUS CODES:**
+
+``EBADF`` - The message queue descriptor does not refer to a valid,
+open message queue.
+
+**DESCRIPTION:**
+
+The mqdes argument specifies a message queue descriptor. The mq_getattr
+function is used to get status information and attributes of the message
+queue associated with the message queue descriptor. The results are
+returned in the mq_attr structure referenced by the mqstat argument. All
+of these attributes are set at create time, except the
+blocking/non-blocking behavior of the message queue which can be
+dynamically set by using mq_setattr. The attribute mq_curmsg is set to
+reflect the number of messages on the queue at the time that mq_getattr
+was called.
+
+Upon successful completion, the mq_getattr function returns zero.
+Otherwise, the function returns -1 and sets errno to indicate the error.
+
+**NOTES:**
+
+.. COMMENT: COPYRIGHT (c) 1988-2014.
+
+.. COMMENT: On-Line Applications Research Corporation (OAR).
+
+.. COMMENT: All rights reserved.
+