1MQ_NOTIFY(3) Linux Programmer's Manual MQ_NOTIFY(3)
2
3
4
6 mq_notify - register for notification when a message is available
7
9 #include <mqueue.h>
10
11 int mq_notify(mqd_t mqdes, const struct sigevent *sevp);
12
13 Link with -lrt.
14
16 mq_notify() allows the calling process to register or unregister for
17 delivery of an asynchronous notification when a new message arrives on
18 the empty message queue referred to by the message queue descriptor
19 mqdes.
20
21 The sevp argument is a pointer to a sigevent structure. For the defi‐
22 nition and general details of this structure, see sigevent(7).
23
24 If sevp is a non-null pointer, then mq_notify() registers the calling
25 process to receive message notification. The sigev_notify field of the
26 sigevent structure to which sevp points specifies how notification is
27 to be performed. This field has one of the following values:
28
29 SIGEV_NONE
30 A "null" notification: the calling process is registered as the
31 target for notification, but when a message arrives, no notifi‐
32 cation is sent.
33
34 SIGEV_SIGNAL
35 Notify the process by sending the signal specified in
36 sigev_signo. See sigevent(7) for general details. The si_code
37 field of the siginfo_t structure will be set to SI_MESGQ. In
38 addition, si_pid will be set to the PID of the process that sent
39 the message, and si_uid will be set to the real user ID of the
40 sending process.
41
42 SIGEV_THREAD
43 Upon message delivery, invoke sigev_notify_function as if it
44 were the start function of a new thread. See sigevent(7) for
45 details.
46
47 Only one process can be registered to receive notification from a mes‐
48 sage queue.
49
50 If sevp is NULL, and the calling process is currently registered to re‐
51 ceive notifications for this message queue, then the registration is
52 removed; another process can then register to receive a message notifi‐
53 cation for this queue.
54
55 Message notification occurs only when a new message arrives and the
56 queue was previously empty. If the queue was not empty at the time
57 mq_notify() was called, then a notification will occur only after the
58 queue is emptied and a new message arrives.
59
60 If another process or thread is waiting to read a message from an empty
61 queue using mq_receive(3), then any message notification registration
62 is ignored: the message is delivered to the process or thread calling
63 mq_receive(3), and the message notification registration remains in ef‐
64 fect.
65
66 Notification occurs once: after a notification is delivered, the noti‐
67 fication registration is removed, and another process can register for
68 message notification. If the notified process wishes to receive the
69 next notification, it can use mq_notify() to request a further notifi‐
70 cation. This should be done before emptying all unread messages from
71 the queue. (Placing the queue in nonblocking mode is useful for empty‐
72 ing the queue of messages without blocking once it is empty.)
73
75 On success mq_notify() returns 0; on error, -1 is returned, with errno
76 set to indicate the error.
77
79 EBADF The message queue descriptor specified in mqdes is invalid.
80
81 EBUSY Another process has already registered to receive notification
82 for this message queue.
83
84 EINVAL sevp->sigev_notify is not one of the permitted values; or
85 sevp->sigev_notify is SIGEV_SIGNAL and sevp->sigev_signo is not
86 a valid signal number.
87
88 ENOMEM Insufficient memory.
89
90 POSIX.1-2008 says that an implementation may generate an EINVAL error
91 if sevp is NULL, and the caller is not currently registered to receive
92 notifications for the queue mqdes.
93
95 For an explanation of the terms used in this section, see at‐
96 tributes(7).
97
98 ┌────────────────────────────────────────────┬───────────────┬─────────┐
99 │Interface │ Attribute │ Value │
100 ├────────────────────────────────────────────┼───────────────┼─────────┤
101 │mq_notify() │ Thread safety │ MT-Safe │
102 └────────────────────────────────────────────┴───────────────┴─────────┘
103
105 POSIX.1-2001.
106
108 C library/kernel differences
109 In the glibc implementation, the mq_notify() library function is imple‐
110 mented on top of the system call of the same name. When sevp is NULL,
111 or specifies a notification mechanism other than SIGEV_THREAD, the li‐
112 brary function directly invokes the system call. For SIGEV_THREAD,
113 much of the implementation resides within the library, rather than the
114 kernel. (This is necessarily so, since the thread involved in handling
115 the notification is one that must be managed by the C library POSIX
116 threads implementation.) The implementation involves the use of a raw
117 netlink(7) socket and creates a new thread for each notification that
118 is delivered to the process.
119
121 The following program registers a notification request for the message
122 queue named in its command-line argument. Notification is performed by
123 creating a thread. The thread executes a function which reads one mes‐
124 sage from the queue and then terminates the process.
125
126 Program source
127 #include <pthread.h>
128 #include <mqueue.h>
129 #include <stdio.h>
130 #include <stdlib.h>
131 #include <unistd.h>
132
133 #define handle_error(msg) \
134 do { perror(msg); exit(EXIT_FAILURE); } while (0)
135
136 static void /* Thread start function */
137 tfunc(union sigval sv)
138 {
139 struct mq_attr attr;
140 ssize_t nr;
141 void *buf;
142 mqd_t mqdes = *((mqd_t *) sv.sival_ptr);
143
144 /* Determine max. msg size; allocate buffer to receive msg */
145
146 if (mq_getattr(mqdes, &attr) == -1)
147 handle_error("mq_getattr");
148 buf = malloc(attr.mq_msgsize);
149 if (buf == NULL)
150 handle_error("malloc");
151
152 nr = mq_receive(mqdes, buf, attr.mq_msgsize, NULL);
153 if (nr == -1)
154 handle_error("mq_receive");
155
156 printf("Read %zd bytes from MQ\n", nr);
157 free(buf);
158 exit(EXIT_SUCCESS); /* Terminate the process */
159 }
160
161 int
162 main(int argc, char *argv[])
163 {
164 mqd_t mqdes;
165 struct sigevent sev;
166
167 if (argc != 2) {
168 fprintf(stderr, "Usage: %s <mq-name>\n", argv[0]);
169 exit(EXIT_FAILURE);
170 }
171
172 mqdes = mq_open(argv[1], O_RDONLY);
173 if (mqdes == (mqd_t) -1)
174 handle_error("mq_open");
175
176 sev.sigev_notify = SIGEV_THREAD;
177 sev.sigev_notify_function = tfunc;
178 sev.sigev_notify_attributes = NULL;
179 sev.sigev_value.sival_ptr = &mqdes; /* Arg. to thread func. */
180 if (mq_notify(mqdes, &sev) == -1)
181 handle_error("mq_notify");
182
183 pause(); /* Process will be terminated by thread function */
184 }
185
187 mq_close(3), mq_getattr(3), mq_open(3), mq_receive(3), mq_send(3),
188 mq_unlink(3), mq_overview(7), sigevent(7)
189
191 This page is part of release 5.12 of the Linux man-pages project. A
192 description of the project, information about reporting bugs, and the
193 latest version of this page, can be found at
194 https://www.kernel.org/doc/man-pages/.
195
196
197
198Linux 2021-03-22 MQ_NOTIFY(3)