diff options
Diffstat (limited to '')
-rw-r--r-- | man3/mq_notify.3 | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/man3/mq_notify.3 b/man3/mq_notify.3 new file mode 100644 index 0000000..bb0d514 --- /dev/null +++ b/man3/mq_notify.3 @@ -0,0 +1,274 @@ +'\" t +.\" Copyright (C) 2006 Michael Kerrisk <mtk.manpages@gmail.com> +.\" +.\" SPDX-License-Identifier: Linux-man-pages-copyleft +.\" +.TH mq_notify 3 2023-07-20 "Linux man-pages 6.05.01" +.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 */" +.PP +.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 . +.PP +The +.I sevp +argument is a pointer to a +.I sigevent +structure. +For the definition and general details of this structure, see +.BR sigevent (7). +.PP +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 (7) +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 (7) +for details. +.PP +Only one process can be registered to receive notification +from a message queue. +.PP +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. +.PP +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. +.PP +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. +.PP +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. +.PP +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 +.sp 1 +.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 (7) |