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