File:  [local] / rpl / src / gestion_variables_partagees.c
Revision 1.41: download - view: text, annotated - select for diffs - revision graph
Tue Dec 18 13:19:35 2012 UTC (11 years, 5 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
En route pour la 4.1.12 !

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.12
    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:             INITIALISATION_MUTEX((*(*l_variable_courante).noeuds
  289:                     [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]])
  290:                     .mutex_feuille);
  291: 
  292:             // Allocation du tableau noeuds[] et initialisation à zéro de
  293:             // tous les pointeurs.
  294: 
  295:             if (((*(*l_variable_courante).noeuds[(*s_etat_processus)
  296:                     .pointeurs_caracteres_variables[*ptr]]).noeuds =
  297:                     allocation_tableau_noeuds_partages(s_etat_processus))
  298:                     == NULL)
  299:             {
  300:                 if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  301:                 {
  302:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  303:                     return(d_erreur);
  304:                 }
  305: 
  306:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  307:                 return(d_erreur);
  308:             }
  309: 
  310:             for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
  311:             {
  312:                 (*(*l_variable_courante).noeuds[(*s_etat_processus)
  313:                         .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
  314:                         = NULL;
  315:             }
  316:         }
  317: 
  318:         if (pthread_mutex_lock(&((*(*l_variable_courante).noeuds
  319:                 [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]])
  320:                 .mutex_feuille)) != 0)
  321:         {
  322:             if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  323:             {
  324:                 (*s_etat_processus).erreur_systeme = d_es_processus;
  325:                 return(d_erreur);
  326:             }
  327: 
  328:             (*s_etat_processus).erreur_systeme = d_es_processus;
  329:             return(d_erreur);
  330:         }
  331: 
  332:         if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
  333:         {
  334:             if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  335:             {
  336:                 (*s_etat_processus).erreur_systeme = d_es_processus;
  337:                 return(d_erreur);
  338:             }
  339: 
  340:             (*s_etat_processus).erreur_systeme = d_es_processus;
  341:             return(d_erreur);
  342:         }
  343: 
  344:         l_variable_courante = (*l_variable_courante).noeuds
  345:                 [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
  346:         ptr++;
  347:     }
  348: 
  349:     if ((l_nouvel_element = malloc(sizeof(struct_liste_variables_partagees)))
  350:             == NULL)
  351:     {
  352:         if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  353:         {
  354:             (*s_etat_processus).erreur_systeme = d_es_processus;
  355:             return(d_erreur);
  356:         }
  357: 
  358:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  359:         return(d_erreur);
  360:     }
  361: 
  362:     // Dans la feuille de l'arbre des variables partagées, on ne balaie
  363:     // les variables que dans l'ordre. Le champ 'reference' est alors utilisé
  364:     // pour sauvegarder une référence vers la liste des variables partagées
  365:     // pour pouvoir purger l'élément en cas de besoin.
  366: 
  367:     (*l_nouvel_element).suivant = (*l_variable_courante).feuille;
  368:     (*l_nouvel_element).precedent = NULL;
  369: 
  370:     if ((*l_nouvel_element).suivant != NULL)
  371:     {
  372:         (*(*l_nouvel_element).suivant).precedent = l_nouvel_element;
  373:     }
  374: 
  375:     (*l_nouvel_element).reference =
  376:             (*(*s_etat_processus).l_liste_variables_partagees);
  377:     (*l_nouvel_element).variable = (**(*s_etat_processus)
  378:             .l_liste_variables_partagees).variable;
  379:     (*l_variable_courante).feuille = l_nouvel_element;
  380:     (*l_nouvel_element).feuille = l_variable_courante;
  381: 
  382:     if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
  383:     {
  384:         if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  385:         {
  386:             (*s_etat_processus).erreur_systeme = d_es_processus;
  387:             return(d_erreur);
  388:         }
  389: 
  390:         (*s_etat_processus).erreur_systeme = d_es_processus;
  391:         return(d_erreur);
  392:     }
  393: 
  394:     if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  395:     {
  396:         (*s_etat_processus).erreur_systeme = d_es_processus;
  397:         return(d_erreur);
  398:     }
  399: 
  400:     return(d_absence_erreur);
  401: }
  402: 
  403: 
  404: /*
  405: ================================================================================
  406:   Routine de recherche d'une variable partagée
  407: ================================================================================
  408:   Entrée :
  409: --------------------------------------------------------------------------------
  410:   Sortie :
  411: --------------------------------------------------------------------------------
  412:   Effets de bords : positionne le mutex sur la variable partagée
  413: ================================================================================
  414: */
  415: 
  416: struct_liste_variables_partagees *
  417: recherche_variable_partagee(struct_processus *s_etat_processus,
  418:         unsigned char *nom_variable, union_position_variable position,
  419:         unsigned char origine)
  420: {
  421:     int                                 pointeur;
  422: 
  423:     struct_arbre_variables_partagees    *l_variable_courante;
  424:     struct_liste_variables_partagees    *l_element_courant;
  425: 
  426:     unsigned char                       *ptr;
  427: 
  428:     l_variable_courante = (*(*s_etat_processus).s_arbre_variables_partagees);
  429:     ptr = nom_variable;
  430: 
  431:     if (l_variable_courante == NULL)
  432:     {
  433:         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  434:         return(NULL);
  435:     }
  436: 
  437:     if (pthread_mutex_lock(&((*l_variable_courante).mutex_feuille)) != 0)
  438:     {
  439:         (*s_etat_processus).erreur_systeme = d_es_processus;
  440:         return(NULL);
  441:     }
  442: 
  443:     while((*ptr) != d_code_fin_chaine)
  444:     {
  445:         pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
  446: 
  447:         if (pointeur < 0)
  448:         {
  449:             // Caractère hors de l'alphabet des variables
  450: 
  451:             (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  452:             return(NULL);
  453:         }
  454: 
  455:         if ((*l_variable_courante).noeuds[pointeur] == NULL)
  456:         {
  457:             // Le chemin de la variable candidate n'existe pas.
  458:             (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  459:             return(NULL);
  460:         }
  461: 
  462:         if (pthread_mutex_lock(&((*(*l_variable_courante).noeuds[pointeur])
  463:                 .mutex_feuille)) != 0)
  464:         {
  465:             (*s_etat_processus).erreur_systeme = d_es_processus;
  466:             return(NULL);
  467:         }
  468: 
  469:         if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
  470:         {
  471:             (*s_etat_processus).erreur_systeme = d_es_processus;
  472:             return(NULL);
  473:         }
  474: 
  475:         l_variable_courante = (*l_variable_courante).noeuds[pointeur];
  476:         ptr++;
  477:     }
  478: 
  479:     if ((*l_variable_courante).feuille != NULL)
  480:     {
  481:         // Il existe au moins une variable statique du nom requis.
  482: 
  483:         l_element_courant = (*l_variable_courante).feuille;
  484: 
  485:         while(l_element_courant != NULL)
  486:         {
  487:             if ((*(*l_element_courant).variable).origine == 'P')
  488:             {
  489:                 if (((*(*l_element_courant).variable).variable_partagee.adresse
  490:                         == position.adresse) &&
  491:                         ((*(*l_element_courant).variable).origine == origine))
  492:                 {
  493:                     if (pthread_mutex_lock(&((*(*l_element_courant).variable)
  494:                             .mutex)) != 0)
  495:                     {
  496:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  497:                         return(NULL);
  498:                     }
  499: 
  500:                     if (pthread_mutex_unlock(&((*l_variable_courante)
  501:                             .mutex_feuille)) != 0)
  502:                     {
  503:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  504:                         return(NULL);
  505:                     }
  506: 
  507:                     (*s_etat_processus).pointeur_variable_partagee_courante
  508:                             = (*l_element_courant).variable;
  509:                     return(l_element_courant);
  510:                 }
  511:             }
  512:             else
  513:             {
  514:                 if (((*(*l_element_courant).variable).variable_partagee.pointeur
  515:                         == position.pointeur) &&
  516:                         ((*(*l_element_courant).variable).origine == origine))
  517:                 {
  518:                     if (pthread_mutex_lock(&((*(*l_element_courant).variable)
  519:                             .mutex)) != 0)
  520:                     {
  521:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  522:                         return(NULL);
  523:                     }
  524: 
  525:                     if (pthread_mutex_unlock(&((*l_variable_courante)
  526:                             .mutex_feuille)) != 0)
  527:                     {
  528:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  529:                         return(NULL);
  530:                     }
  531: 
  532:                     (*s_etat_processus).pointeur_variable_partagee_courante
  533:                             = (*l_element_courant).variable;
  534:                     return(l_element_courant);
  535:                 }
  536:             }
  537: 
  538:             l_element_courant = (*l_element_courant).suivant;
  539:         }
  540:     }
  541: 
  542:     if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
  543:     {
  544:         (*s_etat_processus).erreur_systeme = d_es_processus;
  545:         return(NULL);
  546:     }
  547: 
  548:     (*s_etat_processus).pointeur_variable_statique_courante = NULL;
  549:     return(NULL);
  550: }
  551: 
  552: 
  553: /*
  554: ================================================================================
  555:   Routine de retrait d'une variable partagée
  556: ================================================================================
  557:   Entrée :
  558: --------------------------------------------------------------------------------
  559:   Sortie :
  560: --------------------------------------------------------------------------------
  561:   Effets de bords : néant
  562: ================================================================================
  563: */
  564: 
  565: logical1
  566: retrait_variable_partagee(struct_processus *s_etat_processus,
  567:         unsigned char *nom_variable, union_position_variable position)
  568: {
  569:     struct_liste_variables_partagees        *l_element_a_supprimer;
  570:     struct_liste_variables_partagees        *l_element_liste_a_supprimer;
  571: 
  572:     logical1                                erreur;
  573: 
  574:     if ((l_element_a_supprimer = recherche_variable_partagee(s_etat_processus,
  575:             nom_variable, position, ((*s_etat_processus)
  576:             .mode_execution_programme == 'Y') ? 'P' : 'E')) != NULL)
  577:     {
  578:         if (pthread_mutex_lock(&mutex_liste_variables_partagees) != 0)
  579:         {
  580:             (*s_etat_processus).erreur_systeme = d_es_processus;
  581:             return(d_erreur);
  582:         }
  583: 
  584:         // (*s_etat_processus).pointeur_variable_partagee_courante
  585:         // pointe sur la variable à éliminer. Cette variable est celle qui
  586:         // est présente dans l'une des feuilles statiques de l'arbre des
  587:         // variables.
  588: 
  589:         l_element_liste_a_supprimer = (*l_element_a_supprimer).reference;
  590: 
  591:         // Suppression de la liste des variables statiques
  592: 
  593:         if ((*l_element_liste_a_supprimer).precedent != NULL)
  594:         {
  595:             // L'élément à supprimer n'est pas le premier de la liste.
  596: 
  597:             (*(*l_element_liste_a_supprimer).precedent).suivant =
  598:                     (*l_element_liste_a_supprimer).suivant;
  599: 
  600:             if ((*l_element_liste_a_supprimer).suivant != NULL)
  601:             {
  602:                 // Il y a un élément suivant. On le chaîne.
  603:                 (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
  604:             }
  605:         }
  606:         else
  607:         {
  608:             // L'élement est le premier de la liste. S'il y a un élément
  609:             // suivant, on le chaîne.
  610: 
  611:             if ((*l_element_liste_a_supprimer).suivant != NULL)
  612:             {
  613:                 (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
  614:             }
  615: 
  616:             (*(*s_etat_processus).l_liste_variables_partagees) =
  617:                     (*l_element_liste_a_supprimer).suivant;
  618:         }
  619: 
  620:         free(l_element_liste_a_supprimer);
  621: 
  622:         // Suppression depuis la feuille statique. Le champ 'precedent' ne sert
  623:         // pas car la liste est simplement chaînée.
  624: 
  625:         if ((*l_element_a_supprimer).precedent != NULL)
  626:         {
  627:             // L'élément n'est pas le premier de la liste.
  628: 
  629:             (*(*l_element_a_supprimer).precedent).suivant =
  630:                     (*l_element_a_supprimer).suivant;
  631: 
  632:             if ((*l_element_a_supprimer).suivant != NULL)
  633:             {
  634:                 (*(*l_element_a_supprimer).suivant).precedent =
  635:                         (*l_element_a_supprimer).precedent;
  636:             }
  637:             else
  638:             {
  639:                 (*(*l_element_a_supprimer).precedent).suivant = NULL;
  640:             }
  641:         }
  642:         else
  643:         {
  644:             // L'élément est le premier de la liste.
  645: 
  646:             if ((*l_element_a_supprimer).suivant != NULL)
  647:             {
  648:                 (*(*l_element_a_supprimer).suivant).precedent = NULL;
  649:             }
  650: 
  651:             (*(*l_element_a_supprimer).feuille).feuille
  652:                     = (*l_element_a_supprimer).suivant;
  653:         }
  654: 
  655:         liberation(s_etat_processus, (*(*l_element_a_supprimer).variable)
  656:                 .objet);
  657:         free((*(*l_element_a_supprimer).variable).nom);
  658:         free((*l_element_a_supprimer).variable);
  659:         free(l_element_a_supprimer);
  660: 
  661:         if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  662:         {
  663:             (*s_etat_processus).erreur_systeme = d_es_processus;
  664:             return(d_erreur);
  665:         }
  666: 
  667:         erreur = d_absence_erreur;
  668:     }
  669:     else
  670:     {
  671:         erreur = d_erreur;
  672:         (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
  673:     }
  674: 
  675:     return(erreur);
  676: }
  677: 
  678: 
  679: /*
  680: ================================================================================
  681:   Routine de retrait des variables partagées
  682: ================================================================================
  683:   Entrée :
  684: --------------------------------------------------------------------------------
  685:   Sortie :
  686: --------------------------------------------------------------------------------
  687:   Effets de bords : néant
  688: ================================================================================
  689: */
  690: 
  691: // Cette routine libère toutes les variables partagées de niveau non
  692: // nul, donc attachées à une expression et non un programme.
  693: 
  694: logical1
  695: retrait_variables_partagees_locales(struct_processus *s_etat_processus)
  696: {
  697:     struct_liste_variables_partagees    *l_element_courant;
  698:     struct_liste_variables_partagees    *l_element_suivant;
  699: 
  700:     unsigned char                       registre_mode_execution;
  701: 
  702:     if (pthread_mutex_lock(&mutex_liste_variables_partagees) != 0)
  703:     {
  704:         (*s_etat_processus).erreur_systeme = d_es_processus;
  705:         return(d_erreur);
  706:     }
  707: 
  708:     registre_mode_execution = (*s_etat_processus).mode_execution_programme;
  709:     l_element_courant = (*(*s_etat_processus).l_liste_variables_partagees);
  710: 
  711:     while(l_element_courant != NULL)
  712:     {
  713:         l_element_suivant = (*l_element_courant).suivant;
  714: 
  715:         (*s_etat_processus).mode_execution_programme =
  716:                 ((*(*l_element_courant).variable).origine == 'P') ? 'Y' : 'N';
  717: 
  718:         if (((*(*l_element_courant).variable).niveau > 0) &&
  719:                 ((*l_element_courant).pid == getpid()) &&
  720:                 (pthread_equal((*l_element_courant).tid, pthread_self()) != 0))
  721:         {
  722:             if (retrait_variable_partagee(s_etat_processus,
  723:                     (*(*l_element_courant).variable).nom,
  724:                     (*(*l_element_courant).variable).variable_partagee)
  725:                     == d_erreur)
  726:             {
  727:                 if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  728:                 {
  729:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  730:                     return(d_erreur);
  731:                 }
  732: 
  733:                 (*s_etat_processus).mode_execution_programme =
  734:                         registre_mode_execution;
  735:                 return(d_erreur);
  736:             }
  737:         }
  738: 
  739:         l_element_courant = l_element_suivant;
  740:     }
  741: 
  742:     (*s_etat_processus).mode_execution_programme = registre_mode_execution;
  743: 
  744:     if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
  745:     {
  746:         (*s_etat_processus).erreur_systeme = d_es_processus;
  747:         return(d_erreur);
  748:     }
  749: 
  750:     return(d_absence_erreur);
  751: }
  752: 
  753: 
  754: /*
  755: ================================================================================
  756:   Routine de libération de l'arbre des variables partagées
  757: ================================================================================
  758:   Entrée :
  759: --------------------------------------------------------------------------------
  760:   Sortie :
  761: --------------------------------------------------------------------------------
  762:   Effets de bords : positionne le mutex sur la variable partagée
  763: ================================================================================
  764: */
  765: 
  766: void
  767: liberation_arbre_variables_partagees(struct_processus *s_etat_processus,
  768:         struct_arbre_variables_partagees *arbre)
  769: {
  770:     int                                 i;
  771: 
  772:     struct_liste_variables_partagees    *l_element_partage_courant;
  773:     struct_liste_variables_partagees    *l_element_partage_suivant;
  774: 
  775:     // Libération de l'arbre des variables. Le contenu des variables n'est
  776:     // pas détruit par cette opération, il sera détruit lors de la libération
  777:     // de la liste des variables par niveau.
  778: 
  779:     if (arbre == NULL)
  780:     {
  781:         return;
  782:     }
  783: 
  784:     if (pthread_mutex_lock(&((*arbre).mutex_feuille)) != 0)
  785:     {
  786:         (*s_etat_processus).erreur_systeme = d_es_processus;
  787:         return;
  788:     }
  789: 
  790:     l_element_partage_courant = (*arbre).feuille;
  791: 
  792:     while(l_element_partage_courant != NULL)
  793:     {
  794:         l_element_partage_suivant = (*l_element_partage_courant).suivant;
  795: 
  796:         if (pthread_mutex_lock(&((*(*l_element_partage_courant).variable)
  797:                 .mutex)) != 0)
  798:         {
  799:             (*s_etat_processus).erreur_systeme = d_es_processus;
  800:             return;
  801:         }
  802: 
  803:         free((*(*l_element_partage_courant).variable).nom);
  804:         liberation(s_etat_processus, (*(*l_element_partage_courant)
  805:                 .variable).objet);
  806:         free((*l_element_partage_courant).variable);
  807: 
  808:         if (pthread_mutex_unlock(&((*(*l_element_partage_courant).variable)
  809:                 .mutex)) != 0)
  810:         {
  811:             (*s_etat_processus).erreur_systeme = d_es_processus;
  812:             return;
  813:         }
  814: 
  815:         if (pthread_mutex_destroy(&((*(*l_element_partage_courant).variable)
  816:                 .mutex)) != 0)
  817:         {
  818:             (*s_etat_processus).erreur_systeme = d_es_processus;
  819:             return;
  820:         }
  821: 
  822:         free(l_element_partage_courant);
  823: 
  824:         l_element_partage_courant = l_element_partage_suivant;
  825:     }
  826: 
  827:     for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
  828:     {
  829:         if ((*arbre).noeuds[i] != NULL)
  830:         {
  831:             liberation_arbre_variables_partagees(s_etat_processus,
  832:                     (*arbre).noeuds[i]);
  833:             (*arbre).noeuds[i] = NULL;
  834:         }
  835:     }
  836: 
  837:     liberation_tableau_noeuds_partages(s_etat_processus, (*arbre).noeuds);
  838:     liberation_noeud_partage(s_etat_processus, arbre);
  839: 
  840:     if (pthread_mutex_unlock(&((*arbre).mutex_feuille)) != 0)
  841:     {
  842:         (*s_etat_processus).erreur_systeme = d_es_processus;
  843:         return;
  844:     }
  845: 
  846:     if (pthread_mutex_destroy(&((*arbre).mutex_feuille)) != 0)
  847:     {
  848:         (*s_etat_processus).erreur_systeme = d_es_processus;
  849:         return;
  850:     }
  851: 
  852:     arbre = NULL;
  853:     return;
  854: }
  855: 
  856: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>