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