/*************************************************************************************************************************************/ /* */ /* 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