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

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

CVSweb interface <joel.bertrand@systella.fr>