]> git.ipfire.org Git - thirdparty/man-pages.git/blob - man3/mq_notify.3
Many pages: Use correct letter case in page titles (TH)
[thirdparty/man-pages.git] / man3 / mq_notify.3
1 .\" Copyright (C) 2006 Michael Kerrisk <mtk.manpages@gmail.com>
2 .\"
3 .\" SPDX-License-Identifier: Linux-man-pages-copyleft
4 .\"
5 .TH mq_notify 3 (date) "Linux man-pages (unreleased)"
6 .SH NAME
7 mq_notify \- register for notification when a message is available
8 .SH LIBRARY
9 Real-time library
10 .RI ( librt ", " \-lrt )
11 .SH SYNOPSIS
12 .nf
13 .B #include <mqueue.h>
14 .BR "#include <signal.h> " "/* Definition of SIGEV_* constants */"
15 .PP
16 .BI "int mq_notify(mqd_t " mqdes ", const struct sigevent *" sevp );
17 .fi
18 .SH DESCRIPTION
19 .BR mq_notify ()
20 allows the calling process to register or unregister for delivery of
21 an asynchronous notification when a new message arrives on
22 the empty message queue referred to by the message queue descriptor
23 .IR mqdes .
24 .PP
25 The
26 .I sevp
27 argument is a pointer to a
28 .I sigevent
29 structure.
30 For the definition and general details of this structure, see
31 .BR sigevent (7).
32 .PP
33 If
34 .I sevp
35 is a non-null pointer, then
36 .BR mq_notify ()
37 registers the calling process to receive message notification.
38 The
39 .I sigev_notify
40 field of the
41 .I sigevent
42 structure to which
43 .I sevp
44 points specifies how notification is to be performed.
45 This field has one of the following values:
46 .TP
47 .B SIGEV_NONE
48 A "null" notification: the calling process is registered as the target
49 for notification, but when a message arrives, no notification is sent.
50 .\" When is SIGEV_NONE useful?
51 .TP
52 .B SIGEV_SIGNAL
53 Notify the process by sending the signal specified in
54 .IR sigev_signo .
55 See
56 .BR sigevent (7)
57 for general details.
58 The
59 .I si_code
60 field of the
61 .I siginfo_t
62 structure will be set to
63 .BR SI_MESGQ .
64 In addition,
65 .\" I don't know of other implementations that set
66 .\" si_pid and si_uid -- MTK
67 .I si_pid
68 will be set to the PID of the process that sent the message, and
69 .I si_uid
70 will be set to the real user ID of the sending process.
71 .TP
72 .B SIGEV_THREAD
73 Upon message delivery, invoke
74 .I sigev_notify_function
75 as if it were the start function of a new thread.
76 See
77 .BR sigevent (7)
78 for details.
79 .PP
80 Only one process can be registered to receive notification
81 from a message queue.
82 .PP
83 If
84 .I sevp
85 is NULL, and the calling process is currently registered to receive
86 notifications for this message queue, then the registration is removed;
87 another process can then register to receive a message notification
88 for this queue.
89 .PP
90 Message notification occurs only when a new message arrives and
91 the queue was previously empty.
92 If the queue was not empty at the time
93 .BR mq_notify ()
94 was called, then a notification will occur only after
95 the queue is emptied and a new message arrives.
96 .PP
97 If another process or thread is waiting to read a message
98 from an empty queue using
99 .BR mq_receive (3),
100 then any message notification registration is ignored:
101 the message is delivered to the process or thread calling
102 .BR mq_receive (3),
103 and the message notification registration remains in effect.
104 .PP
105 Notification occurs once: after a notification is delivered,
106 the notification registration is removed,
107 and another process can register for message notification.
108 If the notified process wishes to receive the next notification,
109 it can use
110 .BR mq_notify ()
111 to request a further notification.
112 This should be done before emptying all unread messages from the queue.
113 (Placing the queue in nonblocking mode is useful for emptying
114 the queue of messages without blocking once it is empty.)
115 .SH RETURN VALUE
116 On success
117 .BR mq_notify ()
118 returns 0; on error, \-1 is returned, with
119 .I errno
120 set to indicate the error.
121 .SH ERRORS
122 .TP
123 .B EBADF
124 The message queue descriptor specified in
125 .I mqdes
126 is invalid.
127 .TP
128 .B EBUSY
129 Another process has already registered to receive notification
130 for this message queue.
131 .TP
132 .B EINVAL
133 .I sevp\->sigev_notify
134 is not one of the permitted values; or
135 .I sevp\->sigev_notify
136 is
137 .B SIGEV_SIGNAL
138 and
139 .I sevp\->sigev_signo
140 is not a valid signal number.
141 .TP
142 .B ENOMEM
143 Insufficient memory.
144 .PP
145 POSIX.1-2008 says that an implementation
146 .I may
147 generate an
148 .B EINVAL
149 .\" Linux does not do this
150 error if
151 .I sevp
152 is NULL, and the caller is not currently registered to receive
153 notifications for the queue
154 .IR mqdes .
155 .SH ATTRIBUTES
156 For an explanation of the terms used in this section, see
157 .BR attributes (7).
158 .ad l
159 .nh
160 .TS
161 allbox;
162 lbx lb lb
163 l l l.
164 Interface Attribute Value
165 T{
166 .BR mq_notify ()
167 T} Thread safety MT-Safe
168 .TE
169 .hy
170 .ad
171 .sp 1
172 .SH STANDARDS
173 POSIX.1-2001.
174 .SH NOTES
175 .\"
176 .SS C library/kernel differences
177 In the glibc implementation, the
178 .BR mq_notify ()
179 library function is implemented on top of the system call of the same name.
180 When
181 .I sevp
182 is NULL, or specifies a notification mechanism other than
183 .BR SIGEV_THREAD ,
184 the library function directly invokes the system call.
185 For
186 .BR SIGEV_THREAD ,
187 much of the implementation resides within the library,
188 rather than the kernel.
189 (This is necessarily so,
190 since the thread involved in handling the notification is one
191 that must be managed by the C library POSIX threads implementation.)
192 The implementation involves the use of a raw
193 .BR netlink (7)
194 socket and creates a new thread for each notification that is
195 delivered to the process.
196 .SH EXAMPLES
197 The following program registers a notification request for the
198 message queue named in its command-line argument.
199 Notification is performed by creating a thread.
200 The thread executes a function which reads one message from the
201 queue and then terminates the process.
202 .SS Program source
203 .\" SRC BEGIN (mq_notify.c)
204 .EX
205 #include <mqueue.h>
206 #include <pthread.h>
207 #include <signal.h>
208 #include <stdio.h>
209 #include <stdlib.h>
210 #include <unistd.h>
211
212 #define handle_error(msg) \e
213 do { perror(msg); exit(EXIT_FAILURE); } while (0)
214
215 static void /* Thread start function */
216 tfunc(union sigval sv)
217 {
218 struct mq_attr attr;
219 ssize_t nr;
220 void *buf;
221 mqd_t mqdes = *((mqd_t *) sv.sival_ptr);
222
223 /* Determine max. msg size; allocate buffer to receive msg */
224
225 if (mq_getattr(mqdes, &attr) == \-1)
226 handle_error("mq_getattr");
227 buf = malloc(attr.mq_msgsize);
228 if (buf == NULL)
229 handle_error("malloc");
230
231 nr = mq_receive(mqdes, buf, attr.mq_msgsize, NULL);
232 if (nr == \-1)
233 handle_error("mq_receive");
234
235 printf("Read %zd bytes from MQ\en", nr);
236 free(buf);
237 exit(EXIT_SUCCESS); /* Terminate the process */
238 }
239
240 int
241 main(int argc, char *argv[])
242 {
243 mqd_t mqdes;
244 struct sigevent sev;
245
246 if (argc != 2) {
247 fprintf(stderr, "Usage: %s <mq\-name>\en", argv[0]);
248 exit(EXIT_FAILURE);
249 }
250
251 mqdes = mq_open(argv[1], O_RDONLY);
252 if (mqdes == (mqd_t) \-1)
253 handle_error("mq_open");
254
255 sev.sigev_notify = SIGEV_THREAD;
256 sev.sigev_notify_function = tfunc;
257 sev.sigev_notify_attributes = NULL;
258 sev.sigev_value.sival_ptr = &mqdes; /* Arg. to thread func. */
259 if (mq_notify(mqdes, &sev) == \-1)
260 handle_error("mq_notify");
261
262 pause(); /* Process will be terminated by thread function */
263 }
264 .EE
265 .\" SRC END
266 .SH SEE ALSO
267 .BR mq_close (3),
268 .BR mq_getattr (3),
269 .BR mq_open (3),
270 .BR mq_receive (3),
271 .BR mq_send (3),
272 .BR mq_unlink (3),
273 .BR mq_overview (7),
274 .BR sigevent (7)