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

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

CVSweb interface <joel.bertrand@systella.fr>