source: rtems-docs/posix_users/message_passing.rst @ 3a71759

4.115
Last change on this file since 3a71759 was 1264a8f, checked in by Amar Takhar <amar@…>, on 01/17/16 at 05:55:21

Split document into seperate files by section.

  • Property mode set to 100644
File size: 26.9 KB
Line 
1Message Passing Manager
2#######################
3
4Introduction
5============
6
7The message passing manager is the means to provide communication and
8synchronization capabilities using POSIX message queues.
9
10The directives provided by the message passing manager are:
11
12- ``mq_open`` - Open a Message Queue
13
14- ``mq_close`` - Close a Message Queue
15
16- ``mq_unlink`` - Remove a Message Queue
17
18- ``mq_send`` - Send a Message to a Message Queue
19
20- ``mq_receive`` - Receive a Message from a Message Queue
21
22- ``mq_notify`` - Notify Process that a Message is Available
23
24- ``mq_setattr`` - Set Message Queue Attributes
25
26- ``mq_getattr`` - Get Message Queue Attributes
27
28Background
29==========
30
31Theory
32------
33
34Message queues are named objects that operate with readers and writers.
35In addition, a message queue is a priority queue of discrete messages.
36POSIX message queues offer a certain, basic amount of application access
37to, and control over, the message queue geometry that can be changed.
38
39Messages
40--------
41
42A message is a variable length buffer where information can be stored to
43support communication. The length of the message and the information
44stored in that message are user-defined and can be actual data,
45pointer(s), or empty. There is a maximum acceptable length for a message
46that is associated with each message queue.
47
48Message Queues
49--------------
50
51Message queues are named objects similar to the pipes of POSIX. They are
52a means of communicating data between multiple processes and for passing
53messages among tasks and ISRs. Message queues can contain a variable
54number of messages from 0 to an upper limit that is user defined. The
55maximum length of the message can be set on a per message queue basis.
56Normally messages are sent and received from the message queue in FIFO
57order. However, messages can also be prioritized and a priority queue
58established for the passing of messages. Synchronization is needed when a
59task waits for a message to arrive at a queue. Also, a task may poll a
60queue for the arrival of a message... index:: mqd_t
61
62The message queue descriptor ``mqd_t`` represents the message queue. It is
63passed as an argument to all of the message queue functions.
64
65Building a Message Queue Attribute Set
66--------------------------------------
67
68The mq_attr structure is used to define the characteristics of the message
69queue... index:: mq_attr
70
71.. code:: c
72
73    typedef struct mq_attr{
74    long mq_flags;
75    long mq_maxmsg;
76    long mq_msgsize;
77    long mq_curmsgs;
78    };
79
80All of these attributes are set when the message queue is created using
81mq_open. The mq_flags field is not used in the creation of a message
82queue, it is only used by mq_setattr and mq_getattr. The structure
83mq_attr is passed as an argument to mq_setattr and mq_getattr.
84
85The mq_flags contain information affecting the behavior of the message
86queue. The O_NONBLOCK mq_flag is the only flag that is defined. In
87mq_setattr, the mq_flag can be set to dynamically change the blocking and
88non-blocking behavior of the message queue. If the non-block flag is set
89then the message queue is non-blocking, and requests to send and receive
90messages do not block waiting for resources. For a blocking message
91queue, a request to send might have to wait for an empty message queue,
92and a request to receive might have to wait for a message to arrive on the
93queue. Both mq_maxmsg and mq_msgsize affect the sizing of the message
94queue. mq_maxmsg specifies how many messages the queue can hold at any
95one time. mq_msgsize specifies the size of any one message on the queue.
96If either of these limits is exceeded, an error message results.
97
98Upon return from mq_getattr, the mq_curmsgs is set according to the
99current state of the message queue. This specifies the number of messages
100currently on the queue.
101
102Notification of a Message on the Queue
103--------------------------------------
104
105Every message queue has the ability to notify one (and only one) process
106whenever the queue’s state changes from empty (0 messages) to nonempty.
107This means that the process does not have to block or constantly poll
108while it waits for a message. By calling mq_notify, you can attach a
109notification request to a message queue. When a message is received by an
110empty queue, if there are no processes blocked and waiting for the
111message, then the queue notifies the requesting process of a message
112arrival. There is only one signal sent by the message queue, after that
113the notification request is de-registered and another process can attach
114its notification request. After receipt of a notification, a process must
115re-register if it wishes to be notified again.
116
117If there is a process blocked and waiting for the message, that process
118gets the message, and notification is not sent. It is also possible for
119another process to receive the message after the notification is sent but
120before the notified process has sent its receive request.
121
122Only one process can have a notification request attached to a message
123queue at any one time. If another process attempts to register a
124notification request, it fails. You can de-register for a message queue
125by passing a NULL to mq_notify, this removes any notification request
126attached to the queue. Whenever the message queue is closed, all
127notification attachments are removed.
128
129POSIX Interpretation Issues
130---------------------------
131
132There is one significant point of interpretation related to
133the RTEMS implementation of POSIX message queues:
134
135*What happens to threads already blocked on a message queue when the
136mode of that same message queue is changed from blocking to non-blocking?*
137
138The RTEMS POSIX implementation decided to unblock all waiting tasks
139with an ``EAGAIN`` status just as if a non-blocking version of
140the same operation had returned unsatisfied.  This case is not
141discussed in the POSIX standard and other implementations may have
142chosen alternative behaviors.
143
144Operations
145==========
146
147Opening or Creating a Message Queue
148-----------------------------------
149
150If the message queue already exists, mq_open() opens it, if the message
151queue does not exist, mq_open() creates it. When a message queue is
152created, the geometry of the message queue is contained in the attribute
153structure that is passed in as an argument. This includes mq_msgsize that
154dictates the maximum size of a single message, and the mq_maxmsg that
155dictates the maximum number of messages the queue can hold at one time.
156The blocking or non-blocking behavior of the queue can also specified.
157
158Closing a Message Queue
159-----------------------
160
161The mq_close() function is used to close the connection made to a message
162queue that was made during mq_open. The message queue itself and the
163messages on the queue are persistent and remain after the queue is closed.
164
165Removing a Message Queue
166------------------------
167
168The mq_unlink() function removes the named message queue. If the message
169queue is not open when mq_unlink is called, then the queue is immediately
170eliminated. Any messages that were on the queue are lost, and the queue
171can not be opened again. If processes have the queue open when mq_unlink
172is called, the removal of the queue is delayed until the last process
173using the queue has finished. However, the name of the message queue is
174removed so that no other process can open it.
175
176Sending a Message to a Message Queue
177------------------------------------
178
179The mq_send() function adds the message in priority order to the message
180queue. Each message has an assigned a priority. The highest priority
181message is be at the front of the queue.
182
183The maximum number of messages that a message queue may accept is
184specified at creation by the mq_maxmsg field of the attribute structure.
185If this amount is exceeded, the behavior of the process is determined
186according to what oflag was used when the message queue was opened. If
187the queue was opened with O_NONBLOCK flag set, the process does not block,
188and an error is returned. If the O_NONBLOCK flag was not set, the process
189does block and wait for space on the queue.
190
191Receiving a Message from a Message Queue
192----------------------------------------
193
194The mq_receive() function is used to receive the oldest of the highest
195priority message(s) from the message queue specified by mqdes. The
196messages are received in FIFO order within the priorities. The received
197message’s priority is stored in the location referenced by the msg_prio.
198If the msg_prio is a NULL, the priority is discarded. The message is
199removed and stored in an area pointed to by msg_ptr whose length is of
200msg_len. The msg_len must be at least equal to the mq_msgsize attribute
201of the message queue.
202
203The blocking behavior of the message queue is set by O_NONBLOCK at mq_open
204or by setting O_NONBLOCK in mq_flags in a call to mq_setattr. If this is
205a blocking queue, the process does block and wait on an empty queue. If
206this a non-blocking queue, the process does not block. Upon successful
207completion, mq_receive returns the length of the selected message in bytes
208and the message is removed from the queue.
209
210Notification of Receipt of a Message on an Empty Queue
211------------------------------------------------------
212
213The mq_notify() function registers the calling process to be notified of
214message arrival at an empty message queue. Every message queue has the
215ability to notify one (and only one) process whenever the queue’s state
216changes from empty (0 messages) to nonempty. This means that the process
217does not have to block or constantly poll while it waits for a message.
218By calling mq_notify, a notification request is attached to a message
219queue. When a message is received by an empty queue, if there are no
220processes blocked and waiting for the message, then the queue notifies the
221requesting process of a message arrival. There is only one signal sent by
222the message queue, after that the notification request is de-registered
223and another process can attach its notification request. After receipt of
224a notification, a process must re-register if it wishes to be notified
225again.
226
227If there is a process blocked and waiting for the message, that process
228gets the message, and notification is not sent. Only one process can have
229a notification request attached to a message queue at any one time. If
230another process attempts to register a notification request, it fails.
231You can de-register for a message queue by passing a NULL to mq_notify,
232this removes any notification request attached to the queue. Whenever the
233message queue is closed, all notification attachments are removed.
234
235Setting the Attributes of a Message Queue
236-----------------------------------------
237
238The mq_setattr() function is used to set attributes associated with the
239open message queue description referenced by the message queue descriptor
240specified by mqdes. The \*omqstat represents the old or previous
241attributes. If omqstat is non-NULL, the function mq_setattr() stores, in
242the location referenced by omqstat, the previous message queue attributes
243and the current queue status. These values are the same as would be
244returned by a call to mq_getattr() at that point.
245
246There is only one mq_attr.mq_flag that can be altered by this call. This
247is the flag that deals with the blocking and non-blocking behavior of the
248message queue. If the flag is set then the message queue is non-blocking,
249and requests to send or receive do not block while waiting for resources.
250If the flag is not set, then message send and receive may involve waiting
251for an empty queue or waiting for a message to arrive.
252
253Getting the Attributes of a Message Queue
254-----------------------------------------
255
256The mq_getattr() function is used to get status information and attributes
257of the message queue associated with the message queue descriptor. The
258results are returned in the mq_attr structure referenced by the mqstat
259argument. All of these attributes are set at create time, except the
260blocking/non-blocking behavior of the message queue which can be
261dynamically set by using mq_setattr. The attribute mq_curmsg is set to
262reflect the number of messages on the queue at the time that mq_getattr
263was called.
264
265Directives
266==========
267
268This section details the message passing manager’s directives. A
269subsection is dedicated to each of this manager’s directives and describes
270the calling sequence, related constants, usage, and status codes.
271
272mq_open - Open a Message Queue
273------------------------------
274.. index:: mq_open
275.. index:: open a message queue
276
277**CALLING SEQUENCE:**
278
279.. code:: c
280
281    #include <mqueue.h>
282    mqd_t mq_open(
283    const char     \*name,
284    int             oflag,
285    mode_t          mode,
286    struct mq_attr \*attr
287    );
288
289**STATUS CODES:**
290
291``EACCES`` - Either the message queue exists and the permissions
292requested in oflags were denied, or the message does not exist and
293permission to create one is denied.
294
295``EEXIST`` - You tried to create a message queue that already exists.
296
297``EINVAL`` - An inappropriate name was given for the message queue, or
298the values of mq-maxmsg or mq_msgsize were less than 0.
299
300``ENOENT`` - The message queue does not exist, and you did not specify
301to create it.
302
303``EINTR`` - The call to mq_open was interrupted by a signal.
304
305``EMFILE`` - The process has too many files or message queues open.
306This is a process limit error.
307
308``ENFILE`` - The system has run out of resources to support more open
309message queues. This is a system error.
310
311``ENAMETOOLONG`` - mq_name is too long.
312
313**DESCRIPTION:**
314
315The mq_open () function establishes the connection between a process and a
316message queue with a message queue descriptor. If the message queue
317already exists, mq_open opens it, if the message queue does not exist,
318mq_open creates it. Message queues can have multiple senders and
319receivers. If mq_open is successful, the function returns a message queue
320descriptor. Otherwise, the function returns a -1 and sets ’errno’ to
321indicate the error.
322
323The name of the message queue is used as an argument. For the best of
324portability, the name of the message queue should begin with a "/" and no
325other "/" should be in the name. Different systems interpret the name in
326different ways.
327
328The oflags contain information on how the message is opened if the queue
329already exists. This may be O_RDONLY for read only, O_WRONLY for write
330only, of O_RDWR, for read and write.
331
332In addition, the oflags contain information needed in the creation of a
333message queue. ``O_NONBLOCK`` - If the non-block flag is set then the
334message queue is non-blocking, and requests to send and receive messages
335do not block waiting for resources. If the flag is not set then the
336message queue is blocking, and a request to send might have to wait for an
337empty message queue. Similarly, a request to receive might have to wait
338for a message to arrive on the queue. ``O_CREAT`` - This call specifies
339that the call the mq_open is to create a new message queue. In this case
340the mode and attribute arguments of the function call are utilized. The
341message queue is created with a mode similar to the creation of a file,
342read and write permission creator, group, and others.
343
344The geometry of the message queue is contained in the attribute structure.
345This includes mq_msgsize that dictates the maximum size of a single
346message, and the mq_maxmsg that dictates the maximum number of messages
347the queue can hold at one time. If a NULL is used in the mq_attr
348argument, then the message queue is created with implementation defined
349defaults. ``O_EXCL`` - is always set if O_CREAT flag is set. If the
350message queue already exists, O_EXCL causes an error message to be
351returned, otherwise, the new message queue fails and appends to the
352existing one.
353
354**NOTES:**
355
356The mq_open () function does not add or remove messages from the queue.
357When a new message queue is being created, the mq_flag field of the
358attribute structure is not used.
359
360mq_close - Close a Message Queue
361--------------------------------
362.. index:: mq_close
363.. index:: close a message queue
364
365**CALLING SEQUENCE:**
366
367.. code:: c
368
369    #include <mqueue.h>
370    int mq_close(
371    mqd_t mqdes
372    );
373
374**STATUS CODES:**
375
376``EINVAL`` - The descriptor does not represent a valid open message
377queue
378
379**DESCRIPTION:**
380
381The mq_close function removes the association between the message queue
382descriptor, mqdes, and its message queue. If mq_close() is successfully
383completed, the function returns a value of zero; otherwise, the function
384returns a value of -1 and sets errno to indicate the error.
385
386**NOTES:**
387
388If the process had successfully attached a notification request to the
389message queue via mq_notify, this attachment is removed, and the message
390queue is available for another process to attach for notification.
391mq_close has no effect on the contents of the message queue, all the
392messages that were in the queue remain in the queue.
393
394mq_unlink - Remove a Message Queue
395----------------------------------
396.. index:: mq_unlink
397.. index:: remove a message queue
398
399**CALLING SEQUENCE:**
400
401.. code:: c
402
403    #include <mqueue.h>
404    int mq_unlink(
405    const char \*name
406    );
407
408**STATUS CODES:**
409
410``EINVAL`` - The descriptor does not represent a valid message queue
411
412**DESCRIPTION:**
413
414The mq_unlink() function removes the named message queue. If the message
415queue is not open when mq_unlink is called, then the queue is immediately
416eliminated. Any messages that were on the queue are lost, and the queue
417can not be opened again. If processes have the queue open when mq_unlink
418is called, the removal of the queue is delayed until the last process
419using the queue has finished. However, the name of the message queue is
420removed so that no other process can open it. Upon successful completion,
421the function returns a value of zero. Otherwise, the named message queue
422is not changed by this function call, and the function returns a value of
423-1 and sets errno to indicate the error.
424
425**NOTES:**
426
427Calls to mq_open() to re-create the message queue may fail until the
428message queue is actually removed. However, the mq_unlink() call need not
429block until all references have been closed; it may return immediately.
430
431mq_send - Send a Message to a Message Queue
432-------------------------------------------
433.. index:: mq_send
434.. index:: send a message to a message queue
435
436**CALLING SEQUENCE:**
437
438.. code:: c
439
440    #include<mqueue.h>
441    int mq_send(
442    mqd_t        mqdes,
443    const char  \*msg_ptr,
444    size_t       msg_len,
445    unsigned int msg_prio
446    );
447
448**STATUS CODES:**
449
450``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.
451
452**DESCRIPTION:**
453
454The mq_send() function adds the message pointed to by the argument msg_ptr
455to the message queue specified by mqdes. Each message is assigned a
456priority , from 0 to MQ_PRIO_MAX. MQ_PRIO_MAX is defined in <limits.h> and
457must be at least 32. Messages are added to the queue in order of their
458priority. The highest priority message is at the front of the queue.
459
460The maximum number of messages that a message queue may accept is
461specified at creation by the mq_maxmsg field of the attribute structure.
462If this amount is exceeded, the behavior of the process is determined
463according to what oflag was used when the message queue was opened. If
464the queue was opened with O_NONBLOCK flag set, then the EAGAIN error is
465returned. If the O_NONBLOCK flag was not set, the process blocks and
466waits for space on the queue, unless it is interrupted by a signal.
467
468Upon successful completion, the mq_send () function returns a value of
469zero. Otherwise, no message is enqueued, the function returns -1, and
470errno is set to indicate the error.
471
472**NOTES:**
473
474If the specified message queue is not full, mq_send inserts the message at
475the position indicated by the msg_prio argument.
476
477mq_receive - Receive a Message from a Message Queue
478---------------------------------------------------
479.. index:: mq_receive
480.. index:: receive a message from a message queue
481
482**CALLING SEQUENCE:**
483
484.. code:: c
485
486    #include <mqueue.h>
487    size_t mq_receive(
488    mqd_t         mqdes,
489    char         \*msg_ptr,
490    size_t        msg_len,
491    unsigned int \*msg_prio
492    );
493
494**STATUS CODES:**
495
496``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.
497
498**DESCRIPTION:**
499
500The mq_receive function is used to receive the oldest of the highest
501priority message(s) from the message queue specified by mqdes. The
502messages are received in FIFO order within the priorities. The received
503message’s priority is stored in the location referenced by the msg_prio.
504If the msg_prio is a NULL, the priority is discarded. The message is
505removed and stored in an area pointed to by msg_ptr whose length is of
506msg_len. The msg_len must be at least equal to the mq_msgsize attribute
507of the message queue.
508
509The blocking behavior of the message queue is set by O_NONBLOCK at mq_open
510or by setting O_NONBLOCK in mq_flags in a call to mq_setattr. If this is
511a blocking queue, the process blocks and waits on an empty queue. If this
512a non-blocking queue, the process does not block.
513
514Upon successful completion, mq_receive returns the length of the selected
515message in bytes and the message is removed from the queue. Otherwise, no
516message is removed from the queue, the function returns a value of -1, and
517sets errno to indicate the error.
518
519**NOTES:**
520
521If the size of the buffer in bytes, specified by the msg_len argument, is
522less than the mq_msgsize attribute of the message queue, the function
523fails and returns an error
524
525mq_notify - Notify Process that a Message is Available
526------------------------------------------------------
527.. index:: mq_notify
528.. index:: notify process that a message is available
529
530**CALLING SEQUENCE:**
531
532.. code:: c
533
534    #include <mqueue.h>
535    int mq_notify(
536    mqd_t                  mqdes,
537    const struct sigevent \*notification
538    );
539
540**STATUS CODES:**
541
542``EBADF`` - The descriptor does not refer to a valid message queue``EBUSY`` - A notification request is already attached to the queue
543
544**DESCRIPTION:**
545
546If the argument notification is not NULL, this function registers the
547calling process to be notified of message arrival at an empty message
548queue associated with the specified message queue descriptor, mqdes.
549
550Every message queue has the ability to notify one (and only one) process
551whenever the queue’s state changes from empty (0 messages) to nonempty.
552This means that the process does not have to block or constantly poll
553while it waits for a message. By calling mq_notify, a notification
554request is attached to a message queue. When a message is received by an
555empty queue, if there are no processes blocked and waiting for the
556message, then the queue notifies the requesting process of a message
557arrival. There is only one signal sent by the message queue, after that
558the notification request is de-registered and another process can attach
559its notification request. After receipt of a notification, a process must
560re-register if it wishes to be notified again.
561
562If there is a process blocked and waiting for the message, that process
563gets the message, and notification is not be sent. Only one process can
564have a notification request attached to a message queue at any one time.
565If another process attempts to register a notification request, it fails.
566You can de-register for a message queue by passing a NULL to mq_notify;
567this removes any notification request attached to the queue. Whenever the
568message queue is closed, all notification attachments are removed.
569
570Upon successful completion, mq_notify returns a value of zero; otherwise,
571the function returns a value of -1 and sets errno to indicate the error.
572
573**NOTES:**
574
575It is possible for another process to receive the message after the notification is sent but before the notified process has sent its receive request.
576
577mq_setattr - Set Message Queue Attributes
578-----------------------------------------
579.. index:: mq_setattr
580.. index:: set message queue attributes
581
582**CALLING SEQUENCE:**
583
584.. code:: c
585
586    #include <mqueue.h>
587    int mq_setattr(
588    mqd_t                 mqdes,
589    const struct mq_attr \*mqstat,
590    struct mq_attr       \*omqstat
591    );
592
593**STATUS CODES:**
594
595``EBADF`` - The message queue descriptor does not refer to a valid, open queue.``EINVAL`` - The mq_flag value is invalid.
596
597**DESCRIPTION:**
598
599The mq_setattr function is used to set attributes associated with the open
600message queue description referenced by the message queue descriptor
601specified by mqdes. The \*omqstat represents the old or previous
602attributes. If omqstat is non-NULL, the function mq_setattr() stores, in
603the location referenced by omqstat, the previous message queue attributes
604and the current queue status. These values are the same as would be
605returned by a call to mq_getattr() at that point.
606
607There is only one mq_attr.mq_flag which can be altered by this call.
608This is the flag that deals with the blocking and non-blocking behavior of
609the message queue. If the flag is set then the message queue is
610non-blocking, and requests to send or receive do not block while waiting
611for resources. If the flag is not set, then message send and receive may
612involve waiting for an empty queue or waiting for a message to arrive.
613
614Upon successful completion, the function returns a value of zero and the
615attributes of the message queue have been changed as specified.
616Otherwise, the message queue attributes is unchanged, and the function
617returns a value of -1 and sets errno to indicate the error.
618
619**NOTES:**
620
621All other fields in the mq_attr are ignored by this call.
622
623mq_getattr - Get Message Queue Attributes
624-----------------------------------------
625.. index:: mq_getattr
626.. index:: get message queue attributes
627
628**CALLING SEQUENCE:**
629
630.. code:: c
631
632    #include <mqueue.h>
633    int mq_getattr(
634    mqd_t mqdes,
635    struct mq_attr \*mqstat
636    );
637
638**STATUS CODES:**
639
640``EBADF`` - The message queue descriptor does not refer to a valid,
641open message queue.
642
643**DESCRIPTION:**
644
645The mqdes argument specifies a message queue descriptor. The mq_getattr
646function is used to get status information and attributes of the message
647queue associated with the message queue descriptor. The results are
648returned in the mq_attr structure referenced by the mqstat argument. All
649of these attributes are set at create time, except the
650blocking/non-blocking behavior of the message queue which can be
651dynamically set by using mq_setattr. The attribute mq_curmsg is set to
652reflect the number of messages on the queue at the time that mq_getattr
653was called.
654
655Upon successful completion, the mq_getattr function returns zero.
656Otherwise, the function returns -1 and sets errno to indicate the error.
657
658**NOTES:**
659
660.. COMMENT: COPYRIGHT (c) 1988-2014.
661
662.. COMMENT: On-Line Applications Research Corporation (OAR).
663
664.. COMMENT: All rights reserved.
665
Note: See TracBrowser for help on using the repository browser.