1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.13
4: Copyright (C) 1989-2013 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(((size_t) (*s_etat_processus)
88: .nombre_caracteres_variables)
89: * sizeof(struct_arbre_variables_partagees *));
90: }
91:
92: return(objet);
93: }
94:
95: static inline void
96: liberation_tableau_noeuds_partages(struct_processus *s_etat_processus,
97: struct_arbre_variables_partagees **objet)
98: {
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: }
110:
111: return;
112: }
113:
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:
127: logical1
128: creation_variable_partagee(struct_processus *s_etat_processus,
129: struct_variable_partagee *s_variable)
130: {
131: int i;
132:
133: struct_arbre_variables_partagees *l_variable_courante;
134:
135: struct_liste_variables_partagees *l_nouvel_element;
136:
137: unsigned char *ptr;
138:
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)
143: {
144: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
145: return(d_erreur);
146: }
147:
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)
183: {
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);
192: }
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)
205: {
206: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
207: {
208: (*s_etat_processus).erreur_systeme = d_es_processus;
209: return(d_erreur);
210: }
211:
212: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
213: return(d_erreur);
214: }
215:
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: }
221: }
222:
223: l_variable_courante = (*(*s_etat_processus).s_arbre_variables_partagees);
224: ptr = (*s_variable).nom;
225:
226: if (pthread_mutex_lock(&((*l_variable_courante).mutex_feuille)) != 0)
227: {
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);
236: }
237:
238: while((*ptr) != d_code_fin_chaine)
239: {
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)
246: {
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)
253: {
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);
262: }
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];
289: INITIALISATION_MUTEX((*(*l_variable_courante).noeuds
290: [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]])
291: .mutex_feuille);
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)
336: {
337: (*s_etat_processus).erreur_systeme = d_es_processus;
338: return(d_erreur);
339: }
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);
357: }
358:
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;
374: }
375:
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);
402: }
403:
404:
405: /*
406: ================================================================================
407: Routine de recherche d'une variable partagée
408: ================================================================================
409: Entrée :
410: --------------------------------------------------------------------------------
411: Sortie :
412: --------------------------------------------------------------------------------
413: Effets de bords : positionne le mutex sur la variable partagée
414: ================================================================================
415: */
416:
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)
421: {
422: int pointeur;
423:
424: struct_arbre_variables_partagees *l_variable_courante;
425: struct_liste_variables_partagees *l_element_courant;
426:
427: unsigned char *ptr;
428:
429: l_variable_courante = (*(*s_etat_processus).s_arbre_variables_partagees);
430: ptr = nom_variable;
431:
432: if (l_variable_courante == NULL)
433: {
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)
449: {
450: // Caractère hors de l'alphabet des variables
451:
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: }
469:
470: if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
471: {
472: (*s_etat_processus).erreur_systeme = d_es_processus;
473: return(NULL);
474: }
475:
476: l_variable_courante = (*l_variable_courante).noeuds[pointeur];
477: ptr++;
478: }
479:
480: if ((*l_variable_courante).feuille != NULL)
481: {
482: // Il existe au moins une variable statique du nom requis.
483:
484: l_element_courant = (*l_variable_courante).feuille;
485:
486: while(l_element_courant != NULL)
487: {
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;
540: }
541: }
542:
543: if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
544: {
545: (*s_etat_processus).erreur_systeme = d_es_processus;
546: return(NULL);
547: }
548:
549: (*s_etat_processus).pointeur_variable_statique_courante = NULL;
550: return(NULL);
551: }
552:
553:
554: /*
555: ================================================================================
556: Routine de retrait d'une variable partagée
557: ================================================================================
558: Entrée :
559: --------------------------------------------------------------------------------
560: Sortie :
561: --------------------------------------------------------------------------------
562: Effets de bords : néant
563: ================================================================================
564: */
565:
566: logical1
567: retrait_variable_partagee(struct_processus *s_etat_processus,
568: unsigned char *nom_variable, union_position_variable position)
569: {
570: struct_liste_variables_partagees *l_element_a_supprimer;
571: struct_liste_variables_partagees *l_element_liste_a_supprimer;
572:
573: logical1 erreur;
574:
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)
578: {
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: }
584:
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.
589:
590: l_element_liste_a_supprimer = (*l_element_a_supprimer).reference;
591:
592: // Suppression de la liste des variables statiques
593:
594: if ((*l_element_liste_a_supprimer).precedent != NULL)
595: {
596: // L'élément à supprimer n'est pas le premier de la liste.
597:
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)
602: {
603: // Il y a un élément suivant. On le chaîne.
604: (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
605: }
606: }
607: else
608: {
609: // L'élement est le premier de la liste. S'il y a un élément
610: // suivant, on le chaîne.
611:
612: if ((*l_element_liste_a_supprimer).suivant != NULL)
613: {
614: (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
615: }
616:
617: (*(*s_etat_processus).l_liste_variables_partagees) =
618: (*l_element_liste_a_supprimer).suivant;
619: }
620:
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.
625:
626: if ((*l_element_a_supprimer).precedent != NULL)
627: {
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)
634: {
635: (*(*l_element_a_supprimer).suivant).precedent =
636: (*l_element_a_supprimer).precedent;
637: }
638: else
639: {
640: (*(*l_element_a_supprimer).precedent).suivant = NULL;
641: }
642: }
643: else
644: {
645: // L'élément est le premier de la liste.
646:
647: if ((*l_element_a_supprimer).suivant != NULL)
648: {
649: (*(*l_element_a_supprimer).suivant).precedent = NULL;
650: }
651:
652: (*(*l_element_a_supprimer).feuille).feuille
653: = (*l_element_a_supprimer).suivant;
654: }
655:
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)
663: {
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.
694:
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: }
708:
709: registre_mode_execution = (*s_etat_processus).mode_execution_programme;
710: l_element_courant = (*(*s_etat_processus).l_liste_variables_partagees);
711:
712: while(l_element_courant != NULL)
713: {
714: l_element_suivant = (*l_element_courant).suivant;
715:
716: (*s_etat_processus).mode_execution_programme =
717: ((*(*l_element_courant).variable).origine == 'P') ? 'Y' : 'N';
718:
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)
727: {
728: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
729: {
730: (*s_etat_processus).erreur_systeme = d_es_processus;
731: return(d_erreur);
732: }
733:
734: (*s_etat_processus).mode_execution_programme =
735: registre_mode_execution;
736: return(d_erreur);
737: }
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;
772:
773: struct_liste_variables_partagees *l_element_partage_courant;
774: struct_liste_variables_partagees *l_element_partage_suivant;
775:
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);
808:
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: }
815:
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;
821: }
822:
823: free(l_element_partage_courant);
824:
825: l_element_partage_courant = l_element_partage_suivant;
826: }
827:
828: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
829: {
830: if ((*arbre).noeuds[i] != NULL)
831: {
832: liberation_arbre_variables_partagees(s_etat_processus,
833: (*arbre).noeuds[i]);
834: (*arbre).noeuds[i] = NULL;
835: }
836: }
837:
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;
855: }
856:
857: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>