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