/*************************************************************************************************************************************/
/* */
/* G E S T I O N D E S P H A S E S C R I T I Q U E S : */
/* */
/* */
/* Utilisation : */
/* */
/* Cette commande est a priori destinee a permettre */
/* le remplacement de : */
/* */
/* $xEa/PhasCriB$vv$Y */
/* $xEa/PhasCriE$vv$Y */
/* */
/* par : */
/* */
/* $xEa/PhasCriB.PhaseCrit.01$vv$Y */
/* $xEa/PhasCriE.PhaseCrit.01$vv$Y */
/* */
/* dans la definition des alias {PhasCriB,PhasCriE} via */
/* les variables {$Falias_PhasCriB,$Falias_PhasCriE}. */
/* */
/* Les experiences de chronometrage reposant sur une iteration de */
/* la simple suite de commandes {PhasCriB,PhasCriE} montrent que */
/* malheureusement le gain semble strictement nul (a la seconde */
/* pres), ce que j'ai du mal a comprendre... */
/* */
/* */
/* Author of '$xcg/PhaseCrit.01$K' : */
/* */
/* Jean-Francois COLONNA (LACTAMME, 20110531095911). */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* I N T E R F A C E ' listG ' : */
/* */
/* */
/* :Debut_listG: */
/* :Fin_listG: */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D I R E C T I V E S S P E C I F I Q U E S D E C O M P I L A T I O N : */
/* */
/*************************************************************************************************************************************/
@define PRAGMA_CL_____PAS_DE_LIBRAIRIES_DYNAMIQUES
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* F I C H I E R S D ' I N C L U D E S : */
/* */
/*************************************************************************************************************************************/
#include INCLUDES_MINI
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* P A R A M E T R E S : */
/* */
/*===================================================================================================================================*/
#define ENTRER_DANS_UNE_PHASE_CRITIQUE \
VRAI \
/* Il y a deux modes de fonctionnement : entree ou 'Begin' ('VRAI') et sortie ou 'End' */ \
/* ('FAUX'). */
#define FORCER_L_ENTREE_DANS_UNE_PHASE_CRITIQUE_QUEL_QUE_SOIT_L_ETAT_DU_FICHIER \
VRAI \
/* Il y a deux modes de fonctionnement lors de l'entree en phase critique : l'un autorisant */ \
/* l'absence du fichier ('VRAI') et l'autre pas ('FAUX')... */
#if ( (defined(CMAP28)) \
)
/* Introduit le 20070423134356... */
# define PRE_METTRE_A_JOUR_LE_CACHE_DES_DIRECTORIES \
VRAI \
/* Si 'IL_NE_FAUT_PAS(executer_une_sequence_en_parallele)' faut-il tenter de pre-mettre */ \
/* a jour le cache des directories ('VRAI') ou pas ('FAUX') ? */
#Aif ( (defined(CMAP28)) \
)
# define PRE_METTRE_A_JOUR_LE_CACHE_DES_DIRECTORIES \
FAUX \
/* Si 'IL_NE_FAUT_PAS(executer_une_sequence_en_parallele)' faut-il tenter de pre-mettre */ \
/* a jour le cache des directories ('VRAI') ou pas ('FAUX') ? */
#Eif ( (defined(CMAP28)) \
)
#define EDITER_LES_MESSAGES_D_ERREUR \
NE_PAS_EDITER_LES_MESSAGES_D_ERREUR_DES_FICHIERS \
/* Indicateur a utiliser pour editer les messages d'erreur des fichiers. */
#define LIMITER_LE_NOMBRE_DE_TENTATIVES \
FAUX
#define NOMBRE_MAXIMAL_DE_TENTATIVES \
INFINI
#define DUREE_D_ATTENTE_ENTRE_DEUX_TENTATIVES \
FDU
/* Nombre maximal de tentatives d'entree dans la phase critique (si necessaire...). */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* M A C R O S U T I L E S : */
/* */
/*************************************************************************************************************************************/
#define CONTENU_DU_VERROU \
chain_Aconcaten10("DATE=" \
,mise_de_la_date_courante_au_format_____AAAAMMJJhhmmss() \
," : MACHINE=" \
,sHOTE \
," (" \
,mHOTE \
,COND(IFET(IFNE_chaine(vCOMPUTER,VALEUR_D_UNE_VARIABLE_UNDEF) \
,IFNE_chaine(vCOMPUTER,amHOTE) \
) \
,chain_Aconcaten4(" ex ",C_VERITABLE_QUOTE,vCOMPUTER,C_VERITABLE_QUOTE) \
,ccCHAR(C_VIDE) \
) \
,COND(IFNE_chaine(mHOTE_Force,VALEUR_D_UNE_VARIABLE_UNDEF) \
,chain_Aconcaten4(" ex ",C_VERITABLE_QUOTE,mHOTE_Force,C_VERITABLE_QUOTE) \
,ccCHAR(C_VIDE) \
) \
,") --> process=" \
,pid \
) \
/* Definition du contenu du verrou... */
#define LECTURE_D_UN_VERROU(verrou_courant) \
Bblock \
DEFV(Int,INIT(taille_du_verrou_courant,UNDEF)); \
\
CALS(Fsize_fichier(nom_du_verrou_du_fichier_a_verrouiller \
,ADRESSE(taille_du_verrou_courant) \
,editer_les_messages_d_erreur \
) \
); \
\
EGAL(verrou_courant,kMalo(taille_du_verrou_courant)); \
CALS(Fload_fichier_non_formatte(nom_du_verrou_du_fichier_a_verrouiller \
,verrou_courant \
,taille_du_verrou_courant \
,size_CHAR \
,editer_les_messages_d_erreur \
,editer_les_messages_d_erreur \
) \
); \
Eblock \
/* Lecture du contenu d'un verrou... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* G E S T I O N D E S P H A S E S C R I T I Q U E S : */
/* */
/*************************************************************************************************************************************/
BCommande(nombre_d_arguments,arguments)
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(CHAR,INIC(POINTERc(nom_du_fichier_a_verrouiller),NOM_UNDEF_VIDE));
/* Nom du fichier a verrouiller par une phase critique... */
DEFV(CHAR,INIC(POINTERc(nom_du_verrou_du_fichier_a_verrouiller),NOM_UNDEF_VIDE));
/* Nom du verrou du fichier a verrouiller par une phase critique... */
DEFV(Logical,INIT(pre_mettre_a_jour_le_cache_des_directories,PRE_METTRE_A_JOUR_LE_CACHE_DES_DIRECTORIES));
/* Si 'IL_NE_FAUT_PAS(executer_une_sequence_en_parallele)' faut-il tenter de pre-mettre */
/* a jour le cache des directories ('VRAI') ou pas ('FAUX') ? */
DEFV(CHAR,INIC(POINTERc(postfixe_VERROU),Gvar("v")));
/* Nom du postfixe de verrouillage a utiliser. */
DEFV(CHAR,INIC(POINTERc(sHOTE),Gvar_sHOTE));
DEFV(CHAR,INIC(POINTERc(mHOTE),Gvar_mHOTE));
DEFV(CHAR,INIC(POINTERc(vCOMPUTER),Gvar_vCOMPUTER));
DEFV(CHAR,INIC(POINTERc(mHOTE_Force),Gvar_mHOTE_Force));
DEFV(CHAR,INIC(POINTERc(amHOTE),Gvar_amHOTE));
/* Definition de la MACHINE "hote"... */
DEFV(CHAR,INIC(POINTERc(pid),chain_Aentier(GvalDefaut("Cshell",Gpid()))));
/* Definition de l'identite du '$CSH' courant (ou du '$X' courant par defaut...). */
DEFV(Logical,INIT(entrer_dans_une_phase_critique,ENTRER_DANS_UNE_PHASE_CRITIQUE));
/* Est-ce une entree ('Begin') ou une sortie ('End') ? */
DEFV(Logical,INIT(forcer_l_entree_dans_une_phase_critique_quel_que_soit_l_etat_du_fichier
,FORCER_L_ENTREE_DANS_UNE_PHASE_CRITIQUE_QUEL_QUE_SOIT_L_ETAT_DU_FICHIER
)
);
/* Il y a deux modes de fonctionnement lors de l'entree en phase critique : l'un autorisant */
/* l'absence du fichier ('VRAI') et l'autre pas ('FAUX')... */
/* */
/* Voir 'v $Falias_PhasCriB ToUjOuRs_PhasCriB' a ce propos... */
DEFV(Logical,INIT(editer_les_messages_d_erreur,EDITER_LES_MESSAGES_D_ERREUR));
/* Indicateur a utiliser pour editer les messages d'erreur des fichiers. */
DEFV(Logical,INIT(limiter_le_nombre_de_tentatives,LIMITER_LE_NOMBRE_DE_TENTATIVES));
DEFV(Positive,INIT(nombre_maximal_de_tentatives,NOMBRE_MAXIMAL_DE_TENTATIVES));
DEFV(Float,INIT(duree_d_attente_entre_deux_tentatives,DUREE_D_ATTENTE_ENTRE_DEUX_TENTATIVES));
/* Nombre maximal de tentatives d'entree dans la phase critique (si necessaire...). */
/* */
/* Voir 'v $Falias_PhasCriB LiMiT_PhasCriB' et 'v $Falias_PhasCriB LiMiT_PhasCriB' a ce */
/* propos... */
/*..............................................................................................................................*/
GET_ARGUMENTS_(nombre_d_arguments
,BLOC(GET_ARGUMENT_C("fichier_a_verrouiller=""fichier=",nom_du_fichier_a_verrouiller);
GET_ARGUMENT_C("VERROU=""verrou=""v=",postfixe_VERROU);
GET_ARGUMENT_L("PhasCriB=""Begin=""B=",entrer_dans_une_phase_critique);
GET_ARGUMENT_N("PhasCriE=""End=""E=",entrer_dans_une_phase_critique);
GET_ARGUMENT_L("forcer_fichier_inexistant=""forcer=""ffi="
,forcer_l_entree_dans_une_phase_critique_quel_que_soit_l_etat_du_fichier
);
GET_ARGUMENT_L("pmajcd=""pmaj=""cache_des_directories=",pre_mettre_a_jour_le_cache_des_directories);
GET_ARGUMENT_L("erreurs=",editer_les_messages_d_erreur);
GET_ARGUMENT_L("limiter_tentatives=""limiter=",limiter_le_nombre_de_tentatives);
GET_ARGUMENT_I("nombre_maximal_tentatives=""tentatives=",nombre_maximal_de_tentatives);
GET_ARGUMENT_F("duree=""temporisation=",duree_d_attente_entre_deux_tentatives);
)
);
Test(IFGT(duree_d_attente_entre_deux_tentatives,FDEUX))
Bblock
PRINT_ERREUR("la duree entre deux tentatives ne peut execeder deux secondes");
EGAL(duree_d_attente_entre_deux_tentatives,FDEUX);
/* A ce propos 'v $xil/defi_c1$vv$DEF 20110531165758'... */
Eblock
ATes
Bblock
Eblock
ETes
EGAL(nom_du_verrou_du_fichier_a_verrouiller,chain_Aconcaten2(nom_du_fichier_a_verrouiller,postfixe_VERROU));
Test(IL_FAUT(entrer_dans_une_phase_critique))
Bblock
DEFV(Logical,INIT(tenter_la_generation_du_verrou,VRAI));
DEFV(Positive,INIT(nombre_de_tentatives,ZERO));
Test(IFOU(IL_FAUT(forcer_l_entree_dans_une_phase_critique_quel_que_soit_l_etat_du_fichier)
,IFET(IL_NE_FAUT_PAS(forcer_l_entree_dans_une_phase_critique_quel_que_soit_l_etat_du_fichier)
,PAS_D_ERREUR(Ftest_fichier_avec_pre_mise_a_jour_du_cache_des_directories
(nom_du_fichier_a_verrouiller
,pre_mettre_a_jour_le_cache_des_directories
,NE_PAS_EDITER_LES_MESSAGES_D_ERREUR_DES_FICHIERS
)
)
)
)
)
Bblock
Tant(IL_FAUT(tenter_la_generation_du_verrou))
Bblock
DEFV(CHAR,INIC(POINTERc(contenu_du_verrou_du_fichier_a_verrouiller),CONTENU_DU_VERROU));
/* Generation d'un verrou approprie... */
Test(PAS_D_ERREUR(CODE_ERROR(Fstore_fichier_non_formatte(contenu_du_verrou_du_fichier_a_verrouiller
,nom_du_verrou_du_fichier_a_verrouiller
,chain_taille(contenu_du_verrou_du_fichier_a_verrouiller)
,size_CHAR
,editer_les_messages_d_erreur
)
)
)
)
Bblock
DEFV(CHAR,INIT(POINTERc(verification_du_contenu_du_verrou_du_fichier_a_verrouiller),CHAINE_UNDEF));
LECTURE_D_UN_VERROU(verification_du_contenu_du_verrou_du_fichier_a_verrouiller);
Test(IFEQ_chaine(verification_du_contenu_du_verrou_du_fichier_a_verrouiller
,contenu_du_verrou_du_fichier_a_verrouiller
)
)
Bblock
EGAL(tenter_la_generation_du_verrou,FAUX);
/* Lorsque le verrou que l'on relit est bien celui que l'on a ecrit, on considere que */
/* l'appropriation est bonne et qu'ainsi on est bien rentre dans la phase critique... */
CALS(Chmod(nom_du_verrou_du_fichier_a_verrouiller,NEUT(S_IRUSR)));
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
Test(IL_FAUT(tenter_la_generation_du_verrou))
Bblock
Test(IL_FAUT(limiter_le_nombre_de_tentatives))
Bblock
INCR(nombre_de_tentatives,I);
Test(IFGE(nombre_de_tentatives,nombre_maximal_de_tentatives))
Bblock
EGAL(tenter_la_generation_du_verrou,FAUX);
/* Lorsque trop de tentatives ont ete effectuees, on arrete brutalement... */
PRINT_ERREUR("trop de tentatives d'entree en phase critique ont ete effectuees");
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
Test(IL_FAUT(tenter_la_generation_du_verrou))
Bblock
PETIT_DODO(MUL2(duree_d_attente_entre_deux_tentatives,nano_secondes));
/* Et on attend un peu avant d'iterer... */
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ETan
Eblock
ATes
Bblock
PRINT_ERREUR("le fichier n'existait pas");
CAL1(Prer1("son nom est '%s'.\n",nom_du_fichier_a_verrouiller));
Eblock
ETes
Eblock
ATes
Bblock
#define nom_du_verrou_du_fichier_a_deverrouiller \
nom_du_verrou_du_fichier_a_verrouiller \
/* Afin d'avoir une notation homogene avec l'action ici accomplie... */
Test(PAS_D_ERREUR(Ftest_fichier_avec_pre_mise_a_jour_du_cache_des_directories(nom_du_verrou_du_fichier_a_deverrouiller
,pre_mettre_a_jour_le_cache_des_directories
,NE_PAS_EDITER_LES_MESSAGES_D_ERREUR_DES_FICHIERS
)
)
)
Bblock
DEFV(CHAR,INIT(POINTERc(contenu_du_verrou_du_fichier_a_deverrouiller),CHAINE_UNDEF));
LECTURE_D_UN_VERROU(contenu_du_verrou_du_fichier_a_deverrouiller);
CALS(Chmod(nom_du_verrou_du_fichier_a_deverrouiller,OUIN(S_IRUSR,S_IWUSR)));
CALS(Fdelete_fichier(nom_du_verrou_du_fichier_a_deverrouiller,editer_les_messages_d_erreur));
/* Destruction du verrou... */
CALZ_FreCC(contenu_du_verrou_du_fichier_a_deverrouiller);
Eblock
ATes
Bblock
PRINT_ERREUR("le verrou n'existait pas");
CAL1(Prer1("son nom est '%s'.\n",nom_du_verrou_du_fichier_a_deverrouiller));
Eblock
ETes
#undef nom_du_verrou_du_fichier_a_deverrouiller
Eblock
ETes
RETU_Commande;
Eblock
ECommande