1: /*
2: ================================================================================
3: RPL/2 (R) version 4.0.15
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: # ifndef SEMAPHORES_NOMMES
86: while(sem_wait(&semaphore_liste_threads) == -1)
87: # else
88: while(sem_wait(semaphore_liste_threads) == -1)
89: # endif
90: {
91: if (errno != EINTR)
92: {
93: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
94: sigpending(&set);
95:
96: (*s_etat_processus).erreur_systeme = d_es_processus;
97: return;
98: }
99: }
100:
101: if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
102: == NULL)
103: {
104: # ifndef SEMAPHORES_NOMMES
105: sem_post(&semaphore_liste_threads);
106: # else
107: sem_post(semaphore_liste_threads);
108: # endif
109: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
110: sigpending(&set);
111:
112: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
113: return;
114: }
115:
116: (*l_nouvel_objet).suivant = liste_threads;
117:
118: if (((*l_nouvel_objet).donnee = malloc(sizeof(struct_thread))) == NULL)
119: {
120: # ifndef SEMAPHORES_NOMMES
121: sem_post(&semaphore_liste_threads);
122: # else
123: sem_post(semaphore_liste_threads);
124: # endif
125: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
126: sigpending(&set);
127:
128: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
129: return;
130: }
131:
132: (*((struct_thread *) (*l_nouvel_objet).donnee)).pid = getpid();
133: (*((struct_thread *) (*l_nouvel_objet).donnee)).tid = pthread_self();
134: (*((struct_thread *) (*l_nouvel_objet).donnee)).thread_principal =
135: thread_principal;
136: (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus =
137: s_etat_processus;
138:
139: liste_threads = l_nouvel_objet;
140:
141: # ifndef SEMAPHORES_NOMMES
142: if (sem_post(&semaphore_liste_threads) != 0)
143: # else
144: if (sem_post(semaphore_liste_threads) != 0)
145: # endif
146: {
147: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
148: sigpending(&set);
149:
150: (*s_etat_processus).erreur_systeme = d_es_processus;
151: return;
152: }
153:
154: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
155: sigpending(&set);
156: return;
157: }
158:
159: void
160: insertion_thread_surveillance(struct_processus *s_etat_processus,
161: struct_descripteur_thread *s_argument_thread)
162: {
163: sigset_t oldset;
164: sigset_t set;
165:
166: volatile struct_liste_chainee_volatile *l_nouvel_objet;
167:
168: sigfillset(&set);
169: pthread_sigmask(SIG_BLOCK, &set, &oldset);
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: if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
188: == NULL)
189: {
190: # ifndef SEMAPHORES_NOMMES
191: sem_post(&semaphore_liste_threads);
192: # else
193: sem_post(semaphore_liste_threads);
194: # endif
195: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
196: sigpending(&set);
197:
198: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
199: return;
200: }
201:
202: (*l_nouvel_objet).suivant = liste_threads_surveillance;
203: (*l_nouvel_objet).donnee = (void *) s_argument_thread;
204:
205: liste_threads_surveillance = l_nouvel_objet;
206:
207: # ifndef SEMAPHORES_NOMMES
208: if (sem_post(&semaphore_liste_threads) != 0)
209: # else
210: if (sem_post(semaphore_liste_threads) != 0)
211: # endif
212: {
213: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
214: sigpending(&set);
215:
216: (*s_etat_processus).erreur_systeme = d_es_processus;
217: return;
218: }
219:
220: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
221: sigpending(&set);
222: return;
223: }
224:
225: void
226: retrait_thread(struct_processus *s_etat_processus)
227: {
228: sigset_t oldset;
229: sigset_t set;
230:
231: volatile struct_liste_chainee_volatile *l_element_precedent;
232: volatile struct_liste_chainee_volatile *l_element_courant;
233:
234: sigfillset(&set);
235: pthread_sigmask(SIG_BLOCK, &set, &oldset);
236:
237: # ifndef SEMAPHORES_NOMMES
238: while(sem_wait(&semaphore_liste_threads) == -1)
239: # else
240: while(sem_wait(semaphore_liste_threads) == -1)
241: # endif
242: {
243: if (errno != EINTR)
244: {
245: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
246: sigpending(&set);
247:
248: (*s_etat_processus).erreur_systeme = d_es_processus;
249: return;
250: }
251: }
252:
253: l_element_precedent = NULL;
254: l_element_courant = liste_threads;
255:
256: while(l_element_courant != NULL)
257: {
258: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
259: == getpid()) && (pthread_equal((*((struct_thread *)
260: (*l_element_courant).donnee)).tid, pthread_self()) != 0))
261: {
262: break;
263: }
264:
265: l_element_precedent = l_element_courant;
266: l_element_courant = (*l_element_courant).suivant;
267: }
268:
269: if (l_element_courant == NULL)
270: {
271: # ifndef SEMAPHORES_NOMMES
272: sem_post(&semaphore_liste_threads);
273: # else
274: sem_post(semaphore_liste_threads);
275: # endif
276: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
277: sigpending(&set);
278:
279: (*s_etat_processus).erreur_systeme = d_es_processus;
280: return;
281: }
282:
283: if (l_element_precedent == NULL)
284: {
285: liste_threads = (*l_element_courant).suivant;
286: }
287: else
288: {
289: (*l_element_precedent).suivant = (*l_element_courant).suivant;
290: }
291:
292: free((void *) (*l_element_courant).donnee);
293: free((struct_liste_chainee_volatile *) l_element_courant);
294:
295: if (pthread_setspecific(semaphore_fork_processus_courant, NULL) != 0)
296: {
297: (*s_etat_processus).erreur_systeme = d_es_processus;
298:
299: # ifndef SEMAPHORES_NOMMES
300: sem_post(&semaphore_liste_threads);
301: # else
302: sem_post(semaphore_liste_threads);
303: # endif
304: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
305: sigpending(&set);
306: return;
307: }
308:
309: # ifndef SEMAPHORES_NOMMES
310: if (sem_post(&semaphore_liste_threads) != 0)
311: # else
312: if (sem_post(semaphore_liste_threads) != 0)
313: # endif
314: {
315: (*s_etat_processus).erreur_systeme = d_es_processus;
316:
317: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
318: sigpending(&set);
319: return;
320: }
321:
322: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
323: sigpending(&set);
324: return;
325: }
326:
327: void
328: retrait_thread_surveillance(struct_processus *s_etat_processus,
329: struct_descripteur_thread *s_argument_thread)
330: {
331: sigset_t set;
332: sigset_t oldset;
333:
334: volatile struct_liste_chainee_volatile *l_element_precedent;
335: volatile struct_liste_chainee_volatile *l_element_courant;
336:
337: sigfillset(&set);
338: pthread_sigmask(SIG_BLOCK, &set, &oldset);
339:
340: # ifndef SEMAPHORES_NOMMES
341: while(sem_wait(&semaphore_liste_threads) == -1)
342: # else
343: while(sem_wait(semaphore_liste_threads) == -1)
344: # endif
345: {
346: if (errno != EINTR)
347: {
348: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
349: sigpending(&set);
350:
351: (*s_etat_processus).erreur_systeme = d_es_processus;
352: return;
353: }
354: }
355:
356: l_element_precedent = NULL;
357: l_element_courant = liste_threads_surveillance;
358:
359: while(l_element_courant != NULL)
360: {
361: if ((*l_element_courant).donnee == (void *) s_argument_thread)
362: {
363: break;
364: }
365:
366: l_element_precedent = l_element_courant;
367: l_element_courant = (*l_element_courant).suivant;
368: }
369:
370: if (l_element_courant == NULL)
371: {
372: # ifndef SEMAPHORES_NOMMES
373: sem_post(&semaphore_liste_threads);
374: # else
375: sem_post(semaphore_liste_threads);
376: # endif
377: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
378: sigpending(&set);
379:
380: (*s_etat_processus).erreur_systeme = d_es_processus;
381: return;
382: }
383:
384: if (l_element_precedent == NULL)
385: {
386: liste_threads_surveillance = (*l_element_courant).suivant;
387: }
388: else
389: {
390: (*l_element_precedent).suivant = (*l_element_courant).suivant;
391: }
392:
393: free((struct_liste_chainee_volatile *) l_element_courant);
394:
395: if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)
396: {
397: # ifndef SEMAPHORES_NOMMES
398: sem_post(&semaphore_liste_threads);
399: # else
400: sem_post(semaphore_liste_threads);
401: # endif
402: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
403: sigpending(&set);
404:
405: (*s_etat_processus).erreur_systeme = d_es_processus;
406: return;
407: }
408:
409: (*s_argument_thread).nombre_references--;
410:
411: BUG((*s_argument_thread).nombre_references < 0,
412: printf("(*s_argument_thread).nombre_references = %d\n",
413: (int) (*s_argument_thread).nombre_references));
414:
415: if ((*s_argument_thread).nombre_references == 0)
416: {
417: if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
418: {
419: # ifndef SEMAPHORES_NOMMES
420: sem_post(&semaphore_liste_threads);
421: # else
422: sem_post(semaphore_liste_threads);
423: # endif
424: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
425: sigpending(&set);
426:
427: (*s_etat_processus).erreur_systeme = d_es_processus;
428: return;
429: }
430:
431: pthread_mutex_destroy(&((*s_argument_thread).mutex));
432: free(s_argument_thread);
433: }
434: else
435: {
436: if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
437: {
438: # ifndef SEMAPHORES_NOMMES
439: sem_post(&semaphore_liste_threads);
440: # else
441: sem_post(semaphore_liste_threads);
442: # endif
443: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
444: sigpending(&set);
445:
446: (*s_etat_processus).erreur_systeme = d_es_processus;
447: return;
448: }
449: }
450:
451: # ifndef SEMAPHORES_NOMMES
452: if (sem_post(&semaphore_liste_threads) != 0)
453: # else
454: if (sem_post(semaphore_liste_threads) != 0)
455: # endif
456: {
457: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
458: sigpending(&set);
459:
460: (*s_etat_processus).erreur_systeme = d_es_processus;
461: return;
462: }
463:
464: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
465: sigpending(&set);
466: return;
467: }
468:
469: void
470: verrouillage_threads_concurrents(struct_processus *s_etat_processus)
471: {
472: volatile struct_liste_chainee_volatile *l_element_courant;
473:
474: # ifndef SEMAPHORES_NOMMES
475: while(sem_wait(&semaphore_liste_threads) == -1)
476: # else
477: while(sem_wait(semaphore_liste_threads) == -1)
478: # endif
479: {
480: if (errno != EINTR)
481: {
482: (*s_etat_processus).erreur_systeme = d_es_processus;
483: return;
484: }
485: }
486:
487: l_element_courant = liste_threads;
488:
489: while(l_element_courant != NULL)
490: {
491: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
492: == getpid()) && (pthread_equal((*((struct_thread *)
493: (*l_element_courant).donnee)).tid, pthread_self()) == 0))
494: {
495: # ifndef SEMAPHORES_NOMMES
496: while(sem_wait(&((*(*((struct_thread *) (*l_element_courant)
497: .donnee)).s_etat_processus).semaphore_fork)) == -1)
498: # else
499: while(sem_wait((*(*((struct_thread *) (*l_element_courant)
500: .donnee)).s_etat_processus).semaphore_fork) == -1)
501: # endif
502: {
503: if (errno != EINTR)
504: {
505: (*s_etat_processus).erreur_systeme = d_es_processus;
506: return;
507: }
508: }
509: }
510:
511: l_element_courant = (*l_element_courant).suivant;
512: }
513:
514: return;
515: }
516:
517: void
518: deverrouillage_threads_concurrents(struct_processus *s_etat_processus)
519: {
520: volatile struct_liste_chainee_volatile *l_element_courant;
521:
522: l_element_courant = liste_threads;
523:
524: while(l_element_courant != NULL)
525: {
526: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
527: == getpid()) && (pthread_equal((*((struct_thread *)
528: (*l_element_courant).donnee)).tid, pthread_self()) == 0))
529: {
530: # ifndef SEMAPHORES_NOMMES
531: if (sem_post(&((*(*((struct_thread *)
532: (*l_element_courant).donnee)).s_etat_processus)
533: .semaphore_fork)) != 0)
534: # else
535: if (sem_post((*(*((struct_thread *)
536: (*l_element_courant).donnee)).s_etat_processus)
537: .semaphore_fork) != 0)
538: # endif
539: {
540: # ifndef SEMAPHORES_NOMMES
541: if (sem_post(&semaphore_liste_threads) != 0)
542: {
543: (*s_etat_processus).erreur_systeme = d_es_processus;
544: return;
545: }
546: # else
547: if (sem_post(semaphore_liste_threads) != 0)
548: {
549: (*s_etat_processus).erreur_systeme = d_es_processus;
550: return;
551: }
552: # endif
553:
554: (*s_etat_processus).erreur_systeme = d_es_processus;
555: return;
556: }
557: }
558:
559: l_element_courant = (*l_element_courant).suivant;
560: }
561:
562: # ifndef SEMAPHORES_NOMMES
563: if (sem_post(&semaphore_liste_threads) != 0)
564: # else
565: if (sem_post(semaphore_liste_threads) != 0)
566: # endif
567: {
568: (*s_etat_processus).erreur_systeme = d_es_processus;
569: return;
570: }
571:
572: return;
573: }
574:
575: void
576: liberation_threads(struct_processus *s_etat_processus)
577: {
578: logical1 suppression_variables_partagees;
579:
580: sigset_t oldset;
581: sigset_t set;
582:
583: struct_descripteur_thread *s_argument_thread;
584:
585: struct_processus *candidat;
586:
587: unsigned long i;
588:
589: void *element_candidat;
590: void *element_courant;
591: void *element_suivant;
592:
593: volatile struct_liste_chainee_volatile *l_element_courant;
594: volatile struct_liste_chainee_volatile *l_element_suivant;
595:
596: sigfillset(&set);
597: pthread_sigmask(SIG_BLOCK, &set, &oldset);
598:
599: # ifndef SEMAPHORES_NOMMES
600: while(sem_wait(&semaphore_liste_threads) == -1)
601: # else
602: while(sem_wait(semaphore_liste_threads) == -1)
603: # endif
604: {
605: if (errno != EINTR)
606: {
607: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
608: (*s_etat_processus).erreur_systeme = d_es_processus;
609: return;
610: }
611: }
612:
613: l_element_courant = liste_threads;
614: suppression_variables_partagees = d_faux;
615:
616: while(l_element_courant != NULL)
617: {
618: if ((*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus
619: != s_etat_processus)
620: {
621: candidat = s_etat_processus;
622: s_etat_processus = (*((struct_thread *)
623: (*l_element_courant).donnee)).s_etat_processus;
624: free((*s_etat_processus).localisation);
625:
626: // (*s_etat_processus).instruction_courante peut pointer sur
627: // n'importe quoi (une instruction courante ou un champ d'une
628: // structure objet). On ne le libère pas quitte à avoir une
629: // petite fuite mémoire dans le processus fils.
630:
631: if ((*s_etat_processus).instruction_courante != NULL)
632: {
633: //free((*s_etat_processus).instruction_courante);
634: }
635:
636: close((*s_etat_processus).pipe_acquittement);
637: close((*s_etat_processus).pipe_donnees);
638: close((*s_etat_processus).pipe_injections);
639: close((*s_etat_processus).pipe_nombre_injections);
640: close((*s_etat_processus).pipe_interruptions);
641: close((*s_etat_processus).pipe_nombre_objets_attente);
642: close((*s_etat_processus).pipe_nombre_interruptions_attente);
643:
644: if ((*s_etat_processus).nom_fichier_impression != NULL)
645: {
646: free((*s_etat_processus).nom_fichier_impression);
647: }
648:
649: while((*s_etat_processus).fichiers_graphiques != NULL)
650: {
651: free((*(*s_etat_processus).fichiers_graphiques).nom);
652:
653: if ((*(*s_etat_processus).fichiers_graphiques).legende != NULL)
654: {
655: free((*(*s_etat_processus).fichiers_graphiques).legende);
656: }
657:
658: element_courant = (*s_etat_processus).fichiers_graphiques;
659: (*s_etat_processus).fichiers_graphiques =
660: (*(*s_etat_processus).fichiers_graphiques).suivant;
661:
662: free(element_courant);
663: }
664:
665: if ((*s_etat_processus).entree_standard != NULL)
666: {
667: pclose((*s_etat_processus).entree_standard);
668: }
669:
670: if ((*s_etat_processus).generateur_aleatoire != NULL)
671: {
672: liberation_generateur_aleatoire(s_etat_processus);
673: }
674:
675: if ((*s_etat_processus).instruction_derniere_erreur != NULL)
676: {
677: free((*s_etat_processus).instruction_derniere_erreur);
678: (*s_etat_processus).instruction_derniere_erreur = NULL;
679: }
680:
681: element_courant = (void *) (*s_etat_processus)
682: .l_base_pile_processus;
683: while(element_courant != NULL)
684: {
685: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
686: element_courant)).donnee).mutex));
687: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
688: element_courant)).donnee).mutex));
689: liberation(s_etat_processus,
690: (*((struct_liste_chainee *) element_courant)).donnee);
691: element_suivant = (*((struct_liste_chainee *) element_courant))
692: .suivant;
693: free((struct_liste_chainee *) element_courant);
694: element_courant = element_suivant;
695: }
696:
697: pthread_mutex_trylock(&((*(*s_etat_processus).indep).mutex));
698: pthread_mutex_unlock(&((*(*s_etat_processus).indep).mutex));
699: liberation(s_etat_processus, (*s_etat_processus).indep);
700:
701: pthread_mutex_trylock(&((*(*s_etat_processus).depend).mutex));
702: pthread_mutex_unlock(&((*(*s_etat_processus).depend).mutex));
703: liberation(s_etat_processus, (*s_etat_processus).depend);
704:
705: free((*s_etat_processus).label_x);
706: free((*s_etat_processus).label_y);
707: free((*s_etat_processus).label_z);
708: free((*s_etat_processus).titre);
709: free((*s_etat_processus).legende);
710:
711: pthread_mutex_trylock(&((*(*s_etat_processus)
712: .parametres_courbes_de_niveau).mutex));
713: pthread_mutex_unlock(&((*(*s_etat_processus)
714: .parametres_courbes_de_niveau).mutex));
715: liberation(s_etat_processus, (*s_etat_processus)
716: .parametres_courbes_de_niveau);
717:
718: for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++)
719: {
720: if ((*s_etat_processus).corps_interruptions[i] != NULL)
721: {
722: pthread_mutex_trylock(&((*(*s_etat_processus)
723: .corps_interruptions[i]).mutex));
724: pthread_mutex_unlock(&((*(*s_etat_processus)
725: .corps_interruptions[i]).mutex));
726:
727: liberation(s_etat_processus,
728: (*s_etat_processus).corps_interruptions[i]);
729: }
730:
731: element_courant = (*s_etat_processus)
732: .pile_origine_interruptions[i];
733:
734: while(element_courant != NULL)
735: {
736: element_suivant = (*((struct_liste_chainee *)
737: element_courant)).suivant;
738:
739: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
740: element_courant)).donnee).mutex));
741: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
742: element_courant)).donnee).mutex));
743:
744: liberation(s_etat_processus,
745: (*((struct_liste_chainee *) element_courant))
746: .donnee);
747: free(element_courant);
748:
749: element_courant = element_suivant;
750: }
751: }
752:
753: for(i = 0; i < (*s_etat_processus).nombre_variables; i++)
754: {
755: pthread_mutex_trylock(&((*(*s_etat_processus)
756: .s_liste_variables[i].objet).mutex));
757: pthread_mutex_unlock(&((*(*s_etat_processus)
758: .s_liste_variables[i].objet).mutex));
759:
760: // Les variables de niveau 0 sont des définitions qui
761: // ne sont pas copiées entre threads.
762: if ((*s_etat_processus).s_liste_variables[i].niveau > 0)
763: {
764: liberation(s_etat_processus,
765: (*s_etat_processus).s_liste_variables[i].objet);
766: }
767:
768: free((*s_etat_processus).s_liste_variables[i].nom);
769: }
770:
771: free((*s_etat_processus).s_liste_variables);
772:
773: for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)
774: {
775: pthread_mutex_trylock(&((*(*s_etat_processus)
776: .s_liste_variables_statiques[i].objet).mutex));
777: pthread_mutex_unlock(&((*(*s_etat_processus)
778: .s_liste_variables_statiques[i].objet).mutex));
779:
780: liberation(s_etat_processus, (*s_etat_processus)
781: .s_liste_variables_statiques[i].objet);
782: free((*s_etat_processus).s_liste_variables_statiques[i].nom);
783: }
784:
785: free((*s_etat_processus).s_liste_variables_statiques);
786:
787: // Ne peut être effacé qu'une seule fois
788: if (suppression_variables_partagees == d_faux)
789: {
790: suppression_variables_partagees = d_vrai;
791:
792: for(i = 0; i < (*(*s_etat_processus)
793: .s_liste_variables_partagees).nombre_variables; i++)
794: {
795: pthread_mutex_trylock(&((*(*(*s_etat_processus)
796: .s_liste_variables_partagees).table[i].objet)
797: .mutex));
798: pthread_mutex_unlock(&((*(*(*s_etat_processus)
799: .s_liste_variables_partagees).table[i].objet)
800: .mutex));
801:
802: liberation(s_etat_processus, (*(*s_etat_processus)
803: .s_liste_variables_partagees).table[i].objet);
804: free((*(*s_etat_processus).s_liste_variables_partagees)
805: .table[i].nom);
806: }
807:
808: if ((*(*s_etat_processus).s_liste_variables_partagees).table
809: != NULL)
810: {
811: free((struct_variable_partagee *) (*(*s_etat_processus)
812: .s_liste_variables_partagees).table);
813: }
814:
815: pthread_mutex_trylock(&((*(*s_etat_processus)
816: .s_liste_variables_partagees).mutex));
817: pthread_mutex_unlock(&((*(*s_etat_processus)
818: .s_liste_variables_partagees).mutex));
819: }
820:
821: element_courant = (*s_etat_processus).l_base_pile;
822: while(element_courant != NULL)
823: {
824: element_suivant = (*((struct_liste_chainee *)
825: element_courant)).suivant;
826:
827: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
828: element_courant)).donnee).mutex));
829: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
830: element_courant)).donnee).mutex));
831:
832: liberation(s_etat_processus,
833: (*((struct_liste_chainee *)
834: element_courant)).donnee);
835: free((struct_liste_chainee *) element_courant);
836:
837: element_courant = element_suivant;
838: }
839:
840: element_courant = (*s_etat_processus).l_base_pile_contextes;
841: while(element_courant != NULL)
842: {
843: element_suivant = (*((struct_liste_chainee *)
844: element_courant)).suivant;
845:
846: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
847: element_courant)).donnee).mutex));
848: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
849: element_courant)).donnee).mutex));
850: liberation(s_etat_processus, (*((struct_liste_chainee *)
851: element_courant)).donnee);
852: free((struct_liste_chainee *) element_courant);
853:
854: element_courant = element_suivant;
855: }
856:
857: element_courant = (*s_etat_processus).l_base_pile_taille_contextes;
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: liberation(s_etat_processus,
868: (*((struct_liste_chainee *)
869: element_courant)).donnee);
870: free((struct_liste_chainee *) element_courant);
871:
872: element_courant = element_suivant;
873: }
874:
875: for(i = 0; i < (*s_etat_processus).nombre_instructions_externes;
876: i++)
877: {
878: free((*s_etat_processus).s_instructions_externes[i].nom);
879: free((*s_etat_processus).s_instructions_externes[i]
880: .nom_bibliotheque);
881: }
882:
883: if ((*s_etat_processus).nombre_instructions_externes != 0)
884: {
885: free((*s_etat_processus).s_instructions_externes);
886: }
887:
888: element_courant = (*s_etat_processus).s_bibliotheques;
889: while(element_courant != NULL)
890: {
891: element_suivant = (*((struct_liste_chainee *)
892: element_courant)).suivant;
893:
894: element_candidat = (*candidat).s_bibliotheques;
895: while(element_candidat != NULL)
896: {
897: if (((*((struct_bibliotheque *) (*((struct_liste_chainee *)
898: element_courant)).donnee))
899: .descripteur == (*((struct_bibliotheque *)
900: (*((struct_liste_chainee *) element_candidat))
901: .donnee)).descripteur) &&
902: ((*((struct_bibliotheque *)
903: (*((struct_liste_chainee *) element_courant))
904: .donnee)).pid == (*((struct_bibliotheque *)
905: (*((struct_liste_chainee *) element_candidat))
906: .donnee)).pid) && (pthread_equal(
907: (*((struct_bibliotheque *)
908: (*((struct_liste_chainee *) element_courant))
909: .donnee)).tid, (*((struct_bibliotheque *)
910: (*((struct_liste_chainee *) element_candidat))
911: .donnee)).tid) != 0))
912: {
913: break;
914: }
915:
916: element_candidat = (*((struct_liste_chainee *)
917: element_candidat)).suivant;
918: }
919:
920: if (element_candidat == NULL)
921: {
922: dlclose((*((struct_bibliotheque *)
923: (*((struct_liste_chainee *) element_courant))
924: .donnee)).descripteur);
925: }
926:
927: free((*((struct_bibliotheque *)
928: (*((struct_liste_chainee *)
929: element_courant)).donnee)).nom);
930: free((*((struct_liste_chainee *) element_courant)).donnee);
931: free(element_courant);
932:
933: element_courant = element_suivant;
934: }
935:
936: element_courant = (*s_etat_processus).l_base_pile_last;
937: while(element_courant != NULL)
938: {
939: element_suivant = (*((struct_liste_chainee *)
940: element_courant)).suivant;
941:
942: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
943: element_courant)).donnee).mutex));
944: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
945: element_courant)).donnee).mutex));
946: liberation(s_etat_processus,
947: (*((struct_liste_chainee *) element_courant)).donnee);
948: free(element_courant);
949:
950: element_courant = element_suivant;
951: }
952:
953: element_courant = (*s_etat_processus).l_base_pile_systeme;
954: while(element_courant != NULL)
955: {
956: element_suivant = (*((struct_liste_pile_systeme *)
957: element_courant)).suivant;
958:
959: if ((*((struct_liste_pile_systeme *)
960: element_courant)).indice_boucle != NULL)
961: {
962: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
963: element_courant)).indice_boucle).mutex));
964: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
965: element_courant)).indice_boucle).mutex));
966: }
967:
968: liberation(s_etat_processus,
969: (*((struct_liste_pile_systeme *)
970: element_courant)).indice_boucle);
971:
972: if ((*((struct_liste_pile_systeme *)
973: element_courant)).limite_indice_boucle != NULL)
974: {
975: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
976: element_courant)).limite_indice_boucle).mutex));
977: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
978: element_courant)).limite_indice_boucle).mutex));
979: }
980:
981: liberation(s_etat_processus,
982: (*((struct_liste_pile_systeme *)
983: element_courant)).limite_indice_boucle);
984:
985: if ((*((struct_liste_pile_systeme *)
986: element_courant)).objet_de_test != NULL)
987: {
988: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
989: element_courant)).objet_de_test).mutex));
990: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
991: element_courant)).objet_de_test).mutex));
992: }
993:
994: liberation(s_etat_processus,
995: (*((struct_liste_pile_systeme *)
996: element_courant)).objet_de_test);
997:
998: if ((*((struct_liste_pile_systeme *)
999: element_courant)).nom_variable != NULL)
1000: {
1001: free((*((struct_liste_pile_systeme *)
1002: element_courant)).nom_variable);
1003: }
1004:
1005: free(element_courant);
1006:
1007: element_courant = element_suivant;
1008: }
1009:
1010: element_courant = (*s_etat_processus).s_fichiers;
1011: while(element_courant != NULL)
1012: {
1013: element_suivant = (*((struct_liste_chainee *)
1014: element_courant)).suivant;
1015:
1016: element_candidat = (*candidat).s_fichiers;
1017: while(element_candidat != NULL)
1018: {
1019: if (((*((struct_descripteur_fichier *)
1020: (*((struct_liste_chainee *) element_courant))
1021: .donnee)).pid ==
1022: (*((struct_descripteur_fichier *)
1023: (*((struct_liste_chainee *) element_candidat))
1024: .donnee)).pid) && (pthread_equal(
1025: (*((struct_descripteur_fichier *)
1026: (*((struct_liste_chainee *) element_courant))
1027: .donnee)).tid, (*((struct_descripteur_fichier *)
1028: (*((struct_liste_chainee *) element_candidat))
1029: .donnee)).tid) != 0))
1030: {
1031: if ((*((struct_descripteur_fichier *)
1032: (*((struct_liste_chainee *) element_courant))
1033: .donnee)).type ==
1034: (*((struct_descripteur_fichier *)
1035: (*((struct_liste_chainee *) element_candidat))
1036: .donnee)).type)
1037: {
1038: if ((*((struct_descripteur_fichier *)
1039: (*((struct_liste_chainee *)
1040: element_candidat)).donnee)).type == 'C')
1041: {
1042: if ((*((struct_descripteur_fichier *)
1043: (*((struct_liste_chainee *)
1044: element_courant)).donnee))
1045: .descripteur_c ==
1046: (*((struct_descripteur_fichier *)
1047: (*((struct_liste_chainee *)
1048: element_candidat)).donnee))
1049: .descripteur_c)
1050: {
1051: break;
1052: }
1053: }
1054: else
1055: {
1056: if (((*((struct_descripteur_fichier *)
1057: (*((struct_liste_chainee *)
1058: element_courant)).donnee))
1059: .descripteur_sqlite ==
1060: (*((struct_descripteur_fichier *)
1061: (*((struct_liste_chainee *)
1062: element_candidat)).donnee))
1063: .descripteur_sqlite) &&
1064: ((*((struct_descripteur_fichier *)
1065: (*((struct_liste_chainee *)
1066: element_courant)).donnee))
1067: .descripteur_c ==
1068: (*((struct_descripteur_fichier *)
1069: (*((struct_liste_chainee *)
1070: element_candidat)).donnee))
1071: .descripteur_c))
1072: {
1073: break;
1074: }
1075: }
1076: }
1077: }
1078:
1079: element_candidat = (*((struct_liste_chainee *)
1080: element_candidat)).suivant;
1081: }
1082:
1083: if (element_candidat == NULL)
1084: {
1085: fclose((*((struct_descripteur_fichier *)
1086: (*((struct_liste_chainee *) element_courant))
1087: .donnee)).descripteur_c);
1088:
1089: if ((*((struct_descripteur_fichier *)
1090: (*((struct_liste_chainee *) element_courant))
1091: .donnee)).type != 'C')
1092: {
1093: sqlite3_close((*((struct_descripteur_fichier *)
1094: (*((struct_liste_chainee *) element_courant))
1095: .donnee)).descripteur_sqlite);
1096: }
1097: }
1098:
1099: free((*((struct_descripteur_fichier *)
1100: (*((struct_liste_chainee *)
1101: element_courant)).donnee)).nom);
1102: free((struct_descripteur_fichier *)
1103: (*((struct_liste_chainee *)
1104: element_courant)).donnee);
1105: free(element_courant);
1106:
1107: element_courant = element_suivant;
1108: }
1109:
1110: element_courant = (*s_etat_processus).s_sockets;
1111: while(element_courant != NULL)
1112: {
1113: element_suivant = (*((struct_liste_chainee *)
1114: element_courant)).suivant;
1115:
1116: element_candidat = (*candidat).s_sockets;
1117: while(element_candidat != NULL)
1118: {
1119: if (((*((struct_socket *)
1120: (*((struct_liste_chainee *) element_courant))
1121: .donnee)).socket == (*((struct_socket *)
1122: (*((struct_liste_chainee *) element_candidat))
1123: .donnee)).socket) &&
1124: ((*((struct_socket *)
1125: (*((struct_liste_chainee *) element_courant))
1126: .donnee)).pid == (*((struct_socket *)
1127: (*((struct_liste_chainee *) element_candidat))
1128: .donnee)).pid) && (pthread_equal(
1129: (*((struct_socket *)
1130: (*((struct_liste_chainee *) element_courant))
1131: .donnee)).tid, (*((struct_socket *)
1132: (*((struct_liste_chainee *) element_candidat))
1133: .donnee)).tid) != 0))
1134: {
1135: break;
1136: }
1137:
1138: element_candidat = (*((struct_liste_chainee *)
1139: element_candidat)).suivant;
1140: }
1141:
1142: if (element_candidat == NULL)
1143: {
1144: if ((*((struct_socket *) (*((struct_liste_chainee *)
1145: element_courant)).donnee)).socket_connectee
1146: == d_vrai)
1147: {
1148: shutdown((*((struct_socket *)
1149: (*((struct_liste_chainee *) element_courant))
1150: .donnee)).socket, SHUT_RDWR);
1151: }
1152:
1153: close((*((struct_socket *)
1154: (*((struct_liste_chainee *) element_courant))
1155: .donnee)).socket);
1156: }
1157:
1158: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1159: element_courant)).donnee).mutex));
1160: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1161: element_courant)).donnee).mutex));
1162:
1163: liberation(s_etat_processus,
1164: (*((struct_liste_chainee *)
1165: element_courant)).donnee);
1166: free(element_courant);
1167:
1168: element_courant = element_suivant;
1169: }
1170:
1171: element_courant = (*s_etat_processus).s_connecteurs_sql;
1172: while(element_courant != NULL)
1173: {
1174: element_suivant = (*((struct_liste_chainee *)
1175: element_courant)).suivant;
1176:
1177: element_candidat = (*candidat).s_connecteurs_sql;
1178: while(element_candidat != NULL)
1179: {
1180: if (((
1181: #ifdef MYSQL_SUPPORT
1182: ((*((struct_connecteur_sql *)
1183: (*((struct_liste_chainee *) element_courant))
1184: .donnee)).descripteur.mysql ==
1185: (*((struct_connecteur_sql *)
1186: (*((struct_liste_chainee *) element_candidat))
1187: .donnee)).descripteur.mysql)
1188: &&
1189: (strcmp((*((struct_connecteur_sql *)
1190: (*((struct_liste_chainee *) element_courant))
1191: .donnee)).type, "MYSQL") == 0)
1192: &&
1193: (strcmp((*((struct_connecteur_sql *)
1194: (*((struct_liste_chainee *) element_candidat))
1195: .donnee)).type, "MYSQL") == 0)
1196: #else
1197: 0
1198: #endif
1199: ) || (
1200: #ifdef POSTGRESQL_SUPPORT
1201: ((*((struct_connecteur_sql *)
1202: (*((struct_liste_chainee *) element_courant))
1203: .donnee)).descripteur.postgresql ==
1204: (*((struct_connecteur_sql *)
1205: (*((struct_liste_chainee *) element_candidat))
1206: .donnee)).descripteur.postgresql)
1207: &&
1208: (strcmp((*((struct_connecteur_sql *)
1209: (*((struct_liste_chainee *) element_courant))
1210: .donnee)).type, "POSTGRESQL") == 0)
1211: &&
1212: (strcmp((*((struct_connecteur_sql *)
1213: (*((struct_liste_chainee *) element_candidat))
1214: .donnee)).type, "POSTGRESQL") == 0)
1215: #else
1216: 0
1217: #endif
1218: )) &&
1219: ((*((struct_connecteur_sql *)
1220: (*((struct_liste_chainee *) element_courant))
1221: .donnee)).pid == (*((struct_connecteur_sql *)
1222: (*((struct_liste_chainee *) element_candidat))
1223: .donnee)).pid) && (pthread_equal(
1224: (*((struct_connecteur_sql *)
1225: (*((struct_liste_chainee *) element_courant))
1226: .donnee)).tid, (*((struct_connecteur_sql *)
1227: (*((struct_liste_chainee *) element_candidat))
1228: .donnee)).tid) != 0))
1229: {
1230: break;
1231: }
1232:
1233: element_candidat = (*((struct_liste_chainee *)
1234: element_candidat)).suivant;
1235: }
1236:
1237: if (element_candidat == NULL)
1238: {
1239: sqlclose((*((struct_liste_chainee *) element_courant))
1240: .donnee);
1241: }
1242:
1243: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1244: element_courant)).donnee).mutex));
1245: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1246: element_courant)).donnee).mutex));
1247:
1248: liberation(s_etat_processus, (*((struct_liste_chainee *)
1249: element_courant)).donnee);
1250: free(element_courant);
1251:
1252: element_courant = element_suivant;
1253: }
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 de 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 (signal == SIGFABORT)
1979: {
1980: (*s_etat_processus).arret_depuis_abort = -1;
1981: }
1982:
1983: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1984: {
1985: if (signal == SIGFSTOP)
1986: {
1987: printf("[%d] SIGFSTOP (thread %llu)\n", (int) getpid(),
1988: (unsigned long long) pthread_self());
1989: fflush(stdout);
1990: }
1991: else
1992: {
1993: printf("[%d] SIGFABORT (thread %llu)\n", (int) getpid(),
1994: (unsigned long long) pthread_self());
1995: fflush(stdout);
1996: }
1997: }
1998:
1999: /*
2000: * var_globale_traitement_retarde_stop :
2001: * 0 -> traitement immédiat
2002: * 1 -> traitement retardé (aucun signal reçu)
2003: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2004: */
2005:
2006: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
2007: {
2008: (*s_etat_processus).var_volatile_requete_arret = -1;
2009: }
2010: else
2011: {
2012: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
2013: }
2014: }
2015: else
2016: {
2017: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2018: == NULL)
2019: {
2020: deverrouillage_gestionnaire_signaux();
2021: return;
2022: }
2023:
2024: if (signal == SIGFABORT)
2025: {
2026: (*s_etat_processus).arret_depuis_abort = -1;
2027: }
2028:
2029: // Envoi d'un signal au thread maître du groupe.
2030:
2031: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2032: {
2033: pthread_kill(thread, signal);
2034: deverrouillage_gestionnaire_signaux();
2035: return;
2036: }
2037: }
2038:
2039: deverrouillage_gestionnaire_signaux();
2040: return;
2041: }
2042:
2043: void
2044: interruption6(int signal, siginfo_t *siginfo, void *context)
2045: {
2046: struct_processus *s_etat_processus;
2047:
2048: verrouillage_gestionnaire_signaux();
2049:
2050: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2051: {
2052: deverrouillage_gestionnaire_signaux();
2053: return;
2054: }
2055:
2056: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2057: {
2058: printf("[%d] SIGINJECT/SIGQUIT (thread %llu)\n", (int) getpid(),
2059: (unsigned long long) pthread_self());
2060: fflush(stdout);
2061: }
2062:
2063: deverrouillage_gestionnaire_signaux();
2064: return;
2065: }
2066:
2067: void
2068: interruption7(int signal, siginfo_t *siginfo, void *context)
2069: {
2070: struct_processus *s_etat_processus;
2071:
2072: verrouillage_gestionnaire_signaux();
2073:
2074: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2075: {
2076: deverrouillage_gestionnaire_signaux();
2077: return;
2078: }
2079:
2080: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2081: {
2082: printf("[%d] SIGPIPE (thread %llu)\n", (int) getpid(),
2083: (unsigned long long) pthread_self());
2084: fflush(stdout);
2085: }
2086:
2087: (*s_etat_processus).var_volatile_requete_arret = -1;
2088: deverrouillage_gestionnaire_signaux();
2089:
2090: BUG(1, printf("[%d] SIGPIPE\n", (int) getpid()));
2091: return;
2092: }
2093:
2094: void
2095: interruption8(int signal, siginfo_t *siginfo, void *context)
2096: {
2097: pthread_t thread;
2098: struct_processus *s_etat_processus;
2099:
2100: verrouillage_gestionnaire_signaux();
2101:
2102: if ((*siginfo).si_pid == getpid())
2103: {
2104: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2105: == NULL)
2106: {
2107: deverrouillage_gestionnaire_signaux();
2108: return;
2109: }
2110:
2111: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2112: {
2113: printf("[%d] SIGURG (thread %llu)\n", (int) getpid(),
2114: (unsigned long long) pthread_self());
2115: fflush(stdout);
2116: }
2117:
2118: (*s_etat_processus).var_volatile_alarme = -1;
2119: (*s_etat_processus).var_volatile_requete_arret = -1;
2120: }
2121: else
2122: {
2123: // Envoi d'un signal au thread maître du groupe.
2124:
2125: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2126: {
2127: pthread_kill(thread, SIGURG);
2128: deverrouillage_gestionnaire_signaux();
2129: return;
2130: }
2131: }
2132:
2133: deverrouillage_gestionnaire_signaux();
2134: return;
2135: }
2136:
2137: void
2138: interruption9(int signal, siginfo_t *siginfo, void *context)
2139: {
2140: struct_processus *s_etat_processus;
2141:
2142: verrouillage_gestionnaire_signaux();
2143:
2144: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2145: {
2146: deverrouillage_gestionnaire_signaux();
2147: return;
2148: }
2149:
2150: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2151: {
2152: printf("[%d] SIGABORT/SIGPROF (thread %llu)\n", (int) getpid(),
2153: (unsigned long long) pthread_self());
2154: fflush(stdout);
2155: }
2156:
2157: pthread_kill((*s_etat_processus).tid_processus_pere, SIGFABORT);
2158: deverrouillage_gestionnaire_signaux();
2159: return;
2160: }
2161:
2162: void
2163: interruption10(int signal, siginfo_t *siginfo, void *context)
2164: {
2165: file *fichier;
2166:
2167: struct_processus *s_etat_processus;
2168:
2169: unsigned char nom[8 + 64 + 1];
2170:
2171: verrouillage_gestionnaire_signaux();
2172:
2173: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2174: {
2175: deverrouillage_gestionnaire_signaux();
2176: return;
2177: }
2178:
2179: snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
2180: (unsigned long) pthread_self());
2181:
2182: if ((fichier = fopen(nom, "w+")) != NULL)
2183: {
2184: fclose(fichier);
2185:
2186: freopen(nom, "w", stdout);
2187: freopen(nom, "w", stderr);
2188: }
2189:
2190: freopen("/dev/null", "r", stdin);
2191:
2192: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2193: {
2194: printf("[%d] SIGHUP (thread %llu)\n", (int) getpid(),
2195: (unsigned long long) pthread_self());
2196: fflush(stdout);
2197: }
2198:
2199: deverrouillage_gestionnaire_signaux();
2200: return;
2201: }
2202:
2203: void
2204: traitement_exceptions_gsl(const char *reason, const char *file,
2205: int line, int gsl_errno)
2206: {
2207: struct_processus *s_etat_processus;
2208:
2209: verrouillage_gestionnaire_signaux();
2210:
2211: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2212: {
2213: deverrouillage_gestionnaire_signaux();
2214: return;
2215: }
2216:
2217: (*s_etat_processus).var_volatile_exception_gsl = gsl_errno;
2218: deverrouillage_gestionnaire_signaux();
2219: return;
2220: }
2221:
2222: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>