Annotation of rpl/src/gestion_variables_partagees.c, revision 1.39

1.1       bertrand    1: /*
                      2: ================================================================================
1.36      bertrand    3:   RPL/2 (R) version 4.1.11
1.30      bertrand    4:   Copyright (C) 1989-2012 Dr. BERTRAND Joël
1.1       bertrand    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: 
1.11      bertrand   23: #include "rpl-conv.h"
1.1       bertrand   24: 
                     25: 
                     26: /*
                     27: ================================================================================
1.39    ! bertrand   28:   Routine de gestion du cache des objets
1.1       bertrand   29: ================================================================================
                     30:   Entrée :
                     31: --------------------------------------------------------------------------------
                     32:   Sortie :
                     33: --------------------------------------------------------------------------------
                     34:   Effets de bords : néant
                     35: ================================================================================
                     36: */
                     37: 
1.39    ! bertrand   38: static inline struct_arbre_variables_partagees *
        !            39: allocation_noeud_partage(struct_processus *s_etat_processus)
1.38      bertrand   40: {
1.39    ! bertrand   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);
1.38      bertrand   54: }
                     55: 
1.39    ! bertrand   56: static inline void
        !            57: liberation_noeud_partage(struct_processus *s_etat_processus,
        !            58:        struct_arbre_variables_partagees *objet)
1.38      bertrand   59: {
1.39    ! bertrand   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;
1.38      bertrand   72: }
                     73: 
1.39    ! bertrand   74: static inline struct_arbre_variables_partagees **
        !            75: allocation_tableau_noeuds_partages(struct_processus *s_etat_processus)
1.38      bertrand   76: {
1.39    ! bertrand   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);
1.38      bertrand   92: }
                     93: 
1.39    ! bertrand   94: static inline void
        !            95: liberation_tableau_noeuds_partages(struct_processus *s_etat_processus,
        !            96:        struct_arbre_variables_partagees **objet)
1.38      bertrand   97: {
1.39    ! bertrand   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:    }
1.38      bertrand  109: 
                    110:    return;
                    111: }
                    112: 
1.39    ! bertrand  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: 
1.1       bertrand  126: logical1
                    127: creation_variable_partagee(struct_processus *s_etat_processus,
                    128:        struct_variable_partagee *s_variable)
                    129: {
1.39    ! bertrand  130:    int                                     i;
        !           131: 
        !           132:    struct_arbre_variables_partagees        *l_variable_courante;
1.1       bertrand  133: 
1.39    ! bertrand  134:    struct_liste_variables_partagees        *l_nouvel_element;
1.1       bertrand  135: 
1.39    ! bertrand  136:    unsigned char                           *ptr;
1.1       bertrand  137: 
1.39    ! bertrand  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)
1.1       bertrand  142:    {
1.39    ! bertrand  143:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           144:        return(d_erreur);
        !           145:    }
1.1       bertrand  146: 
1.39    ! bertrand  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)
1.1       bertrand  182:        {
1.39    ! bertrand  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);
1.1       bertrand  191:        }
1.39    ! bertrand  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)
1.1       bertrand  204:        {
1.39    ! bertrand  205:            if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
1.1       bertrand  206:            {
1.39    ! bertrand  207:                (*s_etat_processus).erreur_systeme = d_es_processus;
        !           208:                return(d_erreur);
1.1       bertrand  209:            }
                    210: 
                    211:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    212:            return(d_erreur);
                    213:        }
                    214: 
1.39    ! bertrand  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:        }
1.1       bertrand  220:    }
                    221: 
1.39    ! bertrand  222:    l_variable_courante = (*(*s_etat_processus).s_arbre_variables_partagees);
        !           223:    ptr = (*s_variable).nom;
1.1       bertrand  224: 
1.39    ! bertrand  225:    if (pthread_mutex_lock(&((*l_variable_courante).mutex_feuille)) != 0)
1.1       bertrand  226:    {
1.39    ! bertrand  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);
1.1       bertrand  235:    }
1.39    ! bertrand  236: 
        !           237:    while((*ptr) != d_code_fin_chaine)
1.1       bertrand  238:    {
1.39    ! bertrand  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)
1.1       bertrand  245:        {
1.39    ! bertrand  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)
1.1       bertrand  252:            {
1.39    ! bertrand  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);
1.1       bertrand  261:            }
1.39    ! bertrand  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)
1.1       bertrand  332:            {
1.39    ! bertrand  333:                (*s_etat_processus).erreur_systeme = d_es_processus;
        !           334:                return(d_erreur);
1.1       bertrand  335:            }
1.39    ! bertrand  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);
1.1       bertrand  353:        }
                    354: 
1.39    ! bertrand  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;
1.1       bertrand  370:    }
                    371: 
1.39    ! bertrand  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);
1.1       bertrand  398: }
                    399: 
                    400: 
                    401: /*
                    402: ================================================================================
1.39    ! bertrand  403:   Routine de recherche d'une variable partagée
1.1       bertrand  404: ================================================================================
                    405:   Entrée :
                    406: --------------------------------------------------------------------------------
                    407:   Sortie :
                    408: --------------------------------------------------------------------------------
1.39    ! bertrand  409:   Effets de bords : positionne le mutex sur la variable partagée
1.1       bertrand  410: ================================================================================
                    411: */
                    412: 
1.39    ! bertrand  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)
1.1       bertrand  417: {
1.39    ! bertrand  418:    int                                 pointeur;
        !           419: 
        !           420:    struct_arbre_variables_partagees    *l_variable_courante;
        !           421:    struct_liste_variables_partagees    *l_element_courant;
1.1       bertrand  422: 
1.39    ! bertrand  423:    unsigned char                       *ptr;
1.1       bertrand  424: 
1.39    ! bertrand  425:    l_variable_courante = (*(*s_etat_processus).s_arbre_variables_partagees);
        !           426:    ptr = nom_variable;
1.1       bertrand  427: 
1.39    ! bertrand  428:    if (l_variable_courante == NULL)
1.1       bertrand  429:    {
1.39    ! bertrand  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)
1.1       bertrand  445:        {
1.39    ! bertrand  446:            // Caractère hors de l'alphabet des variables
1.1       bertrand  447: 
1.39    ! bertrand  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:        }
1.1       bertrand  465: 
1.39    ! bertrand  466:        if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
        !           467:        {
        !           468:            (*s_etat_processus).erreur_systeme = d_es_processus;
        !           469:            return(NULL);
1.1       bertrand  470:        }
                    471: 
1.39    ! bertrand  472:        l_variable_courante = (*l_variable_courante).noeuds[pointeur];
        !           473:        ptr++;
        !           474:    }
1.1       bertrand  475: 
1.39    ! bertrand  476:    if ((*l_variable_courante).feuille != NULL)
        !           477:    {
        !           478:        // Il existe au moins une variable statique du nom requis.
1.1       bertrand  479: 
1.39    ! bertrand  480:        l_element_courant = (*l_variable_courante).feuille;
1.1       bertrand  481: 
1.39    ! bertrand  482:        while(l_element_courant != NULL)
1.1       bertrand  483:        {
1.39    ! bertrand  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;
1.1       bertrand  536:        }
1.39    ! bertrand  537:    }
1.1       bertrand  538: 
1.39    ! bertrand  539:    if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
1.1       bertrand  540:    {
1.39    ! bertrand  541:        (*s_etat_processus).erreur_systeme = d_es_processus;
        !           542:        return(NULL);
1.1       bertrand  543:    }
                    544: 
1.39    ! bertrand  545:    (*s_etat_processus).pointeur_variable_statique_courante = NULL;
        !           546:    return(NULL);
1.1       bertrand  547: }
                    548: 
                    549: 
                    550: /*
                    551: ================================================================================
1.39    ! bertrand  552:   Routine de retrait d'une variable partagée
1.1       bertrand  553: ================================================================================
                    554:   Entrée :
                    555: --------------------------------------------------------------------------------
                    556:   Sortie :
                    557: --------------------------------------------------------------------------------
1.39    ! bertrand  558:   Effets de bords : néant
1.1       bertrand  559: ================================================================================
                    560: */
                    561: 
                    562: logical1
1.39    ! bertrand  563: retrait_variable_partagee(struct_processus *s_etat_processus,
        !           564:        unsigned char *nom_variable, union_position_variable position)
1.1       bertrand  565: {
1.39    ! bertrand  566:    struct_liste_variables_partagees        *l_element_a_supprimer;
        !           567:    struct_liste_variables_partagees        *l_element_liste_a_supprimer;
1.1       bertrand  568: 
1.39    ! bertrand  569:    logical1                                erreur;
1.1       bertrand  570: 
1.39    ! bertrand  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)
1.1       bertrand  574:    {
1.39    ! bertrand  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:        }
1.1       bertrand  580: 
1.39    ! bertrand  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.
1.1       bertrand  585: 
1.39    ! bertrand  586:        l_element_liste_a_supprimer = (*l_element_a_supprimer).reference;
1.1       bertrand  587: 
1.39    ! bertrand  588:        // Suppression de la liste des variables statiques
1.1       bertrand  589: 
1.39    ! bertrand  590:        if ((*l_element_liste_a_supprimer).precedent != NULL)
1.1       bertrand  591:        {
1.39    ! bertrand  592:            // L'élément à supprimer n'est pas le premier de la liste.
1.1       bertrand  593: 
1.39    ! bertrand  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)
1.1       bertrand  598:            {
1.39    ! bertrand  599:                // Il y a un élément suivant. On le chaîne.
        !           600:                (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
1.1       bertrand  601:            }
                    602:        }
                    603:        else
                    604:        {
1.39    ! bertrand  605:            // L'élement est le premier de la liste. S'il y a un élément
        !           606:            // suivant, on le chaîne.
1.1       bertrand  607: 
1.39    ! bertrand  608:            if ((*l_element_liste_a_supprimer).suivant != NULL)
1.1       bertrand  609:            {
1.39    ! bertrand  610:                (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
1.1       bertrand  611:            }
                    612: 
1.39    ! bertrand  613:            (*(*s_etat_processus).l_liste_variables_partagees) =
        !           614:                    (*l_element_liste_a_supprimer).suivant;
1.1       bertrand  615:        }
                    616: 
1.39    ! bertrand  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.
1.1       bertrand  621: 
1.39    ! bertrand  622:        if ((*l_element_a_supprimer).precedent != NULL)
1.1       bertrand  623:        {
1.39    ! bertrand  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)
1.1       bertrand  630:            {
1.39    ! bertrand  631:                (*(*l_element_a_supprimer).suivant).precedent =
        !           632:                        (*l_element_a_supprimer).precedent;
1.1       bertrand  633:            }
                    634:            else
                    635:            {
1.39    ! bertrand  636:                (*(*l_element_a_supprimer).precedent).suivant = NULL;
1.1       bertrand  637:            }
                    638:        }
                    639:        else
                    640:        {
1.39    ! bertrand  641:            // L'élément est le premier de la liste.
        !           642: 
        !           643:            if ((*l_element_a_supprimer).suivant != NULL)
1.1       bertrand  644:            {
1.39    ! bertrand  645:                (*(*l_element_a_supprimer).suivant).precedent = NULL;
1.1       bertrand  646:            }
1.39    ! bertrand  647: 
        !           648:            (*(*l_element_a_supprimer).feuille).feuille
        !           649:                    = (*l_element_a_supprimer).suivant;
1.1       bertrand  650:        }
                    651: 
1.39    ! bertrand  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)
1.1       bertrand  659:        {
1.39    ! bertrand  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.
1.1       bertrand  690: 
1.39    ! bertrand  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:    }
1.1       bertrand  704: 
1.39    ! bertrand  705:    registre_mode_execution = (*s_etat_processus).mode_execution_programme;
        !           706:    l_element_courant = (*(*s_etat_processus).l_liste_variables_partagees);
1.1       bertrand  707: 
1.39    ! bertrand  708:    while(l_element_courant != NULL)
        !           709:    {
        !           710:        l_element_suivant = (*l_element_courant).suivant;
1.1       bertrand  711: 
1.39    ! bertrand  712:        (*s_etat_processus).mode_execution_programme =
        !           713:                ((*(*l_element_courant).variable).origine == 'P') ? 'Y' : 'N';
1.1       bertrand  714: 
1.39    ! bertrand  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)
1.1       bertrand  723:            {
1.39    ! bertrand  724:                if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
1.1       bertrand  725:                {
1.39    ! bertrand  726:                    (*s_etat_processus).erreur_systeme = d_es_processus;
        !           727:                    return(d_erreur);
1.1       bertrand  728:                }
1.39    ! bertrand  729: 
        !           730:                (*s_etat_processus).mode_execution_programme =
        !           731:                        registre_mode_execution;
        !           732:                return(d_erreur);
1.1       bertrand  733:            }
1.39    ! bertrand  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;
1.1       bertrand  768: 
1.39    ! bertrand  769:    struct_liste_variables_partagees    *l_element_partage_courant;
        !           770:    struct_liste_variables_partagees    *l_element_partage_suivant;
1.1       bertrand  771: 
1.39    ! bertrand  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);
1.1       bertrand  804: 
1.39    ! bertrand  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:        }
1.1       bertrand  811: 
1.39    ! bertrand  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;
1.1       bertrand  817:        }
                    818: 
1.39    ! bertrand  819:        free(l_element_partage_courant);
        !           820: 
        !           821:        l_element_partage_courant = l_element_partage_suivant;
1.1       bertrand  822:    }
                    823: 
1.39    ! bertrand  824:    for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1.1       bertrand  825:    {
1.39    ! bertrand  826:        if ((*arbre).noeuds[i] != NULL)
1.1       bertrand  827:        {
1.39    ! bertrand  828:            liberation_arbre_variables_partagees(s_etat_processus,
        !           829:                    (*arbre).noeuds[i]);
        !           830:            (*arbre).noeuds[i] = NULL;
1.1       bertrand  831:        }
                    832:    }
                    833: 
1.39    ! bertrand  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;
1.1       bertrand  851: }
1.39    ! bertrand  852: 
1.1       bertrand  853: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>