tzfile.5, tzselect.8: sync from tzdb upstream
[man-pages.git] / man3 / mq_notify.3
blob6974074707ab061e8721585a49954325af9d650a
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 .PP
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 .PP
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 (7).
33 .PP
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 (7)
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 (7)
79 for details.
80 .PP
81 Only one process can be registered to receive notification
82 from a message queue.
83 .PP
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 .PP
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 .PP
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.
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
124 .B EBADF
125 The message queue descriptor specified in
126 .I mqdes
127 is invalid.
129 .B EBUSY
130 Another process has already registered to receive notification
131 for this message queue.
133 .B EINVAL
134 .I sevp\->sigev_notify
135 is not one of the permitted values; or
136 .I sevp\->sigev_notify
138 .B SIGEV_SIGNAL
140 .I sevp\->sigev_signo
141 is not a valid signal number.
143 .B ENOMEM
144 Insufficient memory.
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 .ad l
162 allbox;
163 lbx lb lb
164 l l l.
165 Interface       Attribute       Value
167 .BR mq_notify ()
168 T}      Thread safety   MT-Safe
172 .sp 1
173 .SH STANDARDS
174 POSIX.1-2001.
175 .SH NOTES
177 .SS C library/kernel differences
178 In the glibc implementation, the
179 .BR mq_notify ()
180 library function is implemented on top of the system call of the same name.
181 When
182 .I sevp
183 is NULL, or specifies a notification mechanism other than
184 .BR SIGEV_THREAD ,
185 the library function directly invokes the system call.
187 .BR SIGEV_THREAD ,
188 much of the implementation resides within the library,
189 rather than the kernel.
190 (This is necessarily so,
191 since the thread involved in handling the notification is one
192 that must be managed by the C library POSIX threads implementation.)
193 The implementation involves the use of a raw
194 .BR netlink (7)
195 socket and creates a new thread for each notification that is
196 delivered to the process.
197 .SH EXAMPLES
198 The following program registers a notification request for the
199 message queue named in its command-line argument.
200 Notification is performed by creating a thread.
201 The thread executes a function which reads one message from the
202 queue and then terminates the process.
203 .SS Program source
204 .\" SRC BEGIN (mq_notify.c)
206 #include <mqueue.h>
207 #include <pthread.h>
208 #include <signal.h>
209 #include <stdio.h>
210 #include <stdlib.h>
211 #include <unistd.h>
213 #define handle_error(msg) \e
214     do { perror(msg); exit(EXIT_FAILURE); } while (0)
216 static void                     /* Thread start function */
217 tfunc(union sigval sv)
219     struct mq_attr attr;
220     ssize_t nr;
221     void *buf;
222     mqd_t mqdes = *((mqd_t *) sv.sival_ptr);
224     /* Determine max. msg size; allocate buffer to receive msg */
226     if (mq_getattr(mqdes, &attr) == \-1)
227         handle_error("mq_getattr");
228     buf = malloc(attr.mq_msgsize);
229     if (buf == NULL)
230         handle_error("malloc");
232     nr = mq_receive(mqdes, buf, attr.mq_msgsize, NULL);
233     if (nr == \-1)
234         handle_error("mq_receive");
236     printf("Read %zd bytes from MQ\en", nr);
237     free(buf);
238     exit(EXIT_SUCCESS);         /* Terminate the process */
242 main(int argc, char *argv[])
244     mqd_t mqdes;
245     struct sigevent sev;
247     if (argc != 2) {
248         fprintf(stderr, "Usage: %s <mq\-name>\en", argv[0]);
249         exit(EXIT_FAILURE);
250     }
252     mqdes = mq_open(argv[1], O_RDONLY);
253     if (mqdes == (mqd_t) \-1)
254         handle_error("mq_open");
256     sev.sigev_notify = SIGEV_THREAD;
257     sev.sigev_notify_function = tfunc;
258     sev.sigev_notify_attributes = NULL;
259     sev.sigev_value.sival_ptr = &mqdes;   /* Arg. to thread func. */
260     if (mq_notify(mqdes, &sev) == \-1)
261         handle_error("mq_notify");
263     pause();    /* Process will be terminated by thread function */
266 .\" SRC END
267 .SH SEE ALSO
268 .BR mq_close (3),
269 .BR mq_getattr (3),
270 .BR mq_open (3),
271 .BR mq_receive (3),
272 .BR mq_send (3),
273 .BR mq_unlink (3),
274 .BR mq_overview (7),
275 .BR sigevent (7)