File:  [local] / rpl / src / gestion_variables_partagees.c
Revision 1.45: download - view: text, annotated - select for diffs - revision graph
Wed Mar 20 17:11:44 2013 UTC (11 years, 2 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Première série de patches pour compiler avec l'option -Wconversion.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.13
    4:   Copyright (C) 1989-2013 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:             (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  453:             return(NULL);
  454:         }
  455: 
  456:         if ((*l_variable_courante).noeuds[pointeur] == NULL)
  457:         {
  458:             // Le chemin de la variable candidate n'existe pas.
  459:             (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  460:             return(NULL);
  461:         }
  462: 
  463:         if (pthread_mutex_lock(&((*(*l_variable_courante).noeuds[pointeur])
  464:                 .mutex_feuille)) != 0)
  465:         {
  466:             (*s_etat_processus).erreur_systeme = d_es_processus;
  467:             return(NULL);
  468:         }
  469: 
  470:         if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
  471:         {
  472:             (*s_etat_processus).erreur_systeme = d_es_processus;
  473:             return(NULL);
  474:         }
  475: 
  476:         l_variable_courante = (*l_variable_courante).noeuds[pointeur];
  477:         ptr++;
  478:     }
  479: 
  480:     if ((*l_variable_courante).feuille != NULL)
  481:     {
  482:         // Il existe au moins une variable statique du nom requis.
  483: 
  484:         l_element_courant = (*l_variable_courante).feuille;
  485: 
  486:         while(l_element_courant != NULL)
  487:         {
  488:             if ((*(*l_element_courant).variable).origine == 'P')
  489:             {
  490:                 if (((*(*l_element_courant).variable).variable_partagee.adresse
  491:                         == position.adresse) &&
  492:                         ((*(*l_element_courant).variable).origine == origine))
  493:                 {
  494:                     if (pthread_mutex_lock(&((*(*l_element_courant).variable)
  495:                             .mutex)) != 0)
  496:                     {
  497:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  498:                         return(NULL);
  499:                     }
  500: 
  501:                     if (pthread_mutex_unlock(&((*l_variable_courante)
  502:                             .mutex_feuille)) != 0)
  503:                     {
  504:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  505:                         return(NULL);
  506:                     }
  507: 
  508:                     (*s_etat_processus).pointeur_variable_partagee_courante
  509:                             = (*l_element_courant).variable;
  510:                     return(l_element_courant);
  511:                 }
  512:             }
  513:             else
  514:             {
  515:                 if (((*(*l_element_courant).variable).variable_partagee.pointeur
  516:                         == position.pointeur) &&
  517:                         ((*(*l_element_courant).variable).origine == origine))
  518:                 {
  519:                     if (pthread_mutex_lock(&((*(*l_element_courant).variable)
  520:                             .mutex)) != 0)
  521:                     {
  522:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  523:                         return(NULL);
  524:                     }
  525: 
  526:                     if (pthread_mutex_unlock(&((*l_variable_courante)
  527:                             .mutex_feuille)) != 0)
  528:                     {
  529:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  530:                         return(NULL);
  531:                     }
  532: 
  533:                     (*s_etat_processus).pointeur_variable_partagee_courante
  534:                             = (*l_element_courant).variable;
  535:                     return(l_element_courant);
  536:                 }
  537:             }
  538: 
  539:             l_element_courant = (*l_element_courant).suivant;
  540:         }
  541:     }
  542: 
  543:     if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
  544:     {
  545:         (*s_etat_processus).erreur_systeme = d_es_processus;
  546:         return(NULL);
  547:     }
  548: 
  549:     (*s_etat_processus).pointeur_variable_statique_courante = NULL;
  550:     return(NULL);
  551: }
  552: 
  553: 
  554: /*
  555: ================================================================================
  556:   Routine de retrait d'une variable partagée
  557: ================================================================================
  558:   Entrée :
  559: --------------------------------------------------------------------------------
  560:   Sortie :
  561: --------------------------------------------------------------------------------
  562:   Effets de bords : néant
  563: ================================================================================
  564: */
  565: 
  566: logical1
  567: retrait_variable_partagee(struct_processus *s_etat_processus,
  568:         unsigned char *nom_variable, union_position_variable position)
  569: {
  570:     struct_liste_variables_partagees        *l_element_a_supprimer;
  571:     struct_liste_variables_partagees        *l_element_liste_a_supprimer;
  572: 
  573:     logical1                                erreur;
  574: 
  575:     if ((l_element_a_supprimer = recherche_variable_partagee(s_etat_processus,
  576:             nom_variable, position, ((*s_etat_processus)
  577:             .mode_execution_programme == 'Y') ? 'P' : 'E')) != NULL)
  578:     {
  579:         if (pthread_mutex_lock(&mutex_liste_variables_partagees) != 0)
  580:         {
  581:             (*s_etat_processus).erreur_systeme = d_es_processus;
  582:             return(d_erreur);
  583:         }
  584: 
  585:         // (*s_etat_processus).pointeur_variable_partagee_courante
  586:         // pointe sur la variable à éliminer. Cette variable est celle qui
  587:         // est présente dans l'une des feuilles statiques de l'arbre des
  588:         // variables.
  589: 
  590:         l_element_liste_a_supprimer = (*l_element_a_supprimer).reference;
  591: 
  592:         // Suppression de la liste des variables statiques
  593: 
  594:         if ((*l_element_liste_a_supprimer).precedent != NULL)
  595:         {
  596:             // L'élément à supprimer n'est pas le premier de la liste.
  597: 
  598:             (*(*l_element_liste_a_supprimer).precedent).suivant =
  599:                     (*l_element_liste_a_supprimer).suivant;
  600: 
  601:             if ((*l_element_liste_a_supprimer).suivant != NULL)
  602:             {
  603:                 // Il y a un élément suivant. On le chaîne.
  604:                 (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
  605:             }
  606:         }
  607:         else
  608:         {
  609:             // L'élement est le premier de la liste. S'il y a un élément
  610:             // suivant, on le chaîne.
  611: 
  612:             if ((*l_element_liste_a_supprimer).suivant != NULL)
  613:             {
  614:                 (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
  615:             }
  616: 
  617:             (*(*s_etat_processus).l_liste_variables_partagees) =
  618:                     (*l_element_liste_a_supprimer).suivant;
  619:         }
  620: 
  621:         free(l_element_liste_a_supprimer);
  622: 
  623:         // Suppression depuis la feuille statique. Le champ 'precedent' ne sert
  624:         // pas car la liste est simplement chaînée.
  625: 
  626:         if ((*l_element_a_supprimer).precedent != NULL)
  627:         {
  628:             // L'élément n'est pas le premier de la liste.
  629: 
  630:             (*(*l_element_a_supprimer).precedent).suivant =
  631:                     (*l_element_a_supprimer).suivant;
  632: 
  633:             if ((*l_element_a_supprimer).suivant != NULL)
  634:             {
  635:                 (*(*l_element_a_supprimer).suivant).precedent =
  636:                         (*l_element_a_supprimer).precedent;
  637:             }
  638:             else
  639:             {
  640:                 (*(*l_element_a_supprimer).precedent).suivant = NULL;
  641:             }
  642:         }
  643:         else
  644:         {
  645:             // L'élément est le premier de la liste.
  646: 
  647:             if ((*l_element_a_supprimer).suivant != NULL)
  648:             {
  649:                 (*(*l_element_a_supprimer).suivant).precedent = NULL;
  650:             }
  651: 
  652:             (*(*l_element_a_supprimer).feuille).feuille
  653:                     = (*l_element_a_supprimer).suivant;
  654:         }
  655: 
  656:         liberation(s_etat_processus, (*(*l_element_a_supprimer).variable)
  657:                 .objet);
  658:         free((*(*l_element_a_supprimer).variable).nom);
  659:         free((*l_element_a_supprimer).variable);
  660:         free(l_element_a_supprimer);
  661: 
  662:         if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  663:         {
  664:             (*s_etat_processus).erreur_systeme = d_es_processus;
  665:             return(d_erreur);
  666:         }
  667: 
  668:         erreur = d_absence_erreur;
  669:     }
  670:     else
  671:     {
  672:         erreur = d_erreur;
  673:         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  674:     }
  675: 
  676:     return(erreur);
  677: }
  678: 
  679: 
  680: /*
  681: ================================================================================
  682:   Routine de retrait des variables partagées
  683: ================================================================================
  684:   Entrée :
  685: --------------------------------------------------------------------------------
  686:   Sortie :
  687: --------------------------------------------------------------------------------
  688:   Effets de bords : néant
  689: ================================================================================
  690: */
  691: 
  692: // Cette routine libère toutes les variables partagées de niveau non
  693: // nul, donc attachées à une expression et non un programme.
  694: 
  695: logical1
  696: retrait_variables_partagees_locales(struct_processus *s_etat_processus)
  697: {
  698:     struct_liste_variables_partagees    *l_element_courant;
  699:     struct_liste_variables_partagees    *l_element_suivant;
  700: 
  701:     unsigned char                       registre_mode_execution;
  702: 
  703:     if (pthread_mutex_lock(&mutex_liste_variables_partagees) != 0)
  704:     {
  705:         (*s_etat_processus).erreur_systeme = d_es_processus;
  706:         return(d_erreur);
  707:     }
  708: 
  709:     registre_mode_execution = (*s_etat_processus).mode_execution_programme;
  710:     l_element_courant = (*(*s_etat_processus).l_liste_variables_partagees);
  711: 
  712:     while(l_element_courant != NULL)
  713:     {
  714:         l_element_suivant = (*l_element_courant).suivant;
  715: 
  716:         (*s_etat_processus).mode_execution_programme =
  717:                 ((*(*l_element_courant).variable).origine == 'P') ? 'Y' : 'N';
  718: 
  719:         if (((*(*l_element_courant).variable).niveau > 0) &&
  720:                 ((*l_element_courant).pid == getpid()) &&
  721:                 (pthread_equal((*l_element_courant).tid, pthread_self()) != 0))
  722:         {
  723:             if (retrait_variable_partagee(s_etat_processus,
  724:                     (*(*l_element_courant).variable).nom,
  725:                     (*(*l_element_courant).variable).variable_partagee)
  726:                     == d_erreur)
  727:             {
  728:                 if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  729:                 {
  730:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  731:                     return(d_erreur);
  732:                 }
  733: 
  734:                 (*s_etat_processus).mode_execution_programme =
  735:                         registre_mode_execution;
  736:                 return(d_erreur);
  737:             }
  738:         }
  739: 
  740:         l_element_courant = l_element_suivant;
  741:     }
  742: 
  743:     (*s_etat_processus).mode_execution_programme = registre_mode_execution;
  744: 
  745:     if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  746:     {
  747:         (*s_etat_processus).erreur_systeme = d_es_processus;
  748:         return(d_erreur);
  749:     }
  750: 
  751:     return(d_absence_erreur);
  752: }
  753: 
  754: 
  755: /*
  756: ================================================================================
  757:   Routine de libération de l'arbre des variables partagées
  758: ================================================================================
  759:   Entrée :
  760: --------------------------------------------------------------------------------
  761:   Sortie :
  762: --------------------------------------------------------------------------------
  763:   Effets de bords : positionne le mutex sur la variable partagée
  764: ================================================================================
  765: */
  766: 
  767: void
  768: liberation_arbre_variables_partagees(struct_processus *s_etat_processus,
  769:         struct_arbre_variables_partagees *arbre)
  770: {
  771:     int                                 i;
  772: 
  773:     struct_liste_variables_partagees    *l_element_partage_courant;
  774:     struct_liste_variables_partagees    *l_element_partage_suivant;
  775: 
  776:     // Libération de l'arbre des variables. Le contenu des variables n'est
  777:     // pas détruit par cette opération, il sera détruit lors de la libération
  778:     // de la liste des variables par niveau.
  779: 
  780:     if (arbre == NULL)
  781:     {
  782:         return;
  783:     }
  784: 
  785:     if (pthread_mutex_lock(&((*arbre).mutex_feuille)) != 0)
  786:     {
  787:         (*s_etat_processus).erreur_systeme = d_es_processus;
  788:         return;
  789:     }
  790: 
  791:     l_element_partage_courant = (*arbre).feuille;
  792: 
  793:     while(l_element_partage_courant != NULL)
  794:     {
  795:         l_element_partage_suivant = (*l_element_partage_courant).suivant;
  796: 
  797:         if (pthread_mutex_lock(&((*(*l_element_partage_courant).variable)
  798:                 .mutex)) != 0)
  799:         {
  800:             (*s_etat_processus).erreur_systeme = d_es_processus;
  801:             return;
  802:         }
  803: 
  804:         free((*(*l_element_partage_courant).variable).nom);
  805:         liberation(s_etat_processus, (*(*l_element_partage_courant)
  806:                 .variable).objet);
  807:         free((*l_element_partage_courant).variable);
  808: 
  809:         if (pthread_mutex_unlock(&((*(*l_element_partage_courant).variable)
  810:                 .mutex)) != 0)
  811:         {
  812:             (*s_etat_processus).erreur_systeme = d_es_processus;
  813:             return;
  814:         }
  815: 
  816:         if (pthread_mutex_destroy(&((*(*l_element_partage_courant).variable)
  817:                 .mutex)) != 0)
  818:         {
  819:             (*s_etat_processus).erreur_systeme = d_es_processus;
  820:             return;
  821:         }
  822: 
  823:         free(l_element_partage_courant);
  824: 
  825:         l_element_partage_courant = l_element_partage_suivant;
  826:     }
  827: 
  828:     for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
  829:     {
  830:         if ((*arbre).noeuds[i] != NULL)
  831:         {
  832:             liberation_arbre_variables_partagees(s_etat_processus,
  833:                     (*arbre).noeuds[i]);
  834:             (*arbre).noeuds[i] = NULL;
  835:         }
  836:     }
  837: 
  838:     liberation_tableau_noeuds_partages(s_etat_processus, (*arbre).noeuds);
  839:     liberation_noeud_partage(s_etat_processus, arbre);
  840: 
  841:     if (pthread_mutex_unlock(&((*arbre).mutex_feuille)) != 0)
  842:     {
  843:         (*s_etat_processus).erreur_systeme = d_es_processus;
  844:         return;
  845:     }
  846: 
  847:     if (pthread_mutex_destroy(&((*arbre).mutex_feuille)) != 0)
  848:     {
  849:         (*s_etat_processus).erreur_systeme = d_es_processus;
  850:         return;
  851:     }
  852: 
  853:     arbre = NULL;
  854:     return;
  855: }
  856: 
  857: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>