1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.11
4: Copyright (C) 1989-2012 Dr. BERTRAND Joël
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:
23: #include "rpl-conv.h"
24:
25:
26: /*
27: ================================================================================
28: Routine de gestion du cache des objets
29: ================================================================================
30: Entrée :
31: --------------------------------------------------------------------------------
32: Sortie :
33: --------------------------------------------------------------------------------
34: Effets de bords : néant
35: ================================================================================
36: */
37:
38: static inline struct_arbre_variables_partagees *
39: allocation_noeud_partage(struct_processus *s_etat_processus)
40: {
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);
54: }
55:
56: static inline void
57: liberation_noeud_partage(struct_processus *s_etat_processus,
58: struct_arbre_variables_partagees *objet)
59: {
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;
72: }
73:
74: static inline struct_arbre_variables_partagees **
75: allocation_tableau_noeuds_partages(struct_processus *s_etat_processus)
76: {
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);
92: }
93:
94: static inline void
95: liberation_tableau_noeuds_partages(struct_processus *s_etat_processus,
96: struct_arbre_variables_partagees **objet)
97: {
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: }
109:
110: return;
111: }
112:
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:
126: logical1
127: creation_variable_partagee(struct_processus *s_etat_processus,
128: struct_variable_partagee *s_variable)
129: {
130: int i;
131:
132: struct_arbre_variables_partagees *l_variable_courante;
133:
134: struct_liste_variables_partagees *l_nouvel_element;
135:
136: unsigned char *ptr;
137:
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)
142: {
143: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
144: return(d_erreur);
145: }
146:
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)
182: {
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);
191: }
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)
204: {
205: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
206: {
207: (*s_etat_processus).erreur_systeme = d_es_processus;
208: return(d_erreur);
209: }
210:
211: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
212: return(d_erreur);
213: }
214:
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: }
220: }
221:
222: l_variable_courante = (*(*s_etat_processus).s_arbre_variables_partagees);
223: ptr = (*s_variable).nom;
224:
225: if (pthread_mutex_lock(&((*l_variable_courante).mutex_feuille)) != 0)
226: {
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);
235: }
236:
237: while((*ptr) != d_code_fin_chaine)
238: {
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)
245: {
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)
252: {
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);
261: }
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)
332: {
333: (*s_etat_processus).erreur_systeme = d_es_processus;
334: return(d_erreur);
335: }
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);
353: }
354:
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;
370: }
371:
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);
398: }
399:
400:
401: /*
402: ================================================================================
403: Routine de recherche d'une variable partagée
404: ================================================================================
405: Entrée :
406: --------------------------------------------------------------------------------
407: Sortie :
408: --------------------------------------------------------------------------------
409: Effets de bords : positionne le mutex sur la variable partagée
410: ================================================================================
411: */
412:
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)
417: {
418: int pointeur;
419:
420: struct_arbre_variables_partagees *l_variable_courante;
421: struct_liste_variables_partagees *l_element_courant;
422:
423: unsigned char *ptr;
424:
425: l_variable_courante = (*(*s_etat_processus).s_arbre_variables_partagees);
426: ptr = nom_variable;
427:
428: if (l_variable_courante == NULL)
429: {
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)
445: {
446: // Caractère hors de l'alphabet des variables
447:
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: }
465:
466: if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
467: {
468: (*s_etat_processus).erreur_systeme = d_es_processus;
469: return(NULL);
470: }
471:
472: l_variable_courante = (*l_variable_courante).noeuds[pointeur];
473: ptr++;
474: }
475:
476: if ((*l_variable_courante).feuille != NULL)
477: {
478: // Il existe au moins une variable statique du nom requis.
479:
480: l_element_courant = (*l_variable_courante).feuille;
481:
482: while(l_element_courant != NULL)
483: {
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;
536: }
537: }
538:
539: if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
540: {
541: (*s_etat_processus).erreur_systeme = d_es_processus;
542: return(NULL);
543: }
544:
545: (*s_etat_processus).pointeur_variable_statique_courante = NULL;
546: return(NULL);
547: }
548:
549:
550: /*
551: ================================================================================
552: Routine de retrait d'une variable partagée
553: ================================================================================
554: Entrée :
555: --------------------------------------------------------------------------------
556: Sortie :
557: --------------------------------------------------------------------------------
558: Effets de bords : néant
559: ================================================================================
560: */
561:
562: logical1
563: retrait_variable_partagee(struct_processus *s_etat_processus,
564: unsigned char *nom_variable, union_position_variable position)
565: {
566: struct_liste_variables_partagees *l_element_a_supprimer;
567: struct_liste_variables_partagees *l_element_liste_a_supprimer;
568:
569: logical1 erreur;
570:
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)
574: {
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: }
580:
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.
585:
586: l_element_liste_a_supprimer = (*l_element_a_supprimer).reference;
587:
588: // Suppression de la liste des variables statiques
589:
590: if ((*l_element_liste_a_supprimer).precedent != NULL)
591: {
592: // L'élément à supprimer n'est pas le premier de la liste.
593:
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)
598: {
599: // Il y a un élément suivant. On le chaîne.
600: (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
601: }
602: }
603: else
604: {
605: // L'élement est le premier de la liste. S'il y a un élément
606: // suivant, on le chaîne.
607:
608: if ((*l_element_liste_a_supprimer).suivant != NULL)
609: {
610: (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
611: }
612:
613: (*(*s_etat_processus).l_liste_variables_partagees) =
614: (*l_element_liste_a_supprimer).suivant;
615: }
616:
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.
621:
622: if ((*l_element_a_supprimer).precedent != NULL)
623: {
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)
630: {
631: (*(*l_element_a_supprimer).suivant).precedent =
632: (*l_element_a_supprimer).precedent;
633: }
634: else
635: {
636: (*(*l_element_a_supprimer).precedent).suivant = NULL;
637: }
638: }
639: else
640: {
641: // L'élément est le premier de la liste.
642:
643: if ((*l_element_a_supprimer).suivant != NULL)
644: {
645: (*(*l_element_a_supprimer).suivant).precedent = NULL;
646: }
647:
648: (*(*l_element_a_supprimer).feuille).feuille
649: = (*l_element_a_supprimer).suivant;
650: }
651:
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)
659: {
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.
690:
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: }
704:
705: registre_mode_execution = (*s_etat_processus).mode_execution_programme;
706: l_element_courant = (*(*s_etat_processus).l_liste_variables_partagees);
707:
708: while(l_element_courant != NULL)
709: {
710: l_element_suivant = (*l_element_courant).suivant;
711:
712: (*s_etat_processus).mode_execution_programme =
713: ((*(*l_element_courant).variable).origine == 'P') ? 'Y' : 'N';
714:
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)
723: {
724: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
725: {
726: (*s_etat_processus).erreur_systeme = d_es_processus;
727: return(d_erreur);
728: }
729:
730: (*s_etat_processus).mode_execution_programme =
731: registre_mode_execution;
732: return(d_erreur);
733: }
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;
768:
769: struct_liste_variables_partagees *l_element_partage_courant;
770: struct_liste_variables_partagees *l_element_partage_suivant;
771:
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);
804:
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: }
811:
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;
817: }
818:
819: free(l_element_partage_courant);
820:
821: l_element_partage_courant = l_element_partage_suivant;
822: }
823:
824: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
825: {
826: if ((*arbre).noeuds[i] != NULL)
827: {
828: liberation_arbre_variables_partagees(s_etat_processus,
829: (*arbre).noeuds[i]);
830: (*arbre).noeuds[i] = NULL;
831: }
832: }
833:
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;
851: }
852:
853: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>