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