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