1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.23
4: Copyright (C) 1989-2015 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: pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille));
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.
460:
461: pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille));
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: {
469: pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille));
470: (*s_etat_processus).erreur_systeme = d_es_processus;
471: return(NULL);
472: }
473:
474: if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
475: {
476: (*s_etat_processus).erreur_systeme = d_es_processus;
477: return(NULL);
478: }
479:
480: l_variable_courante = (*l_variable_courante).noeuds[pointeur];
481: ptr++;
482: }
483:
484: if ((*l_variable_courante).feuille != NULL)
485: {
486: // Il existe au moins une variable partagée du nom requis.
487:
488: l_element_courant = (*l_variable_courante).feuille;
489:
490: while(l_element_courant != NULL)
491: {
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;
544: }
545: }
546:
547: if (pthread_mutex_unlock(&((*l_variable_courante).mutex_feuille)) != 0)
548: {
549: (*s_etat_processus).erreur_systeme = d_es_processus;
550: return(NULL);
551: }
552:
553: (*s_etat_processus).pointeur_variable_statique_courante = NULL;
554: return(NULL);
555: }
556:
557:
558: /*
559: ================================================================================
560: Routine de retrait d'une variable partagée
561: ================================================================================
562: Entrée :
563: --------------------------------------------------------------------------------
564: Sortie :
565: --------------------------------------------------------------------------------
566: Effets de bords : néant
567: ================================================================================
568: */
569:
570: logical1
571: retrait_variable_partagee(struct_processus *s_etat_processus,
572: unsigned char *nom_variable, union_position_variable position)
573: {
574: struct_liste_variables_partagees *l_element_a_supprimer;
575: struct_liste_variables_partagees *l_element_liste_a_supprimer;
576:
577: logical1 erreur;
578:
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)
582: {
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: }
588:
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.
593:
594: l_element_liste_a_supprimer = (*l_element_a_supprimer).reference;
595:
596: // Suppression de la liste des variables statiques
597:
598: if ((*l_element_liste_a_supprimer).precedent != NULL)
599: {
600: // L'élément à supprimer n'est pas le premier de la liste.
601:
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)
606: {
607: // Il y a un élément suivant. On le chaîne.
608: (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
609: }
610: }
611: else
612: {
613: // L'élement est le premier de la liste. S'il y a un élément
614: // suivant, on le chaîne.
615:
616: if ((*l_element_liste_a_supprimer).suivant != NULL)
617: {
618: (*(*l_element_liste_a_supprimer).suivant).precedent = NULL;
619: }
620:
621: (*(*s_etat_processus).l_liste_variables_partagees) =
622: (*l_element_liste_a_supprimer).suivant;
623: }
624:
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.
629:
630: if ((*l_element_a_supprimer).precedent != NULL)
631: {
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)
638: {
639: (*(*l_element_a_supprimer).suivant).precedent =
640: (*l_element_a_supprimer).precedent;
641: }
642: else
643: {
644: (*(*l_element_a_supprimer).precedent).suivant = NULL;
645: }
646: }
647: else
648: {
649: // L'élément est le premier de la liste.
650:
651: if ((*l_element_a_supprimer).suivant != NULL)
652: {
653: (*(*l_element_a_supprimer).suivant).precedent = NULL;
654: }
655:
656: (*(*l_element_a_supprimer).feuille).feuille
657: = (*l_element_a_supprimer).suivant;
658: }
659:
660: liberation(s_etat_processus, (*(*l_element_a_supprimer).variable)
661: .objet);
662: free((*(*l_element_a_supprimer).variable).nom);
663: pthread_mutex_unlock(&((*(*l_element_a_supprimer).variable).mutex));
664: pthread_mutex_destroy(&((*(*l_element_a_supprimer).variable).mutex));
665: free((*l_element_a_supprimer).variable);
666: free(l_element_a_supprimer);
667:
668: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
669: {
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.
700:
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: }
714:
715: registre_mode_execution = (*s_etat_processus).mode_execution_programme;
716: l_element_courant = (*(*s_etat_processus).l_liste_variables_partagees);
717:
718: while(l_element_courant != NULL)
719: {
720: l_element_suivant = (*l_element_courant).suivant;
721:
722: (*s_etat_processus).mode_execution_programme =
723: ((*(*l_element_courant).variable).origine == 'P') ? 'Y' : 'N';
724:
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)
733: {
734: if (pthread_mutex_unlock(&mutex_liste_variables_partagees) != 0)
735: {
736: (*s_etat_processus).erreur_systeme = d_es_processus;
737: return(d_erreur);
738: }
739:
740: (*s_etat_processus).mode_execution_programme =
741: registre_mode_execution;
742: return(d_erreur);
743: }
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;
778:
779: struct_liste_variables_partagees *l_element_partage_courant;
780: struct_liste_variables_partagees *l_element_partage_suivant;
781:
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);
814:
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: }
821:
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;
827: }
828:
829: free(l_element_partage_courant);
830:
831: l_element_partage_courant = l_element_partage_suivant;
832: }
833:
834: for(i = 0; i < (*s_etat_processus).nombre_caracteres_variables; i++)
835: {
836: if ((*arbre).noeuds[i] != NULL)
837: {
838: liberation_arbre_variables_partagees(s_etat_processus,
839: (*arbre).noeuds[i]);
840: (*arbre).noeuds[i] = NULL;
841: }
842: }
843:
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;
861: }
862:
863: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>