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