1 .\" Copyright (C) 2006 Michael Kerrisk <mtk.manpages@gmail.com>
3 .\" %%%LICENSE_START(VERBATIM)
4 .\" Permission is granted to make and distribute verbatim copies of this
5 .\" manual provided the copyright notice and this permission notice are
6 .\" preserved on all copies.
8 .\" Permission is granted to copy and distribute modified versions of this
9 .\" manual under the conditions for verbatim copying, provided that the
10 .\" entire resulting derived work is distributed under the terms of a
11 .\" permission notice identical to this one.
13 .\" Since the Linux kernel and libraries are constantly changing, this
14 .\" manual page may be incorrect or out-of-date. The author(s) assume no
15 .\" responsibility for errors or omissions, or for damages resulting from
16 .\" the use of the information contained herein. The author(s) may not
17 .\" have taken the same level of care in the production of this manual,
18 .\" which is licensed free of charge, as they might when working
21 .\" Formatted or processed versions of this manual, if unaccompanied by
22 .\" the source, must acknowledge the copyright and authors of this work.
25 .TH MQ_NOTIFY 3 2021-03-22 "Linux" "Linux Programmer's Manual"
27 mq_notify \- register for notification when a message is available
30 .B #include <mqueue.h>
32 .BI "int mq_notify(mqd_t " mqdes ", const struct sigevent *" sevp );
35 Link with \fI\-lrt\fP.
38 allows the calling process to register or unregister for delivery of
39 an asynchronous notification when a new message arrives on
40 the empty message queue referred to by the message queue descriptor
45 argument is a pointer to a
48 For the definition and general details of this structure, see
53 is a non-null pointer, then
55 registers the calling process to receive message notification.
62 points specifies how notification is to be performed.
63 This field has one of the following values:
66 A "null" notification: the calling process is registered as the target
67 for notification, but when a message arrives, no notification is sent.
68 .\" When is SIGEV_NONE useful?
71 Notify the process by sending the signal specified in
80 structure will be set to
83 .\" I don't know of other implementations that set
84 .\" si_pid and si_uid -- MTK
86 will be set to the PID of the process that sent the message, and
88 will be set to the real user ID of the sending process.
91 Upon message delivery, invoke
92 .I sigev_notify_function
93 as if it were the start function of a new thread.
98 Only one process can be registered to receive notification
103 is NULL, and the calling process is currently registered to receive
104 notifications for this message queue, then the registration is removed;
105 another process can then register to receive a message notification
108 Message notification occurs only when a new message arrives and
109 the queue was previously empty.
110 If the queue was not empty at the time
112 was called, then a notification will occur only after
113 the queue is emptied and a new message arrives.
115 If another process or thread is waiting to read a message
116 from an empty queue using
118 then any message notification registration is ignored:
119 the message is delivered to the process or thread calling
121 and the message notification registration remains in effect.
123 Notification occurs once: after a notification is delivered,
124 the notification registration is removed,
125 and another process can register for message notification.
126 If the notified process wishes to receive the next notification,
129 to request a further notification.
130 This should be done before emptying all unread messages from the queue.
131 (Placing the queue in nonblocking mode is useful for emptying
132 the queue of messages without blocking once it is empty.)
136 returns 0; on error, \-1 is returned, with
138 set to indicate the error.
142 The message queue descriptor specified in
147 Another process has already registered to receive notification
148 for this message queue.
151 .I sevp\->sigev_notify
152 is not one of the permitted values; or
153 .I sevp\->sigev_notify
157 .I sevp\->sigev_signo
158 is not a valid signal number.
163 POSIX.1-2008 says that an implementation
167 .\" Linux does not do this
170 is NULL, and the caller is not currently registered to receive
171 notifications for the queue
174 For an explanation of the terms used in this section, see
182 Interface Attribute Value
185 T} Thread safety MT-Safe
194 .SS C library/kernel differences
195 In the glibc implementation, the
197 library function is implemented on top of the system call of the same name.
200 is NULL, or specifies a notification mechanism other than
202 the library function directly invokes the system call.
205 much of the implementation resides within the library,
206 rather than the kernel.
207 (This is necessarily so,
208 since the thread involved in handling the notification is one
209 that must be managed by the C library POSIX threads implementation.)
210 The implementation involves the use of a raw
212 socket and creates a new thread for each notification that is
213 delivered to the process.
215 The following program registers a notification request for the
216 message queue named in its command-line argument.
217 Notification is performed by creating a thread.
218 The thread executes a function which reads one message from the
219 queue and then terminates the process.
228 #define handle_error(msg) \e
229 do { perror(msg); exit(EXIT_FAILURE); } while (0)
231 static void /* Thread start function */
232 tfunc(union sigval sv)
237 mqd_t mqdes = *((mqd_t *) sv.sival_ptr);
239 /* Determine max. msg size; allocate buffer to receive msg */
241 if (mq_getattr(mqdes, &attr) == \-1)
242 handle_error("mq_getattr");
243 buf = malloc(attr.mq_msgsize);
245 handle_error("malloc");
247 nr = mq_receive(mqdes, buf, attr.mq_msgsize, NULL);
249 handle_error("mq_receive");
251 printf("Read %zd bytes from MQ\en", nr);
253 exit(EXIT_SUCCESS); /* Terminate the process */
257 main(int argc, char *argv[])
263 fprintf(stderr, "Usage: %s <mq\-name>\en", argv[0]);
267 mqdes = mq_open(argv[1], O_RDONLY);
268 if (mqdes == (mqd_t) \-1)
269 handle_error("mq_open");
271 sev.sigev_notify = SIGEV_THREAD;
272 sev.sigev_notify_function = tfunc;
273 sev.sigev_notify_attributes = NULL;
274 sev.sigev_value.sival_ptr = &mqdes; /* Arg. to thread func. */
275 if (mq_notify(mqdes, &sev) == \-1)
276 handle_error("mq_notify");
278 pause(); /* Process will be terminated by thread function */