Annotation of rpl/src/interruptions.c, revision 1.41
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.41 ! bertrand 1607: while(sem_wait(&semaphore_liste_threads) == -1)
1.8 bertrand 1608: # else
1.41 ! bertrand 1609: while(sem_wait(semaphore_liste_threads) == -1)
1.8 bertrand 1610: # endif
1.1 bertrand 1611: {
1.41 ! bertrand 1612: if (errno != EINTR)
1.1 bertrand 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: }
1630:
1631: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1632: sigpending(&set);
1633:
1634: return;
1635: }
1636:
1637: static inline void
1638: deverrouillage_gestionnaire_signaux()
1639: {
1640: int semaphore;
1641:
1642: sem_t *sem;
1643:
1644: sigset_t oldset;
1645: sigset_t set;
1646:
1647: // Il faut respecteur l'atomicité des deux opérations suivantes !
1648:
1649: sigfillset(&set);
1650: pthread_sigmask(SIG_BLOCK, &set, &oldset);
1651:
1.8 bertrand 1652: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1653: while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
1.8 bertrand 1654: # else
1655: while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)
1656: # endif
1.1 bertrand 1657: {
1658: if (errno != EINTR)
1659: {
1660: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1661: BUG(1, uprintf("Unlock error !\n"));
1662: return;
1663: }
1664: }
1665:
1.8 bertrand 1666: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1667: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1.8 bertrand 1668: # else
1669: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1670: # endif
1.1 bertrand 1671: {
1672: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1673: BUG(1, uprintf("Unlock error !\n"));
1674: return;
1675: }
1676:
1.8 bertrand 1677: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1678: while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
1.8 bertrand 1679: # else
1680: while(sem_wait(semaphore_gestionnaires_signaux) == -1)
1681: # endif
1.1 bertrand 1682: {
1683: if (errno != EINTR)
1684: {
1685: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1686: BUG(1, uprintf("Unlock error !\n"));
1687: return;
1688: }
1689: }
1690:
1.8 bertrand 1691: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1692: if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
1.8 bertrand 1693: # else
1694: if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)
1695: # endif
1.1 bertrand 1696: {
1697: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1698: BUG(1, uprintf("Unlock error !\n"));
1699: return;
1700: }
1701:
1702: if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
1703: != NULL)
1704: {
1705: while(sem_wait(sem) == -1)
1706: {
1707: if (errno != EINTR)
1708: {
1709: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1710: BUG(1, uprintf("Unlock error !\n"));
1711: return;
1712: }
1713: }
1714: }
1715:
1716: if (semaphore == 1)
1717: {
1.8 bertrand 1718: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1719: if (sem_post(&semaphore_liste_threads) != 0)
1.8 bertrand 1720: # else
1721: if (sem_post(semaphore_liste_threads) != 0)
1722: # endif
1.1 bertrand 1723: {
1724: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1725:
1726: BUG(1, uprintf("Unlock error !\n"));
1727: return;
1728: }
1729: }
1730:
1731: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1732: sigpending(&set);
1733:
1734: return;
1735: }
1736:
1.30 bertrand 1737: void
1738: interruption1(SIGHANDLER_ARGS)
1739: {
1740: pid_t pid;
1741:
1.1 bertrand 1742: pthread_t thread;
1743:
1744: struct_processus *s_etat_processus;
1745:
1746: volatile sig_atomic_t exclusion = 0;
1747:
1.32 bertrand 1748: verrouillage_gestionnaire_signaux();
1749:
1.29 bertrand 1750: # ifdef _BROKEN_SIGINFO
1.31 bertrand 1751: if (signal == SIGINT)
1752: {
1753: // Si l'interruption provient du clavier, il n'y a pas eu d'appel
1754: // à queue_in().
1755:
1756: pid = getpid();
1757: }
1758: else
1759: {
1760: pid = origine_signal(signal);
1761: }
1.30 bertrand 1762: # else
1.39 bertrand 1763: if (siginfo != NULL)
1764: {
1765: pid = (*siginfo).si_pid;
1766: }
1767: else
1768: {
1769: pid = getpid();
1770: }
1.29 bertrand 1771: # endif
1772:
1.1 bertrand 1773: switch(signal)
1774: {
1775: case SIGALRM :
1776: {
1.30 bertrand 1777: if (pid == getpid())
1.1 bertrand 1778: {
1779: if ((s_etat_processus = recherche_thread(getpid(),
1780: pthread_self())) == NULL)
1781: {
1782: deverrouillage_gestionnaire_signaux();
1.30 bertrand 1783: return;
1.1 bertrand 1784: }
1785:
1786: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1787: {
1788: printf("[%d] SIGALRM (thread %llu)\n", (int) getpid(),
1789: (unsigned long long) pthread_self());
1790: fflush(stdout);
1791: }
1792:
1793: if ((*s_etat_processus).pid_processus_pere != getpid())
1794: {
1795: kill((*s_etat_processus).pid_processus_pere, signal);
1796: }
1797: else
1798: {
1799: (*s_etat_processus).var_volatile_alarme = -1;
1800: (*s_etat_processus).var_volatile_requete_arret = -1;
1801: }
1802: }
1803: else
1804: {
1805: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1806: {
1807: pthread_kill(thread, signal);
1808: }
1809: }
1810:
1811: break;
1812: }
1813:
1814: case SIGINT :
1815: {
1816: /*
1817: * Une vieille spécification POSIX permet au pointeur siginfo
1818: * d'être nul dans le cas d'un ^C envoyé depuis le clavier.
1819: * Solaris suit en particulier cette spécification.
1820: */
1821:
1.30 bertrand 1822: # ifndef _BROKEN_SIGINFO
1.1 bertrand 1823: if (siginfo == NULL)
1824: {
1825: kill(getpid(), signal);
1826: }
1.30 bertrand 1827: else
1828: # endif
1829: if (pid == getpid())
1.1 bertrand 1830: {
1831: if ((s_etat_processus = recherche_thread(getpid(),
1832: pthread_self())) == NULL)
1833: {
1834: deverrouillage_gestionnaire_signaux();
1835: return;
1836: }
1837:
1838: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1839: {
1840: printf("[%d] SIGINT (thread %llu)\n", (int) getpid(),
1841: (unsigned long long) pthread_self());
1842: fflush(stdout);
1843: }
1844:
1845: if ((*s_etat_processus).pid_processus_pere != getpid())
1846: {
1847: kill((*s_etat_processus).pid_processus_pere, signal);
1848: }
1849: else
1850: {
1851: (*s_etat_processus).var_volatile_traitement_sigint = -1;
1852:
1853: while(exclusion == 1);
1854: exclusion = 1;
1855:
1856: if ((*s_etat_processus).var_volatile_requete_arret == -1)
1857: {
1858: deverrouillage_gestionnaire_signaux();
1859: exclusion = 0;
1860: return;
1861: }
1862:
1863: if (strncmp(getenv("LANG"), "fr", 2) == 0)
1864: {
1865: printf("+++Interruption\n");
1866: }
1867: else
1868: {
1869: printf("+++Interrupt\n");
1870: }
1871:
1872: fflush(stdout);
1873:
1874: (*s_etat_processus).var_volatile_requete_arret = -1;
1875: (*s_etat_processus).var_volatile_alarme = -1;
1876:
1877: exclusion = 0;
1878: }
1879: }
1880: else
1881: {
1882: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1883: {
1884: pthread_kill(thread, signal);
1885: }
1886: }
1887:
1888: break;
1889: }
1890:
1891: default :
1892: {
1893: BUG(1, uprintf("[%d] Unknown signal %d in this context\n",
1894: (int) getpid(), signal));
1895: break;
1896: }
1897: }
1898:
1899: deverrouillage_gestionnaire_signaux();
1900: return;
1901: }
1902:
1903: void
1.30 bertrand 1904: interruption2(SIGHANDLER_ARGS)
1.1 bertrand 1905: {
1.30 bertrand 1906: pid_t pid;
1907:
1.1 bertrand 1908: pthread_t thread;
1.30 bertrand 1909:
1.1 bertrand 1910: struct_processus *s_etat_processus;
1911:
1.32 bertrand 1912: verrouillage_gestionnaire_signaux();
1913:
1.29 bertrand 1914: # ifdef _BROKEN_SIGINFO
1.30 bertrand 1915: pid = origine_signal(signal);
1916: # else
1.39 bertrand 1917: if (siginfo != NULL)
1918: {
1919: pid = (*siginfo).si_pid;
1920: }
1921: else
1922: {
1923: pid = getpid();
1924: }
1.29 bertrand 1925: # endif
1926:
1.30 bertrand 1927: # ifndef _BROKEN_SIGINFO
1.1 bertrand 1928: if (siginfo == NULL)
1929: {
1930: /*
1931: * Le signal SIGFSTP provient de la mort du processus de contrôle.
1932: * Sous certains systèmes (Linux...), la mort du terminal de contrôle
1933: * se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
1934: * (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
1935: * non initialisée (pointeur NULL) issue de TERMIO.
1936: */
1937:
1938: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1939: {
1940: pthread_kill(thread, SIGHUP);
1941: deverrouillage_gestionnaire_signaux();
1942: return;
1943: }
1944: }
1.30 bertrand 1945: else
1946: # endif
1947: if (pid == getpid())
1.1 bertrand 1948: {
1949: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
1950: == NULL)
1951: {
1952: deverrouillage_gestionnaire_signaux();
1953: return;
1954: }
1955:
1956: /*
1957: * 0 => fonctionnement normal
1958: * -1 => requête
1959: * 1 => requête acceptée en attente de traitement
1960: */
1961:
1962: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1963: {
1964: printf("[%d] SIGTSTP (thread %llu)\n", (int) getpid(),
1965: (unsigned long long) pthread_self());
1966: fflush(stdout);
1967: }
1968:
1969: if ((*s_etat_processus).var_volatile_processus_pere == 0)
1970: {
1971: kill((*s_etat_processus).pid_processus_pere, signal);
1972: }
1973: else
1974: {
1975: (*s_etat_processus).var_volatile_requete_arret2 = -1;
1976: }
1977: }
1978: else
1979: {
1980: // Envoi d'un signal au thread maître du groupe.
1981:
1982: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
1983: {
1984: pthread_kill(thread, SIGTSTP);
1985: deverrouillage_gestionnaire_signaux();
1986: return;
1987: }
1988: }
1989:
1990: deverrouillage_gestionnaire_signaux();
1991: return;
1992: }
1993:
1994: void
1.30 bertrand 1995: interruption3(SIGHANDLER_ARGS)
1.1 bertrand 1996: {
1.30 bertrand 1997: pid_t pid;
1998:
1.1 bertrand 1999: struct_processus *s_etat_processus;
2000:
2001: static int compteur = 0;
2002:
1.32 bertrand 2003: verrouillage_gestionnaire_signaux();
2004:
1.29 bertrand 2005: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2006: pid = origine_signal(signal);
2007: # else
2008: pid = (*siginfo).si_pid;
1.29 bertrand 2009: # endif
2010:
1.1 bertrand 2011: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2012: {
2013: deverrouillage_gestionnaire_signaux();
2014: return;
2015: }
2016:
2017: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2018: {
2019: printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),
2020: (unsigned long long) pthread_self());
2021: fflush(stdout);
2022: }
2023:
2024: if ((*s_etat_processus).var_volatile_recursivite == -1)
2025: {
2026: // Segfault dans un appel de fonction récursive
2027: deverrouillage_gestionnaire_signaux();
2028: longjmp(contexte, -1);
2029: }
2030: else
2031: {
2032: // Segfault dans une routine interne
2033: if (strncmp(getenv("LANG"), "fr", 2) == 0)
2034: {
2035: printf("+++Système : Violation d'accès (dépassement de pile)\n");
2036: }
2037: else
2038: {
2039: printf("+++System : Access violation (stack overflow)\n");
2040: }
2041:
2042: fflush(stdout);
2043:
2044: compteur++;
2045:
2046: if (compteur > 1)
2047: {
2048: deverrouillage_gestionnaire_signaux();
2049: exit(EXIT_FAILURE);
2050: }
2051: else
2052: {
2053: deverrouillage_gestionnaire_signaux();
2054: longjmp(contexte_initial, -1);
2055: }
2056: }
2057:
2058: deverrouillage_gestionnaire_signaux();
2059: return;
2060: }
2061:
2062: void
1.30 bertrand 2063: interruption4(SIGHANDLER_ARGS)
1.1 bertrand 2064: {
1.30 bertrand 2065: pid_t pid;
2066:
1.1 bertrand 2067: struct_processus *s_etat_processus;
2068:
1.32 bertrand 2069: verrouillage_gestionnaire_signaux();
2070:
1.29 bertrand 2071: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2072: pid = origine_signal(signal);
2073: # else
2074: pid = (*siginfo).si_pid;
1.29 bertrand 2075: # endif
2076:
1.1 bertrand 2077: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2078: {
2079: deverrouillage_gestionnaire_signaux();
2080: return;
2081: }
2082:
2083: /*
2084: * Démarrage d'un processus fils ou gestion de SIGCONT (SUSPEND)
2085: */
2086:
2087: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2088: {
2089: printf("[%d] SIGSTART/SIGCONT (thread %llu)\n", (int) getpid(),
2090: (unsigned long long) pthread_self());
2091: fflush(stdout);
2092: }
2093:
2094: deverrouillage_gestionnaire_signaux();
2095: return;
2096: }
2097:
2098: void
1.30 bertrand 2099: interruption5(SIGHANDLER_ARGS)
1.1 bertrand 2100: {
1.30 bertrand 2101: pid_t pid;
2102:
1.1 bertrand 2103: pthread_t thread;
1.30 bertrand 2104:
1.1 bertrand 2105: struct_processus *s_etat_processus;
2106:
1.32 bertrand 2107: verrouillage_gestionnaire_signaux();
2108:
1.29 bertrand 2109: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2110: pid = origine_signal(signal);
2111: # else
2112: pid = (*siginfo).si_pid;
1.29 bertrand 2113: # endif
2114:
1.30 bertrand 2115: if (pid == getpid())
1.1 bertrand 2116: {
2117: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2118: == NULL)
2119: {
2120: deverrouillage_gestionnaire_signaux();
2121: return;
2122: }
2123:
2124: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2125: {
1.16 bertrand 2126: printf("[%d] SIGFSTOP (thread %llu)\n", (int) getpid(),
2127: (unsigned long long) pthread_self());
2128: fflush(stdout);
1.1 bertrand 2129: }
2130:
2131: /*
2132: * var_globale_traitement_retarde_stop :
2133: * 0 -> traitement immédiat
2134: * 1 -> traitement retardé (aucun signal reçu)
2135: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2136: */
2137:
1.11 bertrand 2138: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
1.1 bertrand 2139: {
1.11 bertrand 2140: (*s_etat_processus).var_volatile_requete_arret = -1;
1.1 bertrand 2141: }
2142: else
2143: {
1.11 bertrand 2144: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
1.1 bertrand 2145: }
2146: }
2147: else
2148: {
1.11 bertrand 2149: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2150: == NULL)
2151: {
2152: deverrouillage_gestionnaire_signaux();
2153: return;
2154: }
2155:
1.1 bertrand 2156: // Envoi d'un signal au thread maître du groupe.
2157:
2158: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2159: {
1.10 bertrand 2160: pthread_kill(thread, signal);
1.1 bertrand 2161: deverrouillage_gestionnaire_signaux();
2162: return;
2163: }
2164: }
2165:
2166: deverrouillage_gestionnaire_signaux();
2167: return;
2168: }
2169:
2170: void
1.30 bertrand 2171: interruption6(SIGHANDLER_ARGS)
1.1 bertrand 2172: {
1.30 bertrand 2173: pid_t pid;
2174:
1.1 bertrand 2175: struct_processus *s_etat_processus;
2176:
1.32 bertrand 2177: verrouillage_gestionnaire_signaux();
2178:
1.29 bertrand 2179: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2180: pid = origine_signal(signal);
2181: # else
2182: pid = (*siginfo).si_pid;
1.29 bertrand 2183: # endif
2184:
1.1 bertrand 2185: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2186: {
2187: deverrouillage_gestionnaire_signaux();
2188: return;
2189: }
2190:
2191: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2192: {
2193: printf("[%d] SIGINJECT/SIGQUIT (thread %llu)\n", (int) getpid(),
2194: (unsigned long long) pthread_self());
2195: fflush(stdout);
2196: }
2197:
2198: deverrouillage_gestionnaire_signaux();
2199: return;
2200: }
2201:
2202: void
1.30 bertrand 2203: interruption7(SIGHANDLER_ARGS)
1.1 bertrand 2204: {
1.30 bertrand 2205: pid_t pid;
2206:
1.1 bertrand 2207: struct_processus *s_etat_processus;
2208:
1.32 bertrand 2209: verrouillage_gestionnaire_signaux();
2210:
1.29 bertrand 2211: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2212: pid = origine_signal(signal);
2213: # else
2214: pid = (*siginfo).si_pid;
1.29 bertrand 2215: # endif
2216:
1.1 bertrand 2217: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2218: {
2219: deverrouillage_gestionnaire_signaux();
2220: return;
2221: }
2222:
2223: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2224: {
2225: printf("[%d] SIGPIPE (thread %llu)\n", (int) getpid(),
2226: (unsigned long long) pthread_self());
2227: fflush(stdout);
2228: }
2229:
2230: (*s_etat_processus).var_volatile_requete_arret = -1;
2231: deverrouillage_gestionnaire_signaux();
2232:
2233: BUG(1, printf("[%d] SIGPIPE\n", (int) getpid()));
2234: return;
2235: }
2236:
2237: void
1.30 bertrand 2238: interruption8(SIGHANDLER_ARGS)
1.1 bertrand 2239: {
1.30 bertrand 2240: pid_t pid;
2241:
1.1 bertrand 2242: pthread_t thread;
1.30 bertrand 2243:
1.1 bertrand 2244: struct_processus *s_etat_processus;
2245:
1.32 bertrand 2246: verrouillage_gestionnaire_signaux();
2247:
1.29 bertrand 2248: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2249: pid = origine_signal(signal);
2250: # else
2251: pid = (*siginfo).si_pid;
1.29 bertrand 2252: # endif
2253:
1.30 bertrand 2254: if (pid == getpid())
1.1 bertrand 2255: {
2256: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2257: == NULL)
2258: {
2259: deverrouillage_gestionnaire_signaux();
2260: return;
2261: }
2262:
2263: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2264: {
2265: printf("[%d] SIGURG (thread %llu)\n", (int) getpid(),
2266: (unsigned long long) pthread_self());
2267: fflush(stdout);
2268: }
2269:
2270: (*s_etat_processus).var_volatile_alarme = -1;
2271: (*s_etat_processus).var_volatile_requete_arret = -1;
2272: }
2273: else
2274: {
2275: // Envoi d'un signal au thread maître du groupe.
2276:
2277: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2278: {
2279: pthread_kill(thread, SIGURG);
2280: deverrouillage_gestionnaire_signaux();
2281: return;
2282: }
2283: }
2284:
2285: deverrouillage_gestionnaire_signaux();
2286: return;
2287: }
2288:
2289: void
1.30 bertrand 2290: interruption9(SIGHANDLER_ARGS)
1.1 bertrand 2291: {
1.30 bertrand 2292: pid_t pid;
2293:
1.1 bertrand 2294: struct_processus *s_etat_processus;
2295:
1.32 bertrand 2296: verrouillage_gestionnaire_signaux();
2297:
1.29 bertrand 2298: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2299: pid = origine_signal(signal);
2300: # else
2301: pid = (*siginfo).si_pid;
1.29 bertrand 2302: # endif
2303:
1.1 bertrand 2304: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2305: {
2306: deverrouillage_gestionnaire_signaux();
2307: return;
2308: }
2309:
2310: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2311: {
2312: printf("[%d] SIGABORT/SIGPROF (thread %llu)\n", (int) getpid(),
2313: (unsigned long long) pthread_self());
2314: fflush(stdout);
2315: }
2316:
1.30 bertrand 2317: # ifdef _BROKEN_SIGINFO
2318: if (queue_in(getpid(), signal) != 0)
2319: {
2320: return;
2321: }
2322:
1.32 bertrand 2323: deverrouillage_gestionnaire_signaux();
1.30 bertrand 2324: interruption11(signal);
2325: # else
1.32 bertrand 2326: deverrouillage_gestionnaire_signaux();
1.17 bertrand 2327: interruption11(signal, siginfo, context);
1.30 bertrand 2328: # endif
1.1 bertrand 2329: return;
2330: }
2331:
2332: void
1.30 bertrand 2333: interruption10(SIGHANDLER_ARGS)
1.1 bertrand 2334: {
2335: file *fichier;
2336:
1.30 bertrand 2337: pid_t pid;
2338:
1.1 bertrand 2339: struct_processus *s_etat_processus;
2340:
2341: unsigned char nom[8 + 64 + 1];
2342:
1.32 bertrand 2343: verrouillage_gestionnaire_signaux();
2344:
1.29 bertrand 2345: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2346: pid = origine_signal(signal);
2347: # else
2348: pid = (*siginfo).si_pid;
1.29 bertrand 2349: # endif
2350:
1.1 bertrand 2351: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2352: {
2353: deverrouillage_gestionnaire_signaux();
2354: return;
2355: }
2356:
2357: snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
2358: (unsigned long) pthread_self());
2359:
2360: if ((fichier = fopen(nom, "w+")) != NULL)
2361: {
2362: fclose(fichier);
2363:
2364: freopen(nom, "w", stdout);
2365: freopen(nom, "w", stderr);
2366: }
2367:
2368: freopen("/dev/null", "r", stdin);
2369:
2370: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2371: {
2372: printf("[%d] SIGHUP (thread %llu)\n", (int) getpid(),
2373: (unsigned long long) pthread_self());
2374: fflush(stdout);
2375: }
2376:
2377: deverrouillage_gestionnaire_signaux();
2378: return;
2379: }
2380:
2381: void
1.30 bertrand 2382: interruption11(SIGHANDLER_ARGS)
1.16 bertrand 2383: {
1.30 bertrand 2384: pid_t pid;
2385:
1.16 bertrand 2386: pthread_t thread;
1.30 bertrand 2387:
1.16 bertrand 2388: struct_processus *s_etat_processus;
2389:
1.32 bertrand 2390: verrouillage_gestionnaire_signaux();
2391:
1.29 bertrand 2392: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2393: pid = origine_signal(signal);
2394: # else
2395: pid = (*siginfo).si_pid;
1.29 bertrand 2396: # endif
2397:
1.30 bertrand 2398: if (pid == getpid())
1.16 bertrand 2399: {
2400: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2401: == NULL)
2402: {
2403: deverrouillage_gestionnaire_signaux();
2404: return;
2405: }
2406:
2407: (*s_etat_processus).arret_depuis_abort = -1;
2408:
2409: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2410: {
2411: printf("[%d] SIGFABORT (thread %llu)\n", (int) getpid(),
2412: (unsigned long long) pthread_self());
2413: fflush(stdout);
2414: }
2415:
2416: /*
2417: * var_globale_traitement_retarde_stop :
2418: * 0 -> traitement immédiat
2419: * 1 -> traitement retardé (aucun signal reçu)
2420: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2421: */
2422:
2423: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
2424: {
2425: (*s_etat_processus).var_volatile_requete_arret = -1;
2426: }
2427: else
2428: {
2429: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
2430: }
2431: }
2432: else
2433: {
2434: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2435: == NULL)
2436: {
2437: deverrouillage_gestionnaire_signaux();
2438: return;
2439: }
2440:
2441: (*s_etat_processus).arret_depuis_abort = -1;
2442:
2443: // Envoi d'un signal au thread maître du groupe.
2444:
2445: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2446: {
2447: pthread_kill(thread, signal);
2448: deverrouillage_gestionnaire_signaux();
2449: return;
2450: }
2451: }
2452:
2453: deverrouillage_gestionnaire_signaux();
2454: return;
2455: }
2456:
2457: void
1.1 bertrand 2458: traitement_exceptions_gsl(const char *reason, const char *file,
2459: int line, int gsl_errno)
2460: {
2461: struct_processus *s_etat_processus;
2462:
2463: verrouillage_gestionnaire_signaux();
2464:
2465: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2466: {
2467: deverrouillage_gestionnaire_signaux();
2468: return;
2469: }
2470:
2471: (*s_etat_processus).var_volatile_exception_gsl = gsl_errno;
2472: deverrouillage_gestionnaire_signaux();
2473: return;
2474: }
2475:
2476: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>