Annotation of rpl/src/interruptions.c, revision 1.35
1.1 bertrand 1: /*
2: ================================================================================
1.26 bertrand 3: RPL/2 (R) version 4.0.18
1.1 bertrand 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:
1.27 bertrand 23: #include "rpl-conv.h"
1.1 bertrand 24:
25:
26: /*
27: ================================================================================
28: Procédures de gestion par thread des variables issues des gestionnaires
29: de signaux
30: ================================================================================
31: Entrée : variable globale
32: --------------------------------------------------------------------------------
33: Sortie : variable globale modifiée
34: --------------------------------------------------------------------------------
35: Effets de bord : néant
36: ================================================================================
37: */
38:
39: typedef struct thread
40: {
41: pid_t pid;
42: pthread_t tid;
43:
44: logical1 thread_principal;
45:
46: struct_processus *s_etat_processus;
47: } struct_thread;
48:
49: typedef struct liste_chainee_volatile
50: {
51: volatile struct liste_chainee_volatile *suivant;
52: volatile void *donnee;
53: } struct_liste_chainee_volatile;
54:
55:
56: static volatile struct_liste_chainee_volatile *liste_threads
57: = NULL;
58: static volatile struct_liste_chainee_volatile *liste_threads_surveillance
59: = NULL;
60:
61: void
62: modification_pid_thread_pere(struct_processus *s_etat_processus)
63: {
64: // La variable existe toujours et aucun thread concurrent ne peut
65: // la modifier puisque cette routine ne peut être appelée que depuis
66: // DAEMON.
67:
68: (*((struct_thread *) (*liste_threads).donnee)).pid =
69: (*s_etat_processus).pid_processus_pere;
70:
71: return;
72: }
73:
74: void
75: insertion_thread(struct_processus *s_etat_processus, logical1 thread_principal)
76: {
77: sigset_t oldset;
78: sigset_t set;
79:
80: volatile struct_liste_chainee_volatile *l_nouvel_objet;
81:
82: sigfillset(&set);
83: pthread_sigmask(SIG_BLOCK, &set, &oldset);
84:
85: if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
86: == NULL)
87: {
88: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
89: sigpending(&set);
90:
91: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
92: return;
93: }
94:
95: if (((*l_nouvel_objet).donnee = malloc(sizeof(struct_thread))) == NULL)
96: {
97: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
98: sigpending(&set);
99:
100: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
101: return;
102: }
103:
104: (*((struct_thread *) (*l_nouvel_objet).donnee)).pid = getpid();
105: (*((struct_thread *) (*l_nouvel_objet).donnee)).tid = pthread_self();
106: (*((struct_thread *) (*l_nouvel_objet).donnee)).thread_principal =
107: thread_principal;
108: (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus =
109: s_etat_processus;
110:
1.13 bertrand 111: # ifndef SEMAPHORES_NOMMES
112: while(sem_wait(&semaphore_liste_threads) == -1)
113: # else
114: while(sem_wait(semaphore_liste_threads) == -1)
115: # endif
116: {
117: if (errno != EINTR)
118: {
119: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
120: sigpending(&set);
121:
122: (*s_etat_processus).erreur_systeme = d_es_processus;
123: return;
124: }
125: }
126:
127: (*l_nouvel_objet).suivant = liste_threads;
1.1 bertrand 128: liste_threads = l_nouvel_objet;
129:
1.8 bertrand 130: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 131: if (sem_post(&semaphore_liste_threads) != 0)
1.8 bertrand 132: # else
133: if (sem_post(semaphore_liste_threads) != 0)
134: # endif
1.1 bertrand 135: {
136: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
137: sigpending(&set);
138:
139: (*s_etat_processus).erreur_systeme = d_es_processus;
140: return;
141: }
142:
143: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
144: sigpending(&set);
145: return;
146: }
147:
148: void
149: insertion_thread_surveillance(struct_processus *s_etat_processus,
150: struct_descripteur_thread *s_argument_thread)
151: {
152: sigset_t oldset;
153: sigset_t set;
154:
155: volatile struct_liste_chainee_volatile *l_nouvel_objet;
156:
157: sigfillset(&set);
158: pthread_sigmask(SIG_BLOCK, &set, &oldset);
159:
1.13 bertrand 160: if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
161: == NULL)
162: {
163: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
164: sigpending(&set);
165:
166: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
167: return;
168: }
169:
1.8 bertrand 170: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 171: while(sem_wait(&semaphore_liste_threads) == -1)
1.8 bertrand 172: # else
173: while(sem_wait(semaphore_liste_threads) == -1)
174: # endif
1.1 bertrand 175: {
176: if (errno != EINTR)
177: {
178: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
179: sigpending(&set);
180:
181: (*s_etat_processus).erreur_systeme = d_es_processus;
182: return;
183: }
184: }
185:
1.22 bertrand 186: pthread_mutex_lock(&((*s_argument_thread).mutex));
1.21 bertrand 187: (*s_argument_thread).nombre_references++;
1.22 bertrand 188: pthread_mutex_unlock(&((*s_argument_thread).mutex));
189:
1.1 bertrand 190: (*l_nouvel_objet).suivant = liste_threads_surveillance;
191: (*l_nouvel_objet).donnee = (void *) s_argument_thread;
192:
193: liste_threads_surveillance = l_nouvel_objet;
194:
1.8 bertrand 195: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 196: if (sem_post(&semaphore_liste_threads) != 0)
1.8 bertrand 197: # else
198: if (sem_post(semaphore_liste_threads) != 0)
199: # endif
1.1 bertrand 200: {
201: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
202: sigpending(&set);
203:
204: (*s_etat_processus).erreur_systeme = d_es_processus;
205: return;
206: }
207:
208: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
209: sigpending(&set);
210: return;
211: }
212:
213: void
214: retrait_thread(struct_processus *s_etat_processus)
215: {
216: sigset_t oldset;
217: sigset_t set;
218:
219: volatile struct_liste_chainee_volatile *l_element_precedent;
220: volatile struct_liste_chainee_volatile *l_element_courant;
221:
222: sigfillset(&set);
223: pthread_sigmask(SIG_BLOCK, &set, &oldset);
224:
1.8 bertrand 225: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 226: while(sem_wait(&semaphore_liste_threads) == -1)
1.8 bertrand 227: # else
228: while(sem_wait(semaphore_liste_threads) == -1)
229: # endif
1.1 bertrand 230: {
231: if (errno != EINTR)
232: {
233: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
234: sigpending(&set);
235:
236: (*s_etat_processus).erreur_systeme = d_es_processus;
237: return;
238: }
239: }
240:
241: l_element_precedent = NULL;
242: l_element_courant = liste_threads;
243:
244: while(l_element_courant != NULL)
245: {
246: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
247: == getpid()) && (pthread_equal((*((struct_thread *)
248: (*l_element_courant).donnee)).tid, pthread_self()) != 0))
249: {
250: break;
251: }
252:
253: l_element_precedent = l_element_courant;
254: l_element_courant = (*l_element_courant).suivant;
255: }
256:
257: if (l_element_courant == NULL)
258: {
1.8 bertrand 259: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 260: sem_post(&semaphore_liste_threads);
1.8 bertrand 261: # else
262: sem_post(semaphore_liste_threads);
263: # endif
1.1 bertrand 264: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
265: sigpending(&set);
266:
267: (*s_etat_processus).erreur_systeme = d_es_processus;
268: return;
269: }
270:
271: if (l_element_precedent == NULL)
272: {
273: liste_threads = (*l_element_courant).suivant;
274: }
275: else
276: {
277: (*l_element_precedent).suivant = (*l_element_courant).suivant;
278: }
279:
280: if (pthread_setspecific(semaphore_fork_processus_courant, NULL) != 0)
281: {
282: (*s_etat_processus).erreur_systeme = d_es_processus;
283:
1.8 bertrand 284: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 285: sem_post(&semaphore_liste_threads);
1.8 bertrand 286: # else
287: sem_post(semaphore_liste_threads);
288: # endif
1.1 bertrand 289: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
290: sigpending(&set);
291: return;
292: }
293:
1.8 bertrand 294: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 295: if (sem_post(&semaphore_liste_threads) != 0)
1.8 bertrand 296: # else
297: if (sem_post(semaphore_liste_threads) != 0)
298: # endif
1.1 bertrand 299: {
300: (*s_etat_processus).erreur_systeme = d_es_processus;
301:
302: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
303: sigpending(&set);
304: return;
305: }
306:
1.13 bertrand 307: free((void *) (*l_element_courant).donnee);
308: free((struct_liste_chainee_volatile *) l_element_courant);
309:
1.1 bertrand 310: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
311: sigpending(&set);
312: return;
313: }
314:
315: void
316: retrait_thread_surveillance(struct_processus *s_etat_processus,
317: struct_descripteur_thread *s_argument_thread)
318: {
319: sigset_t set;
320: sigset_t oldset;
321:
322: volatile struct_liste_chainee_volatile *l_element_precedent;
323: volatile struct_liste_chainee_volatile *l_element_courant;
324:
325: sigfillset(&set);
326: pthread_sigmask(SIG_BLOCK, &set, &oldset);
327:
1.8 bertrand 328: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 329: while(sem_wait(&semaphore_liste_threads) == -1)
1.8 bertrand 330: # else
331: while(sem_wait(semaphore_liste_threads) == -1)
332: # endif
1.1 bertrand 333: {
334: if (errno != EINTR)
335: {
336: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
337: sigpending(&set);
338:
339: (*s_etat_processus).erreur_systeme = d_es_processus;
340: return;
341: }
342: }
343:
344: l_element_precedent = NULL;
345: l_element_courant = liste_threads_surveillance;
346:
347: while(l_element_courant != NULL)
348: {
349: if ((*l_element_courant).donnee == (void *) s_argument_thread)
350: {
351: break;
352: }
353:
354: l_element_precedent = l_element_courant;
355: l_element_courant = (*l_element_courant).suivant;
356: }
357:
358: if (l_element_courant == NULL)
359: {
1.8 bertrand 360: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 361: sem_post(&semaphore_liste_threads);
1.8 bertrand 362: # else
363: sem_post(semaphore_liste_threads);
364: # endif
1.1 bertrand 365: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
366: sigpending(&set);
367:
368: (*s_etat_processus).erreur_systeme = d_es_processus;
369: return;
370: }
371:
372: if (l_element_precedent == NULL)
373: {
374: liste_threads_surveillance = (*l_element_courant).suivant;
375: }
376: else
377: {
378: (*l_element_precedent).suivant = (*l_element_courant).suivant;
379: }
380:
381: if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)
382: {
1.12 bertrand 383: # ifndef SEMAPHORES_NOMMES
384: sem_post(&semaphore_liste_threads);
385: # else
386: sem_post(semaphore_liste_threads);
387: # endif
1.1 bertrand 388: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
389: sigpending(&set);
390:
391: (*s_etat_processus).erreur_systeme = d_es_processus;
392: return;
393: }
394:
395: (*s_argument_thread).nombre_references--;
396:
397: BUG((*s_argument_thread).nombre_references < 0,
398: printf("(*s_argument_thread).nombre_references = %d\n",
399: (int) (*s_argument_thread).nombre_references));
400:
401: if ((*s_argument_thread).nombre_references == 0)
402: {
403: if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
404: {
1.12 bertrand 405: # ifndef SEMAPHORES_NOMMES
406: sem_post(&semaphore_liste_threads);
407: # else
408: sem_post(semaphore_liste_threads);
409: # endif
1.1 bertrand 410: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
411: sigpending(&set);
412:
413: (*s_etat_processus).erreur_systeme = d_es_processus;
414: return;
415: }
416:
417: pthread_mutex_destroy(&((*s_argument_thread).mutex));
418: free(s_argument_thread);
419: }
420: else
421: {
422: if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
423: {
1.12 bertrand 424: # ifndef SEMAPHORES_NOMMES
425: sem_post(&semaphore_liste_threads);
426: # else
427: sem_post(semaphore_liste_threads);
428: # endif
1.1 bertrand 429: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
430: sigpending(&set);
431:
432: (*s_etat_processus).erreur_systeme = d_es_processus;
433: return;
434: }
435: }
436:
1.8 bertrand 437: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 438: if (sem_post(&semaphore_liste_threads) != 0)
1.8 bertrand 439: # else
440: if (sem_post(semaphore_liste_threads) != 0)
441: # endif
1.1 bertrand 442: {
443: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
444: sigpending(&set);
445:
446: (*s_etat_processus).erreur_systeme = d_es_processus;
447: return;
448: }
449:
1.13 bertrand 450: free((struct_liste_chainee_volatile *) l_element_courant);
451:
1.1 bertrand 452: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
453: sigpending(&set);
1.20 bertrand 454:
1.1 bertrand 455: return;
456: }
457:
458: void
459: verrouillage_threads_concurrents(struct_processus *s_etat_processus)
460: {
461: volatile struct_liste_chainee_volatile *l_element_courant;
462:
1.8 bertrand 463: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 464: while(sem_wait(&semaphore_liste_threads) == -1)
1.8 bertrand 465: # else
466: while(sem_wait(semaphore_liste_threads) == -1)
467: # endif
1.1 bertrand 468: {
469: if (errno != EINTR)
470: {
471: (*s_etat_processus).erreur_systeme = d_es_processus;
472: return;
473: }
474: }
475:
476: l_element_courant = liste_threads;
477:
478: while(l_element_courant != NULL)
479: {
480: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
481: == getpid()) && (pthread_equal((*((struct_thread *)
482: (*l_element_courant).donnee)).tid, pthread_self()) == 0))
483: {
1.8 bertrand 484: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 485: while(sem_wait(&((*(*((struct_thread *) (*l_element_courant)
486: .donnee)).s_etat_processus).semaphore_fork)) == -1)
1.8 bertrand 487: # else
488: while(sem_wait((*(*((struct_thread *) (*l_element_courant)
489: .donnee)).s_etat_processus).semaphore_fork) == -1)
490: # endif
1.1 bertrand 491: {
492: if (errno != EINTR)
493: {
494: (*s_etat_processus).erreur_systeme = d_es_processus;
495: return;
496: }
497: }
498: }
499:
500: l_element_courant = (*l_element_courant).suivant;
501: }
502:
503: return;
504: }
505:
506: void
507: deverrouillage_threads_concurrents(struct_processus *s_etat_processus)
508: {
509: volatile struct_liste_chainee_volatile *l_element_courant;
510:
511: l_element_courant = liste_threads;
512:
513: while(l_element_courant != NULL)
514: {
515: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
516: == getpid()) && (pthread_equal((*((struct_thread *)
517: (*l_element_courant).donnee)).tid, pthread_self()) == 0))
518: {
1.8 bertrand 519: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 520: if (sem_post(&((*(*((struct_thread *)
521: (*l_element_courant).donnee)).s_etat_processus)
522: .semaphore_fork)) != 0)
1.8 bertrand 523: # else
524: if (sem_post((*(*((struct_thread *)
525: (*l_element_courant).donnee)).s_etat_processus)
526: .semaphore_fork) != 0)
527: # endif
1.1 bertrand 528: {
1.8 bertrand 529: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 530: if (sem_post(&semaphore_liste_threads) != 0)
531: {
532: (*s_etat_processus).erreur_systeme = d_es_processus;
533: return;
534: }
1.8 bertrand 535: # else
536: if (sem_post(semaphore_liste_threads) != 0)
537: {
538: (*s_etat_processus).erreur_systeme = d_es_processus;
539: return;
540: }
541: # endif
1.1 bertrand 542:
543: (*s_etat_processus).erreur_systeme = d_es_processus;
544: return;
545: }
546: }
547:
548: l_element_courant = (*l_element_courant).suivant;
549: }
550:
1.8 bertrand 551: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 552: if (sem_post(&semaphore_liste_threads) != 0)
1.8 bertrand 553: # else
554: if (sem_post(semaphore_liste_threads) != 0)
555: # endif
1.1 bertrand 556: {
557: (*s_etat_processus).erreur_systeme = d_es_processus;
558: return;
559: }
560:
561: return;
562: }
563:
564: void
565: liberation_threads(struct_processus *s_etat_processus)
566: {
567: logical1 suppression_variables_partagees;
568:
569: sigset_t oldset;
570: sigset_t set;
571:
572: struct_descripteur_thread *s_argument_thread;
573:
574: struct_processus *candidat;
575:
576: unsigned long i;
577:
578: void *element_candidat;
579: void *element_courant;
580: void *element_suivant;
581:
582: volatile struct_liste_chainee_volatile *l_element_courant;
583: volatile struct_liste_chainee_volatile *l_element_suivant;
584:
585: sigfillset(&set);
586: pthread_sigmask(SIG_BLOCK, &set, &oldset);
587:
1.8 bertrand 588: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 589: while(sem_wait(&semaphore_liste_threads) == -1)
1.8 bertrand 590: # else
591: while(sem_wait(semaphore_liste_threads) == -1)
592: # endif
1.1 bertrand 593: {
594: if (errno != EINTR)
595: {
596: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
597: (*s_etat_processus).erreur_systeme = d_es_processus;
598: return;
599: }
600: }
601:
602: l_element_courant = liste_threads;
603: suppression_variables_partagees = d_faux;
604:
605: while(l_element_courant != NULL)
606: {
607: if ((*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus
608: != s_etat_processus)
609: {
610: candidat = s_etat_processus;
611: s_etat_processus = (*((struct_thread *)
612: (*l_element_courant).donnee)).s_etat_processus;
613: free((*s_etat_processus).localisation);
614:
615: // (*s_etat_processus).instruction_courante peut pointer sur
616: // n'importe quoi (une instruction courante ou un champ d'une
617: // structure objet). On ne le libère pas quitte à avoir une
618: // petite fuite mémoire dans le processus fils.
619:
620: if ((*s_etat_processus).instruction_courante != NULL)
621: {
622: //free((*s_etat_processus).instruction_courante);
623: }
624:
625: close((*s_etat_processus).pipe_acquittement);
626: close((*s_etat_processus).pipe_donnees);
627: close((*s_etat_processus).pipe_injections);
628: close((*s_etat_processus).pipe_nombre_injections);
629: close((*s_etat_processus).pipe_interruptions);
630: close((*s_etat_processus).pipe_nombre_objets_attente);
631: close((*s_etat_processus).pipe_nombre_interruptions_attente);
632:
1.13 bertrand 633: liberation(s_etat_processus, (*s_etat_processus).at_exit);
634:
1.1 bertrand 635: if ((*s_etat_processus).nom_fichier_impression != NULL)
636: {
637: free((*s_etat_processus).nom_fichier_impression);
638: }
639:
640: while((*s_etat_processus).fichiers_graphiques != NULL)
641: {
642: free((*(*s_etat_processus).fichiers_graphiques).nom);
643:
644: if ((*(*s_etat_processus).fichiers_graphiques).legende != NULL)
645: {
646: free((*(*s_etat_processus).fichiers_graphiques).legende);
647: }
648:
649: element_courant = (*s_etat_processus).fichiers_graphiques;
650: (*s_etat_processus).fichiers_graphiques =
651: (*(*s_etat_processus).fichiers_graphiques).suivant;
652:
653: free(element_courant);
654: }
655:
656: if ((*s_etat_processus).entree_standard != NULL)
657: {
658: pclose((*s_etat_processus).entree_standard);
659: }
660:
661: if ((*s_etat_processus).generateur_aleatoire != NULL)
662: {
663: liberation_generateur_aleatoire(s_etat_processus);
664: }
665:
666: if ((*s_etat_processus).instruction_derniere_erreur != NULL)
667: {
668: free((*s_etat_processus).instruction_derniere_erreur);
669: (*s_etat_processus).instruction_derniere_erreur = NULL;
670: }
671:
672: element_courant = (void *) (*s_etat_processus)
673: .l_base_pile_processus;
674: while(element_courant != NULL)
675: {
1.20 bertrand 676: s_argument_thread = (struct_descripteur_thread *)
677: (*((struct_liste_chainee *) element_courant)).donnee;
678:
679: if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)
680: {
681: (*s_etat_processus).erreur_systeme = d_es_processus;
682: sem_post(&semaphore_liste_threads);
683: return;
684: }
685:
686: (*s_argument_thread).nombre_references--;
687:
688: BUG((*s_argument_thread).nombre_references < 0,
689: printf("(*s_argument_thread).nombre_references = %d\n",
690: (int) (*s_argument_thread).nombre_references));
691:
692: if ((*s_argument_thread).nombre_references == 0)
693: {
694: close((*s_argument_thread).pipe_objets[0]);
695: close((*s_argument_thread).pipe_acquittement[1]);
696: close((*s_argument_thread).pipe_injections[1]);
697: close((*s_argument_thread).pipe_nombre_injections[1]);
698: close((*s_argument_thread).pipe_nombre_objets_attente[0]);
699: close((*s_argument_thread).pipe_interruptions[0]);
700: close((*s_argument_thread)
701: .pipe_nombre_interruptions_attente[0]);
702:
703: if (pthread_mutex_unlock(&((*s_argument_thread).mutex))
704: != 0)
705: {
706: (*s_etat_processus).erreur_systeme = d_es_processus;
707: sem_post(&semaphore_liste_threads);
708: return;
709: }
710:
711: pthread_mutex_destroy(&((*s_argument_thread).mutex));
712:
713: if ((*s_argument_thread).processus_detache == d_faux)
714: {
715: if ((*s_argument_thread).destruction_objet == d_vrai)
716: {
717: liberation(s_etat_processus, (*s_argument_thread)
718: .argument);
719: }
720: }
721:
722: free(s_argument_thread);
723: }
724: else
725: {
726: if (pthread_mutex_unlock(&((*s_argument_thread).mutex))
727: != 0)
728: {
729: (*s_etat_processus).erreur_systeme = d_es_processus;
730: sem_post(&semaphore_liste_threads);
731: return;
732: }
733: }
734:
1.1 bertrand 735: element_suivant = (*((struct_liste_chainee *) element_courant))
736: .suivant;
1.20 bertrand 737: free(element_courant);
1.1 bertrand 738: element_courant = element_suivant;
739: }
740:
1.20 bertrand 741: (*s_etat_processus).l_base_pile_processus = NULL;
742:
1.1 bertrand 743: pthread_mutex_trylock(&((*(*s_etat_processus).indep).mutex));
744: pthread_mutex_unlock(&((*(*s_etat_processus).indep).mutex));
745: liberation(s_etat_processus, (*s_etat_processus).indep);
746:
747: pthread_mutex_trylock(&((*(*s_etat_processus).depend).mutex));
748: pthread_mutex_unlock(&((*(*s_etat_processus).depend).mutex));
749: liberation(s_etat_processus, (*s_etat_processus).depend);
750:
751: free((*s_etat_processus).label_x);
752: free((*s_etat_processus).label_y);
753: free((*s_etat_processus).label_z);
754: free((*s_etat_processus).titre);
755: free((*s_etat_processus).legende);
756:
757: pthread_mutex_trylock(&((*(*s_etat_processus)
758: .parametres_courbes_de_niveau).mutex));
759: pthread_mutex_unlock(&((*(*s_etat_processus)
760: .parametres_courbes_de_niveau).mutex));
761: liberation(s_etat_processus, (*s_etat_processus)
762: .parametres_courbes_de_niveau);
763:
764: for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++)
765: {
766: if ((*s_etat_processus).corps_interruptions[i] != NULL)
767: {
768: pthread_mutex_trylock(&((*(*s_etat_processus)
769: .corps_interruptions[i]).mutex));
770: pthread_mutex_unlock(&((*(*s_etat_processus)
771: .corps_interruptions[i]).mutex));
772:
773: liberation(s_etat_processus,
774: (*s_etat_processus).corps_interruptions[i]);
775: }
776:
777: element_courant = (*s_etat_processus)
778: .pile_origine_interruptions[i];
779:
780: while(element_courant != NULL)
781: {
782: element_suivant = (*((struct_liste_chainee *)
783: element_courant)).suivant;
784:
785: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
786: element_courant)).donnee).mutex));
787: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
788: element_courant)).donnee).mutex));
789:
790: liberation(s_etat_processus,
791: (*((struct_liste_chainee *) element_courant))
792: .donnee);
793: free(element_courant);
794:
795: element_courant = element_suivant;
796: }
797: }
798:
799: for(i = 0; i < (*s_etat_processus).nombre_variables; i++)
800: {
801: pthread_mutex_trylock(&((*(*s_etat_processus)
802: .s_liste_variables[i].objet).mutex));
803: pthread_mutex_unlock(&((*(*s_etat_processus)
804: .s_liste_variables[i].objet).mutex));
805:
806: // Les variables de niveau 0 sont des définitions qui
807: // ne sont pas copiées entre threads.
808: if ((*s_etat_processus).s_liste_variables[i].niveau > 0)
809: {
810: liberation(s_etat_processus,
811: (*s_etat_processus).s_liste_variables[i].objet);
812: }
813:
814: free((*s_etat_processus).s_liste_variables[i].nom);
815: }
816:
817: free((*s_etat_processus).s_liste_variables);
818:
819: for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)
820: {
821: pthread_mutex_trylock(&((*(*s_etat_processus)
822: .s_liste_variables_statiques[i].objet).mutex));
823: pthread_mutex_unlock(&((*(*s_etat_processus)
824: .s_liste_variables_statiques[i].objet).mutex));
825:
826: liberation(s_etat_processus, (*s_etat_processus)
827: .s_liste_variables_statiques[i].objet);
828: free((*s_etat_processus).s_liste_variables_statiques[i].nom);
829: }
830:
831: free((*s_etat_processus).s_liste_variables_statiques);
832:
833: // Ne peut être effacé qu'une seule fois
834: if (suppression_variables_partagees == d_faux)
835: {
836: suppression_variables_partagees = d_vrai;
837:
838: for(i = 0; i < (*(*s_etat_processus)
839: .s_liste_variables_partagees).nombre_variables; i++)
840: {
841: pthread_mutex_trylock(&((*(*(*s_etat_processus)
842: .s_liste_variables_partagees).table[i].objet)
843: .mutex));
844: pthread_mutex_unlock(&((*(*(*s_etat_processus)
845: .s_liste_variables_partagees).table[i].objet)
846: .mutex));
847:
848: liberation(s_etat_processus, (*(*s_etat_processus)
849: .s_liste_variables_partagees).table[i].objet);
850: free((*(*s_etat_processus).s_liste_variables_partagees)
851: .table[i].nom);
852: }
853:
854: if ((*(*s_etat_processus).s_liste_variables_partagees).table
855: != NULL)
856: {
857: free((struct_variable_partagee *) (*(*s_etat_processus)
858: .s_liste_variables_partagees).table);
859: }
860:
861: pthread_mutex_trylock(&((*(*s_etat_processus)
862: .s_liste_variables_partagees).mutex));
863: pthread_mutex_unlock(&((*(*s_etat_processus)
864: .s_liste_variables_partagees).mutex));
865: }
866:
867: element_courant = (*s_etat_processus).l_base_pile;
868: while(element_courant != NULL)
869: {
870: element_suivant = (*((struct_liste_chainee *)
871: element_courant)).suivant;
872:
873: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
874: element_courant)).donnee).mutex));
875: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
876: element_courant)).donnee).mutex));
877:
878: liberation(s_etat_processus,
879: (*((struct_liste_chainee *)
880: element_courant)).donnee);
881: free((struct_liste_chainee *) element_courant);
882:
883: element_courant = element_suivant;
884: }
885:
886: element_courant = (*s_etat_processus).l_base_pile_contextes;
887: while(element_courant != NULL)
888: {
889: element_suivant = (*((struct_liste_chainee *)
890: element_courant)).suivant;
891:
892: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
893: element_courant)).donnee).mutex));
894: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
895: element_courant)).donnee).mutex));
896: liberation(s_etat_processus, (*((struct_liste_chainee *)
897: element_courant)).donnee);
898: free((struct_liste_chainee *) element_courant);
899:
900: element_courant = element_suivant;
901: }
902:
903: element_courant = (*s_etat_processus).l_base_pile_taille_contextes;
904: while(element_courant != NULL)
905: {
906: element_suivant = (*((struct_liste_chainee *)
907: element_courant)).suivant;
908:
909: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
910: element_courant)).donnee).mutex));
911: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
912: element_courant)).donnee).mutex));
913: liberation(s_etat_processus,
914: (*((struct_liste_chainee *)
915: element_courant)).donnee);
916: free((struct_liste_chainee *) element_courant);
917:
918: element_courant = element_suivant;
919: }
920:
921: for(i = 0; i < (*s_etat_processus).nombre_instructions_externes;
922: i++)
923: {
924: free((*s_etat_processus).s_instructions_externes[i].nom);
925: free((*s_etat_processus).s_instructions_externes[i]
926: .nom_bibliotheque);
927: }
928:
929: if ((*s_etat_processus).nombre_instructions_externes != 0)
930: {
931: free((*s_etat_processus).s_instructions_externes);
932: }
933:
934: element_courant = (*s_etat_processus).s_bibliotheques;
935: while(element_courant != NULL)
936: {
937: element_suivant = (*((struct_liste_chainee *)
938: element_courant)).suivant;
939:
940: element_candidat = (*candidat).s_bibliotheques;
941: while(element_candidat != NULL)
942: {
943: if (((*((struct_bibliotheque *) (*((struct_liste_chainee *)
944: element_courant)).donnee))
945: .descripteur == (*((struct_bibliotheque *)
946: (*((struct_liste_chainee *) element_candidat))
947: .donnee)).descripteur) &&
948: ((*((struct_bibliotheque *)
949: (*((struct_liste_chainee *) element_courant))
950: .donnee)).pid == (*((struct_bibliotheque *)
951: (*((struct_liste_chainee *) element_candidat))
952: .donnee)).pid) && (pthread_equal(
953: (*((struct_bibliotheque *)
954: (*((struct_liste_chainee *) element_courant))
955: .donnee)).tid, (*((struct_bibliotheque *)
956: (*((struct_liste_chainee *) element_candidat))
957: .donnee)).tid) != 0))
958: {
959: break;
960: }
961:
962: element_candidat = (*((struct_liste_chainee *)
963: element_candidat)).suivant;
964: }
965:
966: if (element_candidat == NULL)
967: {
968: dlclose((*((struct_bibliotheque *)
969: (*((struct_liste_chainee *) element_courant))
970: .donnee)).descripteur);
971: }
972:
973: free((*((struct_bibliotheque *)
974: (*((struct_liste_chainee *)
975: element_courant)).donnee)).nom);
976: free((*((struct_liste_chainee *) element_courant)).donnee);
977: free(element_courant);
978:
979: element_courant = element_suivant;
980: }
981:
982: element_courant = (*s_etat_processus).l_base_pile_last;
983: while(element_courant != NULL)
984: {
985: element_suivant = (*((struct_liste_chainee *)
986: element_courant)).suivant;
987:
988: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
989: element_courant)).donnee).mutex));
990: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
991: element_courant)).donnee).mutex));
992: liberation(s_etat_processus,
993: (*((struct_liste_chainee *) element_courant)).donnee);
994: free(element_courant);
995:
996: element_courant = element_suivant;
997: }
998:
999: element_courant = (*s_etat_processus).l_base_pile_systeme;
1000: while(element_courant != NULL)
1001: {
1002: element_suivant = (*((struct_liste_pile_systeme *)
1003: element_courant)).suivant;
1004:
1005: if ((*((struct_liste_pile_systeme *)
1006: element_courant)).indice_boucle != NULL)
1007: {
1008: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
1009: element_courant)).indice_boucle).mutex));
1010: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
1011: element_courant)).indice_boucle).mutex));
1012: }
1013:
1014: liberation(s_etat_processus,
1015: (*((struct_liste_pile_systeme *)
1016: element_courant)).indice_boucle);
1017:
1018: if ((*((struct_liste_pile_systeme *)
1019: element_courant)).limite_indice_boucle != NULL)
1020: {
1021: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
1022: element_courant)).limite_indice_boucle).mutex));
1023: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
1024: element_courant)).limite_indice_boucle).mutex));
1025: }
1026:
1027: liberation(s_etat_processus,
1028: (*((struct_liste_pile_systeme *)
1029: element_courant)).limite_indice_boucle);
1030:
1031: if ((*((struct_liste_pile_systeme *)
1032: element_courant)).objet_de_test != NULL)
1033: {
1034: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
1035: element_courant)).objet_de_test).mutex));
1036: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
1037: element_courant)).objet_de_test).mutex));
1038: }
1039:
1040: liberation(s_etat_processus,
1041: (*((struct_liste_pile_systeme *)
1042: element_courant)).objet_de_test);
1043:
1044: if ((*((struct_liste_pile_systeme *)
1045: element_courant)).nom_variable != NULL)
1046: {
1047: free((*((struct_liste_pile_systeme *)
1048: element_courant)).nom_variable);
1049: }
1050:
1051: free(element_courant);
1052:
1053: element_courant = element_suivant;
1054: }
1055:
1056: element_courant = (*s_etat_processus).s_fichiers;
1057: while(element_courant != NULL)
1058: {
1059: element_suivant = (*((struct_liste_chainee *)
1060: element_courant)).suivant;
1061:
1062: element_candidat = (*candidat).s_fichiers;
1063: while(element_candidat != NULL)
1064: {
1065: if (((*((struct_descripteur_fichier *)
1066: (*((struct_liste_chainee *) element_courant))
1067: .donnee)).pid ==
1068: (*((struct_descripteur_fichier *)
1069: (*((struct_liste_chainee *) element_candidat))
1070: .donnee)).pid) && (pthread_equal(
1071: (*((struct_descripteur_fichier *)
1072: (*((struct_liste_chainee *) element_courant))
1073: .donnee)).tid, (*((struct_descripteur_fichier *)
1074: (*((struct_liste_chainee *) element_candidat))
1075: .donnee)).tid) != 0))
1076: {
1.5 bertrand 1077: if ((*((struct_descripteur_fichier *)
1078: (*((struct_liste_chainee *) element_courant))
1079: .donnee)).type ==
1080: (*((struct_descripteur_fichier *)
1081: (*((struct_liste_chainee *) element_candidat))
1082: .donnee)).type)
1083: {
1084: if ((*((struct_descripteur_fichier *)
1085: (*((struct_liste_chainee *)
1086: element_candidat)).donnee)).type == 'C')
1087: {
1088: if ((*((struct_descripteur_fichier *)
1089: (*((struct_liste_chainee *)
1090: element_courant)).donnee))
1091: .descripteur_c ==
1092: (*((struct_descripteur_fichier *)
1093: (*((struct_liste_chainee *)
1094: element_candidat)).donnee))
1095: .descripteur_c)
1096: {
1097: break;
1098: }
1099: }
1100: else
1101: {
1102: if (((*((struct_descripteur_fichier *)
1103: (*((struct_liste_chainee *)
1104: element_courant)).donnee))
1105: .descripteur_sqlite ==
1106: (*((struct_descripteur_fichier *)
1107: (*((struct_liste_chainee *)
1108: element_candidat)).donnee))
1109: .descripteur_sqlite) &&
1110: ((*((struct_descripteur_fichier *)
1111: (*((struct_liste_chainee *)
1112: element_courant)).donnee))
1113: .descripteur_c ==
1114: (*((struct_descripteur_fichier *)
1115: (*((struct_liste_chainee *)
1116: element_candidat)).donnee))
1117: .descripteur_c))
1118: {
1119: break;
1120: }
1121: }
1122: }
1.1 bertrand 1123: }
1124:
1125: element_candidat = (*((struct_liste_chainee *)
1126: element_candidat)).suivant;
1127: }
1128:
1129: if (element_candidat == NULL)
1130: {
1131: fclose((*((struct_descripteur_fichier *)
1132: (*((struct_liste_chainee *) element_courant))
1.5 bertrand 1133: .donnee)).descripteur_c);
1134:
1135: if ((*((struct_descripteur_fichier *)
1136: (*((struct_liste_chainee *) element_courant))
1137: .donnee)).type != 'C')
1138: {
1139: sqlite3_close((*((struct_descripteur_fichier *)
1140: (*((struct_liste_chainee *) element_courant))
1141: .donnee)).descripteur_sqlite);
1142: }
1.1 bertrand 1143: }
1144:
1145: free((*((struct_descripteur_fichier *)
1146: (*((struct_liste_chainee *)
1147: element_courant)).donnee)).nom);
1148: free((struct_descripteur_fichier *)
1149: (*((struct_liste_chainee *)
1150: element_courant)).donnee);
1151: free(element_courant);
1152:
1153: element_courant = element_suivant;
1154: }
1155:
1156: element_courant = (*s_etat_processus).s_sockets;
1157: while(element_courant != NULL)
1158: {
1159: element_suivant = (*((struct_liste_chainee *)
1160: element_courant)).suivant;
1161:
1162: element_candidat = (*candidat).s_sockets;
1163: while(element_candidat != NULL)
1164: {
1165: if (((*((struct_socket *)
1166: (*((struct_liste_chainee *) element_courant))
1167: .donnee)).socket == (*((struct_socket *)
1168: (*((struct_liste_chainee *) element_candidat))
1169: .donnee)).socket) &&
1170: ((*((struct_socket *)
1171: (*((struct_liste_chainee *) element_courant))
1172: .donnee)).pid == (*((struct_socket *)
1173: (*((struct_liste_chainee *) element_candidat))
1174: .donnee)).pid) && (pthread_equal(
1175: (*((struct_socket *)
1176: (*((struct_liste_chainee *) element_courant))
1177: .donnee)).tid, (*((struct_socket *)
1178: (*((struct_liste_chainee *) element_candidat))
1179: .donnee)).tid) != 0))
1180: {
1181: break;
1182: }
1183:
1184: element_candidat = (*((struct_liste_chainee *)
1185: element_candidat)).suivant;
1186: }
1187:
1188: if (element_candidat == NULL)
1189: {
1190: if ((*((struct_socket *) (*((struct_liste_chainee *)
1191: element_courant)).donnee)).socket_connectee
1192: == d_vrai)
1193: {
1194: shutdown((*((struct_socket *)
1195: (*((struct_liste_chainee *) element_courant))
1196: .donnee)).socket, SHUT_RDWR);
1197: }
1198:
1199: close((*((struct_socket *)
1200: (*((struct_liste_chainee *) element_courant))
1201: .donnee)).socket);
1202: }
1203:
1204: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1205: element_courant)).donnee).mutex));
1206: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1207: element_courant)).donnee).mutex));
1208:
1209: liberation(s_etat_processus,
1210: (*((struct_liste_chainee *)
1211: element_courant)).donnee);
1212: free(element_courant);
1213:
1214: element_courant = element_suivant;
1215: }
1216:
1.14 bertrand 1217: /*
1218: ================================================================================
1219: À noter : on ne ferme pas la connexion car la conséquence immédiate est
1220: une destruction de l'objet pour le processus père.
1221: ================================================================================
1222:
1.1 bertrand 1223: element_courant = (*s_etat_processus).s_connecteurs_sql;
1224: while(element_courant != NULL)
1225: {
1226: element_suivant = (*((struct_liste_chainee *)
1227: element_courant)).suivant;
1228:
1229: element_candidat = (*candidat).s_connecteurs_sql;
1230: while(element_candidat != NULL)
1231: {
1232: if (((
1233: #ifdef MYSQL_SUPPORT
1234: ((*((struct_connecteur_sql *)
1235: (*((struct_liste_chainee *) element_courant))
1236: .donnee)).descripteur.mysql ==
1237: (*((struct_connecteur_sql *)
1238: (*((struct_liste_chainee *) element_candidat))
1239: .donnee)).descripteur.mysql)
1240: &&
1241: (strcmp((*((struct_connecteur_sql *)
1242: (*((struct_liste_chainee *) element_courant))
1243: .donnee)).type, "MYSQL") == 0)
1244: &&
1245: (strcmp((*((struct_connecteur_sql *)
1246: (*((struct_liste_chainee *) element_candidat))
1247: .donnee)).type, "MYSQL") == 0)
1248: #else
1249: 0
1250: #endif
1251: ) || (
1252: #ifdef POSTGRESQL_SUPPORT
1253: ((*((struct_connecteur_sql *)
1254: (*((struct_liste_chainee *) element_courant))
1255: .donnee)).descripteur.postgresql ==
1256: (*((struct_connecteur_sql *)
1257: (*((struct_liste_chainee *) element_candidat))
1258: .donnee)).descripteur.postgresql)
1259: &&
1260: (strcmp((*((struct_connecteur_sql *)
1261: (*((struct_liste_chainee *) element_courant))
1262: .donnee)).type, "POSTGRESQL") == 0)
1263: &&
1264: (strcmp((*((struct_connecteur_sql *)
1265: (*((struct_liste_chainee *) element_candidat))
1266: .donnee)).type, "POSTGRESQL") == 0)
1267: #else
1268: 0
1269: #endif
1270: )) &&
1271: ((*((struct_connecteur_sql *)
1272: (*((struct_liste_chainee *) element_courant))
1273: .donnee)).pid == (*((struct_connecteur_sql *)
1274: (*((struct_liste_chainee *) element_candidat))
1275: .donnee)).pid) && (pthread_equal(
1276: (*((struct_connecteur_sql *)
1277: (*((struct_liste_chainee *) element_courant))
1278: .donnee)).tid, (*((struct_connecteur_sql *)
1279: (*((struct_liste_chainee *) element_candidat))
1280: .donnee)).tid) != 0))
1281: {
1282: break;
1283: }
1284:
1285: element_candidat = (*((struct_liste_chainee *)
1286: element_candidat)).suivant;
1287: }
1288:
1289: if (element_candidat == NULL)
1290: {
1291: sqlclose((*((struct_liste_chainee *) element_courant))
1292: .donnee);
1293: }
1294:
1295: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1296: element_courant)).donnee).mutex));
1297: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1298: element_courant)).donnee).mutex));
1299:
1300: liberation(s_etat_processus, (*((struct_liste_chainee *)
1301: element_courant)).donnee);
1302: free(element_courant);
1303:
1304: element_courant = element_suivant;
1305: }
1.14 bertrand 1306: */
1.1 bertrand 1307:
1.15 bertrand 1308: (*s_etat_processus).s_connecteurs_sql = NULL;
1309:
1.1 bertrand 1310: element_courant = (*s_etat_processus).s_marques;
1311: while(element_courant != NULL)
1312: {
1313: free((*((struct_marque *) element_courant)).label);
1314: free((*((struct_marque *) element_courant)).position);
1315: element_suivant = (*((struct_marque *) element_courant))
1316: .suivant;
1317: free(element_courant);
1318: element_courant = element_suivant;
1319: }
1320:
1321: liberation_allocateur(s_etat_processus);
1322:
1.8 bertrand 1323: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1324: sem_post(&((*s_etat_processus).semaphore_fork));
1325: sem_destroy(&((*s_etat_processus).semaphore_fork));
1.8 bertrand 1326: # else
1327: sem_post((*s_etat_processus).semaphore_fork);
1328: sem_destroy2((*s_etat_processus).semaphore_fork, sem_fork);
1329: # endif
1.1 bertrand 1330:
1331: free(s_etat_processus);
1332:
1333: s_etat_processus = candidat;
1334: }
1335:
1336: l_element_suivant = (*l_element_courant).suivant;
1337:
1338: free((struct_thread *) (*l_element_courant).donnee);
1339: free((struct_liste_chainee *) l_element_courant);
1340:
1341: l_element_courant = l_element_suivant;
1342: }
1343:
1344: liste_threads = NULL;
1345:
1346: l_element_courant = liste_threads_surveillance;
1347:
1348: while(l_element_courant != NULL)
1349: {
1350: s_argument_thread = (struct_descripteur_thread *)
1351: (*l_element_courant).donnee;
1352:
1353: if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)
1354: {
1355: (*s_etat_processus).erreur_systeme = d_es_processus;
1.12 bertrand 1356: sem_post(&semaphore_liste_threads);
1.1 bertrand 1357: return;
1358: }
1359:
1360: (*s_argument_thread).nombre_references--;
1361:
1362: BUG((*s_argument_thread).nombre_references < 0,
1363: printf("(*s_argument_thread).nombre_references = %d\n",
1364: (int) (*s_argument_thread).nombre_references));
1365:
1366: if ((*s_argument_thread).nombre_references == 0)
1367: {
1.20 bertrand 1368: close((*s_argument_thread).pipe_objets[0]);
1369: close((*s_argument_thread).pipe_acquittement[1]);
1370: close((*s_argument_thread).pipe_injections[1]);
1371: close((*s_argument_thread).pipe_nombre_injections[1]);
1372: close((*s_argument_thread).pipe_nombre_objets_attente[0]);
1373: close((*s_argument_thread).pipe_interruptions[0]);
1374: close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);
1375:
1.1 bertrand 1376: if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
1377: {
1378: (*s_etat_processus).erreur_systeme = d_es_processus;
1.12 bertrand 1379: sem_post(&semaphore_liste_threads);
1.1 bertrand 1380: return;
1381: }
1382:
1383: pthread_mutex_destroy(&((*s_argument_thread).mutex));
1.20 bertrand 1384:
1385: if ((*s_argument_thread).processus_detache == d_faux)
1386: {
1387: if ((*s_argument_thread).destruction_objet == d_vrai)
1388: {
1389: liberation(s_etat_processus, (*s_argument_thread).argument);
1390: }
1391: }
1392:
1.1 bertrand 1393: free(s_argument_thread);
1394: }
1395: else
1396: {
1397: if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
1398: {
1399: (*s_etat_processus).erreur_systeme = d_es_processus;
1.12 bertrand 1400: sem_post(&semaphore_liste_threads);
1.1 bertrand 1401: return;
1402: }
1403: }
1404:
1405: l_element_suivant = (*l_element_courant).suivant;
1406: free((struct_liste_chainee *) l_element_courant);
1407: l_element_courant = l_element_suivant;
1408: }
1409:
1410: liste_threads_surveillance = NULL;
1411:
1.8 bertrand 1412: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1413: if (sem_post(&semaphore_liste_threads) != 0)
1.8 bertrand 1414: # else
1415: if (sem_post(semaphore_liste_threads) != 0)
1416: # endif
1.1 bertrand 1417: {
1418: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1419: (*s_etat_processus).erreur_systeme = d_es_processus;
1420: return;
1421: }
1422:
1423: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1424: sigpending(&set);
1425: return;
1426: }
1427:
1428: static struct_processus *
1429: recherche_thread(pid_t pid, pthread_t tid)
1430: {
1431: volatile struct_liste_chainee_volatile *l_element_courant;
1432:
1433: struct_processus *s_etat_processus;
1434:
1435: l_element_courant = liste_threads;
1436:
1437: while(l_element_courant != NULL)
1438: {
1439: if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee))
1440: .tid, tid) != 0) && ((*((struct_thread *)
1441: (*l_element_courant).donnee)).pid == pid))
1442: {
1443: break;
1444: }
1445:
1446: l_element_courant = (*l_element_courant).suivant;
1447: }
1448:
1449: if (l_element_courant == NULL)
1450: {
1451: /*
1452: * Le processus n'existe plus. On ne distribue aucun signal.
1453: */
1454:
1455: return(NULL);
1456: }
1457:
1458: s_etat_processus = (*((struct_thread *)
1459: (*l_element_courant).donnee)).s_etat_processus;
1460:
1461: return(s_etat_processus);
1462: }
1463:
1464: static logical1
1465: recherche_thread_principal(pid_t pid, pthread_t *thread)
1466: {
1467: volatile struct_liste_chainee_volatile *l_element_courant;
1468:
1469: l_element_courant = liste_threads;
1470:
1471: while(l_element_courant != NULL)
1472: {
1473: if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal
1474: == d_vrai) && ((*((struct_thread *)
1475: (*l_element_courant).donnee)).pid == pid))
1476: {
1477: break;
1478: }
1479:
1480: l_element_courant = (*l_element_courant).suivant;
1481: }
1482:
1483: if (l_element_courant == NULL)
1484: {
1485: /*
1486: * Le processus n'existe plus. On ne distribue aucun signal.
1487: */
1488:
1489: return(d_faux);
1490: }
1491:
1492: (*thread) = (*((struct_thread *) (*l_element_courant).donnee)).tid;
1493:
1494: return(d_vrai);
1495: }
1496:
1497:
1498: /*
1499: ================================================================================
1500: Procédures de gestion des signaux d'interruption
1501: ================================================================================
1502: Entrée : variable globale
1503: --------------------------------------------------------------------------------
1504: Sortie : variable globale modifiée
1505: --------------------------------------------------------------------------------
1506: Effets de bord : néant
1507: ================================================================================
1508: */
1509:
1510: // Les routines suivantes sont uniquement appelées depuis les gestionnaires
1.17 bertrand 1511: // des signaux asynchrones. Elles ne doivent pas bloquer dans le cas où
1.1 bertrand 1512: // les sémaphores sont déjà bloqués par un gestionnaire de signal.
1513:
1514: static inline void
1515: verrouillage_gestionnaire_signaux()
1516: {
1517: int semaphore;
1518:
1519: sigset_t oldset;
1520: sigset_t set;
1521:
1522: sem_t *sem;
1523:
1524: if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
1525: != NULL)
1526: {
1527: if (sem_post(sem) != 0)
1528: {
1529: BUG(1, uprintf("Lock error !\n"));
1530: return;
1531: }
1532: }
1533:
1534: // Il faut respecteur l'atomicité des deux opérations suivantes !
1535:
1536: sigfillset(&set);
1537: pthread_sigmask(SIG_BLOCK, &set, &oldset);
1538:
1.8 bertrand 1539: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1540: while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
1.8 bertrand 1541: # else
1542: while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)
1543: # endif
1.1 bertrand 1544: {
1545: if (errno != EINTR)
1546: {
1547: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1548: BUG(1, uprintf("Unlock error !\n"));
1549: return;
1550: }
1551: }
1552:
1.8 bertrand 1553: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1554: if (sem_post(&semaphore_gestionnaires_signaux) == -1)
1.8 bertrand 1555: # else
1556: if (sem_post(semaphore_gestionnaires_signaux) == -1)
1557: # endif
1.1 bertrand 1558: {
1559: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1560: BUG(1, uprintf("Lock error !\n"));
1561: return;
1562: }
1563:
1.8 bertrand 1564: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1565: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1.8 bertrand 1566: # else
1567: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1568: # endif
1.1 bertrand 1569: {
1570: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1571: BUG(1, uprintf("Lock error !\n"));
1572: return;
1573: }
1574:
1.8 bertrand 1575: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1576: if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
1.8 bertrand 1577: # else
1578: if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)
1579: # endif
1.1 bertrand 1580: {
1581: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1582: BUG(1, uprintf("Unlock error !\n"));
1583: return;
1584: }
1585:
1586: if (semaphore == 1)
1587: {
1588: // Le semaphore ne peut être pris par le thread qui a appelé
1589: // le gestionnaire de signal car le signal est bloqué par ce thread
1590: // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que
1591: // par un thread concurrent. On essaye donc de le bloquer jusqu'à
1592: // ce que ce soit possible.
1593:
1.8 bertrand 1594: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1595: while(sem_trywait(&semaphore_liste_threads) == -1)
1.8 bertrand 1596: # else
1597: while(sem_trywait(semaphore_liste_threads) == -1)
1598: # endif
1.1 bertrand 1599: {
1600: if ((errno != EINTR) && (errno != EAGAIN))
1601: {
1602: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1603:
1604: while(sem_wait(sem) == -1)
1605: {
1606: if (errno != EINTR)
1607: {
1608: BUG(1, uprintf("Lock error !\n"));
1609: return;
1610: }
1611: }
1612:
1613: BUG(1, uprintf("Lock error !\n"));
1614: return;
1615: }
1616:
1617: sched_yield();
1618: }
1619: }
1620:
1621: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1622: sigpending(&set);
1623:
1624: return;
1625: }
1626:
1627: static inline void
1628: deverrouillage_gestionnaire_signaux()
1629: {
1630: int semaphore;
1631:
1632: sem_t *sem;
1633:
1634: sigset_t oldset;
1635: sigset_t set;
1636:
1637: // Il faut respecteur l'atomicité des deux opérations suivantes !
1638:
1639: sigfillset(&set);
1640: pthread_sigmask(SIG_BLOCK, &set, &oldset);
1641:
1.8 bertrand 1642: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1643: while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
1.8 bertrand 1644: # else
1645: while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)
1646: # endif
1.1 bertrand 1647: {
1648: if (errno != EINTR)
1649: {
1650: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1651: BUG(1, uprintf("Unlock error !\n"));
1652: return;
1653: }
1654: }
1655:
1.8 bertrand 1656: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1657: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1.8 bertrand 1658: # else
1659: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1660: # endif
1.1 bertrand 1661: {
1662: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1663: BUG(1, uprintf("Unlock error !\n"));
1664: return;
1665: }
1666:
1.8 bertrand 1667: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1668: while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
1.8 bertrand 1669: # else
1670: while(sem_wait(semaphore_gestionnaires_signaux) == -1)
1671: # endif
1.1 bertrand 1672: {
1673: if (errno != EINTR)
1674: {
1675: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1676: BUG(1, uprintf("Unlock error !\n"));
1677: return;
1678: }
1679: }
1680:
1.8 bertrand 1681: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1682: if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
1.8 bertrand 1683: # else
1684: if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)
1685: # endif
1.1 bertrand 1686: {
1687: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1688: BUG(1, uprintf("Unlock error !\n"));
1689: return;
1690: }
1691:
1692: if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
1693: != NULL)
1694: {
1695: while(sem_wait(sem) == -1)
1696: {
1697: if (errno != EINTR)
1698: {
1699: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1700: BUG(1, uprintf("Unlock error !\n"));
1701: return;
1702: }
1703: }
1704: }
1705:
1706: if (semaphore == 1)
1707: {
1.8 bertrand 1708: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 1709: if (sem_post(&semaphore_liste_threads) != 0)
1.8 bertrand 1710: # else
1711: if (sem_post(semaphore_liste_threads) != 0)
1712: # endif
1.1 bertrand 1713: {
1714: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1715:
1716: BUG(1, uprintf("Unlock error !\n"));
1717: return;
1718: }
1719: }
1720:
1721: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
1722: sigpending(&set);
1723:
1724: return;
1725: }
1726:
1.30 bertrand 1727: #ifdef _BROKEN_SIGINFO
1728:
1.33 bertrand 1729: #define longueur_queue 256
1730: #define nombre_queues 13
1731:
1.30 bertrand 1732: static int *fifos;
1.35 ! bertrand 1733: static int markov;
1.30 bertrand 1734: static int segment;
1.33 bertrand 1735: static sem_t *semaphores[nombre_queues];
1736: static sem_t *semaphore_global;
1.30 bertrand 1737:
1.33 bertrand 1738: #ifdef IPCS_SYSV
1.30 bertrand 1739: static unsigned char *chemin = NULL;
1.33 bertrand 1740: #endif
1.30 bertrand 1741:
1742: unsigned char *
1743: nom_segment(unsigned char *chemin, pid_t pid)
1744: {
1745: unsigned char *fichier;
1746:
1.33 bertrand 1747: # ifdef IPCS_SYSV
1.30 bertrand 1748: if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) *
1749: sizeof(unsigned char))) == NULL)
1750: {
1751: return(NULL);
1752: }
1753:
1754: sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);
1.33 bertrand 1755: # else
1756: if ((fichier = malloc((1 + 256 + 1) *
1757: sizeof(unsigned char))) == NULL)
1758: {
1759: return(NULL);
1760: }
1761:
1762: sprintf(fichier, "/RPL-SIGQUEUES-%d", (int) pid);
1763: # endif
1.30 bertrand 1764:
1765: return(fichier);
1766: }
1767:
1768: unsigned char *
1.33 bertrand 1769: nom_semaphore(pid_t pid, int queue)
1.30 bertrand 1770: {
1771: unsigned char *fichier;
1772:
1.33 bertrand 1773: if ((fichier = malloc((256 + 1) * sizeof(unsigned char))) == NULL)
1.30 bertrand 1774: {
1775: return(NULL);
1776: }
1777:
1.33 bertrand 1778: sprintf(fichier, "/RPL-SIGESMAPHORES-%d-%d", (int) pid, queue);
1.30 bertrand 1779:
1780: return(fichier);
1781: }
1782:
1.33 bertrand 1783: inline int
1.30 bertrand 1784: queue_de_signal(int signal)
1785: {
1786: switch(signal)
1787: {
1788: case SIGINT:
1789: return(0);
1790: case SIGTSTP:
1791: return(1);
1792: case SIGCONT:
1793: return(2);
1794: case SIGURG:
1795: return(3);
1796: case SIGPIPE:
1797: return(4);
1798: case SIGALRM:
1799: return(5);
1800: case SIGFSTOP:
1801: return(6);
1802: case SIGSTART:
1803: return(7);
1804: case SIGINJECT:
1805: return(8);
1806: case SIGABORT:
1807: return(9);
1808: case SIGFABORT:
1809: return(10);
1.33 bertrand 1810: case SIGSEGV:
1811: return(11);
1812: case SIGBUS:
1813: return(12);
1.30 bertrand 1814: }
1815:
1816: return(-1);
1817: }
1818:
1.1 bertrand 1819: void
1.30 bertrand 1820: creation_fifos_signaux(struct_processus *s_etat_processus)
1.1 bertrand 1821: {
1.33 bertrand 1822: /*
1823: * Signaux utilisés
1824: * SIGINT, SIGTSTP, SIGCONT, SIGURG, SIGPIPE, SIGALRM, SIGFSTOP,
1825: * SIGSTART, SIGINJECT, SIGABORT, SIGFABORT
1826: */
1827:
1.35 ! bertrand 1828: int i;
! 1829:
! 1830: unsigned char *nom;
! 1831:
1.33 bertrand 1832: # ifndef IPCS_SYSV // POSIX
1.35 ! bertrand 1833:
! 1834: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
! 1835: getpid())) == NULL)
! 1836: {
! 1837: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 1838: return;
! 1839: }
! 1840:
! 1841: if ((segment = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,
! 1842: S_IRUSR | S_IWUSR)) == -1)
! 1843: {
! 1844: free(nom);
! 1845: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 1846: return;
! 1847: }
! 1848:
! 1849: if (ftruncate(segment, nombre_queues * ((2 * longueur_queue) + 4) *
! 1850: sizeof(int)) == -1)
! 1851: {
! 1852: free(nom);
! 1853: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 1854: return;
! 1855: }
! 1856:
! 1857: fifos = mmap(NULL, nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
! 1858: PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0);
! 1859: close(segment);
! 1860:
! 1861: if (((void *) fifos) == ((void *) -1))
! 1862: {
! 1863: if (shm_unlink(nom) == -1)
! 1864: {
! 1865: free(nom);
! 1866: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 1867: return;
! 1868: }
! 1869:
! 1870: free(nom);
! 1871: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 1872: return;
! 1873: }
! 1874:
! 1875: free(nom);
! 1876:
1.33 bertrand 1877: # else // SystemV
1878:
1.30 bertrand 1879: file *desc;
1880:
1881: key_t clef;
1882:
1883: // Création d'un segment de données associé au PID du processus courant
1884:
1885: chemin = (*s_etat_processus).chemin_fichiers_temporaires;
1886:
1887: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
1888: getpid())) == NULL)
1889: {
1890: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1891: return;
1892: }
1893:
1894: if ((desc = fopen(nom, "w")) == NULL)
1895: {
1896: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
1897: return;
1898: }
1899:
1900: fclose(desc);
1901:
1902: if ((clef = ftok(nom, 1)) == -1)
1903: {
1904: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1905: return;
1906: }
1907:
1908: free(nom);
1909:
1910: if ((segment = shmget(clef,
1.35 ! bertrand 1911: nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
1.30 bertrand 1912: IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)
1913: {
1914: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1915: return;
1916: }
1917:
1918: fifos = shmat(segment, NULL, 0);
1919:
1920: if (((void *) fifos) == ((void *) -1))
1921: {
1.33 bertrand 1922: if (shmctl(segment, IPC_RMID, 0) == -1)
1923: {
1924: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1925: return;
1926: }
1927:
1.30 bertrand 1928: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1929: return;
1930: }
1931:
1.33 bertrand 1932: # endif
1933:
1934: /*
1935: * Structure d'une queue
1936: * 0 : pointeur en lecture sur le premier emplacement libre (int)
1937: * 1 : pointeur en écriture sur le premier emplacement à lire (int)
1938: * 2 : longueur de la queue (int)
1939: * 3 : éléments restants (int)
1940: * 4 à 4 + (2) : queue (int)
1.35 ! bertrand 1941: * 4 + (2) + 1 ) 4 + 2 * (2) : horodatage en centième de secondes.
1.33 bertrand 1942: */
1943:
1.30 bertrand 1944: for(i = 0; i < nombre_queues; i++)
1945: {
1946: fifos[(i * (longueur_queue + 4))] = 0;
1947: fifos[(i * (longueur_queue + 4)) + 1] = 0;
1948: fifos[(i * (longueur_queue + 4)) + 2] = longueur_queue;
1949: fifos[(i * (longueur_queue + 4)) + 3] = longueur_queue;
1950: }
1951:
1.33 bertrand 1952: // Création des sémaphores : un sémaphore par signal et par queue
1953: // plus un sémaphore global pour tous les threads.
1954:
1955: for(i = 0; i < nombre_queues; i++)
1.30 bertrand 1956: {
1.33 bertrand 1957: if ((nom = nom_semaphore(getpid(), i)) == NULL)
1958: {
1959: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1960: return;
1961: }
1.30 bertrand 1962:
1.33 bertrand 1963: // Le sémaphore est créé en écrasant si nécessaire un sémaphore
1964: // préexistant. Comme le nom du sémaphore contient l'identifiant du
1965: // processus, il est anormal d'avoir un sémaphore de même nom
1966: // préexistant.
1.30 bertrand 1967:
1.33 bertrand 1968: if ((semaphores[i] = sem_open(nom, O_CREAT, S_IRUSR | S_IWUSR,
1969: 1)) == SEM_FAILED)
1970: {
1971: (*s_etat_processus).erreur_systeme = d_es_semaphore;
1972: return;
1973: }
1.30 bertrand 1974:
1.33 bertrand 1975: free(nom);
1.30 bertrand 1976: }
1977:
1978:
1.33 bertrand 1979: if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
1.30 bertrand 1980: {
1981: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1982: return;
1983: }
1984:
1.33 bertrand 1985: if ((semaphore_global = sem_open(nom, O_CREAT, S_IRUSR | S_IWUSR,
1986: 1)) == SEM_FAILED)
1.30 bertrand 1987: {
1.33 bertrand 1988: (*s_etat_processus).erreur_systeme = d_es_semaphore;
1.30 bertrand 1989: return;
1990: }
1991:
1.33 bertrand 1992: free(nom);
1.30 bertrand 1993:
1.35 ! bertrand 1994: markov = 0;
! 1995:
1.30 bertrand 1996: return;
1997: }
1998:
1999: void
2000: liberation_fifos_signaux(struct_processus *s_etat_processus)
2001: {
1.33 bertrand 2002: int i;
2003:
1.35 ! bertrand 2004: # ifdef IPCS_SYSV // SystemV
! 2005:
1.30 bertrand 2006: if (shmdt(fifos) == -1)
2007: {
2008: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2009: return;
2010: }
2011:
1.35 ! bertrand 2012: # else // POSIX
! 2013:
! 2014: if (munmap(fifos, nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int))
! 2015: != 0)
! 2016: {
! 2017: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 2018: return;
! 2019: }
! 2020:
! 2021: # endif
! 2022:
1.33 bertrand 2023: for(i = 0; i < nombre_queues; i++)
2024: {
2025: if (sem_close(semaphores[i]) != 0)
2026: {
2027: (*s_etat_processus).erreur_systeme = d_es_semaphore;
2028: return;
2029: }
2030: }
2031:
2032: if (sem_close(semaphore_global) != 0)
1.30 bertrand 2033: {
1.33 bertrand 2034: (*s_etat_processus).erreur_systeme = d_es_semaphore;
1.30 bertrand 2035: return;
2036: }
2037:
2038: return;
2039: }
2040:
2041: void
2042: destruction_fifos_signaux(struct_processus *s_etat_processus)
2043: {
2044: int i;
1.31 bertrand 2045:
1.30 bertrand 2046: unsigned char *nom;
2047:
1.35 ! bertrand 2048: # ifdef IPCS_SYSV // SystemV
! 2049:
1.30 bertrand 2050: if (shmdt(fifos) == -1)
2051: {
2052: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2053: return;
2054: }
2055:
2056: if (shmctl(segment, IPC_RMID, 0) == -1)
2057: {
2058: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2059: return;
2060: }
2061:
1.33 bertrand 2062: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
2063: getpid())) == NULL)
1.30 bertrand 2064: {
2065: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2066: return;
2067: }
2068:
1.33 bertrand 2069: unlink(nom);
2070: free(nom);
2071:
1.35 ! bertrand 2072: # else // POSIX
! 2073:
! 2074: if (munmap(fifos, nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int))
! 2075: != 0)
! 2076: {
! 2077: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 2078: return;
! 2079: }
! 2080:
! 2081: if ((nom = nom_segment(NULL, getpid())) == NULL)
! 2082: {
! 2083: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 2084: return;
! 2085: }
! 2086:
! 2087: if (shm_unlink(nom) != 0)
! 2088: {
! 2089: free(nom);
! 2090: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
! 2091: return;
! 2092: }
! 2093:
! 2094: free(nom);
! 2095:
! 2096: # endif
! 2097:
1.33 bertrand 2098: for(i = 0; i < nombre_queues; i++)
1.30 bertrand 2099: {
1.33 bertrand 2100: if ((nom = nom_semaphore(getpid(), i)) == NULL)
2101: {
2102: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2103: return;
2104: }
2105:
2106: if (sem_unlink(nom) != 0)
2107: {
2108: (*s_etat_processus).erreur_systeme = d_es_semaphore;
2109: return;
2110: }
2111:
2112: free(nom);
1.30 bertrand 2113: }
2114:
1.33 bertrand 2115: if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
1.30 bertrand 2116: {
2117: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2118: return;
2119: }
2120:
1.33 bertrand 2121: if (sem_unlink(nom) != 0)
1.30 bertrand 2122: {
1.33 bertrand 2123: (*s_etat_processus).erreur_systeme = d_es_semaphore;
1.30 bertrand 2124: return;
2125: }
2126:
2127: free(nom);
2128:
2129: return;
2130: }
2131:
1.35 ! bertrand 2132: inline int
! 2133: horodatage()
! 2134: {
! 2135: int ts;
! 2136:
! 2137: struct timeval tv;
! 2138:
! 2139: gettimeofday(&tv, NULL);
! 2140: ts = (int) ((tv.tv_sec * 100) + (tv.tv_usec / 10000));
! 2141:
! 2142: return(ts);
! 2143: }
! 2144:
1.30 bertrand 2145: int
2146: queue_in(pid_t pid, int signal)
2147: {
1.35 ! bertrand 2148: int queue;
1.30 bertrand 2149: int *base;
2150: int *buffer;
1.35 ! bertrand 2151: int horodatage_initial;
! 2152: int identifiant;
1.30 bertrand 2153: int *projection_fifos;
2154:
1.33 bertrand 2155: sem_t *semaphore;
2156:
1.35 ! bertrand 2157: queue = queue_de_signal(signal);
1.30 bertrand 2158:
2159: unsigned char *nom;
2160:
1.35 ! bertrand 2161: # ifndef IPCS_SYSV
! 2162:
! 2163: // Ouverture des projections
! 2164:
! 2165: if ((nom = nom_segment(NULL, pid)) == NULL)
! 2166: {
! 2167: return(-1);
! 2168: }
! 2169:
! 2170: // Dans le cas de SIGSTART, premier signal envoyé à un processus fils,
! 2171: // il convient d'attendre que le fichier support soit effectivement
! 2172: // accessible. Dans tous les autres cas, ce fichier doit exister. S'il
! 2173: // n'existe plus, le processus associé n'existe plus.
! 2174:
! 2175: if (signal == SIGSTART)
! 2176: {
! 2177: horodatage_initial = horodatage();
! 2178:
! 2179: while((identifiant = shm_open(nom, O_RDWR, S_IRUSR | S_IWUSR)) == -1)
! 2180: {
! 2181: if (abs(horodatage_initial - horodatage()) > 500)
! 2182: {
! 2183: return(-1);
! 2184: }
! 2185: }
! 2186: }
! 2187: else
! 2188: {
! 2189: if ((identifiant = shm_open(nom, O_RDWR, S_IRUSR | S_IWUSR)) == -1)
! 2190: {
! 2191: return(-1);
! 2192: }
! 2193: }
! 2194:
! 2195: projection_fifos = mmap(NULL, nombre_queues * ((2 * longueur_queue) + 4)
! 2196: * sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, identifiant, 0);
! 2197: close(identifiant);
! 2198:
! 2199: if (((void *) projection_fifos) == ((void *) -1))
! 2200: {
! 2201: return(-1);
! 2202: }
! 2203:
! 2204: # else // Traitement à l'aide d'IPCS SystemV
! 2205:
! 2206: key_t clef;
! 2207:
! 2208: struct stat s_stat;
1.30 bertrand 2209:
2210: // Ouverture des projections
2211:
2212: if ((nom = nom_segment(chemin, pid)) == NULL)
2213: {
2214: return(-1);
2215: }
2216:
1.33 bertrand 2217: // Dans le cas de SIGSTART, premier signal envoyé à un processus fils,
2218: // il convient d'attendre que le fichier support soit effectivement
2219: // accessible. Dans tous les autres cas, ce fichier doit exister. S'il
2220: // n'existe plus, le processus associé n'existe plus.
2221:
2222: if (signal == SIGSTART)
2223: {
2224: // On attend que le fichier sois présent
2225:
1.35 ! bertrand 2226: horodatage_initial = horodatage();
! 2227:
! 2228: while(stat(nom, &s_stat) != 0)
! 2229: {
! 2230: if (abs(horodatage_initial - horodatage()) > 500)
! 2231: {
! 2232: return(-1);
! 2233: }
! 2234: }
1.33 bertrand 2235: }
2236:
1.30 bertrand 2237: if ((clef = ftok(nom, 1)) == -1)
2238: {
2239: return(-1);
2240: }
2241:
2242: free(nom);
2243:
1.33 bertrand 2244: if (signal == SIGSTART)
2245: {
2246: while((identifiant = shmget(clef,
1.35 ! bertrand 2247: nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
1.33 bertrand 2248: S_IRUSR | S_IWUSR)) == -1);
2249: }
2250: else
2251: {
2252: if ((identifiant = shmget(clef,
1.35 ! bertrand 2253: nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
1.33 bertrand 2254: S_IRUSR | S_IWUSR)) == -1)
2255: {
2256: return(-1);
2257: }
2258: }
1.30 bertrand 2259:
2260: projection_fifos = shmat(identifiant, NULL, 0);
2261:
1.33 bertrand 2262: if (((void *) projection_fifos) == ((void *) -1))
1.30 bertrand 2263: {
2264: return(-1);
2265: }
2266:
1.35 ! bertrand 2267: # endif
! 2268:
1.33 bertrand 2269: if ((nom = nom_semaphore(pid, queue)) == NULL)
1.30 bertrand 2270: {
1.35 ! bertrand 2271: # ifdef IPCS_SYSV
1.33 bertrand 2272: shmdt(projection_fifos);
1.35 ! bertrand 2273: # else
! 2274: munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
! 2275: * sizeof(int));
! 2276: # endif
1.30 bertrand 2277: return(-1);
2278: }
2279:
1.33 bertrand 2280: while((semaphore = sem_open(nom, 0)) == SEM_FAILED);
1.35 ! bertrand 2281: free(nom);
1.30 bertrand 2282:
1.35 ! bertrand 2283: while(sem_wait(semaphore) != 0)
1.30 bertrand 2284: {
1.35 ! bertrand 2285: if (errno != EINTR)
! 2286: {
! 2287: # ifdef IPCS_SYSV
! 2288: shmdt(projection_fifos);
! 2289: # else
! 2290: munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
! 2291: * sizeof(int));
! 2292: # endif
! 2293: return(-1);
! 2294: }
1.30 bertrand 2295: }
2296:
2297: base = &(projection_fifos[(longueur_queue + 4) * queue]);
2298: buffer = &(base[4]);
2299:
1.33 bertrand 2300: // base[3] contient le nombre d'éléments restants
1.30 bertrand 2301:
2302: if (base[3] <= 0)
2303: {
1.33 bertrand 2304: sem_post(semaphore);
2305: sem_close(semaphore);
1.35 ! bertrand 2306: # ifdef IPCS_SYSV
1.30 bertrand 2307: shmdt(projection_fifos);
1.35 ! bertrand 2308: # else
! 2309: munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
! 2310: * sizeof(int));
! 2311: # endif
1.30 bertrand 2312: return(-1);
2313: }
2314:
2315: base[3]--;
2316:
1.33 bertrand 2317: // base[1] contient le prochain élément à écrire
1.35 ! bertrand 2318:
! 2319: buffer[base[1] + (nombre_queues * base[2])] = horodatage();
1.33 bertrand 2320: buffer[base[1]++] = (int) pid;
2321: base[1] %= base[2];
2322:
2323: if (sem_post(semaphore) != 0)
1.30 bertrand 2324: {
1.35 ! bertrand 2325: # ifdef IPCS_SYSV
1.30 bertrand 2326: shmdt(projection_fifos);
1.35 ! bertrand 2327: # else
! 2328: munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
! 2329: * sizeof(int));
! 2330: # endif
1.33 bertrand 2331: sem_close(semaphore);
1.30 bertrand 2332: return(-1);
2333: }
2334:
1.33 bertrand 2335: sem_close(semaphore);
2336:
1.30 bertrand 2337: // Fermeture des projections
1.35 ! bertrand 2338: # ifdef IPCS_SYSV
1.30 bertrand 2339: shmdt(projection_fifos);
1.35 ! bertrand 2340: # else
! 2341: munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
! 2342: * sizeof(int));
1.33 bertrand 2343: # endif
2344:
1.30 bertrand 2345: return(0);
2346: }
2347:
1.35 ! bertrand 2348: inline int
! 2349: chaine_markov(int markov, int delta)
! 2350: {
! 2351: double memoire = 0.9;
! 2352: int valeur;
! 2353:
! 2354: valeur = (int) ((memoire * markov) + ((1 - memoire) * delta));
! 2355: valeur = (valeur < 10) ? 10 : valeur;
! 2356:
! 2357: return(valeur);
! 2358: }
! 2359:
1.30 bertrand 2360: pid_t
2361: origine_signal(int signal)
2362: {
1.35 ! bertrand 2363: logical1 drapeau;
! 2364:
1.30 bertrand 2365: int *base;
2366: int *buffer;
1.35 ! bertrand 2367: int delta;
1.30 bertrand 2368: int pid;
2369: int queue;
2370:
2371: queue = queue_de_signal(signal);
2372:
2373: BUG(queue == -1, uprintf("[%d] Unknown signal %d in this context\n",
2374: (int) getpid(), signal));
2375:
1.35 ! bertrand 2376: while(sem_wait(semaphores[queue]) != 0)
1.30 bertrand 2377: {
1.35 ! bertrand 2378: if (errno != EINTR)
! 2379: {
! 2380: return(-1);
! 2381: }
1.30 bertrand 2382: }
2383:
1.35 ! bertrand 2384: // On retire les interruptions anciennes qui ont été ratées sauf s'il
! 2385: // s'agit de la dernière dans la queue.
! 2386:
! 2387: base = &(fifos[(longueur_queue + 4) * queue]);
! 2388: buffer = &(base[4]);
! 2389:
! 2390: if (base[3] == (base[2] - 1))
1.33 bertrand 2391: {
1.35 ! bertrand 2392: delta = abs(horodatage() -
! 2393: buffer[base[0] + (nombre_queues * base[2])]);
! 2394: // Une seule interruption dans la queue.
1.33 bertrand 2395: pid = buffer[base[0]++];
2396: base[0] %= base[2];
2397: base[3]++;
1.35 ! bertrand 2398:
! 2399: markov = chaine_markov(markov, delta);
1.33 bertrand 2400: }
1.35 ! bertrand 2401: else if (base[3] >= base[2])
! 2402: {
! 2403: // Aucune interruption n'est dans la queue.
! 2404: // On a retiré trop d'interruptions de la queue.
1.30 bertrand 2405:
1.35 ! bertrand 2406: // (base[3] - base[2]) + 1 : nombre d'interruptions manquantes
! 2407: // base[0] - 1 : dernière interruption lue
! 2408: pid = buffer[((((base[0] + base[2] - 1) % base[2])
! 2409: - ((base[3] - base[2]) + 1)) + base[2]) % base[2]];
! 2410: }
! 2411: else
1.30 bertrand 2412: {
1.35 ! bertrand 2413: // Plusieurs interruptions à distribuer.
! 2414: drapeau = d_vrai;
! 2415:
! 2416: do
! 2417: {
! 2418: delta = abs(horodatage() -
! 2419: buffer[base[0] + (nombre_queues * base[2])]);
! 2420: pid = buffer[base[0]++];
! 2421: base[0] %= base[2];
! 2422: base[3]++;
! 2423:
! 2424: if ((delta > (2 * markov)) && (base[3] < base[2]))
! 2425: {
! 2426: drapeau = d_vrai;
! 2427: }
! 2428: else
! 2429: {
! 2430: drapeau = d_faux;
! 2431: }
! 2432: } while(drapeau == d_vrai);
! 2433:
! 2434: markov = chaine_markov(markov, delta);
1.30 bertrand 2435: }
1.33 bertrand 2436:
2437: if (sem_post(semaphores[queue]) != 0)
1.30 bertrand 2438: {
2439: return(-1);
2440: }
2441:
2442: return((pid_t) pid);
2443: }
2444:
2445: #endif
2446:
2447: void
2448: interruption1(SIGHANDLER_ARGS)
2449: {
2450: pid_t pid;
2451:
1.1 bertrand 2452: pthread_t thread;
2453:
2454: struct_processus *s_etat_processus;
2455:
2456: volatile sig_atomic_t exclusion = 0;
2457:
1.32 bertrand 2458: verrouillage_gestionnaire_signaux();
2459:
1.29 bertrand 2460: # ifdef _BROKEN_SIGINFO
1.31 bertrand 2461: if (signal == SIGINT)
2462: {
2463: // Si l'interruption provient du clavier, il n'y a pas eu d'appel
2464: // à queue_in().
2465:
2466: pid = getpid();
2467: }
2468: else
2469: {
2470: pid = origine_signal(signal);
2471: }
1.30 bertrand 2472: # else
2473: pid = (*siginfo).si_pid;
1.29 bertrand 2474: # endif
2475:
1.1 bertrand 2476: switch(signal)
2477: {
2478: case SIGALRM :
2479: {
1.30 bertrand 2480: if (pid == getpid())
1.1 bertrand 2481: {
2482: if ((s_etat_processus = recherche_thread(getpid(),
2483: pthread_self())) == NULL)
2484: {
2485: deverrouillage_gestionnaire_signaux();
1.30 bertrand 2486: return;
1.1 bertrand 2487: }
2488:
2489: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2490: {
2491: printf("[%d] SIGALRM (thread %llu)\n", (int) getpid(),
2492: (unsigned long long) pthread_self());
2493: fflush(stdout);
2494: }
2495:
2496: if ((*s_etat_processus).pid_processus_pere != getpid())
2497: {
2498: kill((*s_etat_processus).pid_processus_pere, signal);
2499: }
2500: else
2501: {
2502: (*s_etat_processus).var_volatile_alarme = -1;
2503: (*s_etat_processus).var_volatile_requete_arret = -1;
2504: }
2505: }
2506: else
2507: {
2508: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2509: {
2510: pthread_kill(thread, signal);
2511: }
2512: }
2513:
2514: break;
2515: }
2516:
2517: case SIGINT :
2518: {
2519: /*
2520: * Une vieille spécification POSIX permet au pointeur siginfo
2521: * d'être nul dans le cas d'un ^C envoyé depuis le clavier.
2522: * Solaris suit en particulier cette spécification.
2523: */
2524:
1.30 bertrand 2525: # ifndef _BROKEN_SIGINFO
1.1 bertrand 2526: if (siginfo == NULL)
2527: {
2528: kill(getpid(), signal);
2529: }
1.30 bertrand 2530: else
2531: # endif
2532: if (pid == getpid())
1.1 bertrand 2533: {
2534: if ((s_etat_processus = recherche_thread(getpid(),
2535: pthread_self())) == NULL)
2536: {
2537: deverrouillage_gestionnaire_signaux();
2538: return;
2539: }
2540:
2541: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2542: {
2543: printf("[%d] SIGINT (thread %llu)\n", (int) getpid(),
2544: (unsigned long long) pthread_self());
2545: fflush(stdout);
2546: }
2547:
2548: if ((*s_etat_processus).pid_processus_pere != getpid())
2549: {
2550: kill((*s_etat_processus).pid_processus_pere, signal);
2551: }
2552: else
2553: {
2554: (*s_etat_processus).var_volatile_traitement_sigint = -1;
2555:
2556: while(exclusion == 1);
2557: exclusion = 1;
2558:
2559: if ((*s_etat_processus).var_volatile_requete_arret == -1)
2560: {
2561: deverrouillage_gestionnaire_signaux();
2562: exclusion = 0;
2563: return;
2564: }
2565:
2566: if (strncmp(getenv("LANG"), "fr", 2) == 0)
2567: {
2568: printf("+++Interruption\n");
2569: }
2570: else
2571: {
2572: printf("+++Interrupt\n");
2573: }
2574:
2575: fflush(stdout);
2576:
2577: (*s_etat_processus).var_volatile_requete_arret = -1;
2578: (*s_etat_processus).var_volatile_alarme = -1;
2579:
2580: exclusion = 0;
2581: }
2582: }
2583: else
2584: {
2585: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2586: {
2587: pthread_kill(thread, signal);
2588: }
2589: }
2590:
2591: break;
2592: }
2593:
2594: default :
2595: {
2596: BUG(1, uprintf("[%d] Unknown signal %d in this context\n",
2597: (int) getpid(), signal));
2598: break;
2599: }
2600: }
2601:
2602: deverrouillage_gestionnaire_signaux();
2603: return;
2604: }
2605:
2606: void
1.30 bertrand 2607: interruption2(SIGHANDLER_ARGS)
1.1 bertrand 2608: {
1.30 bertrand 2609: pid_t pid;
2610:
1.1 bertrand 2611: pthread_t thread;
1.30 bertrand 2612:
1.1 bertrand 2613: struct_processus *s_etat_processus;
2614:
1.32 bertrand 2615: verrouillage_gestionnaire_signaux();
2616:
1.29 bertrand 2617: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2618: pid = origine_signal(signal);
2619: # else
2620: pid = (*siginfo).si_pid;
1.29 bertrand 2621: # endif
2622:
1.30 bertrand 2623: # ifndef _BROKEN_SIGINFO
1.1 bertrand 2624: if (siginfo == NULL)
2625: {
2626: /*
2627: * Le signal SIGFSTP provient de la mort du processus de contrôle.
2628: * Sous certains systèmes (Linux...), la mort du terminal de contrôle
2629: * se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
2630: * (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
2631: * non initialisée (pointeur NULL) issue de TERMIO.
2632: */
2633:
2634: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2635: {
2636: pthread_kill(thread, SIGHUP);
2637: deverrouillage_gestionnaire_signaux();
2638: return;
2639: }
2640: }
1.30 bertrand 2641: else
2642: # endif
2643: if (pid == getpid())
1.1 bertrand 2644: {
2645: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2646: == NULL)
2647: {
2648: deverrouillage_gestionnaire_signaux();
2649: return;
2650: }
2651:
2652: /*
2653: * 0 => fonctionnement normal
2654: * -1 => requête
2655: * 1 => requête acceptée en attente de traitement
2656: */
2657:
2658: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2659: {
2660: printf("[%d] SIGTSTP (thread %llu)\n", (int) getpid(),
2661: (unsigned long long) pthread_self());
2662: fflush(stdout);
2663: }
2664:
2665: if ((*s_etat_processus).var_volatile_processus_pere == 0)
2666: {
2667: kill((*s_etat_processus).pid_processus_pere, signal);
2668: }
2669: else
2670: {
2671: (*s_etat_processus).var_volatile_requete_arret2 = -1;
2672: }
2673: }
2674: else
2675: {
2676: // Envoi d'un signal au thread maître du groupe.
2677:
2678: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2679: {
2680: pthread_kill(thread, SIGTSTP);
2681: deverrouillage_gestionnaire_signaux();
2682: return;
2683: }
2684: }
2685:
2686: deverrouillage_gestionnaire_signaux();
2687: return;
2688: }
2689:
2690: void
1.30 bertrand 2691: interruption3(SIGHANDLER_ARGS)
1.1 bertrand 2692: {
1.30 bertrand 2693: pid_t pid;
2694:
1.1 bertrand 2695: struct_processus *s_etat_processus;
2696:
2697: static int compteur = 0;
2698:
1.32 bertrand 2699: verrouillage_gestionnaire_signaux();
2700:
1.29 bertrand 2701: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2702: pid = origine_signal(signal);
2703: # else
2704: pid = (*siginfo).si_pid;
1.29 bertrand 2705: # endif
2706:
1.1 bertrand 2707: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2708: {
2709: deverrouillage_gestionnaire_signaux();
2710: return;
2711: }
2712:
2713: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2714: {
2715: printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),
2716: (unsigned long long) pthread_self());
2717: fflush(stdout);
2718: }
2719:
2720: if ((*s_etat_processus).var_volatile_recursivite == -1)
2721: {
2722: // Segfault dans un appel de fonction récursive
2723: deverrouillage_gestionnaire_signaux();
2724: longjmp(contexte, -1);
2725: }
2726: else
2727: {
2728: // Segfault dans une routine interne
2729: if (strncmp(getenv("LANG"), "fr", 2) == 0)
2730: {
2731: printf("+++Système : Violation d'accès (dépassement de pile)\n");
2732: }
2733: else
2734: {
2735: printf("+++System : Access violation (stack overflow)\n");
2736: }
2737:
2738: fflush(stdout);
2739:
2740: compteur++;
2741:
2742: if (compteur > 1)
2743: {
2744: deverrouillage_gestionnaire_signaux();
2745: exit(EXIT_FAILURE);
2746: }
2747: else
2748: {
2749: deverrouillage_gestionnaire_signaux();
2750: longjmp(contexte_initial, -1);
2751: }
2752: }
2753:
2754: deverrouillage_gestionnaire_signaux();
2755: return;
2756: }
2757:
2758: void
1.30 bertrand 2759: interruption4(SIGHANDLER_ARGS)
1.1 bertrand 2760: {
1.30 bertrand 2761: pid_t pid;
2762:
1.1 bertrand 2763: struct_processus *s_etat_processus;
2764:
1.32 bertrand 2765: verrouillage_gestionnaire_signaux();
2766:
1.29 bertrand 2767: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2768: pid = origine_signal(signal);
2769: # else
2770: pid = (*siginfo).si_pid;
1.29 bertrand 2771: # endif
2772:
1.1 bertrand 2773: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2774: {
2775: deverrouillage_gestionnaire_signaux();
2776: return;
2777: }
2778:
2779: /*
2780: * Démarrage d'un processus fils ou gestion de SIGCONT (SUSPEND)
2781: */
2782:
2783: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2784: {
2785: printf("[%d] SIGSTART/SIGCONT (thread %llu)\n", (int) getpid(),
2786: (unsigned long long) pthread_self());
2787: fflush(stdout);
2788: }
2789:
2790: deverrouillage_gestionnaire_signaux();
2791: return;
2792: }
2793:
2794: void
1.30 bertrand 2795: interruption5(SIGHANDLER_ARGS)
1.1 bertrand 2796: {
1.30 bertrand 2797: pid_t pid;
2798:
1.1 bertrand 2799: pthread_t thread;
1.30 bertrand 2800:
1.1 bertrand 2801: struct_processus *s_etat_processus;
2802:
1.32 bertrand 2803: verrouillage_gestionnaire_signaux();
2804:
1.29 bertrand 2805: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2806: pid = origine_signal(signal);
2807: # else
2808: pid = (*siginfo).si_pid;
1.29 bertrand 2809: # endif
2810:
1.30 bertrand 2811: if (pid == getpid())
1.1 bertrand 2812: {
2813: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2814: == NULL)
2815: {
2816: deverrouillage_gestionnaire_signaux();
2817: return;
2818: }
2819:
2820: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2821: {
1.16 bertrand 2822: printf("[%d] SIGFSTOP (thread %llu)\n", (int) getpid(),
2823: (unsigned long long) pthread_self());
2824: fflush(stdout);
1.1 bertrand 2825: }
2826:
2827: /*
2828: * var_globale_traitement_retarde_stop :
2829: * 0 -> traitement immédiat
2830: * 1 -> traitement retardé (aucun signal reçu)
2831: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2832: */
2833:
1.11 bertrand 2834: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
1.1 bertrand 2835: {
1.11 bertrand 2836: (*s_etat_processus).var_volatile_requete_arret = -1;
1.1 bertrand 2837: }
2838: else
2839: {
1.11 bertrand 2840: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
1.1 bertrand 2841: }
2842: }
2843: else
2844: {
1.11 bertrand 2845: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2846: == NULL)
2847: {
2848: deverrouillage_gestionnaire_signaux();
2849: return;
2850: }
2851:
1.1 bertrand 2852: // Envoi d'un signal au thread maître du groupe.
2853:
2854: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2855: {
1.10 bertrand 2856: pthread_kill(thread, signal);
1.1 bertrand 2857: deverrouillage_gestionnaire_signaux();
2858: return;
2859: }
2860: }
2861:
2862: deverrouillage_gestionnaire_signaux();
2863: return;
2864: }
2865:
2866: void
1.30 bertrand 2867: interruption6(SIGHANDLER_ARGS)
1.1 bertrand 2868: {
1.30 bertrand 2869: pid_t pid;
2870:
1.1 bertrand 2871: struct_processus *s_etat_processus;
2872:
1.32 bertrand 2873: verrouillage_gestionnaire_signaux();
2874:
1.29 bertrand 2875: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2876: pid = origine_signal(signal);
2877: # else
2878: pid = (*siginfo).si_pid;
1.29 bertrand 2879: # endif
2880:
1.1 bertrand 2881: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2882: {
2883: deverrouillage_gestionnaire_signaux();
2884: return;
2885: }
2886:
2887: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2888: {
2889: printf("[%d] SIGINJECT/SIGQUIT (thread %llu)\n", (int) getpid(),
2890: (unsigned long long) pthread_self());
2891: fflush(stdout);
2892: }
2893:
2894: deverrouillage_gestionnaire_signaux();
2895: return;
2896: }
2897:
2898: void
1.30 bertrand 2899: interruption7(SIGHANDLER_ARGS)
1.1 bertrand 2900: {
1.30 bertrand 2901: pid_t pid;
2902:
1.1 bertrand 2903: struct_processus *s_etat_processus;
2904:
1.32 bertrand 2905: verrouillage_gestionnaire_signaux();
2906:
1.29 bertrand 2907: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2908: pid = origine_signal(signal);
2909: # else
2910: pid = (*siginfo).si_pid;
1.29 bertrand 2911: # endif
2912:
1.1 bertrand 2913: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2914: {
2915: deverrouillage_gestionnaire_signaux();
2916: return;
2917: }
2918:
2919: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2920: {
2921: printf("[%d] SIGPIPE (thread %llu)\n", (int) getpid(),
2922: (unsigned long long) pthread_self());
2923: fflush(stdout);
2924: }
2925:
2926: (*s_etat_processus).var_volatile_requete_arret = -1;
2927: deverrouillage_gestionnaire_signaux();
2928:
2929: BUG(1, printf("[%d] SIGPIPE\n", (int) getpid()));
2930: return;
2931: }
2932:
2933: void
1.30 bertrand 2934: interruption8(SIGHANDLER_ARGS)
1.1 bertrand 2935: {
1.30 bertrand 2936: pid_t pid;
2937:
1.1 bertrand 2938: pthread_t thread;
1.30 bertrand 2939:
1.1 bertrand 2940: struct_processus *s_etat_processus;
2941:
1.32 bertrand 2942: verrouillage_gestionnaire_signaux();
2943:
1.29 bertrand 2944: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2945: pid = origine_signal(signal);
2946: # else
2947: pid = (*siginfo).si_pid;
1.29 bertrand 2948: # endif
2949:
1.30 bertrand 2950: if (pid == getpid())
1.1 bertrand 2951: {
2952: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
2953: == NULL)
2954: {
2955: deverrouillage_gestionnaire_signaux();
2956: return;
2957: }
2958:
2959: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2960: {
2961: printf("[%d] SIGURG (thread %llu)\n", (int) getpid(),
2962: (unsigned long long) pthread_self());
2963: fflush(stdout);
2964: }
2965:
2966: (*s_etat_processus).var_volatile_alarme = -1;
2967: (*s_etat_processus).var_volatile_requete_arret = -1;
2968: }
2969: else
2970: {
2971: // Envoi d'un signal au thread maître du groupe.
2972:
2973: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
2974: {
2975: pthread_kill(thread, SIGURG);
2976: deverrouillage_gestionnaire_signaux();
2977: return;
2978: }
2979: }
2980:
2981: deverrouillage_gestionnaire_signaux();
2982: return;
2983: }
2984:
2985: void
1.30 bertrand 2986: interruption9(SIGHANDLER_ARGS)
1.1 bertrand 2987: {
1.30 bertrand 2988: pid_t pid;
2989:
1.1 bertrand 2990: struct_processus *s_etat_processus;
2991:
1.32 bertrand 2992: verrouillage_gestionnaire_signaux();
2993:
1.29 bertrand 2994: # ifdef _BROKEN_SIGINFO
1.30 bertrand 2995: pid = origine_signal(signal);
2996: # else
2997: pid = (*siginfo).si_pid;
1.29 bertrand 2998: # endif
2999:
1.1 bertrand 3000: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
3001: {
3002: deverrouillage_gestionnaire_signaux();
3003: return;
3004: }
3005:
3006: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
3007: {
3008: printf("[%d] SIGABORT/SIGPROF (thread %llu)\n", (int) getpid(),
3009: (unsigned long long) pthread_self());
3010: fflush(stdout);
3011: }
3012:
1.30 bertrand 3013: # ifdef _BROKEN_SIGINFO
3014: if (queue_in(getpid(), signal) != 0)
3015: {
3016: return;
3017: }
3018:
1.32 bertrand 3019: deverrouillage_gestionnaire_signaux();
1.30 bertrand 3020: interruption11(signal);
3021: # else
1.32 bertrand 3022: deverrouillage_gestionnaire_signaux();
1.17 bertrand 3023: interruption11(signal, siginfo, context);
1.30 bertrand 3024: # endif
1.1 bertrand 3025: return;
3026: }
3027:
3028: void
1.30 bertrand 3029: interruption10(SIGHANDLER_ARGS)
1.1 bertrand 3030: {
3031: file *fichier;
3032:
1.30 bertrand 3033: pid_t pid;
3034:
1.1 bertrand 3035: struct_processus *s_etat_processus;
3036:
3037: unsigned char nom[8 + 64 + 1];
3038:
1.32 bertrand 3039: verrouillage_gestionnaire_signaux();
3040:
1.29 bertrand 3041: # ifdef _BROKEN_SIGINFO
1.30 bertrand 3042: pid = origine_signal(signal);
3043: # else
3044: pid = (*siginfo).si_pid;
1.29 bertrand 3045: # endif
3046:
1.1 bertrand 3047: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
3048: {
3049: deverrouillage_gestionnaire_signaux();
3050: return;
3051: }
3052:
3053: snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
3054: (unsigned long) pthread_self());
3055:
3056: if ((fichier = fopen(nom, "w+")) != NULL)
3057: {
3058: fclose(fichier);
3059:
3060: freopen(nom, "w", stdout);
3061: freopen(nom, "w", stderr);
3062: }
3063:
3064: freopen("/dev/null", "r", stdin);
3065:
3066: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
3067: {
3068: printf("[%d] SIGHUP (thread %llu)\n", (int) getpid(),
3069: (unsigned long long) pthread_self());
3070: fflush(stdout);
3071: }
3072:
3073: deverrouillage_gestionnaire_signaux();
3074: return;
3075: }
3076:
3077: void
1.30 bertrand 3078: interruption11(SIGHANDLER_ARGS)
1.16 bertrand 3079: {
1.30 bertrand 3080: pid_t pid;
3081:
1.16 bertrand 3082: pthread_t thread;
1.30 bertrand 3083:
1.16 bertrand 3084: struct_processus *s_etat_processus;
3085:
1.32 bertrand 3086: verrouillage_gestionnaire_signaux();
3087:
1.29 bertrand 3088: # ifdef _BROKEN_SIGINFO
1.30 bertrand 3089: pid = origine_signal(signal);
3090: # else
3091: pid = (*siginfo).si_pid;
1.29 bertrand 3092: # endif
3093:
1.30 bertrand 3094: if (pid == getpid())
1.16 bertrand 3095: {
3096: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
3097: == NULL)
3098: {
3099: deverrouillage_gestionnaire_signaux();
3100: return;
3101: }
3102:
3103: (*s_etat_processus).arret_depuis_abort = -1;
3104:
3105: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
3106: {
3107: printf("[%d] SIGFABORT (thread %llu)\n", (int) getpid(),
3108: (unsigned long long) pthread_self());
3109: fflush(stdout);
3110: }
3111:
3112: /*
3113: * var_globale_traitement_retarde_stop :
3114: * 0 -> traitement immédiat
3115: * 1 -> traitement retardé (aucun signal reçu)
3116: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
3117: */
3118:
3119: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
3120: {
3121: (*s_etat_processus).var_volatile_requete_arret = -1;
3122: }
3123: else
3124: {
3125: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
3126: }
3127: }
3128: else
3129: {
3130: if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
3131: == NULL)
3132: {
3133: deverrouillage_gestionnaire_signaux();
3134: return;
3135: }
3136:
3137: (*s_etat_processus).arret_depuis_abort = -1;
3138:
3139: // Envoi d'un signal au thread maître du groupe.
3140:
3141: if (recherche_thread_principal(getpid(), &thread) == d_vrai)
3142: {
3143: pthread_kill(thread, signal);
3144: deverrouillage_gestionnaire_signaux();
3145: return;
3146: }
3147: }
3148:
3149: deverrouillage_gestionnaire_signaux();
3150: return;
3151: }
3152:
3153: void
1.1 bertrand 3154: traitement_exceptions_gsl(const char *reason, const char *file,
3155: int line, int gsl_errno)
3156: {
3157: struct_processus *s_etat_processus;
3158:
3159: verrouillage_gestionnaire_signaux();
3160:
3161: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
3162: {
3163: deverrouillage_gestionnaire_signaux();
3164: return;
3165: }
3166:
3167: (*s_etat_processus).var_volatile_exception_gsl = gsl_errno;
3168: deverrouillage_gestionnaire_signaux();
3169: return;
3170: }
3171:
1.30 bertrand 3172: #ifdef _BROKEN_SIGINFO
3173:
3174: #undef kill
3175: #undef pthread_kill
3176:
3177: int
1.33 bertrand 3178: kill_broken_siginfo(pid_t pid, int signal)
1.30 bertrand 3179: {
1.33 bertrand 3180: int ios;
3181:
3182: sem_t *semaphore;
3183:
3184: unsigned char *nom;
3185:
1.30 bertrand 3186: /*
3187: * Lorsqu'on veut interrompre le processus pid, on ouvre le segment
3188: * correspondant au processus en question et ou ajoute le pid dans la
3189: * queue.
1.33 bertrand 3190: *
3191: * Le sémaphore global à tous les threads d'un même processus sert
3192: * à garantir que les signaux seront traités dans l'ordre de ce qui est
3193: * effectivement mis dans la queue.
1.30 bertrand 3194: */
3195:
1.33 bertrand 3196: // Sémaphore acquis
3197:
3198: if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
3199: {
3200: return(-1);
3201: }
3202:
1.35 ! bertrand 3203: while((semaphore = sem_open(nom, 0)) == SEM_FAILED);
1.33 bertrand 3204: free(nom);
3205:
1.35 ! bertrand 3206: while(sem_wait(semaphore) != 0)
1.33 bertrand 3207: {
1.35 ! bertrand 3208: if (errno != EINTR)
! 3209: {
! 3210: return(-1);
! 3211: }
1.33 bertrand 3212: }
3213:
1.31 bertrand 3214: if ((signal != 0) && (signal != SIGINT))
1.30 bertrand 3215: {
3216: if (queue_in(pid, signal) != 0)
3217: {
1.33 bertrand 3218: sem_post(semaphore);
3219: sem_close(semaphore);
1.30 bertrand 3220: return(-1);
3221: }
3222: }
3223:
1.33 bertrand 3224: ios = kill(pid, signal);
3225:
3226: // Sémaphore relâché
3227:
3228: sem_post(semaphore);
3229: sem_close(semaphore);
3230:
3231: return(ios);
1.30 bertrand 3232: }
3233:
3234: int
1.33 bertrand 3235: pthread_kill_broken_siginfo(pthread_t tid, int signal)
1.30 bertrand 3236: {
1.33 bertrand 3237: int ios;
3238:
3239: sem_t *semaphore;
3240:
3241: unsigned char *nom;
3242:
3243: if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
3244: {
3245: return(-1);
3246: }
3247:
1.35 ! bertrand 3248: while((semaphore = sem_open(nom, 0)) == SEM_FAILED);
1.33 bertrand 3249: free(nom);
3250:
1.35 ! bertrand 3251: while(sem_wait(semaphore) != 0)
1.33 bertrand 3252: {
1.35 ! bertrand 3253: if (errno != EINTR)
! 3254: {
! 3255: return(-1);
! 3256: }
1.33 bertrand 3257: }
3258:
1.31 bertrand 3259: if ((signal != 0) && (signal != SIGINT))
1.30 bertrand 3260: {
3261: if (queue_in(getpid(), signal) != 0)
3262: {
1.33 bertrand 3263: sem_post(semaphore);
3264: sem_close(semaphore);
1.30 bertrand 3265: return(-1);
3266: }
3267: }
3268:
1.33 bertrand 3269: ios = pthread_kill(tid, signal);
3270:
3271: sem_post(semaphore);
3272: sem_close(semaphore);
3273:
3274: return(ios);
1.30 bertrand 3275: }
3276:
3277: #endif
3278:
1.1 bertrand 3279: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>