File:  [local] / rpl / src / gestion_variables_partagees.c
Revision 1.39: download - view: text, annotated - select for diffs - revision graph
Mon Dec 17 21:22:43 2012 UTC (11 years, 5 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Série de patches pour les variables partagées. Les patches ne provoquent pas
de segfault, mais n'ont pas encore été testés sur des variables partagées.

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

CVSweb interface <joel.bertrand@systella.fr>