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_systeme;
990: while(element_courant != NULL)
991: {
992: element_suivant = (*((struct_liste_pile_systeme *)
993: element_courant)).suivant;
994:
995: if ((*((struct_liste_pile_systeme *)
996: element_courant)).indice_boucle != NULL)
997: {
998: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
999: element_courant)).indice_boucle).mutex));
1000: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
1001: element_courant)).indice_boucle).mutex));
1002: }
1003:
1004: liberation(s_etat_processus,
1005: (*((struct_liste_pile_systeme *)
1006: element_courant)).indice_boucle);
1007:
1008: if ((*((struct_liste_pile_systeme *)
1009: element_courant)).limite_indice_boucle != NULL)
1010: {
1011: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
1012: element_courant)).limite_indice_boucle).mutex));
1013: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
1014: element_courant)).limite_indice_boucle).mutex));
1015: }
1016:
1017: liberation(s_etat_processus,
1018: (*((struct_liste_pile_systeme *)
1019: element_courant)).limite_indice_boucle);
1020:
1021: if ((*((struct_liste_pile_systeme *)
1022: element_courant)).objet_de_test != NULL)
1023: {
1024: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
1025: element_courant)).objet_de_test).mutex));
1026: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
1027: element_courant)).objet_de_test).mutex));
1028: }
1029:
1030: liberation(s_etat_processus,
1031: (*((struct_liste_pile_systeme *)
1032: element_courant)).objet_de_test);
1033:
1034: if ((*((struct_liste_pile_systeme *)
1035: element_courant)).nom_variable != NULL)
1036: {
1037: free((*((struct_liste_pile_systeme *)
1038: element_courant)).nom_variable);
1039: }
1040:
1041: free(element_courant);
1042:
1043: element_courant = element_suivant;
1044: }
1045:
1046: element_courant = (*s_etat_processus).s_fichiers;
1047: while(element_courant != NULL)
1048: {
1049: element_suivant = (*((struct_liste_chainee *)
1050: element_courant)).suivant;
1051:
1052: element_candidat = (*candidat).s_fichiers;
1053: while(element_candidat != NULL)
1054: {
1055: if (((*((struct_descripteur_fichier *)
1056: (*((struct_liste_chainee *) element_courant))
1057: .donnee)).pid ==
1058: (*((struct_descripteur_fichier *)
1059: (*((struct_liste_chainee *) element_candidat))
1060: .donnee)).pid) && (pthread_equal(
1061: (*((struct_descripteur_fichier *)
1062: (*((struct_liste_chainee *) element_courant))
1063: .donnee)).tid, (*((struct_descripteur_fichier *)
1064: (*((struct_liste_chainee *) element_candidat))
1065: .donnee)).tid) != 0))
1066: {
1067: if ((*((struct_descripteur_fichier *)
1068: (*((struct_liste_chainee *) element_courant))
1069: .donnee)).type ==
1070: (*((struct_descripteur_fichier *)
1071: (*((struct_liste_chainee *) element_candidat))
1072: .donnee)).type)
1073: {
1074: if ((*((struct_descripteur_fichier *)
1075: (*((struct_liste_chainee *)
1076: element_candidat)).donnee)).type == 'C')
1077: {
1078: if ((*((struct_descripteur_fichier *)
1079: (*((struct_liste_chainee *)
1080: element_courant)).donnee))
1081: .descripteur_c ==
1082: (*((struct_descripteur_fichier *)
1083: (*((struct_liste_chainee *)
1084: element_candidat)).donnee))
1085: .descripteur_c)
1086: {
1087: break;
1088: }
1089: }
1090: else
1091: {
1092: if (((*((struct_descripteur_fichier *)
1093: (*((struct_liste_chainee *)
1094: element_courant)).donnee))
1095: .descripteur_sqlite ==
1096: (*((struct_descripteur_fichier *)
1097: (*((struct_liste_chainee *)
1098: element_candidat)).donnee))
1099: .descripteur_sqlite) &&
1100: ((*((struct_descripteur_fichier *)
1101: (*((struct_liste_chainee *)
1102: element_courant)).donnee))
1103: .descripteur_c ==
1104: (*((struct_descripteur_fichier *)
1105: (*((struct_liste_chainee *)
1106: element_candidat)).donnee))
1107: .descripteur_c))
1108: {
1109: break;
1110: }
1111: }
1112: }
1113: }
1114:
1115: element_candidat = (*((struct_liste_chainee *)
1116: element_candidat)).suivant;
1117: }
1118:
1119: if (element_candidat == NULL)
1120: {
1121: fclose((*((struct_descripteur_fichier *)
1122: (*((struct_liste_chainee *) element_courant))
1123: .donnee)).descripteur_c);
1124:
1125: if ((*((struct_descripteur_fichier *)
1126: (*((struct_liste_chainee *) element_courant))
1127: .donnee)).type != 'C')
1128: {
1129: sqlite3_close((*((struct_descripteur_fichier *)
1130: (*((struct_liste_chainee *) element_courant))
1131: .donnee)).descripteur_sqlite);
1132: }
1133: }
1134:
1135: free((*((struct_descripteur_fichier *)
1136: (*((struct_liste_chainee *)
1137: element_courant)).donnee)).nom);
1138: free((struct_descripteur_fichier *)
1139: (*((struct_liste_chainee *)
1140: element_courant)).donnee);
1141: free(element_courant);
1142:
1143: element_courant = element_suivant;
1144: }
1145:
1146: element_courant = (*s_etat_processus).s_sockets;
1147: while(element_courant != NULL)
1148: {
1149: element_suivant = (*((struct_liste_chainee *)
1150: element_courant)).suivant;
1151:
1152: element_candidat = (*candidat).s_sockets;
1153: while(element_candidat != NULL)
1154: {
1155: if (((*((struct_socket *)
1156: (*((struct_liste_chainee *) element_courant))
1157: .donnee)).socket == (*((struct_socket *)
1158: (*((struct_liste_chainee *) element_candidat))
1159: .donnee)).socket) &&
1160: ((*((struct_socket *)
1161: (*((struct_liste_chainee *) element_courant))
1162: .donnee)).pid == (*((struct_socket *)
1163: (*((struct_liste_chainee *) element_candidat))
1164: .donnee)).pid) && (pthread_equal(
1165: (*((struct_socket *)
1166: (*((struct_liste_chainee *) element_courant))
1167: .donnee)).tid, (*((struct_socket *)
1168: (*((struct_liste_chainee *) element_candidat))
1169: .donnee)).tid) != 0))
1170: {
1171: break;
1172: }
1173:
1174: element_candidat = (*((struct_liste_chainee *)
1175: element_candidat)).suivant;
1176: }
1177:
1178: if (element_candidat == NULL)
1179: {
1180: if ((*((struct_socket *) (*((struct_liste_chainee *)
1181: element_courant)).donnee)).socket_connectee
1182: == d_vrai)
1183: {
1184: shutdown((*((struct_socket *)
1185: (*((struct_liste_chainee *) element_courant))
1186: .donnee)).socket, SHUT_RDWR);
1187: }
1188:
1189: close((*((struct_socket *)
1190: (*((struct_liste_chainee *) element_courant))
1191: .donnee)).socket);
1192: }
1193:
1194: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1195: element_courant)).donnee).mutex));
1196: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1197: element_courant)).donnee).mutex));
1198:
1199: liberation(s_etat_processus,
1200: (*((struct_liste_chainee *)
1201: element_courant)).donnee);
1202: free(element_courant);
1203:
1204: element_courant = element_suivant;
1205: }
1206:
1207: /*
1208: ================================================================================
1209: À noter : on ne ferme pas la connexion car la conséquence immédiate est
1210: une destruction de l'objet pour le processus père.
1211: ================================================================================
1212:
1213: element_courant = (*s_etat_processus).s_connecteurs_sql;
1214: while(element_courant != NULL)
1215: {
1216: element_suivant = (*((struct_liste_chainee *)
1217: element_courant)).suivant;
1218:
1219: element_candidat = (*candidat).s_connecteurs_sql;
1220: while(element_candidat != NULL)
1221: {
1222: if (((
1223: #ifdef MYSQL_SUPPORT
1224: ((*((struct_connecteur_sql *)
1225: (*((struct_liste_chainee *) element_courant))
1226: .donnee)).descripteur.mysql ==
1227: (*((struct_connecteur_sql *)
1228: (*((struct_liste_chainee *) element_candidat))
1229: .donnee)).descripteur.mysql)
1230: &&
1231: (strcmp((*((struct_connecteur_sql *)
1232: (*((struct_liste_chainee *) element_courant))
1233: .donnee)).type, "MYSQL") == 0)
1234: &&
1235: (strcmp((*((struct_connecteur_sql *)
1236: (*((struct_liste_chainee *) element_candidat))
1237: .donnee)).type, "MYSQL") == 0)
1238: #else
1239: 0
1240: #endif
1241: ) || (
1242: #ifdef POSTGRESQL_SUPPORT
1243: ((*((struct_connecteur_sql *)
1244: (*((struct_liste_chainee *) element_courant))
1245: .donnee)).descripteur.postgresql ==
1246: (*((struct_connecteur_sql *)
1247: (*((struct_liste_chainee *) element_candidat))
1248: .donnee)).descripteur.postgresql)
1249: &&
1250: (strcmp((*((struct_connecteur_sql *)
1251: (*((struct_liste_chainee *) element_courant))
1252: .donnee)).type, "POSTGRESQL") == 0)
1253: &&
1254: (strcmp((*((struct_connecteur_sql *)
1255: (*((struct_liste_chainee *) element_candidat))
1256: .donnee)).type, "POSTGRESQL") == 0)
1257: #else
1258: 0
1259: #endif
1260: )) &&
1261: ((*((struct_connecteur_sql *)
1262: (*((struct_liste_chainee *) element_courant))
1263: .donnee)).pid == (*((struct_connecteur_sql *)
1264: (*((struct_liste_chainee *) element_candidat))
1265: .donnee)).pid) && (pthread_equal(
1266: (*((struct_connecteur_sql *)
1267: (*((struct_liste_chainee *) element_courant))
1268: .donnee)).tid, (*((struct_connecteur_sql *)
1269: (*((struct_liste_chainee *) element_candidat))
1270: .donnee)).tid) != 0))
1271: {
1272: break;
1273: }
1274:
1275: element_candidat = (*((struct_liste_chainee *)
1276: element_candidat)).suivant;
1277: }
1278:
1279: if (element_candidat == NULL)
1280: {
1281: sqlclose((*((struct_liste_chainee *) element_courant))
1282: .donnee);
1283: }
1284:
1285: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1286: element_courant)).donnee).mutex));
1287: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1288: element_courant)).donnee).mutex));
1289:
1290: liberation(s_etat_processus, (*((struct_liste_chainee *)
1291: element_courant)).donnee);
1292: free(element_courant);
1293:
1294: element_courant = element_suivant;
1295: }
1296: */
1297:
1298: (*s_etat_processus).s_connecteurs_sql = NULL;
1299:
1300: element_courant = (*s_etat_processus).s_marques;
1301: while(element_courant != NULL)
1302: {
1303: free((*((struct_marque *) element_courant)).label);
1304: free((*((struct_marque *) element_courant)).position);
1305: element_suivant = (*((struct_marque *) element_courant))
1306: .suivant;
1307: free(element_courant);
1308: element_courant = element_suivant;
1309: }
1310:
1311: liberation_allocateur(s_etat_processus);
1312:
1313: # ifndef SEMAPHORES_NOMMES
1314: sem_post(&((*s_etat_processus).semaphore_fork));
1315: sem_destroy(&((*s_etat_processus).semaphore_fork));
1316: # else
1317: sem_post((*s_etat_processus).semaphore_fork);
1318: sem_destroy2((*s_etat_processus).semaphore_fork, sem_fork);
1319: # endif
1320:
1321: liberation_contexte_cas(s_etat_processus);
1322: free(s_etat_processus);
1323:
1324: s_etat_processus = candidat;
1325: }
1326:
1327: l_element_suivant = (*l_element_courant).suivant;
1328:
1329: free((struct_thread *) (*l_element_courant).donnee);
1330: free((struct_liste_chainee *) l_element_courant);
1331:
1332: l_element_courant = l_element_suivant;
1333: }
1334:
1335: liste_threads = NULL;
1336:
1337: l_element_courant = liste_threads_surveillance;
1338:
1339: while(l_element_courant != NULL)
1340: {
1341: s_argument_thread = (struct_descripteur_thread *)
1342: (*l_element_courant).donnee;
1343:
1344: if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
1345: != 0)
1346: {
1347: (*s_etat_processus).erreur_systeme = d_es_processus;
1348: sem_post(&semaphore_liste_threads);
1349: return;
1350: }
1351:
1352: (*s_argument_thread).nombre_references--;
1353:
1354: BUG((*s_argument_thread).nombre_references < 0,
1355: printf("(*s_argument_thread).nombre_references = %d\n",
1356: (int) (*s_argument_thread).nombre_references));
1357:
1358: if ((*s_argument_thread).nombre_references == 0)
1359: {
1360: close((*s_argument_thread).pipe_objets[0]);
1361: close((*s_argument_thread).pipe_acquittement[1]);
1362: close((*s_argument_thread).pipe_injections[1]);
1363: close((*s_argument_thread).pipe_nombre_injections[1]);
1364: close((*s_argument_thread).pipe_nombre_objets_attente[0]);
1365: close((*s_argument_thread).pipe_interruptions[0]);
1366: close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);
1367:
1368: if (pthread_mutex_unlock(&((*s_argument_thread)
1369: .mutex_nombre_references)) != 0)
1370: {
1371: (*s_etat_processus).erreur_systeme = d_es_processus;
1372: sem_post(&semaphore_liste_threads);
1373: return;
1374: }
1375:
1376: pthread_mutex_destroy(&((*s_argument_thread).mutex));
1377: pthread_mutex_destroy(&((*s_argument_thread)
1378: .mutex_nombre_references));
1379:
1380: if ((*s_argument_thread).processus_detache == d_faux)
1381: {
1382: if ((*s_argument_thread).destruction_objet == d_vrai)
1383: {
1384: liberation(s_etat_processus, (*s_argument_thread).argument);
1385: }
1386: }
1387:
1388: free(s_argument_thread);
1389: }
1390: else
1391: {
1392: if (pthread_mutex_unlock(&((*s_argument_thread)
1393: .mutex_nombre_references)) != 0)
1394: {
1395: (*s_etat_processus).erreur_systeme = d_es_processus;
1396: sem_post(&semaphore_liste_threads);
1397: return;
1398: }
1399: }
1400:
1401: l_element_suivant = (*l_element_courant).suivant;
1402: free((struct_liste_chainee *) l_element_courant);
1403: l_element_courant = l_element_suivant;
1404: }
1405:
1406: liste_threads_surveillance = NULL;
1407:
1408: # ifndef SEMAPHORES_NOMMES
1409: if (sem_post(&semaphore_liste_threads) != 0)
1410: # else
1411: if (sem_post(semaphore_liste_threads) != 0)
1412: # endif
1413: {
1414: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1415: (*s_etat_processus).erreur_systeme = d_es_processus;
1416: return;
1417: }
1418:
1419: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1420: sigpending(&set);
1421: return;
1422: }
1423:
1424: static struct_processus *
1425: recherche_thread(pid_t pid, pthread_t tid)
1426: {
1427: volatile struct_liste_chainee_volatile *l_element_courant;
1428:
1429: struct_processus *s_etat_processus;
1430:
1431: l_element_courant = liste_threads;
1432:
1433: while(l_element_courant != NULL)
1434: {
1435: if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee))
1436: .tid, tid) != 0) && ((*((struct_thread *)
1437: (*l_element_courant).donnee)).pid == pid))
1438: {
1439: break;
1440: }
1441:
1442: l_element_courant = (*l_element_courant).suivant;
1443: }
1444:
1445: if (l_element_courant == NULL)
1446: {
1447: /*
1448: * Le processus n'existe plus. On ne distribue aucun signal.
1449: */
1450:
1451: return(NULL);
1452: }
1453:
1454: s_etat_processus = (*((struct_thread *)
1455: (*l_element_courant).donnee)).s_etat_processus;
1456:
1457: return(s_etat_processus);
1458: }
1459:
1460: static logical1
1461: recherche_thread_principal(pid_t pid, pthread_t *thread)
1462: {
1463: volatile struct_liste_chainee_volatile *l_element_courant;
1464:
1465: l_element_courant = liste_threads;
1466:
1467: while(l_element_courant != NULL)
1468: {
1469: if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal
1470: == d_vrai) && ((*((struct_thread *)
1471: (*l_element_courant).donnee)).pid == pid))
1472: {
1473: break;
1474: }
1475:
1476: l_element_courant = (*l_element_courant).suivant;
1477: }
1478:
1479: if (l_element_courant == NULL)
1480: {
1481: /*
1482: * Le processus n'existe plus. On ne distribue aucun signal.
1483: */
1484:
1485: return(d_faux);
1486: }
1487:
1488: (*thread) = (*((struct_thread *) (*l_element_courant).donnee)).tid;
1489:
1490: return(d_vrai);
1491: }
1492:
1493:
1494: /*
1495: ================================================================================
1496: Procédures de gestion des signaux d'interruption
1497: ================================================================================
1498: Entrée : variable globale
1499: --------------------------------------------------------------------------------
1500: Sortie : variable globale modifiée
1501: --------------------------------------------------------------------------------
1502: Effets de bord : néant
1503: ================================================================================
1504: */
1505:
1506: // Les routines suivantes sont uniquement appelées depuis les gestionnaires
1507: // des signaux asynchrones. Elles ne doivent pas bloquer dans le cas où
1508: // les sémaphores sont déjà bloqués par un gestionnaire de signal.
1509:
1510: static inline void
1511: verrouillage_gestionnaire_signaux()
1512: {
1513: int semaphore;
1514:
1515: sigset_t oldset;
1516: sigset_t set;
1517:
1518: sem_t *sem;
1519:
1520: if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
1521: != NULL)
1522: {
1523: if (sem_post(sem) != 0)
1524: {
1525: BUG(1, uprintf("Lock error !\n"));
1526: return;
1527: }
1528: }
1529:
1530: // Il faut respecteur l'atomicité des deux opérations suivantes !
1531:
1532: sigfillset(&set);
1533: pthread_sigmask(SIG_BLOCK, &set, &oldset);
1534:
1535: # ifndef SEMAPHORES_NOMMES
1536: while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
1537: # else
1538: while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)
1539: # endif
1540: {
1541: if (errno != EINTR)
1542: {
1543: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1544: BUG(1, uprintf("Unlock error !\n"));
1545: return;
1546: }
1547: }
1548:
1549: # ifndef SEMAPHORES_NOMMES
1550: if (sem_post(&semaphore_gestionnaires_signaux) == -1)
1551: # else
1552: if (sem_post(semaphore_gestionnaires_signaux) == -1)
1553: # endif
1554: {
1555: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1556: BUG(1, uprintf("Lock error !\n"));
1557: return;
1558: }
1559:
1560: # ifndef SEMAPHORES_NOMMES
1561: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1562: # else
1563: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1564: # endif
1565: {
1566: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1567: BUG(1, uprintf("Lock error !\n"));
1568: return;
1569: }
1570:
1571: # ifndef SEMAPHORES_NOMMES
1572: if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
1573: # else
1574: if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)
1575: # endif
1576: {
1577: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1578: BUG(1, uprintf("Unlock error !\n"));
1579: return;
1580: }
1581:
1582: if (semaphore == 1)
1583: {
1584: // Le semaphore ne peut être pris par le thread qui a appelé
1585: // le gestionnaire de signal car le signal est bloqué par ce thread
1586: // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que
1587: // par un thread concurrent. On essaye donc de le bloquer jusqu'à
1588: // ce que ce soit possible.
1589:
1590: # ifndef SEMAPHORES_NOMMES
1591: while(sem_wait(&semaphore_liste_threads) == -1)
1592: # else
1593: while(sem_wait(semaphore_liste_threads) == -1)
1594: # endif
1595: {
1596: if (errno != EINTR)
1597: {
1598: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1599:
1600: while(sem_wait(sem) == -1)
1601: {
1602: if (errno != EINTR)
1603: {
1604: BUG(1, uprintf("Lock error !\n"));
1605: return;
1606: }
1607: }
1608:
1609: BUG(1, uprintf("Lock error !\n"));
1610: return;
1611: }
1612: }
1613: }
1614:
1615: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1616: sigpending(&set);
1617:
1618: return;
1619: }
1620:
1621: static inline void
1622: deverrouillage_gestionnaire_signaux()
1623: {
1624: int semaphore;
1625:
1626: sem_t *sem;
1627:
1628: sigset_t oldset;
1629: sigset_t set;
1630:
1631: // Il faut respecteur l'atomicité des deux opérations suivantes !
1632:
1633: sigfillset(&set);
1634: pthread_sigmask(SIG_BLOCK, &set, &oldset);
1635:
1636: # ifndef SEMAPHORES_NOMMES
1637: while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
1638: # else
1639: while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)
1640: # endif
1641: {
1642: if (errno != EINTR)
1643: {
1644: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1645: BUG(1, uprintf("Unlock error !\n"));
1646: return;
1647: }
1648: }
1649:
1650: # ifndef SEMAPHORES_NOMMES
1651: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1652: # else
1653: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1654: # endif
1655: {
1656: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1657: BUG(1, uprintf("Unlock error !\n"));
1658: return;
1659: }
1660:
1661: # ifndef SEMAPHORES_NOMMES
1662: while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
1663: # else
1664: while(sem_wait(semaphore_gestionnaires_signaux) == -1)
1665: # endif
1666: {
1667: if (errno != EINTR)
1668: {
1669: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1670: BUG(1, uprintf("Unlock error !\n"));
1671: return;
1672: }
1673: }
1674:
1675: # ifndef SEMAPHORES_NOMMES
1676: if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
1677: # else
1678: if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)
1679: # endif
1680: {
1681: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1682: BUG(1, uprintf("Unlock error !\n"));
1683: return;
1684: }
1685:
1686: if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
1687: != NULL)
1688: {
1689: while(sem_wait(sem) == -1)
1690: {
1691: if (errno != EINTR)
1692: {
1693: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1694: BUG(1, uprintf("Unlock error !\n"));
1695: return;
1696: }
1697: }
1698: }
1699:
1700: if (semaphore == 1)
1701: {
1702: # ifndef SEMAPHORES_NOMMES
1703: if (sem_post(&semaphore_liste_threads) != 0)
1704: # else
1705: if (sem_post(semaphore_liste_threads) != 0)
1706: # endif
1707: {
1708: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1709:
1710: BUG(1, uprintf("Unlock error !\n"));
1711: return;
1712: }
1713: }
1714:
1715: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1716: sigpending(&set);
1717:
1718: return;
1719: }
1720:
1721: void
1722: interruption1(SIGHANDLER_ARGS)
1723: {
1724: pid_t pid;
1725:
1726: pthread_t thread;
1727:
1728: struct_processus *s_etat_processus;
1729:
1730: volatile sig_atomic_t exclusion = 0;
1731:
1732: verrouillage_gestionnaire_signaux();
1733:
1734: # ifdef _BROKEN_SIGINFO
1735: if ((signal == SIGINT) || (signal == SIGTERM))
1736: {
1737: // Si l'interruption provient du clavier, il n'y a pas eu d'appel
1738: // à queue_in().
1739:
1740: pid = getpid();
1741: }
1742: else
1743: {
1744: pid = origine_signal(signal);
1745: }
1746: # else
1747: if (siginfo != NULL)
1748: {
1749: pid = (*siginfo).si_pid;
1750: }
1751: else
1752: {
1753: pid = getpid();
1754: }
1755: # endif
1756:
1757: switch(signal)
1758: {
1759: case SIGALRM :
1760: {
1761: if (pid == getpid())
1762: {
1763: if ((s_etat_processus = recherche_thread(getpid(),
1764: pthread_self())) == NULL)
1765: {
1766: deverrouillage_gestionnaire_signaux();
1767: return;
1768: }
1769:
1770: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1771: {
1772: printf("[%d] SIGALRM (thread %llu)\n", (int) getpid(),
1773: (unsigned long long) pthread_self());
1774: fflush(stdout);
1775: }
1776:
1777: if ((*s_etat_processus).pid_processus_pere != getpid())
1778: {
1779: kill((*s_etat_processus).pid_processus_pere, signal);
1780: }
1781: else
1782: {
1783: (*s_etat_processus).var_volatile_alarme = -1;
1784: (*s_etat_processus).var_volatile_requete_arret = -1;
1785: }
1786: }
1787: else
1788: {
1789: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1790: {
1791: pthread_kill(thread, signal);
1792: }
1793: }
1794:
1795: break;
1796: }
1797:
1798: case SIGINT :
1799: case SIGTERM :
1800: {
1801: /*
1802: * Une vieille spécification POSIX permet au pointeur siginfo
1803: * d'être nul dans le cas d'un ^C envoyé depuis le clavier.
1804: * Solaris suit en particulier cette spécification.
1805: */
1806:
1807: # ifndef _BROKEN_SIGINFO
1808: if (siginfo == NULL)
1809: {
1810: kill(getpid(), signal);
1811: }
1812: else
1813: # endif
1814: if (pid == getpid())
1815: {
1816: if ((s_etat_processus = recherche_thread(getpid(),
1817: pthread_self())) == NULL)
1818: {
1819: deverrouillage_gestionnaire_signaux();
1820: return;
1821: }
1822:
1823: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1824: {
1825: if (signal == SIGINT)
1826: {
1827: printf("[%d] SIGINT (thread %llu)\n", (int) getpid(),
1828: (unsigned long long) pthread_self());
1829: }
1830: else
1831: {
1832: printf("[%d] SIGTERM (thread %llu)\n", (int) getpid(),
1833: (unsigned long long) pthread_self());
1834: }
1835:
1836: fflush(stdout);
1837: }
1838:
1839: if ((*s_etat_processus).pid_processus_pere != getpid())
1840: {
1841: kill((*s_etat_processus).pid_processus_pere, signal);
1842: }
1843: else
1844: {
1845: (*s_etat_processus).var_volatile_traitement_sigint = -1;
1846:
1847: while(exclusion == 1);
1848: exclusion = 1;
1849:
1850: if ((*s_etat_processus).var_volatile_requete_arret == -1)
1851: {
1852: deverrouillage_gestionnaire_signaux();
1853: exclusion = 0;
1854: return;
1855: }
1856:
1857: if (signal == SIGINT)
1858: {
1859: if (strncmp(getenv("LANG"), "fr", 2) == 0)
1860: {
1861: printf("+++Interruption\n");
1862: }
1863: else
1864: {
1865: printf("+++Interrupt\n");
1866: }
1867:
1868: fflush(stdout);
1869: }
1870:
1871: (*s_etat_processus).var_volatile_requete_arret = -1;
1872: (*s_etat_processus).var_volatile_alarme = -1;
1873:
1874: exclusion = 0;
1875: }
1876: }
1877: else
1878: {
1879: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1880: {
1881: pthread_kill(thread, signal);
1882: }
1883: }
1884:
1885: break;
1886: }
1887:
1888: default :
1889: {
1890: BUG(1, uprintf("[%d] Unknown signal %d in this context\n",
1891: (int) getpid(), signal));
1892: break;
1893: }
1894: }
1895:
1896: deverrouillage_gestionnaire_signaux();
1897: return;
1898: }
1899:
1900: void
1901: interruption2(SIGHANDLER_ARGS)
1902: {
1903: pid_t pid;
1904:
1905: pthread_t thread;
1906:
1907: struct_processus *s_etat_processus;
1908:
1909: verrouillage_gestionnaire_signaux();
1910:
1911: # ifdef _BROKEN_SIGINFO
1912: pid = origine_signal(signal);
1913: # else
1914: if (siginfo != NULL)
1915: {
1916: pid = (*siginfo).si_pid;
1917: }
1918: else
1919: {
1920: pid = getpid();
1921: }
1922: # endif
1923:
1924: # ifndef _BROKEN_SIGINFO
1925: if (siginfo == NULL)
1926: {
1927: /*
1928: * Le signal SIGFSTP provient de la mort du processus de contrôle.
1929: * Sous certains systèmes (Linux...), la mort du terminal de contrôle
1930: * se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
1931: * (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
1932: * non initialisée (pointeur NULL) issue de TERMIO.
1933: */
1934:
1935: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1936: {
1937: pthread_kill(thread, SIGHUP);
1938: deverrouillage_gestionnaire_signaux();
1939: return;
1940: }
1941: }
1942: else
1943: # endif
1944: if (pid == getpid())
1945: {
1946: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
1947: == NULL)
1948: {
1949: deverrouillage_gestionnaire_signaux();
1950: return;
1951: }
1952:
1953: /*
1954: * 0 => fonctionnement normal
1955: * -1 => requête
1956: * 1 => requête acceptée en attente de traitement
1957: */
1958:
1959: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1960: {
1961: printf("[%d] SIGTSTP (thread %llu)\n", (int) getpid(),
1962: (unsigned long long) pthread_self());
1963: fflush(stdout);
1964: }
1965:
1966: if ((*s_etat_processus).var_volatile_processus_pere == 0)
1967: {
1968: kill((*s_etat_processus).pid_processus_pere, signal);
1969: }
1970: else
1971: {
1972: (*s_etat_processus).var_volatile_requete_arret2 = -1;
1973: }
1974: }
1975: else
1976: {
1977: // Envoi d'un signal au thread maître du groupe.
1978:
1979: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1980: {
1981: pthread_kill(thread, SIGTSTP);
1982: deverrouillage_gestionnaire_signaux();
1983: return;
1984: }
1985: }
1986:
1987: deverrouillage_gestionnaire_signaux();
1988: return;
1989: }
1990:
1991: void
1992: interruption3(SIGHANDLER_ARGS)
1993: {
1994: pthread_t thread;
1995:
1996: struct_processus *s_etat_processus;
1997:
1998: verrouillage_gestionnaire_signaux();
1999:
2000: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2001: {
2002: deverrouillage_gestionnaire_signaux();
2003: return;
2004: }
2005:
2006: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2007: {
2008: printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),
2009: (unsigned long long) pthread_self());
2010: fflush(stdout);
2011: }
2012:
2013: if ((*s_etat_processus).var_volatile_recursivite == -1)
2014: {
2015: // Segfault dans un appel de fonction récursive
2016: deverrouillage_gestionnaire_signaux();
2017: longjmp(contexte, -1);
2018: }
2019: else
2020: {
2021: // Segfault dans une routine interne
2022: if (strncmp(getenv("LANG"), "fr", 2) == 0)
2023: {
2024: printf("+++Système : Violation d'accès\n");
2025: }
2026: else
2027: {
2028: printf("+++System : Access violation\n");
2029: }
2030:
2031: fflush(stdout);
2032:
2033: (*s_etat_processus).compteur_violation_d_acces++;
2034:
2035: if ((*s_etat_processus).compteur_violation_d_acces > 1)
2036: {
2037: // On vient de récupérer plus d'une erreur de segmentation
2038: // dans le même processus ou le même thread. L'erreur n'est pas
2039: // récupérable et on sort autoritairement du programme. Il peut
2040: // rester des processus orphelins en attente !
2041:
2042: if (strncmp(getenv("LANG"), "fr", 2) == 0)
2043: {
2044: printf("+++Système : Violation d'accès\n");
2045: }
2046: else
2047: {
2048: printf("+++System : Access violation\n");
2049: }
2050:
2051: fflush(stdout);
2052:
2053: deverrouillage_gestionnaire_signaux();
2054: exit(EXIT_FAILURE);
2055: }
2056: else
2057: {
2058: // Première erreur de segmentation. On essaie de terminer
2059: // proprement le thread ou le processus. Le signal ne peut être
2060: // envoyé que depuis le même processus.
2061:
2062: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2063: {
2064: if (pthread_equal(thread, pthread_self()) != 0)
2065: {
2066: deverrouillage_gestionnaire_signaux();
2067:
2068: if ((*s_etat_processus).pid_processus_pere != getpid())
2069: {
2070: // On est dans le thread principal d'un processus.
2071:
2072: longjmp(contexte_processus, -1);
2073: }
2074: else
2075: {
2076: // On est dans le thread principal du processus
2077: // père.
2078:
2079: longjmp(contexte_initial, -1);
2080: }
2081: }
2082: else
2083: {
2084: // On est dans un thread fils d'un thread principal.
2085:
2086: deverrouillage_gestionnaire_signaux();
2087: longjmp(contexte_thread, -1);
2088: }
2089: }
2090:
2091: // Là, on ramasse les miettes puisque le thread n'existe plus
2092: // dans la base (corruption de la mémoire).
2093:
2094: deverrouillage_gestionnaire_signaux();
2095: longjmp(contexte_initial, -1);
2096: }
2097: }
2098:
2099: deverrouillage_gestionnaire_signaux();
2100: return;
2101: }
2102:
2103: void
2104: interruption4(SIGHANDLER_ARGS)
2105: {
2106: struct_processus *s_etat_processus;
2107:
2108: verrouillage_gestionnaire_signaux();
2109:
2110: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2111: {
2112: deverrouillage_gestionnaire_signaux();
2113: return;
2114: }
2115:
2116: /*
2117: * Démarrage d'un processus fils ou gestion de SIGCONT (SUSPEND)
2118: */
2119:
2120: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2121: {
2122: printf("[%d] SIGSTART/SIGCONT (thread %llu)\n", (int) getpid(),
2123: (unsigned long long) pthread_self());
2124: fflush(stdout);
2125: }
2126:
2127: deverrouillage_gestionnaire_signaux();
2128: return;
2129: }
2130:
2131: void
2132: interruption5(SIGHANDLER_ARGS)
2133: {
2134: pid_t pid;
2135:
2136: pthread_t thread;
2137:
2138: struct_processus *s_etat_processus;
2139:
2140: verrouillage_gestionnaire_signaux();
2141:
2142: # ifdef _BROKEN_SIGINFO
2143: pid = origine_signal(signal);
2144: # else
2145: pid = (*siginfo).si_pid;
2146: # endif
2147:
2148: if (pid == getpid())
2149: {
2150: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2151: == NULL)
2152: {
2153: deverrouillage_gestionnaire_signaux();
2154: return;
2155: }
2156:
2157: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2158: {
2159: printf("[%d] SIGFSTOP (thread %llu)\n", (int) getpid(),
2160: (unsigned long long) pthread_self());
2161: fflush(stdout);
2162: }
2163:
2164: /*
2165: * var_globale_traitement_retarde_stop :
2166: * 0 -> traitement immédiat
2167: * 1 -> traitement retardé (aucun signal reçu)
2168: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2169: */
2170:
2171: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
2172: {
2173: (*s_etat_processus).var_volatile_requete_arret = -1;
2174: }
2175: else
2176: {
2177: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
2178: }
2179: }
2180: else
2181: {
2182: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2183: == NULL)
2184: {
2185: deverrouillage_gestionnaire_signaux();
2186: return;
2187: }
2188:
2189: // Envoi d'un signal au thread maître du groupe.
2190:
2191: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2192: {
2193: pthread_kill(thread, signal);
2194: deverrouillage_gestionnaire_signaux();
2195: return;
2196: }
2197: }
2198:
2199: deverrouillage_gestionnaire_signaux();
2200: return;
2201: }
2202:
2203: void
2204: interruption6(SIGHANDLER_ARGS)
2205: {
2206: struct_processus *s_etat_processus;
2207:
2208: verrouillage_gestionnaire_signaux();
2209:
2210: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2211: {
2212: deverrouillage_gestionnaire_signaux();
2213: return;
2214: }
2215:
2216: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2217: {
2218: printf("[%d] SIGINJECT/SIGQUIT (thread %llu)\n", (int) getpid(),
2219: (unsigned long long) pthread_self());
2220: fflush(stdout);
2221: }
2222:
2223: deverrouillage_gestionnaire_signaux();
2224: return;
2225: }
2226:
2227: void
2228: interruption7(SIGHANDLER_ARGS)
2229: {
2230: struct_processus *s_etat_processus;
2231:
2232: verrouillage_gestionnaire_signaux();
2233:
2234: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2235: {
2236: deverrouillage_gestionnaire_signaux();
2237: return;
2238: }
2239:
2240: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2241: {
2242: printf("[%d] SIGPIPE (thread %llu)\n", (int) getpid(),
2243: (unsigned long long) pthread_self());
2244: fflush(stdout);
2245: }
2246:
2247: (*s_etat_processus).var_volatile_requete_arret = -1;
2248: deverrouillage_gestionnaire_signaux();
2249:
2250: BUG(1, printf("[%d] SIGPIPE\n", (int) getpid()));
2251: return;
2252: }
2253:
2254: void
2255: interruption8(SIGHANDLER_ARGS)
2256: {
2257: pid_t pid;
2258:
2259: pthread_t thread;
2260:
2261: struct_processus *s_etat_processus;
2262:
2263: verrouillage_gestionnaire_signaux();
2264:
2265: # ifdef _BROKEN_SIGINFO
2266: pid = origine_signal(signal);
2267: # else
2268: pid = (*siginfo).si_pid;
2269: # endif
2270:
2271: if (pid == getpid())
2272: {
2273: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2274: == NULL)
2275: {
2276: deverrouillage_gestionnaire_signaux();
2277: return;
2278: }
2279:
2280: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2281: {
2282: printf("[%d] SIGURG (thread %llu)\n", (int) getpid(),
2283: (unsigned long long) pthread_self());
2284: fflush(stdout);
2285: }
2286:
2287: (*s_etat_processus).var_volatile_alarme = -1;
2288: (*s_etat_processus).var_volatile_requete_arret = -1;
2289: }
2290: else
2291: {
2292: // Envoi d'un signal au thread maître du groupe.
2293:
2294: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2295: {
2296: pthread_kill(thread, SIGURG);
2297: deverrouillage_gestionnaire_signaux();
2298: return;
2299: }
2300: }
2301:
2302: deverrouillage_gestionnaire_signaux();
2303: return;
2304: }
2305:
2306: void
2307: interruption9(SIGHANDLER_ARGS)
2308: {
2309: struct_processus *s_etat_processus;
2310:
2311: verrouillage_gestionnaire_signaux();
2312:
2313: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2314: {
2315: deverrouillage_gestionnaire_signaux();
2316: return;
2317: }
2318:
2319: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2320: {
2321: printf("[%d] SIGABORT/SIGPROF (thread %llu)\n", (int) getpid(),
2322: (unsigned long long) pthread_self());
2323: fflush(stdout);
2324: }
2325:
2326: # ifdef _BROKEN_SIGINFO
2327: if (queue_in(getpid(), signal) != 0)
2328: {
2329: return;
2330: }
2331:
2332: deverrouillage_gestionnaire_signaux();
2333: interruption11(signal);
2334: # else
2335: deverrouillage_gestionnaire_signaux();
2336: interruption11(signal, siginfo, context);
2337: # endif
2338: return;
2339: }
2340:
2341: void
2342: interruption10(SIGHANDLER_ARGS)
2343: {
2344: file *fichier;
2345:
2346: struct_processus *s_etat_processus;
2347:
2348: unsigned char nom[8 + 64 + 1];
2349:
2350: verrouillage_gestionnaire_signaux();
2351:
2352: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2353: {
2354: deverrouillage_gestionnaire_signaux();
2355: return;
2356: }
2357:
2358: snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
2359: (unsigned long) pthread_self());
2360:
2361: if ((fichier = fopen(nom, "w+")) != NULL)
2362: {
2363: fclose(fichier);
2364:
2365: freopen(nom, "w", stdout);
2366: freopen(nom, "w", stderr);
2367: }
2368:
2369: freopen("/dev/null", "r", stdin);
2370:
2371: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2372: {
2373: printf("[%d] SIGHUP (thread %llu)\n", (int) getpid(),
2374: (unsigned long long) pthread_self());
2375: fflush(stdout);
2376: }
2377:
2378: deverrouillage_gestionnaire_signaux();
2379: return;
2380: }
2381:
2382: void
2383: interruption11(SIGHANDLER_ARGS)
2384: {
2385: pid_t pid;
2386:
2387: pthread_t thread;
2388:
2389: struct_processus *s_etat_processus;
2390:
2391: verrouillage_gestionnaire_signaux();
2392:
2393: # ifdef _BROKEN_SIGINFO
2394: pid = origine_signal(signal);
2395: # else
2396: pid = (*siginfo).si_pid;
2397: # endif
2398:
2399: if (pid == getpid())
2400: {
2401: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2402: == NULL)
2403: {
2404: deverrouillage_gestionnaire_signaux();
2405: return;
2406: }
2407:
2408: (*s_etat_processus).arret_depuis_abort = -1;
2409:
2410: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2411: {
2412: printf("[%d] SIGFABORT (thread %llu)\n", (int) getpid(),
2413: (unsigned long long) pthread_self());
2414: fflush(stdout);
2415: }
2416:
2417: /*
2418: * var_globale_traitement_retarde_stop :
2419: * 0 -> traitement immédiat
2420: * 1 -> traitement retardé (aucun signal reçu)
2421: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2422: */
2423:
2424: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
2425: {
2426: (*s_etat_processus).var_volatile_requete_arret = -1;
2427: }
2428: else
2429: {
2430: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
2431: }
2432: }
2433: else
2434: {
2435: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2436: == NULL)
2437: {
2438: deverrouillage_gestionnaire_signaux();
2439: return;
2440: }
2441:
2442: (*s_etat_processus).arret_depuis_abort = -1;
2443:
2444: // Envoi d'un signal au thread maître du groupe.
2445:
2446: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2447: {
2448: pthread_kill(thread, signal);
2449: deverrouillage_gestionnaire_signaux();
2450: return;
2451: }
2452: }
2453:
2454: deverrouillage_gestionnaire_signaux();
2455: return;
2456: }
2457:
2458: void
2459: traitement_exceptions_gsl(const char *reason, const char *file,
2460: int line, int gsl_errno)
2461: {
2462: struct_processus *s_etat_processus;
2463:
2464: verrouillage_gestionnaire_signaux();
2465:
2466: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2467: {
2468: deverrouillage_gestionnaire_signaux();
2469: return;
2470: }
2471:
2472: (*s_etat_processus).var_volatile_exception_gsl = gsl_errno;
2473: deverrouillage_gestionnaire_signaux();
2474: return;
2475: }
2476:
2477: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>