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