Annotation of rpl/src/interruptions.c, revision 1.40
1.1 bertrand 1: /*
2: ================================================================================
1.37 bertrand 3: RPL/2 (R) version 4.0.19
1.1 bertrand 4: Copyright (C) 1989-2010 Dr. BERTRAND Joël
5:
6: This file is part of RPL/2.
7:
8: RPL/2 is free software; you can redistribute it and/or modify it
9: under the terms of the CeCILL V2 License as published by the french
10: CEA, CNRS and INRIA.
11:
12: RPL/2 is distributed in the hope that it will be useful, but WITHOUT
13: ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14: FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License
15: for more details.
16:
17: You should have received a copy of the CeCILL License
18: along with RPL/2. If not, write to info@cecill.info.
19: ================================================================================
20: */
21:
22:
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:
806: for(i = 0; i < (*s_etat_processus).nombre_variables; i++)
807: {
808: pthread_mutex_trylock(&((*(*s_etat_processus)
809: .s_liste_variables[i].objet).mutex));
810: pthread_mutex_unlock(&((*(*s_etat_processus)
811: .s_liste_variables[i].objet).mutex));
812:
813: // Les variables de niveau 0 sont des définitions qui
814: // ne sont pas copiées entre threads.
815: if ((*s_etat_processus).s_liste_variables[i].niveau > 0)
816: {
817: liberation(s_etat_processus,
818: (*s_etat_processus).s_liste_variables[i].objet);
819: }
820:
821: free((*s_etat_processus).s_liste_variables[i].nom);
822: }
823:
824: free((*s_etat_processus).s_liste_variables);
825:
826: for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)
827: {
828: pthread_mutex_trylock(&((*(*s_etat_processus)
829: .s_liste_variables_statiques[i].objet).mutex));
830: pthread_mutex_unlock(&((*(*s_etat_processus)
831: .s_liste_variables_statiques[i].objet).mutex));
832:
833: liberation(s_etat_processus, (*s_etat_processus)
834: .s_liste_variables_statiques[i].objet);
835: free((*s_etat_processus).s_liste_variables_statiques[i].nom);
836: }
837:
838: free((*s_etat_processus).s_liste_variables_statiques);
839:
840: // Ne peut être effacé qu'une seule fois
841: if (suppression_variables_partagees == d_faux)
842: {
843: suppression_variables_partagees = d_vrai;
844:
845: for(i = 0; i < (*(*s_etat_processus)
846: .s_liste_variables_partagees).nombre_variables; i++)
847: {
848: pthread_mutex_trylock(&((*(*(*s_etat_processus)
849: .s_liste_variables_partagees).table[i].objet)
850: .mutex));
851: pthread_mutex_unlock(&((*(*(*s_etat_processus)
852: .s_liste_variables_partagees).table[i].objet)
853: .mutex));
854:
855: liberation(s_etat_processus, (*(*s_etat_processus)
856: .s_liste_variables_partagees).table[i].objet);
857: free((*(*s_etat_processus).s_liste_variables_partagees)
858: .table[i].nom);
859: }
860:
861: if ((*(*s_etat_processus).s_liste_variables_partagees).table
862: != NULL)
863: {
864: free((struct_variable_partagee *) (*(*s_etat_processus)
865: .s_liste_variables_partagees).table);
866: }
867:
868: pthread_mutex_trylock(&((*(*s_etat_processus)
869: .s_liste_variables_partagees).mutex));
870: pthread_mutex_unlock(&((*(*s_etat_processus)
871: .s_liste_variables_partagees).mutex));
872: }
873:
874: element_courant = (*s_etat_processus).l_base_pile;
875: while(element_courant != NULL)
876: {
877: element_suivant = (*((struct_liste_chainee *)
878: element_courant)).suivant;
879:
880: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
881: element_courant)).donnee).mutex));
882: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
883: element_courant)).donnee).mutex));
884:
885: liberation(s_etat_processus,
886: (*((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_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, (*((struct_liste_chainee *)
904: element_courant)).donnee);
905: free((struct_liste_chainee *) element_courant);
906:
907: element_courant = element_suivant;
908: }
909:
910: element_courant = (*s_etat_processus).l_base_pile_taille_contextes;
911: while(element_courant != NULL)
912: {
913: element_suivant = (*((struct_liste_chainee *)
914: element_courant)).suivant;
915:
916: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
917: element_courant)).donnee).mutex));
918: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
919: element_courant)).donnee).mutex));
920: liberation(s_etat_processus,
921: (*((struct_liste_chainee *)
922: element_courant)).donnee);
923: free((struct_liste_chainee *) element_courant);
924:
925: element_courant = element_suivant;
926: }
927:
928: for(i = 0; i < (*s_etat_processus).nombre_instructions_externes;
929: i++)
930: {
931: free((*s_etat_processus).s_instructions_externes[i].nom);
932: free((*s_etat_processus).s_instructions_externes[i]
933: .nom_bibliotheque);
934: }
935:
936: if ((*s_etat_processus).nombre_instructions_externes != 0)
937: {
938: free((*s_etat_processus).s_instructions_externes);
939: }
940:
941: element_courant = (*s_etat_processus).s_bibliotheques;
942: while(element_courant != NULL)
943: {
944: element_suivant = (*((struct_liste_chainee *)
945: element_courant)).suivant;
946:
947: element_candidat = (*candidat).s_bibliotheques;
948: while(element_candidat != NULL)
949: {
950: if (((*((struct_bibliotheque *) (*((struct_liste_chainee *)
951: element_courant)).donnee))
952: .descripteur == (*((struct_bibliotheque *)
953: (*((struct_liste_chainee *) element_candidat))
954: .donnee)).descripteur) &&
955: ((*((struct_bibliotheque *)
956: (*((struct_liste_chainee *) element_courant))
957: .donnee)).pid == (*((struct_bibliotheque *)
958: (*((struct_liste_chainee *) element_candidat))
959: .donnee)).pid) && (pthread_equal(
960: (*((struct_bibliotheque *)
961: (*((struct_liste_chainee *) element_courant))
962: .donnee)).tid, (*((struct_bibliotheque *)
963: (*((struct_liste_chainee *) element_candidat))
964: .donnee)).tid) != 0))
965: {
966: break;
967: }
968:
969: element_candidat = (*((struct_liste_chainee *)
970: element_candidat)).suivant;
971: }
972:
973: if (element_candidat == NULL)
974: {
975: dlclose((*((struct_bibliotheque *)
976: (*((struct_liste_chainee *) element_courant))
977: .donnee)).descripteur);
978: }
979:
980: free((*((struct_bibliotheque *)
981: (*((struct_liste_chainee *)
982: element_courant)).donnee)).nom);
983: free((*((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_last;
990: while(element_courant != NULL)
991: {
992: element_suivant = (*((struct_liste_chainee *)
993: element_courant)).suivant;
994:
995: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
996: element_courant)).donnee).mutex));
997: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
998: element_courant)).donnee).mutex));
999: liberation(s_etat_processus,
1000: (*((struct_liste_chainee *) element_courant)).donnee);
1001: free(element_courant);
1002:
1003: element_courant = element_suivant;
1004: }
1005:
1006: element_courant = (*s_etat_processus).l_base_pile_systeme;
1007: while(element_courant != NULL)
1008: {
1009: element_suivant = (*((struct_liste_pile_systeme *)
1010: element_courant)).suivant;
1011:
1012: if ((*((struct_liste_pile_systeme *)
1013: element_courant)).indice_boucle != NULL)
1014: {
1015: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
1016: element_courant)).indice_boucle).mutex));
1017: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
1018: element_courant)).indice_boucle).mutex));
1019: }
1020:
1021: liberation(s_etat_processus,
1022: (*((struct_liste_pile_systeme *)
1023: element_courant)).indice_boucle);
1024:
1025: if ((*((struct_liste_pile_systeme *)
1026: element_courant)).limite_indice_boucle != NULL)
1027: {
1028: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
1029: element_courant)).limite_indice_boucle).mutex));
1030: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
1031: element_courant)).limite_indice_boucle).mutex));
1032: }
1033:
1034: liberation(s_etat_processus,
1035: (*((struct_liste_pile_systeme *)
1036: element_courant)).limite_indice_boucle);
1037:
1038: if ((*((struct_liste_pile_systeme *)
1039: element_courant)).objet_de_test != NULL)
1040: {
1041: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
1042: element_courant)).objet_de_test).mutex));
1043: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
1044: element_courant)).objet_de_test).mutex));
1045: }
1046:
1047: liberation(s_etat_processus,
1048: (*((struct_liste_pile_systeme *)
1049: element_courant)).objet_de_test);
1050:
1051: if ((*((struct_liste_pile_systeme *)
1052: element_courant)).nom_variable != NULL)
1053: {
1054: free((*((struct_liste_pile_systeme *)
1055: element_courant)).nom_variable);
1056: }
1057:
1058: free(element_courant);
1059:
1060: element_courant = element_suivant;
1061: }
1062:
1063: element_courant = (*s_etat_processus).s_fichiers;
1064: while(element_courant != NULL)
1065: {
1066: element_suivant = (*((struct_liste_chainee *)
1067: element_courant)).suivant;
1068:
1069: element_candidat = (*candidat).s_fichiers;
1070: while(element_candidat != NULL)
1071: {
1072: if (((*((struct_descripteur_fichier *)
1073: (*((struct_liste_chainee *) element_courant))
1074: .donnee)).pid ==
1075: (*((struct_descripteur_fichier *)
1076: (*((struct_liste_chainee *) element_candidat))
1077: .donnee)).pid) && (pthread_equal(
1078: (*((struct_descripteur_fichier *)
1079: (*((struct_liste_chainee *) element_courant))
1080: .donnee)).tid, (*((struct_descripteur_fichier *)
1081: (*((struct_liste_chainee *) element_candidat))
1082: .donnee)).tid) != 0))
1083: {
1.5 bertrand 1084: if ((*((struct_descripteur_fichier *)
1085: (*((struct_liste_chainee *) element_courant))
1086: .donnee)).type ==
1087: (*((struct_descripteur_fichier *)
1088: (*((struct_liste_chainee *) element_candidat))
1089: .donnee)).type)
1090: {
1091: if ((*((struct_descripteur_fichier *)
1092: (*((struct_liste_chainee *)
1093: element_candidat)).donnee)).type == 'C')
1094: {
1095: if ((*((struct_descripteur_fichier *)
1096: (*((struct_liste_chainee *)
1097: element_courant)).donnee))
1098: .descripteur_c ==
1099: (*((struct_descripteur_fichier *)
1100: (*((struct_liste_chainee *)
1101: element_candidat)).donnee))
1102: .descripteur_c)
1103: {
1104: break;
1105: }
1106: }
1107: else
1108: {
1109: if (((*((struct_descripteur_fichier *)
1110: (*((struct_liste_chainee *)
1111: element_courant)).donnee))
1112: .descripteur_sqlite ==
1113: (*((struct_descripteur_fichier *)
1114: (*((struct_liste_chainee *)
1115: element_candidat)).donnee))
1116: .descripteur_sqlite) &&
1117: ((*((struct_descripteur_fichier *)
1118: (*((struct_liste_chainee *)
1119: element_courant)).donnee))
1120: .descripteur_c ==
1121: (*((struct_descripteur_fichier *)
1122: (*((struct_liste_chainee *)
1123: element_candidat)).donnee))
1124: .descripteur_c))
1125: {
1126: break;
1127: }
1128: }
1129: }
1.1 bertrand 1130: }
1131:
1132: element_candidat = (*((struct_liste_chainee *)
1133: element_candidat)).suivant;
1134: }
1135:
1136: if (element_candidat == NULL)
1137: {
1138: fclose((*((struct_descripteur_fichier *)
1139: (*((struct_liste_chainee *) element_courant))
1.5 bertrand 1140: .donnee)).descripteur_c);
1141:
1142: if ((*((struct_descripteur_fichier *)
1143: (*((struct_liste_chainee *) element_courant))
1144: .donnee)).type != 'C')
1145: {
1146: sqlite3_close((*((struct_descripteur_fichier *)
1147: (*((struct_liste_chainee *) element_courant))
1148: .donnee)).descripteur_sqlite);
1149: }
1.1 bertrand 1150: }
1151:
1152: free((*((struct_descripteur_fichier *)
1153: (*((struct_liste_chainee *)
1154: element_courant)).donnee)).nom);
1155: free((struct_descripteur_fichier *)
1156: (*((struct_liste_chainee *)
1157: element_courant)).donnee);
1158: free(element_courant);
1159:
1160: element_courant = element_suivant;
1161: }
1162:
1163: element_courant = (*s_etat_processus).s_sockets;
1164: while(element_courant != NULL)
1165: {
1166: element_suivant = (*((struct_liste_chainee *)
1167: element_courant)).suivant;
1168:
1169: element_candidat = (*candidat).s_sockets;
1170: while(element_candidat != NULL)
1171: {
1172: if (((*((struct_socket *)
1173: (*((struct_liste_chainee *) element_courant))
1174: .donnee)).socket == (*((struct_socket *)
1175: (*((struct_liste_chainee *) element_candidat))
1176: .donnee)).socket) &&
1177: ((*((struct_socket *)
1178: (*((struct_liste_chainee *) element_courant))
1179: .donnee)).pid == (*((struct_socket *)
1180: (*((struct_liste_chainee *) element_candidat))
1181: .donnee)).pid) && (pthread_equal(
1182: (*((struct_socket *)
1183: (*((struct_liste_chainee *) element_courant))
1184: .donnee)).tid, (*((struct_socket *)
1185: (*((struct_liste_chainee *) element_candidat))
1186: .donnee)).tid) != 0))
1187: {
1188: break;
1189: }
1190:
1191: element_candidat = (*((struct_liste_chainee *)
1192: element_candidat)).suivant;
1193: }
1194:
1195: if (element_candidat == NULL)
1196: {
1197: if ((*((struct_socket *) (*((struct_liste_chainee *)
1198: element_courant)).donnee)).socket_connectee
1199: == d_vrai)
1200: {
1201: shutdown((*((struct_socket *)
1202: (*((struct_liste_chainee *) element_courant))
1203: .donnee)).socket, SHUT_RDWR);
1204: }
1205:
1206: close((*((struct_socket *)
1207: (*((struct_liste_chainee *) element_courant))
1208: .donnee)).socket);
1209: }
1210:
1211: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1212: element_courant)).donnee).mutex));
1213: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1214: element_courant)).donnee).mutex));
1215:
1216: liberation(s_etat_processus,
1217: (*((struct_liste_chainee *)
1218: element_courant)).donnee);
1219: free(element_courant);
1220:
1221: element_courant = element_suivant;
1222: }
1223:
1.14 bertrand 1224: /*
1225: ================================================================================
1226: À noter : on ne ferme pas la connexion car la conséquence immédiate est
1227: une destruction de l'objet pour le processus père.
1228: ================================================================================
1229:
1.1 bertrand 1230: element_courant = (*s_etat_processus).s_connecteurs_sql;
1231: while(element_courant != NULL)
1232: {
1233: element_suivant = (*((struct_liste_chainee *)
1234: element_courant)).suivant;
1235:
1236: element_candidat = (*candidat).s_connecteurs_sql;
1237: while(element_candidat != NULL)
1238: {
1239: if (((
1240: #ifdef MYSQL_SUPPORT
1241: ((*((struct_connecteur_sql *)
1242: (*((struct_liste_chainee *) element_courant))
1243: .donnee)).descripteur.mysql ==
1244: (*((struct_connecteur_sql *)
1245: (*((struct_liste_chainee *) element_candidat))
1246: .donnee)).descripteur.mysql)
1247: &&
1248: (strcmp((*((struct_connecteur_sql *)
1249: (*((struct_liste_chainee *) element_courant))
1250: .donnee)).type, "MYSQL") == 0)
1251: &&
1252: (strcmp((*((struct_connecteur_sql *)
1253: (*((struct_liste_chainee *) element_candidat))
1254: .donnee)).type, "MYSQL") == 0)
1255: #else
1256: 0
1257: #endif
1258: ) || (
1259: #ifdef POSTGRESQL_SUPPORT
1260: ((*((struct_connecteur_sql *)
1261: (*((struct_liste_chainee *) element_courant))
1262: .donnee)).descripteur.postgresql ==
1263: (*((struct_connecteur_sql *)
1264: (*((struct_liste_chainee *) element_candidat))
1265: .donnee)).descripteur.postgresql)
1266: &&
1267: (strcmp((*((struct_connecteur_sql *)
1268: (*((struct_liste_chainee *) element_courant))
1269: .donnee)).type, "POSTGRESQL") == 0)
1270: &&
1271: (strcmp((*((struct_connecteur_sql *)
1272: (*((struct_liste_chainee *) element_candidat))
1273: .donnee)).type, "POSTGRESQL") == 0)
1274: #else
1275: 0
1276: #endif
1277: )) &&
1278: ((*((struct_connecteur_sql *)
1279: (*((struct_liste_chainee *) element_courant))
1280: .donnee)).pid == (*((struct_connecteur_sql *)
1281: (*((struct_liste_chainee *) element_candidat))
1282: .donnee)).pid) && (pthread_equal(
1283: (*((struct_connecteur_sql *)
1284: (*((struct_liste_chainee *) element_courant))
1285: .donnee)).tid, (*((struct_connecteur_sql *)
1286: (*((struct_liste_chainee *) element_candidat))
1287: .donnee)).tid) != 0))
1288: {
1289: break;
1290: }
1291:
1292: element_candidat = (*((struct_liste_chainee *)
1293: element_candidat)).suivant;
1294: }
1295:
1296: if (element_candidat == NULL)
1297: {
1298: sqlclose((*((struct_liste_chainee *) element_courant))
1299: .donnee);
1300: }
1301:
1302: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1303: element_courant)).donnee).mutex));
1304: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1305: element_courant)).donnee).mutex));
1306:
1307: liberation(s_etat_processus, (*((struct_liste_chainee *)
1308: element_courant)).donnee);
1309: free(element_courant);
1310:
1311: element_courant = element_suivant;
1312: }
1.14 bertrand 1313: */
1.1 bertrand 1314:
1.15 bertrand 1315: (*s_etat_processus).s_connecteurs_sql = NULL;
1316:
1.1 bertrand 1317: element_courant = (*s_etat_processus).s_marques;
1318: while(element_courant != NULL)
1319: {
1320: free((*((struct_marque *) element_courant)).label);
1321: free((*((struct_marque *) element_courant)).position);
1322: element_suivant = (*((struct_marque *) element_courant))
1323: .suivant;
1324: free(element_courant);
1325: element_courant = element_suivant;
1326: }
1327:
1328: liberation_allocateur(s_etat_processus);
1329:
1.8 bertrand 1330: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1331: sem_post(&((*s_etat_processus).semaphore_fork));
1332: sem_destroy(&((*s_etat_processus).semaphore_fork));
1.8 bertrand 1333: # else
1334: sem_post((*s_etat_processus).semaphore_fork);
1335: sem_destroy2((*s_etat_processus).semaphore_fork, sem_fork);
1336: # endif
1.1 bertrand 1337:
1338: free(s_etat_processus);
1339:
1340: s_etat_processus = candidat;
1341: }
1342:
1343: l_element_suivant = (*l_element_courant).suivant;
1344:
1345: free((struct_thread *) (*l_element_courant).donnee);
1346: free((struct_liste_chainee *) l_element_courant);
1347:
1348: l_element_courant = l_element_suivant;
1349: }
1350:
1351: liste_threads = NULL;
1352:
1353: l_element_courant = liste_threads_surveillance;
1354:
1355: while(l_element_courant != NULL)
1356: {
1357: s_argument_thread = (struct_descripteur_thread *)
1358: (*l_element_courant).donnee;
1359:
1.40 ! bertrand 1360: if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
! 1361: != 0)
1.1 bertrand 1362: {
1363: (*s_etat_processus).erreur_systeme = d_es_processus;
1.12 bertrand 1364: sem_post(&semaphore_liste_threads);
1.1 bertrand 1365: return;
1366: }
1367:
1368: (*s_argument_thread).nombre_references--;
1369:
1370: BUG((*s_argument_thread).nombre_references < 0,
1371: printf("(*s_argument_thread).nombre_references = %d\n",
1372: (int) (*s_argument_thread).nombre_references));
1373:
1374: if ((*s_argument_thread).nombre_references == 0)
1375: {
1.20 bertrand 1376: close((*s_argument_thread).pipe_objets[0]);
1377: close((*s_argument_thread).pipe_acquittement[1]);
1378: close((*s_argument_thread).pipe_injections[1]);
1379: close((*s_argument_thread).pipe_nombre_injections[1]);
1380: close((*s_argument_thread).pipe_nombre_objets_attente[0]);
1381: close((*s_argument_thread).pipe_interruptions[0]);
1382: close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);
1383:
1.40 ! bertrand 1384: if (pthread_mutex_unlock(&((*s_argument_thread)
! 1385: .mutex_nombre_references)) != 0)
1.1 bertrand 1386: {
1387: (*s_etat_processus).erreur_systeme = d_es_processus;
1.12 bertrand 1388: sem_post(&semaphore_liste_threads);
1.1 bertrand 1389: return;
1390: }
1391:
1392: pthread_mutex_destroy(&((*s_argument_thread).mutex));
1.40 ! bertrand 1393: pthread_mutex_destroy(&((*s_argument_thread)
! 1394: .mutex_nombre_references));
1.20 bertrand 1395:
1396: if ((*s_argument_thread).processus_detache == d_faux)
1397: {
1398: if ((*s_argument_thread).destruction_objet == d_vrai)
1399: {
1400: liberation(s_etat_processus, (*s_argument_thread).argument);
1401: }
1402: }
1403:
1.1 bertrand 1404: free(s_argument_thread);
1405: }
1406: else
1407: {
1.40 ! bertrand 1408: if (pthread_mutex_unlock(&((*s_argument_thread)
! 1409: .mutex_nombre_references)) != 0)
1.1 bertrand 1410: {
1411: (*s_etat_processus).erreur_systeme = d_es_processus;
1.12 bertrand 1412: sem_post(&semaphore_liste_threads);
1.1 bertrand 1413: return;
1414: }
1415: }
1416:
1417: l_element_suivant = (*l_element_courant).suivant;
1418: free((struct_liste_chainee *) l_element_courant);
1419: l_element_courant = l_element_suivant;
1420: }
1421:
1422: liste_threads_surveillance = NULL;
1423:
1.8 bertrand 1424: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1425: if (sem_post(&semaphore_liste_threads) != 0)
1.8 bertrand 1426: # else
1427: if (sem_post(semaphore_liste_threads) != 0)
1428: # endif
1.1 bertrand 1429: {
1430: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1431: (*s_etat_processus).erreur_systeme = d_es_processus;
1432: return;
1433: }
1434:
1435: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1436: sigpending(&set);
1437: return;
1438: }
1439:
1440: static struct_processus *
1441: recherche_thread(pid_t pid, pthread_t tid)
1442: {
1443: volatile struct_liste_chainee_volatile *l_element_courant;
1444:
1445: struct_processus *s_etat_processus;
1446:
1447: l_element_courant = liste_threads;
1448:
1449: while(l_element_courant != NULL)
1450: {
1451: if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee))
1452: .tid, tid) != 0) && ((*((struct_thread *)
1453: (*l_element_courant).donnee)).pid == pid))
1454: {
1455: break;
1456: }
1457:
1458: l_element_courant = (*l_element_courant).suivant;
1459: }
1460:
1461: if (l_element_courant == NULL)
1462: {
1463: /*
1464: * Le processus n'existe plus. On ne distribue aucun signal.
1465: */
1466:
1467: return(NULL);
1468: }
1469:
1470: s_etat_processus = (*((struct_thread *)
1471: (*l_element_courant).donnee)).s_etat_processus;
1472:
1473: return(s_etat_processus);
1474: }
1475:
1476: static logical1
1477: recherche_thread_principal(pid_t pid, pthread_t *thread)
1478: {
1479: volatile struct_liste_chainee_volatile *l_element_courant;
1480:
1481: l_element_courant = liste_threads;
1482:
1483: while(l_element_courant != NULL)
1484: {
1485: if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal
1486: == d_vrai) && ((*((struct_thread *)
1487: (*l_element_courant).donnee)).pid == pid))
1488: {
1489: break;
1490: }
1491:
1492: l_element_courant = (*l_element_courant).suivant;
1493: }
1494:
1495: if (l_element_courant == NULL)
1496: {
1497: /*
1498: * Le processus n'existe plus. On ne distribue aucun signal.
1499: */
1500:
1501: return(d_faux);
1502: }
1503:
1504: (*thread) = (*((struct_thread *) (*l_element_courant).donnee)).tid;
1505:
1506: return(d_vrai);
1507: }
1508:
1509:
1510: /*
1511: ================================================================================
1512: Procédures de gestion des signaux d'interruption
1513: ================================================================================
1514: Entrée : variable globale
1515: --------------------------------------------------------------------------------
1516: Sortie : variable globale modifiée
1517: --------------------------------------------------------------------------------
1518: Effets de bord : néant
1519: ================================================================================
1520: */
1521:
1522: // Les routines suivantes sont uniquement appelées depuis les gestionnaires
1.17 bertrand 1523: // des signaux asynchrones. Elles ne doivent pas bloquer dans le cas où
1.1 bertrand 1524: // les sémaphores sont déjà bloqués par un gestionnaire de signal.
1525:
1526: static inline void
1527: verrouillage_gestionnaire_signaux()
1528: {
1529: int semaphore;
1530:
1531: sigset_t oldset;
1532: sigset_t set;
1533:
1534: sem_t *sem;
1535:
1536: if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
1537: != NULL)
1538: {
1539: if (sem_post(sem) != 0)
1540: {
1541: BUG(1, uprintf("Lock error !\n"));
1542: return;
1543: }
1544: }
1545:
1546: // Il faut respecteur l'atomicité des deux opérations suivantes !
1547:
1548: sigfillset(&set);
1549: pthread_sigmask(SIG_BLOCK, &set, &oldset);
1550:
1.8 bertrand 1551: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1552: while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
1.8 bertrand 1553: # else
1554: while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)
1555: # endif
1.1 bertrand 1556: {
1557: if (errno != EINTR)
1558: {
1559: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1560: BUG(1, uprintf("Unlock error !\n"));
1561: return;
1562: }
1563: }
1564:
1.8 bertrand 1565: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1566: if (sem_post(&semaphore_gestionnaires_signaux) == -1)
1.8 bertrand 1567: # else
1568: if (sem_post(semaphore_gestionnaires_signaux) == -1)
1569: # endif
1.1 bertrand 1570: {
1571: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1572: BUG(1, uprintf("Lock error !\n"));
1573: return;
1574: }
1575:
1.8 bertrand 1576: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1577: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1.8 bertrand 1578: # else
1579: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1580: # endif
1.1 bertrand 1581: {
1582: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1583: BUG(1, uprintf("Lock error !\n"));
1584: return;
1585: }
1586:
1.8 bertrand 1587: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1588: if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
1.8 bertrand 1589: # else
1590: if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)
1591: # endif
1.1 bertrand 1592: {
1593: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1594: BUG(1, uprintf("Unlock error !\n"));
1595: return;
1596: }
1597:
1598: if (semaphore == 1)
1599: {
1600: // Le semaphore ne peut être pris par le thread qui a appelé
1601: // le gestionnaire de signal car le signal est bloqué par ce thread
1602: // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que
1603: // par un thread concurrent. On essaye donc de le bloquer jusqu'à
1604: // ce que ce soit possible.
1605:
1.8 bertrand 1606: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1607: while(sem_trywait(&semaphore_liste_threads) == -1)
1.8 bertrand 1608: # else
1609: while(sem_trywait(semaphore_liste_threads) == -1)
1610: # endif
1.1 bertrand 1611: {
1612: if ((errno != EINTR) && (errno != EAGAIN))
1613: {
1614: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1615:
1616: while(sem_wait(sem) == -1)
1617: {
1618: if (errno != EINTR)
1619: {
1620: BUG(1, uprintf("Lock error !\n"));
1621: return;
1622: }
1623: }
1624:
1625: BUG(1, uprintf("Lock error !\n"));
1626: return;
1627: }
1628:
1629: sched_yield();
1630: }
1631: }
1632:
1633: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1634: sigpending(&set);
1635:
1636: return;
1637: }
1638:
1639: static inline void
1640: deverrouillage_gestionnaire_signaux()
1641: {
1642: int semaphore;
1643:
1644: sem_t *sem;
1645:
1646: sigset_t oldset;
1647: sigset_t set;
1648:
1649: // Il faut respecteur l'atomicité des deux opérations suivantes !
1650:
1651: sigfillset(&set);
1652: pthread_sigmask(SIG_BLOCK, &set, &oldset);
1653:
1.8 bertrand 1654: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1655: while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
1.8 bertrand 1656: # else
1657: while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)
1658: # endif
1.1 bertrand 1659: {
1660: if (errno != EINTR)
1661: {
1662: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1663: BUG(1, uprintf("Unlock error !\n"));
1664: return;
1665: }
1666: }
1667:
1.8 bertrand 1668: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1669: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1.8 bertrand 1670: # else
1671: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1672: # endif
1.1 bertrand 1673: {
1674: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1675: BUG(1, uprintf("Unlock error !\n"));
1676: return;
1677: }
1678:
1.8 bertrand 1679: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1680: while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
1.8 bertrand 1681: # else
1682: while(sem_wait(semaphore_gestionnaires_signaux) == -1)
1683: # endif
1.1 bertrand 1684: {
1685: if (errno != EINTR)
1686: {
1687: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1688: BUG(1, uprintf("Unlock error !\n"));
1689: return;
1690: }
1691: }
1692:
1.8 bertrand 1693: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1694: if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
1.8 bertrand 1695: # else
1696: if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)
1697: # endif
1.1 bertrand 1698: {
1699: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1700: BUG(1, uprintf("Unlock error !\n"));
1701: return;
1702: }
1703:
1704: if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
1705: != NULL)
1706: {
1707: while(sem_wait(sem) == -1)
1708: {
1709: if (errno != EINTR)
1710: {
1711: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1712: BUG(1, uprintf("Unlock error !\n"));
1713: return;
1714: }
1715: }
1716: }
1717:
1718: if (semaphore == 1)
1719: {
1.8 bertrand 1720: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1721: if (sem_post(&semaphore_liste_threads) != 0)
1.8 bertrand 1722: # else
1723: if (sem_post(semaphore_liste_threads) != 0)
1724: # endif
1.1 bertrand 1725: {
1726: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1727:
1728: BUG(1, uprintf("Unlock error !\n"));
1729: return;
1730: }
1731: }
1732:
1733: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1734: sigpending(&set);
1735:
1736: return;
1737: }
1738:
1.30 bertrand 1739: void
1740: interruption1(SIGHANDLER_ARGS)
1741: {
1742: pid_t pid;
1743:
1.1 bertrand 1744: pthread_t thread;
1745:
1746: struct_processus *s_etat_processus;
1747:
1748: volatile sig_atomic_t exclusion = 0;
1749:
1.32 bertrand 1750: verrouillage_gestionnaire_signaux();
1751:
1.29 bertrand 1752: # ifdef _BROKEN_SIGINFO
1.31 bertrand 1753: if (signal == SIGINT)
1754: {
1755: // Si l'interruption provient du clavier, il n'y a pas eu d'appel
1756: // à queue_in().
1757:
1758: pid = getpid();
1759: }
1760: else
1761: {
1762: pid = origine_signal(signal);
1763: }
1.30 bertrand 1764: # else
1.39 bertrand 1765: if (siginfo != NULL)
1766: {
1767: pid = (*siginfo).si_pid;
1768: }
1769: else
1770: {
1771: pid = getpid();
1772: }
1.29 bertrand 1773: # endif
1774:
1.1 bertrand 1775: switch(signal)
1776: {
1777: case SIGALRM :
1778: {
1.30 bertrand 1779: if (pid == getpid())
1.1 bertrand 1780: {
1781: if ((s_etat_processus = recherche_thread(getpid(),
1782: pthread_self())) == NULL)
1783: {
1784: deverrouillage_gestionnaire_signaux();
1.30 bertrand 1785: return;
1.1 bertrand 1786: }
1787:
1788: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1789: {
1790: printf("[%d] SIGALRM (thread %llu)\n", (int) getpid(),
1791: (unsigned long long) pthread_self());
1792: fflush(stdout);
1793: }
1794:
1795: if ((*s_etat_processus).pid_processus_pere != getpid())
1796: {
1797: kill((*s_etat_processus).pid_processus_pere, signal);
1798: }
1799: else
1800: {
1801: (*s_etat_processus).var_volatile_alarme = -1;
1802: (*s_etat_processus).var_volatile_requete_arret = -1;
1803: }
1804: }
1805: else
1806: {
1807: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1808: {
1809: pthread_kill(thread, signal);
1810: }
1811: }
1812:
1813: break;
1814: }
1815:
1816: case SIGINT :
1817: {
1818: /*
1819: * Une vieille spécification POSIX permet au pointeur siginfo
1820: * d'être nul dans le cas d'un ^C envoyé depuis le clavier.
1821: * Solaris suit en particulier cette spécification.
1822: */
1823:
1.30 bertrand 1824: # ifndef _BROKEN_SIGINFO
1.1 bertrand 1825: if (siginfo == NULL)
1826: {
1827: kill(getpid(), signal);
1828: }
1.30 bertrand 1829: else
1830: # endif
1831: if (pid == getpid())
1.1 bertrand 1832: {
1833: if ((s_etat_processus = recherche_thread(getpid(),
1834: pthread_self())) == NULL)
1835: {
1836: deverrouillage_gestionnaire_signaux();
1837: return;
1838: }
1839:
1840: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1841: {
1842: printf("[%d] SIGINT (thread %llu)\n", (int) getpid(),
1843: (unsigned long long) pthread_self());
1844: fflush(stdout);
1845: }
1846:
1847: if ((*s_etat_processus).pid_processus_pere != getpid())
1848: {
1849: kill((*s_etat_processus).pid_processus_pere, signal);
1850: }
1851: else
1852: {
1853: (*s_etat_processus).var_volatile_traitement_sigint = -1;
1854:
1855: while(exclusion == 1);
1856: exclusion = 1;
1857:
1858: if ((*s_etat_processus).var_volatile_requete_arret == -1)
1859: {
1860: deverrouillage_gestionnaire_signaux();
1861: exclusion = 0;
1862: return;
1863: }
1864:
1865: if (strncmp(getenv("LANG"), "fr", 2) == 0)
1866: {
1867: printf("+++Interruption\n");
1868: }
1869: else
1870: {
1871: printf("+++Interrupt\n");
1872: }
1873:
1874: fflush(stdout);
1875:
1876: (*s_etat_processus).var_volatile_requete_arret = -1;
1877: (*s_etat_processus).var_volatile_alarme = -1;
1878:
1879: exclusion = 0;
1880: }
1881: }
1882: else
1883: {
1884: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1885: {
1886: pthread_kill(thread, signal);
1887: }
1888: }
1889:
1890: break;
1891: }
1892:
1893: default :
1894: {
1895: BUG(1, uprintf("[%d] Unknown signal %d in this context\n",
1896: (int) getpid(), signal));
1897: break;
1898: }
1899: }
1900:
1901: deverrouillage_gestionnaire_signaux();
1902: return;
1903: }
1904:
1905: void
1.30 bertrand 1906: interruption2(SIGHANDLER_ARGS)
1.1 bertrand 1907: {
1.30 bertrand 1908: pid_t pid;
1909:
1.1 bertrand 1910: pthread_t thread;
1.30 bertrand 1911:
1.1 bertrand 1912: struct_processus *s_etat_processus;
1913:
1.32 bertrand 1914: verrouillage_gestionnaire_signaux();
1915:
1.29 bertrand 1916: # ifdef _BROKEN_SIGINFO
1.30 bertrand 1917: pid = origine_signal(signal);
1918: # else
1.39 bertrand 1919: if (siginfo != NULL)
1920: {
1921: pid = (*siginfo).si_pid;
1922: }
1923: else
1924: {
1925: pid = getpid();
1926: }
1.29 bertrand 1927: # endif
1928:
1.30 bertrand 1929: # ifndef _BROKEN_SIGINFO
1.1 bertrand 1930: if (siginfo == NULL)
1931: {
1932: /*
1933: * Le signal SIGFSTP provient de la mort du processus de contrôle.
1934: * Sous certains systèmes (Linux...), la mort du terminal de contrôle
1935: * se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
1936: * (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
1937: * non initialisée (pointeur NULL) issue de TERMIO.
1938: */
1939:
1940: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1941: {
1942: pthread_kill(thread, SIGHUP);
1943: deverrouillage_gestionnaire_signaux();
1944: return;
1945: }
1946: }
1.30 bertrand 1947: else
1948: # endif
1949: if (pid == getpid())
1.1 bertrand 1950: {
1951: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
1952: == NULL)
1953: {
1954: deverrouillage_gestionnaire_signaux();
1955: return;
1956: }
1957:
1958: /*
1959: * 0 => fonctionnement normal
1960: * -1 => requête
1961: * 1 => requête acceptée en attente de traitement
1962: */
1963:
1964: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1965: {
1966: printf("[%d] SIGTSTP (thread %llu)\n", (int) getpid(),
1967: (unsigned long long) pthread_self());
1968: fflush(stdout);
1969: }
1970:
1971: if ((*s_etat_processus).var_volatile_processus_pere == 0)
1972: {
1973: kill((*s_etat_processus).pid_processus_pere, signal);
1974: }
1975: else
1976: {
1977: (*s_etat_processus).var_volatile_requete_arret2 = -1;
1978: }
1979: }
1980: else
1981: {
1982: // Envoi d'un signal au thread maître du groupe.
1983:
1984: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1985: {
1986: pthread_kill(thread, SIGTSTP);
1987: deverrouillage_gestionnaire_signaux();
1988: return;
1989: }
1990: }
1991:
1992: deverrouillage_gestionnaire_signaux();
1993: return;
1994: }
1995:
1996: void
1.30 bertrand 1997: interruption3(SIGHANDLER_ARGS)
1.1 bertrand 1998: {
1.30 bertrand 1999: pid_t pid;
2000:
1.1 bertrand 2001: struct_processus *s_etat_processus;
2002:
2003: static int compteur = 0;
2004:
1.32 bertrand 2005: verrouillage_gestionnaire_signaux();
2006:
1.29 bertrand 2007: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2008: pid = origine_signal(signal);
2009: # else
2010: pid = (*siginfo).si_pid;
1.29 bertrand 2011: # endif
2012:
1.1 bertrand 2013: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2014: {
2015: deverrouillage_gestionnaire_signaux();
2016: return;
2017: }
2018:
2019: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2020: {
2021: printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),
2022: (unsigned long long) pthread_self());
2023: fflush(stdout);
2024: }
2025:
2026: if ((*s_etat_processus).var_volatile_recursivite == -1)
2027: {
2028: // Segfault dans un appel de fonction récursive
2029: deverrouillage_gestionnaire_signaux();
2030: longjmp(contexte, -1);
2031: }
2032: else
2033: {
2034: // Segfault dans une routine interne
2035: if (strncmp(getenv("LANG"), "fr", 2) == 0)
2036: {
2037: printf("+++Système : Violation d'accès (dépassement de pile)\n");
2038: }
2039: else
2040: {
2041: printf("+++System : Access violation (stack overflow)\n");
2042: }
2043:
2044: fflush(stdout);
2045:
2046: compteur++;
2047:
2048: if (compteur > 1)
2049: {
2050: deverrouillage_gestionnaire_signaux();
2051: exit(EXIT_FAILURE);
2052: }
2053: else
2054: {
2055: deverrouillage_gestionnaire_signaux();
2056: longjmp(contexte_initial, -1);
2057: }
2058: }
2059:
2060: deverrouillage_gestionnaire_signaux();
2061: return;
2062: }
2063:
2064: void
1.30 bertrand 2065: interruption4(SIGHANDLER_ARGS)
1.1 bertrand 2066: {
1.30 bertrand 2067: pid_t pid;
2068:
1.1 bertrand 2069: struct_processus *s_etat_processus;
2070:
1.32 bertrand 2071: verrouillage_gestionnaire_signaux();
2072:
1.29 bertrand 2073: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2074: pid = origine_signal(signal);
2075: # else
2076: pid = (*siginfo).si_pid;
1.29 bertrand 2077: # endif
2078:
1.1 bertrand 2079: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2080: {
2081: deverrouillage_gestionnaire_signaux();
2082: return;
2083: }
2084:
2085: /*
2086: * Démarrage d'un processus fils ou gestion de SIGCONT (SUSPEND)
2087: */
2088:
2089: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2090: {
2091: printf("[%d] SIGSTART/SIGCONT (thread %llu)\n", (int) getpid(),
2092: (unsigned long long) pthread_self());
2093: fflush(stdout);
2094: }
2095:
2096: deverrouillage_gestionnaire_signaux();
2097: return;
2098: }
2099:
2100: void
1.30 bertrand 2101: interruption5(SIGHANDLER_ARGS)
1.1 bertrand 2102: {
1.30 bertrand 2103: pid_t pid;
2104:
1.1 bertrand 2105: pthread_t thread;
1.30 bertrand 2106:
1.1 bertrand 2107: struct_processus *s_etat_processus;
2108:
1.32 bertrand 2109: verrouillage_gestionnaire_signaux();
2110:
1.29 bertrand 2111: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2112: pid = origine_signal(signal);
2113: # else
2114: pid = (*siginfo).si_pid;
1.29 bertrand 2115: # endif
2116:
1.30 bertrand 2117: if (pid == getpid())
1.1 bertrand 2118: {
2119: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2120: == NULL)
2121: {
2122: deverrouillage_gestionnaire_signaux();
2123: return;
2124: }
2125:
2126: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2127: {
1.16 bertrand 2128: printf("[%d] SIGFSTOP (thread %llu)\n", (int) getpid(),
2129: (unsigned long long) pthread_self());
2130: fflush(stdout);
1.1 bertrand 2131: }
2132:
2133: /*
2134: * var_globale_traitement_retarde_stop :
2135: * 0 -> traitement immédiat
2136: * 1 -> traitement retardé (aucun signal reçu)
2137: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2138: */
2139:
1.11 bertrand 2140: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
1.1 bertrand 2141: {
1.11 bertrand 2142: (*s_etat_processus).var_volatile_requete_arret = -1;
1.1 bertrand 2143: }
2144: else
2145: {
1.11 bertrand 2146: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
1.1 bertrand 2147: }
2148: }
2149: else
2150: {
1.11 bertrand 2151: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2152: == NULL)
2153: {
2154: deverrouillage_gestionnaire_signaux();
2155: return;
2156: }
2157:
1.1 bertrand 2158: // Envoi d'un signal au thread maître du groupe.
2159:
2160: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2161: {
1.10 bertrand 2162: pthread_kill(thread, signal);
1.1 bertrand 2163: deverrouillage_gestionnaire_signaux();
2164: return;
2165: }
2166: }
2167:
2168: deverrouillage_gestionnaire_signaux();
2169: return;
2170: }
2171:
2172: void
1.30 bertrand 2173: interruption6(SIGHANDLER_ARGS)
1.1 bertrand 2174: {
1.30 bertrand 2175: pid_t pid;
2176:
1.1 bertrand 2177: struct_processus *s_etat_processus;
2178:
1.32 bertrand 2179: verrouillage_gestionnaire_signaux();
2180:
1.29 bertrand 2181: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2182: pid = origine_signal(signal);
2183: # else
2184: pid = (*siginfo).si_pid;
1.29 bertrand 2185: # endif
2186:
1.1 bertrand 2187: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2188: {
2189: deverrouillage_gestionnaire_signaux();
2190: return;
2191: }
2192:
2193: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2194: {
2195: printf("[%d] SIGINJECT/SIGQUIT (thread %llu)\n", (int) getpid(),
2196: (unsigned long long) pthread_self());
2197: fflush(stdout);
2198: }
2199:
2200: deverrouillage_gestionnaire_signaux();
2201: return;
2202: }
2203:
2204: void
1.30 bertrand 2205: interruption7(SIGHANDLER_ARGS)
1.1 bertrand 2206: {
1.30 bertrand 2207: pid_t pid;
2208:
1.1 bertrand 2209: struct_processus *s_etat_processus;
2210:
1.32 bertrand 2211: verrouillage_gestionnaire_signaux();
2212:
1.29 bertrand 2213: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2214: pid = origine_signal(signal);
2215: # else
2216: pid = (*siginfo).si_pid;
1.29 bertrand 2217: # endif
2218:
1.1 bertrand 2219: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2220: {
2221: deverrouillage_gestionnaire_signaux();
2222: return;
2223: }
2224:
2225: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2226: {
2227: printf("[%d] SIGPIPE (thread %llu)\n", (int) getpid(),
2228: (unsigned long long) pthread_self());
2229: fflush(stdout);
2230: }
2231:
2232: (*s_etat_processus).var_volatile_requete_arret = -1;
2233: deverrouillage_gestionnaire_signaux();
2234:
2235: BUG(1, printf("[%d] SIGPIPE\n", (int) getpid()));
2236: return;
2237: }
2238:
2239: void
1.30 bertrand 2240: interruption8(SIGHANDLER_ARGS)
1.1 bertrand 2241: {
1.30 bertrand 2242: pid_t pid;
2243:
1.1 bertrand 2244: pthread_t thread;
1.30 bertrand 2245:
1.1 bertrand 2246: struct_processus *s_etat_processus;
2247:
1.32 bertrand 2248: verrouillage_gestionnaire_signaux();
2249:
1.29 bertrand 2250: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2251: pid = origine_signal(signal);
2252: # else
2253: pid = (*siginfo).si_pid;
1.29 bertrand 2254: # endif
2255:
1.30 bertrand 2256: if (pid == getpid())
1.1 bertrand 2257: {
2258: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2259: == NULL)
2260: {
2261: deverrouillage_gestionnaire_signaux();
2262: return;
2263: }
2264:
2265: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2266: {
2267: printf("[%d] SIGURG (thread %llu)\n", (int) getpid(),
2268: (unsigned long long) pthread_self());
2269: fflush(stdout);
2270: }
2271:
2272: (*s_etat_processus).var_volatile_alarme = -1;
2273: (*s_etat_processus).var_volatile_requete_arret = -1;
2274: }
2275: else
2276: {
2277: // Envoi d'un signal au thread maître du groupe.
2278:
2279: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2280: {
2281: pthread_kill(thread, SIGURG);
2282: deverrouillage_gestionnaire_signaux();
2283: return;
2284: }
2285: }
2286:
2287: deverrouillage_gestionnaire_signaux();
2288: return;
2289: }
2290:
2291: void
1.30 bertrand 2292: interruption9(SIGHANDLER_ARGS)
1.1 bertrand 2293: {
1.30 bertrand 2294: pid_t pid;
2295:
1.1 bertrand 2296: struct_processus *s_etat_processus;
2297:
1.32 bertrand 2298: verrouillage_gestionnaire_signaux();
2299:
1.29 bertrand 2300: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2301: pid = origine_signal(signal);
2302: # else
2303: pid = (*siginfo).si_pid;
1.29 bertrand 2304: # endif
2305:
1.1 bertrand 2306: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2307: {
2308: deverrouillage_gestionnaire_signaux();
2309: return;
2310: }
2311:
2312: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2313: {
2314: printf("[%d] SIGABORT/SIGPROF (thread %llu)\n", (int) getpid(),
2315: (unsigned long long) pthread_self());
2316: fflush(stdout);
2317: }
2318:
1.30 bertrand 2319: # ifdef _BROKEN_SIGINFO
2320: if (queue_in(getpid(), signal) != 0)
2321: {
2322: return;
2323: }
2324:
1.32 bertrand 2325: deverrouillage_gestionnaire_signaux();
1.30 bertrand 2326: interruption11(signal);
2327: # else
1.32 bertrand 2328: deverrouillage_gestionnaire_signaux();
1.17 bertrand 2329: interruption11(signal, siginfo, context);
1.30 bertrand 2330: # endif
1.1 bertrand 2331: return;
2332: }
2333:
2334: void
1.30 bertrand 2335: interruption10(SIGHANDLER_ARGS)
1.1 bertrand 2336: {
2337: file *fichier;
2338:
1.30 bertrand 2339: pid_t pid;
2340:
1.1 bertrand 2341: struct_processus *s_etat_processus;
2342:
2343: unsigned char nom[8 + 64 + 1];
2344:
1.32 bertrand 2345: verrouillage_gestionnaire_signaux();
2346:
1.29 bertrand 2347: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2348: pid = origine_signal(signal);
2349: # else
2350: pid = (*siginfo).si_pid;
1.29 bertrand 2351: # endif
2352:
1.1 bertrand 2353: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2354: {
2355: deverrouillage_gestionnaire_signaux();
2356: return;
2357: }
2358:
2359: snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
2360: (unsigned long) pthread_self());
2361:
2362: if ((fichier = fopen(nom, "w+")) != NULL)
2363: {
2364: fclose(fichier);
2365:
2366: freopen(nom, "w", stdout);
2367: freopen(nom, "w", stderr);
2368: }
2369:
2370: freopen("/dev/null", "r", stdin);
2371:
2372: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2373: {
2374: printf("[%d] SIGHUP (thread %llu)\n", (int) getpid(),
2375: (unsigned long long) pthread_self());
2376: fflush(stdout);
2377: }
2378:
2379: deverrouillage_gestionnaire_signaux();
2380: return;
2381: }
2382:
2383: void
1.30 bertrand 2384: interruption11(SIGHANDLER_ARGS)
1.16 bertrand 2385: {
1.30 bertrand 2386: pid_t pid;
2387:
1.16 bertrand 2388: pthread_t thread;
1.30 bertrand 2389:
1.16 bertrand 2390: struct_processus *s_etat_processus;
2391:
1.32 bertrand 2392: verrouillage_gestionnaire_signaux();
2393:
1.29 bertrand 2394: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2395: pid = origine_signal(signal);
2396: # else
2397: pid = (*siginfo).si_pid;
1.29 bertrand 2398: # endif
2399:
1.30 bertrand 2400: if (pid == getpid())
1.16 bertrand 2401: {
2402: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2403: == NULL)
2404: {
2405: deverrouillage_gestionnaire_signaux();
2406: return;
2407: }
2408:
2409: (*s_etat_processus).arret_depuis_abort = -1;
2410:
2411: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2412: {
2413: printf("[%d] SIGFABORT (thread %llu)\n", (int) getpid(),
2414: (unsigned long long) pthread_self());
2415: fflush(stdout);
2416: }
2417:
2418: /*
2419: * var_globale_traitement_retarde_stop :
2420: * 0 -> traitement immédiat
2421: * 1 -> traitement retardé (aucun signal reçu)
2422: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2423: */
2424:
2425: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
2426: {
2427: (*s_etat_processus).var_volatile_requete_arret = -1;
2428: }
2429: else
2430: {
2431: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
2432: }
2433: }
2434: else
2435: {
2436: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2437: == NULL)
2438: {
2439: deverrouillage_gestionnaire_signaux();
2440: return;
2441: }
2442:
2443: (*s_etat_processus).arret_depuis_abort = -1;
2444:
2445: // Envoi d'un signal au thread maître du groupe.
2446:
2447: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2448: {
2449: pthread_kill(thread, signal);
2450: deverrouillage_gestionnaire_signaux();
2451: return;
2452: }
2453: }
2454:
2455: deverrouillage_gestionnaire_signaux();
2456: return;
2457: }
2458:
2459: void
1.1 bertrand 2460: traitement_exceptions_gsl(const char *reason, const char *file,
2461: int line, int gsl_errno)
2462: {
2463: struct_processus *s_etat_processus;
2464:
2465: verrouillage_gestionnaire_signaux();
2466:
2467: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2468: {
2469: deverrouillage_gestionnaire_signaux();
2470: return;
2471: }
2472:
2473: (*s_etat_processus).var_volatile_exception_gsl = gsl_errno;
2474: deverrouillage_gestionnaire_signaux();
2475: return;
2476: }
2477:
2478: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>