File:
[local] /
rpl /
src /
interruptions.c
Revision
1.53:
download - view:
text,
annotated -
select for diffs -
revision graph
Tue Jun 21 15:26:35 2011 UTC (12 years, 10 months ago) by
bertrand
Branches:
MAIN
CVS tags:
HEAD
Correction d'une réinitialisation sauvage de la pile des variables par niveau
dans la copie de la structure de description du processus. Cela corrige
la fonction SPAWN qui échouait sur un segmentation fault car la pile des
variables par niveau était vide alors même que l'arbre des variables contenait
bien les variables. Passage à la prerelease 2.
1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.0.prerelease.2
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: free(s_etat_processus);
1322:
1323: s_etat_processus = candidat;
1324: }
1325:
1326: l_element_suivant = (*l_element_courant).suivant;
1327:
1328: free((struct_thread *) (*l_element_courant).donnee);
1329: free((struct_liste_chainee *) l_element_courant);
1330:
1331: l_element_courant = l_element_suivant;
1332: }
1333:
1334: liste_threads = NULL;
1335:
1336: l_element_courant = liste_threads_surveillance;
1337:
1338: while(l_element_courant != NULL)
1339: {
1340: s_argument_thread = (struct_descripteur_thread *)
1341: (*l_element_courant).donnee;
1342:
1343: if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
1344: != 0)
1345: {
1346: (*s_etat_processus).erreur_systeme = d_es_processus;
1347: sem_post(&semaphore_liste_threads);
1348: return;
1349: }
1350:
1351: (*s_argument_thread).nombre_references--;
1352:
1353: BUG((*s_argument_thread).nombre_references < 0,
1354: printf("(*s_argument_thread).nombre_references = %d\n",
1355: (int) (*s_argument_thread).nombre_references));
1356:
1357: if ((*s_argument_thread).nombre_references == 0)
1358: {
1359: close((*s_argument_thread).pipe_objets[0]);
1360: close((*s_argument_thread).pipe_acquittement[1]);
1361: close((*s_argument_thread).pipe_injections[1]);
1362: close((*s_argument_thread).pipe_nombre_injections[1]);
1363: close((*s_argument_thread).pipe_nombre_objets_attente[0]);
1364: close((*s_argument_thread).pipe_interruptions[0]);
1365: close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);
1366:
1367: if (pthread_mutex_unlock(&((*s_argument_thread)
1368: .mutex_nombre_references)) != 0)
1369: {
1370: (*s_etat_processus).erreur_systeme = d_es_processus;
1371: sem_post(&semaphore_liste_threads);
1372: return;
1373: }
1374:
1375: pthread_mutex_destroy(&((*s_argument_thread).mutex));
1376: pthread_mutex_destroy(&((*s_argument_thread)
1377: .mutex_nombre_references));
1378:
1379: if ((*s_argument_thread).processus_detache == d_faux)
1380: {
1381: if ((*s_argument_thread).destruction_objet == d_vrai)
1382: {
1383: liberation(s_etat_processus, (*s_argument_thread).argument);
1384: }
1385: }
1386:
1387: free(s_argument_thread);
1388: }
1389: else
1390: {
1391: if (pthread_mutex_unlock(&((*s_argument_thread)
1392: .mutex_nombre_references)) != 0)
1393: {
1394: (*s_etat_processus).erreur_systeme = d_es_processus;
1395: sem_post(&semaphore_liste_threads);
1396: return;
1397: }
1398: }
1399:
1400: l_element_suivant = (*l_element_courant).suivant;
1401: free((struct_liste_chainee *) l_element_courant);
1402: l_element_courant = l_element_suivant;
1403: }
1404:
1405: liste_threads_surveillance = NULL;
1406:
1407: # ifndef SEMAPHORES_NOMMES
1408: if (sem_post(&semaphore_liste_threads) != 0)
1409: # else
1410: if (sem_post(semaphore_liste_threads) != 0)
1411: # endif
1412: {
1413: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1414: (*s_etat_processus).erreur_systeme = d_es_processus;
1415: return;
1416: }
1417:
1418: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1419: sigpending(&set);
1420: return;
1421: }
1422:
1423: static struct_processus *
1424: recherche_thread(pid_t pid, pthread_t tid)
1425: {
1426: volatile struct_liste_chainee_volatile *l_element_courant;
1427:
1428: struct_processus *s_etat_processus;
1429:
1430: l_element_courant = liste_threads;
1431:
1432: while(l_element_courant != NULL)
1433: {
1434: if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee))
1435: .tid, tid) != 0) && ((*((struct_thread *)
1436: (*l_element_courant).donnee)).pid == pid))
1437: {
1438: break;
1439: }
1440:
1441: l_element_courant = (*l_element_courant).suivant;
1442: }
1443:
1444: if (l_element_courant == NULL)
1445: {
1446: /*
1447: * Le processus n'existe plus. On ne distribue aucun signal.
1448: */
1449:
1450: return(NULL);
1451: }
1452:
1453: s_etat_processus = (*((struct_thread *)
1454: (*l_element_courant).donnee)).s_etat_processus;
1455:
1456: return(s_etat_processus);
1457: }
1458:
1459: static logical1
1460: recherche_thread_principal(pid_t pid, pthread_t *thread)
1461: {
1462: volatile struct_liste_chainee_volatile *l_element_courant;
1463:
1464: l_element_courant = liste_threads;
1465:
1466: while(l_element_courant != NULL)
1467: {
1468: if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal
1469: == d_vrai) && ((*((struct_thread *)
1470: (*l_element_courant).donnee)).pid == pid))
1471: {
1472: break;
1473: }
1474:
1475: l_element_courant = (*l_element_courant).suivant;
1476: }
1477:
1478: if (l_element_courant == NULL)
1479: {
1480: /*
1481: * Le processus n'existe plus. On ne distribue aucun signal.
1482: */
1483:
1484: return(d_faux);
1485: }
1486:
1487: (*thread) = (*((struct_thread *) (*l_element_courant).donnee)).tid;
1488:
1489: return(d_vrai);
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: void
1721: interruption1(SIGHANDLER_ARGS)
1722: {
1723: pid_t pid;
1724:
1725: pthread_t thread;
1726:
1727: struct_processus *s_etat_processus;
1728:
1729: volatile sig_atomic_t exclusion = 0;
1730:
1731: verrouillage_gestionnaire_signaux();
1732:
1733: # ifdef _BROKEN_SIGINFO
1734: if ((signal == SIGINT) || (signal == SIGTERM))
1735: {
1736: // Si l'interruption provient du clavier, il n'y a pas eu d'appel
1737: // à queue_in().
1738:
1739: pid = getpid();
1740: }
1741: else
1742: {
1743: pid = origine_signal(signal);
1744: }
1745: # else
1746: if (siginfo != NULL)
1747: {
1748: pid = (*siginfo).si_pid;
1749: }
1750: else
1751: {
1752: pid = getpid();
1753: }
1754: # endif
1755:
1756: switch(signal)
1757: {
1758: case SIGALRM :
1759: {
1760: if (pid == getpid())
1761: {
1762: if ((s_etat_processus = recherche_thread(getpid(),
1763: pthread_self())) == NULL)
1764: {
1765: deverrouillage_gestionnaire_signaux();
1766: return;
1767: }
1768:
1769: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1770: {
1771: printf("[%d] SIGALRM (thread %llu)\n", (int) getpid(),
1772: (unsigned long long) pthread_self());
1773: fflush(stdout);
1774: }
1775:
1776: if ((*s_etat_processus).pid_processus_pere != getpid())
1777: {
1778: kill((*s_etat_processus).pid_processus_pere, signal);
1779: }
1780: else
1781: {
1782: (*s_etat_processus).var_volatile_alarme = -1;
1783: (*s_etat_processus).var_volatile_requete_arret = -1;
1784: }
1785: }
1786: else
1787: {
1788: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1789: {
1790: pthread_kill(thread, signal);
1791: }
1792: }
1793:
1794: break;
1795: }
1796:
1797: case SIGINT :
1798: case SIGTERM :
1799: {
1800: /*
1801: * Une vieille spécification POSIX permet au pointeur siginfo
1802: * d'être nul dans le cas d'un ^C envoyé depuis le clavier.
1803: * Solaris suit en particulier cette spécification.
1804: */
1805:
1806: # ifndef _BROKEN_SIGINFO
1807: if (siginfo == NULL)
1808: {
1809: kill(getpid(), signal);
1810: }
1811: else
1812: # endif
1813: if (pid == getpid())
1814: {
1815: if ((s_etat_processus = recherche_thread(getpid(),
1816: pthread_self())) == NULL)
1817: {
1818: deverrouillage_gestionnaire_signaux();
1819: return;
1820: }
1821:
1822: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1823: {
1824: if (signal == SIGINT)
1825: {
1826: printf("[%d] SIGINT (thread %llu)\n", (int) getpid(),
1827: (unsigned long long) pthread_self());
1828: }
1829: else
1830: {
1831: printf("[%d] SIGTERM (thread %llu)\n", (int) getpid(),
1832: (unsigned long long) pthread_self());
1833: }
1834:
1835: fflush(stdout);
1836: }
1837:
1838: if ((*s_etat_processus).pid_processus_pere != getpid())
1839: {
1840: kill((*s_etat_processus).pid_processus_pere, signal);
1841: }
1842: else
1843: {
1844: (*s_etat_processus).var_volatile_traitement_sigint = -1;
1845:
1846: while(exclusion == 1);
1847: exclusion = 1;
1848:
1849: if ((*s_etat_processus).var_volatile_requete_arret == -1)
1850: {
1851: deverrouillage_gestionnaire_signaux();
1852: exclusion = 0;
1853: return;
1854: }
1855:
1856: if (signal == SIGINT)
1857: {
1858: if (strncmp(getenv("LANG"), "fr", 2) == 0)
1859: {
1860: printf("+++Interruption\n");
1861: }
1862: else
1863: {
1864: printf("+++Interrupt\n");
1865: }
1866:
1867: fflush(stdout);
1868: }
1869:
1870: (*s_etat_processus).var_volatile_requete_arret = -1;
1871: (*s_etat_processus).var_volatile_alarme = -1;
1872:
1873: exclusion = 0;
1874: }
1875: }
1876: else
1877: {
1878: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1879: {
1880: pthread_kill(thread, signal);
1881: }
1882: }
1883:
1884: break;
1885: }
1886:
1887: default :
1888: {
1889: BUG(1, uprintf("[%d] Unknown signal %d in this context\n",
1890: (int) getpid(), signal));
1891: break;
1892: }
1893: }
1894:
1895: deverrouillage_gestionnaire_signaux();
1896: return;
1897: }
1898:
1899: void
1900: interruption2(SIGHANDLER_ARGS)
1901: {
1902: pid_t pid;
1903:
1904: pthread_t thread;
1905:
1906: struct_processus *s_etat_processus;
1907:
1908: verrouillage_gestionnaire_signaux();
1909:
1910: # ifdef _BROKEN_SIGINFO
1911: pid = origine_signal(signal);
1912: # else
1913: if (siginfo != NULL)
1914: {
1915: pid = (*siginfo).si_pid;
1916: }
1917: else
1918: {
1919: pid = getpid();
1920: }
1921: # endif
1922:
1923: # ifndef _BROKEN_SIGINFO
1924: if (siginfo == NULL)
1925: {
1926: /*
1927: * Le signal SIGFSTP provient de la mort du processus de contrôle.
1928: * Sous certains systèmes (Linux...), la mort du terminal de contrôle
1929: * se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
1930: * (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
1931: * non initialisée (pointeur NULL) issue de TERMIO.
1932: */
1933:
1934: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1935: {
1936: pthread_kill(thread, SIGHUP);
1937: deverrouillage_gestionnaire_signaux();
1938: return;
1939: }
1940: }
1941: else
1942: # endif
1943: if (pid == getpid())
1944: {
1945: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
1946: == NULL)
1947: {
1948: deverrouillage_gestionnaire_signaux();
1949: return;
1950: }
1951:
1952: /*
1953: * 0 => fonctionnement normal
1954: * -1 => requête
1955: * 1 => requête acceptée en attente de traitement
1956: */
1957:
1958: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1959: {
1960: printf("[%d] SIGTSTP (thread %llu)\n", (int) getpid(),
1961: (unsigned long long) pthread_self());
1962: fflush(stdout);
1963: }
1964:
1965: if ((*s_etat_processus).var_volatile_processus_pere == 0)
1966: {
1967: kill((*s_etat_processus).pid_processus_pere, signal);
1968: }
1969: else
1970: {
1971: (*s_etat_processus).var_volatile_requete_arret2 = -1;
1972: }
1973: }
1974: else
1975: {
1976: // Envoi d'un signal au thread maître du groupe.
1977:
1978: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1979: {
1980: pthread_kill(thread, SIGTSTP);
1981: deverrouillage_gestionnaire_signaux();
1982: return;
1983: }
1984: }
1985:
1986: deverrouillage_gestionnaire_signaux();
1987: return;
1988: }
1989:
1990: void
1991: interruption3(SIGHANDLER_ARGS)
1992: {
1993: pid_t pid;
1994:
1995: struct_processus *s_etat_processus;
1996:
1997: static int compteur = 0;
1998:
1999: verrouillage_gestionnaire_signaux();
2000:
2001: # ifdef _BROKEN_SIGINFO
2002: pid = origine_signal(signal);
2003: # else
2004: pid = (*siginfo).si_pid;
2005: # endif
2006:
2007: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2008: {
2009: deverrouillage_gestionnaire_signaux();
2010: return;
2011: }
2012:
2013: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2014: {
2015: printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),
2016: (unsigned long long) pthread_self());
2017: fflush(stdout);
2018: }
2019:
2020: if ((*s_etat_processus).var_volatile_recursivite == -1)
2021: {
2022: // Segfault dans un appel de fonction récursive
2023: deverrouillage_gestionnaire_signaux();
2024: longjmp(contexte, -1);
2025: }
2026: else
2027: {
2028: // Segfault dans une routine interne
2029: if (strncmp(getenv("LANG"), "fr", 2) == 0)
2030: {
2031: printf("+++Système : Violation d'accès (dépassement de pile)\n");
2032: }
2033: else
2034: {
2035: printf("+++System : Access violation (stack overflow)\n");
2036: }
2037:
2038: fflush(stdout);
2039:
2040: compteur++;
2041:
2042: if (compteur > 1)
2043: {
2044: deverrouillage_gestionnaire_signaux();
2045: exit(EXIT_FAILURE);
2046: }
2047: else
2048: {
2049: deverrouillage_gestionnaire_signaux();
2050: longjmp(contexte_initial, -1);
2051: }
2052: }
2053:
2054: deverrouillage_gestionnaire_signaux();
2055: return;
2056: }
2057:
2058: void
2059: interruption4(SIGHANDLER_ARGS)
2060: {
2061: pid_t pid;
2062:
2063: struct_processus *s_etat_processus;
2064:
2065: verrouillage_gestionnaire_signaux();
2066:
2067: # ifdef _BROKEN_SIGINFO
2068: pid = origine_signal(signal);
2069: # else
2070: pid = (*siginfo).si_pid;
2071: # endif
2072:
2073: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2074: {
2075: deverrouillage_gestionnaire_signaux();
2076: return;
2077: }
2078:
2079: /*
2080: * Démarrage d'un processus fils ou gestion de SIGCONT (SUSPEND)
2081: */
2082:
2083: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2084: {
2085: printf("[%d] SIGSTART/SIGCONT (thread %llu)\n", (int) getpid(),
2086: (unsigned long long) pthread_self());
2087: fflush(stdout);
2088: }
2089:
2090: deverrouillage_gestionnaire_signaux();
2091: return;
2092: }
2093:
2094: void
2095: interruption5(SIGHANDLER_ARGS)
2096: {
2097: pid_t pid;
2098:
2099: pthread_t thread;
2100:
2101: struct_processus *s_etat_processus;
2102:
2103: verrouillage_gestionnaire_signaux();
2104:
2105: # ifdef _BROKEN_SIGINFO
2106: pid = origine_signal(signal);
2107: # else
2108: pid = (*siginfo).si_pid;
2109: # endif
2110:
2111: if (pid == getpid())
2112: {
2113: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2114: == NULL)
2115: {
2116: deverrouillage_gestionnaire_signaux();
2117: return;
2118: }
2119:
2120: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2121: {
2122: printf("[%d] SIGFSTOP (thread %llu)\n", (int) getpid(),
2123: (unsigned long long) pthread_self());
2124: fflush(stdout);
2125: }
2126:
2127: /*
2128: * var_globale_traitement_retarde_stop :
2129: * 0 -> traitement immédiat
2130: * 1 -> traitement retardé (aucun signal reçu)
2131: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2132: */
2133:
2134: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
2135: {
2136: (*s_etat_processus).var_volatile_requete_arret = -1;
2137: }
2138: else
2139: {
2140: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
2141: }
2142: }
2143: else
2144: {
2145: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2146: == NULL)
2147: {
2148: deverrouillage_gestionnaire_signaux();
2149: return;
2150: }
2151:
2152: // Envoi d'un signal au thread maître du groupe.
2153:
2154: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2155: {
2156: pthread_kill(thread, signal);
2157: deverrouillage_gestionnaire_signaux();
2158: return;
2159: }
2160: }
2161:
2162: deverrouillage_gestionnaire_signaux();
2163: return;
2164: }
2165:
2166: void
2167: interruption6(SIGHANDLER_ARGS)
2168: {
2169: pid_t pid;
2170:
2171: struct_processus *s_etat_processus;
2172:
2173: verrouillage_gestionnaire_signaux();
2174:
2175: # ifdef _BROKEN_SIGINFO
2176: pid = origine_signal(signal);
2177: # else
2178: pid = (*siginfo).si_pid;
2179: # endif
2180:
2181: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2182: {
2183: deverrouillage_gestionnaire_signaux();
2184: return;
2185: }
2186:
2187: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2188: {
2189: printf("[%d] SIGINJECT/SIGQUIT (thread %llu)\n", (int) getpid(),
2190: (unsigned long long) pthread_self());
2191: fflush(stdout);
2192: }
2193:
2194: deverrouillage_gestionnaire_signaux();
2195: return;
2196: }
2197:
2198: void
2199: interruption7(SIGHANDLER_ARGS)
2200: {
2201: pid_t pid;
2202:
2203: struct_processus *s_etat_processus;
2204:
2205: verrouillage_gestionnaire_signaux();
2206:
2207: # ifdef _BROKEN_SIGINFO
2208: pid = origine_signal(signal);
2209: # else
2210: pid = (*siginfo).si_pid;
2211: # endif
2212:
2213: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2214: {
2215: deverrouillage_gestionnaire_signaux();
2216: return;
2217: }
2218:
2219: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2220: {
2221: printf("[%d] SIGPIPE (thread %llu)\n", (int) getpid(),
2222: (unsigned long long) pthread_self());
2223: fflush(stdout);
2224: }
2225:
2226: (*s_etat_processus).var_volatile_requete_arret = -1;
2227: deverrouillage_gestionnaire_signaux();
2228:
2229: BUG(1, printf("[%d] SIGPIPE\n", (int) getpid()));
2230: return;
2231: }
2232:
2233: void
2234: interruption8(SIGHANDLER_ARGS)
2235: {
2236: pid_t pid;
2237:
2238: pthread_t thread;
2239:
2240: struct_processus *s_etat_processus;
2241:
2242: verrouillage_gestionnaire_signaux();
2243:
2244: # ifdef _BROKEN_SIGINFO
2245: pid = origine_signal(signal);
2246: # else
2247: pid = (*siginfo).si_pid;
2248: # endif
2249:
2250: if (pid == getpid())
2251: {
2252: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2253: == NULL)
2254: {
2255: deverrouillage_gestionnaire_signaux();
2256: return;
2257: }
2258:
2259: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2260: {
2261: printf("[%d] SIGURG (thread %llu)\n", (int) getpid(),
2262: (unsigned long long) pthread_self());
2263: fflush(stdout);
2264: }
2265:
2266: (*s_etat_processus).var_volatile_alarme = -1;
2267: (*s_etat_processus).var_volatile_requete_arret = -1;
2268: }
2269: else
2270: {
2271: // Envoi d'un signal au thread maître du groupe.
2272:
2273: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2274: {
2275: pthread_kill(thread, SIGURG);
2276: deverrouillage_gestionnaire_signaux();
2277: return;
2278: }
2279: }
2280:
2281: deverrouillage_gestionnaire_signaux();
2282: return;
2283: }
2284:
2285: void
2286: interruption9(SIGHANDLER_ARGS)
2287: {
2288: pid_t pid;
2289:
2290: struct_processus *s_etat_processus;
2291:
2292: verrouillage_gestionnaire_signaux();
2293:
2294: # ifdef _BROKEN_SIGINFO
2295: pid = origine_signal(signal);
2296: # else
2297: pid = (*siginfo).si_pid;
2298: # endif
2299:
2300: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2301: {
2302: deverrouillage_gestionnaire_signaux();
2303: return;
2304: }
2305:
2306: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2307: {
2308: printf("[%d] SIGABORT/SIGPROF (thread %llu)\n", (int) getpid(),
2309: (unsigned long long) pthread_self());
2310: fflush(stdout);
2311: }
2312:
2313: # ifdef _BROKEN_SIGINFO
2314: if (queue_in(getpid(), signal) != 0)
2315: {
2316: return;
2317: }
2318:
2319: deverrouillage_gestionnaire_signaux();
2320: interruption11(signal);
2321: # else
2322: deverrouillage_gestionnaire_signaux();
2323: interruption11(signal, siginfo, context);
2324: # endif
2325: return;
2326: }
2327:
2328: void
2329: interruption10(SIGHANDLER_ARGS)
2330: {
2331: file *fichier;
2332:
2333: pid_t pid;
2334:
2335: struct_processus *s_etat_processus;
2336:
2337: unsigned char nom[8 + 64 + 1];
2338:
2339: verrouillage_gestionnaire_signaux();
2340:
2341: # ifdef _BROKEN_SIGINFO
2342: pid = origine_signal(signal);
2343: # else
2344: pid = (*siginfo).si_pid;
2345: # endif
2346:
2347: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2348: {
2349: deverrouillage_gestionnaire_signaux();
2350: return;
2351: }
2352:
2353: snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
2354: (unsigned long) pthread_self());
2355:
2356: if ((fichier = fopen(nom, "w+")) != NULL)
2357: {
2358: fclose(fichier);
2359:
2360: freopen(nom, "w", stdout);
2361: freopen(nom, "w", stderr);
2362: }
2363:
2364: freopen("/dev/null", "r", stdin);
2365:
2366: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2367: {
2368: printf("[%d] SIGHUP (thread %llu)\n", (int) getpid(),
2369: (unsigned long long) pthread_self());
2370: fflush(stdout);
2371: }
2372:
2373: deverrouillage_gestionnaire_signaux();
2374: return;
2375: }
2376:
2377: void
2378: interruption11(SIGHANDLER_ARGS)
2379: {
2380: pid_t pid;
2381:
2382: pthread_t thread;
2383:
2384: struct_processus *s_etat_processus;
2385:
2386: verrouillage_gestionnaire_signaux();
2387:
2388: # ifdef _BROKEN_SIGINFO
2389: pid = origine_signal(signal);
2390: # else
2391: pid = (*siginfo).si_pid;
2392: # endif
2393:
2394: if (pid == getpid())
2395: {
2396: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2397: == NULL)
2398: {
2399: deverrouillage_gestionnaire_signaux();
2400: return;
2401: }
2402:
2403: (*s_etat_processus).arret_depuis_abort = -1;
2404:
2405: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2406: {
2407: printf("[%d] SIGFABORT (thread %llu)\n", (int) getpid(),
2408: (unsigned long long) pthread_self());
2409: fflush(stdout);
2410: }
2411:
2412: /*
2413: * var_globale_traitement_retarde_stop :
2414: * 0 -> traitement immédiat
2415: * 1 -> traitement retardé (aucun signal reçu)
2416: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2417: */
2418:
2419: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
2420: {
2421: (*s_etat_processus).var_volatile_requete_arret = -1;
2422: }
2423: else
2424: {
2425: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
2426: }
2427: }
2428: else
2429: {
2430: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2431: == NULL)
2432: {
2433: deverrouillage_gestionnaire_signaux();
2434: return;
2435: }
2436:
2437: (*s_etat_processus).arret_depuis_abort = -1;
2438:
2439: // Envoi d'un signal au thread maître du groupe.
2440:
2441: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2442: {
2443: pthread_kill(thread, signal);
2444: deverrouillage_gestionnaire_signaux();
2445: return;
2446: }
2447: }
2448:
2449: deverrouillage_gestionnaire_signaux();
2450: return;
2451: }
2452:
2453: void
2454: traitement_exceptions_gsl(const char *reason, const char *file,
2455: int line, int gsl_errno)
2456: {
2457: struct_processus *s_etat_processus;
2458:
2459: verrouillage_gestionnaire_signaux();
2460:
2461: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2462: {
2463: deverrouillage_gestionnaire_signaux();
2464: return;
2465: }
2466:
2467: (*s_etat_processus).var_volatile_exception_gsl = gsl_errno;
2468: deverrouillage_gestionnaire_signaux();
2469: return;
2470: }
2471:
2472: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>