1MQ_NOTIFY(3)               Linux Programmer's Manual              MQ_NOTIFY(3)
2
3
4

NAME

6       mq_notify - register for notification when a message is available
7

SYNOPSIS

9       #include <mqueue.h>
10
11       int mq_notify(mqd_t mqdes, const struct sigevent *sevp);
12
13       Link with -lrt.
14

DESCRIPTION

16       mq_notify()  allows  the  calling process to register or unregister for
17       delivery of an asynchronous notification when a new message arrives  on
18       the  empty  message  queue  referred to by the message queue descriptor
19       mqdes.
20
21       The sevp argument is a pointer to a sigevent structure.  For the  defi‐
22       nition and general details of this structure, see sigevent(7).
23
24       If  sevp  is a non-null pointer, then mq_notify() registers the calling
25       process to receive message notification.  The sigev_notify field of the
26       sigevent  structure  to which sevp points specifies how notification is
27       to be performed.  This field has one of the following values:
28
29       SIGEV_NONE
30              A "null" notification: the calling process is registered as  the
31              target  for notification, but when a message arrives, no notifi‐
32              cation is sent.
33
34       SIGEV_SIGNAL
35              Notify  the  process  by  sending  the   signal   specified   in
36              sigev_signo.   See sigevent(7) for general details.  The si_code
37              field of the siginfo_t structure will be set  to  SI_MESGQ.   In
38              addition, si_pid will be set to the PID of the process that sent
39              the message, and si_uid will be set to the real user ID  of  the
40              sending process.
41
42       SIGEV_THREAD
43              Upon  message  delivery,  invoke  sigev_notify_function as if it
44              were the start function of a new thread.   See  sigevent(7)  for
45              details.
46
47       Only  one process can be registered to receive notification from a mes‐
48       sage queue.
49
50       If sevp is NULL, and the calling process  is  currently  registered  to
51       receive  notifications for this message queue, then the registration is
52       removed; another process can then register to receive a message notifi‐
53       cation for this queue.
54
55       Message  notification  occurs  only  when a new message arrives and the
56       queue was previously empty.  If the queue was not  empty  at  the  time
57       mq_notify()  was  called, then a notification will occur only after the
58       queue is emptied and a new message arrives.
59
60       If another process or thread is waiting to read a message from an empty
61       queue  using  mq_receive(3), then any message notification registration
62       is ignored: the message is delivered to the process or  thread  calling
63       mq_receive(3),  and  the  message  notification registration remains in
64       effect.
65
66       Notification occurs once: after a notification is delivered, the  noti‐
67       fication  registration is removed, and another process can register for
68       message notification.  If the notified process wishes  to  receive  the
69       next  notification, it can use mq_notify() to request a further notifi‐
70       cation.  This should be done before emptying all unread  messages  from
71       the queue.  (Placing the queue in nonblocking mode is useful for empty‐
72       ing the queue of messages without blocking once it is empty.)
73

RETURN VALUE

75       On success mq_notify() returns 0; on error, -1 is returned, with  errno
76       set to indicate the error.
77

ERRORS

79       EBADF  The message queue descriptor specified in mqdes is invalid.
80
81       EBUSY  Another  process  has already registered to receive notification
82              for this message queue.
83
84       EINVAL sevp->sigev_notify is  not  one  of  the  permitted  values;  or
85              sevp->sigev_notify  is SIGEV_SIGNAL and sevp->sigev_signo is not
86              a valid signal number.
87
88       ENOMEM Insufficient memory.
89
90       POSIX.1-2008 says that an implementation may generate an  EINVAL  error
91       if  sevp is NULL, and the caller is not currently registered to receive
92       notifications for the queue mqdes.
93

ATTRIBUTES

95       For  an  explanation  of  the  terms  used   in   this   section,   see
96       attributes(7).
97
98       ┌────────────┬───────────────┬─────────┐
99Interface   Attribute     Value   
100       ├────────────┼───────────────┼─────────┤
101mq_notify() │ Thread safety │ MT-Safe │
102       └────────────┴───────────────┴─────────┘
103

CONFORMING TO

105       POSIX.1-2001.
106

NOTES

108   C library/kernel differences
109       In the glibc implementation, the mq_notify() library function is imple‐
110       mented on top of the system call of the same name.  When sevp is  NULL,
111       or  specifies  a  notification  mechanism  other than SIGEV_THREAD, the
112       library function directly invokes the system call.   For  SIGEV_THREAD,
113       much  of the implementation resides within the library, rather than the
114       kernel.  (This is necessarily so, since the thread involved in handling
115       the  notification  is  one  that must be managed by the C library POSIX
116       threads implementation.)  The implementation involves the use of a  raw
117       netlink(7)  socket  and creates a new thread for each notification that
118       is delivered to the process.
119

EXAMPLE

121       The following program registers a notification request for the  message
122       queue named in its command-line argument.  Notification is performed by
123       creating a thread.  The thread executes a function which reads one mes‐
124       sage from the queue and then terminates the process.
125
126   Program source
127       #include <pthread.h>
128       #include <mqueue.h>
129       #include <stdio.h>
130       #include <stdlib.h>
131       #include <unistd.h>
132
133       #define handle_error(msg) \
134           do { perror(msg); exit(EXIT_FAILURE); } while (0)
135
136       static void                     /* Thread start function */
137       tfunc(union sigval sv)
138       {
139           struct mq_attr attr;
140           ssize_t nr;
141           void *buf;
142           mqd_t mqdes = *((mqd_t *) sv.sival_ptr);
143
144           /* Determine max. msg size; allocate buffer to receive msg */
145
146           if (mq_getattr(mqdes, &attr) == -1)
147               handle_error("mq_getattr");
148           buf = malloc(attr.mq_msgsize);
149           if (buf == NULL)
150               handle_error("malloc");
151
152           nr = mq_receive(mqdes, buf, attr.mq_msgsize, NULL);
153           if (nr == -1)
154               handle_error("mq_receive");
155
156           printf("Read %zd bytes from MQ\n", nr);
157           free(buf);
158           exit(EXIT_SUCCESS);         /* Terminate the process */
159       }
160
161       int
162       main(int argc, char *argv[])
163       {
164           mqd_t mqdes;
165           struct sigevent sev;
166
167           if (argc != 2) {
168               fprintf(stderr, "Usage: %s <mq-name>\n", argv[0]);
169               exit(EXIT_FAILURE);
170           }
171
172           mqdes = mq_open(argv[1], O_RDONLY);
173           if (mqdes == (mqd_t) -1)
174               handle_error("mq_open");
175
176           sev.sigev_notify = SIGEV_THREAD;
177           sev.sigev_notify_function = tfunc;
178           sev.sigev_notify_attributes = NULL;
179           sev.sigev_value.sival_ptr = &mqdes;   /* Arg. to thread func. */
180           if (mq_notify(mqdes, &sev) == -1)
181               handle_error("mq_notify");
182
183           pause();    /* Process will be terminated by thread function */
184       }
185

SEE ALSO

187       mq_close(3),   mq_getattr(3),  mq_open(3),  mq_receive(3),  mq_send(3),
188       mq_unlink(3), mq_overview(7), sigevent(7)
189

COLOPHON

191       This page is part of release 4.15 of the Linux  man-pages  project.   A
192       description  of  the project, information about reporting bugs, and the
193       latest    version    of    this    page,    can     be     found     at
194       https://www.kernel.org/doc/man-pages/.
195
196
197
198Linux                             2017-09-15                      MQ_NOTIFY(3)
Impressum