Annotation of rpl/src/gestion_variables_partagees.c, revision 1.39
1.1 bertrand 1: /*
2: ================================================================================
1.36 bertrand 3: RPL/2 (R) version 4.1.11
1.30 bertrand 4: Copyright (C) 1989-2012 Dr. BERTRAND Joël
1.1 bertrand 5:
6: This file is part of RPL/2.
7:
8: RPL/2 is free software; you can redistribute it and/or modify it
9: under the terms of the CeCILL V2 License as published by the french
10: CEA, CNRS and INRIA.
11:
12: RPL/2 is distributed in the hope that it will be useful, but WITHOUT
13: ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14: FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License
15: for more details.
16:
17: You should have received a copy of the CeCILL License
18: along with RPL/2. If not, write to info@cecill.info.
19: ================================================================================
20: */
21:
22:
1.11 bertrand 23: #include "rpl-conv.h"
1.1 bertrand 24:
25:
26: /*
27: ================================================================================
1.39 ! bertrand 28: Routine de gestion du cache des objets
1.1 bertrand 29: ================================================================================
30: Entrée :
31: --------------------------------------------------------------------------------
32: Sortie :
33: --------------------------------------------------------------------------------
34: Effets de bords : néant
35: ================================================================================
36: */
37:
1.39 ! bertrand 38: static inline struct_arbre_variables_partagees *
! 39: allocation_noeud_partage(struct_processus *s_etat_processus)
1.38 bertrand 40: {
1.39 ! bertrand 41: struct_arbre_variables_partagees *objet;
! 42:
! 43: if ((*s_etat_processus).pointeur_variables_partagees_noeud > 0)
! 44: {
! 45: objet = (*s_etat_processus).variables_partagees_noeud
! 46: [--(*s_etat_processus).pointeur_variables_partagees_noeud];
! 47: }
! 48: else
! 49: {
! 50: objet = malloc(sizeof(struct_arbre_variables_partagees));
! 51: }
! 52:
! 53: return(objet);
1.38 bertrand 54: }
55:
1.39 ! bertrand 56: static inline void
! 57: liberation_noeud_partage(struct_processus *s_etat_processus,
! 58: struct_arbre_variables_partagees *objet)
1.38 bertrand 59: {
1.39 ! bertrand 60: if ((*s_etat_processus).pointeur_variables_partagees_noeud < TAILLE_CACHE)
! 61: {
! 62: (*s_etat_processus).variables_partagees_noeud
! 63: [(*s_etat_processus).pointeur_variables_partagees_noeud++] =
! 64: objet;
! 65: }
! 66: else
! 67: {
! 68: free(objet);
! 69: }
! 70:
! 71: return;
1.38 bertrand 72: }
73:
1.39 ! bertrand 74: static inline struct_arbre_variables_partagees **
! 75: allocation_tableau_noeuds_partages(struct_processus *s_etat_processus)
1.38 bertrand 76: {
1.39 ! bertrand 77: struct_arbre_variables_partagees **objet;
! 78:
! 79: if ((*s_etat_processus).pointeur_variables_tableau_noeuds_partages > 0)
! 80: {
! 81: objet = (*s_etat_processus).variables_tableau_noeuds_partages
! 82: [--(*s_etat_processus)
! 83: .pointeur_variables_tableau_noeuds_partages];
! 84: }
! 85: else
! 86: {
! 87: objet = malloc((*s_etat_processus).nombre_caracteres_variables
! 88: * sizeof(struct_arbre_variables_partagees *));
! 89: }
! 90:
! 91: return(objet);
1.38 bertrand 92: }
93:
1.39 ! bertrand 94: static inline void
! 95: liberation_tableau_noeuds_partages(struct_processus *s_etat_processus,
! 96: struct_arbre_variables_partagees **objet)
1.38 bertrand 97: {
1.39 ! bertrand 98: if ((*s_etat_processus).pointeur_variables_tableau_noeuds_partages
! 99: < TAILLE_CACHE)
! 100: {
! 101: (*s_etat_processus).variables_tableau_noeuds_partages
! 102: [(*s_etat_processus)
! 103: .pointeur_variables_tableau_noeuds_partages++] = objet;
! 104: }
! 105: else
! 106: {
! 107: free(objet);
! 108: }
1.38 bertrand 109:
110: return;
111: }
112:
1.39 ! bertrand 113:
! 114: /*
! 115: ================================================================================
! 116: Routine de création d'une nouvelle variable partagee
! 117: ================================================================================
! 118: Entrée :
! 119: --------------------------------------------------------------------------------
! 120: Sortie :
! 121: --------------------------------------------------------------------------------
! 122: Effets de bords : néant
! 123: ================================================================================
! 124: */
! 125:
1.1 bertrand 126: logical1
127: creation_variable_partagee(struct_processus *s_etat_processus,
128: struct_variable_partagee *s_variable)
129: {
1.39 ! bertrand 130: int i;
! 131:
! 132: struct_arbre_variables_partagees *l_variable_courante;
1.1 bertrand 133:
1.39 ! bertrand 134: struct_liste_variables_partagees *l_nouvel_element;
1.1 bertrand 135:
1.39 ! bertrand 136: unsigned char *ptr;
1.1 bertrand 137:
1.39 ! bertrand 138: // Ajout de la variable en tête de la liste des variables partagées
! 139:
! 140: if ((l_nouvel_element = malloc(sizeof(struct_liste_variables_partagees)))
! 141: == NULL)
1.1 bertrand 142: {
1.39 ! bertrand 143: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 144: return(d_erreur);
! 145: }
1.1 bertrand 146:
1.39 ! bertrand 147: if (((*l_nouvel_element).variable = malloc(sizeof(
! 148: struct_variable_partagee))) == NULL)
! 149: {
! 150: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 151: return(d_erreur);
! 152: }
! 153:
! 154: (*(*l_nouvel_element).variable) = (*s_variable);
! 155: (*l_nouvel_element).pid = getpid();
! 156: (*l_nouvel_element).tid = pthread_self();
! 157:
! 158: if (pthread_mutex_lock(&mutex_liste_variables_partagees) != 0)
! 159: {
! 160: (*s_etat_processus).erreur_systeme = d_es_processus;
! 161: return(d_erreur);
! 162: }
! 163:
! 164: (*l_nouvel_element).suivant = (*(*s_etat_processus)
! 165: .l_liste_variables_partagees);
! 166: (*l_nouvel_element).precedent = NULL;
! 167:
! 168: if ((*(*s_etat_processus).l_liste_variables_partagees) != NULL)
! 169: {
! 170: (**(*s_etat_processus).l_liste_variables_partagees).precedent
! 171: = l_nouvel_element;
! 172: }
! 173:
! 174: (*(*s_etat_processus).l_liste_variables_partagees) = l_nouvel_element;
! 175:
! 176: // Ajout de la variable à la feuille de l'arbre des variables partagees
! 177:
! 178: if ((*(*s_etat_processus).s_arbre_variables_partagees) == NULL)
! 179: {
! 180: if (((*(*s_etat_processus).s_arbre_variables_partagees) =
! 181: allocation_noeud_partage(s_etat_processus)) == NULL)
1.1 bertrand 182: {
1.39 ! bertrand 183: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
! 184: {
! 185: (*s_etat_processus).erreur_systeme = d_es_processus;
! 186: return(d_erreur);
! 187: }
! 188:
! 189: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 190: return(d_erreur);
1.1 bertrand 191: }
1.39 ! bertrand 192:
! 193: (**(*s_etat_processus).s_arbre_variables_partagees).feuille = NULL;
! 194: (**(*s_etat_processus).s_arbre_variables_partagees)
! 195: .noeuds_utilises = 0;
! 196: (**(*s_etat_processus).s_arbre_variables_partagees).indice_tableau_pere
! 197: = -1;
! 198: (**(*s_etat_processus).s_arbre_variables_partagees).noeud_pere = NULL;
! 199: INITIALISATION_MUTEX((**(*s_etat_processus).s_arbre_variables_partagees)
! 200: .mutex_feuille);
! 201:
! 202: if (((**(*s_etat_processus).s_arbre_variables_partagees).noeuds =
! 203: allocation_tableau_noeuds_partages(s_etat_processus)) == NULL)
1.1 bertrand 204: {
1.39 ! bertrand 205: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
1.1 bertrand 206: {
1.39 ! bertrand 207: (*s_etat_processus).erreur_systeme = d_es_processus;
! 208: return(d_erreur);
1.1 bertrand 209: }
210:
211: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
212: return(d_erreur);
213: }
214:
1.39 ! bertrand 215: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
! 216: {
! 217: (**(*s_etat_processus).s_arbre_variables_partagees).noeuds[i] =
! 218: NULL;
! 219: }
1.1 bertrand 220: }
221:
1.39 ! bertrand 222: l_variable_courante = (*(*s_etat_processus).s_arbre_variables_partagees);
! 223: ptr = (*s_variable).nom;
1.1 bertrand 224:
1.39 ! bertrand 225: if (pthread_mutex_lock(&((*l_variable_courante).mutex_feuille)) != 0)
1.1 bertrand 226: {
1.39 ! bertrand 227: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
! 228: {
! 229: (*s_etat_processus).erreur_systeme = d_es_processus;
! 230: return(d_erreur);
! 231: }
! 232:
! 233: (*s_etat_processus).erreur_systeme = d_es_processus;
! 234: return(d_erreur);
1.1 bertrand 235: }
1.39 ! bertrand 236:
! 237: while((*ptr) != d_code_fin_chaine)
1.1 bertrand 238: {
1.39 ! bertrand 239: BUG((*s_etat_processus).pointeurs_caracteres_variables[*ptr] < 0,
! 240: uprintf("Variable=\"%s\", (*ptr)='%c'\n", (*s_variable).nom,
! 241: *ptr));
! 242:
! 243: if ((*l_variable_courante).noeuds[(*s_etat_processus)
! 244: .pointeurs_caracteres_variables[*ptr]] == NULL)
1.1 bertrand 245: {
1.39 ! bertrand 246: // Le noeud n'existe pas encore, on le crée et on le marque
! 247: // comme utilisé dans la structure parente.
! 248:
! 249: if (((*l_variable_courante).noeuds[(*s_etat_processus)
! 250: .pointeurs_caracteres_variables[*ptr]] =
! 251: allocation_noeud_partage(s_etat_processus)) == NULL)
1.1 bertrand 252: {
1.39 ! bertrand 253: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
! 254: {
! 255: (*s_etat_processus).erreur_systeme = d_es_processus;
! 256: return(d_erreur);
! 257: }
! 258:
! 259: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 260: return(d_erreur);
1.1 bertrand 261: }
1.39 ! bertrand 262:
! 263: (*l_variable_courante).noeuds_utilises++;
! 264:
! 265: // La feuille est par défaut vide et aucun élément du tableau noeuds
! 266: // (les branches qui peuvent être issues de ce nouveau noeud)
! 267: // n'est encore utilisée.
! 268:
! 269: (*(*l_variable_courante).noeuds[(*s_etat_processus)
! 270: .pointeurs_caracteres_variables[*ptr]]).feuille = NULL;
! 271: (*(*l_variable_courante).noeuds[(*s_etat_processus)
! 272: .pointeurs_caracteres_variables[*ptr]]).noeuds_utilises = 0;
! 273:
! 274: // Le champ noeud_pere de la structure créée pointe sur
! 275: // la structure parente et l'indice tableau_pere correspond à la
! 276: // position réelle dans le tableau noeuds[] de la structure parente
! 277: // du noeud courant. Cette valeur sera utilisée lors de la
! 278: // destruction du noeud pour annuler le pointeur contenu dans
! 279: // le tableau noeuds[] de la structure parente.
! 280:
! 281: (*(*l_variable_courante).noeuds[(*s_etat_processus)
! 282: .pointeurs_caracteres_variables[*ptr]]).noeud_pere =
! 283: l_variable_courante;
! 284: (*(*l_variable_courante).noeuds[(*s_etat_processus)
! 285: .pointeurs_caracteres_variables[*ptr]])
! 286: .indice_tableau_pere = (*s_etat_processus)
! 287: .pointeurs_caracteres_variables[*ptr];
! 288:
! 289: // Allocation du tableau noeuds[] et initialisation à zéro de
! 290: // tous les pointeurs.
! 291:
! 292: if (((*(*l_variable_courante).noeuds[(*s_etat_processus)
! 293: .pointeurs_caracteres_variables[*ptr]]).noeuds =
! 294: allocation_tableau_noeuds_partages(s_etat_processus))
! 295: == NULL)
! 296: {
! 297: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
! 298: {
! 299: (*s_etat_processus).erreur_systeme = d_es_processus;
! 300: return(d_erreur);
! 301: }
! 302:
! 303: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 304: return(d_erreur);
! 305: }
! 306:
! 307: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
! 308: {
! 309: (*(*l_variable_courante).noeuds[(*s_etat_processus)
! 310: .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
! 311: = NULL;
! 312: }
! 313: }
! 314:
! 315: if (pthread_mutex_lock(&((*(*l_variable_courante).noeuds
! 316: [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]])
! 317: .mutex_feuille)) != 0)
! 318: {
! 319: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
! 320: {
! 321: (*s_etat_processus).erreur_systeme = d_es_processus;
! 322: return(d_erreur);
! 323: }
! 324:
! 325: (*s_etat_processus).erreur_systeme = d_es_processus;
! 326: return(d_erreur);
! 327: }
! 328:
! 329: if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
! 330: {
! 331: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
1.1 bertrand 332: {
1.39 ! bertrand 333: (*s_etat_processus).erreur_systeme = d_es_processus;
! 334: return(d_erreur);
1.1 bertrand 335: }
1.39 ! bertrand 336:
! 337: (*s_etat_processus).erreur_systeme = d_es_processus;
! 338: return(d_erreur);
! 339: }
! 340:
! 341: l_variable_courante = (*l_variable_courante).noeuds
! 342: [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
! 343: ptr++;
! 344: }
! 345:
! 346: if ((l_nouvel_element = malloc(sizeof(struct_liste_variables_partagees)))
! 347: == NULL)
! 348: {
! 349: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
! 350: {
! 351: (*s_etat_processus).erreur_systeme = d_es_processus;
! 352: return(d_erreur);
1.1 bertrand 353: }
354:
1.39 ! bertrand 355: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 356: return(d_erreur);
! 357: }
! 358:
! 359: // Dans la feuille de l'arbre des variables partagées, on ne balaie
! 360: // les variables que dans l'ordre. Le champ 'reference' est alors utilisé
! 361: // pour sauvegarder une référence vers la liste des variables partagées
! 362: // pour pouvoir purger l'élément en cas de besoin.
! 363:
! 364: (*l_nouvel_element).suivant = (*l_variable_courante).feuille;
! 365: (*l_nouvel_element).precedent = NULL;
! 366:
! 367: if ((*l_nouvel_element).suivant != NULL)
! 368: {
! 369: (*(*l_nouvel_element).suivant).precedent = l_nouvel_element;
1.1 bertrand 370: }
371:
1.39 ! bertrand 372: (*l_nouvel_element).reference =
! 373: (*(*s_etat_processus).l_liste_variables_partagees);
! 374: (*l_nouvel_element).variable = (**(*s_etat_processus)
! 375: .l_liste_variables_partagees).variable;
! 376: (*l_variable_courante).feuille = l_nouvel_element;
! 377: (*l_nouvel_element).feuille = l_variable_courante;
! 378:
! 379: if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
! 380: {
! 381: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
! 382: {
! 383: (*s_etat_processus).erreur_systeme = d_es_processus;
! 384: return(d_erreur);
! 385: }
! 386:
! 387: (*s_etat_processus).erreur_systeme = d_es_processus;
! 388: return(d_erreur);
! 389: }
! 390:
! 391: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
! 392: {
! 393: (*s_etat_processus).erreur_systeme = d_es_processus;
! 394: return(d_erreur);
! 395: }
! 396:
! 397: return(d_absence_erreur);
1.1 bertrand 398: }
399:
400:
401: /*
402: ================================================================================
1.39 ! bertrand 403: Routine de recherche d'une variable partagée
1.1 bertrand 404: ================================================================================
405: Entrée :
406: --------------------------------------------------------------------------------
407: Sortie :
408: --------------------------------------------------------------------------------
1.39 ! bertrand 409: Effets de bords : positionne le mutex sur la variable partagée
1.1 bertrand 410: ================================================================================
411: */
412:
1.39 ! bertrand 413: struct_liste_variables_partagees *
! 414: recherche_variable_partagee(struct_processus *s_etat_processus,
! 415: unsigned char *nom_variable, union_position_variable position,
! 416: unsigned char origine)
1.1 bertrand 417: {
1.39 ! bertrand 418: int pointeur;
! 419:
! 420: struct_arbre_variables_partagees *l_variable_courante;
! 421: struct_liste_variables_partagees *l_element_courant;
1.1 bertrand 422:
1.39 ! bertrand 423: unsigned char *ptr;
1.1 bertrand 424:
1.39 ! bertrand 425: l_variable_courante = (*(*s_etat_processus).s_arbre_variables_partagees);
! 426: ptr = nom_variable;
1.1 bertrand 427:
1.39 ! bertrand 428: if (l_variable_courante == NULL)
1.1 bertrand 429: {
1.39 ! bertrand 430: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
! 431: return(NULL);
! 432: }
! 433:
! 434: if (pthread_mutex_lock(&((*l_variable_courante).mutex_feuille)) != 0)
! 435: {
! 436: (*s_etat_processus).erreur_systeme = d_es_processus;
! 437: return(NULL);
! 438: }
! 439:
! 440: while((*ptr) != d_code_fin_chaine)
! 441: {
! 442: pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
! 443:
! 444: if (pointeur < 0)
1.1 bertrand 445: {
1.39 ! bertrand 446: // Caractère hors de l'alphabet des variables
1.1 bertrand 447:
1.39 ! bertrand 448: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
! 449: return(NULL);
! 450: }
! 451:
! 452: if ((*l_variable_courante).noeuds[pointeur] == NULL)
! 453: {
! 454: // Le chemin de la variable candidate n'existe pas.
! 455: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
! 456: return(NULL);
! 457: }
! 458:
! 459: if (pthread_mutex_lock(&((*(*l_variable_courante).noeuds[pointeur])
! 460: .mutex_feuille)) != 0)
! 461: {
! 462: (*s_etat_processus).erreur_systeme = d_es_processus;
! 463: return(NULL);
! 464: }
1.1 bertrand 465:
1.39 ! bertrand 466: if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
! 467: {
! 468: (*s_etat_processus).erreur_systeme = d_es_processus;
! 469: return(NULL);
1.1 bertrand 470: }
471:
1.39 ! bertrand 472: l_variable_courante = (*l_variable_courante).noeuds[pointeur];
! 473: ptr++;
! 474: }
1.1 bertrand 475:
1.39 ! bertrand 476: if ((*l_variable_courante).feuille != NULL)
! 477: {
! 478: // Il existe au moins une variable statique du nom requis.
1.1 bertrand 479:
1.39 ! bertrand 480: l_element_courant = (*l_variable_courante).feuille;
1.1 bertrand 481:
1.39 ! bertrand 482: while(l_element_courant != NULL)
1.1 bertrand 483: {
1.39 ! bertrand 484: if ((*(*l_element_courant).variable).origine == 'P')
! 485: {
! 486: if (((*(*l_element_courant).variable).variable_partagee.adresse
! 487: == position.adresse) &&
! 488: ((*(*l_element_courant).variable).origine == origine))
! 489: {
! 490: if (pthread_mutex_lock(&((*(*l_element_courant).variable)
! 491: .mutex)) != 0)
! 492: {
! 493: (*s_etat_processus).erreur_systeme = d_es_processus;
! 494: return(NULL);
! 495: }
! 496:
! 497: if (pthread_mutex_unlock(&((*l_variable_courante)
! 498: .mutex_feuille)) != 0)
! 499: {
! 500: (*s_etat_processus).erreur_systeme = d_es_processus;
! 501: return(NULL);
! 502: }
! 503:
! 504: (*s_etat_processus).pointeur_variable_partagee_courante
! 505: = (*l_element_courant).variable;
! 506: return(l_element_courant);
! 507: }
! 508: }
! 509: else
! 510: {
! 511: if (((*(*l_element_courant).variable).variable_partagee.pointeur
! 512: == position.pointeur) &&
! 513: ((*(*l_element_courant).variable).origine == origine))
! 514: {
! 515: if (pthread_mutex_lock(&((*(*l_element_courant).variable)
! 516: .mutex)) != 0)
! 517: {
! 518: (*s_etat_processus).erreur_systeme = d_es_processus;
! 519: return(NULL);
! 520: }
! 521:
! 522: if (pthread_mutex_unlock(&((*l_variable_courante)
! 523: .mutex_feuille)) != 0)
! 524: {
! 525: (*s_etat_processus).erreur_systeme = d_es_processus;
! 526: return(NULL);
! 527: }
! 528:
! 529: (*s_etat_processus).pointeur_variable_partagee_courante
! 530: = (*l_element_courant).variable;
! 531: return(l_element_courant);
! 532: }
! 533: }
! 534:
! 535: l_element_courant = (*l_element_courant).suivant;
1.1 bertrand 536: }
1.39 ! bertrand 537: }
1.1 bertrand 538:
1.39 ! bertrand 539: if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
1.1 bertrand 540: {
1.39 ! bertrand 541: (*s_etat_processus).erreur_systeme = d_es_processus;
! 542: return(NULL);
1.1 bertrand 543: }
544:
1.39 ! bertrand 545: (*s_etat_processus).pointeur_variable_statique_courante = NULL;
! 546: return(NULL);
1.1 bertrand 547: }
548:
549:
550: /*
551: ================================================================================
1.39 ! bertrand 552: Routine de retrait d'une variable partagée
1.1 bertrand 553: ================================================================================
554: Entrée :
555: --------------------------------------------------------------------------------
556: Sortie :
557: --------------------------------------------------------------------------------
1.39 ! bertrand 558: Effets de bords : néant
1.1 bertrand 559: ================================================================================
560: */
561:
562: logical1
1.39 ! bertrand 563: retrait_variable_partagee(struct_processus *s_etat_processus,
! 564: unsigned char *nom_variable, union_position_variable position)
1.1 bertrand 565: {
1.39 ! bertrand 566: struct_liste_variables_partagees *l_element_a_supprimer;
! 567: struct_liste_variables_partagees *l_element_liste_a_supprimer;
1.1 bertrand 568:
1.39 ! bertrand 569: logical1 erreur;
1.1 bertrand 570:
1.39 ! bertrand 571: if ((l_element_a_supprimer = recherche_variable_partagee(s_etat_processus,
! 572: nom_variable, position, ((*s_etat_processus)
! 573: .mode_execution_programme == 'Y') ? 'P' : 'E')) != NULL)
1.1 bertrand 574: {
1.39 ! bertrand 575: if (pthread_mutex_lock(&mutex_liste_variables_partagees) != 0)
! 576: {
! 577: (*s_etat_processus).erreur_systeme = d_es_processus;
! 578: return(d_erreur);
! 579: }
1.1 bertrand 580:
1.39 ! bertrand 581: // (*s_etat_processus).pointeur_variable_partagee_courante
! 582: // pointe sur la variable à éliminer. Cette variable est celle qui
! 583: // est présente dans l'une des feuilles statiques de l'arbre des
! 584: // variables.
1.1 bertrand 585:
1.39 ! bertrand 586: l_element_liste_a_supprimer = (*l_element_a_supprimer).reference;
1.1 bertrand 587:
1.39 ! bertrand 588: // Suppression de la liste des variables statiques
1.1 bertrand 589:
1.39 ! bertrand 590: if ((*l_element_liste_a_supprimer).precedent != NULL)
1.1 bertrand 591: {
1.39 ! bertrand 592: // L'élément à supprimer n'est pas le premier de la liste.
1.1 bertrand 593:
1.39 ! bertrand 594: (*(*l_element_liste_a_supprimer).precedent).suivant =
! 595: (*l_element_liste_a_supprimer).suivant;
! 596:
! 597: if ((*l_element_liste_a_supprimer).suivant != NULL)
1.1 bertrand 598: {
1.39 ! bertrand 599: // Il y a un élément suivant. On le chaîne.
! 600: (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
1.1 bertrand 601: }
602: }
603: else
604: {
1.39 ! bertrand 605: // L'élement est le premier de la liste. S'il y a un élément
! 606: // suivant, on le chaîne.
1.1 bertrand 607:
1.39 ! bertrand 608: if ((*l_element_liste_a_supprimer).suivant != NULL)
1.1 bertrand 609: {
1.39 ! bertrand 610: (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
1.1 bertrand 611: }
612:
1.39 ! bertrand 613: (*(*s_etat_processus).l_liste_variables_partagees) =
! 614: (*l_element_liste_a_supprimer).suivant;
1.1 bertrand 615: }
616:
1.39 ! bertrand 617: free(l_element_liste_a_supprimer);
! 618:
! 619: // Suppression depuis la feuille statique. Le champ 'precedent' ne sert
! 620: // pas car la liste est simplement chaînée.
1.1 bertrand 621:
1.39 ! bertrand 622: if ((*l_element_a_supprimer).precedent != NULL)
1.1 bertrand 623: {
1.39 ! bertrand 624: // L'élément n'est pas le premier de la liste.
! 625:
! 626: (*(*l_element_a_supprimer).precedent).suivant =
! 627: (*l_element_a_supprimer).suivant;
! 628:
! 629: if ((*l_element_a_supprimer).suivant != NULL)
1.1 bertrand 630: {
1.39 ! bertrand 631: (*(*l_element_a_supprimer).suivant).precedent =
! 632: (*l_element_a_supprimer).precedent;
1.1 bertrand 633: }
634: else
635: {
1.39 ! bertrand 636: (*(*l_element_a_supprimer).precedent).suivant = NULL;
1.1 bertrand 637: }
638: }
639: else
640: {
1.39 ! bertrand 641: // L'élément est le premier de la liste.
! 642:
! 643: if ((*l_element_a_supprimer).suivant != NULL)
1.1 bertrand 644: {
1.39 ! bertrand 645: (*(*l_element_a_supprimer).suivant).precedent = NULL;
1.1 bertrand 646: }
1.39 ! bertrand 647:
! 648: (*(*l_element_a_supprimer).feuille).feuille
! 649: = (*l_element_a_supprimer).suivant;
1.1 bertrand 650: }
651:
1.39 ! bertrand 652: liberation(s_etat_processus, (*(*l_element_a_supprimer).variable)
! 653: .objet);
! 654: free((*(*l_element_a_supprimer).variable).nom);
! 655: free((*l_element_a_supprimer).variable);
! 656: free(l_element_a_supprimer);
! 657:
! 658: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
1.1 bertrand 659: {
1.39 ! bertrand 660: (*s_etat_processus).erreur_systeme = d_es_processus;
! 661: return(d_erreur);
! 662: }
! 663:
! 664: erreur = d_absence_erreur;
! 665: }
! 666: else
! 667: {
! 668: erreur = d_erreur;
! 669: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
! 670: }
! 671:
! 672: return(erreur);
! 673: }
! 674:
! 675:
! 676: /*
! 677: ================================================================================
! 678: Routine de retrait des variables partagées
! 679: ================================================================================
! 680: Entrée :
! 681: --------------------------------------------------------------------------------
! 682: Sortie :
! 683: --------------------------------------------------------------------------------
! 684: Effets de bords : néant
! 685: ================================================================================
! 686: */
! 687:
! 688: // Cette routine libère toutes les variables partagées de niveau non
! 689: // nul, donc attachées à une expression et non un programme.
1.1 bertrand 690:
1.39 ! bertrand 691: logical1
! 692: retrait_variables_partagees_locales(struct_processus *s_etat_processus)
! 693: {
! 694: struct_liste_variables_partagees *l_element_courant;
! 695: struct_liste_variables_partagees *l_element_suivant;
! 696:
! 697: unsigned char registre_mode_execution;
! 698:
! 699: if (pthread_mutex_lock(&mutex_liste_variables_partagees) != 0)
! 700: {
! 701: (*s_etat_processus).erreur_systeme = d_es_processus;
! 702: return(d_erreur);
! 703: }
1.1 bertrand 704:
1.39 ! bertrand 705: registre_mode_execution = (*s_etat_processus).mode_execution_programme;
! 706: l_element_courant = (*(*s_etat_processus).l_liste_variables_partagees);
1.1 bertrand 707:
1.39 ! bertrand 708: while(l_element_courant != NULL)
! 709: {
! 710: l_element_suivant = (*l_element_courant).suivant;
1.1 bertrand 711:
1.39 ! bertrand 712: (*s_etat_processus).mode_execution_programme =
! 713: ((*(*l_element_courant).variable).origine == 'P') ? 'Y' : 'N';
1.1 bertrand 714:
1.39 ! bertrand 715: if (((*(*l_element_courant).variable).niveau > 0) &&
! 716: ((*l_element_courant).pid == getpid()) &&
! 717: (pthread_equal((*l_element_courant).tid, pthread_self()) != 0))
! 718: {
! 719: if (retrait_variable_partagee(s_etat_processus,
! 720: (*(*l_element_courant).variable).nom,
! 721: (*(*l_element_courant).variable).variable_partagee)
! 722: == d_erreur)
1.1 bertrand 723: {
1.39 ! bertrand 724: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
1.1 bertrand 725: {
1.39 ! bertrand 726: (*s_etat_processus).erreur_systeme = d_es_processus;
! 727: return(d_erreur);
1.1 bertrand 728: }
1.39 ! bertrand 729:
! 730: (*s_etat_processus).mode_execution_programme =
! 731: registre_mode_execution;
! 732: return(d_erreur);
1.1 bertrand 733: }
1.39 ! bertrand 734: }
! 735:
! 736: l_element_courant = l_element_suivant;
! 737: }
! 738:
! 739: (*s_etat_processus).mode_execution_programme = registre_mode_execution;
! 740:
! 741: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
! 742: {
! 743: (*s_etat_processus).erreur_systeme = d_es_processus;
! 744: return(d_erreur);
! 745: }
! 746:
! 747: return(d_absence_erreur);
! 748: }
! 749:
! 750:
! 751: /*
! 752: ================================================================================
! 753: Routine de libération de l'arbre des variables partagées
! 754: ================================================================================
! 755: Entrée :
! 756: --------------------------------------------------------------------------------
! 757: Sortie :
! 758: --------------------------------------------------------------------------------
! 759: Effets de bords : positionne le mutex sur la variable partagée
! 760: ================================================================================
! 761: */
! 762:
! 763: void
! 764: liberation_arbre_variables_partagees(struct_processus *s_etat_processus,
! 765: struct_arbre_variables_partagees *arbre)
! 766: {
! 767: int i;
1.1 bertrand 768:
1.39 ! bertrand 769: struct_liste_variables_partagees *l_element_partage_courant;
! 770: struct_liste_variables_partagees *l_element_partage_suivant;
1.1 bertrand 771:
1.39 ! bertrand 772: // Libération de l'arbre des variables. Le contenu des variables n'est
! 773: // pas détruit par cette opération, il sera détruit lors de la libération
! 774: // de la liste des variables par niveau.
! 775:
! 776: if (arbre == NULL)
! 777: {
! 778: return;
! 779: }
! 780:
! 781: if (pthread_mutex_lock(&((*arbre).mutex_feuille)) != 0)
! 782: {
! 783: (*s_etat_processus).erreur_systeme = d_es_processus;
! 784: return;
! 785: }
! 786:
! 787: l_element_partage_courant = (*arbre).feuille;
! 788:
! 789: while(l_element_partage_courant != NULL)
! 790: {
! 791: l_element_partage_suivant = (*l_element_partage_courant).suivant;
! 792:
! 793: if (pthread_mutex_lock(&((*(*l_element_partage_courant).variable)
! 794: .mutex)) != 0)
! 795: {
! 796: (*s_etat_processus).erreur_systeme = d_es_processus;
! 797: return;
! 798: }
! 799:
! 800: free((*(*l_element_partage_courant).variable).nom);
! 801: liberation(s_etat_processus, (*(*l_element_partage_courant)
! 802: .variable).objet);
! 803: free((*l_element_partage_courant).variable);
1.1 bertrand 804:
1.39 ! bertrand 805: if (pthread_mutex_unlock(&((*(*l_element_partage_courant).variable)
! 806: .mutex)) != 0)
! 807: {
! 808: (*s_etat_processus).erreur_systeme = d_es_processus;
! 809: return;
! 810: }
1.1 bertrand 811:
1.39 ! bertrand 812: if (pthread_mutex_destroy(&((*(*l_element_partage_courant).variable)
! 813: .mutex)) != 0)
! 814: {
! 815: (*s_etat_processus).erreur_systeme = d_es_processus;
! 816: return;
1.1 bertrand 817: }
818:
1.39 ! bertrand 819: free(l_element_partage_courant);
! 820:
! 821: l_element_partage_courant = l_element_partage_suivant;
1.1 bertrand 822: }
823:
1.39 ! bertrand 824: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
1.1 bertrand 825: {
1.39 ! bertrand 826: if ((*arbre).noeuds[i] != NULL)
1.1 bertrand 827: {
1.39 ! bertrand 828: liberation_arbre_variables_partagees(s_etat_processus,
! 829: (*arbre).noeuds[i]);
! 830: (*arbre).noeuds[i] = NULL;
1.1 bertrand 831: }
832: }
833:
1.39 ! bertrand 834: liberation_tableau_noeuds_partages(s_etat_processus, (*arbre).noeuds);
! 835: liberation_noeud_partage(s_etat_processus, arbre);
! 836:
! 837: if (pthread_mutex_unlock(&((*arbre).mutex_feuille)) != 0)
! 838: {
! 839: (*s_etat_processus).erreur_systeme = d_es_processus;
! 840: return;
! 841: }
! 842:
! 843: if (pthread_mutex_destroy(&((*arbre).mutex_feuille)) != 0)
! 844: {
! 845: (*s_etat_processus).erreur_systeme = d_es_processus;
! 846: return;
! 847: }
! 848:
! 849: arbre = NULL;
! 850: return;
1.1 bertrand 851: }
1.39 ! bertrand 852:
1.1 bertrand 853: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>