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:
61: void
62: modification_pid_thread_pere(struct_processus *s_etat_processus)
63: {
64: // La variable existe toujours et aucun thread concurrent ne peut
65: // la modifier puisque cette routine ne peut être appelée que depuis
66: // DAEMON.
67:
68: (*((struct_thread *) (*liste_threads).donnee)).pid =
69: (*s_etat_processus).pid_processus_pere;
70:
71: return;
72: }
73:
74: void
75: insertion_thread(struct_processus *s_etat_processus, logical1 thread_principal)
76: {
77: sigset_t oldset;
78: sigset_t set;
79:
80: volatile struct_liste_chainee_volatile *l_nouvel_objet;
81:
82: sigfillset(&set);
83: pthread_sigmask(SIG_BLOCK, &set, &oldset);
84:
85: if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
86: == NULL)
87: {
88: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
89: sigpending(&set);
90:
91: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
92: return;
93: }
94:
95: if (((*l_nouvel_objet).donnee = malloc(sizeof(struct_thread))) == NULL)
96: {
97: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
98: sigpending(&set);
99:
100: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
101: return;
102: }
103:
104: (*((struct_thread *) (*l_nouvel_objet).donnee)).pid = getpid();
105: (*((struct_thread *) (*l_nouvel_objet).donnee)).tid = pthread_self();
106: (*((struct_thread *) (*l_nouvel_objet).donnee)).thread_principal =
107: thread_principal;
108: (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus =
109: s_etat_processus;
110:
111: # ifndef SEMAPHORES_NOMMES
112: while(sem_wait(&semaphore_liste_threads) == -1)
113: # else
114: while(sem_wait(semaphore_liste_threads) == -1)
115: # endif
116: {
117: if (errno != EINTR)
118: {
119: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
120: sigpending(&set);
121:
122: (*s_etat_processus).erreur_systeme = d_es_processus;
123: return;
124: }
125: }
126:
127: (*l_nouvel_objet).suivant = liste_threads;
128: liste_threads = l_nouvel_objet;
129:
130: # ifndef SEMAPHORES_NOMMES
131: if (sem_post(&semaphore_liste_threads) != 0)
132: # else
133: if (sem_post(semaphore_liste_threads) != 0)
134: # endif
135: {
136: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
137: sigpending(&set);
138:
139: (*s_etat_processus).erreur_systeme = d_es_processus;
140: return;
141: }
142:
143: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
144: sigpending(&set);
145: return;
146: }
147:
148: void
149: insertion_thread_surveillance(struct_processus *s_etat_processus,
150: struct_descripteur_thread *s_argument_thread)
151: {
152: sigset_t oldset;
153: sigset_t set;
154:
155: volatile struct_liste_chainee_volatile *l_nouvel_objet;
156:
157: sigfillset(&set);
158: pthread_sigmask(SIG_BLOCK, &set, &oldset);
159:
160: if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
161: == NULL)
162: {
163: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
164: sigpending(&set);
165:
166: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
167: return;
168: }
169:
170: # ifndef SEMAPHORES_NOMMES
171: while(sem_wait(&semaphore_liste_threads) == -1)
172: # else
173: while(sem_wait(semaphore_liste_threads) == -1)
174: # endif
175: {
176: if (errno != EINTR)
177: {
178: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
179: sigpending(&set);
180:
181: (*s_etat_processus).erreur_systeme = d_es_processus;
182: return;
183: }
184: }
185:
186: pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references));
187: (*s_argument_thread).nombre_references++;
188: pthread_mutex_unlock(&((*s_argument_thread).mutex_nombre_references));
189:
190: (*l_nouvel_objet).suivant = liste_threads_surveillance;
191: (*l_nouvel_objet).donnee = (void *) s_argument_thread;
192:
193: liste_threads_surveillance = l_nouvel_objet;
194:
195: # ifndef SEMAPHORES_NOMMES
196: if (sem_post(&semaphore_liste_threads) != 0)
197: # else
198: if (sem_post(semaphore_liste_threads) != 0)
199: # endif
200: {
201: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
202: sigpending(&set);
203:
204: (*s_etat_processus).erreur_systeme = d_es_processus;
205: return;
206: }
207:
208: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
209: sigpending(&set);
210: return;
211: }
212:
213: void
214: retrait_thread(struct_processus *s_etat_processus)
215: {
216: sigset_t oldset;
217: sigset_t set;
218:
219: volatile struct_liste_chainee_volatile *l_element_precedent;
220: volatile struct_liste_chainee_volatile *l_element_courant;
221:
222: sigfillset(&set);
223: pthread_sigmask(SIG_BLOCK, &set, &oldset);
224:
225: # ifndef SEMAPHORES_NOMMES
226: while(sem_wait(&semaphore_liste_threads) == -1)
227: # else
228: while(sem_wait(semaphore_liste_threads) == -1)
229: # endif
230: {
231: if (errno != EINTR)
232: {
233: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
234: sigpending(&set);
235:
236: (*s_etat_processus).erreur_systeme = d_es_processus;
237: return;
238: }
239: }
240:
241: l_element_precedent = NULL;
242: l_element_courant = liste_threads;
243:
244: while(l_element_courant != NULL)
245: {
246: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
247: == getpid()) && (pthread_equal((*((struct_thread *)
248: (*l_element_courant).donnee)).tid, pthread_self()) != 0))
249: {
250: break;
251: }
252:
253: l_element_precedent = l_element_courant;
254: l_element_courant = (*l_element_courant).suivant;
255: }
256:
257: if (l_element_courant == NULL)
258: {
259: # ifndef SEMAPHORES_NOMMES
260: sem_post(&semaphore_liste_threads);
261: # else
262: sem_post(semaphore_liste_threads);
263: # endif
264: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
265: sigpending(&set);
266:
267: (*s_etat_processus).erreur_systeme = d_es_processus;
268: return;
269: }
270:
271: if (l_element_precedent == NULL)
272: {
273: liste_threads = (*l_element_courant).suivant;
274: }
275: else
276: {
277: (*l_element_precedent).suivant = (*l_element_courant).suivant;
278: }
279:
280: if (pthread_setspecific(semaphore_fork_processus_courant, NULL) != 0)
281: {
282: (*s_etat_processus).erreur_systeme = d_es_processus;
283:
284: # ifndef SEMAPHORES_NOMMES
285: sem_post(&semaphore_liste_threads);
286: # else
287: sem_post(semaphore_liste_threads);
288: # endif
289: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
290: sigpending(&set);
291: return;
292: }
293:
294: # ifndef SEMAPHORES_NOMMES
295: if (sem_post(&semaphore_liste_threads) != 0)
296: # else
297: if (sem_post(semaphore_liste_threads) != 0)
298: # endif
299: {
300: (*s_etat_processus).erreur_systeme = d_es_processus;
301:
302: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
303: sigpending(&set);
304: return;
305: }
306:
307: free((void *) (*l_element_courant).donnee);
308: free((struct_liste_chainee_volatile *) l_element_courant);
309:
310: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
311: sigpending(&set);
312: return;
313: }
314:
315: void
316: retrait_thread_surveillance(struct_processus *s_etat_processus,
317: struct_descripteur_thread *s_argument_thread)
318: {
319: sigset_t set;
320: sigset_t oldset;
321:
322: volatile struct_liste_chainee_volatile *l_element_precedent;
323: volatile struct_liste_chainee_volatile *l_element_courant;
324:
325: sigfillset(&set);
326: pthread_sigmask(SIG_BLOCK, &set, &oldset);
327:
328: # ifndef SEMAPHORES_NOMMES
329: while(sem_wait(&semaphore_liste_threads) == -1)
330: # else
331: while(sem_wait(semaphore_liste_threads) == -1)
332: # endif
333: {
334: if (errno != EINTR)
335: {
336: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
337: sigpending(&set);
338:
339: (*s_etat_processus).erreur_systeme = d_es_processus;
340: return;
341: }
342: }
343:
344: l_element_precedent = NULL;
345: l_element_courant = liste_threads_surveillance;
346:
347: while(l_element_courant != NULL)
348: {
349: if ((*l_element_courant).donnee == (void *) s_argument_thread)
350: {
351: break;
352: }
353:
354: l_element_precedent = l_element_courant;
355: l_element_courant = (*l_element_courant).suivant;
356: }
357:
358: if (l_element_courant == NULL)
359: {
360: # ifndef SEMAPHORES_NOMMES
361: sem_post(&semaphore_liste_threads);
362: # else
363: sem_post(semaphore_liste_threads);
364: # endif
365: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
366: sigpending(&set);
367:
368: (*s_etat_processus).erreur_systeme = d_es_processus;
369: return;
370: }
371:
372: if (l_element_precedent == NULL)
373: {
374: liste_threads_surveillance = (*l_element_courant).suivant;
375: }
376: else
377: {
378: (*l_element_precedent).suivant = (*l_element_courant).suivant;
379: }
380:
381: if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
382: != 0)
383: {
384: # ifndef SEMAPHORES_NOMMES
385: sem_post(&semaphore_liste_threads);
386: # else
387: sem_post(semaphore_liste_threads);
388: # endif
389: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
390: sigpending(&set);
391:
392: (*s_etat_processus).erreur_systeme = d_es_processus;
393: return;
394: }
395:
396: (*s_argument_thread).nombre_references--;
397:
398: BUG((*s_argument_thread).nombre_references < 0,
399: printf("(*s_argument_thread).nombre_references = %d\n",
400: (int) (*s_argument_thread).nombre_references));
401:
402: if ((*s_argument_thread).nombre_references == 0)
403: {
404: if (pthread_mutex_unlock(&((*s_argument_thread)
405: .mutex_nombre_references)) != 0)
406: {
407: # ifndef SEMAPHORES_NOMMES
408: sem_post(&semaphore_liste_threads);
409: # else
410: sem_post(semaphore_liste_threads);
411: # endif
412: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
413: sigpending(&set);
414:
415: (*s_etat_processus).erreur_systeme = d_es_processus;
416: return;
417: }
418:
419: pthread_mutex_destroy(&((*s_argument_thread).mutex));
420: pthread_mutex_destroy(&((*s_argument_thread).mutex_nombre_references));
421: free(s_argument_thread);
422: }
423: else
424: {
425: if (pthread_mutex_unlock(&((*s_argument_thread)
426: .mutex_nombre_references)) != 0)
427: {
428: # ifndef SEMAPHORES_NOMMES
429: sem_post(&semaphore_liste_threads);
430: # else
431: sem_post(semaphore_liste_threads);
432: # endif
433: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
434: sigpending(&set);
435:
436: (*s_etat_processus).erreur_systeme = d_es_processus;
437: return;
438: }
439: }
440:
441: # ifndef SEMAPHORES_NOMMES
442: if (sem_post(&semaphore_liste_threads) != 0)
443: # else
444: if (sem_post(semaphore_liste_threads) != 0)
445: # endif
446: {
447: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
448: sigpending(&set);
449:
450: (*s_etat_processus).erreur_systeme = d_es_processus;
451: return;
452: }
453:
454: free((struct_liste_chainee_volatile *) l_element_courant);
455:
456: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
457: sigpending(&set);
458:
459: return;
460: }
461:
462: void
463: verrouillage_threads_concurrents(struct_processus *s_etat_processus)
464: {
465: volatile struct_liste_chainee_volatile *l_element_courant;
466:
467: # ifndef SEMAPHORES_NOMMES
468: while(sem_wait(&semaphore_liste_threads) == -1)
469: # else
470: while(sem_wait(semaphore_liste_threads) == -1)
471: # endif
472: {
473: if (errno != EINTR)
474: {
475: (*s_etat_processus).erreur_systeme = d_es_processus;
476: return;
477: }
478: }
479:
480: l_element_courant = liste_threads;
481:
482: while(l_element_courant != NULL)
483: {
484: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
485: == getpid()) && (pthread_equal((*((struct_thread *)
486: (*l_element_courant).donnee)).tid, pthread_self()) == 0))
487: {
488: # ifndef SEMAPHORES_NOMMES
489: while(sem_wait(&((*(*((struct_thread *) (*l_element_courant)
490: .donnee)).s_etat_processus).semaphore_fork)) == -1)
491: # else
492: while(sem_wait((*(*((struct_thread *) (*l_element_courant)
493: .donnee)).s_etat_processus).semaphore_fork) == -1)
494: # endif
495: {
496: if (errno != EINTR)
497: {
498: (*s_etat_processus).erreur_systeme = d_es_processus;
499: return;
500: }
501: }
502: }
503:
504: l_element_courant = (*l_element_courant).suivant;
505: }
506:
507: return;
508: }
509:
510: void
511: deverrouillage_threads_concurrents(struct_processus *s_etat_processus)
512: {
513: volatile struct_liste_chainee_volatile *l_element_courant;
514:
515: l_element_courant = liste_threads;
516:
517: while(l_element_courant != NULL)
518: {
519: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
520: == getpid()) && (pthread_equal((*((struct_thread *)
521: (*l_element_courant).donnee)).tid, pthread_self()) == 0))
522: {
523: # ifndef SEMAPHORES_NOMMES
524: if (sem_post(&((*(*((struct_thread *)
525: (*l_element_courant).donnee)).s_etat_processus)
526: .semaphore_fork)) != 0)
527: # else
528: if (sem_post((*(*((struct_thread *)
529: (*l_element_courant).donnee)).s_etat_processus)
530: .semaphore_fork) != 0)
531: # endif
532: {
533: # ifndef SEMAPHORES_NOMMES
534: if (sem_post(&semaphore_liste_threads) != 0)
535: {
536: (*s_etat_processus).erreur_systeme = d_es_processus;
537: return;
538: }
539: # else
540: if (sem_post(semaphore_liste_threads) != 0)
541: {
542: (*s_etat_processus).erreur_systeme = d_es_processus;
543: return;
544: }
545: # endif
546:
547: (*s_etat_processus).erreur_systeme = d_es_processus;
548: return;
549: }
550: }
551:
552: l_element_courant = (*l_element_courant).suivant;
553: }
554:
555: # ifndef SEMAPHORES_NOMMES
556: if (sem_post(&semaphore_liste_threads) != 0)
557: # else
558: if (sem_post(semaphore_liste_threads) != 0)
559: # endif
560: {
561: (*s_etat_processus).erreur_systeme = d_es_processus;
562: return;
563: }
564:
565: return;
566: }
567:
568: void
569: liberation_threads(struct_processus *s_etat_processus)
570: {
571: logical1 suppression_variables_partagees;
572:
573: sigset_t oldset;
574: sigset_t set;
575:
576: struct_descripteur_thread *s_argument_thread;
577:
578: struct_processus *candidat;
579:
580: unsigned long i;
581:
582: void *element_candidat;
583: void *element_courant;
584: void *element_suivant;
585:
586: volatile struct_liste_chainee_volatile *l_element_courant;
587: volatile struct_liste_chainee_volatile *l_element_suivant;
588:
589: sigfillset(&set);
590: pthread_sigmask(SIG_BLOCK, &set, &oldset);
591:
592: # ifndef SEMAPHORES_NOMMES
593: while(sem_wait(&semaphore_liste_threads) == -1)
594: # else
595: while(sem_wait(semaphore_liste_threads) == -1)
596: # endif
597: {
598: if (errno != EINTR)
599: {
600: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
601: (*s_etat_processus).erreur_systeme = d_es_processus;
602: return;
603: }
604: }
605:
606: l_element_courant = liste_threads;
607: suppression_variables_partagees = d_faux;
608:
609: while(l_element_courant != NULL)
610: {
611: if ((*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus
612: != s_etat_processus)
613: {
614: candidat = s_etat_processus;
615: s_etat_processus = (*((struct_thread *)
616: (*l_element_courant).donnee)).s_etat_processus;
617: free((*s_etat_processus).localisation);
618:
619: // (*s_etat_processus).instruction_courante peut pointer sur
620: // n'importe quoi (une instruction courante ou un champ d'une
621: // structure objet). On ne le libère pas quitte à avoir une
622: // petite fuite mémoire dans le processus fils.
623:
624: if ((*s_etat_processus).instruction_courante != NULL)
625: {
626: //free((*s_etat_processus).instruction_courante);
627: }
628:
629: close((*s_etat_processus).pipe_acquittement);
630: close((*s_etat_processus).pipe_donnees);
631: close((*s_etat_processus).pipe_injections);
632: close((*s_etat_processus).pipe_nombre_injections);
633: close((*s_etat_processus).pipe_interruptions);
634: close((*s_etat_processus).pipe_nombre_objets_attente);
635: close((*s_etat_processus).pipe_nombre_interruptions_attente);
636:
637: liberation(s_etat_processus, (*s_etat_processus).at_exit);
638:
639: if ((*s_etat_processus).nom_fichier_impression != NULL)
640: {
641: free((*s_etat_processus).nom_fichier_impression);
642: }
643:
644: while((*s_etat_processus).fichiers_graphiques != NULL)
645: {
646: free((*(*s_etat_processus).fichiers_graphiques).nom);
647:
648: if ((*(*s_etat_processus).fichiers_graphiques).legende != NULL)
649: {
650: free((*(*s_etat_processus).fichiers_graphiques).legende);
651: }
652:
653: element_courant = (*s_etat_processus).fichiers_graphiques;
654: (*s_etat_processus).fichiers_graphiques =
655: (*(*s_etat_processus).fichiers_graphiques).suivant;
656:
657: free(element_courant);
658: }
659:
660: if ((*s_etat_processus).entree_standard != NULL)
661: {
662: pclose((*s_etat_processus).entree_standard);
663: }
664:
665: if ((*s_etat_processus).generateur_aleatoire != NULL)
666: {
667: liberation_generateur_aleatoire(s_etat_processus);
668: }
669:
670: if ((*s_etat_processus).instruction_derniere_erreur != NULL)
671: {
672: free((*s_etat_processus).instruction_derniere_erreur);
673: (*s_etat_processus).instruction_derniere_erreur = NULL;
674: }
675:
676: element_courant = (void *) (*s_etat_processus)
677: .l_base_pile_processus;
678: while(element_courant != NULL)
679: {
680: s_argument_thread = (struct_descripteur_thread *)
681: (*((struct_liste_chainee *) element_courant)).donnee;
682:
683: if (pthread_mutex_lock(&((*s_argument_thread)
684: .mutex_nombre_references)) != 0)
685: {
686: (*s_etat_processus).erreur_systeme = d_es_processus;
687: sem_post(&semaphore_liste_threads);
688: return;
689: }
690:
691: (*s_argument_thread).nombre_references--;
692:
693: BUG((*s_argument_thread).nombre_references < 0,
694: printf("(*s_argument_thread).nombre_references = %d\n",
695: (int) (*s_argument_thread).nombre_references));
696:
697: if ((*s_argument_thread).nombre_references == 0)
698: {
699: close((*s_argument_thread).pipe_objets[0]);
700: close((*s_argument_thread).pipe_acquittement[1]);
701: close((*s_argument_thread).pipe_injections[1]);
702: close((*s_argument_thread).pipe_nombre_injections[1]);
703: close((*s_argument_thread).pipe_nombre_objets_attente[0]);
704: close((*s_argument_thread).pipe_interruptions[0]);
705: close((*s_argument_thread)
706: .pipe_nombre_interruptions_attente[0]);
707:
708: if (pthread_mutex_unlock(&((*s_argument_thread)
709: .mutex_nombre_references)) != 0)
710: {
711: (*s_etat_processus).erreur_systeme = d_es_processus;
712: sem_post(&semaphore_liste_threads);
713: return;
714: }
715:
716: pthread_mutex_destroy(&((*s_argument_thread).mutex));
717: pthread_mutex_destroy(&((*s_argument_thread)
718: .mutex_nombre_references));
719:
720: if ((*s_argument_thread).processus_detache == d_faux)
721: {
722: if ((*s_argument_thread).destruction_objet == d_vrai)
723: {
724: liberation(s_etat_processus, (*s_argument_thread)
725: .argument);
726: }
727: }
728:
729: free(s_argument_thread);
730: }
731: else
732: {
733: if (pthread_mutex_unlock(&((*s_argument_thread)
734: .mutex_nombre_references)) != 0)
735: {
736: (*s_etat_processus).erreur_systeme = d_es_processus;
737: sem_post(&semaphore_liste_threads);
738: return;
739: }
740: }
741:
742: element_suivant = (*((struct_liste_chainee *) element_courant))
743: .suivant;
744: free(element_courant);
745: element_courant = element_suivant;
746: }
747:
748: (*s_etat_processus).l_base_pile_processus = NULL;
749:
750: pthread_mutex_trylock(&((*(*s_etat_processus).indep).mutex));
751: pthread_mutex_unlock(&((*(*s_etat_processus).indep).mutex));
752: liberation(s_etat_processus, (*s_etat_processus).indep);
753:
754: pthread_mutex_trylock(&((*(*s_etat_processus).depend).mutex));
755: pthread_mutex_unlock(&((*(*s_etat_processus).depend).mutex));
756: liberation(s_etat_processus, (*s_etat_processus).depend);
757:
758: free((*s_etat_processus).label_x);
759: free((*s_etat_processus).label_y);
760: free((*s_etat_processus).label_z);
761: free((*s_etat_processus).titre);
762: free((*s_etat_processus).legende);
763:
764: pthread_mutex_trylock(&((*(*s_etat_processus)
765: .parametres_courbes_de_niveau).mutex));
766: pthread_mutex_unlock(&((*(*s_etat_processus)
767: .parametres_courbes_de_niveau).mutex));
768: liberation(s_etat_processus, (*s_etat_processus)
769: .parametres_courbes_de_niveau);
770:
771: for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++)
772: {
773: if ((*s_etat_processus).corps_interruptions[i] != NULL)
774: {
775: pthread_mutex_trylock(&((*(*s_etat_processus)
776: .corps_interruptions[i]).mutex));
777: pthread_mutex_unlock(&((*(*s_etat_processus)
778: .corps_interruptions[i]).mutex));
779:
780: liberation(s_etat_processus,
781: (*s_etat_processus).corps_interruptions[i]);
782: }
783:
784: element_courant = (*s_etat_processus)
785: .pile_origine_interruptions[i];
786:
787: while(element_courant != NULL)
788: {
789: element_suivant = (*((struct_liste_chainee *)
790: element_courant)).suivant;
791:
792: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
793: element_courant)).donnee).mutex));
794: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
795: element_courant)).donnee).mutex));
796:
797: liberation(s_etat_processus,
798: (*((struct_liste_chainee *) element_courant))
799: .donnee);
800: free(element_courant);
801:
802: element_courant = element_suivant;
803: }
804: }
805:
806: liberation_arbre_variables(s_etat_processus,
807: (*s_etat_processus).s_arbre_variables, d_faux);
808:
809: for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)
810: {
811: pthread_mutex_trylock(&((*(*s_etat_processus)
812: .s_liste_variables_statiques[i].objet).mutex));
813: pthread_mutex_unlock(&((*(*s_etat_processus)
814: .s_liste_variables_statiques[i].objet).mutex));
815:
816: liberation(s_etat_processus, (*s_etat_processus)
817: .s_liste_variables_statiques[i].objet);
818: free((*s_etat_processus).s_liste_variables_statiques[i].nom);
819: }
820:
821: free((*s_etat_processus).s_liste_variables_statiques);
822:
823: // Ne peut être effacé qu'une seule fois
824: if (suppression_variables_partagees == d_faux)
825: {
826: suppression_variables_partagees = d_vrai;
827:
828: for(i = 0; i < (*(*s_etat_processus)
829: .s_liste_variables_partagees).nombre_variables; i++)
830: {
831: pthread_mutex_trylock(&((*(*(*s_etat_processus)
832: .s_liste_variables_partagees).table[i].objet)
833: .mutex));
834: pthread_mutex_unlock(&((*(*(*s_etat_processus)
835: .s_liste_variables_partagees).table[i].objet)
836: .mutex));
837:
838: liberation(s_etat_processus, (*(*s_etat_processus)
839: .s_liste_variables_partagees).table[i].objet);
840: free((*(*s_etat_processus).s_liste_variables_partagees)
841: .table[i].nom);
842: }
843:
844: if ((*(*s_etat_processus).s_liste_variables_partagees).table
845: != NULL)
846: {
847: free((struct_variable_partagee *) (*(*s_etat_processus)
848: .s_liste_variables_partagees).table);
849: }
850:
851: pthread_mutex_trylock(&((*(*s_etat_processus)
852: .s_liste_variables_partagees).mutex));
853: pthread_mutex_unlock(&((*(*s_etat_processus)
854: .s_liste_variables_partagees).mutex));
855: }
856:
857: element_courant = (*s_etat_processus).l_base_pile;
858: while(element_courant != NULL)
859: {
860: element_suivant = (*((struct_liste_chainee *)
861: element_courant)).suivant;
862:
863: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
864: element_courant)).donnee).mutex));
865: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
866: element_courant)).donnee).mutex));
867:
868: liberation(s_etat_processus,
869: (*((struct_liste_chainee *)
870: element_courant)).donnee);
871: free((struct_liste_chainee *) element_courant);
872:
873: element_courant = element_suivant;
874: }
875:
876: element_courant = (*s_etat_processus).l_base_pile_contextes;
877: while(element_courant != NULL)
878: {
879: element_suivant = (*((struct_liste_chainee *)
880: element_courant)).suivant;
881:
882: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
883: element_courant)).donnee).mutex));
884: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
885: element_courant)).donnee).mutex));
886: liberation(s_etat_processus, (*((struct_liste_chainee *)
887: element_courant)).donnee);
888: free((struct_liste_chainee *) element_courant);
889:
890: element_courant = element_suivant;
891: }
892:
893: element_courant = (*s_etat_processus).l_base_pile_taille_contextes;
894: while(element_courant != NULL)
895: {
896: element_suivant = (*((struct_liste_chainee *)
897: element_courant)).suivant;
898:
899: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
900: element_courant)).donnee).mutex));
901: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
902: element_courant)).donnee).mutex));
903: liberation(s_etat_processus,
904: (*((struct_liste_chainee *)
905: element_courant)).donnee);
906: free((struct_liste_chainee *) element_courant);
907:
908: element_courant = element_suivant;
909: }
910:
911: for(i = 0; i < (*s_etat_processus).nombre_instructions_externes;
912: i++)
913: {
914: free((*s_etat_processus).s_instructions_externes[i].nom);
915: free((*s_etat_processus).s_instructions_externes[i]
916: .nom_bibliotheque);
917: }
918:
919: if ((*s_etat_processus).nombre_instructions_externes != 0)
920: {
921: free((*s_etat_processus).s_instructions_externes);
922: }
923:
924: element_courant = (*s_etat_processus).s_bibliotheques;
925: while(element_courant != NULL)
926: {
927: element_suivant = (*((struct_liste_chainee *)
928: element_courant)).suivant;
929:
930: element_candidat = (*candidat).s_bibliotheques;
931: while(element_candidat != NULL)
932: {
933: if (((*((struct_bibliotheque *) (*((struct_liste_chainee *)
934: element_courant)).donnee))
935: .descripteur == (*((struct_bibliotheque *)
936: (*((struct_liste_chainee *) element_candidat))
937: .donnee)).descripteur) &&
938: ((*((struct_bibliotheque *)
939: (*((struct_liste_chainee *) element_courant))
940: .donnee)).pid == (*((struct_bibliotheque *)
941: (*((struct_liste_chainee *) element_candidat))
942: .donnee)).pid) && (pthread_equal(
943: (*((struct_bibliotheque *)
944: (*((struct_liste_chainee *) element_courant))
945: .donnee)).tid, (*((struct_bibliotheque *)
946: (*((struct_liste_chainee *) element_candidat))
947: .donnee)).tid) != 0))
948: {
949: break;
950: }
951:
952: element_candidat = (*((struct_liste_chainee *)
953: element_candidat)).suivant;
954: }
955:
956: if (element_candidat == NULL)
957: {
958: dlclose((*((struct_bibliotheque *)
959: (*((struct_liste_chainee *) element_courant))
960: .donnee)).descripteur);
961: }
962:
963: free((*((struct_bibliotheque *)
964: (*((struct_liste_chainee *)
965: element_courant)).donnee)).nom);
966: free((*((struct_liste_chainee *) element_courant)).donnee);
967: free(element_courant);
968:
969: element_courant = element_suivant;
970: }
971:
972: element_courant = (*s_etat_processus).l_base_pile_last;
973: while(element_courant != NULL)
974: {
975: element_suivant = (*((struct_liste_chainee *)
976: element_courant)).suivant;
977:
978: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
979: element_courant)).donnee).mutex));
980: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
981: element_courant)).donnee).mutex));
982: liberation(s_etat_processus,
983: (*((struct_liste_chainee *) element_courant)).donnee);
984: free(element_courant);
985:
986: element_courant = element_suivant;
987: }
988:
989: element_courant = (*s_etat_processus).l_base_pile_undo;
990: while(element_courant != NULL)
991: {
992: element_suivant = (*((struct_liste_chainee *)
993: element_courant)).suivant;
994:
995: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
996: element_courant)).donnee).mutex));
997: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
998: element_courant)).donnee).mutex));
999: liberation(s_etat_processus,
1000: (*((struct_liste_chainee *) element_courant)).donnee);
1001: free(element_courant);
1002:
1003: element_courant = element_suivant;
1004: }
1005:
1006: element_courant = (*s_etat_processus).l_base_pile_systeme;
1007: while(element_courant != NULL)
1008: {
1009: element_suivant = (*((struct_liste_pile_systeme *)
1010: element_courant)).suivant;
1011:
1012: if ((*((struct_liste_pile_systeme *)
1013: element_courant)).indice_boucle != NULL)
1014: {
1015: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
1016: element_courant)).indice_boucle).mutex));
1017: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
1018: element_courant)).indice_boucle).mutex));
1019: }
1020:
1021: liberation(s_etat_processus,
1022: (*((struct_liste_pile_systeme *)
1023: element_courant)).indice_boucle);
1024:
1025: if ((*((struct_liste_pile_systeme *)
1026: element_courant)).limite_indice_boucle != NULL)
1027: {
1028: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
1029: element_courant)).limite_indice_boucle).mutex));
1030: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
1031: element_courant)).limite_indice_boucle).mutex));
1032: }
1033:
1034: liberation(s_etat_processus,
1035: (*((struct_liste_pile_systeme *)
1036: element_courant)).limite_indice_boucle);
1037:
1038: if ((*((struct_liste_pile_systeme *)
1039: element_courant)).objet_de_test != NULL)
1040: {
1041: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
1042: element_courant)).objet_de_test).mutex));
1043: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
1044: element_courant)).objet_de_test).mutex));
1045: }
1046:
1047: liberation(s_etat_processus,
1048: (*((struct_liste_pile_systeme *)
1049: element_courant)).objet_de_test);
1050:
1051: if ((*((struct_liste_pile_systeme *)
1052: element_courant)).nom_variable != NULL)
1053: {
1054: free((*((struct_liste_pile_systeme *)
1055: element_courant)).nom_variable);
1056: }
1057:
1058: free(element_courant);
1059:
1060: element_courant = element_suivant;
1061: }
1062:
1063: element_courant = (*s_etat_processus).s_fichiers;
1064: while(element_courant != NULL)
1065: {
1066: element_suivant = (*((struct_liste_chainee *)
1067: element_courant)).suivant;
1068:
1069: element_candidat = (*candidat).s_fichiers;
1070: while(element_candidat != NULL)
1071: {
1072: if (((*((struct_descripteur_fichier *)
1073: (*((struct_liste_chainee *) element_courant))
1074: .donnee)).pid ==
1075: (*((struct_descripteur_fichier *)
1076: (*((struct_liste_chainee *) element_candidat))
1077: .donnee)).pid) && (pthread_equal(
1078: (*((struct_descripteur_fichier *)
1079: (*((struct_liste_chainee *) element_courant))
1080: .donnee)).tid, (*((struct_descripteur_fichier *)
1081: (*((struct_liste_chainee *) element_candidat))
1082: .donnee)).tid) != 0))
1083: {
1084: if ((*((struct_descripteur_fichier *)
1085: (*((struct_liste_chainee *) element_courant))
1086: .donnee)).type ==
1087: (*((struct_descripteur_fichier *)
1088: (*((struct_liste_chainee *) element_candidat))
1089: .donnee)).type)
1090: {
1091: if ((*((struct_descripteur_fichier *)
1092: (*((struct_liste_chainee *)
1093: element_candidat)).donnee)).type == 'C')
1094: {
1095: if ((*((struct_descripteur_fichier *)
1096: (*((struct_liste_chainee *)
1097: element_courant)).donnee))
1098: .descripteur_c ==
1099: (*((struct_descripteur_fichier *)
1100: (*((struct_liste_chainee *)
1101: element_candidat)).donnee))
1102: .descripteur_c)
1103: {
1104: break;
1105: }
1106: }
1107: else
1108: {
1109: if (((*((struct_descripteur_fichier *)
1110: (*((struct_liste_chainee *)
1111: element_courant)).donnee))
1112: .descripteur_sqlite ==
1113: (*((struct_descripteur_fichier *)
1114: (*((struct_liste_chainee *)
1115: element_candidat)).donnee))
1116: .descripteur_sqlite) &&
1117: ((*((struct_descripteur_fichier *)
1118: (*((struct_liste_chainee *)
1119: element_courant)).donnee))
1120: .descripteur_c ==
1121: (*((struct_descripteur_fichier *)
1122: (*((struct_liste_chainee *)
1123: element_candidat)).donnee))
1124: .descripteur_c))
1125: {
1126: break;
1127: }
1128: }
1129: }
1130: }
1131:
1132: element_candidat = (*((struct_liste_chainee *)
1133: element_candidat)).suivant;
1134: }
1135:
1136: if (element_candidat == NULL)
1137: {
1138: fclose((*((struct_descripteur_fichier *)
1139: (*((struct_liste_chainee *) element_courant))
1140: .donnee)).descripteur_c);
1141:
1142: if ((*((struct_descripteur_fichier *)
1143: (*((struct_liste_chainee *) element_courant))
1144: .donnee)).type != 'C')
1145: {
1146: sqlite3_close((*((struct_descripteur_fichier *)
1147: (*((struct_liste_chainee *) element_courant))
1148: .donnee)).descripteur_sqlite);
1149: }
1150: }
1151:
1152: free((*((struct_descripteur_fichier *)
1153: (*((struct_liste_chainee *)
1154: element_courant)).donnee)).nom);
1155: free((struct_descripteur_fichier *)
1156: (*((struct_liste_chainee *)
1157: element_courant)).donnee);
1158: free(element_courant);
1159:
1160: element_courant = element_suivant;
1161: }
1162:
1163: element_courant = (*s_etat_processus).s_sockets;
1164: while(element_courant != NULL)
1165: {
1166: element_suivant = (*((struct_liste_chainee *)
1167: element_courant)).suivant;
1168:
1169: element_candidat = (*candidat).s_sockets;
1170: while(element_candidat != NULL)
1171: {
1172: if (((*((struct_socket *)
1173: (*((struct_liste_chainee *) element_courant))
1174: .donnee)).socket == (*((struct_socket *)
1175: (*((struct_liste_chainee *) element_candidat))
1176: .donnee)).socket) &&
1177: ((*((struct_socket *)
1178: (*((struct_liste_chainee *) element_courant))
1179: .donnee)).pid == (*((struct_socket *)
1180: (*((struct_liste_chainee *) element_candidat))
1181: .donnee)).pid) && (pthread_equal(
1182: (*((struct_socket *)
1183: (*((struct_liste_chainee *) element_courant))
1184: .donnee)).tid, (*((struct_socket *)
1185: (*((struct_liste_chainee *) element_candidat))
1186: .donnee)).tid) != 0))
1187: {
1188: break;
1189: }
1190:
1191: element_candidat = (*((struct_liste_chainee *)
1192: element_candidat)).suivant;
1193: }
1194:
1195: if (element_candidat == NULL)
1196: {
1197: if ((*((struct_socket *) (*((struct_liste_chainee *)
1198: element_courant)).donnee)).socket_connectee
1199: == d_vrai)
1200: {
1201: shutdown((*((struct_socket *)
1202: (*((struct_liste_chainee *) element_courant))
1203: .donnee)).socket, SHUT_RDWR);
1204: }
1205:
1206: close((*((struct_socket *)
1207: (*((struct_liste_chainee *) element_courant))
1208: .donnee)).socket);
1209: }
1210:
1211: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1212: element_courant)).donnee).mutex));
1213: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1214: element_courant)).donnee).mutex));
1215:
1216: liberation(s_etat_processus,
1217: (*((struct_liste_chainee *)
1218: element_courant)).donnee);
1219: free(element_courant);
1220:
1221: element_courant = element_suivant;
1222: }
1223:
1224: /*
1225: ================================================================================
1226: À noter : on ne ferme pas la connexion car la conséquence immédiate est
1227: une destruction de l'objet pour le processus père.
1228: ================================================================================
1229:
1230: element_courant = (*s_etat_processus).s_connecteurs_sql;
1231: while(element_courant != NULL)
1232: {
1233: element_suivant = (*((struct_liste_chainee *)
1234: element_courant)).suivant;
1235:
1236: element_candidat = (*candidat).s_connecteurs_sql;
1237: while(element_candidat != NULL)
1238: {
1239: if (((
1240: #ifdef MYSQL_SUPPORT
1241: ((*((struct_connecteur_sql *)
1242: (*((struct_liste_chainee *) element_courant))
1243: .donnee)).descripteur.mysql ==
1244: (*((struct_connecteur_sql *)
1245: (*((struct_liste_chainee *) element_candidat))
1246: .donnee)).descripteur.mysql)
1247: &&
1248: (strcmp((*((struct_connecteur_sql *)
1249: (*((struct_liste_chainee *) element_courant))
1250: .donnee)).type, "MYSQL") == 0)
1251: &&
1252: (strcmp((*((struct_connecteur_sql *)
1253: (*((struct_liste_chainee *) element_candidat))
1254: .donnee)).type, "MYSQL") == 0)
1255: #else
1256: 0
1257: #endif
1258: ) || (
1259: #ifdef POSTGRESQL_SUPPORT
1260: ((*((struct_connecteur_sql *)
1261: (*((struct_liste_chainee *) element_courant))
1262: .donnee)).descripteur.postgresql ==
1263: (*((struct_connecteur_sql *)
1264: (*((struct_liste_chainee *) element_candidat))
1265: .donnee)).descripteur.postgresql)
1266: &&
1267: (strcmp((*((struct_connecteur_sql *)
1268: (*((struct_liste_chainee *) element_courant))
1269: .donnee)).type, "POSTGRESQL") == 0)
1270: &&
1271: (strcmp((*((struct_connecteur_sql *)
1272: (*((struct_liste_chainee *) element_candidat))
1273: .donnee)).type, "POSTGRESQL") == 0)
1274: #else
1275: 0
1276: #endif
1277: )) &&
1278: ((*((struct_connecteur_sql *)
1279: (*((struct_liste_chainee *) element_courant))
1280: .donnee)).pid == (*((struct_connecteur_sql *)
1281: (*((struct_liste_chainee *) element_candidat))
1282: .donnee)).pid) && (pthread_equal(
1283: (*((struct_connecteur_sql *)
1284: (*((struct_liste_chainee *) element_courant))
1285: .donnee)).tid, (*((struct_connecteur_sql *)
1286: (*((struct_liste_chainee *) element_candidat))
1287: .donnee)).tid) != 0))
1288: {
1289: break;
1290: }
1291:
1292: element_candidat = (*((struct_liste_chainee *)
1293: element_candidat)).suivant;
1294: }
1295:
1296: if (element_candidat == NULL)
1297: {
1298: sqlclose((*((struct_liste_chainee *) element_courant))
1299: .donnee);
1300: }
1301:
1302: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1303: element_courant)).donnee).mutex));
1304: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1305: element_courant)).donnee).mutex));
1306:
1307: liberation(s_etat_processus, (*((struct_liste_chainee *)
1308: element_courant)).donnee);
1309: free(element_courant);
1310:
1311: element_courant = element_suivant;
1312: }
1313: */
1314:
1315: (*s_etat_processus).s_connecteurs_sql = NULL;
1316:
1317: element_courant = (*s_etat_processus).s_marques;
1318: while(element_courant != NULL)
1319: {
1320: free((*((struct_marque *) element_courant)).label);
1321: free((*((struct_marque *) element_courant)).position);
1322: element_suivant = (*((struct_marque *) element_courant))
1323: .suivant;
1324: free(element_courant);
1325: element_courant = element_suivant;
1326: }
1327:
1328: liberation_allocateur(s_etat_processus);
1329:
1330: # ifndef SEMAPHORES_NOMMES
1331: sem_post(&((*s_etat_processus).semaphore_fork));
1332: sem_destroy(&((*s_etat_processus).semaphore_fork));
1333: # else
1334: sem_post((*s_etat_processus).semaphore_fork);
1335: sem_destroy2((*s_etat_processus).semaphore_fork, sem_fork);
1336: # endif
1337:
1338: liberation_contexte_cas(s_etat_processus);
1339: free(s_etat_processus);
1340:
1341: s_etat_processus = candidat;
1342: }
1343:
1344: l_element_suivant = (*l_element_courant).suivant;
1345:
1346: free((struct_thread *) (*l_element_courant).donnee);
1347: free((struct_liste_chainee *) l_element_courant);
1348:
1349: l_element_courant = l_element_suivant;
1350: }
1351:
1352: liste_threads = NULL;
1353:
1354: l_element_courant = liste_threads_surveillance;
1355:
1356: while(l_element_courant != NULL)
1357: {
1358: s_argument_thread = (struct_descripteur_thread *)
1359: (*l_element_courant).donnee;
1360:
1361: if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
1362: != 0)
1363: {
1364: (*s_etat_processus).erreur_systeme = d_es_processus;
1365: sem_post(&semaphore_liste_threads);
1366: return;
1367: }
1368:
1369: (*s_argument_thread).nombre_references--;
1370:
1371: BUG((*s_argument_thread).nombre_references < 0,
1372: printf("(*s_argument_thread).nombre_references = %d\n",
1373: (int) (*s_argument_thread).nombre_references));
1374:
1375: if ((*s_argument_thread).nombre_references == 0)
1376: {
1377: close((*s_argument_thread).pipe_objets[0]);
1378: close((*s_argument_thread).pipe_acquittement[1]);
1379: close((*s_argument_thread).pipe_injections[1]);
1380: close((*s_argument_thread).pipe_nombre_injections[1]);
1381: close((*s_argument_thread).pipe_nombre_objets_attente[0]);
1382: close((*s_argument_thread).pipe_interruptions[0]);
1383: close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);
1384:
1385: if (pthread_mutex_unlock(&((*s_argument_thread)
1386: .mutex_nombre_references)) != 0)
1387: {
1388: (*s_etat_processus).erreur_systeme = d_es_processus;
1389: sem_post(&semaphore_liste_threads);
1390: return;
1391: }
1392:
1393: pthread_mutex_destroy(&((*s_argument_thread).mutex));
1394: pthread_mutex_destroy(&((*s_argument_thread)
1395: .mutex_nombre_references));
1396:
1397: if ((*s_argument_thread).processus_detache == d_faux)
1398: {
1399: if ((*s_argument_thread).destruction_objet == d_vrai)
1400: {
1401: liberation(s_etat_processus, (*s_argument_thread).argument);
1402: }
1403: }
1404:
1405: free(s_argument_thread);
1406: }
1407: else
1408: {
1409: if (pthread_mutex_unlock(&((*s_argument_thread)
1410: .mutex_nombre_references)) != 0)
1411: {
1412: (*s_etat_processus).erreur_systeme = d_es_processus;
1413: sem_post(&semaphore_liste_threads);
1414: return;
1415: }
1416: }
1417:
1418: l_element_suivant = (*l_element_courant).suivant;
1419: free((struct_liste_chainee *) l_element_courant);
1420: l_element_courant = l_element_suivant;
1421: }
1422:
1423: liste_threads_surveillance = NULL;
1424:
1425: # ifndef SEMAPHORES_NOMMES
1426: if (sem_post(&semaphore_liste_threads) != 0)
1427: # else
1428: if (sem_post(semaphore_liste_threads) != 0)
1429: # endif
1430: {
1431: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1432: (*s_etat_processus).erreur_systeme = d_es_processus;
1433: return;
1434: }
1435:
1436: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1437: sigpending(&set);
1438: return;
1439: }
1440:
1441: static struct_processus *
1442: recherche_thread(pid_t pid, pthread_t tid)
1443: {
1444: volatile struct_liste_chainee_volatile *l_element_courant;
1445:
1446: struct_processus *s_etat_processus;
1447:
1448: l_element_courant = liste_threads;
1449:
1450: while(l_element_courant != NULL)
1451: {
1452: if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee))
1453: .tid, tid) != 0) && ((*((struct_thread *)
1454: (*l_element_courant).donnee)).pid == pid))
1455: {
1456: break;
1457: }
1458:
1459: l_element_courant = (*l_element_courant).suivant;
1460: }
1461:
1462: if (l_element_courant == NULL)
1463: {
1464: /*
1465: * Le processus n'existe plus. On ne distribue aucun signal.
1466: */
1467:
1468: return(NULL);
1469: }
1470:
1471: s_etat_processus = (*((struct_thread *)
1472: (*l_element_courant).donnee)).s_etat_processus;
1473:
1474: return(s_etat_processus);
1475: }
1476:
1477: static logical1
1478: recherche_thread_principal(pid_t pid, pthread_t *thread)
1479: {
1480: volatile struct_liste_chainee_volatile *l_element_courant;
1481:
1482: l_element_courant = liste_threads;
1483:
1484: while(l_element_courant != NULL)
1485: {
1486: if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal
1487: == d_vrai) && ((*((struct_thread *)
1488: (*l_element_courant).donnee)).pid == pid))
1489: {
1490: break;
1491: }
1492:
1493: l_element_courant = (*l_element_courant).suivant;
1494: }
1495:
1496: if (l_element_courant == NULL)
1497: {
1498: /*
1499: * Le processus n'existe plus. On ne distribue aucun signal.
1500: */
1501:
1502: return(d_faux);
1503: }
1504:
1505: (*thread) = (*((struct_thread *) (*l_element_courant).donnee)).tid;
1506:
1507: return(d_vrai);
1508: }
1509:
1510:
1511: /*
1512: ================================================================================
1513: Procédures de gestion des signaux d'interruption
1514: ================================================================================
1515: Entrée : variable globale
1516: --------------------------------------------------------------------------------
1517: Sortie : variable globale modifiée
1518: --------------------------------------------------------------------------------
1519: Effets de bord : néant
1520: ================================================================================
1521: */
1522:
1523: // Les routines suivantes sont uniquement appelées depuis les gestionnaires
1524: // des signaux asynchrones. Elles ne doivent pas bloquer dans le cas où
1525: // les sémaphores sont déjà bloqués par un gestionnaire de signal.
1526:
1527: static inline void
1528: verrouillage_gestionnaire_signaux()
1529: {
1530: int semaphore;
1531:
1532: sigset_t oldset;
1533: sigset_t set;
1534:
1535: sem_t *sem;
1536:
1537: if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
1538: != NULL)
1539: {
1540: if (sem_post(sem) != 0)
1541: {
1542: BUG(1, uprintf("Lock error !\n"));
1543: return;
1544: }
1545: }
1546:
1547: // Il faut respecteur l'atomicité des deux opérations suivantes !
1548:
1549: sigfillset(&set);
1550: pthread_sigmask(SIG_BLOCK, &set, &oldset);
1551:
1552: # ifndef SEMAPHORES_NOMMES
1553: while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
1554: # else
1555: while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)
1556: # endif
1557: {
1558: if (errno != EINTR)
1559: {
1560: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1561: BUG(1, uprintf("Unlock error !\n"));
1562: return;
1563: }
1564: }
1565:
1566: # ifndef SEMAPHORES_NOMMES
1567: if (sem_post(&semaphore_gestionnaires_signaux) == -1)
1568: # else
1569: if (sem_post(semaphore_gestionnaires_signaux) == -1)
1570: # endif
1571: {
1572: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1573: BUG(1, uprintf("Lock error !\n"));
1574: return;
1575: }
1576:
1577: # ifndef SEMAPHORES_NOMMES
1578: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1579: # else
1580: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1581: # endif
1582: {
1583: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1584: BUG(1, uprintf("Lock error !\n"));
1585: return;
1586: }
1587:
1588: # ifndef SEMAPHORES_NOMMES
1589: if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
1590: # else
1591: if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)
1592: # endif
1593: {
1594: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1595: BUG(1, uprintf("Unlock error !\n"));
1596: return;
1597: }
1598:
1599: if (semaphore == 1)
1600: {
1601: // Le semaphore ne peut être pris par le thread qui a appelé
1602: // le gestionnaire de signal car le signal est bloqué par ce thread
1603: // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que
1604: // par un thread concurrent. On essaye donc de le bloquer jusqu'à
1605: // ce que ce soit possible.
1606:
1607: # ifndef SEMAPHORES_NOMMES
1608: while(sem_wait(&semaphore_liste_threads) == -1)
1609: # else
1610: while(sem_wait(semaphore_liste_threads) == -1)
1611: # endif
1612: {
1613: if (errno != EINTR)
1614: {
1615: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1616:
1617: while(sem_wait(sem) == -1)
1618: {
1619: if (errno != EINTR)
1620: {
1621: BUG(1, uprintf("Lock error !\n"));
1622: return;
1623: }
1624: }
1625:
1626: BUG(1, uprintf("Lock error !\n"));
1627: return;
1628: }
1629: }
1630: }
1631:
1632: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1633: sigpending(&set);
1634:
1635: return;
1636: }
1637:
1638: static inline void
1639: deverrouillage_gestionnaire_signaux()
1640: {
1641: int semaphore;
1642:
1643: sem_t *sem;
1644:
1645: sigset_t oldset;
1646: sigset_t set;
1647:
1648: // Il faut respecteur l'atomicité des deux opérations suivantes !
1649:
1650: sigfillset(&set);
1651: pthread_sigmask(SIG_BLOCK, &set, &oldset);
1652:
1653: # ifndef SEMAPHORES_NOMMES
1654: while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
1655: # else
1656: while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)
1657: # endif
1658: {
1659: if (errno != EINTR)
1660: {
1661: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1662: BUG(1, uprintf("Unlock error !\n"));
1663: return;
1664: }
1665: }
1666:
1667: # ifndef SEMAPHORES_NOMMES
1668: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1669: # else
1670: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1671: # endif
1672: {
1673: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1674: BUG(1, uprintf("Unlock error !\n"));
1675: return;
1676: }
1677:
1678: # ifndef SEMAPHORES_NOMMES
1679: while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
1680: # else
1681: while(sem_wait(semaphore_gestionnaires_signaux) == -1)
1682: # endif
1683: {
1684: if (errno != EINTR)
1685: {
1686: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1687: BUG(1, uprintf("Unlock error !\n"));
1688: return;
1689: }
1690: }
1691:
1692: # ifndef SEMAPHORES_NOMMES
1693: if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
1694: # else
1695: if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)
1696: # endif
1697: {
1698: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1699: BUG(1, uprintf("Unlock error !\n"));
1700: return;
1701: }
1702:
1703: if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
1704: != NULL)
1705: {
1706: while(sem_wait(sem) == -1)
1707: {
1708: if (errno != EINTR)
1709: {
1710: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1711: BUG(1, uprintf("Unlock error !\n"));
1712: return;
1713: }
1714: }
1715: }
1716:
1717: if (semaphore == 1)
1718: {
1719: # ifndef SEMAPHORES_NOMMES
1720: if (sem_post(&semaphore_liste_threads) != 0)
1721: # else
1722: if (sem_post(semaphore_liste_threads) != 0)
1723: # endif
1724: {
1725: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1726:
1727: BUG(1, uprintf("Unlock error !\n"));
1728: return;
1729: }
1730: }
1731:
1732: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1733: sigpending(&set);
1734:
1735: return;
1736: }
1737:
1738: void
1739: interruption1(SIGHANDLER_ARGS)
1740: {
1741: pid_t pid;
1742:
1743: pthread_t thread;
1744:
1745: struct_processus *s_etat_processus;
1746:
1747: volatile sig_atomic_t exclusion = 0;
1748:
1749: verrouillage_gestionnaire_signaux();
1750:
1751: # ifdef _BROKEN_SIGINFO
1752: if ((signal == SIGINT) || (signal == SIGTERM))
1753: {
1754: // Si l'interruption provient du clavier, il n'y a pas eu d'appel
1755: // à queue_in().
1756:
1757: pid = getpid();
1758: }
1759: else
1760: {
1761: pid = origine_signal(signal);
1762: }
1763: # else
1764: if (siginfo != NULL)
1765: {
1766: pid = (*siginfo).si_pid;
1767: }
1768: else
1769: {
1770: pid = getpid();
1771: }
1772: # endif
1773:
1774: switch(signal)
1775: {
1776: case SIGALRM :
1777: {
1778: if (pid == getpid())
1779: {
1780: if ((s_etat_processus = recherche_thread(getpid(),
1781: pthread_self())) == NULL)
1782: {
1783: deverrouillage_gestionnaire_signaux();
1784: return;
1785: }
1786:
1787: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1788: {
1789: printf("[%d] SIGALRM (thread %llu)\n", (int) getpid(),
1790: (unsigned long long) pthread_self());
1791: fflush(stdout);
1792: }
1793:
1794: if ((*s_etat_processus).pid_processus_pere != getpid())
1795: {
1796: kill((*s_etat_processus).pid_processus_pere, signal);
1797: }
1798: else
1799: {
1800: (*s_etat_processus).var_volatile_alarme = -1;
1801: (*s_etat_processus).var_volatile_requete_arret = -1;
1802: }
1803: }
1804: else
1805: {
1806: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1807: {
1808: pthread_kill(thread, signal);
1809: }
1810: }
1811:
1812: break;
1813: }
1814:
1815: case SIGINT :
1816: case SIGTERM :
1817: {
1818: /*
1819: * Une vieille spécification POSIX permet au pointeur siginfo
1820: * d'être nul dans le cas d'un ^C envoyé depuis le clavier.
1821: * Solaris suit en particulier cette spécification.
1822: */
1823:
1824: # ifndef _BROKEN_SIGINFO
1825: if (siginfo == NULL)
1826: {
1827: kill(getpid(), signal);
1828: }
1829: else
1830: # endif
1831: if (pid == getpid())
1832: {
1833: if ((s_etat_processus = recherche_thread(getpid(),
1834: pthread_self())) == NULL)
1835: {
1836: deverrouillage_gestionnaire_signaux();
1837: return;
1838: }
1839:
1840: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1841: {
1842: if (signal == SIGINT)
1843: {
1844: printf("[%d] SIGINT (thread %llu)\n", (int) getpid(),
1845: (unsigned long long) pthread_self());
1846: }
1847: else
1848: {
1849: printf("[%d] SIGTERM (thread %llu)\n", (int) getpid(),
1850: (unsigned long long) pthread_self());
1851: }
1852:
1853: fflush(stdout);
1854: }
1855:
1856: if ((*s_etat_processus).pid_processus_pere != getpid())
1857: {
1858: kill((*s_etat_processus).pid_processus_pere, signal);
1859: }
1860: else
1861: {
1862: (*s_etat_processus).var_volatile_traitement_sigint = -1;
1863:
1864: while(exclusion == 1);
1865: exclusion = 1;
1866:
1867: if ((*s_etat_processus).var_volatile_requete_arret == -1)
1868: {
1869: deverrouillage_gestionnaire_signaux();
1870: exclusion = 0;
1871: return;
1872: }
1873:
1874: if (signal == SIGINT)
1875: {
1876: if (strncmp(getenv("LANG"), "fr", 2) == 0)
1877: {
1878: printf("+++Interruption\n");
1879: }
1880: else
1881: {
1882: printf("+++Interrupt\n");
1883: }
1884:
1885: fflush(stdout);
1886: }
1887:
1888: (*s_etat_processus).var_volatile_requete_arret = -1;
1889: (*s_etat_processus).var_volatile_alarme = -1;
1890:
1891: exclusion = 0;
1892: }
1893: }
1894: else
1895: {
1896: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1897: {
1898: pthread_kill(thread, signal);
1899: }
1900: }
1901:
1902: break;
1903: }
1904:
1905: default :
1906: {
1907: BUG(1, uprintf("[%d] Unknown signal %d in this context\n",
1908: (int) getpid(), signal));
1909: break;
1910: }
1911: }
1912:
1913: deverrouillage_gestionnaire_signaux();
1914: return;
1915: }
1916:
1917: void
1918: interruption2(SIGHANDLER_ARGS)
1919: {
1920: pid_t pid;
1921:
1922: pthread_t thread;
1923:
1924: struct_processus *s_etat_processus;
1925:
1926: verrouillage_gestionnaire_signaux();
1927:
1928: # ifdef _BROKEN_SIGINFO
1929: pid = origine_signal(signal);
1930: # else
1931: if (siginfo != NULL)
1932: {
1933: pid = (*siginfo).si_pid;
1934: }
1935: else
1936: {
1937: pid = getpid();
1938: }
1939: # endif
1940:
1941: # ifndef _BROKEN_SIGINFO
1942: if (siginfo == NULL)
1943: {
1944: /*
1945: * Le signal SIGFSTP provient de la mort du processus de contrôle.
1946: * Sous certains systèmes (Linux...), la mort du terminal de contrôle
1947: * se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
1948: * (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
1949: * non initialisée (pointeur NULL) issue de TERMIO.
1950: */
1951:
1952: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1953: {
1954: pthread_kill(thread, SIGHUP);
1955: deverrouillage_gestionnaire_signaux();
1956: return;
1957: }
1958: }
1959: else
1960: # endif
1961: if (pid == getpid())
1962: {
1963: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
1964: == NULL)
1965: {
1966: deverrouillage_gestionnaire_signaux();
1967: return;
1968: }
1969:
1970: /*
1971: * 0 => fonctionnement normal
1972: * -1 => requête
1973: * 1 => requête acceptée en attente de traitement
1974: */
1975:
1976: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1977: {
1978: printf("[%d] SIGTSTP (thread %llu)\n", (int) getpid(),
1979: (unsigned long long) pthread_self());
1980: fflush(stdout);
1981: }
1982:
1983: if ((*s_etat_processus).var_volatile_processus_pere == 0)
1984: {
1985: kill((*s_etat_processus).pid_processus_pere, signal);
1986: }
1987: else
1988: {
1989: (*s_etat_processus).var_volatile_requete_arret2 = -1;
1990: }
1991: }
1992: else
1993: {
1994: // Envoi d'un signal au thread maître du groupe.
1995:
1996: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1997: {
1998: pthread_kill(thread, SIGTSTP);
1999: deverrouillage_gestionnaire_signaux();
2000: return;
2001: }
2002: }
2003:
2004: deverrouillage_gestionnaire_signaux();
2005: return;
2006: }
2007:
2008: void
2009: interruption3(SIGHANDLER_ARGS)
2010: {
2011: pid_t pid;
2012:
2013: struct_processus *s_etat_processus;
2014:
2015: static int compteur = 0;
2016:
2017: verrouillage_gestionnaire_signaux();
2018:
2019: # ifdef _BROKEN_SIGINFO
2020: pid = origine_signal(signal);
2021: # else
2022: pid = (*siginfo).si_pid;
2023: # endif
2024:
2025: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2026: {
2027: deverrouillage_gestionnaire_signaux();
2028: return;
2029: }
2030:
2031: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2032: {
2033: printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),
2034: (unsigned long long) pthread_self());
2035: fflush(stdout);
2036: }
2037:
2038: if ((*s_etat_processus).var_volatile_recursivite == -1)
2039: {
2040: // Segfault dans un appel de fonction récursive
2041: deverrouillage_gestionnaire_signaux();
2042: longjmp(contexte, -1);
2043: }
2044: else
2045: {
2046: // Segfault dans une routine interne
2047: if (strncmp(getenv("LANG"), "fr", 2) == 0)
2048: {
2049: printf("+++Système : Violation d'accès (dépassement de pile)\n");
2050: }
2051: else
2052: {
2053: printf("+++System : Access violation (stack overflow)\n");
2054: }
2055:
2056: fflush(stdout);
2057:
2058: compteur++;
2059:
2060: if (compteur > 1)
2061: {
2062: deverrouillage_gestionnaire_signaux();
2063: exit(EXIT_FAILURE);
2064: }
2065: else
2066: {
2067: deverrouillage_gestionnaire_signaux();
2068: longjmp(contexte_initial, -1);
2069: }
2070: }
2071:
2072: deverrouillage_gestionnaire_signaux();
2073: return;
2074: }
2075:
2076: void
2077: interruption4(SIGHANDLER_ARGS)
2078: {
2079: pid_t pid;
2080:
2081: struct_processus *s_etat_processus;
2082:
2083: verrouillage_gestionnaire_signaux();
2084:
2085: # ifdef _BROKEN_SIGINFO
2086: pid = origine_signal(signal);
2087: # else
2088: pid = (*siginfo).si_pid;
2089: # endif
2090:
2091: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2092: {
2093: deverrouillage_gestionnaire_signaux();
2094: return;
2095: }
2096:
2097: /*
2098: * Démarrage d'un processus fils ou gestion de SIGCONT (SUSPEND)
2099: */
2100:
2101: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2102: {
2103: printf("[%d] SIGSTART/SIGCONT (thread %llu)\n", (int) getpid(),
2104: (unsigned long long) pthread_self());
2105: fflush(stdout);
2106: }
2107:
2108: deverrouillage_gestionnaire_signaux();
2109: return;
2110: }
2111:
2112: void
2113: interruption5(SIGHANDLER_ARGS)
2114: {
2115: pid_t pid;
2116:
2117: pthread_t thread;
2118:
2119: struct_processus *s_etat_processus;
2120:
2121: verrouillage_gestionnaire_signaux();
2122:
2123: # ifdef _BROKEN_SIGINFO
2124: pid = origine_signal(signal);
2125: # else
2126: pid = (*siginfo).si_pid;
2127: # endif
2128:
2129: if (pid == getpid())
2130: {
2131: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2132: == NULL)
2133: {
2134: deverrouillage_gestionnaire_signaux();
2135: return;
2136: }
2137:
2138: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2139: {
2140: printf("[%d] SIGFSTOP (thread %llu)\n", (int) getpid(),
2141: (unsigned long long) pthread_self());
2142: fflush(stdout);
2143: }
2144:
2145: /*
2146: * var_globale_traitement_retarde_stop :
2147: * 0 -> traitement immédiat
2148: * 1 -> traitement retardé (aucun signal reçu)
2149: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2150: */
2151:
2152: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
2153: {
2154: (*s_etat_processus).var_volatile_requete_arret = -1;
2155: }
2156: else
2157: {
2158: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
2159: }
2160: }
2161: else
2162: {
2163: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2164: == NULL)
2165: {
2166: deverrouillage_gestionnaire_signaux();
2167: return;
2168: }
2169:
2170: // Envoi d'un signal au thread maître du groupe.
2171:
2172: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2173: {
2174: pthread_kill(thread, signal);
2175: deverrouillage_gestionnaire_signaux();
2176: return;
2177: }
2178: }
2179:
2180: deverrouillage_gestionnaire_signaux();
2181: return;
2182: }
2183:
2184: void
2185: interruption6(SIGHANDLER_ARGS)
2186: {
2187: pid_t pid;
2188:
2189: struct_processus *s_etat_processus;
2190:
2191: verrouillage_gestionnaire_signaux();
2192:
2193: # ifdef _BROKEN_SIGINFO
2194: pid = origine_signal(signal);
2195: # else
2196: pid = (*siginfo).si_pid;
2197: # endif
2198:
2199: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2200: {
2201: deverrouillage_gestionnaire_signaux();
2202: return;
2203: }
2204:
2205: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2206: {
2207: printf("[%d] SIGINJECT/SIGQUIT (thread %llu)\n", (int) getpid(),
2208: (unsigned long long) pthread_self());
2209: fflush(stdout);
2210: }
2211:
2212: deverrouillage_gestionnaire_signaux();
2213: return;
2214: }
2215:
2216: void
2217: interruption7(SIGHANDLER_ARGS)
2218: {
2219: pid_t pid;
2220:
2221: struct_processus *s_etat_processus;
2222:
2223: verrouillage_gestionnaire_signaux();
2224:
2225: # ifdef _BROKEN_SIGINFO
2226: pid = origine_signal(signal);
2227: # else
2228: pid = (*siginfo).si_pid;
2229: # endif
2230:
2231: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2232: {
2233: deverrouillage_gestionnaire_signaux();
2234: return;
2235: }
2236:
2237: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2238: {
2239: printf("[%d] SIGPIPE (thread %llu)\n", (int) getpid(),
2240: (unsigned long long) pthread_self());
2241: fflush(stdout);
2242: }
2243:
2244: (*s_etat_processus).var_volatile_requete_arret = -1;
2245: deverrouillage_gestionnaire_signaux();
2246:
2247: BUG(1, printf("[%d] SIGPIPE\n", (int) getpid()));
2248: return;
2249: }
2250:
2251: void
2252: interruption8(SIGHANDLER_ARGS)
2253: {
2254: pid_t pid;
2255:
2256: pthread_t thread;
2257:
2258: struct_processus *s_etat_processus;
2259:
2260: verrouillage_gestionnaire_signaux();
2261:
2262: # ifdef _BROKEN_SIGINFO
2263: pid = origine_signal(signal);
2264: # else
2265: pid = (*siginfo).si_pid;
2266: # endif
2267:
2268: if (pid == getpid())
2269: {
2270: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2271: == NULL)
2272: {
2273: deverrouillage_gestionnaire_signaux();
2274: return;
2275: }
2276:
2277: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2278: {
2279: printf("[%d] SIGURG (thread %llu)\n", (int) getpid(),
2280: (unsigned long long) pthread_self());
2281: fflush(stdout);
2282: }
2283:
2284: (*s_etat_processus).var_volatile_alarme = -1;
2285: (*s_etat_processus).var_volatile_requete_arret = -1;
2286: }
2287: else
2288: {
2289: // Envoi d'un signal au thread maître du groupe.
2290:
2291: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2292: {
2293: pthread_kill(thread, SIGURG);
2294: deverrouillage_gestionnaire_signaux();
2295: return;
2296: }
2297: }
2298:
2299: deverrouillage_gestionnaire_signaux();
2300: return;
2301: }
2302:
2303: void
2304: interruption9(SIGHANDLER_ARGS)
2305: {
2306: pid_t pid;
2307:
2308: struct_processus *s_etat_processus;
2309:
2310: verrouillage_gestionnaire_signaux();
2311:
2312: # ifdef _BROKEN_SIGINFO
2313: pid = origine_signal(signal);
2314: # else
2315: pid = (*siginfo).si_pid;
2316: # endif
2317:
2318: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2319: {
2320: deverrouillage_gestionnaire_signaux();
2321: return;
2322: }
2323:
2324: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2325: {
2326: printf("[%d] SIGABORT/SIGPROF (thread %llu)\n", (int) getpid(),
2327: (unsigned long long) pthread_self());
2328: fflush(stdout);
2329: }
2330:
2331: # ifdef _BROKEN_SIGINFO
2332: if (queue_in(getpid(), signal) != 0)
2333: {
2334: return;
2335: }
2336:
2337: deverrouillage_gestionnaire_signaux();
2338: interruption11(signal);
2339: # else
2340: deverrouillage_gestionnaire_signaux();
2341: interruption11(signal, siginfo, context);
2342: # endif
2343: return;
2344: }
2345:
2346: void
2347: interruption10(SIGHANDLER_ARGS)
2348: {
2349: file *fichier;
2350:
2351: pid_t pid;
2352:
2353: struct_processus *s_etat_processus;
2354:
2355: unsigned char nom[8 + 64 + 1];
2356:
2357: verrouillage_gestionnaire_signaux();
2358:
2359: # ifdef _BROKEN_SIGINFO
2360: pid = origine_signal(signal);
2361: # else
2362: pid = (*siginfo).si_pid;
2363: # endif
2364:
2365: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2366: {
2367: deverrouillage_gestionnaire_signaux();
2368: return;
2369: }
2370:
2371: snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
2372: (unsigned long) pthread_self());
2373:
2374: if ((fichier = fopen(nom, "w+")) != NULL)
2375: {
2376: fclose(fichier);
2377:
2378: freopen(nom, "w", stdout);
2379: freopen(nom, "w", stderr);
2380: }
2381:
2382: freopen("/dev/null", "r", stdin);
2383:
2384: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2385: {
2386: printf("[%d] SIGHUP (thread %llu)\n", (int) getpid(),
2387: (unsigned long long) pthread_self());
2388: fflush(stdout);
2389: }
2390:
2391: deverrouillage_gestionnaire_signaux();
2392: return;
2393: }
2394:
2395: void
2396: interruption11(SIGHANDLER_ARGS)
2397: {
2398: pid_t pid;
2399:
2400: pthread_t thread;
2401:
2402: struct_processus *s_etat_processus;
2403:
2404: verrouillage_gestionnaire_signaux();
2405:
2406: # ifdef _BROKEN_SIGINFO
2407: pid = origine_signal(signal);
2408: # else
2409: pid = (*siginfo).si_pid;
2410: # endif
2411:
2412: if (pid == getpid())
2413: {
2414: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2415: == NULL)
2416: {
2417: deverrouillage_gestionnaire_signaux();
2418: return;
2419: }
2420:
2421: (*s_etat_processus).arret_depuis_abort = -1;
2422:
2423: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2424: {
2425: printf("[%d] SIGFABORT (thread %llu)\n", (int) getpid(),
2426: (unsigned long long) pthread_self());
2427: fflush(stdout);
2428: }
2429:
2430: /*
2431: * var_globale_traitement_retarde_stop :
2432: * 0 -> traitement immédiat
2433: * 1 -> traitement retardé (aucun signal reçu)
2434: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2435: */
2436:
2437: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
2438: {
2439: (*s_etat_processus).var_volatile_requete_arret = -1;
2440: }
2441: else
2442: {
2443: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
2444: }
2445: }
2446: else
2447: {
2448: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2449: == NULL)
2450: {
2451: deverrouillage_gestionnaire_signaux();
2452: return;
2453: }
2454:
2455: (*s_etat_processus).arret_depuis_abort = -1;
2456:
2457: // Envoi d'un signal au thread maître du groupe.
2458:
2459: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2460: {
2461: pthread_kill(thread, signal);
2462: deverrouillage_gestionnaire_signaux();
2463: return;
2464: }
2465: }
2466:
2467: deverrouillage_gestionnaire_signaux();
2468: return;
2469: }
2470:
2471: void
2472: traitement_exceptions_gsl(const char *reason, const char *file,
2473: int line, int gsl_errno)
2474: {
2475: struct_processus *s_etat_processus;
2476:
2477: verrouillage_gestionnaire_signaux();
2478:
2479: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2480: {
2481: deverrouillage_gestionnaire_signaux();
2482: return;
2483: }
2484:
2485: (*s_etat_processus).var_volatile_exception_gsl = gsl_errno;
2486: deverrouillage_gestionnaire_signaux();
2487: return;
2488: }
2489:
2490: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>