1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.3
4: Copyright (C) 1989-2011 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: Procédures de gestion par thread des variables issues des gestionnaires
29: de signaux
30: ================================================================================
31: Entrée : variable globale
32: --------------------------------------------------------------------------------
33: Sortie : variable globale modifiée
34: --------------------------------------------------------------------------------
35: Effets de bord : néant
36: ================================================================================
37: */
38:
39: typedef struct thread
40: {
41: pid_t pid;
42: pthread_t tid;
43:
44: logical1 thread_principal;
45:
46: struct_processus *s_etat_processus;
47: } struct_thread;
48:
49: typedef struct liste_chainee_volatile
50: {
51: volatile struct liste_chainee_volatile *suivant;
52: volatile void *donnee;
53: } struct_liste_chainee_volatile;
54:
55:
56: static volatile struct_liste_chainee_volatile *liste_threads
57: = NULL;
58: static volatile struct_liste_chainee_volatile *liste_threads_surveillance
59: = NULL;
60: static volatile int code_erreur_gsl = 0;
61:
62: unsigned char *racine_segment;
63:
64: static pthread_mutex_t mutex_interruptions
65: = PTHREAD_MUTEX_INITIALIZER;
66:
67: void
68: modification_pid_thread_pere(struct_processus *s_etat_processus)
69: {
70: // La variable existe toujours et aucun thread concurrent ne peut
71: // la modifier puisque cette routine ne peut être appelée que depuis
72: // DAEMON.
73:
74: (*((struct_thread *) (*liste_threads).donnee)).pid =
75: (*s_etat_processus).pid_processus_pere;
76:
77: return;
78: }
79:
80: void
81: insertion_thread(struct_processus *s_etat_processus, logical1 thread_principal)
82: {
83: volatile struct_liste_chainee_volatile *l_nouvel_objet;
84:
85: if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
86: == NULL)
87: {
88: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
89: return;
90: }
91:
92: if (((*l_nouvel_objet).donnee = malloc(sizeof(struct_thread))) == NULL)
93: {
94: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
95: return;
96: }
97:
98: (*((struct_thread *) (*l_nouvel_objet).donnee)).pid = getpid();
99: (*((struct_thread *) (*l_nouvel_objet).donnee)).tid = pthread_self();
100: (*((struct_thread *) (*l_nouvel_objet).donnee)).thread_principal =
101: thread_principal;
102: (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus =
103: s_etat_processus;
104:
105: if (pthread_mutex_lock(&mutex_liste_threads) != 0)
106: {
107: (*s_etat_processus).erreur_systeme = d_es_processus;
108: return;
109: }
110:
111: (*l_nouvel_objet).suivant = liste_threads;
112: liste_threads = l_nouvel_objet;
113:
114: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
115: {
116: (*s_etat_processus).erreur_systeme = d_es_processus;
117: return;
118: }
119:
120: return;
121: }
122:
123: void
124: insertion_thread_surveillance(struct_processus *s_etat_processus,
125: struct_descripteur_thread *s_argument_thread)
126: {
127: volatile struct_liste_chainee_volatile *l_nouvel_objet;
128:
129: if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
130: == NULL)
131: {
132: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
133: return;
134: }
135:
136: if (pthread_mutex_lock(&mutex_liste_threads) != 0)
137: {
138: (*s_etat_processus).erreur_systeme = d_es_processus;
139: return;
140: }
141:
142: pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references));
143: (*s_argument_thread).nombre_references++;
144: pthread_mutex_unlock(&((*s_argument_thread).mutex_nombre_references));
145:
146: (*l_nouvel_objet).suivant = liste_threads_surveillance;
147: (*l_nouvel_objet).donnee = (void *) s_argument_thread;
148:
149: liste_threads_surveillance = l_nouvel_objet;
150:
151: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
152: {
153: (*s_etat_processus).erreur_systeme = d_es_processus;
154: return;
155: }
156:
157: return;
158: }
159:
160: void
161: retrait_thread(struct_processus *s_etat_processus)
162: {
163: volatile struct_liste_chainee_volatile *l_element_precedent;
164: volatile struct_liste_chainee_volatile *l_element_courant;
165:
166: if (pthread_mutex_lock(&mutex_liste_threads) != 0)
167: {
168: (*s_etat_processus).erreur_systeme = d_es_processus;
169: return;
170: }
171:
172: l_element_precedent = NULL;
173: l_element_courant = liste_threads;
174:
175: while(l_element_courant != NULL)
176: {
177: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
178: == getpid()) && (pthread_equal((*((struct_thread *)
179: (*l_element_courant).donnee)).tid, pthread_self()) != 0))
180: {
181: break;
182: }
183:
184: l_element_precedent = l_element_courant;
185: l_element_courant = (*l_element_courant).suivant;
186: }
187:
188: if (l_element_courant == NULL)
189: {
190: pthread_mutex_unlock(&mutex_liste_threads);
191: (*s_etat_processus).erreur_systeme = d_es_processus;
192: return;
193: }
194:
195: if (l_element_precedent == NULL)
196: {
197: liste_threads = (*l_element_courant).suivant;
198: }
199: else
200: {
201: (*l_element_precedent).suivant = (*l_element_courant).suivant;
202: }
203:
204: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
205: {
206: (*s_etat_processus).erreur_systeme = d_es_processus;
207: return;
208: }
209:
210: free((void *) (*l_element_courant).donnee);
211: free((struct_liste_chainee_volatile *) l_element_courant);
212:
213: return;
214: }
215:
216: void
217: retrait_thread_surveillance(struct_processus *s_etat_processus,
218: struct_descripteur_thread *s_argument_thread)
219: {
220: volatile struct_liste_chainee_volatile *l_element_precedent;
221: volatile struct_liste_chainee_volatile *l_element_courant;
222:
223: if (pthread_mutex_lock(&mutex_liste_threads) != 0)
224: {
225: (*s_etat_processus).erreur_systeme = d_es_processus;
226: return;
227: }
228:
229: l_element_precedent = NULL;
230: l_element_courant = liste_threads_surveillance;
231:
232: while(l_element_courant != NULL)
233: {
234: if ((*l_element_courant).donnee == (void *) s_argument_thread)
235: {
236: break;
237: }
238:
239: l_element_precedent = l_element_courant;
240: l_element_courant = (*l_element_courant).suivant;
241: }
242:
243: if (l_element_courant == NULL)
244: {
245: pthread_mutex_unlock(&mutex_liste_threads);
246: (*s_etat_processus).erreur_systeme = d_es_processus;
247: return;
248: }
249:
250: if (l_element_precedent == NULL)
251: {
252: liste_threads_surveillance = (*l_element_courant).suivant;
253: }
254: else
255: {
256: (*l_element_precedent).suivant = (*l_element_courant).suivant;
257: }
258:
259: if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
260: != 0)
261: {
262: pthread_mutex_unlock(&mutex_liste_threads);
263: (*s_etat_processus).erreur_systeme = d_es_processus;
264: return;
265: }
266:
267: (*s_argument_thread).nombre_references--;
268:
269: BUG((*s_argument_thread).nombre_references < 0,
270: printf("(*s_argument_thread).nombre_references = %d\n",
271: (int) (*s_argument_thread).nombre_references));
272:
273: if ((*s_argument_thread).nombre_references == 0)
274: {
275: if (pthread_mutex_unlock(&((*s_argument_thread)
276: .mutex_nombre_references)) != 0)
277: {
278: pthread_mutex_unlock(&mutex_liste_threads);
279: (*s_etat_processus).erreur_systeme = d_es_processus;
280: return;
281: }
282:
283: pthread_mutex_destroy(&((*s_argument_thread).mutex));
284: pthread_mutex_destroy(&((*s_argument_thread).mutex_nombre_references));
285: free(s_argument_thread);
286: }
287: else
288: {
289: if (pthread_mutex_unlock(&((*s_argument_thread)
290: .mutex_nombre_references)) != 0)
291: {
292: pthread_mutex_unlock(&mutex_liste_threads);
293: (*s_etat_processus).erreur_systeme = d_es_processus;
294: return;
295: }
296: }
297:
298: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
299: {
300: (*s_etat_processus).erreur_systeme = d_es_processus;
301: return;
302: }
303:
304: free((struct_liste_chainee_volatile *) l_element_courant);
305: return;
306: }
307:
308: void
309: verrouillage_threads_concurrents(struct_processus *s_etat_processus)
310: {
311: volatile struct_liste_chainee_volatile *l_element_courant;
312:
313: if (pthread_mutex_lock(&mutex_liste_threads) != 0)
314: {
315: (*s_etat_processus).erreur_systeme = d_es_processus;
316: return;
317: }
318:
319: l_element_courant = liste_threads;
320:
321: while(l_element_courant != NULL)
322: {
323: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
324: == getpid()) && (pthread_equal((*((struct_thread *)
325: (*l_element_courant).donnee)).tid, pthread_self()) == 0))
326: {
327: # ifndef SEMAPHORES_NOMMES
328: while(sem_wait(&((*(*((struct_thread *) (*l_element_courant)
329: .donnee)).s_etat_processus).semaphore_fork)) == -1)
330: # else
331: while(sem_wait((*(*((struct_thread *) (*l_element_courant)
332: .donnee)).s_etat_processus).semaphore_fork) == -1)
333: # endif
334: {
335: (*s_etat_processus).erreur_systeme = d_es_processus;
336: return;
337: }
338: }
339:
340: l_element_courant = (*l_element_courant).suivant;
341: }
342:
343: return;
344: }
345:
346: void
347: deverrouillage_threads_concurrents(struct_processus *s_etat_processus)
348: {
349: volatile struct_liste_chainee_volatile *l_element_courant;
350:
351: l_element_courant = liste_threads;
352:
353: while(l_element_courant != NULL)
354: {
355: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
356: == getpid()) && (pthread_equal((*((struct_thread *)
357: (*l_element_courant).donnee)).tid, pthread_self()) == 0))
358: {
359: # ifndef SEMAPHORES_NOMMES
360: if (sem_post(&((*(*((struct_thread *)
361: (*l_element_courant).donnee)).s_etat_processus)
362: .semaphore_fork)) != 0)
363: # else
364: if (sem_post((*(*((struct_thread *)
365: (*l_element_courant).donnee)).s_etat_processus)
366: .semaphore_fork) != 0)
367: # endif
368: {
369: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
370: {
371: (*s_etat_processus).erreur_systeme = d_es_processus;
372: return;
373: }
374:
375: (*s_etat_processus).erreur_systeme = d_es_processus;
376: return;
377: }
378: }
379:
380: l_element_courant = (*l_element_courant).suivant;
381: }
382:
383: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
384: {
385: (*s_etat_processus).erreur_systeme = d_es_processus;
386: return;
387: }
388:
389: return;
390: }
391:
392: void
393: liberation_threads(struct_processus *s_etat_processus)
394: {
395: logical1 suppression_variables_partagees;
396:
397: struct_descripteur_thread *s_argument_thread;
398:
399: struct_processus *candidat;
400:
401: unsigned long i;
402:
403: void *element_candidat;
404: void *element_courant;
405: void *element_suivant;
406:
407: volatile struct_liste_chainee_volatile *l_element_courant;
408: volatile struct_liste_chainee_volatile *l_element_suivant;
409:
410: if (pthread_mutex_lock(&mutex_liste_threads) == -1)
411: {
412: (*s_etat_processus).erreur_systeme = d_es_processus;
413: return;
414: }
415:
416: l_element_courant = liste_threads;
417: suppression_variables_partagees = d_faux;
418:
419: while(l_element_courant != NULL)
420: {
421: if ((*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus
422: != s_etat_processus)
423: {
424: candidat = s_etat_processus;
425: s_etat_processus = (*((struct_thread *)
426: (*l_element_courant).donnee)).s_etat_processus;
427: free((*s_etat_processus).localisation);
428:
429: // (*s_etat_processus).instruction_courante peut pointer sur
430: // n'importe quoi (une instruction courante ou un champ d'une
431: // structure objet). On ne le libère pas quitte à avoir une
432: // petite fuite mémoire dans le processus fils.
433:
434: if ((*s_etat_processus).instruction_courante != NULL)
435: {
436: //free((*s_etat_processus).instruction_courante);
437: }
438:
439: close((*s_etat_processus).pipe_acquittement);
440: close((*s_etat_processus).pipe_donnees);
441: close((*s_etat_processus).pipe_injections);
442: close((*s_etat_processus).pipe_nombre_injections);
443: close((*s_etat_processus).pipe_interruptions);
444: close((*s_etat_processus).pipe_nombre_objets_attente);
445: close((*s_etat_processus).pipe_nombre_interruptions_attente);
446:
447: liberation(s_etat_processus, (*s_etat_processus).at_exit);
448:
449: if ((*s_etat_processus).nom_fichier_impression != NULL)
450: {
451: free((*s_etat_processus).nom_fichier_impression);
452: }
453:
454: while((*s_etat_processus).fichiers_graphiques != NULL)
455: {
456: free((*(*s_etat_processus).fichiers_graphiques).nom);
457:
458: if ((*(*s_etat_processus).fichiers_graphiques).legende != NULL)
459: {
460: free((*(*s_etat_processus).fichiers_graphiques).legende);
461: }
462:
463: element_courant = (*s_etat_processus).fichiers_graphiques;
464: (*s_etat_processus).fichiers_graphiques =
465: (*(*s_etat_processus).fichiers_graphiques).suivant;
466:
467: free(element_courant);
468: }
469:
470: if ((*s_etat_processus).entree_standard != NULL)
471: {
472: pclose((*s_etat_processus).entree_standard);
473: }
474:
475: if ((*s_etat_processus).generateur_aleatoire != NULL)
476: {
477: liberation_generateur_aleatoire(s_etat_processus);
478: }
479:
480: if ((*s_etat_processus).instruction_derniere_erreur != NULL)
481: {
482: free((*s_etat_processus).instruction_derniere_erreur);
483: (*s_etat_processus).instruction_derniere_erreur = NULL;
484: }
485:
486: element_courant = (void *) (*s_etat_processus)
487: .l_base_pile_processus;
488: while(element_courant != NULL)
489: {
490: s_argument_thread = (struct_descripteur_thread *)
491: (*((struct_liste_chainee *) element_courant)).donnee;
492:
493: if (pthread_mutex_lock(&((*s_argument_thread)
494: .mutex_nombre_references)) != 0)
495: {
496: (*s_etat_processus).erreur_systeme = d_es_processus;
497: pthread_mutex_unlock(&mutex_liste_threads);
498: return;
499: }
500:
501: (*s_argument_thread).nombre_references--;
502:
503: BUG((*s_argument_thread).nombre_references < 0,
504: printf("(*s_argument_thread).nombre_references = %d\n",
505: (int) (*s_argument_thread).nombre_references));
506:
507: if ((*s_argument_thread).nombre_references == 0)
508: {
509: close((*s_argument_thread).pipe_objets[0]);
510: close((*s_argument_thread).pipe_acquittement[1]);
511: close((*s_argument_thread).pipe_injections[1]);
512: close((*s_argument_thread).pipe_nombre_injections[1]);
513: close((*s_argument_thread).pipe_nombre_objets_attente[0]);
514: close((*s_argument_thread).pipe_interruptions[0]);
515: close((*s_argument_thread)
516: .pipe_nombre_interruptions_attente[0]);
517:
518: if (pthread_mutex_unlock(&((*s_argument_thread)
519: .mutex_nombre_references)) != 0)
520: {
521: (*s_etat_processus).erreur_systeme = d_es_processus;
522: pthread_mutex_unlock(&mutex_liste_threads);
523: return;
524: }
525:
526: pthread_mutex_destroy(&((*s_argument_thread).mutex));
527: pthread_mutex_destroy(&((*s_argument_thread)
528: .mutex_nombre_references));
529:
530: if ((*s_argument_thread).processus_detache == d_faux)
531: {
532: if ((*s_argument_thread).destruction_objet == d_vrai)
533: {
534: liberation(s_etat_processus, (*s_argument_thread)
535: .argument);
536: }
537: }
538:
539: free(s_argument_thread);
540: }
541: else
542: {
543: if (pthread_mutex_unlock(&((*s_argument_thread)
544: .mutex_nombre_references)) != 0)
545: {
546: (*s_etat_processus).erreur_systeme = d_es_processus;
547: pthread_mutex_unlock(&mutex_liste_threads);
548: return;
549: }
550: }
551:
552: element_suivant = (*((struct_liste_chainee *) element_courant))
553: .suivant;
554: free(element_courant);
555: element_courant = element_suivant;
556: }
557:
558: (*s_etat_processus).l_base_pile_processus = NULL;
559:
560: pthread_mutex_trylock(&((*(*s_etat_processus).indep).mutex));
561: pthread_mutex_unlock(&((*(*s_etat_processus).indep).mutex));
562: liberation(s_etat_processus, (*s_etat_processus).indep);
563:
564: pthread_mutex_trylock(&((*(*s_etat_processus).depend).mutex));
565: pthread_mutex_unlock(&((*(*s_etat_processus).depend).mutex));
566: liberation(s_etat_processus, (*s_etat_processus).depend);
567:
568: free((*s_etat_processus).label_x);
569: free((*s_etat_processus).label_y);
570: free((*s_etat_processus).label_z);
571: free((*s_etat_processus).titre);
572: free((*s_etat_processus).legende);
573:
574: pthread_mutex_trylock(&((*(*s_etat_processus)
575: .parametres_courbes_de_niveau).mutex));
576: pthread_mutex_unlock(&((*(*s_etat_processus)
577: .parametres_courbes_de_niveau).mutex));
578: liberation(s_etat_processus, (*s_etat_processus)
579: .parametres_courbes_de_niveau);
580:
581: for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++)
582: {
583: if ((*s_etat_processus).corps_interruptions[i] != NULL)
584: {
585: pthread_mutex_trylock(&((*(*s_etat_processus)
586: .corps_interruptions[i]).mutex));
587: pthread_mutex_unlock(&((*(*s_etat_processus)
588: .corps_interruptions[i]).mutex));
589:
590: liberation(s_etat_processus,
591: (*s_etat_processus).corps_interruptions[i]);
592: }
593:
594: element_courant = (*s_etat_processus)
595: .pile_origine_interruptions[i];
596:
597: while(element_courant != NULL)
598: {
599: element_suivant = (*((struct_liste_chainee *)
600: element_courant)).suivant;
601:
602: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
603: element_courant)).donnee).mutex));
604: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
605: element_courant)).donnee).mutex));
606:
607: liberation(s_etat_processus,
608: (*((struct_liste_chainee *) element_courant))
609: .donnee);
610: free(element_courant);
611:
612: element_courant = element_suivant;
613: }
614: }
615:
616: liberation_arbre_variables(s_etat_processus,
617: (*s_etat_processus).s_arbre_variables, d_faux);
618:
619: for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)
620: {
621: pthread_mutex_trylock(&((*(*s_etat_processus)
622: .s_liste_variables_statiques[i].objet).mutex));
623: pthread_mutex_unlock(&((*(*s_etat_processus)
624: .s_liste_variables_statiques[i].objet).mutex));
625:
626: liberation(s_etat_processus, (*s_etat_processus)
627: .s_liste_variables_statiques[i].objet);
628: free((*s_etat_processus).s_liste_variables_statiques[i].nom);
629: }
630:
631: free((*s_etat_processus).s_liste_variables_statiques);
632:
633: // Ne peut être effacé qu'une seule fois
634: if (suppression_variables_partagees == d_faux)
635: {
636: suppression_variables_partagees = d_vrai;
637:
638: for(i = 0; i < (*(*s_etat_processus)
639: .s_liste_variables_partagees).nombre_variables; i++)
640: {
641: pthread_mutex_trylock(&((*(*(*s_etat_processus)
642: .s_liste_variables_partagees).table[i].objet)
643: .mutex));
644: pthread_mutex_unlock(&((*(*(*s_etat_processus)
645: .s_liste_variables_partagees).table[i].objet)
646: .mutex));
647:
648: liberation(s_etat_processus, (*(*s_etat_processus)
649: .s_liste_variables_partagees).table[i].objet);
650: free((*(*s_etat_processus).s_liste_variables_partagees)
651: .table[i].nom);
652: }
653:
654: if ((*(*s_etat_processus).s_liste_variables_partagees).table
655: != NULL)
656: {
657: free((struct_variable_partagee *) (*(*s_etat_processus)
658: .s_liste_variables_partagees).table);
659: }
660:
661: pthread_mutex_trylock(&((*(*s_etat_processus)
662: .s_liste_variables_partagees).mutex));
663: pthread_mutex_unlock(&((*(*s_etat_processus)
664: .s_liste_variables_partagees).mutex));
665: }
666:
667: element_courant = (*s_etat_processus).l_base_pile;
668: while(element_courant != NULL)
669: {
670: element_suivant = (*((struct_liste_chainee *)
671: element_courant)).suivant;
672:
673: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
674: element_courant)).donnee).mutex));
675: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
676: element_courant)).donnee).mutex));
677:
678: liberation(s_etat_processus,
679: (*((struct_liste_chainee *)
680: element_courant)).donnee);
681: free((struct_liste_chainee *) element_courant);
682:
683: element_courant = element_suivant;
684: }
685:
686: element_courant = (*s_etat_processus).l_base_pile_contextes;
687: while(element_courant != NULL)
688: {
689: element_suivant = (*((struct_liste_chainee *)
690: element_courant)).suivant;
691:
692: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
693: element_courant)).donnee).mutex));
694: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
695: element_courant)).donnee).mutex));
696: liberation(s_etat_processus, (*((struct_liste_chainee *)
697: element_courant)).donnee);
698: free((struct_liste_chainee *) element_courant);
699:
700: element_courant = element_suivant;
701: }
702:
703: element_courant = (*s_etat_processus).l_base_pile_taille_contextes;
704: while(element_courant != NULL)
705: {
706: element_suivant = (*((struct_liste_chainee *)
707: element_courant)).suivant;
708:
709: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
710: element_courant)).donnee).mutex));
711: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
712: element_courant)).donnee).mutex));
713: liberation(s_etat_processus,
714: (*((struct_liste_chainee *)
715: element_courant)).donnee);
716: free((struct_liste_chainee *) element_courant);
717:
718: element_courant = element_suivant;
719: }
720:
721: for(i = 0; i < (*s_etat_processus).nombre_instructions_externes;
722: i++)
723: {
724: free((*s_etat_processus).s_instructions_externes[i].nom);
725: free((*s_etat_processus).s_instructions_externes[i]
726: .nom_bibliotheque);
727: }
728:
729: if ((*s_etat_processus).nombre_instructions_externes != 0)
730: {
731: free((*s_etat_processus).s_instructions_externes);
732: }
733:
734: element_courant = (*s_etat_processus).s_bibliotheques;
735: while(element_courant != NULL)
736: {
737: element_suivant = (*((struct_liste_chainee *)
738: element_courant)).suivant;
739:
740: element_candidat = (*candidat).s_bibliotheques;
741: while(element_candidat != NULL)
742: {
743: if (((*((struct_bibliotheque *) (*((struct_liste_chainee *)
744: element_courant)).donnee))
745: .descripteur == (*((struct_bibliotheque *)
746: (*((struct_liste_chainee *) element_candidat))
747: .donnee)).descripteur) &&
748: ((*((struct_bibliotheque *)
749: (*((struct_liste_chainee *) element_courant))
750: .donnee)).pid == (*((struct_bibliotheque *)
751: (*((struct_liste_chainee *) element_candidat))
752: .donnee)).pid) && (pthread_equal(
753: (*((struct_bibliotheque *)
754: (*((struct_liste_chainee *) element_courant))
755: .donnee)).tid, (*((struct_bibliotheque *)
756: (*((struct_liste_chainee *) element_candidat))
757: .donnee)).tid) != 0))
758: {
759: break;
760: }
761:
762: element_candidat = (*((struct_liste_chainee *)
763: element_candidat)).suivant;
764: }
765:
766: if (element_candidat == NULL)
767: {
768: dlclose((*((struct_bibliotheque *)
769: (*((struct_liste_chainee *) element_courant))
770: .donnee)).descripteur);
771: }
772:
773: free((*((struct_bibliotheque *)
774: (*((struct_liste_chainee *)
775: element_courant)).donnee)).nom);
776: free((*((struct_liste_chainee *) element_courant)).donnee);
777: free(element_courant);
778:
779: element_courant = element_suivant;
780: }
781:
782: element_courant = (*s_etat_processus).l_base_pile_last;
783: while(element_courant != NULL)
784: {
785: element_suivant = (*((struct_liste_chainee *)
786: element_courant)).suivant;
787:
788: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
789: element_courant)).donnee).mutex));
790: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
791: element_courant)).donnee).mutex));
792: liberation(s_etat_processus,
793: (*((struct_liste_chainee *) element_courant)).donnee);
794: free(element_courant);
795:
796: element_courant = element_suivant;
797: }
798:
799: element_courant = (*s_etat_processus).l_base_pile_systeme;
800: while(element_courant != NULL)
801: {
802: element_suivant = (*((struct_liste_pile_systeme *)
803: element_courant)).suivant;
804:
805: if ((*((struct_liste_pile_systeme *)
806: element_courant)).indice_boucle != NULL)
807: {
808: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
809: element_courant)).indice_boucle).mutex));
810: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
811: element_courant)).indice_boucle).mutex));
812: }
813:
814: liberation(s_etat_processus,
815: (*((struct_liste_pile_systeme *)
816: element_courant)).indice_boucle);
817:
818: if ((*((struct_liste_pile_systeme *)
819: element_courant)).limite_indice_boucle != NULL)
820: {
821: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
822: element_courant)).limite_indice_boucle).mutex));
823: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
824: element_courant)).limite_indice_boucle).mutex));
825: }
826:
827: liberation(s_etat_processus,
828: (*((struct_liste_pile_systeme *)
829: element_courant)).limite_indice_boucle);
830:
831: if ((*((struct_liste_pile_systeme *)
832: element_courant)).objet_de_test != NULL)
833: {
834: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
835: element_courant)).objet_de_test).mutex));
836: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
837: element_courant)).objet_de_test).mutex));
838: }
839:
840: liberation(s_etat_processus,
841: (*((struct_liste_pile_systeme *)
842: element_courant)).objet_de_test);
843:
844: if ((*((struct_liste_pile_systeme *)
845: element_courant)).nom_variable != NULL)
846: {
847: free((*((struct_liste_pile_systeme *)
848: element_courant)).nom_variable);
849: }
850:
851: free(element_courant);
852:
853: element_courant = element_suivant;
854: }
855:
856: element_courant = (*s_etat_processus).s_fichiers;
857: while(element_courant != NULL)
858: {
859: element_suivant = (*((struct_liste_chainee *)
860: element_courant)).suivant;
861:
862: element_candidat = (*candidat).s_fichiers;
863: while(element_candidat != NULL)
864: {
865: if (((*((struct_descripteur_fichier *)
866: (*((struct_liste_chainee *) element_courant))
867: .donnee)).pid ==
868: (*((struct_descripteur_fichier *)
869: (*((struct_liste_chainee *) element_candidat))
870: .donnee)).pid) && (pthread_equal(
871: (*((struct_descripteur_fichier *)
872: (*((struct_liste_chainee *) element_courant))
873: .donnee)).tid, (*((struct_descripteur_fichier *)
874: (*((struct_liste_chainee *) element_candidat))
875: .donnee)).tid) != 0))
876: {
877: if ((*((struct_descripteur_fichier *)
878: (*((struct_liste_chainee *) element_courant))
879: .donnee)).type ==
880: (*((struct_descripteur_fichier *)
881: (*((struct_liste_chainee *) element_candidat))
882: .donnee)).type)
883: {
884: if ((*((struct_descripteur_fichier *)
885: (*((struct_liste_chainee *)
886: element_candidat)).donnee)).type == 'C')
887: {
888: if ((*((struct_descripteur_fichier *)
889: (*((struct_liste_chainee *)
890: element_courant)).donnee))
891: .descripteur_c ==
892: (*((struct_descripteur_fichier *)
893: (*((struct_liste_chainee *)
894: element_candidat)).donnee))
895: .descripteur_c)
896: {
897: break;
898: }
899: }
900: else
901: {
902: if (((*((struct_descripteur_fichier *)
903: (*((struct_liste_chainee *)
904: element_courant)).donnee))
905: .descripteur_sqlite ==
906: (*((struct_descripteur_fichier *)
907: (*((struct_liste_chainee *)
908: element_candidat)).donnee))
909: .descripteur_sqlite) &&
910: ((*((struct_descripteur_fichier *)
911: (*((struct_liste_chainee *)
912: element_courant)).donnee))
913: .descripteur_c ==
914: (*((struct_descripteur_fichier *)
915: (*((struct_liste_chainee *)
916: element_candidat)).donnee))
917: .descripteur_c))
918: {
919: break;
920: }
921: }
922: }
923: }
924:
925: element_candidat = (*((struct_liste_chainee *)
926: element_candidat)).suivant;
927: }
928:
929: if (element_candidat == NULL)
930: {
931: fclose((*((struct_descripteur_fichier *)
932: (*((struct_liste_chainee *) element_courant))
933: .donnee)).descripteur_c);
934:
935: if ((*((struct_descripteur_fichier *)
936: (*((struct_liste_chainee *) element_courant))
937: .donnee)).type != 'C')
938: {
939: sqlite3_close((*((struct_descripteur_fichier *)
940: (*((struct_liste_chainee *) element_courant))
941: .donnee)).descripteur_sqlite);
942: }
943: }
944:
945: free((*((struct_descripteur_fichier *)
946: (*((struct_liste_chainee *)
947: element_courant)).donnee)).nom);
948: free((struct_descripteur_fichier *)
949: (*((struct_liste_chainee *)
950: element_courant)).donnee);
951: free(element_courant);
952:
953: element_courant = element_suivant;
954: }
955:
956: element_courant = (*s_etat_processus).s_sockets;
957: while(element_courant != NULL)
958: {
959: element_suivant = (*((struct_liste_chainee *)
960: element_courant)).suivant;
961:
962: element_candidat = (*candidat).s_sockets;
963: while(element_candidat != NULL)
964: {
965: if (((*((struct_socket *)
966: (*((struct_liste_chainee *) element_courant))
967: .donnee)).socket == (*((struct_socket *)
968: (*((struct_liste_chainee *) element_candidat))
969: .donnee)).socket) &&
970: ((*((struct_socket *)
971: (*((struct_liste_chainee *) element_courant))
972: .donnee)).pid == (*((struct_socket *)
973: (*((struct_liste_chainee *) element_candidat))
974: .donnee)).pid) && (pthread_equal(
975: (*((struct_socket *)
976: (*((struct_liste_chainee *) element_courant))
977: .donnee)).tid, (*((struct_socket *)
978: (*((struct_liste_chainee *) element_candidat))
979: .donnee)).tid) != 0))
980: {
981: break;
982: }
983:
984: element_candidat = (*((struct_liste_chainee *)
985: element_candidat)).suivant;
986: }
987:
988: if (element_candidat == NULL)
989: {
990: if ((*((struct_socket *) (*((struct_liste_chainee *)
991: element_courant)).donnee)).socket_connectee
992: == d_vrai)
993: {
994: shutdown((*((struct_socket *)
995: (*((struct_liste_chainee *) element_courant))
996: .donnee)).socket, SHUT_RDWR);
997: }
998:
999: close((*((struct_socket *)
1000: (*((struct_liste_chainee *) element_courant))
1001: .donnee)).socket);
1002: }
1003:
1004: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1005: element_courant)).donnee).mutex));
1006: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1007: element_courant)).donnee).mutex));
1008:
1009: liberation(s_etat_processus,
1010: (*((struct_liste_chainee *)
1011: element_courant)).donnee);
1012: free(element_courant);
1013:
1014: element_courant = element_suivant;
1015: }
1016:
1017: /*
1018: ================================================================================
1019: À noter : on ne ferme pas la connexion car la conséquence immédiate est
1020: une destruction de l'objet pour le processus père.
1021: ================================================================================
1022:
1023: element_courant = (*s_etat_processus).s_connecteurs_sql;
1024: while(element_courant != NULL)
1025: {
1026: element_suivant = (*((struct_liste_chainee *)
1027: element_courant)).suivant;
1028:
1029: element_candidat = (*candidat).s_connecteurs_sql;
1030: while(element_candidat != NULL)
1031: {
1032: if (((
1033: #ifdef MYSQL_SUPPORT
1034: ((*((struct_connecteur_sql *)
1035: (*((struct_liste_chainee *) element_courant))
1036: .donnee)).descripteur.mysql ==
1037: (*((struct_connecteur_sql *)
1038: (*((struct_liste_chainee *) element_candidat))
1039: .donnee)).descripteur.mysql)
1040: &&
1041: (strcmp((*((struct_connecteur_sql *)
1042: (*((struct_liste_chainee *) element_courant))
1043: .donnee)).type, "MYSQL") == 0)
1044: &&
1045: (strcmp((*((struct_connecteur_sql *)
1046: (*((struct_liste_chainee *) element_candidat))
1047: .donnee)).type, "MYSQL") == 0)
1048: #else
1049: 0
1050: #endif
1051: ) || (
1052: #ifdef POSTGRESQL_SUPPORT
1053: ((*((struct_connecteur_sql *)
1054: (*((struct_liste_chainee *) element_courant))
1055: .donnee)).descripteur.postgresql ==
1056: (*((struct_connecteur_sql *)
1057: (*((struct_liste_chainee *) element_candidat))
1058: .donnee)).descripteur.postgresql)
1059: &&
1060: (strcmp((*((struct_connecteur_sql *)
1061: (*((struct_liste_chainee *) element_courant))
1062: .donnee)).type, "POSTGRESQL") == 0)
1063: &&
1064: (strcmp((*((struct_connecteur_sql *)
1065: (*((struct_liste_chainee *) element_candidat))
1066: .donnee)).type, "POSTGRESQL") == 0)
1067: #else
1068: 0
1069: #endif
1070: )) &&
1071: ((*((struct_connecteur_sql *)
1072: (*((struct_liste_chainee *) element_courant))
1073: .donnee)).pid == (*((struct_connecteur_sql *)
1074: (*((struct_liste_chainee *) element_candidat))
1075: .donnee)).pid) && (pthread_equal(
1076: (*((struct_connecteur_sql *)
1077: (*((struct_liste_chainee *) element_courant))
1078: .donnee)).tid, (*((struct_connecteur_sql *)
1079: (*((struct_liste_chainee *) element_candidat))
1080: .donnee)).tid) != 0))
1081: {
1082: break;
1083: }
1084:
1085: element_candidat = (*((struct_liste_chainee *)
1086: element_candidat)).suivant;
1087: }
1088:
1089: if (element_candidat == NULL)
1090: {
1091: sqlclose((*((struct_liste_chainee *) element_courant))
1092: .donnee);
1093: }
1094:
1095: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1096: element_courant)).donnee).mutex));
1097: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1098: element_courant)).donnee).mutex));
1099:
1100: liberation(s_etat_processus, (*((struct_liste_chainee *)
1101: element_courant)).donnee);
1102: free(element_courant);
1103:
1104: element_courant = element_suivant;
1105: }
1106: */
1107:
1108: (*s_etat_processus).s_connecteurs_sql = NULL;
1109:
1110: element_courant = (*s_etat_processus).s_marques;
1111: while(element_courant != NULL)
1112: {
1113: free((*((struct_marque *) element_courant)).label);
1114: free((*((struct_marque *) element_courant)).position);
1115: element_suivant = (*((struct_marque *) element_courant))
1116: .suivant;
1117: free(element_courant);
1118: element_courant = element_suivant;
1119: }
1120:
1121: liberation_allocateur(s_etat_processus);
1122:
1123: # ifndef SEMAPHORES_NOMMES
1124: sem_post(&((*s_etat_processus).semaphore_fork));
1125: sem_destroy(&((*s_etat_processus).semaphore_fork));
1126: # else
1127: sem_post((*s_etat_processus).semaphore_fork);
1128: sem_destroy2((*s_etat_processus).semaphore_fork, getpid());
1129: # endif
1130:
1131: liberation_contexte_cas(s_etat_processus);
1132: free(s_etat_processus);
1133:
1134: s_etat_processus = candidat;
1135: }
1136:
1137: l_element_suivant = (*l_element_courant).suivant;
1138:
1139: free((struct_thread *) (*l_element_courant).donnee);
1140: free((struct_liste_chainee *) l_element_courant);
1141:
1142: l_element_courant = l_element_suivant;
1143: }
1144:
1145: liste_threads = NULL;
1146:
1147: l_element_courant = liste_threads_surveillance;
1148:
1149: while(l_element_courant != NULL)
1150: {
1151: s_argument_thread = (struct_descripteur_thread *)
1152: (*l_element_courant).donnee;
1153:
1154: if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
1155: != 0)
1156: {
1157: (*s_etat_processus).erreur_systeme = d_es_processus;
1158: pthread_mutex_unlock(&mutex_liste_threads);
1159: return;
1160: }
1161:
1162: (*s_argument_thread).nombre_references--;
1163:
1164: BUG((*s_argument_thread).nombre_references < 0,
1165: printf("(*s_argument_thread).nombre_references = %d\n",
1166: (int) (*s_argument_thread).nombre_references));
1167:
1168: if ((*s_argument_thread).nombre_references == 0)
1169: {
1170: close((*s_argument_thread).pipe_objets[0]);
1171: close((*s_argument_thread).pipe_acquittement[1]);
1172: close((*s_argument_thread).pipe_injections[1]);
1173: close((*s_argument_thread).pipe_nombre_injections[1]);
1174: close((*s_argument_thread).pipe_nombre_objets_attente[0]);
1175: close((*s_argument_thread).pipe_interruptions[0]);
1176: close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);
1177:
1178: if (pthread_mutex_unlock(&((*s_argument_thread)
1179: .mutex_nombre_references)) != 0)
1180: {
1181: (*s_etat_processus).erreur_systeme = d_es_processus;
1182: pthread_mutex_unlock(&mutex_liste_threads);
1183: return;
1184: }
1185:
1186: pthread_mutex_destroy(&((*s_argument_thread).mutex));
1187: pthread_mutex_destroy(&((*s_argument_thread)
1188: .mutex_nombre_references));
1189:
1190: if ((*s_argument_thread).processus_detache == d_faux)
1191: {
1192: if ((*s_argument_thread).destruction_objet == d_vrai)
1193: {
1194: liberation(s_etat_processus, (*s_argument_thread).argument);
1195: }
1196: }
1197:
1198: free(s_argument_thread);
1199: }
1200: else
1201: {
1202: if (pthread_mutex_unlock(&((*s_argument_thread)
1203: .mutex_nombre_references)) != 0)
1204: {
1205: (*s_etat_processus).erreur_systeme = d_es_processus;
1206: pthread_mutex_unlock(&mutex_liste_threads);
1207: return;
1208: }
1209: }
1210:
1211: l_element_suivant = (*l_element_courant).suivant;
1212: free((struct_liste_chainee *) l_element_courant);
1213: l_element_courant = l_element_suivant;
1214: }
1215:
1216: liste_threads_surveillance = NULL;
1217:
1218: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1219: {
1220: (*s_etat_processus).erreur_systeme = d_es_processus;
1221: return;
1222: }
1223:
1224: return;
1225: }
1226:
1227: static struct_processus *
1228: recherche_thread(pid_t pid, pthread_t tid)
1229: {
1230: volatile struct_liste_chainee_volatile *l_element_courant;
1231:
1232: struct_processus *s_etat_processus;
1233:
1234: l_element_courant = liste_threads;
1235:
1236: while(l_element_courant != NULL)
1237: {
1238: if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee))
1239: .tid, tid) != 0) && ((*((struct_thread *)
1240: (*l_element_courant).donnee)).pid == pid))
1241: {
1242: break;
1243: }
1244:
1245: l_element_courant = (*l_element_courant).suivant;
1246: }
1247:
1248: if (l_element_courant == NULL)
1249: {
1250: /*
1251: * Le processus n'existe plus. On ne distribue aucun signal.
1252: */
1253:
1254: return(NULL);
1255: }
1256:
1257: s_etat_processus = (*((struct_thread *)
1258: (*l_element_courant).donnee)).s_etat_processus;
1259:
1260: return(s_etat_processus);
1261: }
1262:
1263: static struct_processus *
1264: recherche_thread_principal(pid_t pid)
1265: {
1266: volatile struct_liste_chainee_volatile *l_element_courant;
1267:
1268: l_element_courant = liste_threads;
1269:
1270: while(l_element_courant != NULL)
1271: {
1272: if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal
1273: == d_vrai) && ((*((struct_thread *)
1274: (*l_element_courant).donnee)).pid == pid))
1275: {
1276: break;
1277: }
1278:
1279: l_element_courant = (*l_element_courant).suivant;
1280: }
1281:
1282: if (l_element_courant == NULL)
1283: {
1284: /*
1285: * Le processus n'existe plus. On ne distribue aucun signal.
1286: */
1287:
1288: return(NULL);
1289: }
1290:
1291: return((*((struct_thread *) (*l_element_courant).donnee))
1292: .s_etat_processus);
1293: }
1294:
1295:
1296: /*
1297: ================================================================================
1298: Procédures de gestion des signaux d'interruption
1299: ================================================================================
1300: Entrée : variable globale
1301: --------------------------------------------------------------------------------
1302: Sortie : variable globale modifiée
1303: --------------------------------------------------------------------------------
1304: Effets de bord : néant
1305: ================================================================================
1306: */
1307:
1308: // Les routines suivantes sont uniquement appelées depuis les gestionnaires
1309: // des signaux asynchrones. Elles ne doivent pas bloquer dans le cas où
1310: // les sémaphores sont déjà bloqués par un gestionnaire de signal.
1311:
1312: static inline void
1313: verrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
1314: {
1315: int semaphore;
1316:
1317: # ifndef SEMAPHORES_NOMMES
1318: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
1319: # else
1320: if (sem_post((*s_etat_processus).semaphore_fork) != 0)
1321: # endif
1322: {
1323: BUG(1, uprintf("Lock error !\n"));
1324: return;
1325: }
1326:
1327: // Il faut respecteur l'atomicité des deux opérations suivantes !
1328:
1329: if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) != 0)
1330: {
1331: # ifndef SEMAPHORES_NOMMES
1332: sem_wait(&((*s_etat_processus).semaphore_fork));
1333: # else
1334: sem_wait((*s_etat_processus).semaphore_fork);
1335: # endif
1336: BUG(1, uprintf("Unlock error !\n"));
1337: return;
1338: }
1339:
1340: # ifndef SEMAPHORES_NOMMES
1341: if (sem_post(&semaphore_gestionnaires_signaux) == -1)
1342: # else
1343: if (sem_post(semaphore_gestionnaires_signaux) == -1)
1344: # endif
1345: {
1346: # ifndef SEMAPHORES_NOMMES
1347: sem_wait(&((*s_etat_processus).semaphore_fork));
1348: # else
1349: sem_wait((*s_etat_processus).semaphore_fork);
1350: # endif
1351: BUG(1, uprintf("Lock error !\n"));
1352: return;
1353: }
1354:
1355: # ifndef SEMAPHORES_NOMMES
1356: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1357: # else
1358: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1359: # endif
1360: {
1361: # ifndef SEMAPHORES_NOMMES
1362: sem_wait(&((*s_etat_processus).semaphore_fork));
1363: # else
1364: sem_wait((*s_etat_processus).semaphore_fork);
1365: # endif
1366: BUG(1, uprintf("Lock error !\n"));
1367: return;
1368: }
1369:
1370: if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)
1371: {
1372: # ifndef SEMAPHORES_NOMMES
1373: sem_wait(&((*s_etat_processus).semaphore_fork));
1374: # else
1375: sem_wait((*s_etat_processus).semaphore_fork);
1376: # endif
1377: BUG(1, uprintf("Unlock error !\n"));
1378: return;
1379: }
1380:
1381: if (semaphore == 1)
1382: {
1383: // Le semaphore ne peut être pris par le thread qui a appelé
1384: // le gestionnaire de signal car le signal est bloqué par ce thread
1385: // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que
1386: // par un thread concurrent. On essaye donc de le bloquer jusqu'à
1387: // ce que ce soit possible.
1388:
1389: if (pthread_mutex_lock(&mutex_liste_threads) != 0)
1390: {
1391: sem_wait(&((*s_etat_processus).semaphore_fork));
1392: BUG(1, uprintf("Lock error !\n"));
1393: return;
1394: }
1395: }
1396:
1397: return;
1398: }
1399:
1400: static inline void
1401: deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
1402: {
1403: int semaphore;
1404:
1405: // Il faut respecteur l'atomicité des deux opérations suivantes !
1406:
1407: if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) == -1)
1408: {
1409: # ifndef SEMAPHORES_NOMMES
1410: sem_wait(&((*s_etat_processus).semaphore_fork));
1411: # else
1412: sem_wait((*s_etat_processus).semaphore_fork);
1413: # endif
1414: BUG(1, uprintf("Unlock error !\n"));
1415: return;
1416: }
1417:
1418: # ifndef SEMAPHORES_NOMMES
1419: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1420: # else
1421: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1422: # endif
1423: {
1424: # ifndef SEMAPHORES_NOMMES
1425: sem_wait(&((*s_etat_processus).semaphore_fork));
1426: # else
1427: sem_wait((*s_etat_processus).semaphore_fork);
1428: # endif
1429: BUG(1, uprintf("Unlock error !\n"));
1430: return;
1431: }
1432:
1433: # ifndef SEMAPHORES_NOMMES
1434: while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
1435: # else
1436: while(sem_wait(semaphore_gestionnaires_signaux) == -1)
1437: # endif
1438: {
1439: if (errno != EINTR)
1440: {
1441: # ifndef SEMAPHORES_NOMMES
1442: sem_wait(&((*s_etat_processus).semaphore_fork));
1443: # else
1444: sem_wait((*s_etat_processus).semaphore_fork);
1445: # endif
1446: BUG(1, uprintf("Unlock error !\n"));
1447: return;
1448: }
1449: }
1450:
1451: if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)
1452: {
1453: # ifndef SEMAPHORES_NOMMES
1454: sem_wait(&((*s_etat_processus).semaphore_fork));
1455: # else
1456: sem_wait((*s_etat_processus).semaphore_fork);
1457: # endif
1458: BUG(1, uprintf("Unlock error !\n"));
1459: return;
1460: }
1461:
1462: # ifndef SEMAPHORES_NOMMES
1463: while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
1464: # else
1465: while(sem_wait((*s_etat_processus).semaphore_fork) != 0)
1466: # endif
1467: {
1468: if (errno != EINTR)
1469: {
1470: BUG(1, uprintf("Unlock error !\n"));
1471: return;
1472: }
1473: }
1474:
1475: if (semaphore == 1)
1476: {
1477: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1478: {
1479: BUG(1, uprintf("Unlock error !\n"));
1480: return;
1481: }
1482: }
1483:
1484: return;
1485: }
1486:
1487: #define test_signal(signal) \
1488: if (signal_test == SIGTEST) { signal_test = signal; return; }
1489:
1490: // Récupération des signaux
1491: // - SIGINT (arrêt au clavier)
1492: // - SIGTERM (signal d'arrêt en provenance du système)
1493:
1494: void
1495: interruption1(int signal)
1496: {
1497: test_signal(signal);
1498:
1499: switch(signal)
1500: {
1501: case SIGINT:
1502: envoi_signal_processus(getpid(), rpl_sigint);
1503: break;
1504:
1505: case SIGTERM:
1506: envoi_signal_processus(getpid(), rpl_sigterm);
1507: break;
1508:
1509: case SIGALRM:
1510: envoi_signal_processus(getpid(), rpl_sigalrm);
1511: break;
1512: }
1513:
1514: return;
1515: }
1516:
1517: inline static void
1518: signal_alrm(struct_processus *s_etat_processus, pid_t pid)
1519: {
1520: struct_processus *s_thread_principal;
1521:
1522: verrouillage_gestionnaire_signaux(s_etat_processus);
1523:
1524: if (pid == getpid())
1525: {
1526: // Si pid est égal à getpid(), le signal à traiter est issu
1527: // du même processus que celui qui va le traiter, mais d'un thread
1528: // différent.
1529:
1530: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1531: {
1532: printf("[%d] RPL/SIGALRM (thread %llu)\n", (int) getpid(),
1533: (unsigned long long) pthread_self());
1534: fflush(stdout);
1535: }
1536:
1537: if ((*s_etat_processus).pid_processus_pere != getpid())
1538: {
1539: // On n'est pas dans le processus père, on remonte le signal.
1540: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1541: rpl_sigalrm);
1542: }
1543: else
1544: {
1545: // On est dans le processus père, on effectue un arrêt d'urgence.
1546: (*s_etat_processus).var_volatile_alarme = -1;
1547: (*s_etat_processus).var_volatile_requete_arret = -1;
1548: }
1549: }
1550: else
1551: {
1552: // Le signal est issu d'un processus différent. On recherche le
1553: // thread principal pour remonter le signal.
1554:
1555: if ((s_thread_principal = recherche_thread_principal(getpid()))
1556: != NULL)
1557: {
1558: envoi_signal_contexte(s_thread_principal, rpl_sigalrm);
1559: }
1560: }
1561:
1562: deverrouillage_gestionnaire_signaux(s_etat_processus);
1563: return;
1564: }
1565:
1566: inline static void
1567: signal_term(struct_processus *s_etat_processus, pid_t pid)
1568: {
1569: struct_processus *s_thread_principal;
1570: volatile sig_atomic_t exclusion = 0;
1571:
1572: verrouillage_gestionnaire_signaux(s_etat_processus);
1573:
1574: if (pid == getpid())
1575: {
1576: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1577: {
1578: printf("[%d] RPL/SIGTERM (thread %llu)\n", (int) getpid(),
1579: (unsigned long long) pthread_self());
1580: fflush(stdout);
1581: }
1582:
1583: if ((*s_etat_processus).pid_processus_pere != getpid())
1584: {
1585: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1586: rpl_sigterm);
1587: }
1588: else
1589: {
1590: (*s_etat_processus).var_volatile_traitement_sigint = -1;
1591:
1592: while(exclusion == 1);
1593: exclusion = 1;
1594:
1595: if ((*s_etat_processus).var_volatile_requete_arret == -1)
1596: {
1597: deverrouillage_gestionnaire_signaux(s_etat_processus);
1598: exclusion = 0;
1599: return;
1600: }
1601:
1602: (*s_etat_processus).var_volatile_requete_arret = -1;
1603: (*s_etat_processus).var_volatile_alarme = -1;
1604:
1605: exclusion = 0;
1606: }
1607: }
1608: else
1609: {
1610: if ((s_thread_principal = recherche_thread_principal(getpid()))
1611: != NULL)
1612: {
1613: envoi_signal_contexte(s_thread_principal, rpl_sigterm);
1614: }
1615: }
1616:
1617: deverrouillage_gestionnaire_signaux(s_etat_processus);
1618: return;
1619: }
1620:
1621: inline static void
1622: signal_int(struct_processus *s_etat_processus, pid_t pid)
1623: {
1624: struct_processus *s_thread_principal;
1625: volatile sig_atomic_t exclusion = 0;
1626:
1627: verrouillage_gestionnaire_signaux(s_etat_processus);
1628:
1629: if (pid == getpid())
1630: {
1631: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1632: {
1633: printf("[%d] RPL/SIGINT (thread %llu)\n", (int) getpid(),
1634: (unsigned long long) pthread_self());
1635: fflush(stdout);
1636: }
1637:
1638: if ((*s_etat_processus).pid_processus_pere != getpid())
1639: {
1640: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1641: rpl_sigint);
1642: }
1643: else
1644: {
1645: (*s_etat_processus).var_volatile_traitement_sigint = -1;
1646:
1647: while(exclusion == 1);
1648: exclusion = 1;
1649:
1650: if ((*s_etat_processus).var_volatile_requete_arret == -1)
1651: {
1652: deverrouillage_gestionnaire_signaux(s_etat_processus);
1653: exclusion = 0;
1654: return;
1655: }
1656:
1657: if ((*s_etat_processus).langue == 'F')
1658: {
1659: printf("+++Interruption\n");
1660: }
1661: else
1662: {
1663: printf("+++Interrupt\n");
1664: }
1665:
1666: fflush(stdout);
1667:
1668: (*s_etat_processus).var_volatile_requete_arret = -1;
1669: (*s_etat_processus).var_volatile_alarme = -1;
1670:
1671: exclusion = 0;
1672: }
1673: }
1674: else
1675: {
1676: if ((s_thread_principal = recherche_thread_principal(getpid()))
1677: != NULL)
1678: {
1679: envoi_signal_contexte(s_thread_principal, rpl_sigint);
1680: }
1681: }
1682:
1683: deverrouillage_gestionnaire_signaux(s_etat_processus);
1684: return;
1685: }
1686:
1687: // Récupération des signaux
1688: // - SIGFSTP
1689: //
1690: // ATTENTION :
1691: // Le signal SIGFSTP provient de la mort du processus de contrôle.
1692: // Sous certains systèmes (Linux...), la mort du terminal de contrôle
1693: // se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
1694: // (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
1695: // non initialisée (pointeur NULL) issue de TERMIO.
1696:
1697: void
1698: interruption2(int signal)
1699: {
1700: test_signal(signal);
1701: envoi_signal_processus(getpid(), rpl_sigtstp);
1702: return;
1703: }
1704:
1705: static inline void
1706: signal_tstp(struct_processus *s_etat_processus, pid_t pid)
1707: {
1708: struct_processus *s_thread_principal;
1709:
1710: verrouillage_gestionnaire_signaux(s_etat_processus);
1711:
1712: if (pid == getpid())
1713: {
1714: /*
1715: * 0 => fonctionnement normal
1716: * -1 => requête
1717: * 1 => requête acceptée en attente de traitement
1718: */
1719:
1720: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1721: {
1722: printf("[%d] RPL/SIGTSTP (thread %llu)\n", (int) getpid(),
1723: (unsigned long long) pthread_self());
1724: fflush(stdout);
1725: }
1726:
1727: if ((*s_etat_processus).var_volatile_processus_pere == 0)
1728: {
1729: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1730: rpl_sigtstp);
1731: }
1732: else
1733: {
1734: (*s_etat_processus).var_volatile_requete_arret2 = -1;
1735: }
1736: }
1737: else
1738: {
1739: // Envoi d'un signal au thread maître du groupe.
1740:
1741: if ((s_thread_principal = recherche_thread_principal(getpid()))
1742: != NULL)
1743: {
1744: envoi_signal_contexte(s_thread_principal, rpl_sigtstp);
1745: }
1746: }
1747:
1748: deverrouillage_gestionnaire_signaux(s_etat_processus);
1749: return;
1750: }
1751:
1752: void
1753: interruption3(int signal)
1754: {
1755: // Si on passe par ici, c'est qu'il est impossible de récupérer
1756: // l'erreur d'accès à la mémoire. On sort donc du programme quitte à
1757: // ce qu'il reste des processus orphelins.
1758:
1759: unsigned char message[] = "+++System : Uncaught access violation\n"
1760: "+++System : Aborting !\n";
1761:
1762: test_signal(signal);
1763:
1764: if (pid_processus_pere == getpid())
1765: {
1766: kill(pid_processus_pere, SIGALRM);
1767: }
1768:
1769: write(STDERR_FILENO, message, strlen(message));
1770: _exit(EXIT_FAILURE);
1771: }
1772:
1773: #if 0
1774: // Utiliser libsigsegv
1775: void INTERRUPTION3_A_FIXER()
1776: {
1777: pthread_t thread;
1778:
1779: struct_processus *s_etat_processus;
1780:
1781: test_signal(signal);
1782: verrouillage_gestionnaire_signaux(s_etat_processus);
1783:
1784: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
1785: {
1786: deverrouillage_gestionnaire_signaux(s_etat_processus);
1787: return;
1788: }
1789:
1790: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1791: {
1792: printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),
1793: (unsigned long long) pthread_self());
1794: fflush(stdout);
1795: }
1796:
1797: if ((*s_etat_processus).var_volatile_recursivite == -1)
1798: {
1799: // Segfault dans un appel de fonction récursive
1800: deverrouillage_gestionnaire_signaux(s_etat_processus);
1801: longjmp(contexte, -1);
1802: }
1803: else
1804: {
1805: // Segfault dans une routine interne
1806: if (strncmp(getenv("LANG"), "fr", 2) == 0)
1807: {
1808: printf("+++Système : Violation d'accès\n");
1809: }
1810: else
1811: {
1812: printf("+++System : Access violation\n");
1813: }
1814:
1815: fflush(stdout);
1816:
1817: (*s_etat_processus).compteur_violation_d_acces++;
1818:
1819: if ((*s_etat_processus).compteur_violation_d_acces > 1)
1820: {
1821: // On vient de récupérer plus d'une erreur de segmentation
1822: // dans le même processus ou le même thread. L'erreur n'est pas
1823: // récupérable et on sort autoritairement du programme. Il peut
1824: // rester des processus orphelins en attente !
1825:
1826: if (strncmp(getenv("LANG"), "fr", 2) == 0)
1827: {
1828: printf("+++Système : Violation d'accès, tentative de "
1829: "terminaison de la tâche\n");
1830: printf(" (defauts multiples)\n");
1831: }
1832: else
1833: {
1834: printf("+++System : Access violation, trying to kill task "
1835: "(multiple defaults)\n");
1836: }
1837:
1838: fflush(stdout);
1839:
1840: deverrouillage_gestionnaire_signaux(s_etat_processus);
1841: exit(EXIT_FAILURE);
1842: }
1843: else
1844: {
1845: // Première erreur de segmentation. On essaie de terminer
1846: // proprement le thread ou le processus. Le signal ne peut être
1847: // envoyé que depuis le même processus.
1848:
1849: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1850: {
1851: if (pthread_equal(thread, pthread_self()) != 0)
1852: {
1853: deverrouillage_gestionnaire_signaux(s_etat_processus);
1854:
1855: if ((*s_etat_processus).pid_processus_pere != getpid())
1856: {
1857: // On est dans le thread principal d'un processus.
1858:
1859: longjmp(contexte_processus, -1);
1860: }
1861: else
1862: {
1863: // On est dans le thread principal du processus
1864: // père.
1865:
1866: longjmp(contexte_initial, -1);
1867: }
1868: }
1869: else
1870: {
1871: // On est dans un thread fils d'un thread principal.
1872:
1873: deverrouillage_gestionnaire_signaux(s_etat_processus);
1874: longjmp(contexte_thread, -1);
1875: }
1876: }
1877:
1878: // Là, on ramasse les miettes puisque le thread n'existe plus
1879: // dans la base (corruption de la mémoire).
1880:
1881: deverrouillage_gestionnaire_signaux(s_etat_processus);
1882: longjmp(contexte_initial, -1);
1883: }
1884: }
1885:
1886: deverrouillage_gestionnaire_signaux(s_etat_processus);
1887: return;
1888: }
1889: #endif
1890:
1891: // Traitement de rpl_sigstart
1892:
1893: static inline void
1894: signal_start(struct_processus *s_etat_processus, pid_t pid)
1895: {
1896: struct_processus *s_thread_principal;
1897:
1898: verrouillage_gestionnaire_signaux(s_etat_processus);
1899:
1900: if (pid == getpid())
1901: {
1902: (*s_etat_processus).demarrage_fils = d_vrai;
1903: }
1904: else
1905: {
1906: // Envoi d'un signal au thread maître du groupe.
1907:
1908: if ((s_thread_principal = recherche_thread_principal(getpid()))
1909: != NULL)
1910: {
1911: envoi_signal_contexte(s_thread_principal, rpl_sigstart);
1912: }
1913: }
1914:
1915: deverrouillage_gestionnaire_signaux(s_etat_processus);
1916: return;
1917: }
1918:
1919: // Traitement de rpl_sigcont
1920:
1921: static inline void
1922: signal_cont(struct_processus *s_etat_processus, pid_t pid)
1923: {
1924: struct_processus *s_thread_principal;
1925:
1926: verrouillage_gestionnaire_signaux(s_etat_processus);
1927:
1928: if (pid == getpid())
1929: {
1930: (*s_etat_processus).redemarrage_processus = d_vrai;
1931: }
1932: else
1933: {
1934: // Envoi d'un signal au thread maître du groupe.
1935:
1936: if ((s_thread_principal = recherche_thread_principal(getpid()))
1937: != NULL)
1938: {
1939: envoi_signal_contexte(s_thread_principal, rpl_sigcont);
1940: }
1941: }
1942:
1943: deverrouillage_gestionnaire_signaux(s_etat_processus);
1944: return;
1945: }
1946:
1947: // Traitement de rpl_sigstop
1948:
1949: static inline void
1950: signal_stop(struct_processus *s_etat_processus, pid_t pid)
1951: {
1952: struct_processus *s_thread_principal;
1953:
1954: verrouillage_gestionnaire_signaux(s_etat_processus);
1955:
1956: if (pid == getpid())
1957: {
1958: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
1959: == NULL)
1960: {
1961: deverrouillage_gestionnaire_signaux(s_etat_processus);
1962: return;
1963: }
1964:
1965: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1966: {
1967: printf("[%d] RPL/SIGSTOP (thread %llu)\n", (int) getpid(),
1968: (unsigned long long) pthread_self());
1969: fflush(stdout);
1970: }
1971:
1972: /*
1973: * var_globale_traitement_retarde_stop :
1974: * 0 -> traitement immédiat
1975: * 1 -> traitement retardé (aucun signal reçu)
1976: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
1977: */
1978:
1979: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
1980: {
1981: (*s_etat_processus).var_volatile_requete_arret = -1;
1982: }
1983: else
1984: {
1985: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
1986: }
1987: }
1988: else
1989: {
1990: // Envoi d'un signal au thread maître du groupe.
1991:
1992: if ((s_thread_principal = recherche_thread_principal(getpid()))
1993: != NULL)
1994: {
1995: envoi_signal_contexte(s_thread_principal, rpl_sigstop);
1996: }
1997: }
1998:
1999: deverrouillage_gestionnaire_signaux(s_etat_processus);
2000: return;
2001: }
2002:
2003: // Traitement de rpl_siginject
2004:
2005: static inline void
2006: signal_inject(struct_processus *s_etat_processus, pid_t pid)
2007: {
2008: verrouillage_gestionnaire_signaux(s_etat_processus);
2009:
2010: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2011: {
2012: deverrouillage_gestionnaire_signaux(s_etat_processus);
2013: return;
2014: }
2015:
2016: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2017: {
2018: printf("[%d] RPL/SIGINJECT (thread %llu)\n", (int) getpid(),
2019: (unsigned long long) pthread_self());
2020: fflush(stdout);
2021: }
2022:
2023: deverrouillage_gestionnaire_signaux(s_etat_processus);
2024: return;
2025: }
2026:
2027: // Récupération des signaux
2028: // - SIGPIPE
2029:
2030: void
2031: interruption5(int signal)
2032: {
2033: unsigned char message[] = "+++System : SIGPIPE\n"
2034: "+++System : Aborting !\n";
2035:
2036: test_signal(signal);
2037:
2038: if (pid_processus_pere == getpid())
2039: {
2040: envoi_signal_processus(pid_processus_pere, rpl_sigalrm);
2041: }
2042:
2043: write(STDERR_FILENO, message, strlen(message));
2044: return;
2045: }
2046:
2047: static inline void
2048: signal_urg(struct_processus *s_etat_processus, pid_t pid)
2049: {
2050: struct_processus *s_thread_principal;
2051:
2052: verrouillage_gestionnaire_signaux(s_etat_processus);
2053:
2054: if (pid == getpid())
2055: {
2056: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2057: == NULL)
2058: {
2059: deverrouillage_gestionnaire_signaux(s_etat_processus);
2060: return;
2061: }
2062:
2063: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2064: {
2065: printf("[%d] RPL/SIGURG (thread %llu)\n", (int) getpid(),
2066: (unsigned long long) pthread_self());
2067: fflush(stdout);
2068: }
2069:
2070: (*s_etat_processus).var_volatile_alarme = -1;
2071: (*s_etat_processus).var_volatile_requete_arret = -1;
2072: }
2073: else
2074: {
2075: // Envoi d'un signal au thread maître du groupe.
2076:
2077: if ((s_thread_principal = recherche_thread_principal(getpid()))
2078: != NULL)
2079: {
2080: envoi_signal_contexte(s_thread_principal, rpl_sigurg);
2081: }
2082: }
2083:
2084: deverrouillage_gestionnaire_signaux(s_etat_processus);
2085: return;
2086: }
2087:
2088: // Traitement de rpl_sigabort
2089:
2090: static inline void
2091: signal_abort(struct_processus *s_etat_processus, pid_t pid)
2092: {
2093: struct_processus *s_thread_principal;
2094:
2095: verrouillage_gestionnaire_signaux(s_etat_processus);
2096:
2097: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2098: {
2099: deverrouillage_gestionnaire_signaux(s_etat_processus);
2100: return;
2101: }
2102:
2103: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2104: {
2105: printf("[%d] RPL/SIGABORT (thread %llu)\n", (int) getpid(),
2106: (unsigned long long) pthread_self());
2107: fflush(stdout);
2108: }
2109:
2110: if (pid == getpid())
2111: {
2112: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2113: == NULL)
2114: {
2115: deverrouillage_gestionnaire_signaux(s_etat_processus);
2116: return;
2117: }
2118:
2119: (*s_etat_processus).arret_depuis_abort = -1;
2120:
2121: /*
2122: * var_globale_traitement_retarde_stop :
2123: * 0 -> traitement immédiat
2124: * 1 -> traitement retardé (aucun signal reçu)
2125: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2126: */
2127:
2128: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
2129: {
2130: (*s_etat_processus).var_volatile_requete_arret = -1;
2131: }
2132: else
2133: {
2134: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
2135: }
2136: }
2137: else
2138: {
2139: (*s_etat_processus).arret_depuis_abort = -1;
2140:
2141: // Envoi d'un signal au thread maître du groupe.
2142:
2143: if ((s_thread_principal = recherche_thread_principal(getpid()))
2144: != NULL)
2145: {
2146: envoi_signal_contexte(s_thread_principal, rpl_sigabort);
2147: }
2148: }
2149:
2150: deverrouillage_gestionnaire_signaux(s_etat_processus);
2151: return;
2152: }
2153:
2154: // Récupération des signaux
2155: // - SIGHUP
2156:
2157: void
2158: interruption4(int signal)
2159: {
2160: test_signal(signal);
2161: envoi_signal_processus(getpid(), rpl_sighup);
2162: return;
2163: }
2164:
2165: static inline void
2166: signal_hup(struct_processus *s_etat_processus, pid_t pid)
2167: {
2168: file *fichier;
2169:
2170: unsigned char nom[8 + 64 + 1];
2171:
2172: verrouillage_gestionnaire_signaux(s_etat_processus);
2173:
2174: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2175: {
2176: deverrouillage_gestionnaire_signaux(s_etat_processus);
2177: return;
2178: }
2179:
2180: snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
2181: (unsigned long) pthread_self());
2182:
2183: if ((fichier = fopen(nom, "w+")) != NULL)
2184: {
2185: fclose(fichier);
2186:
2187: freopen(nom, "w", stdout);
2188: freopen(nom, "w", stderr);
2189: }
2190:
2191: freopen("/dev/null", "r", stdin);
2192:
2193: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2194: {
2195: printf("[%d] RPL/SIGHUP (thread %llu)\n", (int) getpid(),
2196: (unsigned long long) pthread_self());
2197: fflush(stdout);
2198: }
2199:
2200: deverrouillage_gestionnaire_signaux(s_etat_processus);
2201: return;
2202: }
2203:
2204: void
2205: traitement_exceptions_gsl(const char *reason, const char *file,
2206: int line, int gsl_errno)
2207: {
2208: code_erreur_gsl = gsl_errno;
2209: envoi_signal_processus(getpid(), rpl_sigexcept);
2210: return;
2211: }
2212:
2213: static inline void
2214: signal_except(struct_processus *s_etat_processus, pid_t pid)
2215: {
2216: verrouillage_gestionnaire_signaux(s_etat_processus);
2217:
2218: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2219: {
2220: deverrouillage_gestionnaire_signaux(s_etat_processus);
2221: return;
2222: }
2223:
2224: (*s_etat_processus).var_volatile_exception_gsl = code_erreur_gsl;
2225: deverrouillage_gestionnaire_signaux(s_etat_processus);
2226:
2227: return;
2228: }
2229:
2230: static inline void
2231: envoi_interruptions(struct_processus *s_etat_processus, enum signaux_rpl signal,
2232: pid_t pid_source)
2233: {
2234: switch(signal)
2235: {
2236: case rpl_signull:
2237: break;
2238:
2239: case rpl_sigint:
2240: signal_int(s_etat_processus, pid_source);
2241: break;
2242:
2243: case rpl_sigterm:
2244: signal_term(s_etat_processus, pid_source);
2245: break;
2246:
2247: case rpl_sigstart:
2248: signal_start(s_etat_processus, pid_source);
2249: break;
2250:
2251: case rpl_sigcont:
2252: signal_cont(s_etat_processus, pid_source);
2253: break;
2254:
2255: case rpl_sigstop:
2256: signal_stop(s_etat_processus, pid_source);
2257: break;
2258:
2259: case rpl_sigabort:
2260: signal_abort(s_etat_processus, pid_source);
2261: break;
2262:
2263: case rpl_sigurg:
2264: signal_urg(s_etat_processus, pid_source);
2265: break;
2266:
2267: case rpl_siginject:
2268: signal_inject(s_etat_processus, pid_source);
2269: break;
2270:
2271: case rpl_sigalrm:
2272: signal_alrm(s_etat_processus, pid_source);
2273: break;
2274:
2275: case rpl_sighup:
2276: signal_hup(s_etat_processus, pid_source);
2277: break;
2278:
2279: case rpl_sigtstp:
2280: signal_tstp(s_etat_processus, pid_source);
2281: break;
2282:
2283: case rpl_sigexcept:
2284: signal_except(s_etat_processus, pid_source);
2285: break;
2286:
2287: default:
2288: if ((*s_etat_processus).langue == 'F')
2289: {
2290: printf("+++System : Spurious signal (%d) !\n", signal);
2291: }
2292: else
2293: {
2294: printf("+++System : Signal inconnu (%d) !\n", signal);
2295: }
2296:
2297: break;
2298: }
2299:
2300: return;
2301: }
2302:
2303: void
2304: scrutation_interruptions(struct_processus *s_etat_processus)
2305: {
2306: // Interruptions qui arrivent sur le processus depuis un
2307: // processus externe.
2308:
2309: // Les pointeurs de lecture pointent sur les prochains éléments
2310: // à lire. Les pointeurs d'écriture pointent sur les prochains éléments à
2311: // écrire.
2312:
2313: # ifndef SEMAPHORES_NOMMES
2314: if (sem_trywait(&((*s_queue_signaux).semaphore)) == 0)
2315: # else
2316: if (sem_trywait(semaphore_queue_signaux) == 0)
2317: # endif
2318: {
2319: if ((*s_queue_signaux).pointeur_lecture !=
2320: (*s_queue_signaux).pointeur_ecriture)
2321: {
2322: // Il y a un signal en attente dans le segment partagé. On le
2323: // traite.
2324:
2325: envoi_interruptions(s_etat_processus,
2326: (*s_queue_signaux).queue[(*s_queue_signaux)
2327: .pointeur_lecture].signal, (*s_queue_signaux).queue
2328: [(*s_queue_signaux).pointeur_lecture].pid);
2329: (*s_queue_signaux).pointeur_lecture =
2330: ((*s_queue_signaux).pointeur_lecture + 1)
2331: % LONGUEUR_QUEUE_SIGNAUX;
2332: }
2333:
2334: # ifndef SEMAPHORES_NOMMES
2335: sem_post(&((*s_queue_signaux).semaphore));
2336: # else
2337: sem_post(semaphore_queue_signaux);
2338: # endif
2339: }
2340:
2341: // Interruptions qui arrivent depuis le groupe courant de threads.
2342:
2343: if (pthread_mutex_trylock(&mutex_interruptions) == 0)
2344: {
2345: if ((*s_etat_processus).pointeur_signal_lecture !=
2346: (*s_etat_processus).pointeur_signal_ecriture)
2347: {
2348: // Il y a un signal dans la queue du thread courant. On le traite.
2349:
2350: envoi_interruptions(s_etat_processus,
2351: (*s_etat_processus).signaux_en_queue
2352: [(*s_etat_processus).pointeur_signal_lecture],
2353: getpid());
2354: (*s_etat_processus).pointeur_signal_lecture =
2355: ((*s_etat_processus).pointeur_signal_lecture + 1)
2356: % LONGUEUR_QUEUE_SIGNAUX;
2357: }
2358:
2359: pthread_mutex_unlock(&mutex_interruptions);
2360: }
2361:
2362: return;
2363: }
2364:
2365: /*
2366: ================================================================================
2367: Fonction renvoyant le nom du segment de mémoire partagée en fonction
2368: du pid du processus.
2369: ================================================================================
2370: Entrée : Chemin absolue servant de racine, pid du processus
2371: --------------------------------------------------------------------------------
2372: Sortie : NULL ou nom du segment
2373: --------------------------------------------------------------------------------
2374: Effet de bord : Néant
2375: ================================================================================
2376: */
2377:
2378: static unsigned char *
2379: nom_segment(unsigned char *chemin, pid_t pid)
2380: {
2381: unsigned char *fichier;
2382:
2383: # ifdef IPCS_SYSV // !POSIX
2384: # ifndef OS2 // !OS2
2385:
2386: if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) *
2387: sizeof(unsigned char))) == NULL)
2388: {
2389: return(NULL);
2390: }
2391:
2392: sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);
2393: # else // OS2
2394: if ((fichier = malloc((10 + 256 + 1) * sizeof(unsigned char)))
2395: == NULL)
2396: {
2397: return(NULL);
2398: }
2399:
2400: sprintf(fichier, "\\SHAREMEM\\RPL-SIGQUEUES-%d", (int) pid);
2401: # endif // OS2
2402: # else // POSIX
2403:
2404: if ((fichier = malloc((1 + 256 + 1) *
2405: sizeof(unsigned char))) == NULL)
2406: {
2407: return(NULL);
2408: }
2409:
2410: sprintf(fichier, "/RPL-SIGQUEUES-%d", (int) pid);
2411: # endif
2412:
2413: return(fichier);
2414: }
2415:
2416:
2417: /*
2418: ================================================================================
2419: Fonctions d'envoi d'un signal à un thread ou à un processus.
2420: ================================================================================
2421: Entrée : processus et signal
2422: --------------------------------------------------------------------------------
2423: Sortie : erreur
2424: --------------------------------------------------------------------------------
2425: Effet de bord : Néant
2426: ================================================================================
2427: */
2428:
2429: int
2430: envoi_signal_processus(pid_t pid, enum signaux_rpl signal)
2431: {
2432: int segment;
2433:
2434: # ifndef IPCS_SYSV
2435: # ifdef SEMAPHORES_NOMMES
2436: sem_t *semaphore;
2437: # endif
2438: # else
2439: int desc;
2440: key_t clef;
2441: # endif
2442:
2443: struct_queue_signaux *queue;
2444:
2445: unsigned char *nom;
2446:
2447: // Il s'agit d'ouvrir le segment de mémoire partagée, de le projeter en
2448: // mémoire puis d'y inscrire le signal à traiter.
2449:
2450: if (pid == getpid())
2451: {
2452: // Le signal est envoyé au même processus.
2453:
2454: if (s_queue_signaux == NULL)
2455: {
2456: return(1);
2457: }
2458:
2459: # ifndef SEMAPHORES_NOMMES
2460: while(sem_wait(&((*s_queue_signaux).semaphore)) != 0)
2461: # else
2462: while(sem_wait(semaphore_queue_signaux) != 0)
2463: # endif
2464: {
2465: if (errno != EINTR)
2466: {
2467: return(1);
2468: }
2469: }
2470:
2471: (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture]
2472: .pid = pid;
2473: (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture]
2474: .signal = signal;
2475:
2476: (*s_queue_signaux).pointeur_ecriture =
2477: ((*s_queue_signaux).pointeur_ecriture + 1)
2478: % LONGUEUR_QUEUE_SIGNAUX;
2479:
2480: # ifndef SEMAPHORES_NOMMES
2481: if (sem_post(&((*s_queue_signaux).semaphore)) != 0)
2482: # else
2483: if (sem_post(semaphore_queue_signaux) != 0)
2484: # endif
2485: {
2486: return(1);
2487: }
2488: }
2489: else
2490: {
2491: // Le signal est envoyé depuis un processus distinct.
2492:
2493: # ifdef IPCS_SYSV
2494: if ((nom = nom_segment(racine_segment, pid)) == NULL)
2495: {
2496: return(1);
2497: }
2498:
2499: if ((desc = open(nom, O_RDWR)) == -1)
2500: {
2501: free(nom);
2502: return(1);
2503: }
2504:
2505: close(desc);
2506:
2507: if ((clef = ftok(nom, 1)) == -1)
2508: {
2509: free(nom);
2510: return(1);
2511: }
2512:
2513: free(nom);
2514:
2515: if ((segment = shmget(clef, sizeof(struct_queue_signaux), 0)) == -1)
2516: {
2517: return(1);
2518: }
2519:
2520: queue = shmat(segment, NULL, 0);
2521: # else // POSIX
2522: if ((nom = nom_segment(racine_segment, pid)) == NULL)
2523: {
2524: return(1);
2525: }
2526:
2527: if ((segment = shm_open(nom, O_RDWR, 0)) == -1)
2528: {
2529: free(nom);
2530: return(1);
2531: }
2532:
2533: free(nom);
2534:
2535: if ((queue = mmap(NULL, sizeof(struct_queue_signaux),
2536: PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0)) ==
2537: MAP_FAILED)
2538: {
2539: close(segment);
2540: return(1);
2541: }
2542: # endif
2543:
2544: // À ce moment, le segment de mémoire partagée est projeté
2545: // dans l'espace du processus.
2546:
2547: # ifndef IPCS_SYSV // POSIX
2548: # ifndef SEMAPHORES_NOMMES
2549: while(sem_wait(&((*queue).semaphore)) != 0)
2550: {
2551: if (errno != EINTR)
2552: {
2553: return(1);
2554: }
2555: }
2556: # else
2557: if ((semaphore = sem_open2(pid)) == SEM_FAILED)
2558: {
2559: return(1);
2560: }
2561:
2562: while(sem_wait(semaphore) != 0)
2563: {
2564: if (errno != EINTR)
2565: {
2566: sem_close(semaphore);
2567: return(1);
2568: }
2569: }
2570: # endif
2571: # else // IPCS_SYSV
2572: while(sem_wait(&((*queue).semaphore)) != 0)
2573: {
2574: if (errno != EINTR)
2575: {
2576: return(1);
2577: }
2578: }
2579: # endif
2580:
2581: (*queue).queue[(*queue).pointeur_ecriture].pid = getpid();
2582: (*queue).queue[(*queue).pointeur_ecriture].signal = signal;
2583:
2584: (*queue).pointeur_ecriture = ((*queue).pointeur_ecriture + 1)
2585: % LONGUEUR_QUEUE_SIGNAUX;
2586:
2587: # ifndef IPCS_SYSV // POSIX
2588: # ifndef SEMAPHORES_NOMMES
2589: if (sem_post(&((*queue).semaphore)) != 0)
2590: {
2591: return(1);
2592: }
2593: # else
2594: if (sem_post(semaphore) != 0)
2595: {
2596: sem_close(semaphore);
2597: return(1);
2598: }
2599:
2600: if (sem_close(semaphore) != 0)
2601: {
2602: return(1);
2603: }
2604: # endif
2605:
2606: if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
2607: {
2608: close(segment);
2609: return(1);
2610: }
2611: # else // IPCS_SYSV
2612: if (sem_post(&((*queue).semaphore)) != 0)
2613: {
2614: return(1);
2615: }
2616:
2617: if (shmdt(queue) != 0)
2618: {
2619: return(1);
2620: }
2621: # endif
2622: }
2623:
2624: return(0);
2625: }
2626:
2627: int
2628: envoi_signal_thread(pthread_t tid, enum signaux_rpl signal)
2629: {
2630: // Un signal est envoyé d'un thread à un autre thread du même processus.
2631:
2632: volatile struct_liste_chainee_volatile *l_element_courant;
2633:
2634: struct_processus *s_etat_processus;
2635:
2636: if (pthread_mutex_lock(&mutex_liste_threads) != 0)
2637: {
2638: return(1);
2639: }
2640:
2641: l_element_courant = liste_threads;
2642:
2643: while(l_element_courant != NULL)
2644: {
2645: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
2646: == getpid()) && (pthread_equal((*((struct_thread *)
2647: (*l_element_courant).donnee)).tid, tid) != 0))
2648: {
2649: break;
2650: }
2651:
2652: l_element_courant = (*l_element_courant).suivant;
2653: }
2654:
2655: if (l_element_courant == NULL)
2656: {
2657: pthread_mutex_unlock(&mutex_liste_threads);
2658: return(1);
2659: }
2660:
2661: if (pthread_mutex_lock(&mutex_interruptions) != 0)
2662: {
2663: pthread_mutex_unlock(&mutex_liste_threads);
2664: return(1);
2665: }
2666:
2667: s_etat_processus = (*((struct_thread *) (*l_element_courant).donnee))
2668: .s_etat_processus;
2669:
2670: (*s_etat_processus).signaux_en_queue
2671: [(*s_etat_processus).pointeur_signal_ecriture] = signal;
2672: (*s_etat_processus).pointeur_signal_ecriture =
2673: ((*s_etat_processus).pointeur_signal_ecriture + 1)
2674: % LONGUEUR_QUEUE_SIGNAUX;
2675:
2676: if (pthread_mutex_unlock(&mutex_interruptions) != 0)
2677: {
2678: pthread_mutex_unlock(&mutex_liste_threads);
2679: return(1);
2680: }
2681:
2682: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
2683: {
2684: return(1);
2685: }
2686:
2687: return(0);
2688: }
2689:
2690: int
2691: envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,
2692: enum signaux_rpl signal)
2693: {
2694: pthread_mutex_lock(&mutex_interruptions);
2695: (*s_etat_processus_a_signaler).signaux_en_queue
2696: [(*s_etat_processus_a_signaler).pointeur_signal_ecriture] =
2697: signal;
2698: (*s_etat_processus_a_signaler).pointeur_signal_ecriture =
2699: ((*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1)
2700: % LONGUEUR_QUEUE_SIGNAUX;
2701: pthread_mutex_unlock(&mutex_interruptions);
2702:
2703: return(0);
2704: }
2705:
2706:
2707: /*
2708: ================================================================================
2709: Fonction créant un segment de mémoire partagée destiné à contenir
2710: la queue des signaux.
2711: ================================================================================
2712: Entrée : structure de description du processus
2713: --------------------------------------------------------------------------------
2714: Sortie : Néant
2715: --------------------------------------------------------------------------------
2716: Effet de bord : Néant
2717: ================================================================================
2718: */
2719:
2720: void
2721: creation_queue_signaux(struct_processus *s_etat_processus)
2722: {
2723: unsigned char *nom;
2724:
2725: racine_segment = (*s_etat_processus).chemin_fichiers_temporaires;
2726:
2727: # ifndef IPCS_SYSV // POSIX
2728: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
2729: getpid())) == NULL)
2730: {
2731: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2732: return;
2733: }
2734:
2735: if ((f_queue_signaux = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,
2736: S_IRUSR | S_IWUSR)) == -1)
2737: {
2738: free(nom);
2739: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2740: return;
2741: }
2742:
2743: if (ftruncate(f_queue_signaux, sizeof(struct_queue_signaux)) == -1)
2744: {
2745: free(nom);
2746: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2747: return;
2748: }
2749:
2750: s_queue_signaux = mmap(NULL, sizeof(struct_queue_signaux),
2751: PROT_READ | PROT_WRITE, MAP_SHARED, f_queue_signaux, 0);
2752:
2753: if (((void *) s_queue_signaux) == ((void *) -1))
2754: {
2755: if (shm_unlink(nom) == -1)
2756: {
2757: free(nom);
2758: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2759: return;
2760: }
2761:
2762: free(nom);
2763: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2764: return;
2765: }
2766:
2767: free(nom);
2768:
2769: # ifndef SEMAPHORES_NOMMES
2770: sem_init(&((*s_queue_signaux).semaphore), 1, 1);
2771: # else
2772: if ((semaphore_queue_signaux = sem_init2(1, getpid()))
2773: == SEM_FAILED)
2774: {
2775: (*s_etat_processus).erreur_systeme = d_es_processus;
2776: return;
2777: }
2778: # endif
2779:
2780: (*s_queue_signaux).pointeur_lecture = 0;
2781: (*s_queue_signaux).pointeur_ecriture = 0;
2782:
2783: if (msync(s_queue_signaux, sizeof(struct_queue_signaux), 0))
2784: {
2785: (*s_etat_processus).erreur_systeme = d_es_processus;
2786: return;
2787: }
2788: # else // IPCS_SYSV
2789: # ifndef OS2
2790: int segment;
2791: int support;
2792:
2793: key_t clef;
2794:
2795: // Création d'un segment de données associé au PID du processus
2796: // courant
2797:
2798: if ((nom = nom_segment((*s_etat_processus)
2799: .chemin_fichiers_temporaires, getpid())) == NULL)
2800: {
2801: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2802: return;
2803: }
2804:
2805: if ((support = open(nom, O_RDWR | O_CREAT | O_EXCL,
2806: S_IRUSR | S_IWUSR)) == -1)
2807: {
2808: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
2809: return;
2810: }
2811:
2812: if ((clef = ftok(nom, 1)) == -1)
2813: {
2814: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2815: return;
2816: }
2817:
2818: close(support);
2819: free(nom);
2820:
2821: if ((segment = shmget(clef, sizeof(struct_queue_signaux),
2822: IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)
2823: {
2824: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2825: return;
2826: }
2827:
2828: s_queue_signaux = shmat(segment, NULL, 0);
2829: f_queue_signaux = segment;
2830:
2831: if (((void *) s_queue_signaux) == ((void *) -1))
2832: {
2833: if (shmctl(f_queue_signaux, IPC_RMID, 0) == -1)
2834: {
2835: (*s_etat_processus).erreur_systeme =
2836: d_es_allocation_memoire;
2837: return;
2838: }
2839:
2840: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2841: return;
2842: }
2843:
2844: sem_init(&((*s_queue_signaux).semaphore), 1, 1);
2845: (*s_queue_signaux).pointeur_lecture = 0;
2846: (*s_queue_signaux).pointeur_ecriture = 0;
2847: # else // OS/2
2848: if ((nom = nom_segment(NULL, getpid())) == NULL)
2849: {
2850: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2851: return;
2852: }
2853:
2854: if (DosAllocSharedMem(&ptr_os2, nom, nombre_queues *
2855: ((2 * longueur_queue) + 4) * sizeof(int),
2856: PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
2857: {
2858: free(nom);
2859: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2860: return;
2861: }
2862:
2863: free(nom);
2864: fifos = ptr_os2;
2865: # endif
2866: # endif
2867:
2868: return;
2869: }
2870:
2871:
2872: /*
2873: ================================================================================
2874: Fonction libérant le segment de mémoire partagée destiné à contenir
2875: la queue des signaux.
2876: ================================================================================
2877: Entrée : structure de description du processus
2878: --------------------------------------------------------------------------------
2879: Sortie : Néant
2880: --------------------------------------------------------------------------------
2881: Effet de bord : Néant
2882: ================================================================================
2883: */
2884:
2885: void
2886: liberation_queue_signaux(struct_processus *s_etat_processus)
2887: {
2888: # ifdef IPCS_SYSV // SystemV
2889: # ifndef OS2
2890: if (shmdt(s_queue_signaux) == -1)
2891: {
2892: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2893: return;
2894: }
2895: # else // OS/2
2896: # endif
2897: # else // POSIX
2898: # ifndef SEMAPHORES_NOMMES
2899: sem_close(&((*s_queue_signaux).semaphore));
2900: # else
2901: sem_close(semaphore_queue_signaux);
2902: # endif
2903:
2904: if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
2905: {
2906: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2907: return;
2908: }
2909:
2910: close(f_queue_signaux);
2911: # endif
2912:
2913: return;
2914: }
2915:
2916:
2917: /*
2918: ================================================================================
2919: Fonction détruisant le segment de mémoire partagée destiné à contenir
2920: la queue des signaux.
2921: ================================================================================
2922: Entrée : structure de description du processus
2923: --------------------------------------------------------------------------------
2924: Sortie : Néant
2925: --------------------------------------------------------------------------------
2926: Effet de bord : Néant
2927: ================================================================================
2928: */
2929:
2930: void
2931: destruction_queue_signaux(struct_processus *s_etat_processus)
2932: {
2933: unsigned char *nom;
2934:
2935: # ifdef IPCS_SYSV // SystemV
2936: # ifndef OS2
2937: // Il faut commencer par éliminer le sémaphore.
2938:
2939: if (semctl((*s_queue_signaux).semaphore.sem, 0, IPC_RMID) == -1)
2940: {
2941: (*s_etat_processus).erreur_systeme = d_es_processus;
2942: return;
2943: }
2944:
2945: unlink((*s_queue_signaux).semaphore.path);
2946:
2947: if (shmdt(s_queue_signaux) == -1)
2948: {
2949: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2950: return;
2951: }
2952:
2953: if (shmctl(f_queue_signaux, IPC_RMID, 0) == -1)
2954: {
2955: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2956: return;
2957: }
2958:
2959: if ((nom = nom_segment((*s_etat_processus)
2960: .chemin_fichiers_temporaires, getpid())) == NULL)
2961: {
2962: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2963: return;
2964: }
2965:
2966: unlink(nom);
2967: free(nom);
2968: # else
2969: if (DosFreeMem(fifos) != 0)
2970: {
2971: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2972: return;
2973: }
2974:
2975: // FERMER LE FICHIER
2976:
2977: # endif
2978: # else // POSIX
2979: # ifndef SEMAPHORES_NOMMES
2980: sem_close(&((*s_queue_signaux).semaphore));
2981: sem_destroy(&((*s_queue_signaux).semaphore));
2982: # else
2983: sem_close(semaphore_queue_signaux);
2984: sem_destroy2(semaphore_queue_signaux, getpid());
2985: # endif
2986:
2987: if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
2988: {
2989: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2990: return;
2991: }
2992:
2993: if ((nom = nom_segment(NULL, getpid())) == NULL)
2994: {
2995: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2996: return;
2997: }
2998:
2999: close(f_queue_signaux);
3000:
3001: if (shm_unlink(nom) != 0)
3002: {
3003: free(nom);
3004: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3005: return;
3006: }
3007:
3008: free(nom);
3009: # endif
3010:
3011: return;
3012: }
3013:
3014: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>