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