MQ_NOTIFY(3)

NOM
mq_notify - S'enregistrer pour la réception d'une notification de l'arrivée d'un nouveau message

SYNOPSIS
#include <mqueue.h>

mqd_t mq_notify(mqd_t mqdes, const struct sigevent *notification);

Utilisez -lrt à l'édition de liens.

DESCRIPTION
mq_notify() permet au processus appelant de s'enregistrer ou se désenregistrer de la délivrance d'une notification asynchrone lorsqu'un nouveau message arrive sur une file de messages vide référencée par le descripteur mqdes. L'argument notification est un pointeur vers une structure sigevent définie de la manière suivante :
union sigval {          /* Data passed with notification */
    int     sival_int;         /* Integer value */
    void   *sival_ptr;         /* Pointer value */
};
struct sigevent {
    int          sigev_notify; /* Notification method */
    int          sigev_signo;  /* Notification signal */
    union sigval sigev_value;  /* Data passed with notification */
    void       (*sigev_notify_function) (union sigval);
                               /* Function for thread notification */
    void        *sigev_notify_attributes;
                               /* Thread function attributes */
};

Si notification est un pointeur non-NULL, mq_notify() enregistre le processus appelant afin qu'il reçoive les notifications de message. Le champ sigev_notify de la structure sigevent sur laquelle pointe notification indique comment sera réalisée la notification. Ce champ peut prendre une des valeurs suivantes :

SIGEV_NONE
    Une notification « nulle » : le processus appelant est enregistré pour être le destinatairee d'une notification, mais lorsqu'un message arrive, aucune notification n'est envoyée.

SIGEV_SIGNAL
    Notifier le processus en envoyant le signal indiqué dans sigev_signo. Si le signal est intercepté par un gestionnaire de signaux qui a été enregistré en utilisant l'attribut SA_SIGINFO de sigaction(2), les champs suivants de la structure siginfo_t passée comme second argument au gestionnaire seront remplis : si_code prend la valeur SI_MESGQ ; si_signo prend le numéro du signal ; si_value prend la valeur contenue dans notification->sigev_value ; si_pid prend le PID du processus qui a envoyé le message ; si_uid prend l'UID réel du processus qui a envoyé le message. Les mêmes informations sont disponibles si le signal est accepté avec sigwaitinfo(2).

SIGEV_THREAD
    Délivrer une notification en invoquant notification->sigev_thread_function comme fonction de démarrage d'un nouveau thread. Cette fonction est invoquée avec notification->sigev_value comme seul argument. Si notification->sigev_notify_attributes n'est pas NULL, il doit pointer vers une structure pthread_attr_t qui définit les attributs du thread.

Un seul processus peut être enregistré pour revevoir les notifications d'une file de messages. Si notification est NULL et si le processus appelant est actuellement enregistré pour recevoir les notifications de cette file de messages, alors l'enregistrement est supprimé permettant à un autre processus de s'enregistrer pour recevoir les notifications de cette file. Une notification de message n'est créée que lorsqu'un nouveau message arrive et que la file est vide. Si la file n'est pas vide au moment où mq_notify() est appelée, la notification ne sera créée qu'après que la file ait été vidée et qu'un nouveau message arrive. Si un autre processus ou thread est en attente de lecture de message dans une file vide en utilisant mq_receive(3), tout enregistrement de notification de message est ignoré : le message est délivré au processus ou thread appelant mq_receive(3), et l'enregistrement de notification de message reste effectif. Une notification ne survient qu'une seule fois. Après qu'une notification ait été délivrée, l'enregistrement de la notification est supprimé. Un autre processus peut ainsi s'enregistrer pour une notification. Si le processus notifié souhaite recevoir une nouvelle notification, il peut utiliser mq_notify() pour demander une notification supplémentaire. Cela devrait être fait avant de vider tous les messages non lus de la file. (Placer la file en mode non bloquant est utile pour vider la file des messages sans qu'elle bloque une fois vide.)

VALEUR RENVOYÉE
Si elle réussit, mq_notify() renvoie 0 ; si elle échoue, elle renvoie -1 et renseigne errno en conséquence.

ERREURS

EBADF
    Le descripteur mqdes n'est pas valide.

EBUSY
    Un autre processus est déjà enregistré pour recevoir les notifications de cette file de messages.

EINVAL
    notification->sigev_notify n'est pas l'une des valeurs permises ; ou notification->sigev_notify vaut SIGEV_SIGNAL et notification->sigev_signo n'est pas un numéro de signal valide.

ENOMEM
    Mémoire insuffisante.

CONFORMITÉ
POSIX.1-2001.

EXEMPLE
Le programme suivant enregistre une demande de notification pour une file de messages dont le nom est fourni sur la ligne de commande. La notification est réalisée en créant un thread. Le thread exécute une fonction qui lit un message dans une file et qui termine le processus.
#include <pthread.h>
#include <mqueue.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define handle_error(msg) \
    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 %ld bytes from MQ\n", (long) nr);
    free(buf);
    exit(EXIT_SUCCESS);         /* Terminate the process */
}
int
main(int argc, char *argv[])
{
    mqd_t mqdes;
    struct sigevent not;
    assert(argc == 2);
    mqdes = mq_open(argv[1], O_RDONLY);
    if (mqdes == (mqd_t) -1)
        handle_error("mq_open");
    not.sigev_notify = SIGEV_THREAD;
    not.sigev_notify_function = tfunc;
    not.sigev_notify_attributes = NULL;
    not.sigev_value.sival_ptr = &mqdes;   /* Arg. to thread func. */
    if (mq_notify(mqdes, &not) == -1)
        handle_error("mq_notify");
    pause();    /* Process will be terminated by thread function */
}

VOIR AUSSI
mq_close(3), mq_getattr(3), mq_open(3), mq_receive(3), mq_send(3), mq_unlink(3), mq_overview(7)

TRADUCTION

Ce document est une traduction réalisée par Alain Portal <aportal AT univ-montp2 DOT fr> le 23 juillet 2006 et révisée le 17 juillet 2008.

L'équipe de traduction a fait le maximum pour réaliser une adaptation française de qualité. La version anglaise la plus à jour de ce document est toujours consultable via la commande : « LANG=C man 3 mq_notify ». N'hésitez pas à signaler à l'auteur ou au traducteur, selon le cas, toute erreur dans cette page de manuel.