1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.3
4: Copyright (C) 1989-2011 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: liste_threads = l_nouvel_objet;
129:
130: # ifndef SEMAPHORES_NOMMES
131: if (sem_post(&semaphore_liste_threads) != 0)
132: # else
133: if (sem_post(semaphore_liste_threads) != 0)
134: # endif
135: {
136: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
137: sigpending(&set);
138:
139: (*s_etat_processus).erreur_systeme = d_es_processus;
140: return;
141: }
142:
143: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
144: sigpending(&set);
145: return;
146: }
147:
148: void
149: insertion_thread_surveillance(struct_processus *s_etat_processus,
150: struct_descripteur_thread *s_argument_thread)
151: {
152: sigset_t oldset;
153: sigset_t set;
154:
155: volatile struct_liste_chainee_volatile *l_nouvel_objet;
156:
157: sigfillset(&set);
158: pthread_sigmask(SIG_BLOCK, &set, &oldset);
159:
160: if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
161: == NULL)
162: {
163: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
164: sigpending(&set);
165:
166: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
167: return;
168: }
169:
170: # ifndef SEMAPHORES_NOMMES
171: while(sem_wait(&semaphore_liste_threads) == -1)
172: # else
173: while(sem_wait(semaphore_liste_threads) == -1)
174: # endif
175: {
176: if (errno != EINTR)
177: {
178: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
179: sigpending(&set);
180:
181: (*s_etat_processus).erreur_systeme = d_es_processus;
182: return;
183: }
184: }
185:
186: pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references));
187: (*s_argument_thread).nombre_references++;
188: pthread_mutex_unlock(&((*s_argument_thread).mutex_nombre_references));
189:
190: (*l_nouvel_objet).suivant = liste_threads_surveillance;
191: (*l_nouvel_objet).donnee = (void *) s_argument_thread;
192:
193: liste_threads_surveillance = l_nouvel_objet;
194:
195: # ifndef SEMAPHORES_NOMMES
196: if (sem_post(&semaphore_liste_threads) != 0)
197: # else
198: if (sem_post(semaphore_liste_threads) != 0)
199: # endif
200: {
201: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
202: sigpending(&set);
203:
204: (*s_etat_processus).erreur_systeme = d_es_processus;
205: return;
206: }
207:
208: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
209: sigpending(&set);
210: return;
211: }
212:
213: void
214: retrait_thread(struct_processus *s_etat_processus)
215: {
216: sigset_t oldset;
217: sigset_t set;
218:
219: volatile struct_liste_chainee_volatile *l_element_precedent;
220: volatile struct_liste_chainee_volatile *l_element_courant;
221:
222: sigfillset(&set);
223: pthread_sigmask(SIG_BLOCK, &set, &oldset);
224:
225: # ifndef SEMAPHORES_NOMMES
226: while(sem_wait(&semaphore_liste_threads) == -1)
227: # else
228: while(sem_wait(semaphore_liste_threads) == -1)
229: # endif
230: {
231: if (errno != EINTR)
232: {
233: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
234: sigpending(&set);
235:
236: (*s_etat_processus).erreur_systeme = d_es_processus;
237: return;
238: }
239: }
240:
241: l_element_precedent = NULL;
242: l_element_courant = liste_threads;
243:
244: while(l_element_courant != NULL)
245: {
246: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
247: == getpid()) && (pthread_equal((*((struct_thread *)
248: (*l_element_courant).donnee)).tid, pthread_self()) != 0))
249: {
250: break;
251: }
252:
253: l_element_precedent = l_element_courant;
254: l_element_courant = (*l_element_courant).suivant;
255: }
256:
257: if (l_element_courant == NULL)
258: {
259: # ifndef SEMAPHORES_NOMMES
260: sem_post(&semaphore_liste_threads);
261: # else
262: sem_post(semaphore_liste_threads);
263: # endif
264: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
265: sigpending(&set);
266:
267: (*s_etat_processus).erreur_systeme = d_es_processus;
268: return;
269: }
270:
271: if (l_element_precedent == NULL)
272: {
273: liste_threads = (*l_element_courant).suivant;
274: }
275: else
276: {
277: (*l_element_precedent).suivant = (*l_element_courant).suivant;
278: }
279:
280: if (pthread_setspecific(semaphore_fork_processus_courant, NULL) != 0)
281: {
282: (*s_etat_processus).erreur_systeme = d_es_processus;
283:
284: # ifndef SEMAPHORES_NOMMES
285: sem_post(&semaphore_liste_threads);
286: # else
287: sem_post(semaphore_liste_threads);
288: # endif
289: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
290: sigpending(&set);
291: return;
292: }
293:
294: # ifndef SEMAPHORES_NOMMES
295: if (sem_post(&semaphore_liste_threads) != 0)
296: # else
297: if (sem_post(semaphore_liste_threads) != 0)
298: # endif
299: {
300: (*s_etat_processus).erreur_systeme = d_es_processus;
301:
302: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
303: sigpending(&set);
304: return;
305: }
306:
307: free((void *) (*l_element_courant).donnee);
308: free((struct_liste_chainee_volatile *) l_element_courant);
309:
310: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
311: sigpending(&set);
312: return;
313: }
314:
315: void
316: retrait_thread_surveillance(struct_processus *s_etat_processus,
317: struct_descripteur_thread *s_argument_thread)
318: {
319: sigset_t set;
320: sigset_t oldset;
321:
322: volatile struct_liste_chainee_volatile *l_element_precedent;
323: volatile struct_liste_chainee_volatile *l_element_courant;
324:
325: sigfillset(&set);
326: pthread_sigmask(SIG_BLOCK, &set, &oldset);
327:
328: # ifndef SEMAPHORES_NOMMES
329: while(sem_wait(&semaphore_liste_threads) == -1)
330: # else
331: while(sem_wait(semaphore_liste_threads) == -1)
332: # endif
333: {
334: if (errno != EINTR)
335: {
336: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
337: sigpending(&set);
338:
339: (*s_etat_processus).erreur_systeme = d_es_processus;
340: return;
341: }
342: }
343:
344: l_element_precedent = NULL;
345: l_element_courant = liste_threads_surveillance;
346:
347: while(l_element_courant != NULL)
348: {
349: if ((*l_element_courant).donnee == (void *) s_argument_thread)
350: {
351: break;
352: }
353:
354: l_element_precedent = l_element_courant;
355: l_element_courant = (*l_element_courant).suivant;
356: }
357:
358: if (l_element_courant == NULL)
359: {
360: # ifndef SEMAPHORES_NOMMES
361: sem_post(&semaphore_liste_threads);
362: # else
363: sem_post(semaphore_liste_threads);
364: # endif
365: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
366: sigpending(&set);
367:
368: (*s_etat_processus).erreur_systeme = d_es_processus;
369: return;
370: }
371:
372: if (l_element_precedent == NULL)
373: {
374: liste_threads_surveillance = (*l_element_courant).suivant;
375: }
376: else
377: {
378: (*l_element_precedent).suivant = (*l_element_courant).suivant;
379: }
380:
381: if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
382: != 0)
383: {
384: # ifndef SEMAPHORES_NOMMES
385: sem_post(&semaphore_liste_threads);
386: # else
387: sem_post(semaphore_liste_threads);
388: # endif
389: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
390: sigpending(&set);
391:
392: (*s_etat_processus).erreur_systeme = d_es_processus;
393: return;
394: }
395:
396: (*s_argument_thread).nombre_references--;
397:
398: BUG((*s_argument_thread).nombre_references < 0,
399: printf("(*s_argument_thread).nombre_references = %d\n",
400: (int) (*s_argument_thread).nombre_references));
401:
402: if ((*s_argument_thread).nombre_references == 0)
403: {
404: if (pthread_mutex_unlock(&((*s_argument_thread)
405: .mutex_nombre_references)) != 0)
406: {
407: # ifndef SEMAPHORES_NOMMES
408: sem_post(&semaphore_liste_threads);
409: # else
410: sem_post(semaphore_liste_threads);
411: # endif
412: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
413: sigpending(&set);
414:
415: (*s_etat_processus).erreur_systeme = d_es_processus;
416: return;
417: }
418:
419: pthread_mutex_destroy(&((*s_argument_thread).mutex));
420: pthread_mutex_destroy(&((*s_argument_thread).mutex_nombre_references));
421: free(s_argument_thread);
422: }
423: else
424: {
425: if (pthread_mutex_unlock(&((*s_argument_thread)
426: .mutex_nombre_references)) != 0)
427: {
428: # ifndef SEMAPHORES_NOMMES
429: sem_post(&semaphore_liste_threads);
430: # else
431: sem_post(semaphore_liste_threads);
432: # endif
433: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
434: sigpending(&set);
435:
436: (*s_etat_processus).erreur_systeme = d_es_processus;
437: return;
438: }
439: }
440:
441: # ifndef SEMAPHORES_NOMMES
442: if (sem_post(&semaphore_liste_threads) != 0)
443: # else
444: if (sem_post(semaphore_liste_threads) != 0)
445: # endif
446: {
447: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
448: sigpending(&set);
449:
450: (*s_etat_processus).erreur_systeme = d_es_processus;
451: return;
452: }
453:
454: free((struct_liste_chainee_volatile *) l_element_courant);
455:
456: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
457: sigpending(&set);
458:
459: return;
460: }
461:
462: void
463: verrouillage_threads_concurrents(struct_processus *s_etat_processus)
464: {
465: volatile struct_liste_chainee_volatile *l_element_courant;
466:
467: # ifndef SEMAPHORES_NOMMES
468: while(sem_wait(&semaphore_liste_threads) == -1)
469: # else
470: while(sem_wait(semaphore_liste_threads) == -1)
471: # endif
472: {
473: if (errno != EINTR)
474: {
475: (*s_etat_processus).erreur_systeme = d_es_processus;
476: return;
477: }
478: }
479:
480: l_element_courant = liste_threads;
481:
482: while(l_element_courant != NULL)
483: {
484: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
485: == getpid()) && (pthread_equal((*((struct_thread *)
486: (*l_element_courant).donnee)).tid, pthread_self()) == 0))
487: {
488: # ifndef SEMAPHORES_NOMMES
489: while(sem_wait(&((*(*((struct_thread *) (*l_element_courant)
490: .donnee)).s_etat_processus).semaphore_fork)) == -1)
491: # else
492: while(sem_wait((*(*((struct_thread *) (*l_element_courant)
493: .donnee)).s_etat_processus).semaphore_fork) == -1)
494: # endif
495: {
496: if (errno != EINTR)
497: {
498: (*s_etat_processus).erreur_systeme = d_es_processus;
499: return;
500: }
501: }
502: }
503:
504: l_element_courant = (*l_element_courant).suivant;
505: }
506:
507: return;
508: }
509:
510: void
511: deverrouillage_threads_concurrents(struct_processus *s_etat_processus)
512: {
513: volatile struct_liste_chainee_volatile *l_element_courant;
514:
515: l_element_courant = liste_threads;
516:
517: while(l_element_courant != NULL)
518: {
519: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
520: == getpid()) && (pthread_equal((*((struct_thread *)
521: (*l_element_courant).donnee)).tid, pthread_self()) == 0))
522: {
523: # ifndef SEMAPHORES_NOMMES
524: if (sem_post(&((*(*((struct_thread *)
525: (*l_element_courant).donnee)).s_etat_processus)
526: .semaphore_fork)) != 0)
527: # else
528: if (sem_post((*(*((struct_thread *)
529: (*l_element_courant).donnee)).s_etat_processus)
530: .semaphore_fork) != 0)
531: # endif
532: {
533: # ifndef SEMAPHORES_NOMMES
534: if (sem_post(&semaphore_liste_threads) != 0)
535: {
536: (*s_etat_processus).erreur_systeme = d_es_processus;
537: return;
538: }
539: # else
540: if (sem_post(semaphore_liste_threads) != 0)
541: {
542: (*s_etat_processus).erreur_systeme = d_es_processus;
543: return;
544: }
545: # endif
546:
547: (*s_etat_processus).erreur_systeme = d_es_processus;
548: return;
549: }
550: }
551:
552: l_element_courant = (*l_element_courant).suivant;
553: }
554:
555: # ifndef SEMAPHORES_NOMMES
556: if (sem_post(&semaphore_liste_threads) != 0)
557: # else
558: if (sem_post(semaphore_liste_threads) != 0)
559: # endif
560: {
561: (*s_etat_processus).erreur_systeme = d_es_processus;
562: return;
563: }
564:
565: return;
566: }
567:
568: void
569: liberation_threads(struct_processus *s_etat_processus)
570: {
571: logical1 suppression_variables_partagees;
572:
573: sigset_t oldset;
574: sigset_t set;
575:
576: struct_descripteur_thread *s_argument_thread;
577:
578: struct_processus *candidat;
579:
580: unsigned long i;
581:
582: void *element_candidat;
583: void *element_courant;
584: void *element_suivant;
585:
586: volatile struct_liste_chainee_volatile *l_element_courant;
587: volatile struct_liste_chainee_volatile *l_element_suivant;
588:
589: sigfillset(&set);
590: pthread_sigmask(SIG_BLOCK, &set, &oldset);
591:
592: # ifndef SEMAPHORES_NOMMES
593: while(sem_wait(&semaphore_liste_threads) == -1)
594: # else
595: while(sem_wait(semaphore_liste_threads) == -1)
596: # endif
597: {
598: if (errno != EINTR)
599: {
600: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
601: (*s_etat_processus).erreur_systeme = d_es_processus;
602: return;
603: }
604: }
605:
606: l_element_courant = liste_threads;
607: suppression_variables_partagees = d_faux;
608:
609: while(l_element_courant != NULL)
610: {
611: if ((*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus
612: != s_etat_processus)
613: {
614: candidat = s_etat_processus;
615: s_etat_processus = (*((struct_thread *)
616: (*l_element_courant).donnee)).s_etat_processus;
617: free((*s_etat_processus).localisation);
618:
619: // (*s_etat_processus).instruction_courante peut pointer sur
620: // n'importe quoi (une instruction courante ou un champ d'une
621: // structure objet). On ne le libère pas quitte à avoir une
622: // petite fuite mémoire dans le processus fils.
623:
624: if ((*s_etat_processus).instruction_courante != NULL)
625: {
626: //free((*s_etat_processus).instruction_courante);
627: }
628:
629: close((*s_etat_processus).pipe_acquittement);
630: close((*s_etat_processus).pipe_donnees);
631: close((*s_etat_processus).pipe_injections);
632: close((*s_etat_processus).pipe_nombre_injections);
633: close((*s_etat_processus).pipe_interruptions);
634: close((*s_etat_processus).pipe_nombre_objets_attente);
635: close((*s_etat_processus).pipe_nombre_interruptions_attente);
636:
637: liberation(s_etat_processus, (*s_etat_processus).at_exit);
638:
639: if ((*s_etat_processus).nom_fichier_impression != NULL)
640: {
641: free((*s_etat_processus).nom_fichier_impression);
642: }
643:
644: while((*s_etat_processus).fichiers_graphiques != NULL)
645: {
646: free((*(*s_etat_processus).fichiers_graphiques).nom);
647:
648: if ((*(*s_etat_processus).fichiers_graphiques).legende != NULL)
649: {
650: free((*(*s_etat_processus).fichiers_graphiques).legende);
651: }
652:
653: element_courant = (*s_etat_processus).fichiers_graphiques;
654: (*s_etat_processus).fichiers_graphiques =
655: (*(*s_etat_processus).fichiers_graphiques).suivant;
656:
657: free(element_courant);
658: }
659:
660: if ((*s_etat_processus).entree_standard != NULL)
661: {
662: pclose((*s_etat_processus).entree_standard);
663: }
664:
665: if ((*s_etat_processus).generateur_aleatoire != NULL)
666: {
667: liberation_generateur_aleatoire(s_etat_processus);
668: }
669:
670: if ((*s_etat_processus).instruction_derniere_erreur != NULL)
671: {
672: free((*s_etat_processus).instruction_derniere_erreur);
673: (*s_etat_processus).instruction_derniere_erreur = NULL;
674: }
675:
676: element_courant = (void *) (*s_etat_processus)
677: .l_base_pile_processus;
678: while(element_courant != NULL)
679: {
680: s_argument_thread = (struct_descripteur_thread *)
681: (*((struct_liste_chainee *) element_courant)).donnee;
682:
683: if (pthread_mutex_lock(&((*s_argument_thread)
684: .mutex_nombre_references)) != 0)
685: {
686: (*s_etat_processus).erreur_systeme = d_es_processus;
687: sem_post(&semaphore_liste_threads);
688: return;
689: }
690:
691: (*s_argument_thread).nombre_references--;
692:
693: BUG((*s_argument_thread).nombre_references < 0,
694: printf("(*s_argument_thread).nombre_references = %d\n",
695: (int) (*s_argument_thread).nombre_references));
696:
697: if ((*s_argument_thread).nombre_references == 0)
698: {
699: close((*s_argument_thread).pipe_objets[0]);
700: close((*s_argument_thread).pipe_acquittement[1]);
701: close((*s_argument_thread).pipe_injections[1]);
702: close((*s_argument_thread).pipe_nombre_injections[1]);
703: close((*s_argument_thread).pipe_nombre_objets_attente[0]);
704: close((*s_argument_thread).pipe_interruptions[0]);
705: close((*s_argument_thread)
706: .pipe_nombre_interruptions_attente[0]);
707:
708: if (pthread_mutex_unlock(&((*s_argument_thread)
709: .mutex_nombre_references)) != 0)
710: {
711: (*s_etat_processus).erreur_systeme = d_es_processus;
712: sem_post(&semaphore_liste_threads);
713: return;
714: }
715:
716: pthread_mutex_destroy(&((*s_argument_thread).mutex));
717: pthread_mutex_destroy(&((*s_argument_thread)
718: .mutex_nombre_references));
719:
720: if ((*s_argument_thread).processus_detache == d_faux)
721: {
722: if ((*s_argument_thread).destruction_objet == d_vrai)
723: {
724: liberation(s_etat_processus, (*s_argument_thread)
725: .argument);
726: }
727: }
728:
729: free(s_argument_thread);
730: }
731: else
732: {
733: if (pthread_mutex_unlock(&((*s_argument_thread)
734: .mutex_nombre_references)) != 0)
735: {
736: (*s_etat_processus).erreur_systeme = d_es_processus;
737: sem_post(&semaphore_liste_threads);
738: return;
739: }
740: }
741:
742: element_suivant = (*((struct_liste_chainee *) element_courant))
743: .suivant;
744: free(element_courant);
745: element_courant = element_suivant;
746: }
747:
748: (*s_etat_processus).l_base_pile_processus = NULL;
749:
750: pthread_mutex_trylock(&((*(*s_etat_processus).indep).mutex));
751: pthread_mutex_unlock(&((*(*s_etat_processus).indep).mutex));
752: liberation(s_etat_processus, (*s_etat_processus).indep);
753:
754: pthread_mutex_trylock(&((*(*s_etat_processus).depend).mutex));
755: pthread_mutex_unlock(&((*(*s_etat_processus).depend).mutex));
756: liberation(s_etat_processus, (*s_etat_processus).depend);
757:
758: free((*s_etat_processus).label_x);
759: free((*s_etat_processus).label_y);
760: free((*s_etat_processus).label_z);
761: free((*s_etat_processus).titre);
762: free((*s_etat_processus).legende);
763:
764: pthread_mutex_trylock(&((*(*s_etat_processus)
765: .parametres_courbes_de_niveau).mutex));
766: pthread_mutex_unlock(&((*(*s_etat_processus)
767: .parametres_courbes_de_niveau).mutex));
768: liberation(s_etat_processus, (*s_etat_processus)
769: .parametres_courbes_de_niveau);
770:
771: for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++)
772: {
773: if ((*s_etat_processus).corps_interruptions[i] != NULL)
774: {
775: pthread_mutex_trylock(&((*(*s_etat_processus)
776: .corps_interruptions[i]).mutex));
777: pthread_mutex_unlock(&((*(*s_etat_processus)
778: .corps_interruptions[i]).mutex));
779:
780: liberation(s_etat_processus,
781: (*s_etat_processus).corps_interruptions[i]);
782: }
783:
784: element_courant = (*s_etat_processus)
785: .pile_origine_interruptions[i];
786:
787: while(element_courant != NULL)
788: {
789: element_suivant = (*((struct_liste_chainee *)
790: element_courant)).suivant;
791:
792: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
793: element_courant)).donnee).mutex));
794: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
795: element_courant)).donnee).mutex));
796:
797: liberation(s_etat_processus,
798: (*((struct_liste_chainee *) element_courant))
799: .donnee);
800: free(element_courant);
801:
802: element_courant = element_suivant;
803: }
804: }
805:
806: liberation_arbre_variables(s_etat_processus,
807: (*s_etat_processus).s_arbre_variables, d_faux);
808:
809: for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)
810: {
811: pthread_mutex_trylock(&((*(*s_etat_processus)
812: .s_liste_variables_statiques[i].objet).mutex));
813: pthread_mutex_unlock(&((*(*s_etat_processus)
814: .s_liste_variables_statiques[i].objet).mutex));
815:
816: liberation(s_etat_processus, (*s_etat_processus)
817: .s_liste_variables_statiques[i].objet);
818: free((*s_etat_processus).s_liste_variables_statiques[i].nom);
819: }
820:
821: free((*s_etat_processus).s_liste_variables_statiques);
822:
823: // Ne peut être effacé qu'une seule fois
824: if (suppression_variables_partagees == d_faux)
825: {
826: suppression_variables_partagees = d_vrai;
827:
828: for(i = 0; i < (*(*s_etat_processus)
829: .s_liste_variables_partagees).nombre_variables; i++)
830: {
831: pthread_mutex_trylock(&((*(*(*s_etat_processus)
832: .s_liste_variables_partagees).table[i].objet)
833: .mutex));
834: pthread_mutex_unlock(&((*(*(*s_etat_processus)
835: .s_liste_variables_partagees).table[i].objet)
836: .mutex));
837:
838: liberation(s_etat_processus, (*(*s_etat_processus)
839: .s_liste_variables_partagees).table[i].objet);
840: free((*(*s_etat_processus).s_liste_variables_partagees)
841: .table[i].nom);
842: }
843:
844: if ((*(*s_etat_processus).s_liste_variables_partagees).table
845: != NULL)
846: {
847: free((struct_variable_partagee *) (*(*s_etat_processus)
848: .s_liste_variables_partagees).table);
849: }
850:
851: pthread_mutex_trylock(&((*(*s_etat_processus)
852: .s_liste_variables_partagees).mutex));
853: pthread_mutex_unlock(&((*(*s_etat_processus)
854: .s_liste_variables_partagees).mutex));
855: }
856:
857: element_courant = (*s_etat_processus).l_base_pile;
858: while(element_courant != NULL)
859: {
860: element_suivant = (*((struct_liste_chainee *)
861: element_courant)).suivant;
862:
863: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
864: element_courant)).donnee).mutex));
865: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
866: element_courant)).donnee).mutex));
867:
868: liberation(s_etat_processus,
869: (*((struct_liste_chainee *)
870: element_courant)).donnee);
871: free((struct_liste_chainee *) element_courant);
872:
873: element_courant = element_suivant;
874: }
875:
876: element_courant = (*s_etat_processus).l_base_pile_contextes;
877: while(element_courant != NULL)
878: {
879: element_suivant = (*((struct_liste_chainee *)
880: element_courant)).suivant;
881:
882: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
883: element_courant)).donnee).mutex));
884: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
885: element_courant)).donnee).mutex));
886: liberation(s_etat_processus, (*((struct_liste_chainee *)
887: element_courant)).donnee);
888: free((struct_liste_chainee *) element_courant);
889:
890: element_courant = element_suivant;
891: }
892:
893: element_courant = (*s_etat_processus).l_base_pile_taille_contextes;
894: while(element_courant != NULL)
895: {
896: element_suivant = (*((struct_liste_chainee *)
897: element_courant)).suivant;
898:
899: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
900: element_courant)).donnee).mutex));
901: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
902: element_courant)).donnee).mutex));
903: liberation(s_etat_processus,
904: (*((struct_liste_chainee *)
905: element_courant)).donnee);
906: free((struct_liste_chainee *) element_courant);
907:
908: element_courant = element_suivant;
909: }
910:
911: for(i = 0; i < (*s_etat_processus).nombre_instructions_externes;
912: i++)
913: {
914: free((*s_etat_processus).s_instructions_externes[i].nom);
915: free((*s_etat_processus).s_instructions_externes[i]
916: .nom_bibliotheque);
917: }
918:
919: if ((*s_etat_processus).nombre_instructions_externes != 0)
920: {
921: free((*s_etat_processus).s_instructions_externes);
922: }
923:
924: element_courant = (*s_etat_processus).s_bibliotheques;
925: while(element_courant != NULL)
926: {
927: element_suivant = (*((struct_liste_chainee *)
928: element_courant)).suivant;
929:
930: element_candidat = (*candidat).s_bibliotheques;
931: while(element_candidat != NULL)
932: {
933: if (((*((struct_bibliotheque *) (*((struct_liste_chainee *)
934: element_courant)).donnee))
935: .descripteur == (*((struct_bibliotheque *)
936: (*((struct_liste_chainee *) element_candidat))
937: .donnee)).descripteur) &&
938: ((*((struct_bibliotheque *)
939: (*((struct_liste_chainee *) element_courant))
940: .donnee)).pid == (*((struct_bibliotheque *)
941: (*((struct_liste_chainee *) element_candidat))
942: .donnee)).pid) && (pthread_equal(
943: (*((struct_bibliotheque *)
944: (*((struct_liste_chainee *) element_courant))
945: .donnee)).tid, (*((struct_bibliotheque *)
946: (*((struct_liste_chainee *) element_candidat))
947: .donnee)).tid) != 0))
948: {
949: break;
950: }
951:
952: element_candidat = (*((struct_liste_chainee *)
953: element_candidat)).suivant;
954: }
955:
956: if (element_candidat == NULL)
957: {
958: dlclose((*((struct_bibliotheque *)
959: (*((struct_liste_chainee *) element_courant))
960: .donnee)).descripteur);
961: }
962:
963: free((*((struct_bibliotheque *)
964: (*((struct_liste_chainee *)
965: element_courant)).donnee)).nom);
966: free((*((struct_liste_chainee *) element_courant)).donnee);
967: free(element_courant);
968:
969: element_courant = element_suivant;
970: }
971:
972: element_courant = (*s_etat_processus).l_base_pile_last;
973: while(element_courant != NULL)
974: {
975: element_suivant = (*((struct_liste_chainee *)
976: element_courant)).suivant;
977:
978: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
979: element_courant)).donnee).mutex));
980: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
981: element_courant)).donnee).mutex));
982: liberation(s_etat_processus,
983: (*((struct_liste_chainee *) element_courant)).donnee);
984: free(element_courant);
985:
986: element_courant = element_suivant;
987: }
988:
989: element_courant = (*s_etat_processus).l_base_pile_systeme;
990: while(element_courant != NULL)
991: {
992: element_suivant = (*((struct_liste_pile_systeme *)
993: element_courant)).suivant;
994:
995: if ((*((struct_liste_pile_systeme *)
996: element_courant)).indice_boucle != NULL)
997: {
998: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
999: element_courant)).indice_boucle).mutex));
1000: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
1001: element_courant)).indice_boucle).mutex));
1002: }
1003:
1004: liberation(s_etat_processus,
1005: (*((struct_liste_pile_systeme *)
1006: element_courant)).indice_boucle);
1007:
1008: if ((*((struct_liste_pile_systeme *)
1009: element_courant)).limite_indice_boucle != NULL)
1010: {
1011: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
1012: element_courant)).limite_indice_boucle).mutex));
1013: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
1014: element_courant)).limite_indice_boucle).mutex));
1015: }
1016:
1017: liberation(s_etat_processus,
1018: (*((struct_liste_pile_systeme *)
1019: element_courant)).limite_indice_boucle);
1020:
1021: if ((*((struct_liste_pile_systeme *)
1022: element_courant)).objet_de_test != NULL)
1023: {
1024: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
1025: element_courant)).objet_de_test).mutex));
1026: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
1027: element_courant)).objet_de_test).mutex));
1028: }
1029:
1030: liberation(s_etat_processus,
1031: (*((struct_liste_pile_systeme *)
1032: element_courant)).objet_de_test);
1033:
1034: if ((*((struct_liste_pile_systeme *)
1035: element_courant)).nom_variable != NULL)
1036: {
1037: free((*((struct_liste_pile_systeme *)
1038: element_courant)).nom_variable);
1039: }
1040:
1041: free(element_courant);
1042:
1043: element_courant = element_suivant;
1044: }
1045:
1046: element_courant = (*s_etat_processus).s_fichiers;
1047: while(element_courant != NULL)
1048: {
1049: element_suivant = (*((struct_liste_chainee *)
1050: element_courant)).suivant;
1051:
1052: element_candidat = (*candidat).s_fichiers;
1053: while(element_candidat != NULL)
1054: {
1055: if (((*((struct_descripteur_fichier *)
1056: (*((struct_liste_chainee *) element_courant))
1057: .donnee)).pid ==
1058: (*((struct_descripteur_fichier *)
1059: (*((struct_liste_chainee *) element_candidat))
1060: .donnee)).pid) && (pthread_equal(
1061: (*((struct_descripteur_fichier *)
1062: (*((struct_liste_chainee *) element_courant))
1063: .donnee)).tid, (*((struct_descripteur_fichier *)
1064: (*((struct_liste_chainee *) element_candidat))
1065: .donnee)).tid) != 0))
1066: {
1067: if ((*((struct_descripteur_fichier *)
1068: (*((struct_liste_chainee *) element_courant))
1069: .donnee)).type ==
1070: (*((struct_descripteur_fichier *)
1071: (*((struct_liste_chainee *) element_candidat))
1072: .donnee)).type)
1073: {
1074: if ((*((struct_descripteur_fichier *)
1075: (*((struct_liste_chainee *)
1076: element_candidat)).donnee)).type == 'C')
1077: {
1078: if ((*((struct_descripteur_fichier *)
1079: (*((struct_liste_chainee *)
1080: element_courant)).donnee))
1081: .descripteur_c ==
1082: (*((struct_descripteur_fichier *)
1083: (*((struct_liste_chainee *)
1084: element_candidat)).donnee))
1085: .descripteur_c)
1086: {
1087: break;
1088: }
1089: }
1090: else
1091: {
1092: if (((*((struct_descripteur_fichier *)
1093: (*((struct_liste_chainee *)
1094: element_courant)).donnee))
1095: .descripteur_sqlite ==
1096: (*((struct_descripteur_fichier *)
1097: (*((struct_liste_chainee *)
1098: element_candidat)).donnee))
1099: .descripteur_sqlite) &&
1100: ((*((struct_descripteur_fichier *)
1101: (*((struct_liste_chainee *)
1102: element_courant)).donnee))
1103: .descripteur_c ==
1104: (*((struct_descripteur_fichier *)
1105: (*((struct_liste_chainee *)
1106: element_candidat)).donnee))
1107: .descripteur_c))
1108: {
1109: break;
1110: }
1111: }
1112: }
1113: }
1114:
1115: element_candidat = (*((struct_liste_chainee *)
1116: element_candidat)).suivant;
1117: }
1118:
1119: if (element_candidat == NULL)
1120: {
1121: fclose((*((struct_descripteur_fichier *)
1122: (*((struct_liste_chainee *) element_courant))
1123: .donnee)).descripteur_c);
1124:
1125: if ((*((struct_descripteur_fichier *)
1126: (*((struct_liste_chainee *) element_courant))
1127: .donnee)).type != 'C')
1128: {
1129: sqlite3_close((*((struct_descripteur_fichier *)
1130: (*((struct_liste_chainee *) element_courant))
1131: .donnee)).descripteur_sqlite);
1132: }
1133: }
1134:
1135: free((*((struct_descripteur_fichier *)
1136: (*((struct_liste_chainee *)
1137: element_courant)).donnee)).nom);
1138: free((struct_descripteur_fichier *)
1139: (*((struct_liste_chainee *)
1140: element_courant)).donnee);
1141: free(element_courant);
1142:
1143: element_courant = element_suivant;
1144: }
1145:
1146: element_courant = (*s_etat_processus).s_sockets;
1147: while(element_courant != NULL)
1148: {
1149: element_suivant = (*((struct_liste_chainee *)
1150: element_courant)).suivant;
1151:
1152: element_candidat = (*candidat).s_sockets;
1153: while(element_candidat != NULL)
1154: {
1155: if (((*((struct_socket *)
1156: (*((struct_liste_chainee *) element_courant))
1157: .donnee)).socket == (*((struct_socket *)
1158: (*((struct_liste_chainee *) element_candidat))
1159: .donnee)).socket) &&
1160: ((*((struct_socket *)
1161: (*((struct_liste_chainee *) element_courant))
1162: .donnee)).pid == (*((struct_socket *)
1163: (*((struct_liste_chainee *) element_candidat))
1164: .donnee)).pid) && (pthread_equal(
1165: (*((struct_socket *)
1166: (*((struct_liste_chainee *) element_courant))
1167: .donnee)).tid, (*((struct_socket *)
1168: (*((struct_liste_chainee *) element_candidat))
1169: .donnee)).tid) != 0))
1170: {
1171: break;
1172: }
1173:
1174: element_candidat = (*((struct_liste_chainee *)
1175: element_candidat)).suivant;
1176: }
1177:
1178: if (element_candidat == NULL)
1179: {
1180: if ((*((struct_socket *) (*((struct_liste_chainee *)
1181: element_courant)).donnee)).socket_connectee
1182: == d_vrai)
1183: {
1184: shutdown((*((struct_socket *)
1185: (*((struct_liste_chainee *) element_courant))
1186: .donnee)).socket, SHUT_RDWR);
1187: }
1188:
1189: close((*((struct_socket *)
1190: (*((struct_liste_chainee *) element_courant))
1191: .donnee)).socket);
1192: }
1193:
1194: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1195: element_courant)).donnee).mutex));
1196: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1197: element_courant)).donnee).mutex));
1198:
1199: liberation(s_etat_processus,
1200: (*((struct_liste_chainee *)
1201: element_courant)).donnee);
1202: free(element_courant);
1203:
1204: element_courant = element_suivant;
1205: }
1206:
1207: /*
1208: ================================================================================
1209: À noter : on ne ferme pas la connexion car la conséquence immédiate est
1210: une destruction de l'objet pour le processus père.
1211: ================================================================================
1212:
1213: element_courant = (*s_etat_processus).s_connecteurs_sql;
1214: while(element_courant != NULL)
1215: {
1216: element_suivant = (*((struct_liste_chainee *)
1217: element_courant)).suivant;
1218:
1219: element_candidat = (*candidat).s_connecteurs_sql;
1220: while(element_candidat != NULL)
1221: {
1222: if (((
1223: #ifdef MYSQL_SUPPORT
1224: ((*((struct_connecteur_sql *)
1225: (*((struct_liste_chainee *) element_courant))
1226: .donnee)).descripteur.mysql ==
1227: (*((struct_connecteur_sql *)
1228: (*((struct_liste_chainee *) element_candidat))
1229: .donnee)).descripteur.mysql)
1230: &&
1231: (strcmp((*((struct_connecteur_sql *)
1232: (*((struct_liste_chainee *) element_courant))
1233: .donnee)).type, "MYSQL") == 0)
1234: &&
1235: (strcmp((*((struct_connecteur_sql *)
1236: (*((struct_liste_chainee *) element_candidat))
1237: .donnee)).type, "MYSQL") == 0)
1238: #else
1239: 0
1240: #endif
1241: ) || (
1242: #ifdef POSTGRESQL_SUPPORT
1243: ((*((struct_connecteur_sql *)
1244: (*((struct_liste_chainee *) element_courant))
1245: .donnee)).descripteur.postgresql ==
1246: (*((struct_connecteur_sql *)
1247: (*((struct_liste_chainee *) element_candidat))
1248: .donnee)).descripteur.postgresql)
1249: &&
1250: (strcmp((*((struct_connecteur_sql *)
1251: (*((struct_liste_chainee *) element_courant))
1252: .donnee)).type, "POSTGRESQL") == 0)
1253: &&
1254: (strcmp((*((struct_connecteur_sql *)
1255: (*((struct_liste_chainee *) element_candidat))
1256: .donnee)).type, "POSTGRESQL") == 0)
1257: #else
1258: 0
1259: #endif
1260: )) &&
1261: ((*((struct_connecteur_sql *)
1262: (*((struct_liste_chainee *) element_courant))
1263: .donnee)).pid == (*((struct_connecteur_sql *)
1264: (*((struct_liste_chainee *) element_candidat))
1265: .donnee)).pid) && (pthread_equal(
1266: (*((struct_connecteur_sql *)
1267: (*((struct_liste_chainee *) element_courant))
1268: .donnee)).tid, (*((struct_connecteur_sql *)
1269: (*((struct_liste_chainee *) element_candidat))
1270: .donnee)).tid) != 0))
1271: {
1272: break;
1273: }
1274:
1275: element_candidat = (*((struct_liste_chainee *)
1276: element_candidat)).suivant;
1277: }
1278:
1279: if (element_candidat == NULL)
1280: {
1281: sqlclose((*((struct_liste_chainee *) element_courant))
1282: .donnee);
1283: }
1284:
1285: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1286: element_courant)).donnee).mutex));
1287: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1288: element_courant)).donnee).mutex));
1289:
1290: liberation(s_etat_processus, (*((struct_liste_chainee *)
1291: element_courant)).donnee);
1292: free(element_courant);
1293:
1294: element_courant = element_suivant;
1295: }
1296: */
1297:
1298: (*s_etat_processus).s_connecteurs_sql = NULL;
1299:
1300: element_courant = (*s_etat_processus).s_marques;
1301: while(element_courant != NULL)
1302: {
1303: free((*((struct_marque *) element_courant)).label);
1304: free((*((struct_marque *) element_courant)).position);
1305: element_suivant = (*((struct_marque *) element_courant))
1306: .suivant;
1307: free(element_courant);
1308: element_courant = element_suivant;
1309: }
1310:
1311: liberation_allocateur(s_etat_processus);
1312:
1313: # ifndef SEMAPHORES_NOMMES
1314: sem_post(&((*s_etat_processus).semaphore_fork));
1315: sem_destroy(&((*s_etat_processus).semaphore_fork));
1316: # else
1317: sem_post((*s_etat_processus).semaphore_fork);
1318: sem_destroy2((*s_etat_processus).semaphore_fork, sem_fork);
1319: # endif
1320:
1321: liberation_contexte_cas(s_etat_processus);
1322: free(s_etat_processus);
1323:
1324: s_etat_processus = candidat;
1325: }
1326:
1327: l_element_suivant = (*l_element_courant).suivant;
1328:
1329: free((struct_thread *) (*l_element_courant).donnee);
1330: free((struct_liste_chainee *) l_element_courant);
1331:
1332: l_element_courant = l_element_suivant;
1333: }
1334:
1335: liste_threads = NULL;
1336:
1337: l_element_courant = liste_threads_surveillance;
1338:
1339: while(l_element_courant != NULL)
1340: {
1341: s_argument_thread = (struct_descripteur_thread *)
1342: (*l_element_courant).donnee;
1343:
1344: if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
1345: != 0)
1346: {
1347: (*s_etat_processus).erreur_systeme = d_es_processus;
1348: sem_post(&semaphore_liste_threads);
1349: return;
1350: }
1351:
1352: (*s_argument_thread).nombre_references--;
1353:
1354: BUG((*s_argument_thread).nombre_references < 0,
1355: printf("(*s_argument_thread).nombre_references = %d\n",
1356: (int) (*s_argument_thread).nombre_references));
1357:
1358: if ((*s_argument_thread).nombre_references == 0)
1359: {
1360: close((*s_argument_thread).pipe_objets[0]);
1361: close((*s_argument_thread).pipe_acquittement[1]);
1362: close((*s_argument_thread).pipe_injections[1]);
1363: close((*s_argument_thread).pipe_nombre_injections[1]);
1364: close((*s_argument_thread).pipe_nombre_objets_attente[0]);
1365: close((*s_argument_thread).pipe_interruptions[0]);
1366: close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);
1367:
1368: if (pthread_mutex_unlock(&((*s_argument_thread)
1369: .mutex_nombre_references)) != 0)
1370: {
1371: (*s_etat_processus).erreur_systeme = d_es_processus;
1372: sem_post(&semaphore_liste_threads);
1373: return;
1374: }
1375:
1376: pthread_mutex_destroy(&((*s_argument_thread).mutex));
1377: pthread_mutex_destroy(&((*s_argument_thread)
1378: .mutex_nombre_references));
1379:
1380: if ((*s_argument_thread).processus_detache == d_faux)
1381: {
1382: if ((*s_argument_thread).destruction_objet == d_vrai)
1383: {
1384: liberation(s_etat_processus, (*s_argument_thread).argument);
1385: }
1386: }
1387:
1388: free(s_argument_thread);
1389: }
1390: else
1391: {
1392: if (pthread_mutex_unlock(&((*s_argument_thread)
1393: .mutex_nombre_references)) != 0)
1394: {
1395: (*s_etat_processus).erreur_systeme = d_es_processus;
1396: sem_post(&semaphore_liste_threads);
1397: return;
1398: }
1399: }
1400:
1401: l_element_suivant = (*l_element_courant).suivant;
1402: free((struct_liste_chainee *) l_element_courant);
1403: l_element_courant = l_element_suivant;
1404: }
1405:
1406: liste_threads_surveillance = NULL;
1407:
1408: # ifndef SEMAPHORES_NOMMES
1409: if (sem_post(&semaphore_liste_threads) != 0)
1410: # else
1411: if (sem_post(semaphore_liste_threads) != 0)
1412: # endif
1413: {
1414: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1415: (*s_etat_processus).erreur_systeme = d_es_processus;
1416: return;
1417: }
1418:
1419: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1420: sigpending(&set);
1421: return;
1422: }
1423:
1424: static struct_processus *
1425: recherche_thread(pid_t pid, pthread_t tid)
1426: {
1427: volatile struct_liste_chainee_volatile *l_element_courant;
1428:
1429: struct_processus *s_etat_processus;
1430:
1431: l_element_courant = liste_threads;
1432:
1433: while(l_element_courant != NULL)
1434: {
1435: if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee))
1436: .tid, tid) != 0) && ((*((struct_thread *)
1437: (*l_element_courant).donnee)).pid == pid))
1438: {
1439: break;
1440: }
1441:
1442: l_element_courant = (*l_element_courant).suivant;
1443: }
1444:
1445: if (l_element_courant == NULL)
1446: {
1447: /*
1448: * Le processus n'existe plus. On ne distribue aucun signal.
1449: */
1450:
1451: return(NULL);
1452: }
1453:
1454: s_etat_processus = (*((struct_thread *)
1455: (*l_element_courant).donnee)).s_etat_processus;
1456:
1457: return(s_etat_processus);
1458: }
1459:
1460: static struct_processus *
1461: recherche_thread_principal(pid_t pid)
1462: {
1463: volatile struct_liste_chainee_volatile *l_element_courant;
1464:
1465: l_element_courant = liste_threads;
1466:
1467: while(l_element_courant != NULL)
1468: {
1469: if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal
1470: == d_vrai) && ((*((struct_thread *)
1471: (*l_element_courant).donnee)).pid == pid))
1472: {
1473: break;
1474: }
1475:
1476: l_element_courant = (*l_element_courant).suivant;
1477: }
1478:
1479: if (l_element_courant == NULL)
1480: {
1481: /*
1482: * Le processus n'existe plus. On ne distribue aucun signal.
1483: */
1484:
1485: return(NULL);
1486: }
1487:
1488: return((*((struct_thread *) (*l_element_courant).donnee))
1489: .s_etat_processus);
1490: }
1491:
1492:
1493: /*
1494: ================================================================================
1495: Procédures de gestion des signaux d'interruption
1496: ================================================================================
1497: Entrée : variable globale
1498: --------------------------------------------------------------------------------
1499: Sortie : variable globale modifiée
1500: --------------------------------------------------------------------------------
1501: Effets de bord : néant
1502: ================================================================================
1503: */
1504:
1505: // Les routines suivantes sont uniquement appelées depuis les gestionnaires
1506: // des signaux asynchrones. Elles ne doivent pas bloquer dans le cas où
1507: // les sémaphores sont déjà bloqués par un gestionnaire de signal.
1508:
1509: static inline void
1510: verrouillage_gestionnaire_signaux()
1511: {
1512: int semaphore;
1513:
1514: sigset_t oldset;
1515: sigset_t set;
1516:
1517: sem_t *sem;
1518:
1519: if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
1520: != NULL)
1521: {
1522: if (sem_post(sem) != 0)
1523: {
1524: BUG(1, uprintf("Lock error !\n"));
1525: return;
1526: }
1527: }
1528:
1529: // Il faut respecteur l'atomicité des deux opérations suivantes !
1530:
1531: sigfillset(&set);
1532: pthread_sigmask(SIG_BLOCK, &set, &oldset);
1533:
1534: # ifndef SEMAPHORES_NOMMES
1535: while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
1536: # else
1537: while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)
1538: # endif
1539: {
1540: if (errno != EINTR)
1541: {
1542: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1543: BUG(1, uprintf("Unlock error !\n"));
1544: return;
1545: }
1546: }
1547:
1548: # ifndef SEMAPHORES_NOMMES
1549: if (sem_post(&semaphore_gestionnaires_signaux) == -1)
1550: # else
1551: if (sem_post(semaphore_gestionnaires_signaux) == -1)
1552: # endif
1553: {
1554: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1555: BUG(1, uprintf("Lock error !\n"));
1556: return;
1557: }
1558:
1559: # ifndef SEMAPHORES_NOMMES
1560: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1561: # else
1562: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1563: # endif
1564: {
1565: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1566: BUG(1, uprintf("Lock error !\n"));
1567: return;
1568: }
1569:
1570: # ifndef SEMAPHORES_NOMMES
1571: if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
1572: # else
1573: if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)
1574: # endif
1575: {
1576: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1577: BUG(1, uprintf("Unlock error !\n"));
1578: return;
1579: }
1580:
1581: if (semaphore == 1)
1582: {
1583: // Le semaphore ne peut être pris par le thread qui a appelé
1584: // le gestionnaire de signal car le signal est bloqué par ce thread
1585: // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que
1586: // par un thread concurrent. On essaye donc de le bloquer jusqu'à
1587: // ce que ce soit possible.
1588:
1589: # ifndef SEMAPHORES_NOMMES
1590: while(sem_wait(&semaphore_liste_threads) == -1)
1591: # else
1592: while(sem_wait(semaphore_liste_threads) == -1)
1593: # endif
1594: {
1595: if (errno != EINTR)
1596: {
1597: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1598:
1599: while(sem_wait(sem) == -1)
1600: {
1601: if (errno != EINTR)
1602: {
1603: BUG(1, uprintf("Lock error !\n"));
1604: return;
1605: }
1606: }
1607:
1608: BUG(1, uprintf("Lock error !\n"));
1609: return;
1610: }
1611: }
1612: }
1613:
1614: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1615: sigpending(&set);
1616:
1617: return;
1618: }
1619:
1620: static inline void
1621: deverrouillage_gestionnaire_signaux()
1622: {
1623: int semaphore;
1624:
1625: sem_t *sem;
1626:
1627: sigset_t oldset;
1628: sigset_t set;
1629:
1630: // Il faut respecteur l'atomicité des deux opérations suivantes !
1631:
1632: sigfillset(&set);
1633: pthread_sigmask(SIG_BLOCK, &set, &oldset);
1634:
1635: # ifndef SEMAPHORES_NOMMES
1636: while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
1637: # else
1638: while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)
1639: # endif
1640: {
1641: if (errno != EINTR)
1642: {
1643: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1644: BUG(1, uprintf("Unlock error !\n"));
1645: return;
1646: }
1647: }
1648:
1649: # ifndef SEMAPHORES_NOMMES
1650: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1651: # else
1652: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1653: # endif
1654: {
1655: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1656: BUG(1, uprintf("Unlock error !\n"));
1657: return;
1658: }
1659:
1660: # ifndef SEMAPHORES_NOMMES
1661: while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
1662: # else
1663: while(sem_wait(semaphore_gestionnaires_signaux) == -1)
1664: # endif
1665: {
1666: if (errno != EINTR)
1667: {
1668: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1669: BUG(1, uprintf("Unlock error !\n"));
1670: return;
1671: }
1672: }
1673:
1674: # ifndef SEMAPHORES_NOMMES
1675: if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
1676: # else
1677: if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)
1678: # endif
1679: {
1680: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1681: BUG(1, uprintf("Unlock error !\n"));
1682: return;
1683: }
1684:
1685: if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
1686: != NULL)
1687: {
1688: while(sem_wait(sem) == -1)
1689: {
1690: if (errno != EINTR)
1691: {
1692: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1693: BUG(1, uprintf("Unlock error !\n"));
1694: return;
1695: }
1696: }
1697: }
1698:
1699: if (semaphore == 1)
1700: {
1701: # ifndef SEMAPHORES_NOMMES
1702: if (sem_post(&semaphore_liste_threads) != 0)
1703: # else
1704: if (sem_post(semaphore_liste_threads) != 0)
1705: # endif
1706: {
1707: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1708:
1709: BUG(1, uprintf("Unlock error !\n"));
1710: return;
1711: }
1712: }
1713:
1714: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1715: sigpending(&set);
1716:
1717: return;
1718: }
1719:
1720: #define test_signal(signal) \
1721: if (signal_test == SIGTEST) { signal_test = signal; return; }
1722:
1723: // Récupération des signaux
1724: // - SIGINT (arrêt au clavier)
1725: // - SIGTERM (signal d'arrêt en provenance du système)
1726:
1727: void
1728: interruption1(int signal)
1729: {
1730: test_signal(signal);
1731:
1732: switch(signal)
1733: {
1734: case SIGINT:
1735: envoi_signal_processus(getpid(), rpl_sigint);
1736: break;
1737:
1738: case SIGTERM:
1739: envoi_signal_processus(getpid(), rpl_sigterm);
1740: break;
1741:
1742: case SIGALRM:
1743: envoi_signal_processus(getpid(), rpl_sigalrm);
1744: break;
1745: }
1746:
1747: return;
1748: }
1749:
1750: inline static void
1751: signal_alrm(struct_processus *s_etat_processus, pid_t pid)
1752: {
1753: struct_processus *s_thread_principal;
1754:
1755: verrouillage_gestionnaire_signaux();
1756:
1757: if (pid == getpid())
1758: {
1759: // Si pid est égal à getpid(), le signal à traiter est issu
1760: // du même processus que celui qui va le traiter, mais d'un thread
1761: // différent.
1762:
1763: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1764: {
1765: printf("[%d] RPL/SIGALRM (thread %llu)\n", (int) getpid(),
1766: (unsigned long long) pthread_self());
1767: fflush(stdout);
1768: }
1769:
1770: if ((*s_etat_processus).pid_processus_pere != getpid())
1771: {
1772: // On n'est pas dans le processus père, on remonte le signal.
1773: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1774: rpl_sigalrm);
1775: }
1776: else
1777: {
1778: // On est dans le processus père, on effectue un arrêt d'urgence.
1779: (*s_etat_processus).var_volatile_alarme = -1;
1780: (*s_etat_processus).var_volatile_requete_arret = -1;
1781: }
1782: }
1783: else
1784: {
1785: // Le signal est issu d'un processus différent. On recherche le
1786: // thread principal pour remonter le signal.
1787:
1788: if ((s_thread_principal = recherche_thread_principal(getpid()))
1789: != NULL)
1790: {
1791: envoi_signal_contexte(s_thread_principal, rpl_sigalrm);
1792: }
1793: }
1794:
1795: deverrouillage_gestionnaire_signaux();
1796: return;
1797: }
1798:
1799: inline static void
1800: signal_term(struct_processus *s_etat_processus, pid_t pid)
1801: {
1802: struct_processus *s_thread_principal;
1803: volatile sig_atomic_t exclusion = 0;
1804:
1805: verrouillage_gestionnaire_signaux();
1806:
1807: if (pid == getpid())
1808: {
1809: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1810: {
1811: printf("[%d] RPL/SIGTERM (thread %llu)\n", (int) getpid(),
1812: (unsigned long long) pthread_self());
1813: fflush(stdout);
1814: }
1815:
1816: if ((*s_etat_processus).pid_processus_pere != getpid())
1817: {
1818: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1819: rpl_sigterm);
1820: }
1821: else
1822: {
1823: (*s_etat_processus).var_volatile_traitement_sigint = -1;
1824:
1825: while(exclusion == 1);
1826: exclusion = 1;
1827:
1828: if ((*s_etat_processus).var_volatile_requete_arret == -1)
1829: {
1830: deverrouillage_gestionnaire_signaux();
1831: exclusion = 0;
1832: return;
1833: }
1834:
1835: (*s_etat_processus).var_volatile_requete_arret = -1;
1836: (*s_etat_processus).var_volatile_alarme = -1;
1837:
1838: exclusion = 0;
1839: }
1840: }
1841: else
1842: {
1843: if ((s_thread_principal = recherche_thread_principal(getpid()))
1844: != NULL)
1845: {
1846: envoi_signal_contexte(s_thread_principal, rpl_sigterm);
1847: }
1848: }
1849:
1850: deverrouillage_gestionnaire_signaux();
1851: return;
1852: }
1853:
1854: inline static void
1855: signal_int(struct_processus *s_etat_processus, pid_t pid)
1856: {
1857: struct_processus *s_thread_principal;
1858: volatile sig_atomic_t exclusion = 0;
1859:
1860: verrouillage_gestionnaire_signaux();
1861:
1862: if (pid == getpid())
1863: {
1864: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1865: {
1866: printf("[%d] RPL/SIGINT (thread %llu)\n", (int) getpid(),
1867: (unsigned long long) pthread_self());
1868: fflush(stdout);
1869: }
1870:
1871: if ((*s_etat_processus).pid_processus_pere != getpid())
1872: {
1873: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1874: rpl_sigint);
1875: }
1876: else
1877: {
1878: (*s_etat_processus).var_volatile_traitement_sigint = -1;
1879:
1880: while(exclusion == 1);
1881: exclusion = 1;
1882:
1883: if ((*s_etat_processus).var_volatile_requete_arret == -1)
1884: {
1885: deverrouillage_gestionnaire_signaux();
1886: exclusion = 0;
1887: return;
1888: }
1889:
1890: if ((*s_etat_processus).langue == 'F')
1891: {
1892: printf("+++Interruption\n");
1893: }
1894: else
1895: {
1896: printf("+++Interrupt\n");
1897: }
1898:
1899: fflush(stdout);
1900:
1901: (*s_etat_processus).var_volatile_requete_arret = -1;
1902: (*s_etat_processus).var_volatile_alarme = -1;
1903:
1904: exclusion = 0;
1905: }
1906: }
1907: else
1908: {
1909: if ((s_thread_principal = recherche_thread_principal(getpid()))
1910: != NULL)
1911: {
1912: envoi_signal_contexte(s_thread_principal, rpl_sigint);
1913: }
1914: }
1915:
1916: deverrouillage_gestionnaire_signaux();
1917: return;
1918: }
1919:
1920: // Récupération des signaux
1921: // - SIGFSTP
1922: //
1923: // ATTENTION :
1924: // Le signal SIGFSTP provient de la mort du processus de contrôle.
1925: // Sous certains systèmes (Linux...), la mort du terminal de contrôle
1926: // se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
1927: // (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
1928: // non initialisée (pointeur NULL) issue de TERMIO.
1929:
1930: void
1931: interruption2(int signal)
1932: {
1933: test_signal(signal);
1934: envoi_signal_processus(getpid(), rpl_sigtstp);
1935: return;
1936: }
1937:
1938: static inline void
1939: signal_tstp(struct_processus *s_etat_processus, pid_t pid)
1940: {
1941: struct_processus *s_thread_principal;
1942:
1943: verrouillage_gestionnaire_signaux();
1944:
1945: if (pid == getpid())
1946: {
1947: /*
1948: * 0 => fonctionnement normal
1949: * -1 => requête
1950: * 1 => requête acceptée en attente de traitement
1951: */
1952:
1953: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1954: {
1955: printf("[%d] RPL/SIGTSTP (thread %llu)\n", (int) getpid(),
1956: (unsigned long long) pthread_self());
1957: fflush(stdout);
1958: }
1959:
1960: if ((*s_etat_processus).var_volatile_processus_pere == 0)
1961: {
1962: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1963: rpl_sigtstp);
1964: }
1965: else
1966: {
1967: (*s_etat_processus).var_volatile_requete_arret2 = -1;
1968: }
1969: }
1970: else
1971: {
1972: // Envoi d'un signal au thread maître du groupe.
1973:
1974: if ((s_thread_principal = recherche_thread_principal(getpid()))
1975: != NULL)
1976: {
1977: envoi_signal_contexte(s_thread_principal, rpl_sigtstp);
1978: }
1979: }
1980:
1981: deverrouillage_gestionnaire_signaux();
1982: return;
1983: }
1984:
1985: void
1986: interruption3(int signal)
1987: {
1988: // Si on passe par ici, c'est qu'il est impossible de récupérer
1989: // l'erreur d'accès à la mémoire. On sort donc du programme quitte à
1990: // ce qu'il reste des processus orphelins.
1991:
1992: unsigned char message[] = "+++System : Uncaught access violation\n"
1993: "+++System : Aborting !\n";
1994:
1995: test_signal(signal);
1996:
1997: if (pid_processus_pere == getpid())
1998: {
1999: kill(pid_processus_pere, SIGALRM);
2000: }
2001:
2002: write(STDERR_FILENO, message, strlen(message));
2003: _exit(EXIT_FAILURE);
2004: }
2005:
2006: #if 0
2007: // Utiliser libsigsegv
2008: void INTERRUPTION3_A_FIXER()
2009: {
2010: pthread_t thread;
2011:
2012: struct_processus *s_etat_processus;
2013:
2014: test_signal(signal);
2015: verrouillage_gestionnaire_signaux();
2016:
2017: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2018: {
2019: deverrouillage_gestionnaire_signaux();
2020: return;
2021: }
2022:
2023: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2024: {
2025: printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),
2026: (unsigned long long) pthread_self());
2027: fflush(stdout);
2028: }
2029:
2030: if ((*s_etat_processus).var_volatile_recursivite == -1)
2031: {
2032: // Segfault dans un appel de fonction récursive
2033: deverrouillage_gestionnaire_signaux();
2034: longjmp(contexte, -1);
2035: }
2036: else
2037: {
2038: // Segfault dans une routine interne
2039: if (strncmp(getenv("LANG"), "fr", 2) == 0)
2040: {
2041: printf("+++Système : Violation d'accès\n");
2042: }
2043: else
2044: {
2045: printf("+++System : Access violation\n");
2046: }
2047:
2048: fflush(stdout);
2049:
2050: (*s_etat_processus).compteur_violation_d_acces++;
2051:
2052: if ((*s_etat_processus).compteur_violation_d_acces > 1)
2053: {
2054: // On vient de récupérer plus d'une erreur de segmentation
2055: // dans le même processus ou le même thread. L'erreur n'est pas
2056: // récupérable et on sort autoritairement du programme. Il peut
2057: // rester des processus orphelins en attente !
2058:
2059: if (strncmp(getenv("LANG"), "fr", 2) == 0)
2060: {
2061: printf("+++Système : Violation d'accès, tentative de "
2062: "terminaison de la tâche\n");
2063: printf(" (defauts multiples)\n");
2064: }
2065: else
2066: {
2067: printf("+++System : Access violation, trying to kill task "
2068: "(multiple defaults)\n");
2069: }
2070:
2071: fflush(stdout);
2072:
2073: deverrouillage_gestionnaire_signaux();
2074: exit(EXIT_FAILURE);
2075: }
2076: else
2077: {
2078: // Première erreur de segmentation. On essaie de terminer
2079: // proprement le thread ou le processus. Le signal ne peut être
2080: // envoyé que depuis le même processus.
2081:
2082: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2083: {
2084: if (pthread_equal(thread, pthread_self()) != 0)
2085: {
2086: deverrouillage_gestionnaire_signaux();
2087:
2088: if ((*s_etat_processus).pid_processus_pere != getpid())
2089: {
2090: // On est dans le thread principal d'un processus.
2091:
2092: longjmp(contexte_processus, -1);
2093: }
2094: else
2095: {
2096: // On est dans le thread principal du processus
2097: // père.
2098:
2099: longjmp(contexte_initial, -1);
2100: }
2101: }
2102: else
2103: {
2104: // On est dans un thread fils d'un thread principal.
2105:
2106: deverrouillage_gestionnaire_signaux();
2107: longjmp(contexte_thread, -1);
2108: }
2109: }
2110:
2111: // Là, on ramasse les miettes puisque le thread n'existe plus
2112: // dans la base (corruption de la mémoire).
2113:
2114: deverrouillage_gestionnaire_signaux();
2115: longjmp(contexte_initial, -1);
2116: }
2117: }
2118:
2119: deverrouillage_gestionnaire_signaux();
2120: return;
2121: }
2122: #endif
2123:
2124: // Traitement de rpl_sigstart
2125:
2126: static inline void
2127: signal_start(struct_processus *s_etat_processus, pid_t pid)
2128: {
2129: (*s_etat_processus).demarrage_fils = d_vrai;
2130: return;
2131: }
2132:
2133: // Traitement de rpl_sigcont
2134:
2135: static inline void
2136: signal_cont(struct_processus *s_etat_processus, pid_t pid)
2137: {
2138: (*s_etat_processus).redemarrage_processus = d_vrai;
2139: return;
2140: }
2141:
2142: // Traitement de rpl_sigstop
2143:
2144: static inline void
2145: signal_stop(struct_processus *s_etat_processus, pid_t pid)
2146: {
2147: struct_processus *s_thread_principal;
2148:
2149: verrouillage_gestionnaire_signaux();
2150:
2151: if (pid == getpid())
2152: {
2153: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2154: == NULL)
2155: {
2156: deverrouillage_gestionnaire_signaux();
2157: return;
2158: }
2159:
2160: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2161: {
2162: printf("[%d] RPL/SIGFSTOP (thread %llu)\n", (int) getpid(),
2163: (unsigned long long) pthread_self());
2164: fflush(stdout);
2165: }
2166:
2167: /*
2168: * var_globale_traitement_retarde_stop :
2169: * 0 -> traitement immédiat
2170: * 1 -> traitement retardé (aucun signal reçu)
2171: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2172: */
2173:
2174: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
2175: {
2176: (*s_etat_processus).var_volatile_requete_arret = -1;
2177: }
2178: else
2179: {
2180: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
2181: }
2182: }
2183: else
2184: {
2185: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2186: == NULL)
2187: {
2188: deverrouillage_gestionnaire_signaux();
2189: return;
2190: }
2191:
2192: // Envoi d'un signal au thread maître du groupe.
2193:
2194: if ((s_thread_principal = recherche_thread_principal(getpid()))
2195: != NULL)
2196: {
2197: envoi_signal_contexte(s_thread_principal, rpl_sigstop);
2198: }
2199: }
2200:
2201: deverrouillage_gestionnaire_signaux();
2202: return;
2203: }
2204:
2205: // Traitement de rpl_siginject
2206:
2207: static inline void
2208: signal_inject(struct_processus *s_etat_processus, pid_t pid)
2209: {
2210: verrouillage_gestionnaire_signaux();
2211:
2212: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2213: {
2214: deverrouillage_gestionnaire_signaux();
2215: return;
2216: }
2217:
2218: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2219: {
2220: printf("[%d] RPL/SIGINJECT (thread %llu)\n", (int) getpid(),
2221: (unsigned long long) pthread_self());
2222: fflush(stdout);
2223: }
2224:
2225: deverrouillage_gestionnaire_signaux();
2226: return;
2227: }
2228:
2229: // Récupération des signaux
2230: // - SIGPIPE
2231:
2232: void
2233: interruption5(int signal)
2234: {
2235: unsigned char message[] = "+++System : SIGPIPE\n"
2236: "+++System : Aborting !\n";
2237:
2238: test_signal(signal);
2239:
2240: if (pid_processus_pere == getpid())
2241: {
2242: envoi_signal_processus(pid_processus_pere, rpl_sigalrm);
2243: }
2244:
2245: write(STDERR_FILENO, message, strlen(message));
2246: return;
2247: }
2248:
2249: static inline void
2250: signal_urg(struct_processus *s_etat_processus, pid_t pid)
2251: {
2252: struct_processus *s_thread_principal;
2253:
2254: verrouillage_gestionnaire_signaux();
2255:
2256: if (pid == getpid())
2257: {
2258: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2259: == NULL)
2260: {
2261: deverrouillage_gestionnaire_signaux();
2262: return;
2263: }
2264:
2265: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2266: {
2267: printf("[%d] RPL/SIGURG (thread %llu)\n", (int) getpid(),
2268: (unsigned long long) pthread_self());
2269: fflush(stdout);
2270: }
2271:
2272: (*s_etat_processus).var_volatile_alarme = -1;
2273: (*s_etat_processus).var_volatile_requete_arret = -1;
2274: }
2275: else
2276: {
2277: // Envoi d'un signal au thread maître du groupe.
2278:
2279: if ((s_thread_principal = recherche_thread_principal(getpid()))
2280: != NULL)
2281: {
2282: envoi_signal_contexte(s_thread_principal, rpl_sigurg);
2283: }
2284: }
2285:
2286: deverrouillage_gestionnaire_signaux();
2287: return;
2288: }
2289:
2290: // Traitement de rpl_sigabort
2291:
2292: static inline void
2293: signal_abort(struct_processus *s_etat_processus, pid_t pid)
2294: {
2295: struct_processus *s_thread_principal;
2296:
2297: verrouillage_gestionnaire_signaux();
2298:
2299: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2300: {
2301: deverrouillage_gestionnaire_signaux();
2302: return;
2303: }
2304:
2305: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2306: {
2307: printf("[%d] RPL/SIGABORT (thread %llu)\n", (int) getpid(),
2308: (unsigned long long) pthread_self());
2309: fflush(stdout);
2310: }
2311:
2312: if (pid == getpid())
2313: {
2314: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2315: == NULL)
2316: {
2317: deverrouillage_gestionnaire_signaux();
2318: return;
2319: }
2320:
2321: (*s_etat_processus).arret_depuis_abort = -1;
2322:
2323: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2324: {
2325: printf("[%d] SIGFABORT (thread %llu)\n", (int) getpid(),
2326: (unsigned long long) pthread_self());
2327: fflush(stdout);
2328: }
2329:
2330: /*
2331: * var_globale_traitement_retarde_stop :
2332: * 0 -> traitement immédiat
2333: * 1 -> traitement retardé (aucun signal reçu)
2334: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2335: */
2336:
2337: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
2338: {
2339: (*s_etat_processus).var_volatile_requete_arret = -1;
2340: }
2341: else
2342: {
2343: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
2344: }
2345: }
2346: else
2347: {
2348: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2349: == NULL)
2350: {
2351: deverrouillage_gestionnaire_signaux();
2352: return;
2353: }
2354:
2355: (*s_etat_processus).arret_depuis_abort = -1;
2356:
2357: // Envoi d'un signal au thread maître du groupe.
2358:
2359: if ((s_thread_principal = recherche_thread_principal(getpid()))
2360: != NULL)
2361: {
2362: envoi_signal_contexte(s_thread_principal, rpl_sigabort);
2363: }
2364: }
2365:
2366: deverrouillage_gestionnaire_signaux();
2367: return;
2368: }
2369:
2370: // Récupération des signaux
2371: // - SIGHUP
2372:
2373: void
2374: interruption4(int signal)
2375: {
2376: test_signal(signal);
2377: envoi_signal_processus(getpid(), rpl_sighup);
2378: return;
2379: }
2380:
2381: static inline void
2382: signal_hup(struct_processus *s_etat_processus, pid_t pid)
2383: {
2384: file *fichier;
2385:
2386: unsigned char nom[8 + 64 + 1];
2387:
2388: verrouillage_gestionnaire_signaux();
2389:
2390: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2391: {
2392: deverrouillage_gestionnaire_signaux();
2393: return;
2394: }
2395:
2396: snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
2397: (unsigned long) pthread_self());
2398:
2399: if ((fichier = fopen(nom, "w+")) != NULL)
2400: {
2401: fclose(fichier);
2402:
2403: freopen(nom, "w", stdout);
2404: freopen(nom, "w", stderr);
2405: }
2406:
2407: freopen("/dev/null", "r", stdin);
2408:
2409: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2410: {
2411: printf("[%d] SIGHUP (thread %llu)\n", (int) getpid(),
2412: (unsigned long long) pthread_self());
2413: fflush(stdout);
2414: }
2415:
2416: deverrouillage_gestionnaire_signaux();
2417: return;
2418: }
2419:
2420: void
2421: traitement_exceptions_gsl(const char *reason, const char *file,
2422: int line, int gsl_errno)
2423: {
2424: struct_processus *s_etat_processus;
2425:
2426: verrouillage_gestionnaire_signaux();
2427:
2428: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2429: {
2430: deverrouillage_gestionnaire_signaux();
2431: return;
2432: }
2433:
2434: (*s_etat_processus).var_volatile_exception_gsl = gsl_errno;
2435: deverrouillage_gestionnaire_signaux();
2436: return;
2437: }
2438:
2439: static inline void
2440: envoi_interruptions(struct_processus *s_etat_processus, enum signaux_rpl signal,
2441: pid_t pid_source)
2442: {
2443: unsigned char message[] = "+++System : Spurious signa !\n";
2444:
2445: switch(signal)
2446: {
2447: case rpl_sigint:
2448: signal_int(s_etat_processus, pid_source);
2449: break;
2450:
2451: case rpl_sigterm:
2452: signal_term(s_etat_processus, pid_source);
2453: break;
2454:
2455: case rpl_sigstart:
2456: signal_start(s_etat_processus, pid_source);
2457: break;
2458:
2459: case rpl_sigcont:
2460: signal_cont(s_etat_processus, pid_source);
2461: break;
2462:
2463: case rpl_sigstop:
2464: signal_stop(s_etat_processus, pid_source);
2465: break;
2466:
2467: case rpl_sigabort:
2468: signal_abort(s_etat_processus, pid_source);
2469: break;
2470:
2471: case rpl_sigurg:
2472: signal_urg(s_etat_processus, pid_source);
2473: break;
2474:
2475: case rpl_siginject:
2476: signal_inject(s_etat_processus, pid_source);
2477: break;
2478:
2479: case rpl_sigalrm:
2480: signal_alrm(s_etat_processus, pid_source);
2481: break;
2482:
2483: case rpl_sighup:
2484: signal_hup(s_etat_processus, pid_source);
2485: break;
2486:
2487: case rpl_sigtstp:
2488: signal_tstp(s_etat_processus, pid_source);
2489: break;
2490:
2491: default:
2492: write(STDERR_FILENO, message, strlen(message));
2493: break;
2494: }
2495:
2496: return;
2497: }
2498:
2499: void
2500: scrutation_interruptions(struct_processus *s_etat_processus)
2501: {
2502: // Interruptions qui arrivent sur le processus depuis un
2503: // processus externe.
2504:
2505: // Interruptions qui arrivent depuis le groupe courant de threads.
2506:
2507: if ((*s_etat_processus).pointeur_signal_lecture !=
2508: (*s_etat_processus).pointeur_signal_ecriture)
2509: {
2510: // Il y a un signal dans la queue du thread courant. On le traite.
2511: }
2512:
2513: return;
2514: }
2515:
2516: int
2517: envoi_signal_processus(pid_t pid, enum signaux_rpl signal)
2518: {
2519: // Il s'agit d'ouvrir le segment de mémoire partagée, de le projeter en
2520: // mémoire puis d'y inscrire le signal à traiter.
2521:
2522: return(0);
2523: }
2524:
2525: int
2526: envoi_signal_thread(pthread_t tid, enum signaux_rpl signal)
2527: {
2528: // Un signal est envoyé d'un thread à un autre thread du même processus.
2529:
2530: return(0);
2531: }
2532:
2533: int
2534: envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,
2535: enum signaux_rpl signal)
2536: {
2537: (*s_etat_processus_a_signaler).signaux_en_queue
2538: [(*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1] =
2539: signal;
2540:
2541: // On valide l'écriture. Cela évite l'utilisation d'un mutex.
2542:
2543: (*s_etat_processus_a_signaler).pointeur_signal_ecriture++;
2544: return(0);
2545: }
2546:
2547:
2548: /*
2549: ================================================================================
2550: Fonction renvoyant le nom du segment de mémoire partagée en fonction
2551: du pid du processus.
2552: ================================================================================
2553: Entrée : Chemin absolue servant de racine, pid du processus
2554: --------------------------------------------------------------------------------
2555: Sortie : NULL ou nom du segment
2556: --------------------------------------------------------------------------------
2557: Effet de bord : Néant
2558: ================================================================================
2559: */
2560:
2561: static unsigned char *
2562: nom_segment(unsigned char *chemin, pid_t pid)
2563: {
2564: unsigned char *fichier;
2565:
2566: # ifdef IPCS_SYSV // !POSIX
2567: # ifndef OS2 // !OS2
2568:
2569: if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) *
2570: sizeof(unsigned char))) == NULL)
2571: {
2572: return(NULL);
2573: }
2574:
2575: sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);
2576: # else // OS2
2577: if ((fichier = malloc((10 + 256 + 1) * sizeof(unsigned char)))
2578: == NULL)
2579: {
2580: return(NULL);
2581: }
2582:
2583: sprintf(fichier, "\\SHAREMEM\\RPL-SIGQUEUES-%d", (int) pid);
2584: # endif // OS2
2585: # else // POSIX
2586:
2587: if ((fichier = malloc((1 + 256 + 1) *
2588: sizeof(unsigned char))) == NULL)
2589: {
2590: return(NULL);
2591: }
2592:
2593: sprintf(fichier, "/RPL-SIGQUEUES-%d", (int) pid);
2594: # endif
2595:
2596: return(fichier);
2597: }
2598:
2599:
2600: /*
2601: ================================================================================
2602: Fonction créant un segment de mémoire partagée destiné à contenir
2603: la queue des signaux.
2604: ================================================================================
2605: Entrée : structure de description du processus
2606: --------------------------------------------------------------------------------
2607: Sortie : Néant
2608: --------------------------------------------------------------------------------
2609: Effet de bord : Néant
2610: ================================================================================
2611: */
2612:
2613: void
2614: creation_queue_signaux(struct_processus *s_etat_processus)
2615: {
2616: int segment;
2617:
2618: pthread_mutexattr_t attributs_mutex;
2619:
2620: unsigned char *nom;
2621:
2622: # ifndef IPCS_SYSV // POSIX
2623:
2624: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
2625: getpid())) == NULL)
2626: {
2627: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2628: return;
2629: }
2630:
2631: if ((segment = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,
2632: S_IRUSR | S_IWUSR)) == -1)
2633: {
2634: free(nom);
2635: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2636: return;
2637: }
2638:
2639: if (ftruncate(segment, sizeof(struct_queue_signaux)) == -1)
2640: {
2641: free(nom);
2642: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2643: return;
2644: }
2645:
2646: s_queue_signaux = mmap(NULL, sizeof(struct_queue_signaux),
2647: PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0);
2648: close(segment);
2649:
2650: if (((void *) s_queue_signaux) == ((void *) -1))
2651: {
2652: if (shm_unlink(nom) == -1)
2653: {
2654: free(nom);
2655: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2656: return;
2657: }
2658:
2659: free(nom);
2660: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2661: return;
2662: }
2663:
2664: free(nom);
2665:
2666: pthread_mutexattr_init(&attributs_mutex);
2667: pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL);
2668: pthread_mutex_init(&((*s_queue_signaux).mutex), &attributs_mutex);
2669: pthread_mutexattr_destroy(&attributs_mutex);
2670:
2671: (*s_queue_signaux).pointeur_lecture = 0;
2672: (*s_queue_signaux).pointeur_ecriture = 0;
2673:
2674: # else // SystemV
2675: # ifndef OS2
2676:
2677: file *desc;
2678:
2679: key_t clef;
2680:
2681: // Création d'un segment de données associé au PID du processus courant
2682:
2683: chemin = (*s_etat_processus).chemin_fichiers_temporaires;
2684:
2685: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
2686: getpid())) == NULL)
2687: {
2688: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2689: return;
2690: }
2691:
2692: if ((desc = fopen(nom, "w")) == NULL)
2693: {
2694: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
2695: return;
2696: }
2697:
2698: fclose(desc);
2699:
2700: if ((clef = ftok(nom, 1)) == -1)
2701: {
2702: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2703: return;
2704: }
2705:
2706: free(nom);
2707:
2708: if ((segment = shmget(clef,
2709: nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
2710: IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)
2711: {
2712: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2713: return;
2714: }
2715:
2716: fifos = shmat(segment, NULL, 0);
2717:
2718: if (((void *) fifos) == ((void *) -1))
2719: {
2720: if (shmctl(segment, IPC_RMID, 0) == -1)
2721: {
2722: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2723: return;
2724: }
2725:
2726: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2727: return;
2728: }
2729:
2730: # else
2731:
2732: if ((nom = nom_segment(NULL, getpid())) == NULL)
2733: {
2734: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2735: return;
2736: }
2737:
2738: if (DosAllocSharedMem(&ptr_os2, nom, nombre_queues *
2739: ((2 * longueur_queue) + 4) * sizeof(int),
2740: PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
2741: {
2742: free(nom);
2743: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2744: return;
2745: }
2746:
2747: free(nom);
2748: fifos = ptr_os2;
2749:
2750: # endif
2751: # endif
2752:
2753: return;
2754: }
2755:
2756:
2757: /*
2758: ================================================================================
2759: Fonction libérant le segment de mémoire partagée destiné à contenir
2760: la queue des signaux.
2761: ================================================================================
2762: Entrée : structure de description du processus
2763: --------------------------------------------------------------------------------
2764: Sortie : Néant
2765: --------------------------------------------------------------------------------
2766: Effet de bord : Néant
2767: ================================================================================
2768: */
2769:
2770: void
2771: liberation_queue_signaux(struct_processus *s_etat_processus)
2772: {
2773: # ifdef IPCS_SYSV // SystemV
2774: # ifndef OS2
2775: # else // OS/2
2776: # endif
2777: # else // POSIX
2778: if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
2779: {
2780: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2781: return;
2782: }
2783: # endif
2784:
2785: return;
2786: }
2787:
2788:
2789: /*
2790: ================================================================================
2791: Fonction détruisant le segment de mémoire partagée destiné à contenir
2792: la queue des signaux.
2793: ================================================================================
2794: Entrée : structure de description du processus
2795: --------------------------------------------------------------------------------
2796: Sortie : Néant
2797: --------------------------------------------------------------------------------
2798: Effet de bord : Néant
2799: ================================================================================
2800: */
2801:
2802: void
2803: destruction_queue_signaux(struct_processus *s_etat_processus)
2804: {
2805: unsigned char *nom;
2806:
2807: # ifdef IPCS_SYSV // SystemV
2808: # ifndef OS2
2809:
2810: if (shmdt(fifos) == -1)
2811: {
2812: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2813: return;
2814: }
2815:
2816: if (shmctl(segment, IPC_RMID, 0) == -1)
2817: {
2818: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2819: return;
2820: }
2821:
2822: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
2823: getpid())) == NULL)
2824: {
2825: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2826: return;
2827: }
2828:
2829: unlink(nom);
2830: free(nom);
2831:
2832: # else
2833:
2834: if (DosFreeMem(fifos) != 0)
2835: {
2836: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2837: return;
2838: }
2839:
2840: # endif
2841: # else // POSIX
2842:
2843: if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
2844: {
2845: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2846: return;
2847: }
2848:
2849: if ((nom = nom_segment(NULL, getpid())) == NULL)
2850: {
2851: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2852: return;
2853: }
2854:
2855: if (shm_unlink(nom) != 0)
2856: {
2857: free(nom);
2858: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2859: return;
2860: }
2861:
2862: free(nom);
2863:
2864: # endif
2865:
2866: return;
2867: }
2868:
2869: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>