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