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