]>
Commit | Line | Data |
---|---|---|
c11b1abf | 1 | .\" Copyright (C) 2006 Michael Kerrisk <mtk.manpages@gmail.com> |
80a99f39 | 2 | .\" |
5fbde956 | 3 | .\" SPDX-License-Identifier: Linux-man-pages-copyleft |
80a99f39 | 4 | .\" |
45186a5d | 5 | .TH MQ_NOTIFY 3 2021-03-22 "Linux man-pages (unreleased)" |
80a99f39 MK |
6 | .SH NAME |
7 | mq_notify \- register for notification when a message is available | |
7af1fbdc AC |
8 | .SH LIBRARY |
9 | Real-time library | |
8fc3b2cf | 10 | .RI ( librt ", " \-lrt ) |
80a99f39 MK |
11 | .SH SYNOPSIS |
12 | .nf | |
13 | .B #include <mqueue.h> | |
e04e6f76 | 14 | .BR "#include <signal.h> " "/* Definition of SIGEV_* constants */" |
68e4db0a | 15 | .PP |
0d5f6a62 | 16 | .BI "int mq_notify(mqd_t " mqdes ", const struct sigevent *" sevp ); |
80a99f39 MK |
17 | .fi |
18 | .SH DESCRIPTION | |
19 | .BR mq_notify () | |
c13182ef MK |
20 | allows the calling process to register or unregister for delivery of |
21 | an asynchronous notification when a new message arrives on | |
d9cb0d7d | 22 | the empty message queue referred to by the message queue descriptor |
80a99f39 | 23 | .IR mqdes . |
847e0d88 | 24 | .PP |
c13182ef | 25 | The |
0d5f6a62 | 26 | .I sevp |
c13182ef | 27 | argument is a pointer to a |
80a99f39 | 28 | .I sigevent |
168e3472 MK |
29 | structure. |
30 | For the definition and general details of this structure, see | |
31 | .BR sigevent (7). | |
08140a81 | 32 | .PP |
c13182ef | 33 | If |
0d5f6a62 | 34 | .I sevp |
b437fdd9 | 35 | is a non-null pointer, then |
80a99f39 MK |
36 | .BR mq_notify () |
37 | registers the calling process to receive message notification. | |
c13182ef MK |
38 | The |
39 | .I sigev_notify | |
80a99f39 MK |
40 | field of the |
41 | .I sigevent | |
168e3472 | 42 | structure to which |
0d5f6a62 | 43 | .I sevp |
80a99f39 MK |
44 | points specifies how notification is to be performed. |
45 | This field has one of the following values: | |
46 | .TP | |
47 | .B SIGEV_NONE | |
c13182ef | 48 | A "null" notification: the calling process is registered as the target |
80a99f39 MK |
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 | |
7cd24403 | 54 | .IR sigev_signo . |
168e3472 MK |
55 | See |
56 | .BR sigevent (7) | |
57 | for general details. | |
58 | The | |
80a99f39 | 59 | .I si_code |
168e3472 MK |
60 | field of the |
61 | .I siginfo_t | |
62 | structure will be set to | |
63 | .BR SI_MESGQ . | |
64 | In addition, | |
80a99f39 MK |
65 | .\" I don't know of other implementations that set |
66 | .\" si_pid and si_uid -- MTK | |
67 | .I si_pid | |
168e3472 | 68 | will be set to the PID of the process that sent the message, and |
80a99f39 | 69 | .I si_uid |
168e3472 | 70 | will be set to the real user ID of the sending process. |
80a99f39 MK |
71 | .TP |
72 | .B SIGEV_THREAD | |
168e3472 MK |
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. | |
80a99f39 MK |
79 | .PP |
80 | Only one process can be registered to receive notification | |
81 | from a message queue. | |
847e0d88 | 82 | .PP |
c13182ef | 83 | If |
0d5f6a62 | 84 | .I sevp |
80a99f39 MK |
85 | is NULL, and the calling process is currently registered to receive |
86 | notifications for this message queue, then the registration is removed; | |
c13182ef | 87 | another process can then register to receive a message notification |
80a99f39 | 88 | for this queue. |
847e0d88 | 89 | .PP |
33a0ccb2 | 90 | Message notification occurs only when a new message arrives and |
80a99f39 MK |
91 | the queue was previously empty. |
92 | If the queue was not empty at the time | |
93 | .BR mq_notify () | |
33a0ccb2 | 94 | was called, then a notification will occur only after |
80a99f39 | 95 | the queue is emptied and a new message arrives. |
847e0d88 | 96 | .PP |
80a99f39 MK |
97 | If another process or thread is waiting to read a message |
98 | from an empty queue using | |
fb186734 | 99 | .BR mq_receive (3), |
c13182ef | 100 | then any message notification registration is ignored: |
80a99f39 | 101 | the message is delivered to the process or thread calling |
fb186734 | 102 | .BR mq_receive (3), |
80a99f39 | 103 | and the message notification registration remains in effect. |
847e0d88 | 104 | .PP |
c13182ef MK |
105 | Notification occurs once: after a notification is delivered, |
106 | the notification registration is removed, | |
80a99f39 MK |
107 | and another process can register for message notification. |
108 | If the notified process wishes to receive the next notification, | |
c13182ef | 109 | it can use |
80a99f39 MK |
110 | .BR mq_notify () |
111 | to request a further notification. | |
112 | This should be done before emptying all unread messages from the queue. | |
ff40dbb3 | 113 | (Placing the queue in nonblocking mode is useful for emptying |
80a99f39 MK |
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 | |
c13182ef | 119 | .I errno |
80a99f39 MK |
120 | set to indicate the error. |
121 | .SH ERRORS | |
122 | .TP | |
123 | .B EBADF | |
d9cb0d7d | 124 | The message queue descriptor specified in |
80a99f39 MK |
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 | |
0d5f6a62 | 133 | .I sevp\->sigev_notify |
80a99f39 | 134 | is not one of the permitted values; or |
0d5f6a62 | 135 | .I sevp\->sigev_notify |
c13182ef MK |
136 | is |
137 | .B SIGEV_SIGNAL | |
138 | and | |
0d5f6a62 | 139 | .I sevp\->sigev_signo |
1954b6a9 | 140 | is not a valid signal number. |
80a99f39 MK |
141 | .TP |
142 | .B ENOMEM | |
143 | Insufficient memory. | |
8ea4ea95 MK |
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 | |
0d5f6a62 | 151 | .I sevp |
8ea4ea95 MK |
152 | is NULL, and the caller is not currently registered to receive |
153 | notifications for the queue | |
154 | .IR mqdes . | |
3964d56d ZL |
155 | .SH ATTRIBUTES |
156 | For an explanation of the terms used in this section, see | |
157 | .BR attributes (7). | |
c466875e MK |
158 | .ad l |
159 | .nh | |
3964d56d ZL |
160 | .TS |
161 | allbox; | |
c466875e | 162 | lbx lb lb |
3964d56d ZL |
163 | l l l. |
164 | Interface Attribute Value | |
165 | T{ | |
166 | .BR mq_notify () | |
167 | T} Thread safety MT-Safe | |
168 | .TE | |
c466875e MK |
169 | .hy |
170 | .ad | |
847e0d88 | 171 | .sp 1 |
3113c7f3 | 172 | .SH STANDARDS |
80a99f39 | 173 | POSIX.1-2001. |
c5aee027 MK |
174 | .SH NOTES |
175 | .\" | |
0722a578 | 176 | .SS C library/kernel differences |
c5aee027 MK |
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. | |
a14af333 | 196 | .SH EXAMPLES |
80a99f39 MK |
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. | |
c13182ef | 200 | The thread executes a function which reads one message from the |
80a99f39 | 201 | queue and then terminates the process. |
f30b7415 | 202 | .SS Program source |
e7d0bb47 | 203 | .EX |
80a99f39 MK |
204 | #include <pthread.h> |
205 | #include <mqueue.h> | |
80a99f39 MK |
206 | #include <stdio.h> |
207 | #include <stdlib.h> | |
208 | #include <unistd.h> | |
e04e6f76 | 209 | #include <signal.h> |
80a99f39 | 210 | |
d1a71985 | 211 | #define handle_error(msg) \e |
6a578b88 | 212 | do { perror(msg); exit(EXIT_FAILURE); } while (0) |
80a99f39 MK |
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 | ||
29059a65 | 224 | if (mq_getattr(mqdes, &attr) == \-1) |
6a578b88 | 225 | handle_error("mq_getattr"); |
80a99f39 | 226 | buf = malloc(attr.mq_msgsize); |
29059a65 | 227 | if (buf == NULL) |
6a578b88 | 228 | handle_error("malloc"); |
80a99f39 MK |
229 | |
230 | nr = mq_receive(mqdes, buf, attr.mq_msgsize, NULL); | |
29059a65 | 231 | if (nr == \-1) |
6a578b88 | 232 | handle_error("mq_receive"); |
80a99f39 | 233 | |
d1a71985 | 234 | printf("Read %zd bytes from MQ\en", nr); |
80a99f39 MK |
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; | |
0d5f6a62 | 243 | struct sigevent sev; |
80a99f39 | 244 | |
6b34fb3f | 245 | if (argc != 2) { |
d1a71985 | 246 | fprintf(stderr, "Usage: %s <mq\-name>\en", argv[0]); |
5a6194a4 | 247 | exit(EXIT_FAILURE); |
6b34fb3f | 248 | } |
80a99f39 MK |
249 | |
250 | mqdes = mq_open(argv[1], O_RDONLY); | |
29059a65 | 251 | if (mqdes == (mqd_t) \-1) |
6a578b88 | 252 | handle_error("mq_open"); |
80a99f39 | 253 | |
0d5f6a62 MK |
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) | |
6a578b88 | 259 | handle_error("mq_notify"); |
80a99f39 MK |
260 | |
261 | pause(); /* Process will be terminated by thread function */ | |
262 | } | |
e7d0bb47 | 263 | .EE |
47297adb | 264 | .SH SEE ALSO |
80a99f39 MK |
265 | .BR mq_close (3), |
266 | .BR mq_getattr (3), | |
267 | .BR mq_open (3), | |
268 | .BR mq_receive (3), | |
269 | .BR mq_send (3), | |
270 | .BR mq_unlink (3), | |
168e3472 MK |
271 | .BR mq_overview (7), |
272 | .BR sigevent (7) |