From 1264a8f1089fad85cabb024c930b19b0a36864b4 Mon Sep 17 00:00:00 2001 From: Amar Takhar Date: Sun, 17 Jan 2016 00:55:21 -0500 Subject: Split document into seperate files by section. --- posix_users/message_passing.rst | 665 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 665 insertions(+) create mode 100644 posix_users/message_passing.rst (limited to 'posix_users/message_passing.rst') 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 + 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 + 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 + 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 + 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 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 + 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 + 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 + 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 + 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. + -- cgit v1.2.3