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 mqd_t mq_notify(mqd_t mqdes, const struct sigevent *notification);
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 descriptor mqdes.
19
20 The notification argument is a pointer to a sigevent structure that is
21 defined something like the following:
22
23 union sigval { /* Data passed with notification */
24 int sival_int; /* Integer value */
25 void *sival_ptr; /* Pointer value */
26 };
27
28 struct sigevent {
29 int sigev_notify; /* Notification method */
30 int sigev_signo; /* Notification signal */
31 union sigval sigev_value; /* Data passed with
32 notification */
33 void (*sigev_notify_function) (union sigval);
34 /* Function for thread
35 notification */
36 void *sigev_notify_attributes;
37 /* Thread function attributes */
38 };
39
40 If notification is a non-NULL pointer, then mq_notify() registers the
41 calling process to receive message notification. The sigev_notify
42 field of the sigevent to which notification points specifies how noti‐
43 fication is to be performed. This field has one of the following val‐
44 ues:
45
46 SIGEV_NONE
47 A "null" notification: the calling process is registered as the
48 target for notification, but when a message arrives, no notifi‐
49 cation is sent.
50
51 SIGEV_SIGNAL
52 Notify the process by sending the signal specified in
53 sigev_signo. If the signal is caught with a signal handler that
54 was registered using the sigaction(2) SA_SIGINFO flag, then the
55 following fields are set in the siginfo_t structure that is
56 passed as the second argument of the handler: si_code is set to
57 SI_MESGQ; si_signo is set to the signal number; si_value is set
58 to the value specified in notification->sigev_value; si_pid is
59 set to the PID of the process that sent the message; and si_uid
60 is set to the real user ID of the sending process. The same
61 information is available if the signal is accepted using sig‐
62 waitinfo(2).
63
64 SIGEV_THREAD
65 Deliver notification by invoking notifica‐
66 tion->sigev_notify_function as the start function of a new
67 thread. The function is invoked with notification->sigev_value
68 as its sole argument. If notification->sigev_notify_attributes
69 is not NULL, then it should point to a pthread_attr_t structure
70 that defines attributes for the thread (see
71 pthread_attr_init(3)).
72
73 Only one process can be registered to receive notification from a mes‐
74 sage queue.
75
76 If notification is NULL, and the calling process is currently regis‐
77 tered to receive notifications for this message queue, then the regis‐
78 tration is removed; another process can then register to receive a mes‐
79 sage notification for this queue.
80
81 Message notification only occurs when a new message arrives and the
82 queue was previously empty. If the queue was not empty at the time
83 mq_notify() was called, then a notification will only occur after the
84 queue is emptied and a new message arrives.
85
86 If another process or thread is waiting to read a message from an empty
87 queue using mq_receive(3), then any message notification registration
88 is ignored: the message is delivered to the process or thread calling
89 mq_receive(3), and the message notification registration remains in
90 effect.
91
92 Notification occurs once: after a notification is delivered, the noti‐
93 fication registration is removed, and another process can register for
94 message notification. If the notified process wishes to receive the
95 next notification, it can use mq_notify() to request a further notifi‐
96 cation. This should be done before emptying all unread messages from
97 the queue. (Placing the queue in nonblocking mode is useful for empty‐
98 ing the queue of messages without blocking once it is empty.)
99
101 On success mq_notify() returns 0; on error, -1 is returned, with errno
102 set to indicate the error.
103
105 EBADF The descriptor specified in mqdes is invalid.
106
107 EBUSY Another process has already registered to receive notification
108 for this message queue.
109
110 EINVAL notification->sigev_notify is not one of the permitted values;
111 or notification->sigev_notify is SIGEV_SIGNAL and notifica‐
112 tion->sigev_signo is not a valid signal number.
113
114 ENOMEM Insufficient memory.
115
116 POSIX.1-2008 says that an implementation may generate an EINVAL error
117 if notification is NULL, and the caller is not currently registered to
118 receive notifications for the queue mqdes.
119
121 POSIX.1-2001.
122
124 The following program registers a notification request for the message
125 queue named in its command-line argument. Notification is performed by
126 creating a thread. The thread executes a function which reads one mes‐
127 sage from the queue and then terminates the process.
128
129 #include <pthread.h>
130 #include <mqueue.h>
131 #include <stdio.h>
132 #include <stdlib.h>
133 #include <unistd.h>
134
135 #define handle_error(msg) \
136 do { perror(msg); exit(EXIT_FAILURE); } while (0)
137
138 static void /* Thread start function */
139 tfunc(union sigval sv)
140 {
141 struct mq_attr attr;
142 ssize_t nr;
143 void *buf;
144 mqd_t mqdes = *((mqd_t *) sv.sival_ptr);
145
146 /* Determine max. msg size; allocate buffer to receive msg */
147
148 if (mq_getattr(mqdes, &attr) == -1)
149 handle_error("mq_getattr");
150 buf = malloc(attr.mq_msgsize);
151 if (buf == NULL)
152 handle_error("malloc");
153
154 nr = mq_receive(mqdes, buf, attr.mq_msgsize, NULL);
155 if (nr == -1)
156 handle_error("mq_receive");
157
158 printf("Read %ld bytes from MQ\n", (long) nr);
159 free(buf);
160 exit(EXIT_SUCCESS); /* Terminate the process */
161 }
162
163 int
164 main(int argc, char *argv[])
165 {
166 mqd_t mqdes;
167 struct sigevent not;
168
169 if (argc != 2) {
170 fprintf(stderr, "Usage: %s <mq-name>\n", argv[0]);
171 exit(EXIT_FAILURE);
172 }
173
174 mqdes = mq_open(argv[1], O_RDONLY);
175 if (mqdes == (mqd_t) -1)
176 handle_error("mq_open");
177
178 not.sigev_notify = SIGEV_THREAD;
179 not.sigev_notify_function = tfunc;
180 not.sigev_notify_attributes = NULL;
181 not.sigev_value.sival_ptr = &mqdes; /* Arg. to thread func. */
182 if (mq_notify(mqdes, ¬) == -1)
183 handle_error("mq_notify");
184
185 pause(); /* Process will be terminated by thread function */
186 }
187
189 mq_close(3), mq_getattr(3), mq_open(3), mq_receive(3), mq_send(3),
190 mq_unlink(3), mq_overview(7)
191
193 This page is part of release 3.25 of the Linux man-pages project. A
194 description of the project, and information about reporting bugs, can
195 be found at http://www.kernel.org/doc/man-pages/.
196
197
198
199Linux 2009-09-15 MQ_NOTIFY(3)