1: #define DEBUG_RETURN
2: #define DEBUG_ERREURS
3:
4: /*
5: ================================================================================
6: RPL/2 (R) version 4.1.22
7: Copyright (C) 1989-2015 Dr. BERTRAND Joël
8:
9: This file is part of RPL/2.
10:
11: RPL/2 is free software; you can redistribute it and/or modify it
12: under the terms of the CeCILL V2 License as published by the french
13: CEA, CNRS and INRIA.
14:
15: RPL/2 is distributed in the hope that it will be useful, but WITHOUT
16: ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17: FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License
18: for more details.
19:
20: You should have received a copy of the CeCILL License
21: along with RPL/2. If not, write to info@cecill.info.
22: ================================================================================
23: */
24:
25:
26: #include "rpl-conv.h"
27:
28:
29: /*
30: ================================================================================
31: Fonction 'DFT'
32: ================================================================================
33: Entrées : structure processus
34: --------------------------------------------------------------------------------
35: Sorties :
36: --------------------------------------------------------------------------------
37: Effets de bord : néant
38: ================================================================================
39: */
40:
41: void
42: instruction_dft(struct_processus *s_etat_processus)
43: {
44: integer4 erreur;
45: integer4 inverse;
46: integer4 longueur_dft;
47: integer4 nombre_colonnes;
48: integer4 nombre_lignes;
49:
50: logical1 presence_longueur_dft;
51:
52: integer8 longueur_dft_signee;
53:
54: struct_complexe16 *matrice_f77;
55:
56: struct_objet *s_objet_argument;
57: struct_objet *s_objet_longueur_dft;
58: struct_objet *s_objet_resultat;
59:
60: integer8 i;
61: integer8 j;
62: integer8 k;
63:
64: (*s_etat_processus).erreur_execution = d_ex;
65:
66: if ((*s_etat_processus).affichage_arguments == 'Y')
67: {
68: printf("\n DFT ");
69:
70: if ((*s_etat_processus).langue == 'F')
71: {
72: printf("(transformée de Fourier discrète)\n\n");
73: }
74: else
75: {
76: printf("(discrete Fourier transform)\n\n");
77: }
78:
79: printf(" 1: %s, %s, %s\n", d_VIN, d_VRL, d_VCX);
80: printf("-> 1: %s\n\n", d_VCX);
81:
82: printf(" 2: %s, %s, %s\n", d_VIN, d_VRL, d_VCX);
83: printf(" 1: %s\n", d_INT);
84: printf("-> 1: %s\n\n", d_VCX);
85:
86: printf(" 1: %s, %s, %s\n", d_MIN, d_MRL, d_MCX);
87: printf("-> 1: %s\n\n", d_VCX);
88:
89: printf(" 2: %s, %s, %s\n", d_MIN, d_MRL, d_MCX);
90: printf(" 1: %s\n", d_INT);
91: printf("-> 1: %s\n", d_MCX);
92:
93: return;
94: }
95: else if ((*s_etat_processus).test_instruction == 'Y')
96: {
97: (*s_etat_processus).nombre_arguments = -1;
98: return;
99: }
100:
101: /*
102: * Il est possible d'imposer une longueur de DFT au premier niveau
103: * de la pile.
104: */
105:
106: if ((*s_etat_processus).l_base_pile == NULL)
107: {
108: (*s_etat_processus).erreur_execution = d_ex_manque_argument;
109: return;
110: }
111:
112: if ((*(*(*s_etat_processus).l_base_pile).donnee).type == INT)
113: {
114: presence_longueur_dft = d_vrai;
115:
116: if (test_cfsf(s_etat_processus, 31) == d_vrai)
117: {
118: if (empilement_pile_last(s_etat_processus, 2) == d_erreur)
119: {
120: return;
121: }
122: }
123:
124: if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
125: &s_objet_longueur_dft) == d_erreur)
126: {
127: (*s_etat_processus).erreur_execution = d_ex_manque_argument;
128: return;
129: }
130:
131: longueur_dft_signee = (*((integer8 *) (*s_objet_longueur_dft).objet));
132:
133: liberation(s_etat_processus, s_objet_longueur_dft);
134:
135: if (longueur_dft_signee <= 0)
136: {
137: (*s_etat_processus).erreur_execution = d_ex_longueur_dft;
138: return;
139: }
140:
141: longueur_dft = (integer4) longueur_dft_signee;
142: }
143: else
144: {
145: presence_longueur_dft = d_faux;
146: longueur_dft = 0;
147:
148: if (test_cfsf(s_etat_processus, 31) == d_vrai)
149: {
150: if (empilement_pile_last(s_etat_processus, 1) == d_erreur)
151: {
152: return;
153: }
154: }
155: }
156:
157: if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
158: &s_objet_argument) == d_erreur)
159: {
160: (*s_etat_processus).erreur_execution = d_ex_manque_argument;
161: return;
162: }
163:
164: /*
165: --------------------------------------------------------------------------------
166: Vecteur
167: --------------------------------------------------------------------------------
168: */
169:
170: if (((*s_objet_argument).type == VIN) ||
171: ((*s_objet_argument).type == VRL) ||
172: ((*s_objet_argument).type == VCX))
173: {
174: if (presence_longueur_dft == d_faux)
175: {
176: longueur_dft = (integer4) (*((struct_vecteur *)
177: (*s_objet_argument).objet)).taille;
178: }
179:
180: if ((matrice_f77 = malloc(((size_t) longueur_dft) *
181: sizeof(struct_complexe16))) == NULL)
182: {
183: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
184: return;
185: }
186:
187: if ((*s_objet_argument).type == VIN)
188: {
189: for(i = 0; i < (*((struct_vecteur *) (*s_objet_argument).objet))
190: .taille; i++)
191: {
192: matrice_f77[i].partie_reelle = (real8) ((integer8 *)
193: (*((struct_vecteur *) (*s_objet_argument).objet))
194: .tableau)[i];
195: matrice_f77[i].partie_imaginaire = (real8) 0;
196: }
197: }
198: else if ((*s_objet_argument).type == VRL)
199: {
200: for(i = 0; i < (*((struct_vecteur *) (*s_objet_argument).objet))
201: .taille; i++)
202: {
203: matrice_f77[i].partie_reelle = ((real8 *)
204: (*((struct_vecteur *) (*s_objet_argument).objet))
205: .tableau)[i];
206: matrice_f77[i].partie_imaginaire = (real8) 0;
207: }
208: }
209: else
210: {
211: for(i = 0; i < (*((struct_vecteur *) (*s_objet_argument).objet))
212: .taille; i++)
213: {
214: matrice_f77[i].partie_reelle = ((struct_complexe16 *)
215: (*((struct_vecteur *) (*s_objet_argument).objet))
216: .tableau)[i].partie_reelle;
217: matrice_f77[i].partie_imaginaire = ((struct_complexe16 *)
218: (*((struct_vecteur *) (*s_objet_argument).objet))
219: .tableau)[i].partie_imaginaire;
220: }
221: }
222:
223: for(; i < longueur_dft; i++)
224: {
225: matrice_f77[i].partie_reelle = (real8) 0;
226: matrice_f77[i].partie_imaginaire = (real8) 0;
227: }
228:
229: nombre_lignes = 1;
230: nombre_colonnes = longueur_dft;
231: inverse = 0;
232:
233: dft(matrice_f77, &nombre_lignes, &nombre_colonnes, &inverse, &erreur);
234:
235: if (erreur != 0)
236: {
237: liberation(s_etat_processus, s_objet_argument);
238: free(matrice_f77);
239:
240: (*s_etat_processus).erreur_execution = d_ex_longueur_dft;
241: return;
242: }
243:
244: if ((s_objet_resultat = allocation(s_etat_processus, VCX)) == NULL)
245: {
246: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
247: return;
248: }
249:
250: (*((struct_vecteur *) (*s_objet_resultat).objet)).taille = longueur_dft;
251: (*((struct_vecteur *) (*s_objet_resultat).objet)).tableau = matrice_f77;
252: }
253:
254: /*
255: --------------------------------------------------------------------------------
256: Matrice
257: --------------------------------------------------------------------------------
258: */
259:
260: else if (((*s_objet_argument).type == MIN) ||
261: ((*s_objet_argument).type == MRL) ||
262: ((*s_objet_argument).type == MCX))
263: {
264: if (presence_longueur_dft == d_faux)
265: {
266: longueur_dft = (integer4) (*((struct_matrice *)
267: (*s_objet_argument).objet)).nombre_colonnes;
268: }
269:
270: if ((matrice_f77 = malloc(((size_t) longueur_dft) * ((size_t)
271: (*((struct_matrice *) (*s_objet_argument).objet))
272: .nombre_lignes) * sizeof(struct_complexe16))) == NULL)
273: {
274: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
275: return;
276: }
277:
278: if ((*s_objet_argument).type == MIN)
279: {
280: for(k = 0, j = 0; j < (*((struct_matrice *) (*s_objet_argument)
281: .objet)).nombre_lignes; j++)
282: {
283: for(i = 0; i < (*((struct_matrice *) (*s_objet_argument)
284: .objet)).nombre_colonnes; i++)
285: {
286: matrice_f77[k].partie_reelle = (real8) ((integer8 **)
287: (*((struct_matrice *) (*s_objet_argument).objet))
288: .tableau)[j][i];
289: matrice_f77[k++].partie_imaginaire = (real8) 0;
290: }
291: }
292:
293: for(; k < longueur_dft * (*((struct_matrice *) (*s_objet_argument)
294: .objet)).nombre_lignes; k++)
295: {
296: matrice_f77[k].partie_reelle = (real8) 0;
297: matrice_f77[k].partie_imaginaire = (real8) 0;
298: }
299: }
300: else if ((*s_objet_argument).type == MRL)
301: {
302: for(k = 0, j = 0; j < (*((struct_matrice *) (*s_objet_argument)
303: .objet)).nombre_lignes; j++)
304: {
305: for(i = 0; i < (*((struct_matrice *) (*s_objet_argument)
306: .objet)).nombre_colonnes; i++)
307: {
308: matrice_f77[k].partie_reelle = ((real8 **)
309: (*((struct_matrice *) (*s_objet_argument).objet))
310: .tableau)[j][i];
311: matrice_f77[k++].partie_imaginaire = (real8) 0;
312: }
313: }
314:
315: for(; k < longueur_dft * (*((struct_matrice *) (*s_objet_argument)
316: .objet)).nombre_lignes; k++)
317: {
318: matrice_f77[k].partie_reelle = (real8) 0;
319: matrice_f77[k].partie_imaginaire = (real8) 0;
320: }
321: }
322: else
323: {
324: for(k = 0, j = 0; j < (*((struct_matrice *) (*s_objet_argument)
325: .objet)).nombre_lignes; j++)
326: {
327: for(i = 0; i < (*((struct_matrice *) (*s_objet_argument)
328: .objet)).nombre_colonnes; i++)
329: {
330: matrice_f77[k].partie_reelle = ((struct_complexe16 **)
331: (*((struct_matrice *) (*s_objet_argument).objet))
332: .tableau)[j][i].partie_reelle;
333: matrice_f77[k++].partie_imaginaire =
334: ((struct_complexe16 **) (*((struct_matrice *)
335: (*s_objet_argument).objet)).tableau)[j][i]
336: .partie_imaginaire;
337: }
338: }
339:
340: for(; k < longueur_dft * (*((struct_matrice *) (*s_objet_argument)
341: .objet)).nombre_lignes; k++)
342: {
343: matrice_f77[k].partie_reelle = (real8) 0;
344: matrice_f77[k].partie_imaginaire = (real8) 0;
345: }
346: }
347:
348: nombre_lignes = (integer4) (*((struct_matrice *) (*s_objet_argument)
349: .objet)).nombre_lignes;
350: nombre_colonnes = longueur_dft;
351: inverse = 0;
352:
353: dft(matrice_f77, &nombre_lignes, &nombre_colonnes, &inverse, &erreur);
354:
355: if (erreur != 0)
356: {
357: liberation(s_etat_processus, s_objet_argument);
358: free(matrice_f77);
359:
360: (*s_etat_processus).erreur_execution = d_ex_longueur_dft;
361: return;
362: }
363:
364: if ((s_objet_resultat = allocation(s_etat_processus, MCX)) == NULL)
365: {
366: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
367: return;
368: }
369:
370: (*((struct_matrice *) (*s_objet_resultat).objet)).nombre_lignes =
371: (*((struct_matrice *) (*s_objet_argument).objet))
372: .nombre_lignes;
373: (*((struct_matrice *) (*s_objet_resultat).objet)).nombre_colonnes =
374: longueur_dft;
375:
376: if (((*((struct_matrice *) (*s_objet_resultat).objet)).tableau =
377: malloc(((size_t) (*((struct_matrice *) (*s_objet_resultat)
378: .objet)).nombre_lignes) * sizeof(struct_complexe16 *))) == NULL)
379: {
380: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
381: return;
382: }
383:
384: for(i = 0; i < (*((struct_matrice *) (*s_objet_resultat).objet))
385: .nombre_lignes; i++)
386: {
387: if ((((struct_complexe16 **) (*((struct_matrice *)
388: (*s_objet_resultat).objet)).tableau)[i] =
389: malloc(((size_t) (*((struct_matrice *)
390: (*s_objet_resultat).objet)).nombre_colonnes) *
391: sizeof(struct_complexe16))) == NULL)
392: {
393: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
394: return;
395: }
396: }
397:
398: for(k = 0, j = 0; j < (*((struct_matrice *) (*s_objet_resultat).objet))
399: .nombre_lignes; j++)
400: {
401: for(i = 0; i < (*((struct_matrice *) (*s_objet_resultat).objet))
402: .nombre_colonnes; i++)
403: {
404: ((struct_complexe16 **) (*((struct_matrice *)
405: (*s_objet_resultat).objet)).tableau)[j][i]
406: .partie_reelle = matrice_f77[k].partie_reelle;
407: ((struct_complexe16 **) (*((struct_matrice *)
408: (*s_objet_resultat).objet)).tableau)[j][i]
409: .partie_imaginaire = matrice_f77[k++].partie_imaginaire;
410: }
411: }
412:
413: free(matrice_f77);
414: }
415:
416: /*
417: --------------------------------------------------------------------------------
418: Calcul de DFT impossible
419: --------------------------------------------------------------------------------
420: */
421:
422: else
423: {
424: liberation(s_etat_processus, s_objet_argument);
425:
426: (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
427: return;
428: }
429:
430: liberation(s_etat_processus, s_objet_argument);
431:
432: if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
433: s_objet_resultat) == d_erreur)
434: {
435: return;
436: }
437:
438: return;
439: }
440:
441:
442: /*
443: ================================================================================
444: Fonction 'DER'
445: ================================================================================
446: Entrées : structure processus
447: --------------------------------------------------------------------------------
448: Sorties :
449: --------------------------------------------------------------------------------
450: Effets de bord : néant
451: ================================================================================
452: */
453:
454: void
455: instruction_der(struct_processus *s_etat_processus)
456: {
457: logical1 expression_rpn;
458: logical1 last_valide;
459:
460: struct_liste_chainee *l_element_courant;
461: struct_liste_chainee *l_element_precedent;
462:
463: struct_objet *s_copie_argument_2;
464: struct_objet *s_objet_argument_1;
465: struct_objet *s_objet_argument_2;
466: struct_objet *s_objet_resultat;
467: struct_objet *s_objet_simplifie;
468:
469: (*s_etat_processus).erreur_execution = d_ex;
470:
471: if ((*s_etat_processus).affichage_arguments == 'Y')
472: {
473: printf("\n DER ");
474:
475: if ((*s_etat_processus).langue == 'F')
476: {
477: printf("(dérivation)\n\n");
478: }
479: else
480: {
481: printf("(derivation)\n\n");
482: }
483:
484: printf(" 2: %s, %s, %s, %s\n", d_INT, d_REL, d_CPL, d_NOM);
485: printf(" 1: %s\n", d_NOM);
486: printf("-> 1: %s\n\n", d_INT);
487:
488: printf(" 2: %s, %s\n", d_RPN, d_ALG);
489: printf(" 1: %s\n", d_NOM);
490: printf("-> 1: %s, %s\n", d_RPN, d_ALG);
491:
492: return;
493: }
494: else if ((*s_etat_processus).test_instruction == 'Y')
495: {
496: (*s_etat_processus).nombre_arguments = 2;
497: return;
498: }
499:
500: if ((last_valide = test_cfsf(s_etat_processus, 31)) == d_vrai)
501: {
502: if (empilement_pile_last(s_etat_processus, 2) == d_erreur)
503: {
504: return;
505: }
506: }
507:
508: if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
509: &s_objet_argument_1) == d_erreur)
510: {
511: (*s_etat_processus).erreur_execution = d_ex_manque_argument;
512: return;
513: }
514:
515: if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
516: &s_objet_argument_2) == d_erreur)
517: {
518: liberation(s_etat_processus, s_objet_argument_1);
519:
520: (*s_etat_processus).erreur_execution = d_ex_manque_argument;
521: return;
522: }
523:
524: expression_rpn = d_faux;
525:
526: /*
527: * Dérivation d'une expression
528: */
529:
530: if (((*s_objet_argument_1).type == NOM) &&
531: (((*s_objet_argument_2).type == RPN) ||
532: ((*s_objet_argument_2).type == ALG)))
533: {
534: if ((s_copie_argument_2 = copie_objet(s_etat_processus,
535: s_objet_argument_2, 'N')) == NULL)
536: {
537: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
538: return;
539: }
540:
541: if ((*s_copie_argument_2).type == RPN)
542: {
543: expression_rpn = d_vrai;
544: }
545:
546: l_element_courant = (struct_liste_chainee *)
547: (*s_copie_argument_2).objet;
548: l_element_precedent = l_element_courant;
549:
550: while((*l_element_courant).suivant != NULL)
551: {
552: l_element_precedent = l_element_courant;
553: l_element_courant = (*l_element_courant).suivant;
554: }
555:
556: if (((*l_element_precedent).suivant =
557: allocation_maillon(s_etat_processus)) == NULL)
558: {
559: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
560: return;
561: }
562:
563: (*(*l_element_precedent).suivant).donnee = s_objet_argument_1;
564: l_element_precedent = (*l_element_precedent).suivant;
565:
566: if (((*l_element_precedent).suivant =
567: allocation_maillon(s_etat_processus)) == NULL)
568: {
569: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
570: return;
571: }
572:
573: if (((*(*l_element_precedent).suivant).donnee =
574: allocation(s_etat_processus, FCT)) == NULL)
575: {
576: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
577: return;
578: }
579:
580: (*((struct_fonction *) (*(*(*l_element_precedent).suivant)
581: .donnee).objet)).nombre_arguments = 2;
582: (*((struct_fonction *) (*(*(*l_element_precedent).suivant)
583: .donnee).objet)).fonction = instruction_der;
584:
585: if (((*((struct_fonction *) (*(*(*l_element_precedent)
586: .suivant).donnee).objet)).nom_fonction =
587: malloc(4 * sizeof(unsigned char))) == NULL)
588: {
589: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
590: return;
591: }
592:
593: strcpy((*((struct_fonction *) (*(*(*l_element_precedent)
594: .suivant).donnee).objet)).nom_fonction, "DER");
595:
596: (*(*l_element_precedent).suivant).suivant = l_element_courant;
597:
598: s_objet_resultat = s_copie_argument_2;
599: s_objet_argument_1 = NULL;
600: }
601:
602: /*
603: * Dérivation d'un nom ou d'une constante
604: */
605:
606: else if (((*s_objet_argument_1).type == NOM) &&
607: (((*s_objet_argument_2).type == NOM) ||
608: ((*s_objet_argument_2).type == INT) ||
609: ((*s_objet_argument_2).type == REL) ||
610: ((*s_objet_argument_2).type == CPL)))
611: {
612: if ((s_objet_resultat = allocation(s_etat_processus, ALG)) == NULL)
613: {
614: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
615: return;
616: }
617:
618: if (((*s_objet_resultat).objet =
619: allocation_maillon(s_etat_processus)) == NULL)
620: {
621: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
622: return;
623: }
624:
625: l_element_courant = (*s_objet_resultat).objet;
626:
627: if (((*l_element_courant).donnee = allocation(s_etat_processus, FCT))
628: == NULL)
629: {
630: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
631: return;
632: }
633:
634: (*((struct_fonction *) (*(*l_element_courant).donnee).objet))
635: .nombre_arguments = 0;
636: (*((struct_fonction *) (*(*l_element_courant).donnee).objet))
637: .fonction = instruction_vers_niveau_superieur;
638:
639: if (((*((struct_fonction *) (*(*l_element_courant).donnee).objet))
640: .nom_fonction = malloc(3 * sizeof(unsigned char))) == NULL)
641: {
642: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
643: return;
644: }
645:
646: strcpy((*((struct_fonction *) (*(*l_element_courant).donnee).objet))
647: .nom_fonction, "<<");
648:
649: if (((*l_element_courant).suivant =
650: allocation_maillon(s_etat_processus)) == NULL)
651: {
652: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
653: return;
654: }
655:
656: l_element_courant = (*l_element_courant).suivant;
657: (*l_element_courant).donnee = s_objet_argument_2;
658:
659: if (((*l_element_courant).suivant =
660: allocation_maillon(s_etat_processus)) == NULL)
661: {
662: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
663: return;
664: }
665:
666: l_element_courant = (*l_element_courant).suivant;
667: (*l_element_courant).donnee = s_objet_argument_1;
668:
669: if (((*l_element_courant).suivant =
670: allocation_maillon(s_etat_processus)) == NULL)
671: {
672: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
673: return;
674: }
675:
676: l_element_courant = (*l_element_courant).suivant;
677:
678: if (((*l_element_courant).donnee = allocation(s_etat_processus, FCT))
679: == NULL)
680: {
681: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
682: return;
683: }
684:
685: (*((struct_fonction *) (*(*l_element_courant).donnee).objet))
686: .nombre_arguments = 2;
687: (*((struct_fonction *) (*(*l_element_courant).donnee).objet))
688: .fonction = instruction_der;
689:
690: if (((*((struct_fonction *) (*(*l_element_courant).donnee).objet))
691: .nom_fonction = malloc(4 * sizeof(unsigned char))) == NULL)
692: {
693: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
694: return;
695: }
696:
697: strcpy((*((struct_fonction *) (*(*l_element_courant).donnee).objet))
698: .nom_fonction, "DER");
699:
700: if (((*l_element_courant).suivant =
701: allocation_maillon(s_etat_processus)) == NULL)
702: {
703: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
704: return;
705: }
706:
707: l_element_courant = (*l_element_courant).suivant;
708:
709: if (((*l_element_courant).donnee = allocation(s_etat_processus, FCT))
710: == NULL)
711: {
712: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
713: return;
714: }
715:
716: (*((struct_fonction *) (*(*l_element_courant).donnee).objet))
717: .nombre_arguments = 0;
718: (*((struct_fonction *) (*(*l_element_courant).donnee).objet))
719: .fonction = instruction_vers_niveau_inferieur;
720:
721: if (((*((struct_fonction *) (*(*l_element_courant).donnee).objet))
722: .nom_fonction = malloc(3 * sizeof(unsigned char))) == NULL)
723: {
724: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
725: return;
726: }
727:
728: strcpy((*((struct_fonction *) (*(*l_element_courant).donnee).objet))
729: .nom_fonction, ">>");
730:
731: (*l_element_courant).suivant = NULL;
732:
733: s_objet_argument_1 = NULL;
734: s_objet_argument_2 = NULL;
735: }
736:
737: /*
738: * Dérivation impossible
739: */
740:
741: else
742: {
743: liberation(s_etat_processus, s_objet_argument_1);
744: liberation(s_etat_processus, s_objet_argument_2);
745:
746: (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
747: return;
748: }
749:
750: liberation(s_etat_processus, s_objet_argument_1);
751: liberation(s_etat_processus, s_objet_argument_2);
752:
753: if (expression_rpn == d_faux)
754: {
755: if (last_valide == d_vrai)
756: {
757: cf(s_etat_processus, 31);
758: }
759:
760: derivation(s_etat_processus, &s_objet_resultat);
761:
762: if (last_valide == d_vrai)
763: {
764: sf(s_etat_processus, 31);
765: }
766:
767: if (((*s_etat_processus).var_volatile_requete_arret == 0) &&
768: (s_objet_resultat != NULL))
769: {
770: if ((s_objet_simplifie = simplification(s_etat_processus,
771: s_objet_resultat)) == NULL)
772: {
773: liberation(s_etat_processus, s_objet_resultat);
774: return;
775: }
776:
777: liberation(s_etat_processus, s_objet_resultat);
778:
779: if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
780: s_objet_simplifie) == d_erreur)
781: {
782: return;
783: }
784: }
785: else
786: {
787: if (s_objet_resultat != NULL)
788: {
789: liberation(s_etat_processus, s_objet_resultat);
790: }
791: }
792: }
793: else
794: {
795: if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
796: s_objet_resultat) == d_erreur)
797: {
798: return;
799: }
800: }
801:
802: return;
803: }
804:
805:
806: /*
807: ================================================================================
808: Fonction 'DETACH'
809: ================================================================================
810: Entrées : structure processus
811: --------------------------------------------------------------------------------
812: Sorties :
813: --------------------------------------------------------------------------------
814: Effets de bord : néant
815: ================================================================================
816: */
817:
818: void
819: instruction_detach(struct_processus *s_etat_processus)
820: {
821: int pipe_initialisation_segment_signaux[2];
822:
823: logical1 drapeau;
824:
825: pid_t ppid;
826:
827: pthread_attr_t attributs;
828:
829: pthread_mutexattr_t attributs_mutex;
830:
831: pthread_t thread_surveillance;
832:
833: sig_atomic_t registre_stop;
834:
835: ssize_t longueur_ecriture;
836:
837: struct_descripteur_thread *s_argument_thread;
838: struct_descripteur_thread *s_argument_thread2;
839:
840: struct_liste_chainee *l_element_courant;
841: struct_liste_chainee *l_element_precedent;
842: struct_liste_chainee *l_element_suivant;
843:
844: struct_liste_variables_partagees *l_element_partage_courant;
845: struct_liste_variables_partagees *l_element_partage_suivant;
846:
847: struct_liste_variables_statiques *l_element_statique_courant;
848: struct_liste_variables_statiques *l_element_statique_suivant;
849:
850: struct_objet *s_copie;
851: struct_objet *s_objet;
852: struct_objet *s_objet_systeme;
853: struct_objet *s_objet_temporaire;
854:
855: struct sigaction action;
856: struct sigaction registre;
857:
858: struct timespec attente;
859:
860: unsigned char caractere;
861: unsigned char *message;
862:
863: unsigned int erreur;
864:
865: integer8 i;
866:
867: volatile logical1 variable_partagee;
868:
869: (*s_etat_processus).erreur_execution = d_ex;
870:
871: attente.tv_sec = 0;
872: attente.tv_nsec = GRANULARITE_us * 1000;
873: s_copie = NULL;
874:
875: if ((*s_etat_processus).affichage_arguments == 'Y')
876: {
877: printf("\n DETACH ");
878:
879: if ((*s_etat_processus).langue == 'F')
880: {
881: printf("(détachement d'un processus)\n\n");
882: }
883: else
884: {
885: printf("(fork)\n\n");
886: }
887:
888: printf(" 1: %s, %s\n", d_NOM, d_RPN);
889: printf("-> 1: %s\n", d_PRC);
890:
891: return;
892: }
893: else if ((*s_etat_processus).test_instruction == 'Y')
894: {
895: (*s_etat_processus).nombre_arguments = -1;
896: return;
897: }
898:
899: if (test_cfsf(s_etat_processus, 31) == d_vrai)
900: {
901: if (empilement_pile_last(s_etat_processus, 1) == d_erreur)
902: {
903: return;
904: }
905: }
906:
907: if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
908: &s_objet) == d_erreur)
909: {
910: (*s_etat_processus).erreur_execution = d_ex_manque_argument;
911: return;
912: }
913:
914: /*
915: * Une routine fille doit pouvoir renvoyer des objets au processus
916: * père au travers de la fonction SEND. Il ne peut donc s'agir que
917: * d'une fonction ou d'une expression RPN.
918: */
919:
920: if (((*s_objet).type != NOM) && ((*s_objet).type != RPN))
921: {
922: liberation(s_etat_processus, s_objet);
923:
924: (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
925: return;
926: }
927:
928: /*
929: * Si l'argument est de type NOM, il faut que la variable correspondante
930: * soit une variable de type RPN.
931: */
932:
933: variable_partagee = d_faux;
934:
935: if ((*s_objet).type == NOM)
936: {
937: if (recherche_variable(s_etat_processus, (*((struct_nom *)
938: (*s_objet).objet)).nom) == d_vrai)
939: {
940: if ((*(*s_etat_processus).pointeur_variable_courante).objet
941: == NULL)
942: {
943: if (recherche_variable_partagee(s_etat_processus,
944: (*(*s_etat_processus).pointeur_variable_courante).nom,
945: (*(*s_etat_processus).pointeur_variable_courante)
946: .variable_partagee, (*(*s_etat_processus)
947: .pointeur_variable_courante).origine) == NULL)
948: {
949: liberation(s_etat_processus, s_objet);
950:
951: (*s_etat_processus).erreur_systeme = d_es;
952: (*s_etat_processus).erreur_execution =
953: d_ex_argument_invalide;
954: return;
955: }
956:
957: if (((*(*(*s_etat_processus)
958: .pointeur_variable_partagee_courante).objet).type
959: == RPN) && ((*(*(*s_etat_processus)
960: .pointeur_variable_partagee_courante).objet).type
961: == ADR))
962: {
963: if (pthread_mutex_unlock(&((*(*s_etat_processus)
964: .pointeur_variable_partagee_courante).mutex)) != 0)
965: {
966: (*s_etat_processus).erreur_systeme = d_es_processus;
967: return;
968: }
969:
970: liberation(s_etat_processus, s_objet);
971:
972: (*s_etat_processus).erreur_execution =
973: d_ex_argument_invalide;
974: return;
975: }
976:
977: if ((s_copie = copie_objet(s_etat_processus,
978: (*(*s_etat_processus)
979: .pointeur_variable_partagee_courante).objet, 'P'))
980: == NULL)
981: {
982: if (pthread_mutex_unlock(&((*(*s_etat_processus)
983: .pointeur_variable_partagee_courante).mutex)) != 0)
984: {
985: (*s_etat_processus).erreur_systeme = d_es_processus;
986: return;
987: }
988:
989: (*s_etat_processus).erreur_systeme =
990: d_es_allocation_memoire;
991:
992: return;
993: }
994:
995: variable_partagee = d_vrai;
996:
997: if (pthread_mutex_unlock(&((*(*s_etat_processus)
998: .pointeur_variable_partagee_courante).mutex)) != 0)
999: {
1000: (*s_etat_processus).erreur_systeme = d_es_processus;
1001: return;
1002: }
1003: }
1004: else
1005: {
1006: if (((*(*(*s_etat_processus).pointeur_variable_courante).objet)
1007: .type != RPN) && ((*(*(*s_etat_processus)
1008: .pointeur_variable_courante).objet).type != ADR))
1009: {
1010: liberation(s_etat_processus, s_objet);
1011:
1012: (*s_etat_processus).erreur_execution =
1013: d_ex_argument_invalide;
1014: return;
1015: }
1016: }
1017: }
1018: else // Variable inexistante
1019: {
1020: liberation(s_etat_processus, s_objet);
1021:
1022: (*s_etat_processus).erreur_systeme = d_es;
1023: (*s_etat_processus).erreur_execution = d_ex_argument_invalide;
1024: return;
1025: }
1026: }
1027:
1028: if ((s_argument_thread = malloc(sizeof(struct_descripteur_thread))) == NULL)
1029: {
1030: (*s_etat_processus).erreur_systeme = d_es_processus;
1031: return;
1032: }
1033:
1034: if (pipe((*s_argument_thread).pipe_erreurs) != 0)
1035: {
1036: (*s_etat_processus).erreur_systeme = d_es_processus;
1037: return;
1038: }
1039:
1040: if (pipe((*s_argument_thread).pipe_interruptions) != 0)
1041: {
1042: (*s_etat_processus).erreur_systeme = d_es_processus;
1043: return;
1044: }
1045:
1046: if (pipe((*s_argument_thread).pipe_nombre_elements_attente) != 0)
1047: {
1048: (*s_etat_processus).erreur_systeme = d_es_processus;
1049: return;
1050: }
1051:
1052: if (pipe((*s_argument_thread).pipe_objets) != 0)
1053: {
1054: (*s_etat_processus).erreur_systeme = d_es_processus;
1055: return;
1056: }
1057:
1058: if (pipe((*s_argument_thread).pipe_acquittement) != 0)
1059: {
1060: (*s_etat_processus).erreur_systeme = d_es_processus;
1061: return;
1062: }
1063:
1064: if (pipe((*s_argument_thread).pipe_injections) != 0)
1065: {
1066: (*s_etat_processus).erreur_systeme = d_es_processus;
1067: return;
1068: }
1069:
1070: if (pipe((*s_argument_thread).pipe_nombre_injections) != 0)
1071: {
1072: (*s_etat_processus).erreur_systeme = d_es_processus;
1073: return;
1074: }
1075:
1076: if (pipe(pipe_initialisation_segment_signaux) != 0)
1077: {
1078: (*s_etat_processus).erreur_systeme = d_es_processus;
1079: return;
1080: }
1081:
1082: ppid = getpid();
1083:
1084: /*
1085: * Le mutex suivant permet de copier un contexte propre.
1086: */
1087:
1088: if (pthread_mutex_lock(&((*s_etat_processus).mutex_pile_processus)) != 0)
1089: {
1090: (*s_etat_processus).erreur_systeme = d_es_processus;
1091: return;
1092: }
1093:
1094: if (pthread_mutex_lock(&((*s_etat_processus).mutex_allocation_buffer)) != 0)
1095: {
1096: (*s_etat_processus).erreur_systeme = d_es_processus;
1097: return;
1098: }
1099:
1100: fflush(NULL);
1101:
1102: /*
1103: * On bloque tous les threads concurents pour qu'il n'y ait ni allocation
1104: * de mémoire, ni libération, ni copie d'objet concurrent au fork().
1105: */
1106:
1107: verrouillage_threads_concurrents(s_etat_processus);
1108: (*s_argument_thread).pid = fork();
1109: deverrouillage_threads_concurrents(s_etat_processus);
1110:
1111: if (pthread_mutex_unlock(&((*s_etat_processus).mutex_allocation_buffer))
1112: != 0)
1113: {
1114: (*s_etat_processus).erreur_systeme = d_es_processus;
1115: return;
1116: }
1117:
1118: (*s_argument_thread).thread_pere = pthread_self();
1119: (*s_argument_thread).processus_detache = d_vrai;
1120:
1121: pthread_mutexattr_init(&attributs_mutex);
1122: pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_RECURSIVE);
1123: pthread_mutex_init(&((*s_argument_thread).mutex), &attributs_mutex);
1124: pthread_mutexattr_destroy(&attributs_mutex);
1125:
1126: pthread_mutexattr_init(&attributs_mutex);
1127: pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_RECURSIVE);
1128: pthread_mutex_init(&((*s_argument_thread).mutex_nombre_references),
1129: &attributs_mutex);
1130: pthread_mutexattr_destroy(&attributs_mutex);
1131:
1132: if ((*s_argument_thread).pid > 0)
1133: {
1134: /*
1135: * Processus père
1136: */
1137:
1138: if (variable_partagee == d_vrai)
1139: {
1140: liberation(s_etat_processus, s_copie);
1141: }
1142:
1143: liberation(s_etat_processus, s_objet);
1144:
1145: if ((s_objet = allocation(s_etat_processus, PRC)) == NULL)
1146: {
1147: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1148: return;
1149: }
1150:
1151: (*((struct_processus_fils *) (*s_objet).objet)).thread =
1152: s_argument_thread;
1153: (*(*((struct_processus_fils *) (*s_objet).objet)).thread)
1154: .nombre_objets_dans_pipe = 0;
1155: (*(*((struct_processus_fils *) (*s_objet).objet)).thread)
1156: .nombre_interruptions_dans_pipe = 0;
1157: (*(*((struct_processus_fils *) (*s_objet).objet)).thread)
1158: .nombre_references = 1;
1159:
1160: /*
1161: * On copie l'objet plutôt que le pointeur car cet objet peut être
1162: * accédé depuis deux threads distincts et aboutir à un blocage lors
1163: * d'une copie.
1164: */
1165:
1166: if ((s_objet_systeme = copie_objet(s_etat_processus, s_objet, 'O'))
1167: == NULL)
1168: {
1169: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1170: return;
1171: }
1172:
1173: if (close((*s_argument_thread).pipe_erreurs[1]) != 0)
1174: {
1175: (*s_etat_processus).erreur_systeme = d_es_processus;
1176: return;
1177: }
1178:
1179: if (close((*s_argument_thread).pipe_interruptions[1]) != 0)
1180: {
1181: (*s_etat_processus).erreur_systeme = d_es_processus;
1182: return;
1183: }
1184:
1185: if (close((*s_argument_thread).pipe_nombre_elements_attente[1])
1186: != 0)
1187: {
1188: (*s_etat_processus).erreur_systeme = d_es_processus;
1189: return;
1190: }
1191:
1192: if (close((*s_argument_thread).pipe_objets[1]) != 0)
1193: {
1194: (*s_etat_processus).erreur_systeme = d_es_processus;
1195: return;
1196: }
1197:
1198: if (close((*s_argument_thread).pipe_injections[0]) != 0)
1199: {
1200: (*s_etat_processus).erreur_systeme = d_es_processus;
1201: return;
1202: }
1203:
1204: if (close((*s_argument_thread).pipe_nombre_injections[0]) != 0)
1205: {
1206: (*s_etat_processus).erreur_systeme = d_es_processus;
1207: return;
1208: }
1209:
1210: if (close((*s_argument_thread).pipe_acquittement[0]) != 0)
1211: {
1212: (*s_etat_processus).erreur_systeme = d_es_processus;
1213: return;
1214: }
1215:
1216: if (pthread_attr_init(&attributs) != 0)
1217: {
1218: (*s_etat_processus).erreur_systeme = d_es_processus;
1219: return;
1220: }
1221:
1222: if (pthread_attr_setdetachstate(&attributs,
1223: PTHREAD_CREATE_DETACHED) != 0)
1224: {
1225: (*s_etat_processus).erreur_systeme = d_es_processus;
1226: return;
1227: }
1228:
1229: # ifdef SCHED_OTHER
1230: if (pthread_attr_setschedpolicy(&attributs, SCHED_OTHER) != 0)
1231: {
1232: (*s_etat_processus).erreur_systeme = d_es_processus;
1233: return;
1234: }
1235: # endif
1236:
1237: # ifdef PTHREAD_EXPLICIT_SCHED
1238: if (pthread_attr_setinheritsched(&attributs,
1239: PTHREAD_EXPLICIT_SCHED) != 0)
1240: {
1241: (*s_etat_processus).erreur_systeme = d_es_processus;
1242: return;
1243: }
1244: # endif
1245:
1246: # ifdef PTHREAD_SCOPE_SYSTEM
1247: if (pthread_attr_setscope(&attributs, PTHREAD_SCOPE_SYSTEM) != 0)
1248: {
1249: (*s_etat_processus).erreur_systeme = d_es_processus;
1250: return;
1251: }
1252: # endif
1253:
1254: (*s_argument_thread).s_etat_processus = s_etat_processus;
1255:
1256: if (pthread_create(&thread_surveillance, &attributs,
1257: surveillance_processus, s_argument_thread) != 0)
1258: {
1259: (*s_etat_processus).erreur_systeme = d_es_processus;
1260: return;
1261: }
1262:
1263: if (pthread_attr_destroy(&attributs) != 0)
1264: {
1265: (*s_etat_processus).erreur_systeme = d_es_processus;
1266: return;
1267: }
1268: }
1269: else if ((*s_argument_thread).pid == 0)
1270: {
1271: /*
1272: * Processus fils
1273: */
1274:
1275: liberation_queue_signaux(s_etat_processus);
1276: creation_queue_signaux(s_etat_processus);
1277:
1278: if (lancement_thread_signaux(s_etat_processus) != d_absence_erreur)
1279: {
1280: (*s_etat_processus).erreur_systeme = d_es_processus;
1281: }
1282:
1283: routine_recursive = 0;
1284:
1285: (*s_etat_processus).pointeur_signal_lecture = 0;
1286: (*s_etat_processus).pointeur_signal_ecriture = 0;
1287:
1288: if (write_atomic(s_etat_processus,
1289: pipe_initialisation_segment_signaux[1],
1290: "-", sizeof(unsigned char)) != sizeof(unsigned char))
1291: {
1292: (*s_etat_processus).erreur_systeme = d_es_processus;
1293: }
1294:
1295: close(pipe_initialisation_segment_signaux[0]);
1296: close(pipe_initialisation_segment_signaux[1]);
1297:
1298: if ((*s_etat_processus).debug == d_vrai)
1299: if (((*s_etat_processus).type_debug &
1300: d_debug_processus) != 0)
1301: {
1302: if ((*s_etat_processus).langue == 'F')
1303: {
1304: printf("[%d] Lancement du processus fils %d de %d\n",
1305: (int) getpid(), (int) getpid(), (int) ppid);
1306: }
1307: else
1308: {
1309: printf("[%d] Start child process %d from %d\n", (int) getpid(),
1310: (int) getpid(), (int) ppid);
1311: }
1312:
1313: fflush(stdout);
1314: }
1315:
1316: if (close((*s_argument_thread).pipe_erreurs[0]) != 0)
1317: {
1318: (*s_etat_processus).erreur_systeme = d_es_processus;
1319: }
1320: else if (close((*s_argument_thread).pipe_interruptions[0]) != 0)
1321: {
1322: (*s_etat_processus).erreur_systeme = d_es_processus;
1323: }
1324: else if (close((*s_argument_thread)
1325: .pipe_nombre_elements_attente[0]) != 0)
1326: {
1327: (*s_etat_processus).erreur_systeme = d_es_processus;
1328: }
1329: else if (close((*s_argument_thread).pipe_objets[0]) != 0)
1330: {
1331: (*s_etat_processus).erreur_systeme = d_es_processus;
1332: }
1333: else if (close((*s_argument_thread).pipe_injections[1]) != 0)
1334: {
1335: (*s_etat_processus).erreur_systeme = d_es_processus;
1336: }
1337: else if (close((*s_argument_thread).pipe_nombre_injections[1]) != 0)
1338: {
1339: (*s_etat_processus).erreur_systeme = d_es_processus;
1340: }
1341: else if (close((*s_argument_thread).pipe_acquittement[1]) != 0)
1342: {
1343: (*s_etat_processus).erreur_systeme = d_es_processus;
1344: }
1345:
1346: if ((*s_etat_processus).debug == d_vrai)
1347: if (((*s_etat_processus).type_debug &
1348: d_debug_processus) != 0)
1349: {
1350: if ((*s_etat_processus).langue == 'F')
1351: {
1352: printf("[%d] Libération des objets du processus père\n",
1353: (int) getpid());
1354: }
1355: else
1356: {
1357: printf("[%d] Freeing parent process memory\n", getpid());
1358: }
1359:
1360: fflush(stdout);
1361: }
1362:
1363: l_element_courant = (*s_etat_processus).liste_mutexes;
1364: while(l_element_courant != NULL)
1365: {
1366: liberation(s_etat_processus, (*l_element_courant).donnee);
1367: l_element_suivant = (*l_element_courant).suivant;
1368: free(l_element_courant);
1369: l_element_courant = l_element_suivant;
1370: }
1371:
1372: (*s_etat_processus).liste_mutexes = NULL;
1373:
1374: liberation_threads(s_etat_processus);
1375: insertion_thread(s_etat_processus, d_vrai);
1376:
1377: // Envoi d'une donnée pour signaler le démarrage du processus au thread
1378: // de surveillance.
1379:
1380: caractere = 0;
1381:
1382: if (write_atomic(s_etat_processus,
1383: (*s_argument_thread).pipe_nombre_elements_attente[1],
1384: &caractere, sizeof(caractere)) != sizeof(caractere))
1385: {
1386: pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus));
1387: (*s_etat_processus).erreur_systeme = d_es_processus;
1388:
1389: while((longueur_ecriture = write_atomic(s_etat_processus,
1390: (*s_argument_thread).pipe_nombre_elements_attente[1],
1391: &caractere, sizeof(caractere))) != sizeof(caractere))
1392: {
1393: if (longueur_ecriture == -1)
1394: {
1395: break;
1396: }
1397: }
1398:
1399: destruction_queue_signaux(s_etat_processus);
1400: BUG(1, uprintf("Process management error line %d\n", __LINE__));
1401: exit(EXIT_FAILURE);
1402: }
1403:
1404: if (pthread_mutex_destroy(&mutex_sections_critiques) != 0)
1405: {
1406: (*s_etat_processus).erreur_systeme = d_es_processus;
1407:
1408: while((longueur_ecriture = write_atomic(s_etat_processus,
1409: (*s_argument_thread).pipe_nombre_elements_attente[1],
1410: &caractere, sizeof(caractere))) != sizeof(caractere))
1411: {
1412: if (longueur_ecriture == -1)
1413: {
1414: break;
1415: }
1416: }
1417:
1418: destruction_queue_signaux(s_etat_processus);
1419: BUG(1, uprintf("Process management error line %d\n", __LINE__));
1420: exit(EXIT_FAILURE);
1421: }
1422:
1423: pthread_mutexattr_init(&attributs_mutex);
1424: pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_RECURSIVE);
1425: pthread_mutex_init(&mutex_sections_critiques, &attributs_mutex);
1426: pthread_mutexattr_destroy(&attributs_mutex);
1427:
1428: if (pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus))
1429: != 0)
1430: {
1431: (*s_etat_processus).erreur_systeme = d_es_processus;
1432:
1433: caractere = 0;
1434:
1435: while((longueur_ecriture = write_atomic(s_etat_processus,
1436: (*s_argument_thread).pipe_nombre_elements_attente[1],
1437: &caractere, sizeof(caractere))) != sizeof(caractere))
1438: {
1439: if (longueur_ecriture == -1)
1440: {
1441: break;
1442: }
1443: }
1444:
1445: destruction_queue_signaux(s_etat_processus);
1446: BUG(1, uprintf("Process management error line %d\n", __LINE__));
1447: exit(EXIT_FAILURE);
1448: }
1449:
1450: pthread_mutex_trylock(&((*s_etat_processus).protection_liste_mutexes));
1451:
1452: if (pthread_mutex_unlock(&((*s_etat_processus)
1453: .protection_liste_mutexes)) != 0)
1454: {
1455: (*s_etat_processus).erreur_systeme = d_es_processus;
1456:
1457: caractere = 0;
1458:
1459: while((longueur_ecriture = write_atomic(s_etat_processus,
1460: (*s_argument_thread).pipe_nombre_elements_attente[1],
1461: &caractere, sizeof(caractere))) != sizeof(caractere))
1462: {
1463: if (longueur_ecriture == -1)
1464: {
1465: break;
1466: }
1467: }
1468:
1469: destruction_queue_signaux(s_etat_processus);
1470: BUG(1, uprintf("Process management error line %d\n", __LINE__));
1471: exit(EXIT_FAILURE);
1472: }
1473:
1474: pthread_mutex_trylock(&((*s_etat_processus).mutex_interruptions));
1475:
1476: if (pthread_mutex_unlock(&((*s_etat_processus).mutex_interruptions))
1477: != 0)
1478: {
1479: (*s_etat_processus).erreur_systeme = d_es_processus;
1480:
1481: caractere = 0;
1482:
1483: while((longueur_ecriture = write_atomic(s_etat_processus,
1484: (*s_argument_thread).pipe_nombre_elements_attente[1],
1485: &caractere, sizeof(caractere))) != sizeof(caractere))
1486: {
1487: if (longueur_ecriture == -1)
1488: {
1489: break;
1490: }
1491: }
1492:
1493: destruction_queue_signaux(s_etat_processus);
1494: BUG(1, uprintf("Process management error line %d\n", __LINE__));
1495: exit(EXIT_FAILURE);
1496: }
1497:
1498: pthread_mutex_trylock(&((*s_etat_processus).mutex_signaux));
1499:
1500: if (pthread_mutex_unlock(&((*s_etat_processus).mutex_signaux))
1501: != 0)
1502: {
1503: (*s_etat_processus).erreur_systeme = d_es_processus;
1504:
1505: caractere = 0;
1506:
1507: while((longueur_ecriture = write_atomic(s_etat_processus,
1508: (*s_argument_thread).pipe_nombre_elements_attente[1],
1509: &caractere, sizeof(caractere))) != sizeof(caractere))
1510: {
1511: if (longueur_ecriture == -1)
1512: {
1513: break;
1514: }
1515: }
1516:
1517: destruction_queue_signaux(s_etat_processus);
1518: BUG(1, uprintf("Process management error line %d\n", __LINE__));
1519: exit(EXIT_FAILURE);
1520: }
1521:
1522: if ((*s_etat_processus).evaluation_expression_compilee == 'N')
1523: {
1524: free((*s_etat_processus).instruction_courante);
1525: (*s_etat_processus).instruction_courante = NULL;
1526: }
1527:
1528: (*s_etat_processus).var_volatile_processus_pere = 0;
1529: (*s_etat_processus).var_volatile_processus_racine = 0;
1530:
1531: // On réinitialise toutes les interruptions.
1532:
1533: (*s_etat_processus).traitement_interruption = 'N';
1534: (*s_etat_processus).traitement_interruptible = 'Y';
1535: (*s_etat_processus).nombre_interruptions_en_queue = 0;
1536: (*s_etat_processus).nombre_interruptions_non_affectees = 0;
1537: (*s_etat_processus).processus_detache = d_vrai;
1538:
1539: liberation(s_etat_processus, (*s_etat_processus).at_exit);
1540: (*s_etat_processus).at_exit = NULL;
1541: liberation(s_etat_processus, (*s_etat_processus).at_poke);
1542: (*s_etat_processus).at_poke = NULL;
1543: (*s_etat_processus).traitement_at_poke = 'N';
1544:
1545: for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++)
1546: {
1547: liberation(s_etat_processus,
1548: (*s_etat_processus).corps_interruptions[i]);
1549:
1550: (*s_etat_processus).corps_interruptions[i] = NULL;
1551: (*s_etat_processus).masque_interruptions[i] = 'N';
1552: (*s_etat_processus).queue_interruptions[i] = 0;
1553:
1554: l_element_courant = (*s_etat_processus)
1555: .pile_origine_interruptions[i];
1556:
1557: while(l_element_courant != NULL)
1558: {
1559: l_element_suivant = (*l_element_courant).suivant;
1560: liberation(s_etat_processus, (*l_element_courant).donnee);
1561: free(l_element_courant);
1562: l_element_courant = l_element_suivant;
1563: }
1564:
1565: (*s_etat_processus).pile_origine_interruptions[i] = NULL;
1566: }
1567:
1568: /*
1569: * On bloque l'exécution du processus fils jusqu'à ce que
1570: * le père ait renseigné correctement la pile des processus.
1571: * Dans le cas contraire, on pourrait essayer de traiter
1572: * un RECV sur un système chargé avant que cette pile soit
1573: * renseignée.
1574: */
1575:
1576: // Attente de la réception du signal rpl_sigstart.
1577:
1578: for((*s_etat_processus).demarrage_fils = d_faux;;)
1579: {
1580: scrutation_interruptions(s_etat_processus);
1581:
1582: if ((*s_etat_processus).demarrage_fils == d_vrai)
1583: {
1584: break;
1585: }
1586:
1587: nanosleep(&attente, NULL);
1588: }
1589:
1590: (*s_etat_processus).niveau_initial = (*s_etat_processus).niveau_courant;
1591: (*s_etat_processus).presence_pipes = d_vrai;
1592: (*s_etat_processus).debug_programme = d_faux;
1593: (*s_etat_processus).pipe_donnees = (*s_argument_thread).pipe_objets[1];
1594: (*s_etat_processus).pipe_nombre_elements_attente = (*s_argument_thread)
1595: .pipe_nombre_elements_attente[1];
1596: (*s_etat_processus).pipe_interruptions = (*s_argument_thread)
1597: .pipe_interruptions[1];
1598: (*s_etat_processus).pipe_injections =
1599: (*s_argument_thread).pipe_injections[0];
1600: (*s_etat_processus).pipe_nombre_injections =
1601: (*s_argument_thread).pipe_nombre_injections[0];
1602: (*s_etat_processus).pipe_acquittement =
1603: (*s_argument_thread).pipe_acquittement[0];
1604: (*s_etat_processus).nombre_objets_injectes = 0;
1605: (*s_etat_processus).nombre_objets_envoyes_non_lus = 0;
1606: (*s_etat_processus).temps_maximal_cpu = 0;
1607: (*s_etat_processus).presence_fusible = d_faux;
1608: (*s_etat_processus).thread_fusible = 0;
1609: (*s_etat_processus).pid_erreur_processus_fils = getpid();
1610: (*s_etat_processus).sections_critiques = 0;
1611: (*s_etat_processus).initialisation_scheduler = d_faux;
1612:
1613: if ((*s_etat_processus).profilage == d_vrai)
1614: {
1615: liberation_profil(s_etat_processus);
1616: }
1617:
1618: (*s_etat_processus).pile_profilage = NULL;
1619:
1620: if ((*s_etat_processus).generateur_aleatoire != NULL)
1621: {
1622: liberation_generateur_aleatoire(s_etat_processus);
1623: }
1624:
1625: (*s_etat_processus).generateur_aleatoire = NULL;
1626:
1627: if ((*s_etat_processus).instruction_derniere_erreur != NULL)
1628: {
1629: free((*s_etat_processus).instruction_derniere_erreur);
1630: (*s_etat_processus).instruction_derniere_erreur = NULL;
1631: }
1632:
1633: /*
1634: * Initialisation de la pile des processus. Cette pile est effacée
1635: * par liberation_threads().
1636: */
1637:
1638: if (pthread_mutex_lock(&((*s_etat_processus).mutex_pile_processus))
1639: != 0)
1640: {
1641: (*s_etat_processus).erreur_systeme = d_es;
1642:
1643: caractere = 0;
1644:
1645: while((longueur_ecriture = write_atomic(s_etat_processus,
1646: (*s_argument_thread).pipe_nombre_elements_attente[1],
1647: &caractere, sizeof(caractere))) != sizeof(caractere))
1648: {
1649: if (longueur_ecriture == -1)
1650: {
1651: break;
1652: }
1653: }
1654:
1655: destruction_queue_signaux(s_etat_processus);
1656: BUG(1, uprintf("Process management error line %d\n", __LINE__));
1657: exit(EXIT_FAILURE);
1658: }
1659:
1660: l_element_courant = (struct_liste_chainee *)
1661: (*s_etat_processus).l_base_pile_processus;
1662:
1663: while(l_element_courant != NULL)
1664: {
1665: s_argument_thread2 = (struct_descripteur_thread *)
1666: (*((struct_processus_fils *) (*(*l_element_courant).donnee)
1667: .objet)).thread;
1668:
1669: (*s_argument_thread2).nombre_references--;
1670:
1671: BUG((*s_argument_thread2).nombre_references < 0,
1672: destruction_queue_signaux(s_etat_processus),
1673: printf("(*s_argument_thread2).nombre_references = %d\n",
1674: (int) (*s_argument_thread2).nombre_references));
1675:
1676: if ((*s_argument_thread2).nombre_references == 0)
1677: {
1678: close((*s_argument_thread2).pipe_objets[0]);
1679: close((*s_argument_thread2).pipe_acquittement[1]);
1680: close((*s_argument_thread2).pipe_injections[1]);
1681: close((*s_argument_thread2).pipe_nombre_injections[1]);
1682: close((*s_argument_thread2).pipe_nombre_elements_attente[0]);
1683: close((*s_argument_thread2).pipe_interruptions[0]);
1684:
1685: pthread_mutex_destroy(&((*s_argument_thread2).mutex));
1686:
1687: if ((*s_argument_thread2).processus_detache == d_faux)
1688: {
1689: if ((*s_argument_thread2).destruction_objet == d_vrai)
1690: {
1691: liberation(s_etat_processus,
1692: (*s_argument_thread2).argument);
1693: }
1694: }
1695:
1696: free(s_argument_thread2);
1697: free((*(*l_element_courant).donnee).objet);
1698: free((*l_element_courant).donnee);
1699: }
1700:
1701: l_element_suivant = (*l_element_courant).suivant;
1702: free((struct_liste_chainee *) l_element_courant);
1703: l_element_courant = l_element_suivant;
1704: }
1705:
1706: (*s_etat_processus).l_base_pile_processus = NULL;
1707:
1708: if (pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus))
1709: != 0)
1710: {
1711: (*s_etat_processus).erreur_systeme = d_es;
1712:
1713: caractere = 0;
1714:
1715: while((longueur_ecriture = write_atomic(s_etat_processus,
1716: (*s_argument_thread).pipe_nombre_elements_attente[1],
1717: &caractere, sizeof(caractere))) != sizeof(caractere))
1718: {
1719: if (longueur_ecriture == -1)
1720: {
1721: break;
1722: }
1723: }
1724:
1725: destruction_queue_signaux(s_etat_processus);
1726: BUG(1, uprintf("Process management error line %d\n", __LINE__));
1727: exit(EXIT_FAILURE);
1728: }
1729:
1730: /*
1731: * Initialisation de la pile système
1732: */
1733:
1734: l_element_courant = (struct_liste_chainee *)
1735: (*s_etat_processus).l_base_pile_systeme;
1736: while(l_element_courant != NULL)
1737: {
1738: l_element_suivant = (struct_liste_chainee *)
1739: (*((struct_liste_pile_systeme *)
1740: l_element_courant)).suivant;
1741:
1742: liberation(s_etat_processus, (*((struct_liste_pile_systeme *)
1743: l_element_courant)).indice_boucle);
1744: liberation(s_etat_processus, (*((struct_liste_pile_systeme *)
1745: l_element_courant)).limite_indice_boucle);
1746: liberation(s_etat_processus, (*((struct_liste_pile_systeme *)
1747: l_element_courant)).objet_de_test);
1748:
1749: if ((*((struct_liste_pile_systeme *) l_element_courant))
1750: .nom_variable != NULL)
1751: {
1752: free((*((struct_liste_pile_systeme *)
1753: l_element_courant)).nom_variable);
1754: }
1755:
1756: free((struct_liste_pile_systeme *) l_element_courant);
1757:
1758: l_element_courant = l_element_suivant;
1759: }
1760:
1761: (*s_etat_processus).l_base_pile_systeme = NULL;
1762: (*s_etat_processus).hauteur_pile_systeme = 0;
1763:
1764: empilement_pile_systeme(s_etat_processus);
1765:
1766: if ((*s_etat_processus).erreur_systeme != d_es)
1767: {
1768: caractere = 0;
1769:
1770: while((longueur_ecriture = write_atomic(s_etat_processus,
1771: (*s_argument_thread).pipe_nombre_elements_attente[1],
1772: &caractere, sizeof(caractere))) != sizeof(caractere))
1773: {
1774: if (longueur_ecriture == -1)
1775: {
1776: break;
1777: }
1778: }
1779:
1780: destruction_queue_signaux(s_etat_processus);
1781: BUG(1, uprintf("Process management error line %d\n", __LINE__));
1782: exit(EXIT_FAILURE);
1783: }
1784:
1785: (*(*s_etat_processus).l_base_pile_systeme).retour_definition = 'Y';
1786:
1787: l_element_courant = (struct_liste_chainee *)
1788: (*s_etat_processus).s_marques;
1789:
1790: while(l_element_courant != NULL)
1791: {
1792: free((*((struct_marque *) l_element_courant)).label);
1793: free((*((struct_marque *) l_element_courant)).position);
1794: l_element_suivant = (struct_liste_chainee *)
1795: (*((struct_marque *) l_element_courant)).suivant;
1796: free((struct_marque *) l_element_courant);
1797: l_element_courant = l_element_suivant;
1798: }
1799:
1800: (*s_etat_processus).s_marques = NULL;
1801:
1802: /*
1803: * On empile deux valeurs retour_definition pour pouvoir récupérer
1804: * les variables dans le cas d'un programme compilé.
1805: */
1806:
1807: empilement_pile_systeme(s_etat_processus);
1808:
1809: if ((*s_etat_processus).erreur_systeme != d_es)
1810: {
1811: caractere = 0;
1812:
1813: while((longueur_ecriture = write_atomic(s_etat_processus,
1814: (*s_argument_thread).pipe_nombre_elements_attente[1],
1815: &caractere, sizeof(caractere))) != sizeof(caractere))
1816: {
1817: if (longueur_ecriture == -1)
1818: {
1819: break;
1820: }
1821: }
1822:
1823: destruction_queue_signaux(s_etat_processus);
1824: BUG(1, uprintf("Process management error line %d\n", __LINE__));
1825: exit(EXIT_FAILURE);
1826: }
1827:
1828: (*(*s_etat_processus).l_base_pile_systeme).retour_definition = 'Y';
1829:
1830: /*
1831: * Destruction des sorties graphiques et PostScript
1832: */
1833:
1834: while((*s_etat_processus).fichiers_graphiques != NULL)
1835: {
1836: free((*(*s_etat_processus).fichiers_graphiques).nom);
1837:
1838: if ((*(*s_etat_processus).fichiers_graphiques).legende != NULL)
1839: {
1840: free((*(*s_etat_processus).fichiers_graphiques).legende);
1841: }
1842:
1843: l_element_precedent = (void *) (*s_etat_processus)
1844: .fichiers_graphiques;
1845: (*s_etat_processus).fichiers_graphiques =
1846: (*(*s_etat_processus).fichiers_graphiques).suivant;
1847: free(l_element_precedent);
1848: }
1849:
1850: if ((*s_etat_processus).entree_standard != NULL)
1851: {
1852: pclose((*s_etat_processus).entree_standard);
1853: (*s_etat_processus).entree_standard = NULL;
1854: }
1855:
1856: (*s_etat_processus).requete_nouveau_plan = d_vrai;
1857: (*s_etat_processus).mise_a_jour_trace_requise = d_faux;
1858:
1859: if ((*s_etat_processus).nom_fichier_impression != NULL)
1860: {
1861: free((*s_etat_processus).nom_fichier_impression);
1862: (*s_etat_processus).nom_fichier_impression = NULL;
1863: }
1864:
1865: /*
1866: * Destruction des piles de fichiers
1867: */
1868:
1869: l_element_courant = (*s_etat_processus).s_fichiers;
1870:
1871: while(l_element_courant != NULL)
1872: {
1873: l_element_suivant = (*l_element_courant).suivant;
1874:
1875: fclose((*((struct_descripteur_fichier *)
1876: (*l_element_courant).donnee)).descripteur_c);
1877:
1878: if ((*((struct_descripteur_fichier *)
1879: (*l_element_courant).donnee)).type != 'C')
1880: {
1881: sqlite3_close((*((struct_descripteur_fichier *)
1882: (*l_element_courant).donnee)).descripteur_sqlite);
1883: }
1884:
1885: free((*((struct_descripteur_fichier *) (*l_element_courant)
1886: .donnee)).nom);
1887: free((struct_descripteur_fichier *) (*l_element_courant).donnee);
1888: free(l_element_courant);
1889:
1890: l_element_courant = l_element_suivant;
1891: }
1892:
1893: /*
1894: * Destruction des piles de connecteurs SQL
1895: */
1896:
1897: /*
1898: ================================================================================
1899: À noter : on ne ferme pas la connexion car la conséquence immédiate est
1900: une destruction de l'objet pour le processus père.
1901: ================================================================================
1902: */
1903:
1904: l_element_courant = (*s_etat_processus).s_connecteurs_sql;
1905:
1906: while(l_element_courant != NULL)
1907: {
1908: l_element_suivant = (*l_element_courant).suivant;
1909:
1910: // sqlclose((*l_element_courant).donnee);
1911: liberation(s_etat_processus, (*l_element_courant).donnee);
1912: l_element_courant = l_element_suivant;
1913: }
1914:
1915: (*s_etat_processus).s_connecteurs_sql = NULL;
1916:
1917: /*
1918: * On ne détruit pas les sockets car il faut utiliser DETACH
1919: * pour traiter plusieurs connexions simultanées sur les sockets
1920: */
1921:
1922: (*s_etat_processus).s_fichiers = NULL;
1923:
1924: if ((*s_etat_processus).debug == d_vrai)
1925: {
1926: if (((*s_etat_processus).type_debug & d_debug_processus)
1927: != 0)
1928: {
1929: if ((*s_etat_processus).langue == 'F')
1930: {
1931: printf("[%d] Évaluation de l'objet détaché\n", getpid());
1932: }
1933: else
1934: {
1935: printf("[%d] Évaluation of detached object\n", getpid());
1936: }
1937: }
1938: }
1939:
1940: if ((*s_etat_processus).erreur_systeme == d_es)
1941: {
1942: // Évite le warning variable s_copie might be clobbered by
1943: // longjmp or vfork
1944: struct_objet **s;
1945:
1946: if ((s = malloc(sizeof(struct_objet *))) == NULL)
1947: {
1948: (*s_etat_processus).erreur_execution = d_es_allocation_memoire;
1949: return;
1950: }
1951:
1952: (*s) = s_copie;
1953:
1954: if (setjmp(contexte_processus) == 0)
1955: {
1956: if (variable_partagee == d_faux)
1957: {
1958: if (evaluation(s_etat_processus, s_objet, 'E') == d_erreur)
1959: {
1960: if (((*s_etat_processus).erreur_execution == d_ex) &&
1961: ((*s_etat_processus).erreur_systeme == d_es))
1962: {
1963: (*s_etat_processus).erreur_execution =
1964: d_ex_erreur_evaluation;
1965: }
1966: }
1967: else
1968: {
1969: if (((*s_etat_processus).arret_depuis_abort == 0)
1970: && ((*s_etat_processus).at_exit != NULL))
1971: {
1972: (*s_etat_processus).var_volatile_requete_arret = 0;
1973: (*s_etat_processus).var_volatile_alarme = 0;
1974: (*s_etat_processus).var_volatile_traitement_sigint
1975: = 0;
1976:
1977: if ((*s_etat_processus).profilage == d_vrai)
1978: {
1979: profilage(s_etat_processus, "ATEXIT");
1980: }
1981:
1982: if (evaluation(s_etat_processus,
1983: (*s_etat_processus).at_exit, 'E') ==
1984: d_erreur)
1985: {
1986: (*s_etat_processus).erreur_execution =
1987: d_ex_erreur_evaluation;
1988: }
1989:
1990: if ((*s_etat_processus).profilage == d_vrai)
1991: {
1992: profilage(s_etat_processus, NULL);
1993: }
1994: }
1995: }
1996: }
1997: else
1998: {
1999: if (evaluation(s_etat_processus, (*s), 'E') == d_erreur)
2000: {
2001: if (((*s_etat_processus).erreur_execution == d_ex) &&
2002: ((*s_etat_processus).erreur_systeme == d_es))
2003: {
2004: (*s_etat_processus).erreur_execution =
2005: d_ex_erreur_evaluation;
2006: }
2007: }
2008: else
2009: {
2010: if (((*s_etat_processus).arret_depuis_abort == 0)
2011: && ((*s_etat_processus).at_exit != NULL))
2012: {
2013: (*s_etat_processus).var_volatile_requete_arret = 0;
2014: (*s_etat_processus).var_volatile_alarme = 0;
2015: (*s_etat_processus).var_volatile_traitement_sigint
2016: = 0;
2017:
2018: if ((*s_etat_processus).profilage == d_vrai)
2019: {
2020: profilage(s_etat_processus, "ATEXIT");
2021: }
2022:
2023: if (evaluation(s_etat_processus,
2024: (*s_etat_processus).at_exit, 'E') ==
2025: d_erreur)
2026: {
2027: (*s_etat_processus).erreur_execution =
2028: d_ex_erreur_evaluation;
2029: }
2030:
2031: if ((*s_etat_processus).profilage == d_vrai)
2032: {
2033: profilage(s_etat_processus, NULL);
2034: }
2035: }
2036: }
2037:
2038: liberation(s_etat_processus, (*s));
2039: }
2040: }
2041:
2042: free(s);
2043: }
2044:
2045: for(i = 0; i < (*s_etat_processus).sections_critiques; i++)
2046: {
2047: pthread_mutex_unlock(&mutex_sections_critiques);
2048: }
2049:
2050: liberation(s_etat_processus, (*s_etat_processus).at_exit);
2051: liberation(s_etat_processus, (*s_etat_processus).at_poke);
2052:
2053: l_element_courant = (*s_etat_processus).liste_mutexes;
2054: while(l_element_courant != NULL)
2055: {
2056: liberation(s_etat_processus, (*l_element_courant).donnee);
2057: l_element_suivant = (*l_element_courant).suivant;
2058: free(l_element_courant);
2059: l_element_courant = l_element_suivant;
2060: }
2061:
2062: if ((*s_etat_processus).presence_fusible == d_vrai)
2063: {
2064: pthread_cancel((*s_etat_processus).thread_fusible);
2065: }
2066:
2067: caractere = 0;
2068:
2069: while((longueur_ecriture = write_atomic(s_etat_processus,
2070: (*s_argument_thread).pipe_nombre_elements_attente[1],
2071: &caractere, sizeof(caractere))) != sizeof(caractere))
2072: {
2073: if (longueur_ecriture == -1)
2074: {
2075: break;
2076: }
2077: }
2078:
2079: if ((*s_etat_processus).var_volatile_processus_pere != 0)
2080: {
2081: // Racine des processus atteinte
2082:
2083: erreur = d_ex;
2084:
2085: while((longueur_ecriture = write_atomic(s_etat_processus,
2086: (*s_argument_thread).pipe_erreurs[1], &erreur,
2087: sizeof((*s_etat_processus).erreur_execution))) !=
2088: sizeof((*s_etat_processus).erreur_execution))
2089: {
2090: if (longueur_ecriture == -1)
2091: {
2092: break;
2093: }
2094: }
2095: }
2096: else
2097: {
2098: while((longueur_ecriture = write_atomic(s_etat_processus,
2099: (*s_argument_thread).pipe_erreurs[1],
2100: (int *) &((*s_etat_processus).erreur_execution),
2101: sizeof((*s_etat_processus).erreur_execution))) !=
2102: sizeof((*s_etat_processus).erreur_execution))
2103: {
2104: if (longueur_ecriture == -1)
2105: {
2106: break;
2107: }
2108: }
2109: }
2110:
2111: if ((*s_etat_processus).var_volatile_processus_pere != 0)
2112: {
2113: // Racine des processus atteinte
2114:
2115: erreur = d_es;
2116:
2117: while((longueur_ecriture = write_atomic(s_etat_processus,
2118: (*s_argument_thread).pipe_erreurs[1], &erreur,
2119: sizeof((*s_etat_processus).erreur_systeme))) !=
2120: sizeof((*s_etat_processus).erreur_systeme))
2121: {
2122: if (longueur_ecriture == -1)
2123: {
2124: break;
2125: }
2126: }
2127: }
2128: else
2129: {
2130: while((longueur_ecriture = write_atomic(s_etat_processus,
2131: (*s_argument_thread).pipe_erreurs[1],
2132: (int *) &((*s_etat_processus).erreur_systeme),
2133: sizeof((*s_etat_processus).erreur_systeme))) !=
2134: sizeof((*s_etat_processus).erreur_systeme))
2135: {
2136: if (longueur_ecriture == -1)
2137: {
2138: break;
2139: }
2140: }
2141: }
2142:
2143: if ((*s_etat_processus).pid_erreur_processus_fils == 0)
2144: {
2145: while((longueur_ecriture = write_atomic(s_etat_processus,
2146: (*s_argument_thread).pipe_erreurs[1],
2147: &ppid, sizeof(ppid))) != sizeof(ppid))
2148: {
2149: if (longueur_ecriture == -1)
2150: {
2151: break;
2152: }
2153: }
2154: }
2155: else
2156: {
2157: while((longueur_ecriture = write_atomic(s_etat_processus,
2158: (*s_argument_thread).pipe_erreurs[1],
2159: &((*s_etat_processus).pid_erreur_processus_fils),
2160: sizeof((*s_etat_processus).pid_erreur_processus_fils))) !=
2161: sizeof((*s_etat_processus).pid_erreur_processus_fils))
2162: {
2163: if (longueur_ecriture == -1)
2164: {
2165: break;
2166: }
2167: }
2168: }
2169:
2170: close((*s_argument_thread).pipe_erreurs[1]);
2171: close((*s_argument_thread).pipe_interruptions[1]);
2172: close((*s_argument_thread).pipe_nombre_elements_attente[1]);
2173: close((*s_argument_thread).pipe_objets[1]);
2174: close((*s_argument_thread).pipe_injections[0]);
2175: close((*s_argument_thread).pipe_nombre_injections[0]);
2176: close((*s_argument_thread).pipe_acquittement[0]);
2177:
2178: l_element_courant = (*s_etat_processus).s_fichiers;
2179:
2180: while(l_element_courant != NULL)
2181: {
2182: l_element_suivant = (*l_element_courant).suivant;
2183:
2184: fclose((*((struct_descripteur_fichier *)
2185: (*l_element_courant).donnee)).descripteur_c);
2186:
2187: if ((*((struct_descripteur_fichier *)
2188: (*l_element_courant).donnee)).type != 'C')
2189: {
2190: sqlite3_close((*((struct_descripteur_fichier *)
2191: (*l_element_courant).donnee)).descripteur_sqlite);
2192: }
2193:
2194: if (((*((struct_descripteur_fichier *) (*l_element_courant)
2195: .donnee)).pid == getpid()) &&
2196: (pthread_equal((*((struct_descripteur_fichier *)
2197: (*l_element_courant).donnee)).tid, pthread_self()) != 0))
2198: {
2199: if ((*((struct_descripteur_fichier *) (*l_element_courant)
2200: .donnee)).effacement == 'Y')
2201: {
2202: unlink((*((struct_descripteur_fichier *)
2203: (*l_element_courant).donnee)).nom);
2204: }
2205: }
2206:
2207: free((*((struct_descripteur_fichier *) (*l_element_courant)
2208: .donnee)).nom);
2209: free((struct_descripteur_fichier *) (*l_element_courant).donnee);
2210: free(l_element_courant);
2211:
2212: l_element_courant = l_element_suivant;
2213: }
2214:
2215: pthread_mutex_lock(&((*s_etat_processus).mutex_pile_processus));
2216:
2217: l_element_courant = (struct_liste_chainee *)
2218: (*s_etat_processus).l_base_pile_processus;
2219:
2220: while(l_element_courant != NULL)
2221: {
2222: if ((*(*((struct_processus_fils *) (*(*((struct_liste_chainee *)
2223: l_element_courant)).donnee).objet)).thread)
2224: .processus_detache == d_vrai)
2225: {
2226: if ((*s_etat_processus).debug == d_vrai)
2227: {
2228: if (((*s_etat_processus).type_debug & d_debug_processus)
2229: != 0)
2230: {
2231: if ((*s_etat_processus).langue == 'F')
2232: {
2233: printf("[%d] Signalement pour arrêt du "
2234: "processus %d\n",
2235: (int) getpid(),
2236: (int) (*(*((struct_processus_fils *)
2237: (*(*((struct_liste_chainee *)
2238: l_element_courant)).donnee).objet))
2239: .thread).pid);
2240: }
2241: else
2242: {
2243: printf("[%d] Send stop signal to process %d\n",
2244: (int) getpid(),
2245: (int) (*(*((struct_processus_fils *)
2246: (*(*((struct_liste_chainee *)
2247: l_element_courant)).donnee).objet))
2248: .thread).pid);
2249: }
2250: }
2251: }
2252:
2253: if ((*s_etat_processus).var_volatile_alarme != 0)
2254: {
2255: envoi_signal_processus((*(*((struct_processus_fils *)
2256: (*(*l_element_courant).donnee).objet)).thread).pid,
2257: rpl_sigurg);
2258: }
2259: else
2260: {
2261: if ((*s_etat_processus).arret_depuis_abort == -1)
2262: {
2263: envoi_signal_processus((*(*((struct_processus_fils *)
2264: (*(*l_element_courant).donnee).objet)).thread)
2265: .pid, rpl_sigabort);
2266: }
2267: else
2268: {
2269: envoi_signal_processus((*(*((struct_processus_fils *)
2270: (*(*l_element_courant).donnee).objet)).thread)
2271: .pid, rpl_sigstop);
2272: }
2273: }
2274: }
2275: else
2276: {
2277: if ((*s_etat_processus).debug == d_vrai)
2278: {
2279: if (((*s_etat_processus).type_debug & d_debug_processus)
2280: != 0)
2281: {
2282: if ((*s_etat_processus).langue == 'F')
2283: {
2284: printf("[%d] Signalement pour arrêt du "
2285: "thread %llu\n",
2286: (int) getpid(), (unsigned long long)
2287: (*(*((struct_processus_fils *)
2288: (*(*((struct_liste_chainee *)
2289: l_element_courant)).donnee).objet)).thread)
2290: .tid);
2291: }
2292: else
2293: {
2294: printf("[%d] Send stop signal to thread %llu\n",
2295: (int) getpid(), (unsigned long long)
2296: (*(*((struct_processus_fils *)
2297: (*(*((struct_liste_chainee *)
2298: l_element_courant)).donnee).objet)).thread)
2299: .tid);
2300: }
2301: }
2302: }
2303:
2304: pthread_mutex_lock(&((*(*((struct_processus_fils *)
2305: (*(*l_element_courant).donnee).objet)).thread).mutex));
2306:
2307: if ((*(*((struct_processus_fils *)
2308: (*(*l_element_courant).donnee).objet)).thread)
2309: .thread_actif == d_vrai)
2310: {
2311: if ((*s_etat_processus).var_volatile_alarme != 0)
2312: {
2313: envoi_signal_thread((*(*((struct_processus_fils *)
2314: (*(*l_element_courant).donnee).objet)).thread)
2315: .tid, rpl_sigurg);
2316: }
2317: else
2318: {
2319: if ((*s_etat_processus).arret_depuis_abort == -1)
2320: {
2321: envoi_signal_thread((*(*((struct_processus_fils *)
2322: (*(*l_element_courant).donnee).objet))
2323: .thread).tid, rpl_sigabort);
2324: }
2325: else
2326: {
2327: envoi_signal_thread((*(*((struct_processus_fils *)
2328: (*(*l_element_courant).donnee).objet))
2329: .thread).tid, rpl_sigstop);
2330: }
2331: }
2332: }
2333:
2334: pthread_mutex_unlock(&((*(*((struct_processus_fils *)
2335: (*(*l_element_courant).donnee).objet)).thread).mutex));
2336: }
2337:
2338: l_element_courant = (*l_element_courant).suivant;
2339: }
2340:
2341: /*
2342: * Attente de la fin de tous les processus fils
2343: */
2344:
2345: for(i = 0; i < d_NOMBRE_INTERRUPTIONS;
2346: (*s_etat_processus).masque_interruptions[i++] = 'I');
2347:
2348: attente.tv_sec = 0;
2349: attente.tv_nsec = GRANULARITE_us * 1000;
2350:
2351: while((*s_etat_processus).l_base_pile_processus != NULL)
2352: {
2353: l_element_courant = (struct_liste_chainee *)
2354: (*s_etat_processus).l_base_pile_processus;
2355:
2356: registre_stop = (*s_etat_processus)
2357: .var_volatile_traitement_retarde_stop;
2358: (*s_etat_processus).var_volatile_traitement_retarde_stop = 1;
2359:
2360: for(i = 0; i < (*(*((struct_processus_fils *)
2361: (*(*l_element_courant)
2362: .donnee).objet)).thread).nombre_objets_dans_pipe; i++)
2363: {
2364: if ((s_objet_temporaire = lecture_pipe(s_etat_processus,
2365: (*(*((struct_processus_fils *) (*(*l_element_courant)
2366: .donnee).objet)).thread).pipe_objets[0])) != NULL)
2367: {
2368: liberation(s_etat_processus, s_objet_temporaire);
2369:
2370: (*(*((struct_processus_fils *) (*(*l_element_courant)
2371: .donnee).objet)).thread).nombre_objets_dans_pipe--;
2372:
2373: action.sa_handler = SIG_IGN;
2374: action.sa_flags = SA_ONSTACK;
2375:
2376: if (sigaction(SIGPIPE, &action, ®istre) != 0)
2377: {
2378: pthread_mutex_unlock(&((*s_etat_processus)
2379: .mutex_pile_processus));
2380:
2381: if (registre_stop == 0)
2382: {
2383: if ((*s_etat_processus)
2384: .var_volatile_traitement_retarde_stop
2385: == -1)
2386: {
2387: (*s_etat_processus)
2388: .var_volatile_requete_arret = -1;
2389: }
2390:
2391: (*s_etat_processus)
2392: .var_volatile_traitement_retarde_stop =
2393: registre_stop;
2394: }
2395:
2396: destruction_queue_signaux(s_etat_processus);
2397: (*s_etat_processus).erreur_systeme = d_es_signal;
2398: exit(EXIT_FAILURE);
2399: }
2400:
2401: while((longueur_ecriture = write_atomic(
2402: s_etat_processus, (*(*((struct_processus_fils *)
2403: (*(*l_element_courant).donnee).objet))
2404: .thread).pipe_nombre_injections[1], "+",
2405: sizeof(unsigned char))) !=
2406: sizeof(unsigned char))
2407: {
2408: if (longueur_ecriture == -1)
2409: {
2410: // Le processus n'existe plus.
2411: break;
2412: }
2413: }
2414:
2415: if (registre_stop == 0)
2416: {
2417: if ((*s_etat_processus)
2418: .var_volatile_traitement_retarde_stop == -1)
2419: {
2420: (*s_etat_processus).var_volatile_requete_arret
2421: = -1;
2422: }
2423:
2424: (*s_etat_processus)
2425: .var_volatile_traitement_retarde_stop =
2426: registre_stop;
2427: }
2428:
2429: if (sigaction(SIGPIPE, ®istre, NULL) != 0)
2430: {
2431: destruction_queue_signaux(s_etat_processus);
2432:
2433: pthread_mutex_unlock(&((*s_etat_processus)
2434: .mutex_pile_processus));
2435: (*s_etat_processus).erreur_systeme = d_es_signal;
2436: exit(EXIT_FAILURE);
2437: }
2438: }
2439: }
2440:
2441: if (pthread_mutex_lock(&((*s_etat_processus).mutex_interruptions))
2442: != 0)
2443: {
2444: destruction_queue_signaux(s_etat_processus);
2445:
2446: pthread_mutex_unlock(&((*s_etat_processus)
2447: .mutex_pile_processus));
2448: (*s_etat_processus).erreur_systeme = d_es_processus;
2449: exit(EXIT_FAILURE);
2450: }
2451:
2452: if ((*s_etat_processus).nombre_interruptions_non_affectees != 0)
2453: {
2454: affectation_interruptions_logicielles(s_etat_processus);
2455: }
2456:
2457: if (pthread_mutex_unlock(&((*s_etat_processus)
2458: .mutex_interruptions)) != 0)
2459: {
2460: destruction_queue_signaux(s_etat_processus);
2461:
2462: pthread_mutex_unlock(&((*s_etat_processus)
2463: .mutex_pile_processus));
2464: (*s_etat_processus).erreur_systeme = d_es_processus;
2465: exit(EXIT_FAILURE);
2466: }
2467:
2468: pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus));
2469: nanosleep(&attente, NULL);
2470: pthread_mutex_lock(&((*s_etat_processus).mutex_pile_processus));
2471:
2472: scrutation_interruptions(s_etat_processus);
2473: }
2474:
2475: pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus));
2476:
2477: l_element_courant = (*s_etat_processus).s_sockets;
2478:
2479: while(l_element_courant != NULL)
2480: {
2481: l_element_suivant = (*l_element_courant).suivant;
2482:
2483: if ((*((struct_socket *) (*(*l_element_courant).donnee)
2484: .objet)).socket_connectee == d_vrai)
2485: {
2486: shutdown((*((struct_socket *) (*(*l_element_courant).donnee)
2487: .objet)).socket, SHUT_RDWR);
2488: }
2489:
2490: close((*((struct_socket *) (*(*l_element_courant).donnee)
2491: .objet)).socket);
2492:
2493: if (((*((struct_socket *) (*(*l_element_courant).donnee).objet))
2494: .pid == getpid()) && (pthread_equal((*((struct_socket *)
2495: (*(*l_element_courant).donnee).objet)).tid, pthread_self())
2496: != 0))
2497: {
2498: if ((*((struct_socket *) (*(*l_element_courant).donnee).objet))
2499: .effacement == 'Y')
2500: {
2501: unlink((*((struct_socket *) (*(*l_element_courant).donnee)
2502: .objet)).adresse);
2503: }
2504: }
2505:
2506: liberation(s_etat_processus,
2507: (*((struct_liste_chainee *) l_element_courant)).donnee);
2508: free(l_element_courant);
2509:
2510: l_element_courant = l_element_suivant;
2511: }
2512:
2513: l_element_courant = (*s_etat_processus).s_connecteurs_sql;
2514:
2515: while(l_element_courant != NULL)
2516: {
2517: l_element_suivant = (*l_element_courant).suivant;
2518:
2519: sqlclose((*l_element_courant).donnee);
2520:
2521: liberation(s_etat_processus,
2522: (*((struct_liste_chainee *) l_element_courant)).donnee);
2523: free(l_element_courant);
2524:
2525: l_element_courant = l_element_suivant;
2526: }
2527:
2528: if ((((*s_etat_processus).erreur_execution != d_ex) ||
2529: ((*s_etat_processus).exception != d_ep) ||
2530: ((*s_etat_processus).erreur_systeme != d_es)) &&
2531: ((*s_etat_processus).var_volatile_traitement_sigint == 0))
2532: {
2533: printf("%s [%d]\n", message =
2534: messages(s_etat_processus), (int) getpid());
2535: free(message);
2536:
2537: if ((*s_etat_processus).core == d_vrai)
2538: {
2539: printf("\n");
2540:
2541: if ((*s_etat_processus).langue == 'F')
2542: {
2543: printf("+++Information : Génération du fichier rpl-core "
2544: "[%d]\n", (int) getpid());
2545: }
2546: else
2547: {
2548: printf("+++Information : Writing rpl-core file [%d]\n",
2549: (int) getpid());
2550: }
2551:
2552: rplcore(s_etat_processus);
2553:
2554: if ((*s_etat_processus).langue == 'F')
2555: {
2556: printf("+++Information : Processus tracé [%d]\n",
2557: (int) getpid());
2558: }
2559: else
2560: {
2561: printf("+++Information : Done [%d]\n", (int) getpid());
2562: }
2563:
2564: printf("\n");
2565: fflush(stdout);
2566: }
2567: }
2568:
2569: liberation_arbre_instructions(s_etat_processus,
2570: (*s_etat_processus).arbre_instructions);
2571: free((*s_etat_processus).pointeurs_caracteres);
2572:
2573: l_element_statique_courant = (*s_etat_processus)
2574: .l_liste_variables_statiques;
2575:
2576: while(l_element_statique_courant != NULL)
2577: {
2578: l_element_statique_suivant = (*l_element_statique_courant).suivant;
2579: free(l_element_statique_courant);
2580: l_element_statique_courant = l_element_statique_suivant;
2581: }
2582:
2583: l_element_partage_courant = (*(*s_etat_processus)
2584: .l_liste_variables_partagees);
2585:
2586: while(l_element_partage_courant != NULL)
2587: {
2588: l_element_partage_suivant = (*l_element_partage_courant).suivant;
2589: free(l_element_partage_courant);
2590: l_element_partage_courant = l_element_partage_suivant;
2591: }
2592:
2593: if ((*s_etat_processus).entree_standard != NULL)
2594: {
2595: pclose((*s_etat_processus).entree_standard);
2596: (*s_etat_processus).entree_standard = NULL;
2597: }
2598:
2599: liberation(s_etat_processus, (*s_etat_processus).indep);
2600: liberation(s_etat_processus, (*s_etat_processus).depend);
2601:
2602: free((*s_etat_processus).label_x);
2603: free((*s_etat_processus).label_y);
2604: free((*s_etat_processus).label_z);
2605: free((*s_etat_processus).titre);
2606: free((*s_etat_processus).legende);
2607:
2608: liberation(s_etat_processus,
2609: (*s_etat_processus).parametres_courbes_de_niveau);
2610:
2611: if ((*s_etat_processus).instruction_derniere_erreur != NULL)
2612: {
2613: free((*s_etat_processus).instruction_derniere_erreur);
2614: (*s_etat_processus).instruction_derniere_erreur = NULL;
2615: }
2616:
2617: liberation_arbre_variables_partagees(s_etat_processus,
2618: (*(*s_etat_processus).s_arbre_variables_partagees));
2619: liberation_arbre_variables(s_etat_processus,
2620: (*s_etat_processus).s_arbre_variables, d_vrai);
2621: free((*s_etat_processus).pointeurs_caracteres_variables);
2622:
2623: l_element_courant = (*s_etat_processus).l_base_pile;
2624: while(l_element_courant != NULL)
2625: {
2626: l_element_suivant = (*l_element_courant).suivant;
2627:
2628: liberation(s_etat_processus, (*l_element_courant).donnee);
2629: free(l_element_courant);
2630:
2631: l_element_courant = l_element_suivant;
2632: }
2633:
2634: l_element_courant = (*s_etat_processus).l_base_pile_last;
2635: while(l_element_courant != NULL)
2636: {
2637: l_element_suivant = (*l_element_courant).suivant;
2638:
2639: liberation(s_etat_processus, (*l_element_courant).donnee);
2640: free(l_element_courant);
2641:
2642: l_element_courant = l_element_suivant;
2643: }
2644:
2645: l_element_courant = (*s_etat_processus).l_base_pile_contextes;
2646: while(l_element_courant != NULL)
2647: {
2648: l_element_suivant = (*l_element_courant).suivant;
2649:
2650: liberation(s_etat_processus, (*l_element_courant).donnee);
2651: free(l_element_courant);
2652:
2653: l_element_courant = l_element_suivant;
2654: }
2655:
2656: l_element_courant = (*s_etat_processus).l_base_pile_taille_contextes;
2657: while(l_element_courant != NULL)
2658: {
2659: l_element_suivant = (*l_element_courant).suivant;
2660:
2661: liberation(s_etat_processus, (*l_element_courant).donnee);
2662: free(l_element_courant);
2663:
2664: l_element_courant = l_element_suivant;
2665: }
2666:
2667: l_element_courant = (struct_liste_chainee *)
2668: (*s_etat_processus).l_base_pile_systeme;
2669: while(l_element_courant != NULL)
2670: {
2671: l_element_suivant = (struct_liste_chainee *)
2672: (*((struct_liste_pile_systeme *)
2673: l_element_courant)).suivant;
2674:
2675: liberation(s_etat_processus, (*((struct_liste_pile_systeme *)
2676: l_element_courant)).indice_boucle);
2677: liberation(s_etat_processus, (*((struct_liste_pile_systeme *)
2678: l_element_courant)).limite_indice_boucle);
2679: liberation(s_etat_processus, (*((struct_liste_pile_systeme *)
2680: l_element_courant)).objet_de_test);
2681:
2682: if ((*((struct_liste_pile_systeme *)
2683: l_element_courant)).nom_variable != NULL)
2684: {
2685: free((*((struct_liste_pile_systeme *)
2686: l_element_courant)).nom_variable);
2687: }
2688:
2689: free((struct_liste_pile_systeme *) l_element_courant);
2690:
2691: l_element_courant = l_element_suivant;
2692: }
2693:
2694: /*
2695: * Destruction des bibliothèques
2696: */
2697:
2698: l_element_courant = (*s_etat_processus).s_bibliotheques;
2699:
2700: while(l_element_courant != NULL)
2701: {
2702: l_element_suivant = (*l_element_courant).suivant;
2703:
2704: free((*((struct_bibliotheque *) (*l_element_courant).donnee)).nom);
2705:
2706: dlclose((*((struct_bibliotheque *) (*l_element_courant).donnee))
2707: .descripteur);
2708:
2709: free((*l_element_courant).donnee);
2710: free(l_element_courant);
2711:
2712: l_element_courant = l_element_suivant;
2713: }
2714:
2715: for(i = 0; i < (*s_etat_processus).nombre_instructions_externes; i++)
2716: {
2717: free((*s_etat_processus).s_instructions_externes[i].nom);
2718: free((*s_etat_processus).s_instructions_externes[i]
2719: .nom_bibliotheque);
2720: }
2721:
2722: if ((*s_etat_processus).nombre_instructions_externes != 0)
2723: {
2724: free((*s_etat_processus).s_instructions_externes);
2725: }
2726:
2727: l_element_courant = (struct_liste_chainee *)
2728: (*s_etat_processus).s_marques;
2729:
2730: while(l_element_courant != NULL)
2731: {
2732: free((*((struct_marque *) l_element_courant)).label);
2733: free((*((struct_marque *) l_element_courant)).position);
2734: l_element_suivant = (struct_liste_chainee *)
2735: (*((struct_marque *) l_element_courant)).suivant;
2736: free((struct_marque *) l_element_courant);
2737: l_element_courant = l_element_suivant;
2738: }
2739:
2740: free((*s_etat_processus).chemin_fichiers_temporaires);
2741:
2742: if ((*s_etat_processus).debug == d_vrai)
2743: if (((*s_etat_processus).type_debug &
2744: d_debug_processus) != 0)
2745: {
2746: if ((*s_etat_processus).langue == 'F')
2747: {
2748: printf("[%d] Arrêt du processus\n", (int) getpid());
2749: }
2750: else
2751: {
2752: printf("[%d] Stop process\n", (int) getpid());
2753: }
2754:
2755: fflush(stdout);
2756: }
2757:
2758: liberation(s_etat_processus, s_objet);
2759:
2760: free((*s_etat_processus).definitions_chainees);
2761: free((*s_etat_processus).nom_fichier_historique);
2762:
2763: for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++)
2764: {
2765: liberation(s_etat_processus,
2766: (*s_etat_processus).corps_interruptions[i]);
2767:
2768: l_element_courant = (*s_etat_processus)
2769: .pile_origine_interruptions[i];
2770:
2771: while(l_element_courant != NULL)
2772: {
2773: l_element_suivant = (*l_element_courant).suivant;
2774:
2775: liberation(s_etat_processus, (*l_element_courant).donnee);
2776: free(l_element_courant);
2777:
2778: l_element_courant = l_element_suivant;
2779: }
2780: }
2781:
2782: if ((*s_etat_processus).generateur_aleatoire != NULL)
2783: {
2784: liberation_generateur_aleatoire(s_etat_processus);
2785: }
2786:
2787: if ((*s_etat_processus).profilage == d_vrai)
2788: {
2789: ecriture_profil(s_etat_processus);
2790: liberation_profil(s_etat_processus);
2791: }
2792:
2793: closelog();
2794:
2795: retrait_thread(s_etat_processus);
2796:
2797: pthread_mutex_destroy(&((*s_etat_processus).mutex_pile_processus));
2798: pthread_mutex_destroy(&((*s_etat_processus).mutex_allocation));
2799: pthread_mutex_destroy(&((*s_etat_processus).mutex_interruptions));
2800: pthread_mutex_destroy(&((*s_etat_processus).mutex_signaux));
2801: pthread_mutex_destroy(&((*s_etat_processus).protection_liste_mutexes));
2802: pthread_mutex_destroy(&mutex_sections_critiques);
2803:
2804: # ifndef SEMAPHORES_NOMMES
2805: sem_post(&((*s_etat_processus).semaphore_fork));
2806: sem_destroy(&((*s_etat_processus).semaphore_fork));
2807: # else
2808: sem_post((*s_etat_processus).semaphore_fork);
2809: sem_destroy3((*s_etat_processus).semaphore_fork, getpid(),
2810: pthread_self(), SEM_FORK);
2811: # endif
2812:
2813: free((*s_etat_processus).localisation);
2814: free(s_argument_thread);
2815:
2816: clear_history();
2817:
2818: destruction_queue_signaux(s_etat_processus);
2819: liberation_contexte_cas(s_etat_processus);
2820: arret_thread_signaux(s_etat_processus);
2821: liberation_allocateur(s_etat_processus);
2822: liberation_allocateur_buffer(s_etat_processus);
2823: pthread_mutex_destroy(&((*s_etat_processus).mutex_allocation_buffer));
2824: sys_free(s_etat_processus);
2825:
2826: # ifdef DEBUG_MEMOIRE
2827: debug_memoire_verification();
2828: analyse_post_mortem();
2829: # endif
2830:
2831: exit(EXIT_SUCCESS);
2832: }
2833: else
2834: {
2835: (*s_etat_processus).erreur_systeme = d_es_processus;
2836: return;
2837: }
2838:
2839: // Si le pid existe déjà dans la pile des processus, il s'agit forcement
2840: // d'un processus moribond. On attend donc qu'il soit effectivement
2841: // libéré.
2842:
2843: do
2844: {
2845: l_element_courant = (struct_liste_chainee *)
2846: (*s_etat_processus).l_base_pile_processus;
2847: drapeau = d_faux;
2848:
2849: attente.tv_sec = 0;
2850: attente.tv_nsec = GRANULARITE_us * 1000;
2851:
2852: while(l_element_courant != NULL)
2853: {
2854: if ((*(*((struct_processus_fils *)
2855: (*(*l_element_courant).donnee).objet)).thread)
2856: .processus_detache == d_vrai)
2857: {
2858: if ((*(*((struct_processus_fils *)
2859: (*(*l_element_courant).donnee).objet)).thread).pid ==
2860: (*s_argument_thread).pid)
2861: {
2862: if (pthread_mutex_unlock(&((*s_etat_processus)
2863: .mutex_pile_processus)) != 0)
2864: {
2865: (*s_etat_processus).erreur_systeme = d_es_processus;
2866: return;
2867: }
2868:
2869: nanosleep(&attente, NULL);
2870: INCR_GRANULARITE(attente.tv_nsec);
2871:
2872: if (pthread_mutex_lock(&((*s_etat_processus)
2873: .mutex_pile_processus)) != 0)
2874: {
2875: (*s_etat_processus).erreur_systeme = d_es_processus;
2876: return;
2877: }
2878:
2879: drapeau = d_vrai;
2880: break;
2881: }
2882: }
2883:
2884: scrutation_interruptions(s_etat_processus);
2885: l_element_courant = (*l_element_courant).suivant;
2886: }
2887: } while(drapeau == d_vrai);
2888:
2889: if (empilement(s_etat_processus,
2890: (struct_liste_chainee **) &((*s_etat_processus)
2891: .l_base_pile_processus), s_objet_systeme) == d_erreur)
2892: {
2893: pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus));
2894: return;
2895: }
2896:
2897: if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
2898: s_objet) == d_erreur)
2899: {
2900: pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus));
2901: return;
2902: }
2903:
2904: // On attend une donnée fictive pour être sûr que le segment de mémoire
2905: // partagée destiné à la gestion des signaux est bien initialisé.
2906:
2907: attente.tv_sec = 0;
2908: attente.tv_nsec = GRANULARITE_us * 1000;
2909:
2910: while(read_atomic(s_etat_processus,
2911: pipe_initialisation_segment_signaux[0],
2912: &caractere, sizeof(caractere)) == 0)
2913: {
2914: scrutation_interruptions(s_etat_processus);
2915: nanosleep(&attente, NULL);
2916: INCR_GRANULARITE(attente.tv_nsec);
2917: }
2918:
2919: close(pipe_initialisation_segment_signaux[0]);
2920: close(pipe_initialisation_segment_signaux[1]);
2921:
2922: // Le fils peut être présent sans être en attente du signal de départ.
2923:
2924: if (envoi_signal_processus((*s_argument_thread).pid, rpl_sigstart) != 0)
2925: {
2926: (*s_etat_processus).erreur_systeme = d_es_processus;
2927: pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus));
2928: return;
2929: }
2930:
2931: if (pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus)) != 0)
2932: {
2933: (*s_etat_processus).erreur_systeme = d_es_processus;
2934: return;
2935: }
2936:
2937: return;
2938: }
2939:
2940: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>