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