Première version
This commit is contained in:
commit
961ddc46da
618
lib/libmsg.3
Normal file
618
lib/libmsg.3
Normal file
@ -0,0 +1,618 @@
|
||||
'\" t
|
||||
.\" @(#)LIBMSG.3 1.0 00/07/04 SMA;
|
||||
.TH LIBMSG 3 "07 Apr 2000"
|
||||
.SH NOM
|
||||
LIBMSG (librairie de communication inter-processus par messages)
|
||||
.SH SYNOPSIS
|
||||
.LP
|
||||
.BI "cc [flag ...] file ... -lver -ldl -lnode -lshmem -ldatastr -lmsg [library ...]"
|
||||
.LP
|
||||
.BI "#include <msg.h>"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Library_Open ( int " Instance ", const char * " Context ", MSGT_Flags " Open_Mode " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Library_IsOpen ( void );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Library_Signal ( void );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Library_Close ( MSGT_Flags " Close_Mode " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Library_Stderr_Set ( FILE * " Out " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Library_Dump ( FILE * " Out " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Port_Open ( int " Id ", MSGT_Port ** " Port ", MSGT_Flags " Open_Mode " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Port_Lock ( MSGT_Port * " Port ", MSGT_Flags " Mode " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Port_Unlock ( MSGT_Port * " Port ", MSGT_Flags " Mode " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Port_Config ( MSGT_Port * " Port ", MSGT_Config " Tag ", " ... " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Port_Close ( MSGT_Port * " Port ", MSGT_Flags " Close_Mode " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_PortList_Open ( MSGT_PortList ** " PortList " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_PortList_Port_Add ( MSGT_PortList * " PortList ", MSGT_Port * " Port " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_PortList_Port_Remove ( MSGT_PortList * " PortList ", MSGT_Port * " Port " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_PortList_Close ( MSGT_PortList * " PortList " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_PortList_Listen ( MSGT_PortList * " PortList ", unsigned int " Type ", MSGT_Message ** " Msg ", MSGT_Flags " Flags " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Message_Alloc ( MSGT_Message ** " Msg ", size_t " Size " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Message_Config ( MSGT_Message * " Msg ", MSGT_Config " Tag ", " ... " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Message_Free ( MSGT_Message * " Msg " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Message_Send ( MSGT_Port * " From ", , MSGT_Port * " To ", MSGT_Message * " Msg " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Message_Receive ( MSGT_Port * " Port ", unsigned int " Type ", MSGT_Message ** " Msg ", MSGT_Flags " Flags " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Message_Reply ( MSGT_Message * " Msg " );"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Message_Return ( MSGT_Message * " Msg " );"
|
||||
.LP
|
||||
.SH "CODES RETOUR"
|
||||
.LP
|
||||
Toutes les fonctions constituant l'API de la librairie LIBMSG retournent un code de type
|
||||
.B MSGT_Status
|
||||
:
|
||||
.LP
|
||||
.RS 3
|
||||
-
|
||||
.B MSGS_OK
|
||||
: la fonction s'est correctement executee et a produit un resultat
|
||||
.LP
|
||||
-
|
||||
.B MSGS_KO
|
||||
: la fonction s'est correctement executee mais n'a pas produit de resultat
|
||||
.LP
|
||||
-
|
||||
.B MSGS_ERRAPI
|
||||
: la fonction a ete appelee avec des arguments de valeur incorrecte
|
||||
.LP
|
||||
-
|
||||
.B MSGS_ERRMEM
|
||||
: la fonction ne s'est pas correctement executee pour un probleme d'allocation memoire
|
||||
.LP
|
||||
-
|
||||
.B MSGS_ERRSHM
|
||||
: la fonction ne s'est pas correctement executee pour un probleme relatif a la memoire partagee
|
||||
.LP
|
||||
-
|
||||
.B MSGS_ERRSEM
|
||||
: la fonction ne s'est pas correctement executee pour un probleme relatif a l'utilisation des semaphores
|
||||
.LP
|
||||
-
|
||||
.B MSGS_ERRSIG
|
||||
: une operation sur semaphore a ete interrompue par un signal
|
||||
.LP
|
||||
-
|
||||
.B MSGS_ERRNOWAIT
|
||||
: une operation sur semaphore n'a pas pu etre realisee et le mode d'operation est sans attente
|
||||
.LP
|
||||
-
|
||||
.B DSS_ERRDLL
|
||||
: la fonction ne s'est pas correctement executee pour un probleme de chargement dynamique d'objet
|
||||
.LP
|
||||
.RS -3
|
||||
.I NB
|
||||
: la macro
|
||||
.B MSG_ERROR()
|
||||
permet de tester si un code retour correspond a une erreur.
|
||||
.LP
|
||||
En cas d'erreur, la variable MSG_Error_Message contient un message du type :
|
||||
.LP
|
||||
.RS 3
|
||||
Error <Nom fonction> : <message d'erreur>
|
||||
.RS -3
|
||||
.LP
|
||||
Pour les fonctions de reception de messages, 3 codes retour supplementaires ont ete definis :
|
||||
.LP
|
||||
.RS 3
|
||||
-
|
||||
.B MSGS_NO_MSG
|
||||
si aucun message n'a ete trouve dans le(s) port(s) de messages ecoute(s)
|
||||
.LP
|
||||
-
|
||||
.B MSGS_BAD_TYPE
|
||||
si des messages sont presents mais qu'aucun ne correspond au type de message demande.
|
||||
.LP
|
||||
-
|
||||
.B MSGS_SIGNAL
|
||||
si l'ecoute du port a ete interrompue par un signal systeme.
|
||||
.RS -3
|
||||
.LP
|
||||
.SH "FONCTIONS"
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Library_Open ( int " Instance ", const char * " Context ", MSGT_Flags " Open_Mode " );"
|
||||
.RS 3
|
||||
.LP
|
||||
La librairie LIBMSG implemente une base qui reference tous les ports de messages et tous les messages crees.
|
||||
.LP
|
||||
Cette fonction permet donc d'acceder a toutes ces ressources pour un contexte et une instance donnes designes par leur nom
|
||||
.I Context
|
||||
et
|
||||
.I Instance
|
||||
:
|
||||
.LP
|
||||
.RS 3
|
||||
- en ouverture simple si
|
||||
.I Open_Mode
|
||||
vaut
|
||||
.B MSGD_OPEN
|
||||
.LP
|
||||
- en creation si
|
||||
.I Open_Mode
|
||||
vaut
|
||||
.B MSGD_CREATE
|
||||
.RS -3
|
||||
.LP
|
||||
.I NB
|
||||
: l'indicateur d'ouverture
|
||||
.I Open_Mode
|
||||
pourra etre combinee avec un mode de debugging (
|
||||
.B MSGD_DEBUG_NONE
|
||||
: aucun message d'erreur n'est affiche
|
||||
.LP
|
||||
.B MSGD_DEBUG
|
||||
: les messages d'erreur generes par la librairie LIBMSG sont affiches sur la sortie standard d'erreur
|
||||
.LP
|
||||
.B MSGD_DEBUG_ALL
|
||||
: les messages d'erreur generes par toutes les librairies sous-jacentes a la LIBMSG sont affiches sur la sortie standard d'erreur
|
||||
.LP
|
||||
.I NB
|
||||
: l'ouverture de la librairie en creation est reservee aux administrateurs.
|
||||
.LP
|
||||
L'ouverture de la librairie est obligatoire avant d'utiliser toute autre fonction de la librairie LIBMSG.
|
||||
.LP
|
||||
.RS -3
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Library_Signal ( void );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet d'informer la librairie LIBMSG de la reception d'un signal systeme.
|
||||
.LP
|
||||
.I NB
|
||||
: cette fonction sera utile a l'utilisateur pour eviter que le processus reste bloque sur une attente de message malgre la reception de signal.
|
||||
.RS -3
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Library_IsOpen ( void );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet de tester si une instance de la librairie LIBMSG a deja ete ouverte.
|
||||
.RS -3
|
||||
.LP
|
||||
.BI "MSGT_Status MSG_Library_Close ( MSGT_Flags " Close_Mode " );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet de fermer toutes les ressources de l'instance de la librairie ouverte :
|
||||
.LP
|
||||
.RS 3
|
||||
- fermeture simple si
|
||||
.I Close_Mode
|
||||
vaut
|
||||
.B MSGD_CLOSE
|
||||
.LP
|
||||
- destruction si
|
||||
.I Close_Mode
|
||||
vaut
|
||||
.B MSGD_DESTROY
|
||||
.RS -3
|
||||
.LP
|
||||
.I NB
|
||||
: l'utilisation du parametre
|
||||
.B MSGD_DESTROY
|
||||
est reservee aux administrateurs.
|
||||
.LP
|
||||
.RS -3
|
||||
.BI "MSGT_Status MSG_Library_Dump ( FILE * " Out " );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet d'afficher toutes les ressources de l'instance de la librairie ouverte.
|
||||
.LP
|
||||
L'argument
|
||||
.I Out
|
||||
designe le flux de sortie de l'affichage.
|
||||
.LP
|
||||
.RS -3
|
||||
.BI "MSGT_Status MSG_Port_Open ( int " Id ", MSGT_Port ** " Port ", MSGT_Flags " Open_Mode " );"
|
||||
.LP
|
||||
.RS 3
|
||||
Cette fonction permet d'ouvrir un port de messages.
|
||||
.LP
|
||||
Elle requiert les arguments suivants :
|
||||
.RS 3
|
||||
.LP
|
||||
* (In)
|
||||
.I Id
|
||||
: l'identifiant numerique du port de messages
|
||||
.LP
|
||||
* (Out)
|
||||
.I Port
|
||||
: l'adresse d'un pointeur sur le port de messages
|
||||
.LP
|
||||
* (In)
|
||||
.I Open_Mode
|
||||
: le mode d'ouverture du port de messages
|
||||
.LP
|
||||
.RS 3
|
||||
- en ouverture simple si
|
||||
.I Open_Mode
|
||||
vaut
|
||||
.B MSGD_OPEN
|
||||
.LP
|
||||
- en creation si
|
||||
.I Open_Mode
|
||||
vaut
|
||||
.B MSGD_CREATE
|
||||
.RS -3
|
||||
.RS -3
|
||||
.LP
|
||||
.RS -3
|
||||
.BI "MSGT_Status MSG_Port_Lock ( MSGT_Port * " Port ", MSGT_Flags " Mode " );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet de verrouiller un port de messages.
|
||||
.LP
|
||||
Elle requiert les arguments suivants :
|
||||
.LP
|
||||
.RS 3
|
||||
* (In)
|
||||
.I Port
|
||||
: un pointeur sur le port de messages a verrouiller
|
||||
.LP
|
||||
* (In)
|
||||
.I Mode
|
||||
: le mode de verrouillage (
|
||||
.B MSGD_READ
|
||||
ou
|
||||
.B MSGD_WRITE
|
||||
)
|
||||
.LP
|
||||
.RS -3
|
||||
.LP
|
||||
.RS -3
|
||||
.BI "MSGT_Status MSG_Port_Unlock ( MSGT_Port * " Port ", MSGT_Flags " Mode " );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet d'oter le verrou pose sur un port de messages.
|
||||
.LP
|
||||
Elle requiert les arguments suivants :
|
||||
.LP
|
||||
.RS 3
|
||||
* (In)
|
||||
.I Port
|
||||
: un pointeur sur le port de messages a deverrouiller
|
||||
.LP
|
||||
* (In)
|
||||
.I Mode
|
||||
: le mode dans lequel le port est verrouille (
|
||||
.B MSGD_READ
|
||||
ou
|
||||
.B MSGD_WRITE
|
||||
)
|
||||
.LP
|
||||
.RS -3
|
||||
.LP
|
||||
.RS -3
|
||||
.BI "MSGT_Status MSG_Port_Config ( MSGT_Port * " Port ", MSGT_Config " Tag ", " ... " );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet de configurer un port de messages.
|
||||
.LP
|
||||
Elle requiert les arguments suivants :
|
||||
.LP
|
||||
.RS 3
|
||||
* (In)
|
||||
.I Port
|
||||
: un pointeur sur le port de messages a configurer
|
||||
.LP
|
||||
* (In)
|
||||
.I Tag
|
||||
: le type de configuration (
|
||||
.B MSGD_CONFIG_SIZE
|
||||
)
|
||||
.LP
|
||||
* (In)
|
||||
.I ...
|
||||
: la ou les valeurs utiles (fonction du type de configuration)
|
||||
.LP
|
||||
.RS -3
|
||||
.LP
|
||||
.RS -3
|
||||
.BI "MSGT_Status MSG_Port_Close ( MSGT_Port * " Port ", MSGT_Flags " Close_Mode " );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet de fermer un port de messages.
|
||||
.LP
|
||||
Elle requiert les arguments suivants :
|
||||
.RS 3
|
||||
.LP
|
||||
* (In)
|
||||
.I Port
|
||||
: un pointeur sur le port de messages a fermer
|
||||
.LP
|
||||
* (In)
|
||||
.I Close_Mode
|
||||
: le mode de fermeture du port de messages
|
||||
.LP
|
||||
.RS 3
|
||||
- fermeture simple si
|
||||
.I Close_Mode
|
||||
vaut
|
||||
.B MSGD_CLOSE
|
||||
.LP
|
||||
- destruction si
|
||||
.I Close_Mode
|
||||
vaut
|
||||
.B MSGD_DESTROY
|
||||
.RS -3
|
||||
.RS -3
|
||||
.LP
|
||||
.RS -3
|
||||
.BI "MSGT_Status MSG_PortList_Open ( MSGT_PortList ** " PortList " );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet d'ouvrir une liste de ports de messages.
|
||||
.LP
|
||||
L'argument
|
||||
.I PortList
|
||||
est l'adresse d'un pointeur sur la liste de port a creer.
|
||||
.LP
|
||||
.I NB
|
||||
: une liste de ports permet a un processus d'ecouter plusieurs ports de messages simultanement.
|
||||
Une liste de ports n'est pas partageable entre les processus.
|
||||
.LP
|
||||
.RS -3
|
||||
.BI "MSGT_Status MSG_PortList_Port_Add ( MSGT_PortList * " PortList ", MSGT_Port * " Port " );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet d'ajouter un port de messages a une liste de ports.
|
||||
.LP
|
||||
Elle requiert les arguments suivants :
|
||||
.LP
|
||||
.RS 3
|
||||
* (In)
|
||||
.I PortList
|
||||
: un pointeur sur une liste de ports
|
||||
.LP
|
||||
* (In)
|
||||
.I Port
|
||||
: un pointeur sur le port de messages a ajouter
|
||||
.LP
|
||||
.RS -3
|
||||
.LP
|
||||
.RS -3
|
||||
.BI "MSGT_Status MSG_PortList_Port_Remove ( MSGT_PortList * " PortList ", MSGT_Port * " Port " );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet de retirer un port de messages d'une liste de ports.
|
||||
.LP
|
||||
Elle requiert les arguments suivants :
|
||||
.LP
|
||||
.RS 3
|
||||
* (In)
|
||||
.I PortList
|
||||
: un pointeur sur une liste de ports
|
||||
.LP
|
||||
* (In)
|
||||
.I Port
|
||||
: un pointeur sur le port de messages a retirer
|
||||
.LP
|
||||
.RS -3
|
||||
.LP
|
||||
.RS -3
|
||||
.BI "MSGT_Status MSG_PortList_Close ( MSGT_PortList * " PortList " );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet de detruire une liste de ports de messages.
|
||||
.LP
|
||||
L'argument
|
||||
.I PortList
|
||||
est un pointeur sur la liste de port a supprimer.
|
||||
.LP
|
||||
.I NB
|
||||
: lorsqu'un processus ajoute un port de messages a sa liste de ports, le port de messages memorise le fait que le processus doit etre averti si un message y est ajoute ou retire.
|
||||
Il est donc important que chaque processus detruise explicitement toutes les listes de ports qu'il a creees lorsque celles-ci ne sont plus utilisees.
|
||||
.LP
|
||||
.RS -3
|
||||
.BI "MSGT_Status MSG_PortList_Listen ( MSGT_PortList * " PortList ", unsigned int " Type ", MSGT_Message ** " Msg ", MSGT_Flags " Flags " );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet de receptionner un message a partir d'une liste de ports.
|
||||
La notion d'ecoute correspond au fait qu'un processus pourra se mettre en attente jusqu'a ce qu'un message soit envoye sur l'un des ports.
|
||||
.LP
|
||||
Elle requiert les arguments suivants :
|
||||
.LP
|
||||
.RS 3
|
||||
* (In)
|
||||
.I Port
|
||||
: un pointeur sur la liste de ports
|
||||
.LP
|
||||
* (In)
|
||||
.I Type
|
||||
: le type du message a receptionner (la valeur
|
||||
.B MSGD_NO_TYPE
|
||||
permet de ne specifier aucun type en particulier)
|
||||
.LP
|
||||
* (Out)
|
||||
.I Msg
|
||||
: l'adresse d'un pointeur sur le message a receptionner.
|
||||
.LP
|
||||
* (In)
|
||||
.I Flags
|
||||
: le type d'ecoute (avec attente :
|
||||
.B MSGD_WAIT
|
||||
, sans attente :
|
||||
.B MSGD_NOWAIT
|
||||
)
|
||||
.LP
|
||||
.RS -3
|
||||
.I NB
|
||||
: pour une ecoute avec attente, un processus sera reveille a chaque fois qu'un message arrive dans l'un des ports de la liste. Il pourra toutefois se remettre en attente si le message a ete receptionne par un autre processus ou bien si son type n'est pas celui demande.
|
||||
.LP
|
||||
.I NB
|
||||
: la recherche des messages dans les differents ports de la liste s'effectue dans l'ordre dans lequel ils ont ete ajoute a la liste.
|
||||
.LP
|
||||
.RS -3
|
||||
.BI "MSGT_Status MSG_Message_Alloc ( MSGT_Message ** " Msg ", size_t " Size " );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet de creer un message et d'allouer de la memoire pour les donnees associees au message.
|
||||
.LP
|
||||
Elle requiert les arguments suivants :
|
||||
.LP
|
||||
.RS 3
|
||||
* (Out)
|
||||
.I Msg
|
||||
: l'adresse d'un pointeur sur le message a creer
|
||||
.LP
|
||||
* (In)
|
||||
.I Size
|
||||
: la taille des donnees du message
|
||||
.RS -3
|
||||
.LP
|
||||
.I NB
|
||||
: l'utilisateur pourra modifier a sa guise la zone de donnees du message pointee par le champ
|
||||
.B Data
|
||||
du message.
|
||||
Il veillera toutefois a ne pas deborder en dehors de cette zone auquel cas le fonctionnement de la librairie pourrait etre corrompue.
|
||||
.LP
|
||||
.RS -3
|
||||
.BI "MSGT_Status MSG_Message_Config ( MSGT_Message * " Msg ", MSGT_Config " Tag ", " ... " );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet de configurer un message.
|
||||
.LP
|
||||
Elle requiert les arguments suivants :
|
||||
.LP
|
||||
.RS 3
|
||||
* (In)
|
||||
.I Msg
|
||||
: un pointeur sur le message a configurer
|
||||
.LP
|
||||
* (In)
|
||||
.I Tag
|
||||
: le type de configuration (
|
||||
.B MSGD_CONFIG_TYPE
|
||||
,
|
||||
.B MSGD_CONFIG_PRIORITY
|
||||
)
|
||||
.LP
|
||||
* (In)
|
||||
.I ...
|
||||
: la ou les valeurs utiles (fonction du type de configuration)
|
||||
.RS -3
|
||||
.LP
|
||||
.RS -3
|
||||
.BI "MSGT_Status MSG_Message_Free ( MSGT_Message * " Msg " );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet de supprimer un message de la base de la librairie LIBMSG.
|
||||
.LP
|
||||
L'argument
|
||||
.I Msg
|
||||
est un pointeur sur le message a supprimer.
|
||||
.LP
|
||||
.I NB
|
||||
: l'utilisateur veillera a ne pas supprimer les messages de maniere inconsideree, ceux-ci pouvant etre en cours d'envoi dans un port de messages.
|
||||
.LP
|
||||
Les regles d'usage veulent que ce soit le processus initiateur d'un message qui le supprime.
|
||||
Dans le cas ou les messages ne sont pas renvoyes au processus initiateur, c'est le processus qui receptionne le message qui le supprimera.
|
||||
.LP
|
||||
.RS -3
|
||||
.BI "MSGT_Status MSG_Message_Send ( MSGT_Port * " From ", , MSGT_Port * " To ", MSGT_Message * " Msg " );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet d'envoyer un message dans un port de messages.
|
||||
.LP
|
||||
Elle requiert les arguments suivants :
|
||||
.LP
|
||||
.RS 3
|
||||
* (In)
|
||||
.I From
|
||||
: un pointeur sur le port de l'emetteur du message
|
||||
.LP
|
||||
* (In)
|
||||
.I To
|
||||
: un pointeur sur le port destinataire du message
|
||||
.LP
|
||||
* (In)
|
||||
.I Msg
|
||||
: un pointeur sur le message a envoyer
|
||||
.LP
|
||||
.RS -3
|
||||
.I NB
|
||||
: un message ne pourra pas etre envoye simultanement dans plusieurs ports de messages.
|
||||
.LP
|
||||
.RS -3
|
||||
.BI "MSGT_Status MSG_Message_Receive ( MSGT_Port * " Port ", unsigned int " Type ", MSGT_Message ** " Msg ", MSGT_Flags " Flags " );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet de receptionner un message dans un port de messages.
|
||||
.LP
|
||||
Elle requiert les arguments suivants :
|
||||
.LP
|
||||
.RS 3
|
||||
* (In)
|
||||
.I Port
|
||||
: un pointeur sur le port de messages a ecouter
|
||||
.LP
|
||||
* (In)
|
||||
.I Type
|
||||
: le type du message a receptionner (la valeur
|
||||
.B MSGD_NO_TYPE
|
||||
permet de ne specifier aucun type en particulier)
|
||||
.LP
|
||||
* (Out)
|
||||
.I Msg
|
||||
: l'adresse d'un pointeur sur le message a receptionner.
|
||||
.LP
|
||||
* (In)
|
||||
.I Flags
|
||||
: le type d'ecoute (avec attente :
|
||||
.B MSGD_WAIT
|
||||
, sans attente :
|
||||
.B MSGD_NOWAIT
|
||||
)
|
||||
.LP
|
||||
.RS -3
|
||||
.I NB
|
||||
: la reception d'un message ne fait que retirer celui-ci du port de messages.
|
||||
Le message n'est donc pas supprime et pourra en consequence etre envoye a nouveau dans une autre port de messages.
|
||||
.LP
|
||||
Pour une reception avec attente, un processus sera reveille a chaque fois qu'un message arrive dans le port de la liste.
|
||||
.LP
|
||||
Independamment du type demande, les messages sont receptionnes selon leur priorite puis selon leur ordre d'envoi.
|
||||
.LP
|
||||
.RS -3
|
||||
.BI "MSGT_Status MSG_Message_Reply ( MSGT_Message * " Msg " );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet de renvoyer un message a son envoyeur.
|
||||
.LP
|
||||
.I NB
|
||||
: l'envoyeur devra alors avoir precise l'identifiant de son port d'ecoute dans le champ
|
||||
.B From
|
||||
du message
|
||||
.I Msg
|
||||
.
|
||||
.LP
|
||||
.RS -3
|
||||
.BI "MSGT_Status MSG_Message_Return ( MSGT_Message * " Msg " );"
|
||||
.RS 3
|
||||
.LP
|
||||
Cette fonction permet de renvoyer un message au processus initiateur du message (different de l'envoyeur si le message passe entre plusieurs mains.
|
||||
.LP
|
||||
.I NB
|
||||
: l'initiateur du message devra alors avoir precise l'identifiant de son port d'ecoute dans le champ
|
||||
.B Init
|
||||
du message
|
||||
.I Msg
|
||||
.
|
||||
.LP
|
||||
.RS -3
|
3181
lib/libmsg.c
Normal file
3181
lib/libmsg.c
Normal file
File diff suppressed because it is too large
Load Diff
BIN
lib/libmsg.doc
Normal file
BIN
lib/libmsg.doc
Normal file
Binary file not shown.
118
lib/libmsg.h
Normal file
118
lib/libmsg.h
Normal file
@ -0,0 +1,118 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/sem.h>
|
||||
#include <ver.h>
|
||||
#include <node.h>
|
||||
#include <datastr.h>
|
||||
#include <msg.h>
|
||||
|
||||
extern char * strdup (const char *);
|
||||
|
||||
int MSG_Signal_Received;
|
||||
|
||||
/* Tous les heaps créés via la librairie LIBMSG seront préfixés par le nom suivant */
|
||||
|
||||
#define MSG_PREFIX "MSG"
|
||||
|
||||
/* Nom du fichier à charger pour accéder aux fonctions manager d'une data structure créée par la LIBMSG */
|
||||
|
||||
#define MSG_FILE_MANAGER "libmsg.so"
|
||||
|
||||
/*
|
||||
Heap dans lequel sera stockée la base de la librairie LIBMSG :
|
||||
Ce heap ne contient que la structure MSGT_Base qui permet de référencer
|
||||
la liste des ports de messages.
|
||||
|
||||
Ce heap ne sera constitué que d'une unique segment très petit.
|
||||
*/
|
||||
|
||||
#define MSG_BASE_HEAP_NAME "BASE"
|
||||
#define MSG_BASE_HEAP_SEGMENT_SIZE 100
|
||||
|
||||
/*
|
||||
Heap dans lequel sera stockée la liste des ports de messages :
|
||||
Ce heap ne contient que la structure MSGT_Base qui permet de référencer
|
||||
la liste des ports de messages.
|
||||
Ce heap n'a pas besoin besoin d'être très grand.
|
||||
*/
|
||||
|
||||
#define MSG_PORT_LIST_NAME "PORT_REF"
|
||||
#define MSG_PORT_LIST_SEGMENT_SIZE 10240
|
||||
|
||||
/*
|
||||
Heap sous-jacent à un port de messages :
|
||||
|
||||
Un port de messages est une data structure qui ne contient que sa racine, les
|
||||
noeuds étant stockés par ailleurs. On peut donc se contenter d'un petit segment.
|
||||
*/
|
||||
|
||||
#define MSG_PORT_SEGMENT_SIZE 1024
|
||||
|
||||
/*
|
||||
Heap dans lequel seront alloués les messages :
|
||||
|
||||
Ce heap étant amené à grandir rapidemment, il vaut mieux choisir
|
||||
une taille importante par segment afin de limiter le nombre de segments.
|
||||
*/
|
||||
|
||||
#define MSG_MESSAGE_HEAP_NAME "MSG_REF"
|
||||
#define MSG_MESSAGE_HEAP_SEGMENT_SIZE 1024000
|
||||
|
||||
/* Utilisation des sémaphores pour l'écoute des ports de messages ou des liste de ports */
|
||||
|
||||
struct sembuf MSG_SemOp_Listen [2] = { {0, -1, 0}, {0, 1, 0} }; /* Opération d'écoute */
|
||||
|
||||
struct sembuf MSG_SemOp_Receive [1] = { {0, -1, IPC_NOWAIT} }; /* Opération de retrait de message */
|
||||
|
||||
struct sembuf MSG_SemOp_Add [1] = { {0, 1, IPC_NOWAIT} }; /* Opération d'ajout de message */
|
||||
|
||||
/* Utilisation des sémaphores pour verrouiller les ports de messages */
|
||||
|
||||
struct sembuf MSG_SemOp_SSL [2] = { {0, -1, SEM_UNDO}, {0, 2, SEM_UNDO} };
|
||||
struct sembuf MSG_SemOp_RSL [2] = { {0, -2, SEM_UNDO|IPC_NOWAIT}, {0, 1, SEM_UNDO|IPC_NOWAIT} };
|
||||
struct sembuf MSG_SemOp_SEL [2] = { {0, -1, SEM_UNDO}, {0, 0, SEM_UNDO} };
|
||||
struct sembuf MSG_SemOp_REL [2] = { {0, 0, SEM_UNDO|IPC_NOWAIT}, {0, 1, SEM_UNDO|IPC_NOWAIT} };
|
||||
|
||||
/* Compteur d'ouverture de la librairie */
|
||||
|
||||
unsigned int MSG_Open_Counter = 0;
|
||||
|
||||
/* Flux de sortie des messages d'erreur générés par la librairie */
|
||||
|
||||
FILE * MSG_stderr;
|
||||
|
||||
typedef union semun {
|
||||
int val;
|
||||
struct semid_ds * buf;
|
||||
unsigned short int * array;
|
||||
} semun;
|
||||
|
||||
NDT_Status MSG_Base_Port_List_Manager (va_list);
|
||||
|
||||
NDT_Status MSG_Semaphore_List_Manager (va_list args_ptr);
|
||||
|
||||
NDT_Status MSG_PortList_Manager (va_list args_ptr);
|
||||
|
||||
NDT_Status MSG_MessageQueue_Manager (va_list);
|
||||
|
||||
MSGT_Status MSG_ShareLock_Set (int);
|
||||
|
||||
MSGT_Status MSG_ShareLock_Release (int);
|
||||
|
||||
MSGT_Status MSG_ExclusiveLock_Set (int);
|
||||
|
||||
MSGT_Status MSG_ExclusiveLock_Release (int);
|
||||
|
||||
MSGT_Status MSG_Semaphore_Operate (int, struct sembuf *, unsigned int);
|
||||
|
||||
void MSG_Error_Print ( void );
|
||||
|
||||
static char * MSG_Name_Prefix (const char * Name);
|
||||
|
||||
char * MSG_LockStatus_Get (int SemID);
|
516
lib/msg.h
Normal file
516
lib/msg.h
Normal file
@ -0,0 +1,516 @@
|
||||
#ifndef _LIBMSG
|
||||
#define _LIBMSG
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <ver.h>
|
||||
#include <node.h>
|
||||
#include <shmem.h>
|
||||
#include <datastr.h>
|
||||
|
||||
/* Code retour des fonctions constituant l'API */
|
||||
|
||||
typedef long MSGT_Status;
|
||||
|
||||
#define MSGS_OK DSS_OK /* La fonction s'est correctement exécutée et a produit un résultat */
|
||||
#define MSGS_KO DSS_KO /* La fonction s'est correctement exécutée mais n'a pas produit de résultat */
|
||||
#define MSGS_YES MSGS_OK /* Résultat booléen positif */
|
||||
#define MSGS_NO MSGS_KO /* Résultat booléen négatif */
|
||||
|
||||
#define MSGS_ERRMEM DSS_ERRMEM /* Problème d'allocation mémoire */
|
||||
#define MSGS_ERRAPI DSS_ERRAPI /* Utilisation incorrecte des API */
|
||||
#define MSGS_ERRSHM DSS_ERRSHM /* Problème relatif aux segments de mémoire partagée */
|
||||
#define MSGS_ERRSEM DSS_ERRSEM /* Problème relatif à l'utilisation des sémaphores */
|
||||
#define MSGS_ERRSIG DSS_ERRSIG /* Opération sur sémaphore interrompue par un signal */
|
||||
#define MSGS_ERRDLL DSS_ERRDLL /* Problème de chargement dynamique de librairie */
|
||||
#define MSGS_ERRNOWAIT -7 /* Opération sur sémaphore impossible et le mode d'opération est sans attente */
|
||||
|
||||
#define MSG_ERROR(s) ((s) < 0) /* Tous les codes retour négatifs correspondent à des erreurs */
|
||||
|
||||
/* Codes retour spécifiques pour la réception de messages */
|
||||
|
||||
#define MSGS_NO_MSG 5
|
||||
#define MSGS_BAD_TYPE 6
|
||||
|
||||
/* Indicateurs */
|
||||
|
||||
typedef int MSGT_Flags;
|
||||
|
||||
/* Flags de debug sur l'ouverture de la librairie */
|
||||
|
||||
#define MSGD_DEBUG_NONE SMD_DEBUG_NONE /* pour n'afficher aucun message généré par les diverses librairies */
|
||||
#define MSGD_DEBUG SMD_DEBUG /* pour afficher les messages générés par la librairie */
|
||||
#define MSGD_DEBUG_ALL SMD_DEBUG_ALL /* pour afficher les messages générés par toutes les librairies sous-jacentes */
|
||||
|
||||
#define MSGD_DEBUG_MSK (MSGD_DEBUG & MSGD_DEBUG_ALL)
|
||||
|
||||
/* Flags d'ouverture et de fermeture des différentes ressources de la librairie */
|
||||
|
||||
#define MSGD_OPEN SMD_OPEN
|
||||
#define MSGD_CREATE SMD_CREATE
|
||||
|
||||
#define MSGD_MSK_OPEN(a) (MSGD_OPEN & (a))
|
||||
#define MSGD_MSK_CREATE(a) (MSGD_CREATE & (a))
|
||||
|
||||
#define MSGD_CLOSE SMD_CLOSE
|
||||
#define MSGD_DESTROY SMD_DESTROY
|
||||
|
||||
/* Flags de réception de message */
|
||||
|
||||
#define MSGD_NO_WAIT 1 /* Réception sans attente si aucun message */
|
||||
#define MSGD_WAIT 2 /* Réception avec attente */
|
||||
|
||||
/* Flags de verrouillage d'un port de messages */
|
||||
|
||||
#define MSGD_READ 1 /* verrou partagé */
|
||||
#define MSGD_WRITE 2 /* verrou exclusif */
|
||||
|
||||
#define MSGD_MSK_READ(a) (MSGD_READ & (a))
|
||||
#define MSGD_MSK_WRITE(a) (MSGD_WRITE & (a))
|
||||
|
||||
#define MSGD_UNLIMITED 0
|
||||
|
||||
/* Notion de port de messages */
|
||||
|
||||
typedef struct {
|
||||
char Name [50]; /* Nom du port de messages */
|
||||
size_t Size; /* Taille limite du port en nombre de messages */
|
||||
int ListenSemID; /* sémaphore permettant l'écoute du port */
|
||||
int LockSemID; /* sémaphore permettant le verrouillage du port */
|
||||
NDT_Root * SemList; /* Liste des sémaphores des listes de ports qui sont à l'écoute du port */
|
||||
NDT_Root * MsgQueue; /* File d'attente des messages */
|
||||
} MSGT_Port;
|
||||
|
||||
/* Quelques ports de message prédéfinis */
|
||||
|
||||
#define MSGD_DEFAULT_PORT_NAME "DEFAULT_PORT"
|
||||
#define MSGD_SYSTEM_PORT_NAME "SYSTEM_PORT"
|
||||
#define MSGD_SUPERVISOR_PORT_NAME "SUPERVISOR_PORT"
|
||||
|
||||
/* Notion de liste de ports de messages */
|
||||
|
||||
typedef struct {
|
||||
NDT_Root * Root; /* Liste de ports de messages */
|
||||
int ListenSemID; /* Identifiant du sémaphore pour l'écoute de la liste de ports */
|
||||
} MSGT_PortList;
|
||||
|
||||
/* Notion de messages */
|
||||
|
||||
typedef struct {
|
||||
char From [50]; /* Nom du port d'écoute de l'initiateur du message */
|
||||
char Via [50]; /* Nom du port d'écoute du dernier envoyeur du message */
|
||||
char To [50]; /* Nom du port du dernier envoi du message */
|
||||
unsigned int Type; /* Type du message */
|
||||
int Priority; /* Priorité du message */
|
||||
size_t Size; /* Taille des données du message */
|
||||
void * Data; /* Données du message */
|
||||
char * Swap; /* Nom du fichier de swap dans lequel est stocké le message */
|
||||
} MSGT_Message;
|
||||
|
||||
#define MSGD_NO_TYPE 0
|
||||
|
||||
/*
|
||||
Types de message :
|
||||
|
||||
Les types de message vont de 1 à 255 et sont partagés en 2 plages :
|
||||
|
||||
- messages systèmes prédéfinis de 1 à 32
|
||||
- messages utilisateur de 33 à 255
|
||||
*/
|
||||
|
||||
#define MSGD_NO_TYPE 0
|
||||
|
||||
#define MSGD_NB_SYSTEM_MESSAGE 32
|
||||
|
||||
#define MSGD_IS_SYSTEM(t) ((t) != MSGD_NO_TYPE && (t) < MSGD_NB_SYSTEM_MESSAGE)
|
||||
#define MSGD_IS_SYSTEM_REQUEST(t) ((t) != MSGD_NO_TYPE && (t) < MSGD_NB_SYSTEM_MESSAGE && (t) % 2 == 1)
|
||||
#define MSGD_IS_SYSTEM_REPLY(t) ((t) != MSGD_NO_TYPE && (t) < MSGD_NB_SYSTEM_MESSAGE && (t) % 2 == 0)
|
||||
|
||||
#define MSGD_SYSTEM_PING_REQUEST 1
|
||||
#define MSGD_SYSTEM_PING_REPLY 2
|
||||
#define MSGD_SYSTEM_STOP_REQUEST 3
|
||||
#define MSGD_SYSTEM_STOP_REPLY 4
|
||||
#define MSGD_SYSTEM_CONTINUE_REQUEST 5
|
||||
#define MSGD_SYSTEM_CONT_REPLY 6
|
||||
#define MSGD_SYSTEM_RESTART_REQUEST 7
|
||||
#define MSGD_SYSTEM_RESTART_REPLY 8
|
||||
#define MSGD_SYSTEM_SHUTDOWN_REQUEST 9
|
||||
#define MSGD_SYSTEM_SHUTDOWN_REPLY 10
|
||||
#define MSGD_SYSTEM_STATUS_REQUEST 11
|
||||
#define MSGD_SYSTEM_STATUS_REPLY 12
|
||||
#define MSGD_SYSTEM_INFO_REQUEST 13
|
||||
#define MSGD_SYSTEM_INFO_REPLY 14
|
||||
#define MSGD_SYSTEM_TRACEON_REQUEST 15
|
||||
#define MSGD_SYSTEM_TRACEON_REPLY 16
|
||||
#define MSGD_SYSTEM_TRACEOFF_REQUEST 17
|
||||
#define MSGD_SYSTEM_TRACEOFF_REPLY 18
|
||||
|
||||
/* Type de message système générique (utile pour ne réceptionner que les messages système) */
|
||||
|
||||
#define MSGD_SYSTEM_GENERIC MSGD_NB_SYSTEM_MESSAGE
|
||||
|
||||
/* Quelques types de messages utilisateur prédéfinis */
|
||||
|
||||
#define MSGD_USER_TYPE1 MSGD_NB_SYSTEM_MESSAGE + 1
|
||||
#define MSGD_USER_TYPE2 MSGD_NB_SYSTEM_MESSAGE + 2
|
||||
|
||||
#define MSGD_DEFAULT_TYPE MSGD_USER_TYPE1
|
||||
|
||||
/*
|
||||
Priorités des messages :
|
||||
|
||||
Les priorités vont de -128 (la plus elevée) à 127 (plus basse) divisées en 2 plages :
|
||||
|
||||
- Priorités des messages système : [-128, -65] U [+65, +127]
|
||||
- Priorités des messages utilisateur : [-64, +64]
|
||||
*/
|
||||
|
||||
#define MSGD_SYSTEM_HIGH_PRIORITY -128
|
||||
#define MSGD_SYSTEM_LOW_PRIORITY 127
|
||||
|
||||
#define MSGD_USER_HIGH_PRIORITY -64
|
||||
#define MSGD_USER_NORMAL_PRIORITY 0
|
||||
#define MSGD_USER_LOW_PRIORITY 64
|
||||
|
||||
#define MSGD_DEFAULT_PRIORITY MSGD_USER_NORMAL_PRIORITY
|
||||
|
||||
/* Types de configuration */
|
||||
|
||||
typedef int MSGT_Config;
|
||||
|
||||
#define MSGD_CONFIG_SIZE 1 /* Configuration de la taille d'un port de messages */
|
||||
#define MSGD_CONFIG_MSGQUEUE 2 /* Choix du type de structure pour la queue de message d'un port de messages */
|
||||
|
||||
#define MSGD_CONFIG_TYPE 3 /* Configuration du type d'un message */
|
||||
#define MSGD_CONFIG_PRIORITY 4 /* Configuration de la priorité d'un message */
|
||||
|
||||
char MSG_Error_Msg [512];
|
||||
|
||||
/* Base de la librairie LIBMSG */
|
||||
|
||||
SMT_Heap * MSG_Base_Heap;
|
||||
SMT_Heap * MSG_Message_Heap;
|
||||
|
||||
typedef struct {
|
||||
NDT_Root * Port_List; /* Liste de tous les ports de messages */
|
||||
} MSGT_Base;
|
||||
|
||||
MSGT_Base * MSG_Base;
|
||||
|
||||
/* Contenu d'un message de type PING_REPLY */
|
||||
|
||||
typedef struct {
|
||||
struct timeval Snd1;
|
||||
struct timeval Rcv1;
|
||||
struct timeval Snd2;
|
||||
struct timeval Rcv2;
|
||||
} MSGT_PingData;
|
||||
|
||||
/* Définition des alias de l'API */
|
||||
|
||||
#ifndef MSG_MODE
|
||||
#define MSG_MODE 0
|
||||
#endif
|
||||
|
||||
#if MSG_MODE == 1
|
||||
|
||||
/* Utilisation des API sans vérification des arguments */
|
||||
|
||||
# define MSG_Library_Open MSG_Library_Open_I
|
||||
# define MSG_Library_Signal MSG_Library_Signal_I
|
||||
# define MSG_Library_IsOpen MSG_Library_IsOpen_I
|
||||
# define MSG_Library_Context_Set MSG_Library_Context_Set_I
|
||||
# define MSG_Library_Context_Get MSG_Library_Context_Get_I
|
||||
# define MSG_Library_Close MSG_Library_Close_I
|
||||
# define MSG_Library_Stderr_Set MSG_Library_Stderr_Set_I
|
||||
# define MSG_Library_Dump MSG_Library_Dump_I
|
||||
# define MSG_Port_Exist MSG_Port_Exist_I
|
||||
# define MSG_Port_Open MSG_Port_Open_I
|
||||
# define MSG_Port_Config MSG_Port_Config_I
|
||||
# define MSG_Port_Lock MSG_Port_Lock_I
|
||||
# define MSG_Port_Unlock MSG_Port_Unlock_I
|
||||
# define MSG_Port_Close MSG_Port_Close_I
|
||||
# define MSG_PortList_Open MSG_PortList_Open_I
|
||||
# define MSG_PortList_Port_Add MSG_PortList_Port_Add_I
|
||||
# define MSG_PortList_Port_Remove MSG_PortList_Port_Remove_I
|
||||
# define MSG_PortList_Close MSG_PortList_Close_I
|
||||
# define MSG_PortList_Listen MSG_PortList_Listen_I
|
||||
# define MSG_Message_Alloc MSG_Message_Alloc_I
|
||||
# define MSG_Message_Config MSG_Message_Config_I
|
||||
# define MSG_Message_Free MSG_Message_Free_I
|
||||
# define MSG_Message_Send MSG_Message_Send_I
|
||||
# define MSG_Message_Receive MSG_Message_Receive_I
|
||||
# define MSG_Message_Reply MSG_Message_Reply_I
|
||||
# define MSG_Message_Return MSG_Message_Return_I
|
||||
|
||||
#else
|
||||
|
||||
/* Utilisation avec vérification des arguments */
|
||||
|
||||
# define MSG_Library_Open MSG_Library_Open_C
|
||||
# define MSG_Library_IsOpen MSG_Library_IsOpen_C
|
||||
# define MSG_Library_Signal MSG_Library_Signal_C
|
||||
# define MSG_Library_Context_Set MSG_Library_Context_Set_C
|
||||
# define MSG_Library_Context_Get MSG_Library_Context_Get_C
|
||||
# define MSG_Library_Close MSG_Library_Close_C
|
||||
# define MSG_Library_Stderr_Set MSG_Library_Stderr_Set_C
|
||||
# define MSG_Library_Dump MSG_Library_Dump_C
|
||||
# define MSG_Port_Exist MSG_Port_Exist_C
|
||||
# define MSG_Port_Open MSG_Port_Open_C
|
||||
# define MSG_Port_Config MSG_Port_Config_C
|
||||
# define MSG_Port_Lock MSG_Port_Lock_C
|
||||
# define MSG_Port_Unlock MSG_Port_Unlock_C
|
||||
# define MSG_Port_Close MSG_Port_Close_C
|
||||
# define MSG_PortList_Open MSG_PortList_Open_C
|
||||
# define MSG_PortList_Port_Add MSG_PortList_Port_Add_C
|
||||
# define MSG_PortList_Port_Remove MSG_PortList_Port_Remove_C
|
||||
# define MSG_PortList_Close MSG_PortList_Close_C
|
||||
# define MSG_PortList_Listen MSG_PortList_Listen_C
|
||||
# define MSG_Message_Alloc MSG_Message_Alloc_C
|
||||
# define MSG_Message_Config MSG_Message_Config_C
|
||||
# define MSG_Message_Free MSG_Message_Free_C
|
||||
# define MSG_Message_Send MSG_Message_Send_C
|
||||
# define MSG_Message_Receive MSG_Message_Receive_C
|
||||
# define MSG_Message_Reply MSG_Message_Reply_C
|
||||
# define MSG_Message_Return MSG_Message_Return_C
|
||||
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Permet d'indiquer à la librairie qu'un signal a été reçu. */
|
||||
/* */
|
||||
/* NB : cette fonction sera appelée par l'utilisateur pour éviter que le */
|
||||
/* processus se bloque sur une attente de message malgré la réception de signal */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Library_Signal_I ( void );
|
||||
MSGT_Status MSG_Library_Signal_C ( void );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Ouverture de la librairie */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) Instance : numéro de l'instance de la librairie */
|
||||
/* (I) Context : contexte d'utilisation de la librairie */
|
||||
/* (I) Open_Mode : mode d'ouverture de la librairie */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Library_Open_I ( int Instance, const char * Context, MSGT_Flags Open_Mode );
|
||||
MSGT_Status MSG_Library_Open_C ( int Instance, const char * Context, MSGT_Flags Open_Mode );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Teste si la librairie a été ouverte */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Library_IsOpen_I ( void );
|
||||
MSGT_Status MSG_Library_IsOpen_C ( void );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Changement de contexte d'utilisation de la librairie */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) Context : nom du nouveau contexte */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Library_Context_Set_I (const char * Context);
|
||||
MSGT_Status MSG_Library_Context_Set_C (const char * Context);
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Récupération du nom du contexte utilisée */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (O) Context : adresse du nom du contexte utilisé */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Library_Context_Get_I (char ** Context);
|
||||
MSGT_Status MSG_Library_Context_Get_C (char ** Context);
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Fermeture de la librairie */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) Close_Mode : mode de fermeture de la librairie */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Library_Close_I ( MSGT_Flags Close_Mode );
|
||||
MSGT_Status MSG_Library_Close_C ( MSGT_Flags Close_Mode );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Définition de la sortie standard des messages d'erreur de la librairie */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) Out : flux de sortie des messages d'erreur */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Library_Stderr_Set_I ( FILE * Out );
|
||||
MSGT_Status MSG_Library_Stderr_Set_C ( FILE * Out );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Affichage des ressources de la librairie */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) Out : Flux de sortie de l'affichage */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Library_Dump_I ( FILE * Out );
|
||||
MSGT_Status MSG_Library_Dump_C ( FILE * Out );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Teste l'existence d'un port de messages */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) Name : nom du port de messages */
|
||||
/* (O) Port : adresse d'un pointeur sur le port de messages */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Port_Exist_I ( const char *, MSGT_Port ** );
|
||||
MSGT_Status MSG_Port_Exist_C ( const char *, MSGT_Port ** );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Création/ouverture d'un port de messages */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) Name : nom du port de messages */
|
||||
/* (O) Port : adresse d'un pointeur sur le port de messages */
|
||||
/* (I) Open_Mode : mode d'ouverture du port de messages */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Port_Open_I ( const char * Name, MSGT_Port ** Port, MSGT_Flags Open_Mode );
|
||||
MSGT_Status MSG_Port_Open_C ( const char * Name, MSGT_Port ** Port, MSGT_Flags Open_Mode );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Configuration d'un port de messages */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) Port : pointeur sur le port de messages */
|
||||
/* (I) Tag : type de configuration */
|
||||
/* (I) ... : données de configuration */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Port_Config_I ( MSGT_Port * Port, MSGT_Config Tag, ... );
|
||||
MSGT_Status MSG_Port_Config_C ( MSGT_Port * Port, MSGT_Config Tag, ... );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Verrouillage d'un port de messages */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) Port : pointeur sur le port de messages */
|
||||
/* (I) Mode : type de verrouillage */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Port_Lock_I ( MSGT_Port * Port, MSGT_Flags Mode );
|
||||
MSGT_Status MSG_Port_Lock_C ( MSGT_Port * Port, MSGT_Flags Mode );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Déverrouillage d'un port de messages */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) Port : pointeur sur le port de messages */
|
||||
/* (I) Mode : type de verrou à enlever */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Port_Unlock_I ( MSGT_Port * Port, MSGT_Flags Mode );
|
||||
MSGT_Status MSG_Port_Unlock_C ( MSGT_Port * Port, MSGT_Flags Mode );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Fermeture d'un port de messages */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) Port : pointeur sur le port de messages */
|
||||
/* (I) Close_Mode : mode de fermeture du port de messages */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Port_Close_I ( MSGT_Port * Port, MSGT_Flags Close_Mode );
|
||||
MSGT_Status MSG_Port_Close_C ( MSGT_Port * Port, MSGT_Flags Close_Mode );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Création/ouverture d'une liste de ports de messages */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (O) PortList : adresse d'un pointeur sur la liste de ports de messages */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_PortList_Open_I ( MSGT_PortList ** PortList );
|
||||
MSGT_Status MSG_PortList_Open_C ( MSGT_PortList ** PortList );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Ajout d'un port de messages à une liste de ports */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) PortList : pointeur sur la liste de ports de messages */
|
||||
/* (I) Port : pointeur sur un port de messages */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_PortList_Port_Add_I ( MSGT_PortList * PortList, MSGT_Port * Port );
|
||||
MSGT_Status MSG_PortList_Port_Add_C ( MSGT_PortList * PortList, MSGT_Port * Port );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Retrait d'un port de messages d'une liste de ports */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) PortList : pointeur sur la liste de ports de messages */
|
||||
/* (I) Port : pointeur sur un port de messages */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_PortList_Port_Remove_I ( MSGT_PortList * PortList, MSGT_Port * Port );
|
||||
MSGT_Status MSG_PortList_Port_Remove_C ( MSGT_PortList * PortList, MSGT_Port * Port );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Suppressin d'une liste de ports de messages */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) PortList : pointeur sur la liste de ports de messages */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_PortList_Close_I ( MSGT_PortList * PortList );
|
||||
MSGT_Status MSG_PortList_Close_C ( MSGT_PortList * PortList );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Ecoute d'une liste de ports de messages */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) PortList : pointeur sur une liste de ports de messages */
|
||||
/* (I) Type : type du message à récupérer */
|
||||
/* (O) Msg : adresse d'un pointeur sur le message à recevoir */
|
||||
/* (I) Flags : paramètres de réception */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_PortList_Listen_I ( MSGT_PortList * PortList, unsigned int Type, MSGT_Message ** Msg, MSGT_Flags Flags);
|
||||
MSGT_Status MSG_PortList_Listen_C ( MSGT_PortList * PortList, unsigned int Type, MSGT_Message ** Msg, MSGT_Flags Flags);
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Création d'un message */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (O) Msg : adresse d'un pointeur sur le message */
|
||||
/* (I) Size : taille en octets des données du message */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Message_Alloc_I ( MSGT_Message ** Msg, size_t Size );
|
||||
MSGT_Status MSG_Message_Alloc_C ( MSGT_Message ** Msg, size_t Size );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Configuration d'un message */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) Msg : pointeur sur un message */
|
||||
/* (I) Tag : type de configuration */
|
||||
/* (I) ... : données de configuration */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Message_Config_I ( MSGT_Message * Msg, MSGT_Config Tag, ... );
|
||||
MSGT_Status MSG_Message_Config_C ( MSGT_Message * Msg, MSGT_Config Tag, ... );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Destruction d'un message */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) Msg : pointeur sur le message */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Message_Free_I ( MSGT_Message * Msg );
|
||||
MSGT_Status MSG_Message_Free_C ( MSGT_Message * Msg );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Envoi d'un message dans un port de messages */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) From : nom du port de messages de l'envoyeur */
|
||||
/* (I) To : pointeur sur le port de messages destinataire */
|
||||
/* (I) Msg : pointeur sur le message */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Message_Send_I ( const char * From, MSGT_Port * To, MSGT_Message * Msg );
|
||||
MSGT_Status MSG_Message_Send_C ( const char * From, MSGT_Port * To, MSGT_Message * Msg );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Réception d'un message dans un port de messages */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) Port : pointeur sur le port de messages */
|
||||
/* (I) Type : type du message à récupérer */
|
||||
/* (O) Msg : adresse d'un pointeur sur le message à recevoir */
|
||||
/* (I) Flags : paramètres de réception */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Message_Receive_I ( MSGT_Port * Port, unsigned int Type, MSGT_Message ** Msg, MSGT_Flags Flags );
|
||||
MSGT_Status MSG_Message_Receive_C ( MSGT_Port * Port, unsigned int Type, MSGT_Message ** Msg, MSGT_Flags Flags );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Retour à l'envoyeur d'un message */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) Msg : pointeur sur le message */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Message_Reply_I ( MSGT_Message * Msg );
|
||||
MSGT_Status MSG_Message_Reply_C ( MSGT_Message * Msg );
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* Retour à l'initiateur d'un message */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
/* (I) Msg : pointeur sur le message */
|
||||
/*------------------------------------------------------------------------------*/
|
||||
MSGT_Status MSG_Message_Return_I ( MSGT_Message * Msg );
|
||||
MSGT_Status MSG_Message_Return_C ( MSGT_Message * Msg );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
235
util/msgadmin.c
Normal file
235
util/msgadmin.c
Normal file
@ -0,0 +1,235 @@
|
||||
#define DATASTR_MODE 1 /* Pas de vérif des arguments + verrou sytématique */
|
||||
#define MSG_MODE 1 /* Pas de vérif des arguments */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/time.h>
|
||||
#include <ver.h>
|
||||
#include <datastr.h>
|
||||
#include <msg.h>
|
||||
|
||||
VER_INFO_EXPORT (msgadmin, "$Revision: 1.1 $", "$Name: $", __FILE__, "$Author: smas $")
|
||||
|
||||
#define USAGE "Usage : %s [ --help | --version [-v] | --create | --destroy ]\n"
|
||||
|
||||
#define QUIT 0
|
||||
#define BASE_INIT 1
|
||||
#define BASE_OPEN 2
|
||||
#define BASE_INFO 3
|
||||
#define BASE_CLOSE 4
|
||||
#define BASE_END 5
|
||||
#define SHOW_PORT_LIST 6
|
||||
#define PORT_CREATE 7
|
||||
#define PORT_DUMP 8
|
||||
#define PORT_FLUSH 9
|
||||
#define PORT_DELETE 10
|
||||
|
||||
char menu [1000];
|
||||
char tmp [100];
|
||||
|
||||
void init_menu (void);
|
||||
int print_menu (void);
|
||||
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
int choice;
|
||||
MSGT_Port * Port;
|
||||
MSGT_Message * Msg;
|
||||
char Answer[10];
|
||||
|
||||
/* Lancement de commande d'administration */
|
||||
|
||||
if (argc >= 2)
|
||||
{
|
||||
if (!strcmp (argv[1], "--help"))
|
||||
{
|
||||
fprintf (stderr, USAGE, argv[0]);
|
||||
return -1;
|
||||
}
|
||||
else if (!strcmp (argv[1], "--version"))
|
||||
{
|
||||
if (argc >= 3 && !strcmp (argv[2], "-v")) return VER_Object_Print (stdout, VERD_VERBOSE);
|
||||
else return VER_Object_Print (stdout, VERD_MINIMAL);
|
||||
}
|
||||
else if (!strcmp (argv[1], "--create"))
|
||||
{
|
||||
if (MSG_Library_Open (0, NULL, MSGD_CREATE | MSGD_DEBUG_ALL) != MSGS_OK)
|
||||
{
|
||||
fprintf (stderr, "=> Impossible de créer l'instance de la librairie LIBMSG\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
else if (!strcmp (argv[1], "--destroy"))
|
||||
{
|
||||
if (MSG_Library_Open (0, NULL, MSGD_OPEN | MSGD_DEBUG_ALL) != MSGS_OK || MSG_Library_Close (MSGD_DESTROY) != MSGS_OK)
|
||||
{
|
||||
fprintf (stderr, "=> Impossible de détruire l'instance de la librairie LIBMSG\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, USAGE, argv[0]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Lancement du menu intercatif */
|
||||
|
||||
init_menu ();
|
||||
|
||||
choice = print_menu ();
|
||||
|
||||
while (choice != QUIT)
|
||||
{
|
||||
strcpy (Answer, "yes");
|
||||
|
||||
switch (choice)
|
||||
{
|
||||
case BASE_INIT:
|
||||
fprintf (stdout, "\nReturn code = %s\n", \
|
||||
MSG_Library_Open (0, NULL, MSGD_CREATE | MSGD_DEBUG_ALL) == MSGS_OK ? "OK" : "NOK" );
|
||||
break;
|
||||
|
||||
case BASE_OPEN:
|
||||
fprintf (stdout, "\nReturn code = %s\n", \
|
||||
MSG_Library_Open (0, NULL, MSGD_OPEN | MSGD_DEBUG_ALL) == MSGS_OK ? "OK" : "NOK" );
|
||||
break;
|
||||
|
||||
case BASE_END:
|
||||
fprintf (stdout, "\nReturn code = %s\n", \
|
||||
MSG_Library_Close (MSGD_DESTROY) == MSGS_OK ? "OK" : "NOK" );
|
||||
break;
|
||||
|
||||
case BASE_CLOSE:
|
||||
fprintf (stdout, "\nReturn code = %s\n", \
|
||||
MSG_Library_Close (MSGD_CLOSE) == MSGS_OK ? "OK" : "NOK" );
|
||||
break;
|
||||
|
||||
case BASE_INFO:
|
||||
if (!MSG_Base)
|
||||
fprintf (stdout, "\nLIBMSG base must be opened first\n");
|
||||
else
|
||||
DS_DataStruct_Info_Print (MSG_Base->Port_List, stdout);
|
||||
break;
|
||||
|
||||
case SHOW_PORT_LIST:
|
||||
if (!MSG_Base) fprintf (stdout, "\nLIBMSG base must be opened first\n");
|
||||
else DS_DataStruct_Print (MSG_Base->Port_List, stdout);
|
||||
break;
|
||||
|
||||
case PORT_CREATE:
|
||||
if (!MSG_Base) fprintf (stdout, "\nLIBMSG base must be opened first\n");
|
||||
else
|
||||
{
|
||||
fprintf (stdout, "\nPort name ? ");
|
||||
gets (tmp);
|
||||
|
||||
if (MSG_Port_Open (tmp, &Port, MSGD_CREATE) != MSGS_OK)
|
||||
fprintf (stdout, "Unable to create port \"%s\"\n", tmp);
|
||||
}
|
||||
break;
|
||||
|
||||
case PORT_DUMP:
|
||||
if (!MSG_Base) fprintf (stdout, "\nLIBMSG base must be opened first\n");
|
||||
else
|
||||
{
|
||||
fprintf (stdout, "\nPort name ? ");
|
||||
gets (tmp);
|
||||
|
||||
if (MSG_Port_Open (tmp, &Port, MSGD_OPEN) != MSGS_OK)
|
||||
fprintf (stdout, "Unable to open port \"%s\"\n", tmp);
|
||||
else
|
||||
{
|
||||
ND_Manager_Exec (MSG_Base->Port_List->Manager, NDD_CMD_PRINT_VALUE, Port, stdout);
|
||||
|
||||
if (fprintf (stdout, "\n\nShow message queue ? (y/n) ") && gets (tmp) && *tmp == 'y')
|
||||
DS_DataStruct_Print (Port->MsgQueue, stdout);
|
||||
|
||||
if (fprintf (stdout, "\nShow semaphore list ? (y/n) ") && gets (tmp) && *tmp == 'y')
|
||||
DS_DataStruct_Print (Port->SemList, stdout);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PORT_FLUSH:
|
||||
if (!MSG_Base) fprintf (stdout, "\nLIBMSG base must be opened first\n");
|
||||
else
|
||||
{
|
||||
fprintf (stdout, "\nPort name ? ");
|
||||
gets (tmp);
|
||||
|
||||
if (MSG_Port_Open (tmp, &Port, MSGD_OPEN) != MSGS_OK)
|
||||
fprintf (stdout, "Unable to open port \"%s\"\n", tmp);
|
||||
|
||||
/* Retrait de tous les messages du port */
|
||||
|
||||
while (MSG_Message_Receive (Port, MSGD_NO_TYPE, &Msg, MSGD_NO_WAIT) == MSGS_OK)
|
||||
MSG_Message_Free (Msg);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case PORT_DELETE:
|
||||
if (!MSG_Base) fprintf (stdout, "\nLIBMSG base must be opened first\n");
|
||||
else
|
||||
{
|
||||
fprintf (stdout, "\nPort name ? ");
|
||||
gets (tmp);
|
||||
|
||||
if (MSG_Port_Exist (tmp, &Port) != MSGS_OK)
|
||||
{
|
||||
fprintf (stdout, "Port \"%s\" does not exist\n", tmp);
|
||||
break;
|
||||
}
|
||||
|
||||
if (MSG_Port_Close (Port, MSGD_DESTROY) != MSGS_OK)
|
||||
fprintf (stdout, "Unable to delete port \"%s\"\n", tmp);
|
||||
}
|
||||
break;
|
||||
|
||||
case QUIT:
|
||||
fprintf (stdout, "\nExiting program ...\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf (stdout, "\nUndefined choice %d\n", choice);
|
||||
}
|
||||
choice = print_menu ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void init_menu (void)
|
||||
{
|
||||
sprintf (menu, "Menu :\n");
|
||||
sprintf (tmp, " - %2d) %-25s", QUIT, "Quit"); strcat (menu, tmp);
|
||||
sprintf (tmp, " - %2d) %-25s\n", BASE_INIT, "Init library"); strcat (menu, tmp);
|
||||
sprintf (tmp, " - %2d) %-25s", BASE_OPEN, "Open library"); strcat (menu, tmp);
|
||||
sprintf (tmp, " - %2d) %-25s\n", BASE_INFO, "Info library"); strcat (menu, tmp);
|
||||
sprintf (tmp, " - %2d) %-25s", BASE_CLOSE, "Close library"); strcat (menu, tmp);
|
||||
sprintf (tmp, " - %2d) %-25s\n", BASE_END, "End library"); strcat (menu, tmp);
|
||||
sprintf (tmp, " - %2d) %-25s", SHOW_PORT_LIST, "Show message ports"); strcat (menu, tmp);
|
||||
sprintf (tmp, " - %2d) %-25s\n", PORT_CREATE, "Create a message port"); strcat (menu, tmp);
|
||||
sprintf (tmp, " - %2d) %-25s", PORT_DUMP, "Dump a message port"); strcat (menu, tmp);
|
||||
sprintf (tmp, " - %2d) %-25s\n", PORT_FLUSH, "Flush all message from a port"); strcat (menu, tmp);
|
||||
sprintf (tmp, " - %2d) %-25s\n", PORT_DELETE, "Delete a message port"); strcat (menu, tmp);
|
||||
}
|
||||
|
||||
int print_menu (void)
|
||||
{
|
||||
fprintf (stdout, "---------------------------------------------------------------------------\n%s", menu);
|
||||
|
||||
tmp[0] = '\0';
|
||||
while (tmp[0] == '\0')
|
||||
{
|
||||
printf ("\nChoice ? ");
|
||||
gets (tmp);
|
||||
}
|
||||
return atoi (tmp);
|
||||
}
|
BIN
util/msgbench.xls
Normal file
BIN
util/msgbench.xls
Normal file
Binary file not shown.
40
util/pingpong.result.cc
Normal file
40
util/pingpong.result.cc
Normal file
@ -0,0 +1,40 @@
|
||||
-------------- TEST LIBMSG -----------------
|
||||
Testing LIBMSG for 10 second(s) with 1 message(s) of 10 byte(s)...
|
||||
20450 message(s) exchanged (2045 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 1 message(s) of 1000 byte(s)...
|
||||
20244 message(s) exchanged (2024 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 1 message(s) of 2048 byte(s)...
|
||||
19520 message(s) exchanged (1952 msg/sec)
|
||||
---------
|
||||
Testing LIBMSG for 10 second(s) with 10 message(s) of 10 byte(s)...
|
||||
30752 message(s) exchanged (3075 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 10 message(s) of 1000 byte(s)...
|
||||
30220 message(s) exchanged (3022 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 10 message(s) of 2048 byte(s)...
|
||||
28590 message(s) exchanged (2859 msg/sec)
|
||||
---------
|
||||
Testing LIBMSG for 10 second(s) with 100 message(s) of 10 byte(s)...
|
||||
27008 message(s) exchanged (2700 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 100 message(s) of 1000 byte(s)...
|
||||
24970 message(s) exchanged (2497 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 100 message(s) of 2048 byte(s)...
|
||||
21838 message(s) exchanged (2183 msg/sec)
|
||||
-------------- TEST IPC -----------------
|
||||
Testing IPC message queue for 10 second (s) with 1 message (s) of 10 byte (s)...
|
||||
169485 message (s) exchanged (16948 Msg/sec)
|
||||
Testing IPC message queue for 10 second (s) with 1 message (s) of 1000 byte (s)...
|
||||
102630 message (s) exchanged (10263 Msg/sec)
|
||||
Testing IPC message queue for 10 second (s) with 1 message (s) of 2048 byte (s)...
|
||||
102040 message (s) exchanged (10204 Msg/sec)
|
||||
---------
|
||||
Testing IPC message queue for 10 second (s) with 10 message (s) of 10 byte (s)...
|
||||
300810 message (s) exchanged (30081 Msg/sec)
|
||||
Testing IPC message queue for 10 second (s) with 10 message (s) of 1000 byte (s)...
|
||||
159352 message (s) exchanged (15935 Msg/sec)
|
||||
Testing IPC message queue for 10 second (s) with 10 message (s) of 2048 byte (s)...
|
||||
127773 message (s) exchanged (12777 Msg/sec)
|
||||
---------
|
||||
Testing IPC message queue for 10 second (s) with 100 message (s) of 1000 byte (s)...
|
||||
175376 message (s) exchanged (17537 Msg/sec)
|
||||
Testing IPC message queue for 10 second (s) with 100 message (s) of 2048 byte (s)...
|
||||
121655 message (s) exchanged (12165 Msg/sec)
|
40
util/pingpong.result.gcc
Normal file
40
util/pingpong.result.gcc
Normal file
@ -0,0 +1,40 @@
|
||||
-------------- TEST LIBMSG -----------------
|
||||
Testing LIBMSG for 10 second(s) with 1 message(s) of 10 byte(s)...
|
||||
30364 message(s) exchanged (3036 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 1 message(s) of 1000 byte(s)...
|
||||
29490 message(s) exchanged (2949 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 1 message(s) of 2048 byte(s)...
|
||||
32788 message(s) exchanged (3278 msg/sec)
|
||||
---------
|
||||
Testing LIBMSG for 10 second(s) with 10 message(s) of 10 byte(s)...
|
||||
32203 message(s) exchanged (3220 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 10 message(s) of 1000 byte(s)...
|
||||
36712 message(s) exchanged (3671 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 10 message(s) of 2048 byte(s)...
|
||||
34887 message(s) exchanged (3488 msg/sec)
|
||||
---------
|
||||
Testing LIBMSG for 10 second(s) with 100 message(s) of 10 byte(s)...
|
||||
24382 message(s) exchanged (2438 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 100 message(s) of 1000 byte(s)...
|
||||
24552 message(s) exchanged (2455 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 100 message(s) of 2048 byte(s)...
|
||||
25862 message(s) exchanged (2586 msg/sec)
|
||||
-------------- TEST IPC -----------------
|
||||
Testing IPC message queue for 10 second (s) with 1 message (s) of 10 byte (s)...
|
||||
162587 message (s) exchanged (16258 Msg/sec)
|
||||
Testing IPC message queue for 10 second (s) with 1 message (s) of 1000 byte (s)...
|
||||
106886 message (s) exchanged (10688 Msg/sec)
|
||||
Testing IPC message queue for 10 second (s) with 1 message (s) of 2048 byte (s)...
|
||||
88864 message (s) exchanged (8886 Msg/sec)
|
||||
---------
|
||||
Testing IPC message queue for 10 second (s) with 10 message (s) of 10 byte (s)...
|
||||
267204 message (s) exchanged (26720 Msg/sec)
|
||||
Testing IPC message queue for 10 second (s) with 10 message (s) of 1000 byte (s)...
|
||||
167169 message (s) exchanged (16716 Msg/sec)
|
||||
Testing IPC message queue for 10 second (s) with 10 message (s) of 2048 byte (s)...
|
||||
121365 message (s) exchanged (12136 Msg/sec)
|
||||
---------
|
||||
Testing IPC message queue for 10 second (s) with 100 message (s) of 1000 byte (s)...
|
||||
165790 message (s) exchanged (16579 Msg/sec)
|
||||
Testing IPC message queue for 10 second (s) with 100 message (s) of 2048 byte (s)...
|
||||
122897 message (s) exchanged (12289 Msg/sec)
|
579
util/pingpong_ipc.c
Normal file
579
util/pingpong_ipc.c
Normal file
@ -0,0 +1,579 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define DEFAULT_TIMER 60 /* Durée par défaut du test (en secondes) */
|
||||
#define DEFAULT_WINSIZE 100 /* Taille par défaut de la fenêtre de messages */
|
||||
#define DEFAULT_MSGSIZE 100 /* Taille par défaut de chaque message */
|
||||
|
||||
#define FATHER_KEY 64 /* Clé du port de messages du père */
|
||||
#define CHILD_KEY 65 /* Clé du port de messages du fils */
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
typedef struct {
|
||||
long mtype;
|
||||
char * mtext;
|
||||
} T_Msg;
|
||||
|
||||
int My_Port, Its_Port;
|
||||
int Child_Pid, Father_Pid, Its_Pid, My_Pid;
|
||||
int Verbose;
|
||||
unsigned int Timer;
|
||||
unsigned int Win_Size;
|
||||
unsigned int Msg_Size;
|
||||
int Cpt_Msg;
|
||||
T_Msg ** Msg_Window;
|
||||
int End_Test, End_Sigum;
|
||||
|
||||
char * error_code (void);
|
||||
void stop_test (int);
|
||||
void stop_father (void);
|
||||
void stop_child (void);
|
||||
void clean (int);
|
||||
void trace (char *);
|
||||
void print_result (void);
|
||||
void parse_arg (int, char **);
|
||||
extern char * strdup (const char *);
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
unsigned int i, size;
|
||||
char str [256];
|
||||
T_Msg * Msg;
|
||||
|
||||
/* Récupération des arguments de la ligne de commande */
|
||||
|
||||
parse_arg (argc, argv);
|
||||
|
||||
/* Récupération du no de process courant */
|
||||
|
||||
Father_Pid = getpid ();
|
||||
|
||||
/* Création d'un process fils avec qui dialoguer */
|
||||
|
||||
if ((Child_Pid = fork ()) != 0)
|
||||
{
|
||||
/*--------- Code pour le process père -----------*/
|
||||
|
||||
Its_Pid = Child_Pid;
|
||||
My_Pid = Father_Pid;
|
||||
|
||||
My_Port = 0;
|
||||
|
||||
signal (SIGINT, stop_test);
|
||||
signal (SIGUSR1, stop_test);
|
||||
|
||||
/* Création d'un port de messages */
|
||||
|
||||
if ((My_Port = msgget (FATHER_KEY, 0777|IPC_CREAT|IPC_EXCL)) == -1)
|
||||
{
|
||||
fprintf (stderr, "Unable to create message queue for the father process : error %d (%s)\n", errno, error_code ());
|
||||
clean (TRUE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (str, "Message port %d created", My_Port);
|
||||
trace (str);
|
||||
}
|
||||
|
||||
/* On attend que le fils ait créé son port de messages */
|
||||
|
||||
sleep (2);
|
||||
|
||||
/* Initialisation de la fenêtre de messages */
|
||||
|
||||
Msg_Window = (T_Msg **)malloc (Win_Size);
|
||||
|
||||
for (i = 0; i < Win_Size; i++)
|
||||
{
|
||||
Msg_Window[i] = (T_Msg *)malloc (sizeof (T_Msg));
|
||||
Msg_Window[i]->mtype = 1;
|
||||
Msg_Window[i]->mtext = (char *)malloc (Msg_Size);
|
||||
Msg_Window[i]->mtext[0] = (char)i;
|
||||
}
|
||||
|
||||
/* Récupération de la port de messages du fils */
|
||||
|
||||
if ((Its_Port = msgget (CHILD_KEY, 0)) == -1)
|
||||
{
|
||||
fprintf (stderr, "Unable to retrieve the message queue of the child process : error %d (%s)\n", errno, error_code ());
|
||||
clean (TRUE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Msg = malloc (sizeof (T_Msg));
|
||||
Msg->mtext = (char *)malloc (Msg_Size);
|
||||
|
||||
/* Initialisation du Timer */
|
||||
|
||||
signal (SIGALRM, stop_test);
|
||||
|
||||
alarm (Timer);
|
||||
|
||||
/* Début du test : traitement des messages */
|
||||
|
||||
fprintf (stdout, "Testing IPC message queue for %d second (s) with %d message (s) of %d byte (s)...\n", Timer, Win_Size, Msg_Size);
|
||||
|
||||
/* Envoi de tous les messages de la fenêtre au fils */
|
||||
|
||||
for (i = 0; i < Win_Size; i++)
|
||||
{
|
||||
errno = 0;
|
||||
|
||||
if (msgsnd (Its_Port, Msg_Window[i], Msg_Size, IPC_NOWAIT) == 0)
|
||||
{
|
||||
if (Verbose)
|
||||
{
|
||||
sprintf (str, "Message %d sent to port %d", i, Its_Port);
|
||||
trace (str);
|
||||
}
|
||||
}
|
||||
|
||||
if (errno != 0 && errno != EAGAIN)
|
||||
fprintf (stderr, "Unable to send message %d to port %d : error %d (%s)\n", i, Its_Port, errno, error_code ());
|
||||
}
|
||||
|
||||
Cpt_Msg = 0;
|
||||
|
||||
while (End_Test == FALSE)
|
||||
{
|
||||
/* Réception de messages */
|
||||
|
||||
errno = 0;
|
||||
|
||||
if ((size = msgrcv (My_Port, Msg, Msg_Size, 0, MSG_NOERROR)) > 0)
|
||||
{
|
||||
i = (int)(Msg->mtext[0]);
|
||||
if (Verbose)
|
||||
{
|
||||
sprintf (str, "Message %d received from port %d", i, My_Port);
|
||||
trace (str);
|
||||
}
|
||||
|
||||
Cpt_Msg++;
|
||||
|
||||
/* Réenvoi du message au fils */
|
||||
|
||||
errno = 0;
|
||||
|
||||
if (msgsnd (Its_Port, Msg_Window[i], Msg_Size, IPC_NOWAIT) == 0)
|
||||
{
|
||||
if (Verbose)
|
||||
{
|
||||
sprintf (str, "Message %d replied", i);
|
||||
trace (str);
|
||||
}
|
||||
}
|
||||
|
||||
if (errno != 0 && errno != EAGAIN)
|
||||
fprintf (stderr, "Unable to reply message %d to port %d (%s)\n", i, Its_Port, error_code ());
|
||||
}
|
||||
|
||||
if (errno != 0)
|
||||
fprintf (stderr, "Unable to receive a message from port %d (%s)\n", My_Port, error_code ());
|
||||
}
|
||||
|
||||
stop_father ();
|
||||
}
|
||||
else
|
||||
{
|
||||
/*---------- Code pour le process fils ----------*/
|
||||
|
||||
My_Pid = getpid ();
|
||||
Its_Pid = Father_Pid;
|
||||
My_Port = 0;
|
||||
|
||||
/* Trap du signal SIGUSR1 envoyé par le process père à la fin du test */
|
||||
|
||||
signal (SIGUSR1, stop_test);
|
||||
signal (SIGINT, stop_test);
|
||||
|
||||
/* Création d'un port de messages */
|
||||
|
||||
if ((My_Port = msgget (CHILD_KEY, 0777|IPC_CREAT|IPC_EXCL)) == -1)
|
||||
{
|
||||
fprintf (stderr, "Unable to create message queue for the child process (%s)\n", error_code ());
|
||||
clean (TRUE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (str, "Message port %d created", My_Port);
|
||||
trace (str);
|
||||
}
|
||||
|
||||
/* On attend que le père ait créé son port de messages */
|
||||
|
||||
sleep (2);
|
||||
|
||||
Msg_Window = (T_Msg **)malloc (Win_Size);
|
||||
|
||||
for (i = 0; i < Win_Size; i++)
|
||||
{
|
||||
Msg_Window[i] = (T_Msg *)malloc (sizeof (T_Msg));
|
||||
Msg_Window[i]->mtype = 1;
|
||||
Msg_Window[i]->mtext = (char *)malloc (Msg_Size * sizeof (char));
|
||||
Msg_Window[i]->mtext[0] = (char)i;
|
||||
}
|
||||
|
||||
/* Récupération du port de messages du père */
|
||||
|
||||
if ((Its_Port = msgget (FATHER_KEY, 0)) == -1)
|
||||
{
|
||||
fprintf (stderr, "Unable to retrieve the message queue of the father process (%s)\n", error_code ());
|
||||
clean (TRUE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Traitement des messages */
|
||||
|
||||
Msg = malloc (sizeof (T_Msg));
|
||||
Msg->mtext = (char *)malloc (Msg_Size * sizeof (char));
|
||||
|
||||
while (End_Test == FALSE)
|
||||
{
|
||||
/* Réception de messages */
|
||||
|
||||
errno = 0;
|
||||
|
||||
if ((size = msgrcv (My_Port, Msg, Msg_Size, 0, MSG_NOERROR)) > 0)
|
||||
{
|
||||
i = (int)(Msg->mtext[0]);
|
||||
if (Verbose)
|
||||
{
|
||||
sprintf (str, "Message %d received from port %d", i, My_Port);
|
||||
trace (str);
|
||||
}
|
||||
|
||||
Cpt_Msg++;
|
||||
|
||||
/* Réenvoi du message au fils */
|
||||
|
||||
errno = 0;
|
||||
|
||||
if (msgsnd (Its_Port, Msg_Window[i], Msg_Size, IPC_NOWAIT) == 0)
|
||||
{
|
||||
if (Verbose)
|
||||
{
|
||||
sprintf (str, "Message %d replied", i);
|
||||
trace (str);
|
||||
}
|
||||
}
|
||||
|
||||
if (errno != 0 && errno != EAGAIN)
|
||||
fprintf (stderr, "Unable to reply message %d to port %d (%s)\n", i, Its_Port, error_code ());
|
||||
}
|
||||
|
||||
if (errno != 0)
|
||||
fprintf (stderr, "Unable to receive a message from port %d (%s)\n", My_Port, error_code ());
|
||||
}
|
||||
|
||||
stop_child ();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
void stop_test (int signum)
|
||||
{
|
||||
End_Sigum = signum;
|
||||
End_Test = TRUE;
|
||||
}
|
||||
/*----------------------------------------------------------------*/
|
||||
void stop_father (void)
|
||||
{
|
||||
switch (End_Sigum)
|
||||
{
|
||||
case SIGINT:
|
||||
|
||||
/* Fin initiée par l'utilisateur : ménage simple */
|
||||
|
||||
case SIGUSR1:
|
||||
|
||||
/* Fin anormale en provenance du fils : ménage simple */
|
||||
|
||||
clean (FALSE);
|
||||
|
||||
break;
|
||||
|
||||
case SIGALRM:
|
||||
|
||||
/* Fin normale : ménage + stop du fils + affichage du réultat */
|
||||
|
||||
clean (TRUE);
|
||||
print_result ();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* Fin anormale sur le process père : ménage + avertit le process fils */
|
||||
|
||||
clean (TRUE);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
void print_result (void)
|
||||
{
|
||||
/* Affichage du résultat du test */
|
||||
|
||||
fprintf (stdout, "%d message (s) exchanged (%d Msg/sec)\n", Cpt_Msg, (int)(Cpt_Msg / Timer));
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
void stop_child (void)
|
||||
{
|
||||
switch (End_Sigum)
|
||||
{
|
||||
case SIGINT:
|
||||
|
||||
/* Fin initiée par l'utilisateur : ménage simple */
|
||||
|
||||
case SIGUSR1:
|
||||
|
||||
/* Fin initiée par le process père : ménage simple */
|
||||
|
||||
clean (FALSE);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* Fin anormale sur le process fils : ménage + avertit le process père */
|
||||
|
||||
clean (TRUE);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
/*----------------------------------------------------------------*/
|
||||
void clean (int warn)
|
||||
{
|
||||
unsigned int i;
|
||||
char str [256];
|
||||
|
||||
/* On avertit l'autre process */
|
||||
|
||||
if (warn == TRUE) kill (Its_Pid, SIGUSR1);
|
||||
|
||||
if (Msg_Window != NULL)
|
||||
{
|
||||
for (i = 0; i < Win_Size; i++)
|
||||
{
|
||||
if (Msg_Window[i] != NULL)
|
||||
{
|
||||
if (Msg_Window[i]->mtext != NULL) free (Msg_Window[i]->mtext);
|
||||
free (Msg_Window[i]);
|
||||
}
|
||||
}
|
||||
free (Msg_Window);
|
||||
}
|
||||
|
||||
/* Destruction de la port de messages */
|
||||
|
||||
if (My_Port > 0)
|
||||
{
|
||||
if (Verbose)
|
||||
{
|
||||
sprintf (str, "Removing message queue %d...\n", My_Port);
|
||||
trace (str);
|
||||
}
|
||||
|
||||
msgctl (My_Port, IPC_RMID, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
char * error_code (void)
|
||||
{
|
||||
static char * str;
|
||||
|
||||
if (str) free (str);
|
||||
|
||||
switch (errno)
|
||||
{
|
||||
case EACCES:
|
||||
str = strdup ("EACCES");
|
||||
break;
|
||||
|
||||
case EEXIST:
|
||||
str = strdup ("EEXIST");
|
||||
break;
|
||||
|
||||
case EIDRM:
|
||||
str = strdup ("EIDRM");
|
||||
break;
|
||||
|
||||
case ENOENT:
|
||||
str = strdup ("ENOENT");
|
||||
break;
|
||||
|
||||
case ENOMEM:
|
||||
str = strdup ("ENOMEM");
|
||||
break;
|
||||
|
||||
case ENOSPC:
|
||||
str = strdup ("ENOSPC");
|
||||
break;
|
||||
|
||||
case EFAULT:
|
||||
str = strdup ("EFAULT");
|
||||
break;
|
||||
|
||||
case EINTR:
|
||||
str = strdup ("EINTR");
|
||||
break;
|
||||
|
||||
case EINVAL:
|
||||
str = strdup ("EINVAL");
|
||||
break;
|
||||
|
||||
case E2BIG:
|
||||
str = strdup ("E2BIG");
|
||||
break;
|
||||
|
||||
case ENOMSG:
|
||||
str = strdup ("ENOMSG");
|
||||
break;
|
||||
|
||||
case EAGAIN:
|
||||
str = strdup ("EAGAIN");
|
||||
break;
|
||||
|
||||
default:
|
||||
str = strdup ("unknown");
|
||||
break;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
void trace (char *str)
|
||||
{
|
||||
time_t dts;
|
||||
struct tm *dt;
|
||||
char current_date [30];
|
||||
char str_trace [256];
|
||||
|
||||
/* Get current date */
|
||||
|
||||
time (&dts);
|
||||
dt = localtime (&dts);
|
||||
sprintf (current_date, "%04d/%02d/%02d %02d:%02d:%02d", dt->tm_year + 1900, dt->tm_mon + 1, dt->tm_mday, dt->tm_hour, dt->tm_min, dt->tm_sec);
|
||||
|
||||
sprintf (str_trace, "Process %d - %s : %s\n", My_Pid, current_date, str);
|
||||
fprintf (stderr, str_trace);
|
||||
fflush (stderr);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
void parse_arg (int argc, char ** argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
Verbose = FALSE;
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if (!strcmp (argv[i], "--help") || !strcmp (argv[i], "-h"))
|
||||
{
|
||||
fprintf (stdout, "Usage : %s [options]\n", argv[0]);
|
||||
fprintf (stdout,"options :\n");
|
||||
fprintf (stdout, "\t --help -h\n");
|
||||
fprintf (stdout, "\t --clean\n");
|
||||
fprintf (stdout, "\t --verbose\n");
|
||||
fprintf (stdout, "\t --duration <time in seconds> (default is %d)\n", DEFAULT_TIMER);
|
||||
fprintf (stdout, "\t --window <message number> (default is %d)\n", DEFAULT_WINSIZE);
|
||||
fprintf (stdout, "\t --message <message size> (default is %d bytes)\n", DEFAULT_MSGSIZE);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (!strcmp (argv[i], "--clean"))
|
||||
{
|
||||
if ((My_Port = msgget (FATHER_KEY, 0)) != -1) msgctl (My_Port, IPC_RMID, NULL);
|
||||
if ((Its_Port = msgget (CHILD_KEY, 0)) != -1) msgctl (Its_Port, IPC_RMID, NULL);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (!strcmp (argv[i], "--verbose"))
|
||||
{
|
||||
Verbose = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp (argv[i], "--duration"))
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
fprintf (stderr, "Missing argument after %s\n", argv[i - 1]);
|
||||
exit (0);
|
||||
}
|
||||
Timer = atoi (argv[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp (argv[i], "--window"))
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
fprintf (stderr, "Missing argument after %s\n", argv[i - 1]);
|
||||
exit (0);
|
||||
}
|
||||
Win_Size = atoi (argv[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp (argv[i], "--message"))
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
fprintf (stderr, "Missing argument after %s\n", argv[i - 1]);
|
||||
exit (0);
|
||||
}
|
||||
Msg_Size = atoi (argv[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
fprintf (stdout, "Unknown option '%s'\n", argv[i]);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
if (Timer <= 0) Timer = DEFAULT_TIMER;
|
||||
if (Win_Size <= 0) Win_Size = DEFAULT_WINSIZE;
|
||||
if (Msg_Size <= 0) Msg_Size = DEFAULT_MSGSIZE;
|
||||
}
|
||||
|
543
util/pingpong_msg.c
Normal file
543
util/pingpong_msg.c
Normal file
@ -0,0 +1,543 @@
|
||||
#define MSG_MODE 1
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <shmem.h>
|
||||
#include <msg.h>
|
||||
|
||||
VER_INFO_EXPORT (pingpong, "1.0", "", __FILE__, "severin")
|
||||
|
||||
#define DEFAULT_TIMER 60 /* Durée par défaut du test (en secondes) */
|
||||
#define DEFAULT_WINSIZE 100 /* Taille par défaut de la fenêtre de messages */
|
||||
#define DEFAULT_MSGSIZE 100 /* Taille par défaut de chaque message */
|
||||
|
||||
#define FATHER_KEY "father_port" /* Clé du port de messages d'écoute du père */
|
||||
#define CHILD_KEY "child_port" /* Clé du port de messages d'écoute du fils */
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
MSGT_Port * My_Port, * Its_Port;
|
||||
unsigned int Child_Pid, Father_Pid, Its_Pid, My_Pid;
|
||||
int Verbose, Tree;
|
||||
unsigned int Win_Size, Msg_Size, Cpt_Msg, Timer;
|
||||
SMT_DSH * DSH;
|
||||
SMT_Heap * Heap;
|
||||
int End_Test, End_Sigum;
|
||||
char str [100];
|
||||
|
||||
void stop_test (int);
|
||||
void stop_father (void);
|
||||
void stop_child (void);
|
||||
void clean (int);
|
||||
void trace (char *);
|
||||
void print_result (void);
|
||||
void parse_arg (int, char **);
|
||||
extern char * strdup (const char *);
|
||||
extern kill (int, int);
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
unsigned int i;
|
||||
MSGT_Message * Msg;
|
||||
|
||||
/* Récupération des arguments de la ligne de commande */
|
||||
|
||||
parse_arg (argc, argv);
|
||||
|
||||
/* Récupération du numéro de processus courant */
|
||||
|
||||
Father_Pid = getpid ();
|
||||
|
||||
/* Création d'un process fils avec qui dialoguer */
|
||||
|
||||
if ((Child_Pid = fork ()) != 0)
|
||||
{
|
||||
Heap = NULL;
|
||||
|
||||
/*--------- Code pour le process père -----------*/
|
||||
|
||||
/* Ouverture de la librairie libmsg */
|
||||
|
||||
if (MSG_Library_Open (0, NULL, MSGD_OPEN | MSGD_DEBUG_ALL) != MSGS_OK) return 0;
|
||||
|
||||
Its_Pid = Child_Pid;
|
||||
My_Pid = Father_Pid;
|
||||
|
||||
signal (SIGINT, stop_test);
|
||||
signal (SIGUSR1, stop_test);
|
||||
|
||||
/* Création d'un port de messages privé pour le père */
|
||||
|
||||
if (MSG_Port_Open (FATHER_KEY, &My_Port, MSGD_CREATE) != MSGS_OK)
|
||||
{
|
||||
fprintf (stderr, "Unable to create a message port for the father process\n");
|
||||
clean (TRUE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else if (Verbose)
|
||||
{
|
||||
sprintf (str, "Message port \"%s\" created", My_Port->Name);
|
||||
trace (str);
|
||||
}
|
||||
|
||||
if (Tree == TRUE)
|
||||
{
|
||||
if (MSG_Port_Config (My_Port, MSGD_CONFIG_MSGQUEUE, NDD_DS_TREE) != MSGS_OK)
|
||||
{
|
||||
fprintf (stderr, "Unable to create a message port for the father process\n");
|
||||
clean (TRUE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* On attend que le fils ait créé son port de messages */
|
||||
|
||||
sleep (1);
|
||||
|
||||
/* Récupération du port de messages privé du fils */
|
||||
|
||||
if (MSG_Port_Open (CHILD_KEY, &Its_Port, MSGD_OPEN) != MSGS_OK)
|
||||
{
|
||||
fprintf (stderr, "Unable to retrieve the message port of the child process\n");
|
||||
clean (TRUE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else if (Verbose)
|
||||
{
|
||||
sprintf (str, "Message port \"%s\" retrieved", Its_Port->Name);
|
||||
trace (str);
|
||||
}
|
||||
|
||||
/* Initialisation du Timer */
|
||||
|
||||
signal (SIGALRM, stop_test);
|
||||
|
||||
alarm (Timer);
|
||||
|
||||
/* Début du test : traitement des messages */
|
||||
|
||||
fprintf (stdout, "Testing LIBMSG for %d second(s) with %d message(s) of %d byte(s)...\n", Timer, Win_Size, Msg_Size);
|
||||
|
||||
/* Création et envoi de tous les messages au fils */
|
||||
|
||||
for (i = 0; i < Win_Size; i++)
|
||||
{
|
||||
if (MSG_Message_Alloc (&Msg, Msg_Size) == MSGS_OK)
|
||||
{
|
||||
if (Verbose)
|
||||
{
|
||||
sprintf (str, "Message %d created", i);
|
||||
trace (str);
|
||||
}
|
||||
|
||||
if (MSG_Message_Send (My_Port->Name, Its_Port, Msg) == MSGS_OK)
|
||||
{
|
||||
if (Verbose)
|
||||
{
|
||||
sprintf (str, "Message %d sent to port \"%s\"", i, Its_Port->Name);
|
||||
trace (str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Cpt_Msg = 0;
|
||||
|
||||
while (End_Test == FALSE)
|
||||
{
|
||||
/* Réception de messages */
|
||||
|
||||
if (MSG_Message_Receive (My_Port, MSGD_NO_TYPE, &Msg, MSGD_WAIT) == MSGS_OK)
|
||||
{
|
||||
if (Verbose)
|
||||
{
|
||||
sprintf (str, "Message %d received from port \"%s\"", Msg->Type, My_Port->Name);
|
||||
trace (str);
|
||||
}
|
||||
|
||||
Cpt_Msg++;
|
||||
|
||||
/* Réenvoi du message au fils */
|
||||
|
||||
if (MSG_Message_Reply (Msg) == MSGS_OK)
|
||||
{
|
||||
if (Verbose)
|
||||
{
|
||||
sprintf (str, "Message %d replied", Msg->Type);
|
||||
trace (str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stop_father ();
|
||||
}
|
||||
else
|
||||
{
|
||||
/*---------- Code pour le process fils ----------*/
|
||||
|
||||
Heap = NULL;
|
||||
|
||||
My_Pid = getpid ();
|
||||
Its_Pid = Father_Pid;
|
||||
|
||||
/* Ouverture de la librairie libmsg */
|
||||
|
||||
if (MSG_Library_Open (0, NULL, SMD_OPEN | MSGD_DEBUG_ALL) != MSGS_OK) return 0;
|
||||
|
||||
/* Trap du signal SIGUSR1 envoyé par le process père à la fin du test */
|
||||
|
||||
signal (SIGUSR1, stop_test);
|
||||
signal (SIGINT, stop_test);
|
||||
|
||||
/* Création d'un port de messages privé pour le fils */
|
||||
|
||||
if (MSG_Port_Open (CHILD_KEY, &My_Port, MSGD_CREATE) != MSGS_OK)
|
||||
{
|
||||
fprintf (stderr, "Unable to create message port for the child process\n");
|
||||
clean (TRUE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else if (Verbose)
|
||||
{
|
||||
sprintf (str, "Message port \"%s\" created", My_Port->Name);
|
||||
trace (str);
|
||||
}
|
||||
|
||||
/* On attend que le père ait créé son port de messages privé */
|
||||
|
||||
sleep (1);
|
||||
|
||||
/* Récupération du port de messages privé du père */
|
||||
|
||||
if (MSG_Port_Open (FATHER_KEY, &Its_Port, MSGD_OPEN) != MSGS_OK)
|
||||
{
|
||||
fprintf (stderr, "Unable to retrieve the message port of the father process\n");
|
||||
clean (TRUE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else if (Verbose)
|
||||
{
|
||||
sprintf (str, "Message port \"%s\" retrieved", Its_Port->Name);
|
||||
trace (str);
|
||||
}
|
||||
|
||||
/* Traitement des messages */
|
||||
|
||||
while (End_Test == FALSE)
|
||||
{
|
||||
/* Réception de messages */
|
||||
|
||||
if (MSG_Message_Receive (My_Port, MSGD_NO_TYPE, &Msg, MSGD_WAIT) == MSGS_OK)
|
||||
{
|
||||
if (Verbose)
|
||||
{
|
||||
sprintf (str, "Message %d received from port \"%s\"", Msg->Type, My_Port->Name);
|
||||
trace (str);
|
||||
}
|
||||
|
||||
/* Renvoi du message */
|
||||
|
||||
if (MSG_Message_Reply (Msg) == MSGS_OK)
|
||||
{
|
||||
if (Verbose)
|
||||
{
|
||||
sprintf (str, "Message %d replied", Msg->Type);
|
||||
trace (str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stop_child ();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
void stop_test (int signum)
|
||||
{
|
||||
End_Sigum = signum;
|
||||
End_Test = TRUE;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
void stop_father (void)
|
||||
{
|
||||
switch (End_Sigum)
|
||||
{
|
||||
case SIGINT:
|
||||
|
||||
/* Fin initiée par l'utilisateur : ménage simple */
|
||||
|
||||
case SIGUSR1:
|
||||
|
||||
/* Fin anormale en provenance du fils : ménage simple */
|
||||
|
||||
sprintf (str, "Signal USR1 received from child process");
|
||||
trace (str);
|
||||
|
||||
clean (FALSE);
|
||||
|
||||
break;
|
||||
|
||||
case SIGALRM:
|
||||
|
||||
/* Fin normale : ménage + stop du fils + affichage du réultat */
|
||||
|
||||
clean (TRUE);
|
||||
print_result ();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* Fin anormale sur le process père : ménage + avertit le process fils */
|
||||
|
||||
clean (TRUE);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
void print_result (void)
|
||||
{
|
||||
/* Affichage du résultat du test */
|
||||
|
||||
fprintf (stdout, "%d message(s) exchanged (%d msg/sec)\n", Cpt_Msg, (int)(Cpt_Msg / Timer));
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
void stop_child (void)
|
||||
{
|
||||
switch (End_Sigum)
|
||||
{
|
||||
case SIGINT:
|
||||
|
||||
/* Fin initiée par l'utilisateur : ménage simple */
|
||||
|
||||
case SIGUSR1:
|
||||
|
||||
/* Fin initiée par le process père : ménage simple */
|
||||
|
||||
sprintf (str, "Signal USR1 received from father process");
|
||||
trace (str);
|
||||
|
||||
clean (FALSE);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* Fin anormale sur le process fils : ménage + avertit le process père */
|
||||
|
||||
clean (TRUE);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
void clean (int warn)
|
||||
{
|
||||
/* On avertit l'autre process */
|
||||
|
||||
if (warn == TRUE) kill (Its_Pid, SIGUSR1);
|
||||
|
||||
/* Fermeture du port de l'autre process */
|
||||
|
||||
if (Its_Port != NULL)
|
||||
{
|
||||
char Port_Name [256];
|
||||
|
||||
strcpy (Port_Name, Its_Port->Name);
|
||||
|
||||
MSG_Port_Close (Its_Port, MSGD_CLOSE);
|
||||
|
||||
if (Verbose)
|
||||
{
|
||||
sprintf (str, "Message port \"%s\" closed", Port_Name);
|
||||
trace (str);
|
||||
}
|
||||
}
|
||||
|
||||
/* Destruction du port de messages privé */
|
||||
|
||||
if (My_Port != NULL)
|
||||
{
|
||||
char Port_Name [256];
|
||||
|
||||
strcpy (Port_Name, My_Port->Name);
|
||||
|
||||
/* On attend un peu afin que l'autre process puisse fermer mon port de messages */
|
||||
|
||||
sleep (1);
|
||||
|
||||
MSG_Port_Close (My_Port, MSGD_DESTROY);
|
||||
|
||||
if (Verbose)
|
||||
{
|
||||
sprintf (str, "Message port \"%s\" removed", Port_Name);
|
||||
trace (str);
|
||||
}
|
||||
}
|
||||
|
||||
MSG_Library_Close (MSGD_CLOSE);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
void trace (char * s)
|
||||
{
|
||||
time_t dts;
|
||||
struct tm * dt;
|
||||
char Current_Date [25];
|
||||
char strace [100];
|
||||
|
||||
/* Get current date */
|
||||
|
||||
time (&dts);
|
||||
dt = localtime (&dts);
|
||||
sprintf (Current_Date, "%04d/%02d/%02d %02d:%02d:%02d", dt->tm_year + 1900, dt->tm_mon + 1, dt->tm_mday, dt->tm_hour, dt->tm_min, dt->tm_sec);
|
||||
|
||||
sprintf (strace, "Process %d - %s : %s\n", My_Pid, Current_Date, s);
|
||||
fprintf (stderr, strace);
|
||||
fflush (stderr);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
void parse_arg (int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
Verbose = Tree = FALSE;
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if (!strcmp (argv[i], "--help") || !strcmp (argv[i], "-h"))
|
||||
{
|
||||
fprintf (stdout, "Usage : %s [options]\n", argv[0]);
|
||||
fprintf (stdout,"options :\n");
|
||||
fprintf (stdout, "\t --help | -h\n");
|
||||
fprintf (stdout, "\t --clean\n");
|
||||
fprintf (stdout, "\t --verbose\n");
|
||||
fprintf (stdout, "\t --duration <time in seconds> (default is %d)\n", DEFAULT_TIMER);
|
||||
fprintf (stdout, "\t --window <message number> (default is %d)\n", DEFAULT_WINSIZE);
|
||||
fprintf (stdout, "\t --message <message size> (default is %d bytes)\n", DEFAULT_MSGSIZE);
|
||||
fprintf (stdout, "\t --tree\n");
|
||||
fprintf (stdout, "\t --version [-v]\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (!strcmp (argv[i], "--clean"))
|
||||
{
|
||||
if (MSG_Library_Open (NULL, NULL, MSGD_OPEN) == MSGS_OK)
|
||||
{
|
||||
if (MSG_Port_Open (FATHER_KEY, &My_Port, MSGD_OPEN) == MSGS_OK)
|
||||
MSG_Port_Close (My_Port, MSGD_DESTROY);
|
||||
|
||||
if (MSG_Port_Open (CHILD_KEY, &Its_Port, MSGD_OPEN) == MSGS_OK)
|
||||
MSG_Port_Close (Its_Port, MSGD_DESTROY);
|
||||
|
||||
MSG_Library_Close (MSGD_CLOSE);
|
||||
}
|
||||
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (!strcmp (argv[i], "--verbose"))
|
||||
{
|
||||
Verbose = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp (argv[i], "--tree"))
|
||||
{
|
||||
Tree = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp (argv[i], "--duration"))
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
fprintf (stderr, "Missing argument after %s\n", argv[i - 1]);
|
||||
exit (0);
|
||||
}
|
||||
Timer = atoi (argv[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp (argv[i], "--window"))
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
fprintf (stderr, "Missing argument after %s\n", argv[i - 1]);
|
||||
exit (0);
|
||||
}
|
||||
Win_Size = atoi (argv[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp (argv[i], "--message"))
|
||||
{
|
||||
i++;
|
||||
if (i == argc)
|
||||
{
|
||||
fprintf (stderr, "Missing argument after %s\n", argv[i - 1]);
|
||||
exit (0);
|
||||
}
|
||||
Msg_Size = atoi (argv[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp (argv[i], "--version"))
|
||||
{
|
||||
if (i+1 < argc && !strcmp (argv[i+1], "-v"))
|
||||
{
|
||||
VER_Object_Print (stdout, VERD_VERBOSE);
|
||||
exit (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
VER_Object_Print (stdout, VERD_MINIMAL);
|
||||
exit (0);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf (stdout, "Unknown option '%s'\n", argv[i]);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
if (Timer <= 0) Timer = DEFAULT_TIMER;
|
||||
if (Win_Size <= 0) Win_Size = DEFAULT_WINSIZE;
|
||||
if (Msg_Size <= 0) Msg_Size = DEFAULT_MSGSIZE;
|
||||
}
|
||||
|
20
util/result.linux
Normal file
20
util/result.linux
Normal file
@ -0,0 +1,20 @@
|
||||
Testing LIBMSG for 10 second(s) with 1 message(s) of 10 byte(s)...
|
||||
25791 message(s) exchanged (2579 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 1 message(s) of 1000 byte(s)...
|
||||
24904 message(s) exchanged (2490 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 1 message(s) of 2048 byte(s)...
|
||||
25248 message(s) exchanged (2524 msg/sec)
|
||||
---------
|
||||
Testing LIBMSG for 10 second(s) with 10 message(s) of 10 byte(s)...
|
||||
27548 message(s) exchanged (2754 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 10 message(s) of 1000 byte(s)...
|
||||
28720 message(s) exchanged (2872 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 10 message(s) of 2048 byte(s)...
|
||||
26860 message(s) exchanged (2686 msg/sec)
|
||||
---------
|
||||
Testing LIBMSG for 10 second(s) with 100 message(s) of 10 byte(s)...
|
||||
31243 message(s) exchanged (3124 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 100 message(s) of 1000 byte(s)...
|
||||
29841 message(s) exchanged (2984 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 100 message(s) of 2048 byte(s)...
|
||||
31047 message(s) exchanged (3104 msg/sec)
|
20
util/result.linux.old
Normal file
20
util/result.linux.old
Normal file
@ -0,0 +1,20 @@
|
||||
Testing LIBMSG for 10 second(s) with 1 message(s) of 10 byte(s)...
|
||||
23639 message(s) exchanged (2363 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 1 message(s) of 1000 byte(s)...
|
||||
22974 message(s) exchanged (2297 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 1 message(s) of 2048 byte(s)...
|
||||
23340 message(s) exchanged (2334 msg/sec)
|
||||
---------
|
||||
Testing LIBMSG for 10 second(s) with 10 message(s) of 10 byte(s)...
|
||||
26497 message(s) exchanged (2649 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 10 message(s) of 1000 byte(s)...
|
||||
26441 message(s) exchanged (2644 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 10 message(s) of 2048 byte(s)...
|
||||
26680 message(s) exchanged (2668 msg/sec)
|
||||
---------
|
||||
Testing LIBMSG for 10 second(s) with 100 message(s) of 10 byte(s)...
|
||||
29914 message(s) exchanged (2991 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 100 message(s) of 1000 byte(s)...
|
||||
29854 message(s) exchanged (2985 msg/sec)
|
||||
Testing LIBMSG for 10 second(s) with 100 message(s) of 2048 byte(s)...
|
||||
29891 message(s) exchanged (2989 msg/sec)
|
155
util/skeleton.c
Normal file
155
util/skeleton.c
Normal file
@ -0,0 +1,155 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <msg.h>
|
||||
|
||||
/*------------------------------------------------------------------------------------------*/
|
||||
/* Fonction principale du programme */
|
||||
/*------------------------------------------------------------------------------------------*/
|
||||
void main ( void )
|
||||
{
|
||||
MSGT_Port * My_Port;
|
||||
MSGT_Message * Msg;
|
||||
int End_Process;
|
||||
|
||||
|
||||
/* Ouverture de la librairie LIBMSG */
|
||||
|
||||
if (MSG_Library_Open (NULL, NULL, MSGD_OPEN) != MSGS_OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Ouverture / création du port de messages privé */
|
||||
|
||||
if (MSG_Port_Open (<PORT_NAME>, &My_Port, <OPEN_MODE>) != MSGS_OK)
|
||||
/*
|
||||
<PORT_NAME> = nom du port privé (sans espace)
|
||||
<OPEN_MODE> = MSGD_OPEN ou MSGD_CREATE
|
||||
*/
|
||||
{
|
||||
MSG_Library_Close (MSGD_CLOSE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Boucle principale du programme */
|
||||
|
||||
End_Process = FALSE;
|
||||
|
||||
while (End_Proces == FALSE)
|
||||
{
|
||||
/* Ecoute du port de messages privé */
|
||||
|
||||
int rc = MSG_Message_Receive (My_Port, <RECEIVE_TYPE>, &Msg, <RECEIVE_MODE>);
|
||||
/*
|
||||
<RECEIVE_MODE> = MSGD_WAIT ou MSGD_NO_WAIT
|
||||
<RECEIVE_TYPE> = MSGD_NO_TYPE ou type prédéfini ou type utilisateur
|
||||
*/
|
||||
|
||||
switch (rc)
|
||||
{
|
||||
case MSGS_OK:
|
||||
|
||||
/* Message reçu */
|
||||
|
||||
Message_Process (Msg);
|
||||
|
||||
break;
|
||||
|
||||
case MSGS_NO_MSG:
|
||||
|
||||
/* Aucun message présent (en mode MSGD_NO_WAIT seulement) */
|
||||
|
||||
...
|
||||
|
||||
break;
|
||||
|
||||
case MSGS_BAD_TYPE:
|
||||
|
||||
/* Aucun message du type demandé (en mode MSGD_NO_WAIT seulement) */
|
||||
|
||||
...
|
||||
|
||||
break;
|
||||
|
||||
case MSGS_SIGNAL:
|
||||
|
||||
/* Ecoute interrompue par l'interception d'un signal */
|
||||
|
||||
...
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Traitement propre au programme */
|
||||
|
||||
...
|
||||
|
||||
} /* Fin de la boucle principale */
|
||||
|
||||
|
||||
/* Fermeture du port de messages privé */
|
||||
|
||||
if (MSG_Port_Close (My_Port, <CLOSE_MODE>) != MSGS_OK) /* <CLOSE_MODE> = MSGD_CLOSE ou MSGD_DESTROY */
|
||||
{
|
||||
MSG_Library_Close (MSGD_CLOSE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Fermeture de la librairie LIBMSG */
|
||||
|
||||
MSG_Library_Close (MSGD_CLOSE);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------------*/
|
||||
/* Fonction de traitement d'un message reçu sur le port privé */
|
||||
/*------------------------------------------------------------------------------------------*/
|
||||
|
||||
void Message_Process ( MSGT_Message * Msg )
|
||||
{
|
||||
/* Quel est le type du message ? */
|
||||
|
||||
switch ( (int)(Msg->Type) )
|
||||
{
|
||||
case <TYPE1>:
|
||||
|
||||
...
|
||||
|
||||
case <TYPE2>:
|
||||
|
||||
/* Traitement selon le message */
|
||||
|
||||
...
|
||||
|
||||
/* Réponse au message */
|
||||
|
||||
if (Msg->Size > strlen ("Message bien reçu"))
|
||||
{
|
||||
/* Réponse au message reçu */
|
||||
|
||||
strcpy ((char *)(Msg->Data), "Message bien reçu");
|
||||
|
||||
/* Retour à l'envoyeur */
|
||||
|
||||
if (MSG_Message_Reply (Msg) == MSGS_OK) return;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Si on n'a pas répondu au message, on le supprime */
|
||||
|
||||
MSG_Message_Free (Msg);
|
||||
}
|
Loading…
Reference in New Issue
Block a user