1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.12
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((*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: INITIALISATION_MUTEX((*(*l_variable_courante).noeuds
289: [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]])
290: .mutex_feuille);
291:
292: // Allocation du tableau noeuds[] et initialisation à zéro de
293: // tous les pointeurs.
294:
295: if (((*(*l_variable_courante).noeuds[(*s_etat_processus)
296: .pointeurs_caracteres_variables[*ptr]]).noeuds =
297: allocation_tableau_noeuds_partages(s_etat_processus))
298: == NULL)
299: {
300: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
301: {
302: (*s_etat_processus).erreur_systeme = d_es_processus;
303: return(d_erreur);
304: }
305:
306: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
307: return(d_erreur);
308: }
309:
310: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
311: {
312: (*(*l_variable_courante).noeuds[(*s_etat_processus)
313: .pointeurs_caracteres_variables[*ptr]]).noeuds[i]
314: = NULL;
315: }
316: }
317:
318: if (pthread_mutex_lock(&((*(*l_variable_courante).noeuds
319: [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]])
320: .mutex_feuille)) != 0)
321: {
322: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
323: {
324: (*s_etat_processus).erreur_systeme = d_es_processus;
325: return(d_erreur);
326: }
327:
328: (*s_etat_processus).erreur_systeme = d_es_processus;
329: return(d_erreur);
330: }
331:
332: if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
333: {
334: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
335: {
336: (*s_etat_processus).erreur_systeme = d_es_processus;
337: return(d_erreur);
338: }
339:
340: (*s_etat_processus).erreur_systeme = d_es_processus;
341: return(d_erreur);
342: }
343:
344: l_variable_courante = (*l_variable_courante).noeuds
345: [(*s_etat_processus).pointeurs_caracteres_variables[*ptr]];
346: ptr++;
347: }
348:
349: if ((l_nouvel_element = malloc(sizeof(struct_liste_variables_partagees)))
350: == NULL)
351: {
352: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
353: {
354: (*s_etat_processus).erreur_systeme = d_es_processus;
355: return(d_erreur);
356: }
357:
358: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
359: return(d_erreur);
360: }
361:
362: // Dans la feuille de l'arbre des variables partagées, on ne balaie
363: // les variables que dans l'ordre. Le champ 'reference' est alors utilisé
364: // pour sauvegarder une référence vers la liste des variables partagées
365: // pour pouvoir purger l'élément en cas de besoin.
366:
367: (*l_nouvel_element).suivant = (*l_variable_courante).feuille;
368: (*l_nouvel_element).precedent = NULL;
369:
370: if ((*l_nouvel_element).suivant != NULL)
371: {
372: (*(*l_nouvel_element).suivant).precedent = l_nouvel_element;
373: }
374:
375: (*l_nouvel_element).reference =
376: (*(*s_etat_processus).l_liste_variables_partagees);
377: (*l_nouvel_element).variable = (**(*s_etat_processus)
378: .l_liste_variables_partagees).variable;
379: (*l_variable_courante).feuille = l_nouvel_element;
380: (*l_nouvel_element).feuille = l_variable_courante;
381:
382: if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
383: {
384: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
385: {
386: (*s_etat_processus).erreur_systeme = d_es_processus;
387: return(d_erreur);
388: }
389:
390: (*s_etat_processus).erreur_systeme = d_es_processus;
391: return(d_erreur);
392: }
393:
394: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
395: {
396: (*s_etat_processus).erreur_systeme = d_es_processus;
397: return(d_erreur);
398: }
399:
400: return(d_absence_erreur);
401: }
402:
403:
404: /*
405: ================================================================================
406: Routine de recherche d'une variable partagée
407: ================================================================================
408: Entrée :
409: --------------------------------------------------------------------------------
410: Sortie :
411: --------------------------------------------------------------------------------
412: Effets de bords : positionne le mutex sur la variable partagée
413: ================================================================================
414: */
415:
416: struct_liste_variables_partagees *
417: recherche_variable_partagee(struct_processus *s_etat_processus,
418: unsigned char *nom_variable, union_position_variable position,
419: unsigned char origine)
420: {
421: int pointeur;
422:
423: struct_arbre_variables_partagees *l_variable_courante;
424: struct_liste_variables_partagees *l_element_courant;
425:
426: unsigned char *ptr;
427:
428: l_variable_courante = (*(*s_etat_processus).s_arbre_variables_partagees);
429: ptr = nom_variable;
430:
431: if (l_variable_courante == NULL)
432: {
433: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
434: return(NULL);
435: }
436:
437: if (pthread_mutex_lock(&((*l_variable_courante).mutex_feuille)) != 0)
438: {
439: (*s_etat_processus).erreur_systeme = d_es_processus;
440: return(NULL);
441: }
442:
443: while((*ptr) != d_code_fin_chaine)
444: {
445: pointeur = (*s_etat_processus).pointeurs_caracteres_variables[*ptr];
446:
447: if (pointeur < 0)
448: {
449: // Caractère hors de l'alphabet des variables
450:
451: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
452: return(NULL);
453: }
454:
455: if ((*l_variable_courante).noeuds[pointeur] == NULL)
456: {
457: // Le chemin de la variable candidate n'existe pas.
458: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
459: return(NULL);
460: }
461:
462: if (pthread_mutex_lock(&((*(*l_variable_courante).noeuds[pointeur])
463: .mutex_feuille)) != 0)
464: {
465: (*s_etat_processus).erreur_systeme = d_es_processus;
466: return(NULL);
467: }
468:
469: if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
470: {
471: (*s_etat_processus).erreur_systeme = d_es_processus;
472: return(NULL);
473: }
474:
475: l_variable_courante = (*l_variable_courante).noeuds[pointeur];
476: ptr++;
477: }
478:
479: if ((*l_variable_courante).feuille != NULL)
480: {
481: // Il existe au moins une variable statique du nom requis.
482:
483: l_element_courant = (*l_variable_courante).feuille;
484:
485: while(l_element_courant != NULL)
486: {
487: if ((*(*l_element_courant).variable).origine == 'P')
488: {
489: if (((*(*l_element_courant).variable).variable_partagee.adresse
490: == position.adresse) &&
491: ((*(*l_element_courant).variable).origine == origine))
492: {
493: if (pthread_mutex_lock(&((*(*l_element_courant).variable)
494: .mutex)) != 0)
495: {
496: (*s_etat_processus).erreur_systeme = d_es_processus;
497: return(NULL);
498: }
499:
500: if (pthread_mutex_unlock(&((*l_variable_courante)
501: .mutex_feuille)) != 0)
502: {
503: (*s_etat_processus).erreur_systeme = d_es_processus;
504: return(NULL);
505: }
506:
507: (*s_etat_processus).pointeur_variable_partagee_courante
508: = (*l_element_courant).variable;
509: return(l_element_courant);
510: }
511: }
512: else
513: {
514: if (((*(*l_element_courant).variable).variable_partagee.pointeur
515: == position.pointeur) &&
516: ((*(*l_element_courant).variable).origine == origine))
517: {
518: if (pthread_mutex_lock(&((*(*l_element_courant).variable)
519: .mutex)) != 0)
520: {
521: (*s_etat_processus).erreur_systeme = d_es_processus;
522: return(NULL);
523: }
524:
525: if (pthread_mutex_unlock(&((*l_variable_courante)
526: .mutex_feuille)) != 0)
527: {
528: (*s_etat_processus).erreur_systeme = d_es_processus;
529: return(NULL);
530: }
531:
532: (*s_etat_processus).pointeur_variable_partagee_courante
533: = (*l_element_courant).variable;
534: return(l_element_courant);
535: }
536: }
537:
538: l_element_courant = (*l_element_courant).suivant;
539: }
540: }
541:
542: if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
543: {
544: (*s_etat_processus).erreur_systeme = d_es_processus;
545: return(NULL);
546: }
547:
548: (*s_etat_processus).pointeur_variable_statique_courante = NULL;
549: return(NULL);
550: }
551:
552:
553: /*
554: ================================================================================
555: Routine de retrait d'une variable partagée
556: ================================================================================
557: Entrée :
558: --------------------------------------------------------------------------------
559: Sortie :
560: --------------------------------------------------------------------------------
561: Effets de bords : néant
562: ================================================================================
563: */
564:
565: logical1
566: retrait_variable_partagee(struct_processus *s_etat_processus,
567: unsigned char *nom_variable, union_position_variable position)
568: {
569: struct_liste_variables_partagees *l_element_a_supprimer;
570: struct_liste_variables_partagees *l_element_liste_a_supprimer;
571:
572: logical1 erreur;
573:
574: if ((l_element_a_supprimer = recherche_variable_partagee(s_etat_processus,
575: nom_variable, position, ((*s_etat_processus)
576: .mode_execution_programme == 'Y') ? 'P' : 'E')) != NULL)
577: {
578: if (pthread_mutex_lock(&mutex_liste_variables_partagees) != 0)
579: {
580: (*s_etat_processus).erreur_systeme = d_es_processus;
581: return(d_erreur);
582: }
583:
584: // (*s_etat_processus).pointeur_variable_partagee_courante
585: // pointe sur la variable à éliminer. Cette variable est celle qui
586: // est présente dans l'une des feuilles statiques de l'arbre des
587: // variables.
588:
589: l_element_liste_a_supprimer = (*l_element_a_supprimer).reference;
590:
591: // Suppression de la liste des variables statiques
592:
593: if ((*l_element_liste_a_supprimer).precedent != NULL)
594: {
595: // L'élément à supprimer n'est pas le premier de la liste.
596:
597: (*(*l_element_liste_a_supprimer).precedent).suivant =
598: (*l_element_liste_a_supprimer).suivant;
599:
600: if ((*l_element_liste_a_supprimer).suivant != NULL)
601: {
602: // Il y a un élément suivant. On le chaîne.
603: (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
604: }
605: }
606: else
607: {
608: // L'élement est le premier de la liste. S'il y a un élément
609: // suivant, on le chaîne.
610:
611: if ((*l_element_liste_a_supprimer).suivant != NULL)
612: {
613: (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
614: }
615:
616: (*(*s_etat_processus).l_liste_variables_partagees) =
617: (*l_element_liste_a_supprimer).suivant;
618: }
619:
620: free(l_element_liste_a_supprimer);
621:
622: // Suppression depuis la feuille statique. Le champ 'precedent' ne sert
623: // pas car la liste est simplement chaînée.
624:
625: if ((*l_element_a_supprimer).precedent != NULL)
626: {
627: // L'élément n'est pas le premier de la liste.
628:
629: (*(*l_element_a_supprimer).precedent).suivant =
630: (*l_element_a_supprimer).suivant;
631:
632: if ((*l_element_a_supprimer).suivant != NULL)
633: {
634: (*(*l_element_a_supprimer).suivant).precedent =
635: (*l_element_a_supprimer).precedent;
636: }
637: else
638: {
639: (*(*l_element_a_supprimer).precedent).suivant = NULL;
640: }
641: }
642: else
643: {
644: // L'élément est le premier de la liste.
645:
646: if ((*l_element_a_supprimer).suivant != NULL)
647: {
648: (*(*l_element_a_supprimer).suivant).precedent = NULL;
649: }
650:
651: (*(*l_element_a_supprimer).feuille).feuille
652: = (*l_element_a_supprimer).suivant;
653: }
654:
655: liberation(s_etat_processus, (*(*l_element_a_supprimer).variable)
656: .objet);
657: free((*(*l_element_a_supprimer).variable).nom);
658: free((*l_element_a_supprimer).variable);
659: free(l_element_a_supprimer);
660:
661: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
662: {
663: (*s_etat_processus).erreur_systeme = d_es_processus;
664: return(d_erreur);
665: }
666:
667: erreur = d_absence_erreur;
668: }
669: else
670: {
671: erreur = d_erreur;
672: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
673: }
674:
675: return(erreur);
676: }
677:
678:
679: /*
680: ================================================================================
681: Routine de retrait des variables partagées
682: ================================================================================
683: Entrée :
684: --------------------------------------------------------------------------------
685: Sortie :
686: --------------------------------------------------------------------------------
687: Effets de bords : néant
688: ================================================================================
689: */
690:
691: // Cette routine libère toutes les variables partagées de niveau non
692: // nul, donc attachées à une expression et non un programme.
693:
694: logical1
695: retrait_variables_partagees_locales(struct_processus *s_etat_processus)
696: {
697: struct_liste_variables_partagees *l_element_courant;
698: struct_liste_variables_partagees *l_element_suivant;
699:
700: unsigned char registre_mode_execution;
701:
702: if (pthread_mutex_lock(&mutex_liste_variables_partagees) != 0)
703: {
704: (*s_etat_processus).erreur_systeme = d_es_processus;
705: return(d_erreur);
706: }
707:
708: registre_mode_execution = (*s_etat_processus).mode_execution_programme;
709: l_element_courant = (*(*s_etat_processus).l_liste_variables_partagees);
710:
711: while(l_element_courant != NULL)
712: {
713: l_element_suivant = (*l_element_courant).suivant;
714:
715: (*s_etat_processus).mode_execution_programme =
716: ((*(*l_element_courant).variable).origine == 'P') ? 'Y' : 'N';
717:
718: if (((*(*l_element_courant).variable).niveau > 0) &&
719: ((*l_element_courant).pid == getpid()) &&
720: (pthread_equal((*l_element_courant).tid, pthread_self()) != 0))
721: {
722: if (retrait_variable_partagee(s_etat_processus,
723: (*(*l_element_courant).variable).nom,
724: (*(*l_element_courant).variable).variable_partagee)
725: == d_erreur)
726: {
727: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
728: {
729: (*s_etat_processus).erreur_systeme = d_es_processus;
730: return(d_erreur);
731: }
732:
733: (*s_etat_processus).mode_execution_programme =
734: registre_mode_execution;
735: return(d_erreur);
736: }
737: }
738:
739: l_element_courant = l_element_suivant;
740: }
741:
742: (*s_etat_processus).mode_execution_programme = registre_mode_execution;
743:
744: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
745: {
746: (*s_etat_processus).erreur_systeme = d_es_processus;
747: return(d_erreur);
748: }
749:
750: return(d_absence_erreur);
751: }
752:
753:
754: /*
755: ================================================================================
756: Routine de libération de l'arbre des variables partagées
757: ================================================================================
758: Entrée :
759: --------------------------------------------------------------------------------
760: Sortie :
761: --------------------------------------------------------------------------------
762: Effets de bords : positionne le mutex sur la variable partagée
763: ================================================================================
764: */
765:
766: void
767: liberation_arbre_variables_partagees(struct_processus *s_etat_processus,
768: struct_arbre_variables_partagees *arbre)
769: {
770: int i;
771:
772: struct_liste_variables_partagees *l_element_partage_courant;
773: struct_liste_variables_partagees *l_element_partage_suivant;
774:
775: // Libération de l'arbre des variables. Le contenu des variables n'est
776: // pas détruit par cette opération, il sera détruit lors de la libération
777: // de la liste des variables par niveau.
778:
779: if (arbre == NULL)
780: {
781: return;
782: }
783:
784: if (pthread_mutex_lock(&((*arbre).mutex_feuille)) != 0)
785: {
786: (*s_etat_processus).erreur_systeme = d_es_processus;
787: return;
788: }
789:
790: l_element_partage_courant = (*arbre).feuille;
791:
792: while(l_element_partage_courant != NULL)
793: {
794: l_element_partage_suivant = (*l_element_partage_courant).suivant;
795:
796: if (pthread_mutex_lock(&((*(*l_element_partage_courant).variable)
797: .mutex)) != 0)
798: {
799: (*s_etat_processus).erreur_systeme = d_es_processus;
800: return;
801: }
802:
803: free((*(*l_element_partage_courant).variable).nom);
804: liberation(s_etat_processus, (*(*l_element_partage_courant)
805: .variable).objet);
806: free((*l_element_partage_courant).variable);
807:
808: if (pthread_mutex_unlock(&((*(*l_element_partage_courant).variable)
809: .mutex)) != 0)
810: {
811: (*s_etat_processus).erreur_systeme = d_es_processus;
812: return;
813: }
814:
815: if (pthread_mutex_destroy(&((*(*l_element_partage_courant).variable)
816: .mutex)) != 0)
817: {
818: (*s_etat_processus).erreur_systeme = d_es_processus;
819: return;
820: }
821:
822: free(l_element_partage_courant);
823:
824: l_element_partage_courant = l_element_partage_suivant;
825: }
826:
827: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
828: {
829: if ((*arbre).noeuds[i] != NULL)
830: {
831: liberation_arbre_variables_partagees(s_etat_processus,
832: (*arbre).noeuds[i]);
833: (*arbre).noeuds[i] = NULL;
834: }
835: }
836:
837: liberation_tableau_noeuds_partages(s_etat_processus, (*arbre).noeuds);
838: liberation_noeud_partage(s_etat_processus, arbre);
839:
840: if (pthread_mutex_unlock(&((*arbre).mutex_feuille)) != 0)
841: {
842: (*s_etat_processus).erreur_systeme = d_es_processus;
843: return;
844: }
845:
846: if (pthread_mutex_destroy(&((*arbre).mutex_feuille)) != 0)
847: {
848: (*s_etat_processus).erreur_systeme = d_es_processus;
849: return;
850: }
851:
852: arbre = NULL;
853: return;
854: }
855:
856: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>