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