summaryrefslogtreecommitdiffstats
path: root/man/man3/mq_notify.3
diff options
context:
space:
mode:
Diffstat (limited to 'man/man3/mq_notify.3')
-rw-r--r--man/man3/mq_notify.3273
1 files changed, 273 insertions, 0 deletions
diff --git a/man/man3/mq_notify.3 b/man/man3/mq_notify.3
new file mode 100644
index 0000000..7c4dc50
--- /dev/null
+++ b/man/man3/mq_notify.3
@@ -0,0 +1,273 @@
+'\" t
+.\" Copyright (C) 2006 Michael Kerrisk <mtk.manpages@gmail.com>
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.TH mq_notify 3 2024-05-02 "Linux man-pages (unreleased)"
+.SH NAME
+mq_notify \- register for notification when a message is available
+.SH LIBRARY
+Real-time library
+.RI ( librt ", " \-lrt )
+.SH SYNOPSIS
+.nf
+.B #include <mqueue.h>
+.BR "#include <signal.h> " "/* Definition of SIGEV_* constants */"
+.P
+.BI "int mq_notify(mqd_t " mqdes ", const struct sigevent *" sevp );
+.fi
+.SH DESCRIPTION
+.BR mq_notify ()
+allows the calling process to register or unregister for delivery of
+an asynchronous notification when a new message arrives on
+the empty message queue referred to by the message queue descriptor
+.IR mqdes .
+.P
+The
+.I sevp
+argument is a pointer to a
+.I sigevent
+structure.
+For the definition and general details of this structure, see
+.BR sigevent (3type).
+.P
+If
+.I sevp
+is a non-null pointer, then
+.BR mq_notify ()
+registers the calling process to receive message notification.
+The
+.I sigev_notify
+field of the
+.I sigevent
+structure to which
+.I sevp
+points specifies how notification is to be performed.
+This field has one of the following values:
+.TP
+.B SIGEV_NONE
+A "null" notification: the calling process is registered as the target
+for notification, but when a message arrives, no notification is sent.
+.\" When is SIGEV_NONE useful?
+.TP
+.B SIGEV_SIGNAL
+Notify the process by sending the signal specified in
+.IR sigev_signo .
+See
+.BR sigevent (3type)
+for general details.
+The
+.I si_code
+field of the
+.I siginfo_t
+structure will be set to
+.BR SI_MESGQ .
+In addition,
+.\" I don't know of other implementations that set
+.\" si_pid and si_uid -- MTK
+.I si_pid
+will be set to the PID of the process that sent the message, and
+.I si_uid
+will be set to the real user ID of the sending process.
+.TP
+.B SIGEV_THREAD
+Upon message delivery, invoke
+.I sigev_notify_function
+as if it were the start function of a new thread.
+See
+.BR sigevent (3type)
+for details.
+.P
+Only one process can be registered to receive notification
+from a message queue.
+.P
+If
+.I sevp
+is NULL, and the calling process is currently registered to receive
+notifications for this message queue, then the registration is removed;
+another process can then register to receive a message notification
+for this queue.
+.P
+Message notification occurs only when a new message arrives and
+the queue was previously empty.
+If the queue was not empty at the time
+.BR mq_notify ()
+was called, then a notification will occur only after
+the queue is emptied and a new message arrives.
+.P
+If another process or thread is waiting to read a message
+from an empty queue using
+.BR mq_receive (3),
+then any message notification registration is ignored:
+the message is delivered to the process or thread calling
+.BR mq_receive (3),
+and the message notification registration remains in effect.
+.P
+Notification occurs once: after a notification is delivered,
+the notification registration is removed,
+and another process can register for message notification.
+If the notified process wishes to receive the next notification,
+it can use
+.BR mq_notify ()
+to request a further notification.
+This should be done before emptying all unread messages from the queue.
+(Placing the queue in nonblocking mode is useful for emptying
+the queue of messages without blocking once it is empty.)
+.SH RETURN VALUE
+On success
+.BR mq_notify ()
+returns 0; on error, \-1 is returned, with
+.I errno
+set to indicate the error.
+.SH ERRORS
+.TP
+.B EBADF
+The message queue descriptor specified in
+.I mqdes
+is invalid.
+.TP
+.B EBUSY
+Another process has already registered to receive notification
+for this message queue.
+.TP
+.B EINVAL
+.I sevp\->sigev_notify
+is not one of the permitted values; or
+.I sevp\->sigev_notify
+is
+.B SIGEV_SIGNAL
+and
+.I sevp\->sigev_signo
+is not a valid signal number.
+.TP
+.B ENOMEM
+Insufficient memory.
+.P
+POSIX.1-2008 says that an implementation
+.I may
+generate an
+.B EINVAL
+.\" Linux does not do this
+error if
+.I sevp
+is NULL, and the caller is not currently registered to receive
+notifications for the queue
+.IR mqdes .
+.SH ATTRIBUTES
+For an explanation of the terms used in this section, see
+.BR attributes (7).
+.TS
+allbox;
+lbx lb lb
+l l l.
+Interface Attribute Value
+T{
+.na
+.nh
+.BR mq_notify ()
+T} Thread safety MT-Safe
+.TE
+.SH VERSIONS
+.SS C library/kernel differences
+In the glibc implementation, the
+.BR mq_notify ()
+library function is implemented on top of the system call of the same name.
+When
+.I sevp
+is NULL, or specifies a notification mechanism other than
+.BR SIGEV_THREAD ,
+the library function directly invokes the system call.
+For
+.BR SIGEV_THREAD ,
+much of the implementation resides within the library,
+rather than the kernel.
+(This is necessarily so,
+since the thread involved in handling the notification is one
+that must be managed by the C library POSIX threads implementation.)
+The implementation involves the use of a raw
+.BR netlink (7)
+socket and creates a new thread for each notification that is
+delivered to the process.
+.SH STANDARDS
+POSIX.1-2008.
+.SH HISTORY
+POSIX.1-2001.
+.SH EXAMPLES
+The following program registers a notification request for the
+message queue named in its command-line argument.
+Notification is performed by creating a thread.
+The thread executes a function which reads one message from the
+queue and then terminates the process.
+.SS Program source
+.\" SRC BEGIN (mq_notify.c)
+.EX
+#include <mqueue.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+\&
+#define handle_error(msg) \e
+ do { perror(msg); exit(EXIT_FAILURE); } while (0)
+\&
+static void /* Thread start function */
+tfunc(union sigval sv)
+{
+ struct mq_attr attr;
+ ssize_t nr;
+ void *buf;
+ mqd_t mqdes = *((mqd_t *) sv.sival_ptr);
+\&
+ /* Determine max. msg size; allocate buffer to receive msg */
+\&
+ if (mq_getattr(mqdes, &attr) == \-1)
+ handle_error("mq_getattr");
+ buf = malloc(attr.mq_msgsize);
+ if (buf == NULL)
+ handle_error("malloc");
+\&
+ nr = mq_receive(mqdes, buf, attr.mq_msgsize, NULL);
+ if (nr == \-1)
+ handle_error("mq_receive");
+\&
+ printf("Read %zd bytes from MQ\en", nr);
+ free(buf);
+ exit(EXIT_SUCCESS); /* Terminate the process */
+}
+\&
+int
+main(int argc, char *argv[])
+{
+ mqd_t mqdes;
+ struct sigevent sev;
+\&
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <mq\-name>\en", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+\&
+ mqdes = mq_open(argv[1], O_RDONLY);
+ if (mqdes == (mqd_t) \-1)
+ handle_error("mq_open");
+\&
+ sev.sigev_notify = SIGEV_THREAD;
+ sev.sigev_notify_function = tfunc;
+ sev.sigev_notify_attributes = NULL;
+ sev.sigev_value.sival_ptr = &mqdes; /* Arg. to thread func. */
+ if (mq_notify(mqdes, &sev) == \-1)
+ handle_error("mq_notify");
+\&
+ pause(); /* Process will be terminated by thread function */
+}
+.EE
+.\" SRC END
+.SH SEE ALSO
+.BR mq_close (3),
+.BR mq_getattr (3),
+.BR mq_open (3),
+.BR mq_receive (3),
+.BR mq_send (3),
+.BR mq_unlink (3),
+.BR mq_overview (7),
+.BR sigevent (3type)