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

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

CVSweb interface <joel.bertrand@systella.fr>