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 non-blocking mode is useful for emp‐
98 tying 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 <assert.h>
132 #include <stdio.h>
133 #include <stdlib.h>
134 #include <unistd.h>
135
136 #define handle_error(msg) \
137 do { perror(msg); exit(EXIT_FAILURE); } while (0)
138
139 static void /* Thread start function */
140 tfunc(union sigval sv)
141 {
142 struct mq_attr attr;
143 ssize_t nr;
144 void *buf;
145 mqd_t mqdes = *((mqd_t *) sv.sival_ptr);
146
147 /* Determine max. msg size; allocate buffer to receive msg */
148
149 if (mq_getattr(mqdes, &attr) == -1)
150 handle_error("mq_getattr");
151 buf = malloc(attr.mq_msgsize);
152 if (buf == NULL)
153 handle_error("malloc");
154
155 nr = mq_receive(mqdes, buf, attr.mq_msgsize, NULL);
156 if (nr == -1)
157 handle_error("mq_receive");
158
159 printf("Read %ld bytes from MQ\n", (long) nr);
160 free(buf);
161 exit(EXIT_SUCCESS); /* Terminate the process */
162 }
163
164 int
165 main(int argc, char *argv[])
166 {
167 mqd_t mqdes;
168 struct sigevent not;
169
170 assert(argc == 2);
171
172 mqdes = mq_open(argv[1], O_RDONLY);
173 if (mqdes == (mqd_t) -1)
174 handle_error("mq_open");
175
176 not.sigev_notify = SIGEV_THREAD;
177 not.sigev_notify_function = tfunc;
178 not.sigev_notify_attributes = NULL;
179 not.sigev_value.sival_ptr = &mqdes; /* Arg. to thread func. */
180 if (mq_notify(mqdes, ¬) == -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)
189
191 This page is part of release 3.22 of the Linux man-pages project. A
192 description of the project, and information about reporting bugs, can
193 be found at http://www.kernel.org/doc/man-pages/.
194
195
196
197Linux 2009-03-31 MQ_NOTIFY(3)