File:  [local] / rpl / src / gestion_variables_partagees.c
Revision 1.72: download - view: text, annotated - select for diffs - revision graph
Fri Jan 10 11:15:43 2020 UTC (4 years, 3 months ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_32, HEAD
Modification du copyright.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.32
    4:   Copyright (C) 1989-2020 Dr. BERTRAND Joël
    5: 
    6:   This file is part of RPL/2.
    7: 
    8:   RPL/2 is free software; you can redistribute it and/or modify it
    9:   under the terms of the CeCILL V2 License as published by the french
   10:   CEA, CNRS and INRIA.
   11:  
   12:   RPL/2 is distributed in the hope that it will be useful, but WITHOUT
   13:   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   14:   FITNESS FOR A PARTICULAR PURPOSE.  See the CeCILL V2 License
   15:   for more details.
   16:  
   17:   You should have received a copy of the CeCILL License
   18:   along with RPL/2. If not, write to info@cecill.info.
   19: ================================================================================
   20: */
   21: 
   22: 
   23: #include "rpl-conv.h"
   24: 
   25: 
   26: /*
   27: ================================================================================
   28:   Routine de gestion du cache des objets
   29: ================================================================================
   30:   Entrée :
   31: --------------------------------------------------------------------------------
   32:   Sortie :
   33: --------------------------------------------------------------------------------
   34:   Effets de bords : néant
   35: ================================================================================
   36: */
   37: 
   38: static inline struct_arbre_variables_partagees *
   39: allocation_noeud_partage(struct_processus *s_etat_processus)
   40: {
   41:     struct_arbre_variables_partagees            *objet;
   42: 
   43:     if ((*s_etat_processus).pointeur_variables_partagees_noeud > 0)
   44:     {
   45:         objet = (*s_etat_processus).variables_partagees_noeud
   46:                 [--(*s_etat_processus).pointeur_variables_partagees_noeud];
   47:     }
   48:     else
   49:     {
   50:         objet = malloc(sizeof(struct_arbre_variables_partagees));
   51:     }
   52: 
   53:     return(objet);
   54: }
   55: 
   56: static inline void
   57: liberation_noeud_partage(struct_processus *s_etat_processus,
   58:         struct_arbre_variables_partagees *objet)
   59: {
   60:     if ((*s_etat_processus).pointeur_variables_partagees_noeud < TAILLE_CACHE)
   61:     {
   62:         (*s_etat_processus).variables_partagees_noeud
   63:                 [(*s_etat_processus).pointeur_variables_partagees_noeud++] =
   64:                 objet;
   65:     }
   66:     else
   67:     {
   68:         free(objet);
   69:     }
   70: 
   71:     return;
   72: }
   73: 
   74: static inline struct_arbre_variables_partagees **
   75: allocation_tableau_noeuds_partages(struct_processus *s_etat_processus)
   76: {
   77:     struct_arbre_variables_partagees            **objet;
   78: 
   79:     if ((*s_etat_processus).pointeur_variables_tableau_noeuds_partages > 0)
   80:     {
   81:         objet = (*s_etat_processus).variables_tableau_noeuds_partages
   82:                 [--(*s_etat_processus)
   83:                 .pointeur_variables_tableau_noeuds_partages];
   84:     }
   85:     else
   86:     {
   87:         objet = malloc(((size_t) (*s_etat_processus)
   88:                 .nombre_caracteres_variables)
   89:                 * sizeof(struct_arbre_variables_partagees *));
   90:     }
   91: 
   92:     return(objet);
   93: }
   94: 
   95: static inline void
   96: liberation_tableau_noeuds_partages(struct_processus *s_etat_processus,
   97:         struct_arbre_variables_partagees **objet)
   98: {
   99:     if ((*s_etat_processus).pointeur_variables_tableau_noeuds_partages
  100:             < TAILLE_CACHE)
  101:     {
  102:         (*s_etat_processus).variables_tableau_noeuds_partages
  103:                 [(*s_etat_processus)
  104:                 .pointeur_variables_tableau_noeuds_partages++] = objet;
  105:     }
  106:     else
  107:     {
  108:         free(objet);
  109:     }
  110: 
  111:     return;
  112: }
  113: 
  114: 
  115: /*
  116: ================================================================================
  117:   Routine de création d'une nouvelle variable partagee
  118: ================================================================================
  119:   Entrée :
  120: --------------------------------------------------------------------------------
  121:   Sortie :
  122: --------------------------------------------------------------------------------
  123:   Effets de bords : néant
  124: ================================================================================
  125: */
  126: 
  127: logical1
  128: creation_variable_partagee(struct_processus *s_etat_processus,
  129:         struct_variable_partagee *s_variable)
  130: {
  131:     int                                     i;
  132: 
  133:     struct_arbre_variables_partagees        *l_variable_courante;
  134: 
  135:     struct_liste_variables_partagees        *l_nouvel_element;
  136: 
  137:     unsigned char                           *ptr;
  138: 
  139:     // Ajout de la variable en tête de la liste des variables partagées
  140: 
  141:     if ((l_nouvel_element = malloc(sizeof(struct_liste_variables_partagees)))
  142:             == NULL)
  143:     {
  144:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  145:         return(d_erreur);
  146:     }
  147: 
  148:     if (((*l_nouvel_element).variable = malloc(sizeof(
  149:             struct_variable_partagee))) == NULL)
  150:     {
  151:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  152:         return(d_erreur);
  153:     }
  154: 
  155:     (*(*l_nouvel_element).variable) = (*s_variable);
  156:     (*l_nouvel_element).pid = getpid();
  157:     (*l_nouvel_element).tid = pthread_self();
  158: 
  159:     if (pthread_mutex_lock(&mutex_liste_variables_partagees) != 0)
  160:     {
  161:         (*s_etat_processus).erreur_systeme = d_es_processus;
  162:         return(d_erreur);
  163:     }
  164: 
  165:     (*l_nouvel_element).suivant = (*(*s_etat_processus)
  166:             .l_liste_variables_partagees);
  167:     (*l_nouvel_element).precedent = NULL;
  168: 
  169:     if ((*(*s_etat_processus).l_liste_variables_partagees) != NULL)
  170:     {
  171:         (**(*s_etat_processus).l_liste_variables_partagees).precedent
  172:                 = l_nouvel_element;
  173:     }
  174: 
  175:     (*(*s_etat_processus).l_liste_variables_partagees) = l_nouvel_element;
  176: 
  177:     // Ajout de la variable à la feuille de l'arbre des variables partagees
  178: 
  179:     if ((*(*s_etat_processus).s_arbre_variables_partagees) == NULL)
  180:     {
  181:         if (((*(*s_etat_processus).s_arbre_variables_partagees) =
  182:                     allocation_noeud_partage(s_etat_processus)) == NULL)
  183:         {
  184:             if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  185:             {
  186:                 (*s_etat_processus).erreur_systeme = d_es_processus;
  187:                 return(d_erreur);
  188:             }
  189: 
  190:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  191:             return(d_erreur);
  192:         }
  193: 
  194:         (**(*s_etat_processus).s_arbre_variables_partagees).feuille = NULL;
  195:         (**(*s_etat_processus).s_arbre_variables_partagees)
  196:                 .noeuds_utilises = 0;
  197:         (**(*s_etat_processus).s_arbre_variables_partagees).indice_tableau_pere
  198:                 = -1;
  199:         (**(*s_etat_processus).s_arbre_variables_partagees).noeud_pere = NULL;
  200:         INITIALISATION_MUTEX((**(*s_etat_processus).s_arbre_variables_partagees)
  201:                 .mutex_feuille);
  202: 
  203:         if (((**(*s_etat_processus).s_arbre_variables_partagees).noeuds =
  204:                 allocation_tableau_noeuds_partages(s_etat_processus)) == NULL)
  205:         {
  206:             if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  207:             {
  208:                 (*s_etat_processus).erreur_systeme = d_es_processus;
  209:                 return(d_erreur);
  210:             }
  211: 
  212:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  213:             return(d_erreur);
  214:         }
  215: 
  216:         for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
  217:         {
  218:             (**(*s_etat_processus).s_arbre_variables_partagees).noeuds[i] =
  219:                     NULL;
  220:         }
  221:     }
  222: 
  223:     l_variable_courante = (*(*s_etat_processus).s_arbre_variables_partagees);
  224:     ptr = (*s_variable).nom;
  225: 
  226:     if (pthread_mutex_lock(&((*l_variable_courante).mutex_feuille)) != 0)
  227:     {
  228:         if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  229:         {
  230:             (*s_etat_processus).erreur_systeme = d_es_processus;
  231:             return(d_erreur);
  232:         }
  233: 
  234:         (*s_etat_processus).erreur_systeme = d_es_processus;
  235:         return(d_erreur);
  236:     }
  237: 
  238:     while((*ptr) != d_code_fin_chaine)
  239:     {
  240:         BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
  241:                 uprintf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
  242:                 *ptr));
  243: 
  244:         if ((*l_variable_courante).noeuds[(*s_etat_processus)
  245:                 .pointeurs_caracteres_variables[*ptr]] == NULL)
  246:         {
  247:             // Le noeud n'existe pas encore, on le crée et on le marque
  248:             // comme utilisé dans la structure parente.
  249: 
  250:             if (((*l_variable_courante).noeuds[(*s_etat_processus)
  251:                     .pointeurs_caracteres_variables[*ptr]] =
  252:                     allocation_noeud_partage(s_etat_processus)) == NULL)
  253:             {
  254:                 if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  255:                 {
  256:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  257:                     return(d_erreur);
  258:                 }
  259: 
  260:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  261:                 return(d_erreur);
  262:             }
  263: 
  264:             (*l_variable_courante).noeuds_utilises++;
  265: 
  266:             // La feuille est par défaut vide et aucun élément du tableau noeuds
  267:             // (les branches qui peuvent être issues de ce nouveau noeud)
  268:             // n'est encore utilisée.
  269: 
  270:             (*(*l_variable_courante).noeuds[(*s_etat_processus)
  271:                     .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
  272:             (*(*l_variable_courante).noeuds[(*s_etat_processus)
  273:                     .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0;
  274: 
  275:             // Le champ noeud_pere de la structure créée pointe sur
  276:             // la structure parente et l'indice tableau_pere correspond à la
  277:             // position réelle dans le tableau noeuds[] de la structure parente
  278:             // du noeud courant. Cette valeur sera utilisée lors de la
  279:             // destruction du noeud pour annuler le pointeur contenu dans
  280:             // le tableau noeuds[] de la structure parente.
  281: 
  282:             (*(*l_variable_courante).noeuds[(*s_etat_processus)
  283:                     .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
  284:                     l_variable_courante;
  285:             (*(*l_variable_courante).noeuds[(*s_etat_processus)
  286:                     .pointeurs_caracteres_variables[*ptr]])
  287:                     .indice_tableau_pere = (*s_etat_processus)
  288:                     .pointeurs_caracteres_variables[*ptr];
  289:             INITIALISATION_MUTEX((*(*l_variable_courante).noeuds
  290:                     [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]])
  291:                     .mutex_feuille);
  292: 
  293:             // Allocation du tableau noeuds[] et initialisation à zéro de
  294:             // tous les pointeurs.
  295: 
  296:             if (((*(*l_variable_courante).noeuds[(*s_etat_processus)
  297:                     .pointeurs_caracteres_variables[*ptr]]).noeuds =
  298:                     allocation_tableau_noeuds_partages(s_etat_processus))
  299:                     == NULL)
  300:             {
  301:                 if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  302:                 {
  303:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  304:                     return(d_erreur);
  305:                 }
  306: 
  307:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  308:                 return(d_erreur);
  309:             }
  310: 
  311:             for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
  312:             {
  313:                 (*(*l_variable_courante).noeuds[(*s_etat_processus)
  314:                         .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
  315:                         = NULL;
  316:             }
  317:         }
  318: 
  319:         if (pthread_mutex_lock(&((*(*l_variable_courante).noeuds
  320:                 [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]])
  321:                 .mutex_feuille)) != 0)
  322:         {
  323:             if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  324:             {
  325:                 (*s_etat_processus).erreur_systeme = d_es_processus;
  326:                 return(d_erreur);
  327:             }
  328: 
  329:             (*s_etat_processus).erreur_systeme = d_es_processus;
  330:             return(d_erreur);
  331:         }
  332: 
  333:         if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
  334:         {
  335:             if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  336:             {
  337:                 (*s_etat_processus).erreur_systeme = d_es_processus;
  338:                 return(d_erreur);
  339:             }
  340: 
  341:             (*s_etat_processus).erreur_systeme = d_es_processus;
  342:             return(d_erreur);
  343:         }
  344: 
  345:         l_variable_courante = (*l_variable_courante).noeuds
  346:                 [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
  347:         ptr++;
  348:     }
  349: 
  350:     if ((l_nouvel_element = malloc(sizeof(struct_liste_variables_partagees)))
  351:             == NULL)
  352:     {
  353:         if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  354:         {
  355:             (*s_etat_processus).erreur_systeme = d_es_processus;
  356:             return(d_erreur);
  357:         }
  358: 
  359:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  360:         return(d_erreur);
  361:     }
  362: 
  363:     // Dans la feuille de l'arbre des variables partagées, on ne balaie
  364:     // les variables que dans l'ordre. Le champ 'reference' est alors utilisé
  365:     // pour sauvegarder une référence vers la liste des variables partagées
  366:     // pour pouvoir purger l'élément en cas de besoin.
  367: 
  368:     (*l_nouvel_element).suivant = (*l_variable_courante).feuille;
  369:     (*l_nouvel_element).precedent = NULL;
  370: 
  371:     if ((*l_nouvel_element).suivant != NULL)
  372:     {
  373:         (*(*l_nouvel_element).suivant).precedent = l_nouvel_element;
  374:     }
  375: 
  376:     (*l_nouvel_element).reference =
  377:             (*(*s_etat_processus).l_liste_variables_partagees);
  378:     (*l_nouvel_element).variable = (**(*s_etat_processus)
  379:             .l_liste_variables_partagees).variable;
  380:     (*l_variable_courante).feuille = l_nouvel_element;
  381:     (*l_nouvel_element).feuille = l_variable_courante;
  382: 
  383:     if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
  384:     {
  385:         if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  386:         {
  387:             (*s_etat_processus).erreur_systeme = d_es_processus;
  388:             return(d_erreur);
  389:         }
  390: 
  391:         (*s_etat_processus).erreur_systeme = d_es_processus;
  392:         return(d_erreur);
  393:     }
  394: 
  395:     if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  396:     {
  397:         (*s_etat_processus).erreur_systeme = d_es_processus;
  398:         return(d_erreur);
  399:     }
  400: 
  401:     return(d_absence_erreur);
  402: }
  403: 
  404: 
  405: /*
  406: ================================================================================
  407:   Routine de recherche d'une variable partagée
  408: ================================================================================
  409:   Entrée :
  410: --------------------------------------------------------------------------------
  411:   Sortie :
  412: --------------------------------------------------------------------------------
  413:   Effets de bords : positionne le mutex sur la variable partagée
  414: ================================================================================
  415: */
  416: 
  417: struct_liste_variables_partagees *
  418: recherche_variable_partagee(struct_processus *s_etat_processus,
  419:         unsigned char *nom_variable, union_position_variable position,
  420:         unsigned char origine)
  421: {
  422:     int                                 pointeur;
  423: 
  424:     struct_arbre_variables_partagees    *l_variable_courante;
  425:     struct_liste_variables_partagees    *l_element_courant;
  426: 
  427:     unsigned char                       *ptr;
  428: 
  429:     l_variable_courante = (*(*s_etat_processus).s_arbre_variables_partagees);
  430:     ptr = nom_variable;
  431: 
  432:     if (l_variable_courante == NULL)
  433:     {
  434:         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  435:         return(NULL);
  436:     }
  437: 
  438:     if (pthread_mutex_lock(&((*l_variable_courante).mutex_feuille)) != 0)
  439:     {
  440:         (*s_etat_processus).erreur_systeme = d_es_processus;
  441:         return(NULL);
  442:     }
  443: 
  444:     while((*ptr) != d_code_fin_chaine)
  445:     {
  446:         pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
  447: 
  448:         if (pointeur < 0)
  449:         {
  450:             // Caractère hors de l'alphabet des variables
  451: 
  452:             pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille));
  453:             (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  454:             return(NULL);
  455:         }
  456: 
  457:         if ((*l_variable_courante).noeuds[pointeur] == NULL)
  458:         {
  459:             // Le chemin de la variable candidate n'existe pas.
  460: 
  461:             pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille));
  462:             (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  463:             return(NULL);
  464:         }
  465: 
  466:         if (pthread_mutex_lock(&((*(*l_variable_courante).noeuds[pointeur])
  467:                 .mutex_feuille)) != 0)
  468:         {
  469:             pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille));
  470:             (*s_etat_processus).erreur_systeme = d_es_processus;
  471:             return(NULL);
  472:         }
  473: 
  474:         if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
  475:         {
  476:             (*s_etat_processus).erreur_systeme = d_es_processus;
  477:             return(NULL);
  478:         }
  479: 
  480:         l_variable_courante = (*l_variable_courante).noeuds[pointeur];
  481:         ptr++;
  482:     }
  483: 
  484:     if ((*l_variable_courante).feuille != NULL)
  485:     {
  486:         // Il existe au moins une variable partagée du nom requis.
  487: 
  488:         l_element_courant = (*l_variable_courante).feuille;
  489: 
  490:         while(l_element_courant != NULL)
  491:         {
  492:             if ((*(*l_element_courant).variable).origine == 'P')
  493:             {
  494:                 if (((*(*l_element_courant).variable).variable_partagee.adresse
  495:                         == position.adresse) &&
  496:                         ((*(*l_element_courant).variable).origine == origine))
  497:                 {
  498:                     if (pthread_mutex_lock(&((*(*l_element_courant).variable)
  499:                             .mutex)) != 0)
  500:                     {
  501:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  502:                         return(NULL);
  503:                     }
  504: 
  505:                     if (pthread_mutex_unlock(&((*l_variable_courante)
  506:                             .mutex_feuille)) != 0)
  507:                     {
  508:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  509:                         return(NULL);
  510:                     }
  511: 
  512:                     (*s_etat_processus).pointeur_variable_partagee_courante
  513:                             = (*l_element_courant).variable;
  514:                     return(l_element_courant);
  515:                 }
  516:             }
  517:             else
  518:             {
  519:                 if (((*(*l_element_courant).variable).variable_partagee.pointeur
  520:                         == position.pointeur) &&
  521:                         ((*(*l_element_courant).variable).origine == origine))
  522:                 {
  523:                     if (pthread_mutex_lock(&((*(*l_element_courant).variable)
  524:                             .mutex)) != 0)
  525:                     {
  526:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  527:                         return(NULL);
  528:                     }
  529: 
  530:                     if (pthread_mutex_unlock(&((*l_variable_courante)
  531:                             .mutex_feuille)) != 0)
  532:                     {
  533:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  534:                         return(NULL);
  535:                     }
  536: 
  537:                     (*s_etat_processus).pointeur_variable_partagee_courante
  538:                             = (*l_element_courant).variable;
  539:                     return(l_element_courant);
  540:                 }
  541:             }
  542: 
  543:             l_element_courant = (*l_element_courant).suivant;
  544:         }
  545:     }
  546: 
  547:     if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
  548:     {
  549:         (*s_etat_processus).erreur_systeme = d_es_processus;
  550:         return(NULL);
  551:     }
  552: 
  553:     (*s_etat_processus).pointeur_variable_statique_courante = NULL;
  554:     return(NULL);
  555: }
  556: 
  557: 
  558: /*
  559: ================================================================================
  560:   Routine de retrait d'une variable partagée
  561: ================================================================================
  562:   Entrée :
  563: --------------------------------------------------------------------------------
  564:   Sortie :
  565: --------------------------------------------------------------------------------
  566:   Effets de bords : néant
  567: ================================================================================
  568: */
  569: 
  570: logical1
  571: retrait_variable_partagee(struct_processus *s_etat_processus,
  572:         unsigned char *nom_variable, union_position_variable position)
  573: {
  574:     struct_liste_variables_partagees        *l_element_a_supprimer;
  575:     struct_liste_variables_partagees        *l_element_liste_a_supprimer;
  576: 
  577:     logical1                                erreur;
  578: 
  579:     if ((l_element_a_supprimer = recherche_variable_partagee(s_etat_processus,
  580:             nom_variable, position, ((*s_etat_processus)
  581:             .mode_execution_programme == 'Y') ? 'P' : 'E')) != NULL)
  582:     {
  583:         if (pthread_mutex_lock(&mutex_liste_variables_partagees) != 0)
  584:         {
  585:             (*s_etat_processus).erreur_systeme = d_es_processus;
  586:             return(d_erreur);
  587:         }
  588: 
  589:         // (*s_etat_processus).pointeur_variable_partagee_courante
  590:         // pointe sur la variable à éliminer. Cette variable est celle qui
  591:         // est présente dans l'une des feuilles statiques de l'arbre des
  592:         // variables.
  593: 
  594:         l_element_liste_a_supprimer = (*l_element_a_supprimer).reference;
  595: 
  596:         // Suppression de la liste des variables statiques
  597: 
  598:         if ((*l_element_liste_a_supprimer).precedent != NULL)
  599:         {
  600:             // L'élément à supprimer n'est pas le premier de la liste.
  601: 
  602:             (*(*l_element_liste_a_supprimer).precedent).suivant =
  603:                     (*l_element_liste_a_supprimer).suivant;
  604: 
  605:             if ((*l_element_liste_a_supprimer).suivant != NULL)
  606:             {
  607:                 // Il y a un élément suivant. On le chaîne.
  608:                 (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
  609:             }
  610:         }
  611:         else
  612:         {
  613:             // L'élement est le premier de la liste. S'il y a un élément
  614:             // suivant, on le chaîne.
  615: 
  616:             if ((*l_element_liste_a_supprimer).suivant != NULL)
  617:             {
  618:                 (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
  619:             }
  620: 
  621:             (*(*s_etat_processus).l_liste_variables_partagees) =
  622:                     (*l_element_liste_a_supprimer).suivant;
  623:         }
  624: 
  625:         free(l_element_liste_a_supprimer);
  626: 
  627:         // Suppression depuis la feuille statique. Le champ 'precedent' ne sert
  628:         // pas car la liste est simplement chaînée.
  629: 
  630:         if ((*l_element_a_supprimer).precedent != NULL)
  631:         {
  632:             // L'élément n'est pas le premier de la liste.
  633: 
  634:             (*(*l_element_a_supprimer).precedent).suivant =
  635:                     (*l_element_a_supprimer).suivant;
  636: 
  637:             if ((*l_element_a_supprimer).suivant != NULL)
  638:             {
  639:                 (*(*l_element_a_supprimer).suivant).precedent =
  640:                         (*l_element_a_supprimer).precedent;
  641:             }
  642:             else
  643:             {
  644:                 (*(*l_element_a_supprimer).precedent).suivant = NULL;
  645:             }
  646:         }
  647:         else
  648:         {
  649:             // L'élément est le premier de la liste.
  650: 
  651:             if ((*l_element_a_supprimer).suivant != NULL)
  652:             {
  653:                 (*(*l_element_a_supprimer).suivant).precedent = NULL;
  654:             }
  655: 
  656:             (*(*l_element_a_supprimer).feuille).feuille
  657:                     = (*l_element_a_supprimer).suivant;
  658:         }
  659: 
  660:         liberation(s_etat_processus, (*(*l_element_a_supprimer).variable)
  661:                 .objet);
  662:         free((*(*l_element_a_supprimer).variable).nom);
  663:         pthread_mutex_unlock(&((*(*l_element_a_supprimer).variable).mutex));
  664:         pthread_mutex_destroy(&((*(*l_element_a_supprimer).variable).mutex));
  665:         free((*l_element_a_supprimer).variable);
  666:         free(l_element_a_supprimer);
  667: 
  668:         if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  669:         {
  670:             (*s_etat_processus).erreur_systeme = d_es_processus;
  671:             return(d_erreur);
  672:         }
  673: 
  674:         erreur = d_absence_erreur;
  675:     }
  676:     else
  677:     {
  678:         erreur = d_erreur;
  679:         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  680:     }
  681: 
  682:     return(erreur);
  683: }
  684: 
  685: 
  686: /*
  687: ================================================================================
  688:   Routine de retrait des variables partagées
  689: ================================================================================
  690:   Entrée :
  691: --------------------------------------------------------------------------------
  692:   Sortie :
  693: --------------------------------------------------------------------------------
  694:   Effets de bords : néant
  695: ================================================================================
  696: */
  697: 
  698: // Cette routine libère toutes les variables partagées de niveau non
  699: // nul, donc attachées à une expression et non un programme.
  700: 
  701: logical1
  702: retrait_variables_partagees_locales(struct_processus *s_etat_processus)
  703: {
  704:     struct_liste_variables_partagees    *l_element_courant;
  705:     struct_liste_variables_partagees    *l_element_suivant;
  706: 
  707:     unsigned char                       registre_mode_execution;
  708: 
  709:     if (pthread_mutex_lock(&mutex_liste_variables_partagees) != 0)
  710:     {
  711:         (*s_etat_processus).erreur_systeme = d_es_processus;
  712:         return(d_erreur);
  713:     }
  714: 
  715:     registre_mode_execution = (*s_etat_processus).mode_execution_programme;
  716:     l_element_courant = (*(*s_etat_processus).l_liste_variables_partagees);
  717: 
  718:     while(l_element_courant != NULL)
  719:     {
  720:         l_element_suivant = (*l_element_courant).suivant;
  721: 
  722:         (*s_etat_processus).mode_execution_programme =
  723:                 ((*(*l_element_courant).variable).origine == 'P') ? 'Y' : 'N';
  724: 
  725:         if (((*(*l_element_courant).variable).niveau > 0) &&
  726:                 ((*l_element_courant).pid == getpid()) &&
  727:                 (pthread_equal((*l_element_courant).tid, pthread_self()) != 0))
  728:         {
  729:             if (retrait_variable_partagee(s_etat_processus,
  730:                     (*(*l_element_courant).variable).nom,
  731:                     (*(*l_element_courant).variable).variable_partagee)
  732:                     == d_erreur)
  733:             {
  734:                 if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  735:                 {
  736:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  737:                     return(d_erreur);
  738:                 }
  739: 
  740:                 (*s_etat_processus).mode_execution_programme =
  741:                         registre_mode_execution;
  742:                 return(d_erreur);
  743:             }
  744:         }
  745: 
  746:         l_element_courant = l_element_suivant;
  747:     }
  748: 
  749:     (*s_etat_processus).mode_execution_programme = registre_mode_execution;
  750: 
  751:     if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  752:     {
  753:         (*s_etat_processus).erreur_systeme = d_es_processus;
  754:         return(d_erreur);
  755:     }
  756: 
  757:     return(d_absence_erreur);
  758: }
  759: 
  760: 
  761: /*
  762: ================================================================================
  763:   Routine de libération de l'arbre des variables partagées
  764: ================================================================================
  765:   Entrée :
  766: --------------------------------------------------------------------------------
  767:   Sortie :
  768: --------------------------------------------------------------------------------
  769:   Effets de bords : positionne le mutex sur la variable partagée
  770: ================================================================================
  771: */
  772: 
  773: void
  774: liberation_arbre_variables_partagees(struct_processus *s_etat_processus,
  775:         struct_arbre_variables_partagees *arbre)
  776: {
  777:     int                                 i;
  778: 
  779:     struct_liste_variables_partagees    *l_element_partage_courant;
  780:     struct_liste_variables_partagees    *l_element_partage_suivant;
  781: 
  782:     // Libération de l'arbre des variables. Le contenu des variables n'est
  783:     // pas détruit par cette opération, il sera détruit lors de la libération
  784:     // de la liste des variables par niveau.
  785: 
  786:     if (arbre == NULL)
  787:     {
  788:         return;
  789:     }
  790: 
  791:     if (pthread_mutex_lock(&((*arbre).mutex_feuille)) != 0)
  792:     {
  793:         (*s_etat_processus).erreur_systeme = d_es_processus;
  794:         return;
  795:     }
  796: 
  797:     l_element_partage_courant = (*arbre).feuille;
  798: 
  799:     while(l_element_partage_courant != NULL)
  800:     {
  801:         l_element_partage_suivant = (*l_element_partage_courant).suivant;
  802: 
  803:         if (pthread_mutex_lock(&((*(*l_element_partage_courant).variable)
  804:                 .mutex)) != 0)
  805:         {
  806:             (*s_etat_processus).erreur_systeme = d_es_processus;
  807:             return;
  808:         }
  809: 
  810:         free((*(*l_element_partage_courant).variable).nom);
  811:         liberation(s_etat_processus, (*(*l_element_partage_courant)
  812:                 .variable).objet);
  813:         free((*l_element_partage_courant).variable);
  814: 
  815:         if (pthread_mutex_unlock(&((*(*l_element_partage_courant).variable)
  816:                 .mutex)) != 0)
  817:         {
  818:             (*s_etat_processus).erreur_systeme = d_es_processus;
  819:             return;
  820:         }
  821: 
  822:         if (pthread_mutex_destroy(&((*(*l_element_partage_courant).variable)
  823:                 .mutex)) != 0)
  824:         {
  825:             (*s_etat_processus).erreur_systeme = d_es_processus;
  826:             return;
  827:         }
  828: 
  829:         free(l_element_partage_courant);
  830: 
  831:         l_element_partage_courant = l_element_partage_suivant;
  832:     }
  833: 
  834:     for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
  835:     {
  836:         if ((*arbre).noeuds[i] != NULL)
  837:         {
  838:             liberation_arbre_variables_partagees(s_etat_processus,
  839:                     (*arbre).noeuds[i]);
  840:             (*arbre).noeuds[i] = NULL;
  841:         }
  842:     }
  843: 
  844:     liberation_tableau_noeuds_partages(s_etat_processus, (*arbre).noeuds);
  845:     liberation_noeud_partage(s_etat_processus, arbre);
  846: 
  847:     if (pthread_mutex_unlock(&((*arbre).mutex_feuille)) != 0)
  848:     {
  849:         (*s_etat_processus).erreur_systeme = d_es_processus;
  850:         return;
  851:     }
  852: 
  853:     if (pthread_mutex_destroy(&((*arbre).mutex_feuille)) != 0)
  854:     {
  855:         (*s_etat_processus).erreur_systeme = d_es_processus;
  856:         return;
  857:     }
  858: 
  859:     arbre = NULL;
  860:     return;
  861: }
  862: 
  863: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>