Annotation of rpl/src/interruptions.c, revision 1.64
1.1 bertrand 1: /*
2: ================================================================================
1.60 bertrand 3: RPL/2 (R) version 4.1.3
1.45 bertrand 4: Copyright (C) 1989-2011 Dr. BERTRAND Joël
1.1 bertrand 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:
1.27 bertrand 23: #include "rpl-conv.h"
1.1 bertrand 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:
1.13 bertrand 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;
1.1 bertrand 128: liste_threads = l_nouvel_objet;
129:
1.8 bertrand 130: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 131: if (sem_post(&semaphore_liste_threads) != 0)
1.8 bertrand 132: # else
133: if (sem_post(semaphore_liste_threads) != 0)
134: # endif
1.1 bertrand 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:
1.13 bertrand 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:
1.8 bertrand 170: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 171: while(sem_wait(&semaphore_liste_threads) == -1)
1.8 bertrand 172: # else
173: while(sem_wait(semaphore_liste_threads) == -1)
174: # endif
1.1 bertrand 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:
1.40 bertrand 186: pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references));
1.21 bertrand 187: (*s_argument_thread).nombre_references++;
1.40 bertrand 188: pthread_mutex_unlock(&((*s_argument_thread).mutex_nombre_references));
1.22 bertrand 189:
1.1 bertrand 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:
1.8 bertrand 195: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 196: if (sem_post(&semaphore_liste_threads) != 0)
1.8 bertrand 197: # else
198: if (sem_post(semaphore_liste_threads) != 0)
199: # endif
1.1 bertrand 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:
1.8 bertrand 225: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 226: while(sem_wait(&semaphore_liste_threads) == -1)
1.8 bertrand 227: # else
228: while(sem_wait(semaphore_liste_threads) == -1)
229: # endif
1.1 bertrand 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: {
1.8 bertrand 259: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 260: sem_post(&semaphore_liste_threads);
1.8 bertrand 261: # else
262: sem_post(semaphore_liste_threads);
263: # endif
1.1 bertrand 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:
1.8 bertrand 284: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 285: sem_post(&semaphore_liste_threads);
1.8 bertrand 286: # else
287: sem_post(semaphore_liste_threads);
288: # endif
1.1 bertrand 289: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
290: sigpending(&set);
291: return;
292: }
293:
1.8 bertrand 294: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 295: if (sem_post(&semaphore_liste_threads) != 0)
1.8 bertrand 296: # else
297: if (sem_post(semaphore_liste_threads) != 0)
298: # endif
1.1 bertrand 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:
1.13 bertrand 307: free((void *) (*l_element_courant).donnee);
308: free((struct_liste_chainee_volatile *) l_element_courant);
309:
1.1 bertrand 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:
1.8 bertrand 328: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 329: while(sem_wait(&semaphore_liste_threads) == -1)
1.8 bertrand 330: # else
331: while(sem_wait(semaphore_liste_threads) == -1)
332: # endif
1.1 bertrand 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: {
1.8 bertrand 360: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 361: sem_post(&semaphore_liste_threads);
1.8 bertrand 362: # else
363: sem_post(semaphore_liste_threads);
364: # endif
1.1 bertrand 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:
1.40 bertrand 381: if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
382: != 0)
1.1 bertrand 383: {
1.12 bertrand 384: # ifndef SEMAPHORES_NOMMES
385: sem_post(&semaphore_liste_threads);
386: # else
387: sem_post(semaphore_liste_threads);
388: # endif
1.1 bertrand 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: {
1.40 bertrand 404: if (pthread_mutex_unlock(&((*s_argument_thread)
405: .mutex_nombre_references)) != 0)
1.1 bertrand 406: {
1.12 bertrand 407: # ifndef SEMAPHORES_NOMMES
408: sem_post(&semaphore_liste_threads);
409: # else
410: sem_post(semaphore_liste_threads);
411: # endif
1.1 bertrand 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));
1.40 bertrand 420: pthread_mutex_destroy(&((*s_argument_thread).mutex_nombre_references));
1.1 bertrand 421: free(s_argument_thread);
422: }
423: else
424: {
1.40 bertrand 425: if (pthread_mutex_unlock(&((*s_argument_thread)
426: .mutex_nombre_references)) != 0)
1.1 bertrand 427: {
1.12 bertrand 428: # ifndef SEMAPHORES_NOMMES
429: sem_post(&semaphore_liste_threads);
430: # else
431: sem_post(semaphore_liste_threads);
432: # endif
1.1 bertrand 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:
1.8 bertrand 441: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 442: if (sem_post(&semaphore_liste_threads) != 0)
1.8 bertrand 443: # else
444: if (sem_post(semaphore_liste_threads) != 0)
445: # endif
1.1 bertrand 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:
1.13 bertrand 454: free((struct_liste_chainee_volatile *) l_element_courant);
455:
1.1 bertrand 456: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
457: sigpending(&set);
1.20 bertrand 458:
1.1 bertrand 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:
1.8 bertrand 467: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 468: while(sem_wait(&semaphore_liste_threads) == -1)
1.8 bertrand 469: # else
470: while(sem_wait(semaphore_liste_threads) == -1)
471: # endif
1.1 bertrand 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: {
1.8 bertrand 488: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 489: while(sem_wait(&((*(*((struct_thread *) (*l_element_courant)
490: .donnee)).s_etat_processus).semaphore_fork)) == -1)
1.8 bertrand 491: # else
492: while(sem_wait((*(*((struct_thread *) (*l_element_courant)
493: .donnee)).s_etat_processus).semaphore_fork) == -1)
494: # endif
1.1 bertrand 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: {
1.8 bertrand 523: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 524: if (sem_post(&((*(*((struct_thread *)
525: (*l_element_courant).donnee)).s_etat_processus)
526: .semaphore_fork)) != 0)
1.8 bertrand 527: # else
528: if (sem_post((*(*((struct_thread *)
529: (*l_element_courant).donnee)).s_etat_processus)
530: .semaphore_fork) != 0)
531: # endif
1.1 bertrand 532: {
1.8 bertrand 533: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 534: if (sem_post(&semaphore_liste_threads) != 0)
535: {
536: (*s_etat_processus).erreur_systeme = d_es_processus;
537: return;
538: }
1.8 bertrand 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
1.1 bertrand 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:
1.8 bertrand 555: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 556: if (sem_post(&semaphore_liste_threads) != 0)
1.8 bertrand 557: # else
558: if (sem_post(semaphore_liste_threads) != 0)
559: # endif
1.1 bertrand 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:
1.8 bertrand 592: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 593: while(sem_wait(&semaphore_liste_threads) == -1)
1.8 bertrand 594: # else
595: while(sem_wait(semaphore_liste_threads) == -1)
596: # endif
1.1 bertrand 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:
1.13 bertrand 637: liberation(s_etat_processus, (*s_etat_processus).at_exit);
638:
1.1 bertrand 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: {
1.20 bertrand 680: s_argument_thread = (struct_descripteur_thread *)
681: (*((struct_liste_chainee *) element_courant)).donnee;
682:
1.40 bertrand 683: if (pthread_mutex_lock(&((*s_argument_thread)
684: .mutex_nombre_references)) != 0)
1.20 bertrand 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:
1.40 bertrand 708: if (pthread_mutex_unlock(&((*s_argument_thread)
709: .mutex_nombre_references)) != 0)
1.20 bertrand 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));
1.40 bertrand 717: pthread_mutex_destroy(&((*s_argument_thread)
718: .mutex_nombre_references));
1.20 bertrand 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: {
1.40 bertrand 733: if (pthread_mutex_unlock(&((*s_argument_thread)
734: .mutex_nombre_references)) != 0)
1.20 bertrand 735: {
736: (*s_etat_processus).erreur_systeme = d_es_processus;
737: sem_post(&semaphore_liste_threads);
738: return;
739: }
740: }
741:
1.1 bertrand 742: element_suivant = (*((struct_liste_chainee *) element_courant))
743: .suivant;
1.20 bertrand 744: free(element_courant);
1.1 bertrand 745: element_courant = element_suivant;
746: }
747:
1.20 bertrand 748: (*s_etat_processus).l_base_pile_processus = NULL;
749:
1.1 bertrand 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:
1.52 bertrand 806: liberation_arbre_variables(s_etat_processus,
807: (*s_etat_processus).s_arbre_variables, d_faux);
1.1 bertrand 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: {
1.5 bertrand 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: }
1.1 bertrand 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))
1.5 bertrand 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: }
1.1 bertrand 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:
1.14 bertrand 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:
1.1 bertrand 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: }
1.14 bertrand 1296: */
1.1 bertrand 1297:
1.15 bertrand 1298: (*s_etat_processus).s_connecteurs_sql = NULL;
1299:
1.1 bertrand 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:
1.8 bertrand 1313: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1314: sem_post(&((*s_etat_processus).semaphore_fork));
1315: sem_destroy(&((*s_etat_processus).semaphore_fork));
1.8 bertrand 1316: # else
1317: sem_post((*s_etat_processus).semaphore_fork);
1318: sem_destroy2((*s_etat_processus).semaphore_fork, sem_fork);
1319: # endif
1.1 bertrand 1320:
1.59 bertrand 1321: liberation_contexte_cas(s_etat_processus);
1.1 bertrand 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:
1.40 bertrand 1344: if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
1345: != 0)
1.1 bertrand 1346: {
1347: (*s_etat_processus).erreur_systeme = d_es_processus;
1.12 bertrand 1348: sem_post(&semaphore_liste_threads);
1.1 bertrand 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: {
1.20 bertrand 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:
1.40 bertrand 1368: if (pthread_mutex_unlock(&((*s_argument_thread)
1369: .mutex_nombre_references)) != 0)
1.1 bertrand 1370: {
1371: (*s_etat_processus).erreur_systeme = d_es_processus;
1.12 bertrand 1372: sem_post(&semaphore_liste_threads);
1.1 bertrand 1373: return;
1374: }
1375:
1376: pthread_mutex_destroy(&((*s_argument_thread).mutex));
1.40 bertrand 1377: pthread_mutex_destroy(&((*s_argument_thread)
1378: .mutex_nombre_references));
1.20 bertrand 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:
1.1 bertrand 1388: free(s_argument_thread);
1389: }
1390: else
1391: {
1.40 bertrand 1392: if (pthread_mutex_unlock(&((*s_argument_thread)
1393: .mutex_nombre_references)) != 0)
1.1 bertrand 1394: {
1395: (*s_etat_processus).erreur_systeme = d_es_processus;
1.12 bertrand 1396: sem_post(&semaphore_liste_threads);
1.1 bertrand 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:
1.8 bertrand 1408: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1409: if (sem_post(&semaphore_liste_threads) != 0)
1.8 bertrand 1410: # else
1411: if (sem_post(semaphore_liste_threads) != 0)
1412: # endif
1.1 bertrand 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 logical1
1461: recherche_thread_principal(pid_t pid, pthread_t *thread)
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(d_faux);
1486: }
1487:
1488: (*thread) = (*((struct_thread *) (*l_element_courant).donnee)).tid;
1489:
1490: return(d_vrai);
1491: }
1492:
1493:
1494: /*
1495: ================================================================================
1496: Procédures de gestion des signaux d'interruption
1497: ================================================================================
1498: Entrée : variable globale
1499: --------------------------------------------------------------------------------
1500: Sortie : variable globale modifiée
1501: --------------------------------------------------------------------------------
1502: Effets de bord : néant
1503: ================================================================================
1504: */
1505:
1506: // Les routines suivantes sont uniquement appelées depuis les gestionnaires
1.17 bertrand 1507: // des signaux asynchrones. Elles ne doivent pas bloquer dans le cas où
1.1 bertrand 1508: // les sémaphores sont déjà bloqués par un gestionnaire de signal.
1509:
1510: static inline void
1511: verrouillage_gestionnaire_signaux()
1512: {
1513: int semaphore;
1514:
1515: sigset_t oldset;
1516: sigset_t set;
1517:
1518: sem_t *sem;
1519:
1520: if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
1521: != NULL)
1522: {
1523: if (sem_post(sem) != 0)
1524: {
1525: BUG(1, uprintf("Lock error !\n"));
1526: return;
1527: }
1528: }
1529:
1530: // Il faut respecteur l'atomicité des deux opérations suivantes !
1531:
1532: sigfillset(&set);
1533: pthread_sigmask(SIG_BLOCK, &set, &oldset);
1534:
1.8 bertrand 1535: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1536: while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
1.8 bertrand 1537: # else
1538: while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)
1539: # endif
1.1 bertrand 1540: {
1541: if (errno != EINTR)
1542: {
1543: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1544: BUG(1, uprintf("Unlock error !\n"));
1545: return;
1546: }
1547: }
1548:
1.8 bertrand 1549: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1550: if (sem_post(&semaphore_gestionnaires_signaux) == -1)
1.8 bertrand 1551: # else
1552: if (sem_post(semaphore_gestionnaires_signaux) == -1)
1553: # endif
1.1 bertrand 1554: {
1555: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1556: BUG(1, uprintf("Lock error !\n"));
1557: return;
1558: }
1559:
1.8 bertrand 1560: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1561: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1.8 bertrand 1562: # else
1563: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1564: # endif
1.1 bertrand 1565: {
1566: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1567: BUG(1, uprintf("Lock error !\n"));
1568: return;
1569: }
1570:
1.8 bertrand 1571: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1572: if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
1.8 bertrand 1573: # else
1574: if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)
1575: # endif
1.1 bertrand 1576: {
1577: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1578: BUG(1, uprintf("Unlock error !\n"));
1579: return;
1580: }
1581:
1582: if (semaphore == 1)
1583: {
1584: // Le semaphore ne peut être pris par le thread qui a appelé
1585: // le gestionnaire de signal car le signal est bloqué par ce thread
1586: // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que
1587: // par un thread concurrent. On essaye donc de le bloquer jusqu'à
1588: // ce que ce soit possible.
1589:
1.8 bertrand 1590: # ifndef SEMAPHORES_NOMMES
1.41 bertrand 1591: while(sem_wait(&semaphore_liste_threads) == -1)
1.8 bertrand 1592: # else
1.41 bertrand 1593: while(sem_wait(semaphore_liste_threads) == -1)
1.8 bertrand 1594: # endif
1.1 bertrand 1595: {
1.41 bertrand 1596: if (errno != EINTR)
1.1 bertrand 1597: {
1598: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1599:
1600: while(sem_wait(sem) == -1)
1601: {
1602: if (errno != EINTR)
1603: {
1604: BUG(1, uprintf("Lock error !\n"));
1605: return;
1606: }
1607: }
1608:
1609: BUG(1, uprintf("Lock error !\n"));
1610: return;
1611: }
1612: }
1613: }
1614:
1615: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1616: sigpending(&set);
1617:
1618: return;
1619: }
1620:
1621: static inline void
1622: deverrouillage_gestionnaire_signaux()
1623: {
1624: int semaphore;
1625:
1626: sem_t *sem;
1627:
1628: sigset_t oldset;
1629: sigset_t set;
1630:
1631: // Il faut respecteur l'atomicité des deux opérations suivantes !
1632:
1633: sigfillset(&set);
1634: pthread_sigmask(SIG_BLOCK, &set, &oldset);
1635:
1.8 bertrand 1636: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1637: while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
1.8 bertrand 1638: # else
1639: while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)
1640: # endif
1.1 bertrand 1641: {
1642: if (errno != EINTR)
1643: {
1644: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1645: BUG(1, uprintf("Unlock error !\n"));
1646: return;
1647: }
1648: }
1649:
1.8 bertrand 1650: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1651: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1.8 bertrand 1652: # else
1653: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1654: # endif
1.1 bertrand 1655: {
1656: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1657: BUG(1, uprintf("Unlock error !\n"));
1658: return;
1659: }
1660:
1.8 bertrand 1661: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1662: while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
1.8 bertrand 1663: # else
1664: while(sem_wait(semaphore_gestionnaires_signaux) == -1)
1665: # endif
1.1 bertrand 1666: {
1667: if (errno != EINTR)
1668: {
1669: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1670: BUG(1, uprintf("Unlock error !\n"));
1671: return;
1672: }
1673: }
1674:
1.8 bertrand 1675: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1676: if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
1.8 bertrand 1677: # else
1678: if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)
1679: # endif
1.1 bertrand 1680: {
1681: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1682: BUG(1, uprintf("Unlock error !\n"));
1683: return;
1684: }
1685:
1686: if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
1687: != NULL)
1688: {
1689: while(sem_wait(sem) == -1)
1690: {
1691: if (errno != EINTR)
1692: {
1693: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1694: BUG(1, uprintf("Unlock error !\n"));
1695: return;
1696: }
1697: }
1698: }
1699:
1700: if (semaphore == 1)
1701: {
1.8 bertrand 1702: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1703: if (sem_post(&semaphore_liste_threads) != 0)
1.8 bertrand 1704: # else
1705: if (sem_post(semaphore_liste_threads) != 0)
1706: # endif
1.1 bertrand 1707: {
1708: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1709:
1710: BUG(1, uprintf("Unlock error !\n"));
1711: return;
1712: }
1713: }
1714:
1715: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1716: sigpending(&set);
1717:
1718: return;
1719: }
1720:
1.30 bertrand 1721: void
1722: interruption1(SIGHANDLER_ARGS)
1723: {
1724: pid_t pid;
1725:
1.1 bertrand 1726: pthread_t thread;
1727:
1728: struct_processus *s_etat_processus;
1729:
1730: volatile sig_atomic_t exclusion = 0;
1731:
1.32 bertrand 1732: verrouillage_gestionnaire_signaux();
1733:
1.29 bertrand 1734: # ifdef _BROKEN_SIGINFO
1.44 bertrand 1735: if ((signal == SIGINT) || (signal == SIGTERM))
1.31 bertrand 1736: {
1737: // Si l'interruption provient du clavier, il n'y a pas eu d'appel
1738: // à queue_in().
1739:
1740: pid = getpid();
1741: }
1742: else
1743: {
1744: pid = origine_signal(signal);
1745: }
1.30 bertrand 1746: # else
1.39 bertrand 1747: if (siginfo != NULL)
1748: {
1749: pid = (*siginfo).si_pid;
1750: }
1751: else
1752: {
1753: pid = getpid();
1754: }
1.29 bertrand 1755: # endif
1756:
1.1 bertrand 1757: switch(signal)
1758: {
1759: case SIGALRM :
1760: {
1.30 bertrand 1761: if (pid == getpid())
1.1 bertrand 1762: {
1763: if ((s_etat_processus = recherche_thread(getpid(),
1764: pthread_self())) == NULL)
1765: {
1766: deverrouillage_gestionnaire_signaux();
1.30 bertrand 1767: return;
1.1 bertrand 1768: }
1769:
1770: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1771: {
1772: printf("[%d] SIGALRM (thread %llu)\n", (int) getpid(),
1773: (unsigned long long) pthread_self());
1774: fflush(stdout);
1775: }
1776:
1777: if ((*s_etat_processus).pid_processus_pere != getpid())
1778: {
1779: kill((*s_etat_processus).pid_processus_pere, signal);
1780: }
1781: else
1782: {
1783: (*s_etat_processus).var_volatile_alarme = -1;
1784: (*s_etat_processus).var_volatile_requete_arret = -1;
1785: }
1786: }
1787: else
1788: {
1789: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1790: {
1791: pthread_kill(thread, signal);
1792: }
1793: }
1794:
1795: break;
1796: }
1797:
1798: case SIGINT :
1.44 bertrand 1799: case SIGTERM :
1.1 bertrand 1800: {
1801: /*
1802: * Une vieille spécification POSIX permet au pointeur siginfo
1803: * d'être nul dans le cas d'un ^C envoyé depuis le clavier.
1804: * Solaris suit en particulier cette spécification.
1805: */
1806:
1.30 bertrand 1807: # ifndef _BROKEN_SIGINFO
1.1 bertrand 1808: if (siginfo == NULL)
1809: {
1810: kill(getpid(), signal);
1811: }
1.30 bertrand 1812: else
1813: # endif
1814: if (pid == getpid())
1.1 bertrand 1815: {
1816: if ((s_etat_processus = recherche_thread(getpid(),
1817: pthread_self())) == NULL)
1818: {
1819: deverrouillage_gestionnaire_signaux();
1820: return;
1821: }
1822:
1823: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1824: {
1.44 bertrand 1825: if (signal == SIGINT)
1826: {
1827: printf("[%d] SIGINT (thread %llu)\n", (int) getpid(),
1828: (unsigned long long) pthread_self());
1829: }
1830: else
1831: {
1832: printf("[%d] SIGTERM (thread %llu)\n", (int) getpid(),
1833: (unsigned long long) pthread_self());
1834: }
1835:
1.1 bertrand 1836: fflush(stdout);
1837: }
1838:
1839: if ((*s_etat_processus).pid_processus_pere != getpid())
1840: {
1841: kill((*s_etat_processus).pid_processus_pere, signal);
1842: }
1843: else
1844: {
1845: (*s_etat_processus).var_volatile_traitement_sigint = -1;
1846:
1847: while(exclusion == 1);
1848: exclusion = 1;
1849:
1850: if ((*s_etat_processus).var_volatile_requete_arret == -1)
1851: {
1852: deverrouillage_gestionnaire_signaux();
1853: exclusion = 0;
1854: return;
1855: }
1856:
1.44 bertrand 1857: if (signal == SIGINT)
1.1 bertrand 1858: {
1.44 bertrand 1859: if (strncmp(getenv("LANG"), "fr", 2) == 0)
1860: {
1861: printf("+++Interruption\n");
1862: }
1863: else
1864: {
1865: printf("+++Interrupt\n");
1866: }
1867:
1868: fflush(stdout);
1.1 bertrand 1869: }
1870:
1871: (*s_etat_processus).var_volatile_requete_arret = -1;
1872: (*s_etat_processus).var_volatile_alarme = -1;
1873:
1874: exclusion = 0;
1875: }
1876: }
1877: else
1878: {
1879: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1880: {
1881: pthread_kill(thread, signal);
1882: }
1883: }
1884:
1885: break;
1886: }
1887:
1888: default :
1889: {
1890: BUG(1, uprintf("[%d] Unknown signal %d in this context\n",
1891: (int) getpid(), signal));
1892: break;
1893: }
1894: }
1895:
1896: deverrouillage_gestionnaire_signaux();
1897: return;
1898: }
1899:
1900: void
1.30 bertrand 1901: interruption2(SIGHANDLER_ARGS)
1.1 bertrand 1902: {
1.30 bertrand 1903: pid_t pid;
1904:
1.1 bertrand 1905: pthread_t thread;
1.30 bertrand 1906:
1.1 bertrand 1907: struct_processus *s_etat_processus;
1908:
1.32 bertrand 1909: verrouillage_gestionnaire_signaux();
1910:
1.29 bertrand 1911: # ifdef _BROKEN_SIGINFO
1.30 bertrand 1912: pid = origine_signal(signal);
1913: # else
1.39 bertrand 1914: if (siginfo != NULL)
1915: {
1916: pid = (*siginfo).si_pid;
1917: }
1918: else
1919: {
1920: pid = getpid();
1921: }
1.29 bertrand 1922: # endif
1923:
1.30 bertrand 1924: # ifndef _BROKEN_SIGINFO
1.1 bertrand 1925: if (siginfo == NULL)
1926: {
1927: /*
1928: * Le signal SIGFSTP provient de la mort du processus de contrôle.
1929: * Sous certains systèmes (Linux...), la mort du terminal de contrôle
1930: * se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
1931: * (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
1932: * non initialisée (pointeur NULL) issue de TERMIO.
1933: */
1934:
1935: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1936: {
1937: pthread_kill(thread, SIGHUP);
1938: deverrouillage_gestionnaire_signaux();
1939: return;
1940: }
1941: }
1.30 bertrand 1942: else
1943: # endif
1944: if (pid == getpid())
1.1 bertrand 1945: {
1946: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
1947: == NULL)
1948: {
1949: deverrouillage_gestionnaire_signaux();
1950: return;
1951: }
1952:
1953: /*
1954: * 0 => fonctionnement normal
1955: * -1 => requête
1956: * 1 => requête acceptée en attente de traitement
1957: */
1958:
1959: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1960: {
1961: printf("[%d] SIGTSTP (thread %llu)\n", (int) getpid(),
1962: (unsigned long long) pthread_self());
1963: fflush(stdout);
1964: }
1965:
1966: if ((*s_etat_processus).var_volatile_processus_pere == 0)
1967: {
1968: kill((*s_etat_processus).pid_processus_pere, signal);
1969: }
1970: else
1971: {
1972: (*s_etat_processus).var_volatile_requete_arret2 = -1;
1973: }
1974: }
1975: else
1976: {
1977: // Envoi d'un signal au thread maître du groupe.
1978:
1979: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1980: {
1981: pthread_kill(thread, SIGTSTP);
1982: deverrouillage_gestionnaire_signaux();
1983: return;
1984: }
1985: }
1986:
1987: deverrouillage_gestionnaire_signaux();
1988: return;
1989: }
1990:
1991: void
1.30 bertrand 1992: interruption3(SIGHANDLER_ARGS)
1.1 bertrand 1993: {
1.63 bertrand 1994: pthread_t thread;
1995:
1.1 bertrand 1996: struct_processus *s_etat_processus;
1997:
1.32 bertrand 1998: verrouillage_gestionnaire_signaux();
1999:
1.1 bertrand 2000: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2001: {
2002: deverrouillage_gestionnaire_signaux();
2003: return;
2004: }
2005:
2006: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2007: {
2008: printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),
2009: (unsigned long long) pthread_self());
2010: fflush(stdout);
2011: }
2012:
2013: if ((*s_etat_processus).var_volatile_recursivite == -1)
2014: {
2015: // Segfault dans un appel de fonction récursive
2016: deverrouillage_gestionnaire_signaux();
2017: longjmp(contexte, -1);
2018: }
2019: else
2020: {
2021: // Segfault dans une routine interne
2022: if (strncmp(getenv("LANG"), "fr", 2) == 0)
2023: {
1.63 bertrand 2024: printf("+++Système : Violation d'accès\n");
1.1 bertrand 2025: }
2026: else
2027: {
1.63 bertrand 2028: printf("+++System : Access violation\n");
1.1 bertrand 2029: }
2030:
2031: fflush(stdout);
2032:
1.63 bertrand 2033: (*s_etat_processus).compteur_violation_d_acces++;
1.1 bertrand 2034:
1.63 bertrand 2035: if ((*s_etat_processus).compteur_violation_d_acces > 1)
1.1 bertrand 2036: {
1.63 bertrand 2037: // On vient de récupérer plus d'une erreur de segmentation
2038: // dans le même processus ou le même thread. L'erreur n'est pas
2039: // récupérable et on sort autoritairement du programme. Il peut
2040: // rester des processus orphelins en attente !
2041:
2042: if (strncmp(getenv("LANG"), "fr", 2) == 0)
2043: {
1.64 ! bertrand 2044: printf("+++Système : Violation d'accès, tentative de "
! 2045: "terminaison de la tâche\n");
! 2046: printf(" (defauts multiples)\n");
1.63 bertrand 2047: }
2048: else
2049: {
1.64 ! bertrand 2050: printf("+++System : Access violation, trying to kill task "
! 2051: "(multiple defaults)\n");
1.63 bertrand 2052: }
2053:
2054: fflush(stdout);
2055:
1.1 bertrand 2056: deverrouillage_gestionnaire_signaux();
2057: exit(EXIT_FAILURE);
2058: }
2059: else
2060: {
1.63 bertrand 2061: // Première erreur de segmentation. On essaie de terminer
2062: // proprement le thread ou le processus. Le signal ne peut être
2063: // envoyé que depuis le même processus.
2064:
2065: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2066: {
2067: if (pthread_equal(thread, pthread_self()) != 0)
2068: {
2069: deverrouillage_gestionnaire_signaux();
2070:
2071: if ((*s_etat_processus).pid_processus_pere != getpid())
2072: {
2073: // On est dans le thread principal d'un processus.
2074:
2075: longjmp(contexte_processus, -1);
2076: }
2077: else
2078: {
2079: // On est dans le thread principal du processus
2080: // père.
2081:
2082: longjmp(contexte_initial, -1);
2083: }
2084: }
2085: else
2086: {
2087: // On est dans un thread fils d'un thread principal.
2088:
2089: deverrouillage_gestionnaire_signaux();
2090: longjmp(contexte_thread, -1);
2091: }
2092: }
2093:
2094: // Là, on ramasse les miettes puisque le thread n'existe plus
2095: // dans la base (corruption de la mémoire).
2096:
1.1 bertrand 2097: deverrouillage_gestionnaire_signaux();
2098: longjmp(contexte_initial, -1);
2099: }
2100: }
2101:
2102: deverrouillage_gestionnaire_signaux();
2103: return;
2104: }
2105:
2106: void
1.30 bertrand 2107: interruption4(SIGHANDLER_ARGS)
1.1 bertrand 2108: {
2109: struct_processus *s_etat_processus;
2110:
1.32 bertrand 2111: verrouillage_gestionnaire_signaux();
2112:
1.1 bertrand 2113: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2114: {
2115: deverrouillage_gestionnaire_signaux();
2116: return;
2117: }
2118:
2119: /*
2120: * Démarrage d'un processus fils ou gestion de SIGCONT (SUSPEND)
2121: */
2122:
2123: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2124: {
2125: printf("[%d] SIGSTART/SIGCONT (thread %llu)\n", (int) getpid(),
2126: (unsigned long long) pthread_self());
2127: fflush(stdout);
2128: }
2129:
2130: deverrouillage_gestionnaire_signaux();
2131: return;
2132: }
2133:
2134: void
1.30 bertrand 2135: interruption5(SIGHANDLER_ARGS)
1.1 bertrand 2136: {
1.30 bertrand 2137: pid_t pid;
2138:
1.1 bertrand 2139: pthread_t thread;
1.30 bertrand 2140:
1.1 bertrand 2141: struct_processus *s_etat_processus;
2142:
1.32 bertrand 2143: verrouillage_gestionnaire_signaux();
2144:
1.29 bertrand 2145: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2146: pid = origine_signal(signal);
2147: # else
2148: pid = (*siginfo).si_pid;
1.29 bertrand 2149: # endif
2150:
1.30 bertrand 2151: if (pid == getpid())
1.1 bertrand 2152: {
2153: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2154: == NULL)
2155: {
2156: deverrouillage_gestionnaire_signaux();
2157: return;
2158: }
2159:
2160: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2161: {
1.16 bertrand 2162: printf("[%d] SIGFSTOP (thread %llu)\n", (int) getpid(),
2163: (unsigned long long) pthread_self());
2164: fflush(stdout);
1.1 bertrand 2165: }
2166:
2167: /*
2168: * var_globale_traitement_retarde_stop :
2169: * 0 -> traitement immédiat
2170: * 1 -> traitement retardé (aucun signal reçu)
2171: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2172: */
2173:
1.11 bertrand 2174: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
1.1 bertrand 2175: {
1.11 bertrand 2176: (*s_etat_processus).var_volatile_requete_arret = -1;
1.1 bertrand 2177: }
2178: else
2179: {
1.11 bertrand 2180: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
1.1 bertrand 2181: }
2182: }
2183: else
2184: {
1.11 bertrand 2185: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2186: == NULL)
2187: {
2188: deverrouillage_gestionnaire_signaux();
2189: return;
2190: }
2191:
1.1 bertrand 2192: // Envoi d'un signal au thread maître du groupe.
2193:
2194: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2195: {
1.10 bertrand 2196: pthread_kill(thread, signal);
1.1 bertrand 2197: deverrouillage_gestionnaire_signaux();
2198: return;
2199: }
2200: }
2201:
2202: deverrouillage_gestionnaire_signaux();
2203: return;
2204: }
2205:
2206: void
1.30 bertrand 2207: interruption6(SIGHANDLER_ARGS)
1.1 bertrand 2208: {
2209: struct_processus *s_etat_processus;
2210:
1.32 bertrand 2211: verrouillage_gestionnaire_signaux();
2212:
1.1 bertrand 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] SIGINJECT/SIGQUIT (thread %llu)\n", (int) getpid(),
2222: (unsigned long long) pthread_self());
2223: fflush(stdout);
2224: }
2225:
2226: deverrouillage_gestionnaire_signaux();
2227: return;
2228: }
2229:
2230: void
1.30 bertrand 2231: interruption7(SIGHANDLER_ARGS)
1.1 bertrand 2232: {
2233: struct_processus *s_etat_processus;
2234:
1.32 bertrand 2235: verrouillage_gestionnaire_signaux();
2236:
1.1 bertrand 2237: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2238: {
2239: deverrouillage_gestionnaire_signaux();
2240: return;
2241: }
2242:
2243: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2244: {
2245: printf("[%d] SIGPIPE (thread %llu)\n", (int) getpid(),
2246: (unsigned long long) pthread_self());
2247: fflush(stdout);
2248: }
2249:
2250: (*s_etat_processus).var_volatile_requete_arret = -1;
2251: deverrouillage_gestionnaire_signaux();
2252:
2253: BUG(1, printf("[%d] SIGPIPE\n", (int) getpid()));
2254: return;
2255: }
2256:
2257: void
1.30 bertrand 2258: interruption8(SIGHANDLER_ARGS)
1.1 bertrand 2259: {
1.30 bertrand 2260: pid_t pid;
2261:
1.1 bertrand 2262: pthread_t thread;
1.30 bertrand 2263:
1.1 bertrand 2264: struct_processus *s_etat_processus;
2265:
1.32 bertrand 2266: verrouillage_gestionnaire_signaux();
2267:
1.29 bertrand 2268: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2269: pid = origine_signal(signal);
2270: # else
2271: pid = (*siginfo).si_pid;
1.29 bertrand 2272: # endif
2273:
1.30 bertrand 2274: if (pid == getpid())
1.1 bertrand 2275: {
2276: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2277: == NULL)
2278: {
2279: deverrouillage_gestionnaire_signaux();
2280: return;
2281: }
2282:
2283: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2284: {
2285: printf("[%d] SIGURG (thread %llu)\n", (int) getpid(),
2286: (unsigned long long) pthread_self());
2287: fflush(stdout);
2288: }
2289:
2290: (*s_etat_processus).var_volatile_alarme = -1;
2291: (*s_etat_processus).var_volatile_requete_arret = -1;
2292: }
2293: else
2294: {
2295: // Envoi d'un signal au thread maître du groupe.
2296:
2297: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2298: {
2299: pthread_kill(thread, SIGURG);
2300: deverrouillage_gestionnaire_signaux();
2301: return;
2302: }
2303: }
2304:
2305: deverrouillage_gestionnaire_signaux();
2306: return;
2307: }
2308:
2309: void
1.30 bertrand 2310: interruption9(SIGHANDLER_ARGS)
1.1 bertrand 2311: {
2312: struct_processus *s_etat_processus;
2313:
1.32 bertrand 2314: verrouillage_gestionnaire_signaux();
2315:
1.1 bertrand 2316: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2317: {
2318: deverrouillage_gestionnaire_signaux();
2319: return;
2320: }
2321:
2322: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2323: {
2324: printf("[%d] SIGABORT/SIGPROF (thread %llu)\n", (int) getpid(),
2325: (unsigned long long) pthread_self());
2326: fflush(stdout);
2327: }
2328:
1.30 bertrand 2329: # ifdef _BROKEN_SIGINFO
2330: if (queue_in(getpid(), signal) != 0)
2331: {
2332: return;
2333: }
2334:
1.32 bertrand 2335: deverrouillage_gestionnaire_signaux();
1.30 bertrand 2336: interruption11(signal);
2337: # else
1.32 bertrand 2338: deverrouillage_gestionnaire_signaux();
1.17 bertrand 2339: interruption11(signal, siginfo, context);
1.30 bertrand 2340: # endif
1.1 bertrand 2341: return;
2342: }
2343:
2344: void
1.30 bertrand 2345: interruption10(SIGHANDLER_ARGS)
1.1 bertrand 2346: {
2347: file *fichier;
2348:
2349: struct_processus *s_etat_processus;
2350:
2351: unsigned char nom[8 + 64 + 1];
2352:
1.32 bertrand 2353: verrouillage_gestionnaire_signaux();
2354:
1.1 bertrand 2355: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2356: {
2357: deverrouillage_gestionnaire_signaux();
2358: return;
2359: }
2360:
2361: snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
2362: (unsigned long) pthread_self());
2363:
2364: if ((fichier = fopen(nom, "w+")) != NULL)
2365: {
2366: fclose(fichier);
2367:
2368: freopen(nom, "w", stdout);
2369: freopen(nom, "w", stderr);
2370: }
2371:
2372: freopen("/dev/null", "r", stdin);
2373:
2374: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2375: {
2376: printf("[%d] SIGHUP (thread %llu)\n", (int) getpid(),
2377: (unsigned long long) pthread_self());
2378: fflush(stdout);
2379: }
2380:
2381: deverrouillage_gestionnaire_signaux();
2382: return;
2383: }
2384:
2385: void
1.30 bertrand 2386: interruption11(SIGHANDLER_ARGS)
1.16 bertrand 2387: {
1.30 bertrand 2388: pid_t pid;
2389:
1.16 bertrand 2390: pthread_t thread;
1.30 bertrand 2391:
1.16 bertrand 2392: struct_processus *s_etat_processus;
2393:
1.32 bertrand 2394: verrouillage_gestionnaire_signaux();
2395:
1.29 bertrand 2396: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2397: pid = origine_signal(signal);
2398: # else
2399: pid = (*siginfo).si_pid;
1.29 bertrand 2400: # endif
2401:
1.30 bertrand 2402: if (pid == getpid())
1.16 bertrand 2403: {
2404: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2405: == NULL)
2406: {
2407: deverrouillage_gestionnaire_signaux();
2408: return;
2409: }
2410:
2411: (*s_etat_processus).arret_depuis_abort = -1;
2412:
2413: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2414: {
2415: printf("[%d] SIGFABORT (thread %llu)\n", (int) getpid(),
2416: (unsigned long long) pthread_self());
2417: fflush(stdout);
2418: }
2419:
2420: /*
2421: * var_globale_traitement_retarde_stop :
2422: * 0 -> traitement immédiat
2423: * 1 -> traitement retardé (aucun signal reçu)
2424: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2425: */
2426:
2427: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
2428: {
2429: (*s_etat_processus).var_volatile_requete_arret = -1;
2430: }
2431: else
2432: {
2433: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
2434: }
2435: }
2436: else
2437: {
2438: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2439: == NULL)
2440: {
2441: deverrouillage_gestionnaire_signaux();
2442: return;
2443: }
2444:
2445: (*s_etat_processus).arret_depuis_abort = -1;
2446:
2447: // Envoi d'un signal au thread maître du groupe.
2448:
2449: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2450: {
2451: pthread_kill(thread, signal);
2452: deverrouillage_gestionnaire_signaux();
2453: return;
2454: }
2455: }
2456:
2457: deverrouillage_gestionnaire_signaux();
2458: return;
2459: }
2460:
2461: void
1.1 bertrand 2462: traitement_exceptions_gsl(const char *reason, const char *file,
2463: int line, int gsl_errno)
2464: {
2465: struct_processus *s_etat_processus;
2466:
2467: verrouillage_gestionnaire_signaux();
2468:
2469: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2470: {
2471: deverrouillage_gestionnaire_signaux();
2472: return;
2473: }
2474:
2475: (*s_etat_processus).var_volatile_exception_gsl = gsl_errno;
2476: deverrouillage_gestionnaire_signaux();
2477: return;
2478: }
2479:
2480: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>