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