File:
[local] /
rpl /
src /
interruptions.c
Revision
1.104:
download - view:
text,
annotated -
select for diffs -
revision graph
Fri Oct 5 13:12:39 2012 UTC (11 years, 11 months ago) by
bertrand
Branches:
MAIN
CVS tags:
HEAD
Seconde série de patches pour intégrer les variables statiques à l'arbre
des variables. Cela compile sans warning mais n'a pas été testé. Au passage, la
condition de dépassement des puissances entières d'un argument réel ou complexe
a été corrigée.
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: // Ne peut être effacé qu'une seule fois
750: if (suppression_variables_partagees == d_faux)
751: {
752: suppression_variables_partagees = d_vrai;
753:
754: for(i = 0; i < (*(*s_etat_processus)
755: .s_liste_variables_partagees).nombre_variables; i++)
756: {
757: pthread_mutex_trylock(&((*(*(*s_etat_processus)
758: .s_liste_variables_partagees).table[i].objet)
759: .mutex));
760: pthread_mutex_unlock(&((*(*(*s_etat_processus)
761: .s_liste_variables_partagees).table[i].objet)
762: .mutex));
763:
764: liberation(s_etat_processus, (*(*s_etat_processus)
765: .s_liste_variables_partagees).table[i].objet);
766: free((*(*s_etat_processus).s_liste_variables_partagees)
767: .table[i].nom);
768: }
769:
770: if ((*(*s_etat_processus).s_liste_variables_partagees).table
771: != NULL)
772: {
773: free((struct_variable_partagee *) (*(*s_etat_processus)
774: .s_liste_variables_partagees).table);
775: }
776:
777: pthread_mutex_trylock(&((*(*s_etat_processus)
778: .s_liste_variables_partagees).mutex));
779: pthread_mutex_unlock(&((*(*s_etat_processus)
780: .s_liste_variables_partagees).mutex));
781: }
782:
783: element_courant = (*s_etat_processus).l_base_pile;
784: while(element_courant != NULL)
785: {
786: element_suivant = (*((struct_liste_chainee *)
787: element_courant)).suivant;
788:
789: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
790: element_courant)).donnee).mutex));
791: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
792: element_courant)).donnee).mutex));
793:
794: liberation(s_etat_processus,
795: (*((struct_liste_chainee *)
796: element_courant)).donnee);
797: free((struct_liste_chainee *) element_courant);
798:
799: element_courant = element_suivant;
800: }
801:
802: element_courant = (*s_etat_processus).l_base_pile_contextes;
803: while(element_courant != NULL)
804: {
805: element_suivant = (*((struct_liste_chainee *)
806: element_courant)).suivant;
807:
808: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
809: element_courant)).donnee).mutex));
810: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
811: element_courant)).donnee).mutex));
812: liberation(s_etat_processus, (*((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_taille_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,
830: (*((struct_liste_chainee *)
831: element_courant)).donnee);
832: free((struct_liste_chainee *) element_courant);
833:
834: element_courant = element_suivant;
835: }
836:
837: for(i = 0; i < (*s_etat_processus).nombre_instructions_externes;
838: i++)
839: {
840: free((*s_etat_processus).s_instructions_externes[i].nom);
841: free((*s_etat_processus).s_instructions_externes[i]
842: .nom_bibliotheque);
843: }
844:
845: if ((*s_etat_processus).nombre_instructions_externes != 0)
846: {
847: free((*s_etat_processus).s_instructions_externes);
848: }
849:
850: element_courant = (*s_etat_processus).s_bibliotheques;
851: while(element_courant != NULL)
852: {
853: element_suivant = (*((struct_liste_chainee *)
854: element_courant)).suivant;
855:
856: element_candidat = (*candidat).s_bibliotheques;
857: while(element_candidat != NULL)
858: {
859: if (((*((struct_bibliotheque *) (*((struct_liste_chainee *)
860: element_courant)).donnee))
861: .descripteur == (*((struct_bibliotheque *)
862: (*((struct_liste_chainee *) element_candidat))
863: .donnee)).descripteur) &&
864: ((*((struct_bibliotheque *)
865: (*((struct_liste_chainee *) element_courant))
866: .donnee)).pid == (*((struct_bibliotheque *)
867: (*((struct_liste_chainee *) element_candidat))
868: .donnee)).pid) && (pthread_equal(
869: (*((struct_bibliotheque *)
870: (*((struct_liste_chainee *) element_courant))
871: .donnee)).tid, (*((struct_bibliotheque *)
872: (*((struct_liste_chainee *) element_candidat))
873: .donnee)).tid) != 0))
874: {
875: break;
876: }
877:
878: element_candidat = (*((struct_liste_chainee *)
879: element_candidat)).suivant;
880: }
881:
882: if (element_candidat == NULL)
883: {
884: dlclose((*((struct_bibliotheque *)
885: (*((struct_liste_chainee *) element_courant))
886: .donnee)).descripteur);
887: }
888:
889: free((*((struct_bibliotheque *)
890: (*((struct_liste_chainee *)
891: element_courant)).donnee)).nom);
892: free((*((struct_liste_chainee *) element_courant)).donnee);
893: free(element_courant);
894:
895: element_courant = element_suivant;
896: }
897:
898: element_courant = (*s_etat_processus).l_base_pile_last;
899: while(element_courant != NULL)
900: {
901: element_suivant = (*((struct_liste_chainee *)
902: element_courant)).suivant;
903:
904: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
905: element_courant)).donnee).mutex));
906: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
907: element_courant)).donnee).mutex));
908: liberation(s_etat_processus,
909: (*((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_systeme;
916: while(element_courant != NULL)
917: {
918: element_suivant = (*((struct_liste_pile_systeme *)
919: element_courant)).suivant;
920:
921: if ((*((struct_liste_pile_systeme *)
922: element_courant)).indice_boucle != NULL)
923: {
924: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
925: element_courant)).indice_boucle).mutex));
926: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
927: element_courant)).indice_boucle).mutex));
928: }
929:
930: liberation(s_etat_processus,
931: (*((struct_liste_pile_systeme *)
932: element_courant)).indice_boucle);
933:
934: if ((*((struct_liste_pile_systeme *)
935: element_courant)).limite_indice_boucle != NULL)
936: {
937: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
938: element_courant)).limite_indice_boucle).mutex));
939: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
940: element_courant)).limite_indice_boucle).mutex));
941: }
942:
943: liberation(s_etat_processus,
944: (*((struct_liste_pile_systeme *)
945: element_courant)).limite_indice_boucle);
946:
947: if ((*((struct_liste_pile_systeme *)
948: element_courant)).objet_de_test != NULL)
949: {
950: pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
951: element_courant)).objet_de_test).mutex));
952: pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
953: element_courant)).objet_de_test).mutex));
954: }
955:
956: liberation(s_etat_processus,
957: (*((struct_liste_pile_systeme *)
958: element_courant)).objet_de_test);
959:
960: if ((*((struct_liste_pile_systeme *)
961: element_courant)).nom_variable != NULL)
962: {
963: free((*((struct_liste_pile_systeme *)
964: element_courant)).nom_variable);
965: }
966:
967: free(element_courant);
968:
969: element_courant = element_suivant;
970: }
971:
972: element_courant = (*s_etat_processus).s_fichiers;
973: while(element_courant != NULL)
974: {
975: element_suivant = (*((struct_liste_chainee *)
976: element_courant)).suivant;
977:
978: element_candidat = (*candidat).s_fichiers;
979: while(element_candidat != NULL)
980: {
981: if (((*((struct_descripteur_fichier *)
982: (*((struct_liste_chainee *) element_courant))
983: .donnee)).pid ==
984: (*((struct_descripteur_fichier *)
985: (*((struct_liste_chainee *) element_candidat))
986: .donnee)).pid) && (pthread_equal(
987: (*((struct_descripteur_fichier *)
988: (*((struct_liste_chainee *) element_courant))
989: .donnee)).tid, (*((struct_descripteur_fichier *)
990: (*((struct_liste_chainee *) element_candidat))
991: .donnee)).tid) != 0))
992: {
993: if ((*((struct_descripteur_fichier *)
994: (*((struct_liste_chainee *) element_courant))
995: .donnee)).type ==
996: (*((struct_descripteur_fichier *)
997: (*((struct_liste_chainee *) element_candidat))
998: .donnee)).type)
999: {
1000: if ((*((struct_descripteur_fichier *)
1001: (*((struct_liste_chainee *)
1002: element_candidat)).donnee)).type == 'C')
1003: {
1004: if ((*((struct_descripteur_fichier *)
1005: (*((struct_liste_chainee *)
1006: element_courant)).donnee))
1007: .descripteur_c ==
1008: (*((struct_descripteur_fichier *)
1009: (*((struct_liste_chainee *)
1010: element_candidat)).donnee))
1011: .descripteur_c)
1012: {
1013: break;
1014: }
1015: }
1016: else
1017: {
1018: if (((*((struct_descripteur_fichier *)
1019: (*((struct_liste_chainee *)
1020: element_courant)).donnee))
1021: .descripteur_sqlite ==
1022: (*((struct_descripteur_fichier *)
1023: (*((struct_liste_chainee *)
1024: element_candidat)).donnee))
1025: .descripteur_sqlite) &&
1026: ((*((struct_descripteur_fichier *)
1027: (*((struct_liste_chainee *)
1028: element_courant)).donnee))
1029: .descripteur_c ==
1030: (*((struct_descripteur_fichier *)
1031: (*((struct_liste_chainee *)
1032: element_candidat)).donnee))
1033: .descripteur_c))
1034: {
1035: break;
1036: }
1037: }
1038: }
1039: }
1040:
1041: element_candidat = (*((struct_liste_chainee *)
1042: element_candidat)).suivant;
1043: }
1044:
1045: if (element_candidat == NULL)
1046: {
1047: fclose((*((struct_descripteur_fichier *)
1048: (*((struct_liste_chainee *) element_courant))
1049: .donnee)).descripteur_c);
1050:
1051: if ((*((struct_descripteur_fichier *)
1052: (*((struct_liste_chainee *) element_courant))
1053: .donnee)).type != 'C')
1054: {
1055: sqlite3_close((*((struct_descripteur_fichier *)
1056: (*((struct_liste_chainee *) element_courant))
1057: .donnee)).descripteur_sqlite);
1058: }
1059: }
1060:
1061: free((*((struct_descripteur_fichier *)
1062: (*((struct_liste_chainee *)
1063: element_courant)).donnee)).nom);
1064: free((struct_descripteur_fichier *)
1065: (*((struct_liste_chainee *)
1066: element_courant)).donnee);
1067: free(element_courant);
1068:
1069: element_courant = element_suivant;
1070: }
1071:
1072: element_courant = (*s_etat_processus).s_sockets;
1073: while(element_courant != NULL)
1074: {
1075: element_suivant = (*((struct_liste_chainee *)
1076: element_courant)).suivant;
1077:
1078: element_candidat = (*candidat).s_sockets;
1079: while(element_candidat != NULL)
1080: {
1081: if (((*((struct_socket *)
1082: (*((struct_liste_chainee *) element_courant))
1083: .donnee)).socket == (*((struct_socket *)
1084: (*((struct_liste_chainee *) element_candidat))
1085: .donnee)).socket) &&
1086: ((*((struct_socket *)
1087: (*((struct_liste_chainee *) element_courant))
1088: .donnee)).pid == (*((struct_socket *)
1089: (*((struct_liste_chainee *) element_candidat))
1090: .donnee)).pid) && (pthread_equal(
1091: (*((struct_socket *)
1092: (*((struct_liste_chainee *) element_courant))
1093: .donnee)).tid, (*((struct_socket *)
1094: (*((struct_liste_chainee *) element_candidat))
1095: .donnee)).tid) != 0))
1096: {
1097: break;
1098: }
1099:
1100: element_candidat = (*((struct_liste_chainee *)
1101: element_candidat)).suivant;
1102: }
1103:
1104: if (element_candidat == NULL)
1105: {
1106: if ((*((struct_socket *) (*((struct_liste_chainee *)
1107: element_courant)).donnee)).socket_connectee
1108: == d_vrai)
1109: {
1110: shutdown((*((struct_socket *)
1111: (*((struct_liste_chainee *) element_courant))
1112: .donnee)).socket, SHUT_RDWR);
1113: }
1114:
1115: close((*((struct_socket *)
1116: (*((struct_liste_chainee *) element_courant))
1117: .donnee)).socket);
1118: }
1119:
1120: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1121: element_courant)).donnee).mutex));
1122: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1123: element_courant)).donnee).mutex));
1124:
1125: liberation(s_etat_processus,
1126: (*((struct_liste_chainee *)
1127: element_courant)).donnee);
1128: free(element_courant);
1129:
1130: element_courant = element_suivant;
1131: }
1132:
1133: /*
1134: ================================================================================
1135: À noter : on ne ferme pas la connexion car la conséquence immédiate est
1136: une destruction de l'objet pour le processus père.
1137: ================================================================================
1138:
1139: element_courant = (*s_etat_processus).s_connecteurs_sql;
1140: while(element_courant != NULL)
1141: {
1142: element_suivant = (*((struct_liste_chainee *)
1143: element_courant)).suivant;
1144:
1145: element_candidat = (*candidat).s_connecteurs_sql;
1146: while(element_candidat != NULL)
1147: {
1148: if (((
1149: #ifdef MYSQL_SUPPORT
1150: ((*((struct_connecteur_sql *)
1151: (*((struct_liste_chainee *) element_courant))
1152: .donnee)).descripteur.mysql ==
1153: (*((struct_connecteur_sql *)
1154: (*((struct_liste_chainee *) element_candidat))
1155: .donnee)).descripteur.mysql)
1156: &&
1157: (strcmp((*((struct_connecteur_sql *)
1158: (*((struct_liste_chainee *) element_courant))
1159: .donnee)).type, "MYSQL") == 0)
1160: &&
1161: (strcmp((*((struct_connecteur_sql *)
1162: (*((struct_liste_chainee *) element_candidat))
1163: .donnee)).type, "MYSQL") == 0)
1164: #else
1165: 0
1166: #endif
1167: ) || (
1168: #ifdef POSTGRESQL_SUPPORT
1169: ((*((struct_connecteur_sql *)
1170: (*((struct_liste_chainee *) element_courant))
1171: .donnee)).descripteur.postgresql ==
1172: (*((struct_connecteur_sql *)
1173: (*((struct_liste_chainee *) element_candidat))
1174: .donnee)).descripteur.postgresql)
1175: &&
1176: (strcmp((*((struct_connecteur_sql *)
1177: (*((struct_liste_chainee *) element_courant))
1178: .donnee)).type, "POSTGRESQL") == 0)
1179: &&
1180: (strcmp((*((struct_connecteur_sql *)
1181: (*((struct_liste_chainee *) element_candidat))
1182: .donnee)).type, "POSTGRESQL") == 0)
1183: #else
1184: 0
1185: #endif
1186: )) &&
1187: ((*((struct_connecteur_sql *)
1188: (*((struct_liste_chainee *) element_courant))
1189: .donnee)).pid == (*((struct_connecteur_sql *)
1190: (*((struct_liste_chainee *) element_candidat))
1191: .donnee)).pid) && (pthread_equal(
1192: (*((struct_connecteur_sql *)
1193: (*((struct_liste_chainee *) element_courant))
1194: .donnee)).tid, (*((struct_connecteur_sql *)
1195: (*((struct_liste_chainee *) element_candidat))
1196: .donnee)).tid) != 0))
1197: {
1198: break;
1199: }
1200:
1201: element_candidat = (*((struct_liste_chainee *)
1202: element_candidat)).suivant;
1203: }
1204:
1205: if (element_candidat == NULL)
1206: {
1207: sqlclose((*((struct_liste_chainee *) element_courant))
1208: .donnee);
1209: }
1210:
1211: pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
1212: element_courant)).donnee).mutex));
1213: pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
1214: element_courant)).donnee).mutex));
1215:
1216: liberation(s_etat_processus, (*((struct_liste_chainee *)
1217: element_courant)).donnee);
1218: free(element_courant);
1219:
1220: element_courant = element_suivant;
1221: }
1222: */
1223:
1224: (*s_etat_processus).s_connecteurs_sql = NULL;
1225:
1226: element_courant = (*s_etat_processus).s_marques;
1227: while(element_courant != NULL)
1228: {
1229: free((*((struct_marque *) element_courant)).label);
1230: free((*((struct_marque *) element_courant)).position);
1231: element_suivant = (*((struct_marque *) element_courant))
1232: .suivant;
1233: free(element_courant);
1234: element_courant = element_suivant;
1235: }
1236:
1237: liberation_allocateur(s_etat_processus);
1238:
1239: # ifndef SEMAPHORES_NOMMES
1240: sem_post(&((*s_etat_processus).semaphore_fork));
1241: sem_destroy(&((*s_etat_processus).semaphore_fork));
1242: # else
1243: sem_post((*s_etat_processus).semaphore_fork);
1244: sem_close((*s_etat_processus).semaphore_fork);
1245: # endif
1246:
1247: liberation_contexte_cas(s_etat_processus);
1248: free(s_etat_processus);
1249:
1250: s_etat_processus = candidat;
1251: }
1252:
1253: l_element_suivant = (*l_element_courant).suivant;
1254:
1255: free((struct_thread *) (*l_element_courant).donnee);
1256: free((struct_liste_chainee *) l_element_courant);
1257:
1258: l_element_courant = l_element_suivant;
1259: }
1260:
1261: liste_threads = NULL;
1262:
1263: l_element_courant = liste_threads_surveillance;
1264:
1265: while(l_element_courant != NULL)
1266: {
1267: s_argument_thread = (struct_descripteur_thread *)
1268: (*l_element_courant).donnee;
1269:
1270: if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
1271: != 0)
1272: {
1273: (*s_etat_processus).erreur_systeme = d_es_processus;
1274: pthread_mutex_unlock(&mutex_liste_threads);
1275: return;
1276: }
1277:
1278: (*s_argument_thread).nombre_references--;
1279:
1280: BUG((*s_argument_thread).nombre_references < 0,
1281: printf("(*s_argument_thread).nombre_references = %d\n",
1282: (int) (*s_argument_thread).nombre_references));
1283:
1284: if ((*s_argument_thread).nombre_references == 0)
1285: {
1286: close((*s_argument_thread).pipe_objets[0]);
1287: close((*s_argument_thread).pipe_acquittement[1]);
1288: close((*s_argument_thread).pipe_injections[1]);
1289: close((*s_argument_thread).pipe_nombre_injections[1]);
1290: close((*s_argument_thread).pipe_nombre_objets_attente[0]);
1291: close((*s_argument_thread).pipe_interruptions[0]);
1292: close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);
1293:
1294: if (pthread_mutex_unlock(&((*s_argument_thread)
1295: .mutex_nombre_references)) != 0)
1296: {
1297: (*s_etat_processus).erreur_systeme = d_es_processus;
1298: pthread_mutex_unlock(&mutex_liste_threads);
1299: return;
1300: }
1301:
1302: pthread_mutex_destroy(&((*s_argument_thread).mutex));
1303: pthread_mutex_destroy(&((*s_argument_thread)
1304: .mutex_nombre_references));
1305:
1306: if ((*s_argument_thread).processus_detache == d_faux)
1307: {
1308: if ((*s_argument_thread).destruction_objet == d_vrai)
1309: {
1310: liberation(s_etat_processus, (*s_argument_thread).argument);
1311: }
1312: }
1313:
1314: free(s_argument_thread);
1315: }
1316: else
1317: {
1318: if (pthread_mutex_unlock(&((*s_argument_thread)
1319: .mutex_nombre_references)) != 0)
1320: {
1321: (*s_etat_processus).erreur_systeme = d_es_processus;
1322: pthread_mutex_unlock(&mutex_liste_threads);
1323: return;
1324: }
1325: }
1326:
1327: l_element_suivant = (*l_element_courant).suivant;
1328: free((struct_liste_chainee *) l_element_courant);
1329: l_element_courant = l_element_suivant;
1330: }
1331:
1332: liste_threads_surveillance = NULL;
1333:
1334: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1335: {
1336: (*s_etat_processus).erreur_systeme = d_es_processus;
1337: return;
1338: }
1339:
1340: return;
1341: }
1342:
1343: static struct_processus *
1344: recherche_thread(pid_t pid, pthread_t tid)
1345: {
1346: volatile struct_liste_chainee_volatile *l_element_courant;
1347:
1348: struct_processus *s_etat_processus;
1349:
1350: l_element_courant = liste_threads;
1351:
1352: while(l_element_courant != NULL)
1353: {
1354: if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee))
1355: .tid, tid) != 0) && ((*((struct_thread *)
1356: (*l_element_courant).donnee)).pid == pid))
1357: {
1358: break;
1359: }
1360:
1361: l_element_courant = (*l_element_courant).suivant;
1362: }
1363:
1364: if (l_element_courant == NULL)
1365: {
1366: /*
1367: * Le processus n'existe plus. On ne distribue aucun signal.
1368: */
1369:
1370: return(NULL);
1371: }
1372:
1373: s_etat_processus = (*((struct_thread *)
1374: (*l_element_courant).donnee)).s_etat_processus;
1375:
1376: return(s_etat_processus);
1377: }
1378:
1379: static struct_processus *
1380: recherche_thread_principal(pid_t pid)
1381: {
1382: volatile struct_liste_chainee_volatile *l_element_courant;
1383:
1384: l_element_courant = liste_threads;
1385:
1386: while(l_element_courant != NULL)
1387: {
1388: if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal
1389: == d_vrai) && ((*((struct_thread *)
1390: (*l_element_courant).donnee)).pid == pid))
1391: {
1392: break;
1393: }
1394:
1395: l_element_courant = (*l_element_courant).suivant;
1396: }
1397:
1398: if (l_element_courant == NULL)
1399: {
1400: /*
1401: * Le processus n'existe plus. On ne distribue aucun signal.
1402: */
1403:
1404: return(NULL);
1405: }
1406:
1407: return((*((struct_thread *) (*l_element_courant).donnee))
1408: .s_etat_processus);
1409: }
1410:
1411:
1412: /*
1413: ================================================================================
1414: Procédures de gestion des signaux d'interruption
1415: ================================================================================
1416: Entrée : variable globale
1417: --------------------------------------------------------------------------------
1418: Sortie : variable globale modifiée
1419: --------------------------------------------------------------------------------
1420: Effets de bord : néant
1421: ================================================================================
1422: */
1423:
1424: // Les routines suivantes sont uniquement appelées depuis les gestionnaires
1425: // des signaux asynchrones. Elles ne doivent pas bloquer dans le cas où
1426: // les sémaphores sont déjà bloqués par un gestionnaire de signal.
1427:
1428: static inline void
1429: verrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
1430: {
1431: int semaphore;
1432:
1433: # ifndef SEMAPHORES_NOMMES
1434: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
1435: # else
1436: if (sem_post((*s_etat_processus).semaphore_fork) != 0)
1437: # endif
1438: {
1439: BUG(1, uprintf("Lock error !\n"));
1440: return;
1441: }
1442:
1443: // Il faut respecteur l'atomicité des deux opérations suivantes !
1444:
1445: if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) != 0)
1446: {
1447: # ifndef SEMAPHORES_NOMMES
1448: sem_wait(&((*s_etat_processus).semaphore_fork));
1449: # else
1450: sem_wait((*s_etat_processus).semaphore_fork);
1451: # endif
1452: BUG(1, uprintf("Unlock error !\n"));
1453: return;
1454: }
1455:
1456: # ifndef SEMAPHORES_NOMMES
1457: if (sem_post(&semaphore_gestionnaires_signaux) == -1)
1458: # else
1459: if (sem_post(semaphore_gestionnaires_signaux) == -1)
1460: # endif
1461: {
1462: # ifndef SEMAPHORES_NOMMES
1463: sem_wait(&((*s_etat_processus).semaphore_fork));
1464: # else
1465: sem_wait((*s_etat_processus).semaphore_fork);
1466: # endif
1467: BUG(1, uprintf("Lock error !\n"));
1468: return;
1469: }
1470:
1471: # ifndef SEMAPHORES_NOMMES
1472: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1473: # else
1474: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1475: # endif
1476: {
1477: # ifndef SEMAPHORES_NOMMES
1478: sem_wait(&((*s_etat_processus).semaphore_fork));
1479: # else
1480: sem_wait((*s_etat_processus).semaphore_fork);
1481: # endif
1482: BUG(1, uprintf("Lock error !\n"));
1483: return;
1484: }
1485:
1486: if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)
1487: {
1488: # ifndef SEMAPHORES_NOMMES
1489: sem_wait(&((*s_etat_processus).semaphore_fork));
1490: # else
1491: sem_wait((*s_etat_processus).semaphore_fork);
1492: # endif
1493: BUG(1, uprintf("Unlock error !\n"));
1494: return;
1495: }
1496:
1497: if (semaphore == 1)
1498: {
1499: // Le semaphore ne peut être pris par le thread qui a appelé
1500: // le gestionnaire de signal car le signal est bloqué par ce thread
1501: // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que
1502: // par un thread concurrent. On essaye donc de le bloquer jusqu'à
1503: // ce que ce soit possible.
1504:
1505: if (pthread_mutex_lock(&mutex_liste_threads) != 0)
1506: {
1507: # ifndef SEMAPHORES_NOMMES
1508: sem_wait(&((*s_etat_processus).semaphore_fork));
1509: # else
1510: sem_wait((*s_etat_processus).semaphore_fork);
1511: # endif
1512: BUG(1, uprintf("Lock error !\n"));
1513: return;
1514: }
1515: }
1516:
1517: return;
1518: }
1519:
1520: static inline void
1521: deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
1522: {
1523: int semaphore;
1524:
1525: // Il faut respecteur l'atomicité des deux opérations suivantes !
1526:
1527: if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) == -1)
1528: {
1529: # ifndef SEMAPHORES_NOMMES
1530: sem_wait(&((*s_etat_processus).semaphore_fork));
1531: # else
1532: sem_wait((*s_etat_processus).semaphore_fork);
1533: # endif
1534: BUG(1, uprintf("Unlock error !\n"));
1535: return;
1536: }
1537:
1538: # ifndef SEMAPHORES_NOMMES
1539: if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1540: # else
1541: if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
1542: # endif
1543: {
1544: # ifndef SEMAPHORES_NOMMES
1545: sem_wait(&((*s_etat_processus).semaphore_fork));
1546: # else
1547: sem_wait((*s_etat_processus).semaphore_fork);
1548: # endif
1549: BUG(1, uprintf("Unlock error !\n"));
1550: return;
1551: }
1552:
1553: # ifndef SEMAPHORES_NOMMES
1554: while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
1555: # else
1556: while(sem_wait(semaphore_gestionnaires_signaux) == -1)
1557: # endif
1558: {
1559: if (errno != EINTR)
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:
1571: if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)
1572: {
1573: # ifndef SEMAPHORES_NOMMES
1574: sem_wait(&((*s_etat_processus).semaphore_fork));
1575: # else
1576: sem_wait((*s_etat_processus).semaphore_fork);
1577: # endif
1578: BUG(1, uprintf("Unlock error !\n"));
1579: return;
1580: }
1581:
1582: # ifndef SEMAPHORES_NOMMES
1583: while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
1584: # else
1585: while(sem_wait((*s_etat_processus).semaphore_fork) != 0)
1586: # endif
1587: {
1588: if (errno != EINTR)
1589: {
1590: BUG(1, uprintf("Unlock error !\n"));
1591: return;
1592: }
1593: }
1594:
1595: if (semaphore == 1)
1596: {
1597: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1598: {
1599: BUG(1, uprintf("Unlock error !\n"));
1600: return;
1601: }
1602: }
1603:
1604: return;
1605: }
1606:
1607: #define test_signal(signal) \
1608: if (signal_test == SIGTEST) { signal_test = signal; return; }
1609:
1610: // Récupération des signaux
1611: // - SIGINT (arrêt au clavier)
1612: // - SIGTERM (signal d'arrêt en provenance du système)
1613:
1614: void
1615: interruption1(int signal)
1616: {
1617: test_signal(signal);
1618:
1619: switch(signal)
1620: {
1621: case SIGINT:
1622: envoi_signal_processus(getpid(), rpl_sigint);
1623: break;
1624:
1625: case SIGTERM:
1626: envoi_signal_processus(getpid(), rpl_sigterm);
1627: break;
1628:
1629: case SIGUSR1:
1630: envoi_signal_processus(getpid(), rpl_sigalrm);
1631: break;
1632: }
1633:
1634: return;
1635: }
1636:
1637: inline static void
1638: signal_alrm(struct_processus *s_etat_processus, pid_t pid)
1639: {
1640: struct_processus *s_thread_principal;
1641:
1642: verrouillage_gestionnaire_signaux(s_etat_processus);
1643:
1644: if (pid == getpid())
1645: {
1646: // Si pid est égal à getpid(), le signal à traiter est issu
1647: // du même processus que celui qui va le traiter, mais d'un thread
1648: // différent.
1649:
1650: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1651: {
1652: printf("[%d] RPL/SIGALRM (thread %llu)\n", (int) getpid(),
1653: (unsigned long long) pthread_self());
1654: fflush(stdout);
1655: }
1656:
1657: if ((*s_etat_processus).pid_processus_pere != getpid())
1658: {
1659: // On n'est pas dans le processus père, on remonte le signal.
1660: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1661: rpl_sigalrm);
1662: }
1663: else
1664: {
1665: // On est dans le processus père, on effectue un arrêt d'urgence.
1666: (*s_etat_processus).var_volatile_alarme = -1;
1667: (*s_etat_processus).var_volatile_requete_arret = -1;
1668: }
1669: }
1670: else
1671: {
1672: // Le signal est issu d'un processus différent. On recherche le
1673: // thread principal pour remonter le signal.
1674:
1675: if ((s_thread_principal = recherche_thread_principal(getpid()))
1676: != NULL)
1677: {
1678: envoi_signal_contexte(s_thread_principal, rpl_sigalrm);
1679: }
1680: }
1681:
1682: deverrouillage_gestionnaire_signaux(s_etat_processus);
1683: return;
1684: }
1685:
1686: inline static void
1687: signal_term(struct_processus *s_etat_processus, pid_t pid)
1688: {
1689: struct_processus *s_thread_principal;
1690: pthread_mutex_t exclusion = PTHREAD_MUTEX_INITIALIZER;
1691:
1692: verrouillage_gestionnaire_signaux(s_etat_processus);
1693:
1694: if (pid == getpid())
1695: {
1696: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1697: {
1698: printf("[%d] RPL/SIGTERM (thread %llu)\n", (int) getpid(),
1699: (unsigned long long) pthread_self());
1700: fflush(stdout);
1701: }
1702:
1703: if ((*s_etat_processus).pid_processus_pere != getpid())
1704: {
1705: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1706: rpl_sigterm);
1707: }
1708: else
1709: {
1710: (*s_etat_processus).var_volatile_traitement_sigint = -1;
1711:
1712: pthread_mutex_lock(&exclusion);
1713:
1714: if ((*s_etat_processus).var_volatile_requete_arret == -1)
1715: {
1716: deverrouillage_gestionnaire_signaux(s_etat_processus);
1717: pthread_mutex_unlock(&exclusion);
1718: return;
1719: }
1720:
1721: (*s_etat_processus).var_volatile_requete_arret = -1;
1722: (*s_etat_processus).var_volatile_alarme = -1;
1723:
1724: pthread_mutex_unlock(&exclusion);
1725: }
1726: }
1727: else
1728: {
1729: if ((s_thread_principal = recherche_thread_principal(getpid()))
1730: != NULL)
1731: {
1732: envoi_signal_contexte(s_thread_principal, rpl_sigterm);
1733: }
1734: }
1735:
1736: deverrouillage_gestionnaire_signaux(s_etat_processus);
1737: return;
1738: }
1739:
1740: inline static void
1741: signal_int(struct_processus *s_etat_processus, pid_t pid)
1742: {
1743: struct_processus *s_thread_principal;
1744: volatile sig_atomic_t exclusion = 0;
1745:
1746: verrouillage_gestionnaire_signaux(s_etat_processus);
1747:
1748: if (pid == getpid())
1749: {
1750: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1751: {
1752: printf("[%d] RPL/SIGINT (thread %llu)\n", (int) getpid(),
1753: (unsigned long long) pthread_self());
1754: fflush(stdout);
1755: }
1756:
1757: if ((*s_etat_processus).pid_processus_pere != getpid())
1758: {
1759: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1760: rpl_sigint);
1761: }
1762: else
1763: {
1764: (*s_etat_processus).var_volatile_traitement_sigint = -1;
1765:
1766: while(exclusion == 1);
1767: exclusion = 1;
1768:
1769: if ((*s_etat_processus).var_volatile_requete_arret == -1)
1770: {
1771: deverrouillage_gestionnaire_signaux(s_etat_processus);
1772: exclusion = 0;
1773: return;
1774: }
1775:
1776: if ((*s_etat_processus).langue == 'F')
1777: {
1778: printf("+++Interruption\n");
1779: }
1780: else
1781: {
1782: printf("+++Interrupt\n");
1783: }
1784:
1785: fflush(stdout);
1786:
1787: (*s_etat_processus).var_volatile_requete_arret = -1;
1788: (*s_etat_processus).var_volatile_alarme = -1;
1789:
1790: exclusion = 0;
1791: }
1792: }
1793: else
1794: {
1795: if ((s_thread_principal = recherche_thread_principal(getpid()))
1796: != NULL)
1797: {
1798: envoi_signal_contexte(s_thread_principal, rpl_sigint);
1799: }
1800: }
1801:
1802: deverrouillage_gestionnaire_signaux(s_etat_processus);
1803: return;
1804: }
1805:
1806: // Récupération des signaux
1807: // - SIGFSTP
1808: //
1809: // ATTENTION :
1810: // Le signal SIGFSTP provient de la mort du processus de contrôle.
1811: // Sous certains systèmes (Linux...), la mort du terminal de contrôle
1812: // se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
1813: // (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
1814: // non initialisée (pointeur NULL) issue de TERMIO.
1815:
1816: void
1817: interruption2(int signal)
1818: {
1819: test_signal(signal);
1820: envoi_signal_processus(getpid(), rpl_sigtstp);
1821: return;
1822: }
1823:
1824: static inline void
1825: signal_tstp(struct_processus *s_etat_processus, pid_t pid)
1826: {
1827: struct_processus *s_thread_principal;
1828:
1829: verrouillage_gestionnaire_signaux(s_etat_processus);
1830:
1831: if (pid == getpid())
1832: {
1833: /*
1834: * 0 => fonctionnement normal
1835: * -1 => requête
1836: * 1 => requête acceptée en attente de traitement
1837: */
1838:
1839: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1840: {
1841: printf("[%d] RPL/SIGTSTP (thread %llu)\n", (int) getpid(),
1842: (unsigned long long) pthread_self());
1843: fflush(stdout);
1844: }
1845:
1846: if ((*s_etat_processus).var_volatile_processus_pere == 0)
1847: {
1848: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1849: rpl_sigtstp);
1850: }
1851: else
1852: {
1853: (*s_etat_processus).var_volatile_requete_arret2 = -1;
1854: }
1855: }
1856: else
1857: {
1858: // Envoi d'un signal au thread maître du groupe.
1859:
1860: if ((s_thread_principal = recherche_thread_principal(getpid()))
1861: != NULL)
1862: {
1863: envoi_signal_contexte(s_thread_principal, rpl_sigtstp);
1864: }
1865: }
1866:
1867: deverrouillage_gestionnaire_signaux(s_etat_processus);
1868: return;
1869: }
1870:
1871: void
1872: interruption3(int signal)
1873: {
1874: // Si on passe par ici, c'est qu'il est impossible de récupérer
1875: // l'erreur d'accès à la mémoire. On sort donc du programme quitte à
1876: // ce qu'il reste des processus orphelins.
1877:
1878: unsigned char message_1[] = "+++System : Uncaught access violation\n"
1879: "+++System : Aborting !\n";
1880: unsigned char message_2[] = "+++System : Stack overflow\n"
1881: "+++System : Aborting !\n";
1882:
1883: test_signal(signal);
1884:
1885: if (pid_processus_pere == getpid())
1886: {
1887: kill(pid_processus_pere, SIGUSR1);
1888: }
1889:
1890: if (signal != SIGUSR2)
1891: {
1892: write(STDERR_FILENO, message_1, strlen(message_1));
1893: }
1894: else
1895: {
1896: write(STDERR_FILENO, message_2, strlen(message_2));
1897: }
1898:
1899: _exit(EXIT_FAILURE);
1900: }
1901:
1902:
1903: static void
1904: sortie_interruption_depassement_pile(void *arg1, void *arg2, void *arg3)
1905: {
1906: switch((*((volatile int *) arg1)))
1907: {
1908: case 1:
1909: longjmp(contexte_ecriture, -1);
1910: break;
1911:
1912: case 2:
1913: longjmp(contexte_impression, -1);
1914: break;
1915: }
1916:
1917: return;
1918: }
1919:
1920:
1921: void
1922: interruption_depassement_pile(int urgence, stackoverflow_context_t scp)
1923: {
1924: if ((urgence == 0) && (routine_recursive != 0))
1925: {
1926: // On peut tenter de récupérer le dépassement de pile. Si la variable
1927: // 'routine_recursive' est non nulle, on récupère l'erreur.
1928:
1929: sigsegv_leave_handler(sortie_interruption_depassement_pile,
1930: (void *) &routine_recursive, NULL, NULL);
1931: }
1932:
1933: // Ici, la panique est totale et il vaut mieux quitter l'application.
1934: interruption3(SIGUSR2);
1935: return;
1936: }
1937:
1938:
1939: int
1940: interruption_violation_access(void *adresse_fautive, int gravite)
1941: {
1942: unsigned char message[] = "+++System : Trying to catch access "
1943: "violation\n";
1944:
1945: static int compteur_erreur = 0;
1946:
1947: if ((gravite == 0) && (routine_recursive != 0))
1948: {
1949: // Il peut s'agir d'un dépassement de pile.
1950:
1951: sigsegv_leave_handler(sortie_interruption_depassement_pile,
1952: (void *) &routine_recursive, NULL, NULL);
1953: }
1954:
1955: // On est dans une bonne vieille violation d'accès. On essaie
1956: // de fermer au mieux l'application.
1957:
1958: compteur_erreur++;
1959:
1960: if (compteur_erreur >= 2)
1961: {
1962: // Erreurs multiples, on arrête l'application.
1963: interruption3(SIGSEGV);
1964: return(0);
1965: }
1966:
1967: write(STDERR_FILENO, message, strlen(message));
1968:
1969: if (pid_processus_pere == getpid())
1970: {
1971: longjmp(contexte_initial, -1);
1972: return(1);
1973: }
1974: else
1975: {
1976: longjmp(contexte_processus, -1);
1977: return(1);
1978: }
1979:
1980: // On renvoie 0 parce qu'on décline toute responsabilité quant à la
1981: // suite des événements...
1982: return(0);
1983: }
1984:
1985: // Traitement de rpl_sigstart
1986:
1987: static inline void
1988: signal_start(struct_processus *s_etat_processus, pid_t pid)
1989: {
1990: struct_processus *s_thread_principal;
1991:
1992: verrouillage_gestionnaire_signaux(s_etat_processus);
1993:
1994: if (pid == getpid())
1995: {
1996: (*s_etat_processus).demarrage_fils = d_vrai;
1997: }
1998: else
1999: {
2000: // Envoi d'un signal au thread maître du groupe.
2001:
2002: if ((s_thread_principal = recherche_thread_principal(getpid()))
2003: != NULL)
2004: {
2005: envoi_signal_contexte(s_thread_principal, rpl_sigstart);
2006: }
2007: }
2008:
2009: deverrouillage_gestionnaire_signaux(s_etat_processus);
2010: return;
2011: }
2012:
2013: // Traitement de rpl_sigcont
2014:
2015: static inline void
2016: signal_cont(struct_processus *s_etat_processus, pid_t pid)
2017: {
2018: struct_processus *s_thread_principal;
2019:
2020: verrouillage_gestionnaire_signaux(s_etat_processus);
2021:
2022: if (pid == getpid())
2023: {
2024: (*s_etat_processus).redemarrage_processus = d_vrai;
2025: }
2026: else
2027: {
2028: // Envoi d'un signal au thread maître du groupe.
2029:
2030: if ((s_thread_principal = recherche_thread_principal(getpid()))
2031: != NULL)
2032: {
2033: envoi_signal_contexte(s_thread_principal, rpl_sigcont);
2034: }
2035: }
2036:
2037: deverrouillage_gestionnaire_signaux(s_etat_processus);
2038: return;
2039: }
2040:
2041: // Traitement de rpl_sigstop
2042:
2043: static inline void
2044: signal_stop(struct_processus *s_etat_processus, pid_t pid)
2045: {
2046: struct_processus *s_thread_principal;
2047:
2048: verrouillage_gestionnaire_signaux(s_etat_processus);
2049:
2050: if (pid == getpid())
2051: {
2052: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2053: {
2054: printf("[%d] RPL/SIGSTOP (thread %llu)\n", (int) getpid(),
2055: (unsigned long long) pthread_self());
2056: fflush(stdout);
2057: }
2058:
2059: /*
2060: * var_globale_traitement_retarde_stop :
2061: * 0 -> traitement immédiat
2062: * 1 -> traitement retardé (aucun signal reçu)
2063: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2064: */
2065:
2066: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
2067: {
2068: (*s_etat_processus).var_volatile_requete_arret = -1;
2069: }
2070: else
2071: {
2072: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
2073: }
2074: }
2075: else
2076: {
2077: // Envoi d'un signal au thread maître du groupe.
2078:
2079: if ((s_thread_principal = recherche_thread_principal(getpid()))
2080: != NULL)
2081: {
2082: envoi_signal_contexte(s_thread_principal, rpl_sigstop);
2083: }
2084: }
2085:
2086: deverrouillage_gestionnaire_signaux(s_etat_processus);
2087: return;
2088: }
2089:
2090: // Traitement de rpl_siginject
2091:
2092: static inline void
2093: signal_inject(struct_processus *s_etat_processus, pid_t pid)
2094: {
2095: verrouillage_gestionnaire_signaux(s_etat_processus);
2096:
2097: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2098: {
2099: deverrouillage_gestionnaire_signaux(s_etat_processus);
2100: return;
2101: }
2102:
2103: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2104: {
2105: printf("[%d] RPL/SIGINJECT (thread %llu)\n", (int) getpid(),
2106: (unsigned long long) pthread_self());
2107: fflush(stdout);
2108: }
2109:
2110: deverrouillage_gestionnaire_signaux(s_etat_processus);
2111: return;
2112: }
2113:
2114: // Récupération des signaux
2115: // - SIGPIPE
2116:
2117: void
2118: interruption5(int signal)
2119: {
2120: unsigned char message[] = "+++System : SIGPIPE\n"
2121: "+++System : Aborting !\n";
2122:
2123: test_signal(signal);
2124:
2125: if (pid_processus_pere == getpid())
2126: {
2127: envoi_signal_processus(pid_processus_pere, rpl_sigalrm);
2128: }
2129:
2130: write(STDERR_FILENO, message, strlen(message));
2131: return;
2132: }
2133:
2134: static inline void
2135: signal_urg(struct_processus *s_etat_processus, pid_t pid)
2136: {
2137: struct_processus *s_thread_principal;
2138:
2139: verrouillage_gestionnaire_signaux(s_etat_processus);
2140:
2141: if (pid == getpid())
2142: {
2143: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2144: {
2145: printf("[%d] RPL/SIGURG (thread %llu)\n", (int) getpid(),
2146: (unsigned long long) pthread_self());
2147: fflush(stdout);
2148: }
2149:
2150: (*s_etat_processus).var_volatile_alarme = -1;
2151: (*s_etat_processus).var_volatile_requete_arret = -1;
2152: }
2153: else
2154: {
2155: // Envoi d'un signal au thread maître du groupe.
2156:
2157: if ((s_thread_principal = recherche_thread_principal(getpid()))
2158: != NULL)
2159: {
2160: envoi_signal_contexte(s_thread_principal, rpl_sigurg);
2161: }
2162: }
2163:
2164: deverrouillage_gestionnaire_signaux(s_etat_processus);
2165: return;
2166: }
2167:
2168: // Traitement de rpl_sigabort
2169:
2170: static inline void
2171: signal_abort(struct_processus *s_etat_processus, pid_t pid)
2172: {
2173: struct_processus *s_thread_principal;
2174:
2175: verrouillage_gestionnaire_signaux(s_etat_processus);
2176:
2177: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2178: {
2179: deverrouillage_gestionnaire_signaux(s_etat_processus);
2180: return;
2181: }
2182:
2183: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2184: {
2185: printf("[%d] RPL/SIGABORT (thread %llu)\n", (int) getpid(),
2186: (unsigned long long) pthread_self());
2187: fflush(stdout);
2188: }
2189:
2190: if (pid == getpid())
2191: {
2192: (*s_etat_processus).arret_depuis_abort = -1;
2193:
2194: /*
2195: * var_globale_traitement_retarde_stop :
2196: * 0 -> traitement immédiat
2197: * 1 -> traitement retardé (aucun signal reçu)
2198: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2199: */
2200:
2201: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
2202: {
2203: (*s_etat_processus).var_volatile_requete_arret = -1;
2204: }
2205: else
2206: {
2207: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
2208: }
2209: }
2210: else
2211: {
2212: (*s_etat_processus).arret_depuis_abort = -1;
2213:
2214: // Envoi d'un signal au thread maître du groupe.
2215:
2216: if ((s_thread_principal = recherche_thread_principal(getpid()))
2217: != NULL)
2218: {
2219: envoi_signal_contexte(s_thread_principal, rpl_sigabort);
2220: }
2221: }
2222:
2223: deverrouillage_gestionnaire_signaux(s_etat_processus);
2224: return;
2225: }
2226:
2227: // Récupération des signaux
2228: // - SIGHUP
2229:
2230: void
2231: interruption4(int signal)
2232: {
2233: test_signal(signal);
2234: envoi_signal_processus(getpid(), rpl_sighup);
2235: return;
2236: }
2237:
2238: static inline void
2239: signal_hup(struct_processus *s_etat_processus, pid_t pid)
2240: {
2241: file *fichier;
2242:
2243: unsigned char nom[8 + 64 + 1];
2244:
2245: verrouillage_gestionnaire_signaux(s_etat_processus);
2246:
2247: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2248: {
2249: deverrouillage_gestionnaire_signaux(s_etat_processus);
2250: return;
2251: }
2252:
2253: snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
2254: (unsigned long) pthread_self());
2255:
2256: if ((fichier = fopen(nom, "w+")) != NULL)
2257: {
2258: fclose(fichier);
2259:
2260: freopen(nom, "w", stdout);
2261: freopen(nom, "w", stderr);
2262: }
2263:
2264: freopen("/dev/null", "r", stdin);
2265:
2266: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2267: {
2268: printf("[%d] RPL/SIGHUP (thread %llu)\n", (int) getpid(),
2269: (unsigned long long) pthread_self());
2270: fflush(stdout);
2271: }
2272:
2273: deverrouillage_gestionnaire_signaux(s_etat_processus);
2274: return;
2275: }
2276:
2277: void
2278: traitement_exceptions_gsl(const char *reason, const char *file,
2279: int line, int gsl_errno)
2280: {
2281: code_erreur_gsl = gsl_errno;
2282: envoi_signal_processus(getpid(), rpl_sigexcept);
2283: return;
2284: }
2285:
2286: static inline void
2287: signal_except(struct_processus *s_etat_processus, pid_t pid)
2288: {
2289: verrouillage_gestionnaire_signaux(s_etat_processus);
2290:
2291: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2292: {
2293: deverrouillage_gestionnaire_signaux(s_etat_processus);
2294: return;
2295: }
2296:
2297: (*s_etat_processus).var_volatile_exception_gsl = code_erreur_gsl;
2298: deverrouillage_gestionnaire_signaux(s_etat_processus);
2299:
2300: return;
2301: }
2302:
2303: static inline void
2304: envoi_interruptions(struct_processus *s_etat_processus, enum signaux_rpl signal,
2305: pid_t pid_source)
2306: {
2307: switch(signal)
2308: {
2309: case rpl_signull:
2310: break;
2311:
2312: case rpl_sigint:
2313: signal_int(s_etat_processus, pid_source);
2314: break;
2315:
2316: case rpl_sigterm:
2317: signal_term(s_etat_processus, pid_source);
2318: break;
2319:
2320: case rpl_sigstart:
2321: signal_start(s_etat_processus, pid_source);
2322: break;
2323:
2324: case rpl_sigcont:
2325: signal_cont(s_etat_processus, pid_source);
2326: break;
2327:
2328: case rpl_sigstop:
2329: signal_stop(s_etat_processus, pid_source);
2330: break;
2331:
2332: case rpl_sigabort:
2333: signal_abort(s_etat_processus, pid_source);
2334: break;
2335:
2336: case rpl_sigurg:
2337: signal_urg(s_etat_processus, pid_source);
2338: break;
2339:
2340: case rpl_siginject:
2341: signal_inject(s_etat_processus, pid_source);
2342: break;
2343:
2344: case rpl_sigalrm:
2345: signal_alrm(s_etat_processus, pid_source);
2346: break;
2347:
2348: case rpl_sighup:
2349: signal_hup(s_etat_processus, pid_source);
2350: break;
2351:
2352: case rpl_sigtstp:
2353: signal_tstp(s_etat_processus, pid_source);
2354: break;
2355:
2356: case rpl_sigexcept:
2357: signal_except(s_etat_processus, pid_source);
2358: break;
2359:
2360: default:
2361: if ((*s_etat_processus).langue == 'F')
2362: {
2363: printf("+++System : Spurious signal (%d) !\n", signal);
2364: }
2365: else
2366: {
2367: printf("+++System : Signal inconnu (%d) !\n", signal);
2368: }
2369:
2370: break;
2371: }
2372:
2373: return;
2374: }
2375:
2376: void
2377: scrutation_interruptions(struct_processus *s_etat_processus)
2378: {
2379: // Interruptions qui arrivent sur le processus depuis un
2380: // processus externe.
2381:
2382: // Les pointeurs de lecture pointent sur les prochains éléments
2383: // à lire. Les pointeurs d'écriture pointent sur les prochains éléments à
2384: // écrire.
2385:
2386: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
2387: if (sem_trywait(&((*s_queue_signaux).semaphore)) == 0)
2388: # else
2389: if (sem_trywait(semaphore_queue_signaux) == 0)
2390: # endif
2391: {
2392: while((*s_queue_signaux).pointeur_lecture !=
2393: (*s_queue_signaux).pointeur_ecriture)
2394: {
2395: // Il y a un signal en attente dans le segment partagé. On le
2396: // traite.
2397:
2398: envoi_interruptions(s_etat_processus,
2399: (*s_queue_signaux).queue[(*s_queue_signaux)
2400: .pointeur_lecture].signal, (*s_queue_signaux).queue
2401: [(*s_queue_signaux).pointeur_lecture].pid);
2402: (*s_queue_signaux).pointeur_lecture =
2403: ((*s_queue_signaux).pointeur_lecture + 1)
2404: % LONGUEUR_QUEUE_SIGNAUX;
2405:
2406: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
2407: sem_wait(&((*s_queue_signaux).signalisation));
2408: # else
2409: sem_wait(semaphore_signalisation);
2410: # endif
2411: }
2412:
2413: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
2414: sem_post(&((*s_queue_signaux).semaphore));
2415: # else
2416: sem_post(semaphore_queue_signaux);
2417: # endif
2418: }
2419:
2420: // Interruptions qui arrivent depuis le groupe courant de threads.
2421:
2422: if (pthread_mutex_trylock(&mutex_interruptions) == 0)
2423: {
2424: while((*s_etat_processus).pointeur_signal_lecture !=
2425: (*s_etat_processus).pointeur_signal_ecriture)
2426: {
2427: // Il y a un signal dans la queue du thread courant. On le traite.
2428:
2429: envoi_interruptions(s_etat_processus,
2430: (*s_etat_processus).signaux_en_queue
2431: [(*s_etat_processus).pointeur_signal_lecture],
2432: getpid());
2433: (*s_etat_processus).pointeur_signal_lecture =
2434: ((*s_etat_processus).pointeur_signal_lecture + 1)
2435: % LONGUEUR_QUEUE_SIGNAUX;
2436:
2437: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
2438: sem_wait(&((*s_queue_signaux).signalisation));
2439: # else
2440: sem_wait(semaphore_signalisation);
2441: # endif
2442: }
2443:
2444: pthread_mutex_unlock(&mutex_interruptions);
2445: }
2446:
2447: return;
2448: }
2449:
2450: /*
2451: ================================================================================
2452: Fonction renvoyant le nom du segment de mémoire partagée en fonction
2453: du pid du processus.
2454: ================================================================================
2455: Entrée : Chemin absolue servant de racine, pid du processus
2456: --------------------------------------------------------------------------------
2457: Sortie : NULL ou nom du segment
2458: --------------------------------------------------------------------------------
2459: Effet de bord : Néant
2460: ================================================================================
2461: */
2462:
2463: static unsigned char *
2464: nom_segment(unsigned char *chemin, pid_t pid)
2465: {
2466: unsigned char *fichier;
2467:
2468: # ifdef IPCS_SYSV // !POSIX
2469: # ifndef OS2 // !OS2
2470:
2471: if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) *
2472: sizeof(unsigned char))) == NULL)
2473: {
2474: return(NULL);
2475: }
2476:
2477: sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);
2478: # else // OS2
2479: if ((fichier = malloc((10 + 256 + 1) * sizeof(unsigned char)))
2480: == NULL)
2481: {
2482: return(NULL);
2483: }
2484:
2485: sprintf(fichier, "\\SHAREMEM\\RPL-SIGQUEUES-%d", (int) pid);
2486: # endif // OS2
2487: # else // POSIX
2488:
2489: if ((fichier = malloc((1 + 256 + 1) *
2490: sizeof(unsigned char))) == NULL)
2491: {
2492: return(NULL);
2493: }
2494:
2495: sprintf(fichier, "/RPL-SIGQUEUES-%d", (int) pid);
2496: # endif
2497:
2498: return(fichier);
2499: }
2500:
2501:
2502: /*
2503: ================================================================================
2504: Fonctions d'envoi d'un signal à un thread ou à un processus.
2505: ================================================================================
2506: Entrée : processus et signal
2507: --------------------------------------------------------------------------------
2508: Sortie : erreur
2509: --------------------------------------------------------------------------------
2510: Effet de bord : Néant
2511: ================================================================================
2512: */
2513:
2514: int
2515: envoi_signal_processus(pid_t pid, enum signaux_rpl signal)
2516: {
2517: # ifndef OS2
2518: int segment;
2519: # endif
2520:
2521: # ifndef IPCS_SYSV
2522: # ifdef SEMAPHORES_NOMMES
2523: sem_t *semaphore;
2524: sem_t *signalisation;
2525: # endif
2526: # else
2527: # ifndef OS2
2528: int desc;
2529: key_t clef;
2530: # endif
2531: # endif
2532:
2533: struct_queue_signaux *queue;
2534:
2535: unsigned char *nom;
2536:
2537: // Il s'agit d'ouvrir le segment de mémoire partagée, de le projeter en
2538: // mémoire puis d'y inscrire le signal à traiter.
2539:
2540: if (pid == getpid())
2541: {
2542: // Le signal est envoyé au même processus.
2543:
2544: if (s_queue_signaux == NULL)
2545: {
2546: return(1);
2547: }
2548:
2549: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
2550: while(sem_wait(&((*s_queue_signaux).semaphore)) != 0)
2551: # else
2552: while(sem_wait(semaphore_queue_signaux) != 0)
2553: # endif
2554: {
2555: if (errno != EINTR)
2556: {
2557: return(1);
2558: }
2559: }
2560:
2561: (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture]
2562: .pid = pid;
2563: (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture]
2564: .signal = signal;
2565:
2566: (*s_queue_signaux).pointeur_ecriture =
2567: ((*s_queue_signaux).pointeur_ecriture + 1)
2568: % LONGUEUR_QUEUE_SIGNAUX;
2569:
2570: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
2571: if (sem_post(&((*s_queue_signaux).semaphore)) != 0)
2572: # else
2573: if (sem_post(semaphore_queue_signaux) != 0)
2574: # endif
2575: {
2576: return(1);
2577: }
2578:
2579: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
2580: if (sem_post(&((*s_queue_signaux).signalisation)) != 0)
2581: # else
2582: if (sem_post(semaphore_signalisation) != 0)
2583: # endif
2584: {
2585: return(1);
2586: }
2587: }
2588: else
2589: {
2590: // Le signal est envoyé depuis un processus distinct.
2591:
2592: # ifdef IPCS_SYSV
2593: if ((nom = nom_segment(racine_segment, pid)) == NULL)
2594: {
2595: return(1);
2596: }
2597:
2598: # ifndef OS2 // SysV
2599: if ((desc = open(nom, O_RDWR)) == -1)
2600: {
2601: free(nom);
2602: return(1);
2603: }
2604:
2605: close(desc);
2606:
2607: if ((clef = ftok(nom, 1)) == -1)
2608: {
2609: free(nom);
2610: return(1);
2611: }
2612:
2613: free(nom);
2614:
2615: if ((segment = shmget(clef, sizeof(struct_queue_signaux), 0))
2616: == -1)
2617: {
2618: return(1);
2619: }
2620:
2621: queue = shmat(segment, NULL, 0);
2622: # else // OS/2
2623: if (DosGetNamedSharedMem((PVOID) &queue, nom,
2624: PAG_WRITE | PAG_READ) != 0)
2625: {
2626: free(nom);
2627: return(1);
2628: }
2629:
2630: free(nom);
2631: # endif
2632: # else // POSIX
2633: if ((nom = nom_segment(racine_segment, pid)) == NULL)
2634: {
2635: return(1);
2636: }
2637:
2638: if ((segment = shm_open(nom, O_RDWR, 0)) == -1)
2639: {
2640: free(nom);
2641: return(1);
2642: }
2643:
2644: free(nom);
2645:
2646: if ((queue = mmap(NULL, sizeof(struct_queue_signaux),
2647: PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0)) ==
2648: MAP_FAILED)
2649: {
2650: close(segment);
2651: return(1);
2652: }
2653: # endif
2654:
2655: // À ce moment, le segment de mémoire partagée est projeté
2656: // dans l'espace du processus.
2657:
2658: # ifndef IPCS_SYSV // POSIX
2659: # ifndef SEMAPHORES_NOMMES
2660: while(sem_wait(&((*queue).semaphore)) != 0)
2661: {
2662: if (errno != EINTR)
2663: {
2664: return(1);
2665: }
2666: }
2667: # else
2668: if ((semaphore = sem_open2(pid, SEM_QUEUE)) == SEM_FAILED)
2669: {
2670: return(1);
2671: }
2672:
2673: if ((signalisation = sem_open2(pid, SEM_SIGNALISATION))
2674: == SEM_FAILED)
2675: {
2676: return(1);
2677: }
2678:
2679: while(sem_wait(semaphore) != 0)
2680: {
2681: if (errno != EINTR)
2682: {
2683: sem_close(semaphore);
2684: sem_close(signalisation);
2685: return(1);
2686: }
2687: }
2688: # endif
2689: # else // IPCS_SYSV
2690: while(sem_wait(&((*queue).semaphore)) != 0)
2691: {
2692: if (errno != EINTR)
2693: {
2694: return(1);
2695: }
2696: }
2697: # endif
2698:
2699: (*queue).queue[(*queue).pointeur_ecriture].pid = getpid();
2700: (*queue).queue[(*queue).pointeur_ecriture].signal = signal;
2701:
2702: (*queue).pointeur_ecriture = ((*queue).pointeur_ecriture + 1)
2703: % LONGUEUR_QUEUE_SIGNAUX;
2704:
2705: # ifndef IPCS_SYSV // POSIX
2706: # ifndef SEMAPHORES_NOMMES
2707: if (sem_post(&((*queue).semaphore)) != 0)
2708: {
2709: return(1);
2710: }
2711:
2712: if (sem_post(&((*queue).signalisation)) != 0)
2713: {
2714: return(1);
2715: }
2716: # else
2717: if (sem_post(semaphore) != 0)
2718: {
2719: sem_close(semaphore);
2720: sem_close(signalisation);
2721: return(1);
2722: }
2723:
2724: if (sem_close(semaphore) != 0)
2725: {
2726: return(1);
2727: }
2728:
2729: if (sem_post(signalisation) != 0)
2730: {
2731: sem_close(signalisation);
2732: return(1);
2733: }
2734:
2735: if (sem_close(signalisation) != 0)
2736: {
2737: return(1);
2738: }
2739:
2740: # endif
2741:
2742: if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
2743: {
2744: close(segment);
2745: return(1);
2746: }
2747: # else // IPCS_SYSV
2748: if (sem_post(&((*queue).semaphore)) != 0)
2749: {
2750: return(1);
2751: }
2752:
2753: if (sem_post(&((*queue).signalisation)) != 0)
2754: {
2755: return(1);
2756: }
2757:
2758: # ifndef OS2 // SysV
2759: if (shmdt(queue) != 0)
2760: {
2761: return(1);
2762: }
2763: # else // OS/2
2764: // Pendant de DosGetNamedSHaredMem()
2765: # endif
2766: # endif
2767: }
2768:
2769: return(0);
2770: }
2771:
2772: int
2773: envoi_signal_thread(pthread_t tid, enum signaux_rpl signal)
2774: {
2775: // Un signal est envoyé d'un thread à un autre thread du même processus.
2776:
2777: volatile struct_liste_chainee_volatile *l_element_courant;
2778:
2779: struct_processus *s_etat_processus;
2780:
2781: if (pthread_mutex_lock(&mutex_liste_threads) != 0)
2782: {
2783: return(1);
2784: }
2785:
2786: l_element_courant = liste_threads;
2787:
2788: while(l_element_courant != NULL)
2789: {
2790: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
2791: == getpid()) && (pthread_equal((*((struct_thread *)
2792: (*l_element_courant).donnee)).tid, tid) != 0))
2793: {
2794: break;
2795: }
2796:
2797: l_element_courant = (*l_element_courant).suivant;
2798: }
2799:
2800: if (l_element_courant == NULL)
2801: {
2802: pthread_mutex_unlock(&mutex_liste_threads);
2803: return(1);
2804: }
2805:
2806: if (pthread_mutex_lock(&mutex_interruptions) != 0)
2807: {
2808: pthread_mutex_unlock(&mutex_liste_threads);
2809: return(1);
2810: }
2811:
2812: s_etat_processus = (*((struct_thread *) (*l_element_courant).donnee))
2813: .s_etat_processus;
2814:
2815: (*s_etat_processus).signaux_en_queue
2816: [(*s_etat_processus).pointeur_signal_ecriture] = signal;
2817: (*s_etat_processus).pointeur_signal_ecriture =
2818: ((*s_etat_processus).pointeur_signal_ecriture + 1)
2819: % LONGUEUR_QUEUE_SIGNAUX;
2820:
2821: if (pthread_mutex_unlock(&mutex_interruptions) != 0)
2822: {
2823: pthread_mutex_unlock(&mutex_liste_threads);
2824: return(1);
2825: }
2826:
2827: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
2828: {
2829: return(1);
2830: }
2831:
2832: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
2833: if (sem_post(&((*s_queue_signaux).signalisation)) != 0)
2834: {
2835: return(1);
2836: }
2837: # else
2838: if (sem_post(semaphore_signalisation) != 0)
2839: {
2840: return(1);
2841: }
2842: # endif
2843:
2844: return(0);
2845: }
2846:
2847: int
2848: envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,
2849: enum signaux_rpl signal)
2850: {
2851: pthread_mutex_lock(&mutex_interruptions);
2852: (*s_etat_processus_a_signaler).signaux_en_queue
2853: [(*s_etat_processus_a_signaler).pointeur_signal_ecriture] =
2854: signal;
2855: (*s_etat_processus_a_signaler).pointeur_signal_ecriture =
2856: ((*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1)
2857: % LONGUEUR_QUEUE_SIGNAUX;
2858: pthread_mutex_unlock(&mutex_interruptions);
2859:
2860: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
2861: if (sem_post(&((*s_queue_signaux).signalisation)) != 0)
2862: {
2863: return(1);
2864: }
2865: # else
2866: if (sem_post(semaphore_signalisation) != 0)
2867: {
2868: return(1);
2869: }
2870: # endif
2871:
2872: return(0);
2873: }
2874:
2875:
2876: /*
2877: ================================================================================
2878: Fonction créant un segment de mémoire partagée destiné à contenir
2879: la queue des signaux.
2880: ================================================================================
2881: Entrée : structure de description du processus
2882: --------------------------------------------------------------------------------
2883: Sortie : Néant
2884: --------------------------------------------------------------------------------
2885: Effet de bord : Néant
2886: ================================================================================
2887: */
2888:
2889: void
2890: creation_queue_signaux(struct_processus *s_etat_processus)
2891: {
2892: pthread_attr_t attributs;
2893:
2894: unsigned char *nom;
2895:
2896: racine_segment = (*s_etat_processus).chemin_fichiers_temporaires;
2897:
2898: # ifndef IPCS_SYSV // POSIX
2899: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
2900: getpid())) == NULL)
2901: {
2902: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2903: return;
2904: }
2905:
2906: if ((f_queue_signaux = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,
2907: S_IRUSR | S_IWUSR)) == -1)
2908: {
2909: free(nom);
2910: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2911: return;
2912: }
2913:
2914: if (ftruncate(f_queue_signaux, sizeof(struct_queue_signaux)) == -1)
2915: {
2916: free(nom);
2917: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2918: return;
2919: }
2920:
2921: s_queue_signaux = mmap(NULL, sizeof(struct_queue_signaux),
2922: PROT_READ | PROT_WRITE, MAP_SHARED, f_queue_signaux, 0);
2923:
2924: if (((void *) s_queue_signaux) == ((void *) -1))
2925: {
2926: if (shm_unlink(nom) == -1)
2927: {
2928: free(nom);
2929: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2930: return;
2931: }
2932:
2933: free(nom);
2934: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2935: return;
2936: }
2937:
2938: free(nom);
2939:
2940: # ifndef SEMAPHORES_NOMMES
2941: sem_init(&((*s_queue_signaux).semaphore), 1, 1);
2942: sem_init(&((*s_queue_signaux).signalisation), 1, 0);
2943: # else
2944: if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE))
2945: == SEM_FAILED)
2946: {
2947: (*s_etat_processus).erreur_systeme = d_es_processus;
2948: return;
2949: }
2950:
2951: if ((semaphore_signalisation = sem_init2(1, getpid(),
2952: SEM_SIGNALISATION)) == SEM_FAILED)
2953: {
2954: (*s_etat_processus).erreur_systeme = d_es_processus;
2955: return;
2956: }
2957: # endif
2958:
2959: (*s_queue_signaux).pointeur_lecture = 0;
2960: (*s_queue_signaux).pointeur_ecriture = 0;
2961: (*s_queue_signaux).requete_arret = d_faux;
2962:
2963: if (msync(s_queue_signaux, sizeof(struct_queue_signaux), 0))
2964: {
2965: (*s_etat_processus).erreur_systeme = d_es_processus;
2966: return;
2967: }
2968: # else // IPCS_SYSV
2969: # ifndef OS2
2970: int segment;
2971: int support;
2972:
2973: key_t clef;
2974:
2975: // Création d'un segment de données associé au PID du processus
2976: // courant
2977:
2978: if ((nom = nom_segment((*s_etat_processus)
2979: .chemin_fichiers_temporaires, getpid())) == NULL)
2980: {
2981: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2982: return;
2983: }
2984:
2985: if ((support = open(nom, O_RDWR | O_CREAT | O_EXCL,
2986: S_IRUSR | S_IWUSR)) == -1)
2987: {
2988: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
2989: return;
2990: }
2991:
2992: if ((clef = ftok(nom, 1)) == -1)
2993: {
2994: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2995: return;
2996: }
2997:
2998: close(support);
2999: free(nom);
3000:
3001: if ((segment = shmget(clef, sizeof(struct_queue_signaux),
3002: IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)
3003: {
3004: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3005: return;
3006: }
3007:
3008: s_queue_signaux = shmat(segment, NULL, 0);
3009: f_queue_signaux = segment;
3010:
3011: if (((void *) s_queue_signaux) == ((void *) -1))
3012: {
3013: if (shmctl(f_queue_signaux, IPC_RMID, 0) == -1)
3014: {
3015: (*s_etat_processus).erreur_systeme =
3016: d_es_allocation_memoire;
3017: return;
3018: }
3019:
3020: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3021: return;
3022: }
3023:
3024: sem_init(&((*s_queue_signaux).semaphore), 1, 1);
3025: sem_init(&((*s_queue_signaux).signalisation), 1, 0);
3026: (*s_queue_signaux).pointeur_lecture = 0;
3027: (*s_queue_signaux).pointeur_ecriture = 0;
3028: (*s_queue_signaux).requete_arret = d_faux;
3029: # else // OS/2
3030: if ((nom = nom_segment(NULL, getpid())) == NULL)
3031: {
3032: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3033: return;
3034: }
3035:
3036: if (DosAllocSharedMem((PVOID) &s_queue_signaux, nom,
3037: sizeof(struct_queue_signaux),
3038: PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
3039: {
3040: free(nom);
3041: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3042: return;
3043: }
3044:
3045: free(nom);
3046:
3047: sem_init(&((*s_queue_signaux).semaphore), 1, 1);
3048: sem_init(&((*s_queue_signaux).signalisation), 1, 0);
3049: (*s_queue_signaux).pointeur_lecture = 0;
3050: (*s_queue_signaux).pointeur_ecriture = 0;
3051: (*s_queue_signaux).requete_arret = d_faux;
3052: # endif
3053: # endif
3054:
3055: // Lancement du thread de récupération des signaux.
3056:
3057: if (pthread_attr_init(&attributs) != 0)
3058: {
3059: (*s_etat_processus).erreur_systeme = d_es_processus;
3060: return;
3061: }
3062:
3063: if (pthread_attr_setdetachstate(&attributs,
3064: PTHREAD_CREATE_JOINABLE) != 0)
3065: {
3066: (*s_etat_processus).erreur_systeme = d_es_processus;
3067: return;
3068: }
3069:
3070: # ifdef SCHED_OTHER
3071: if (pthread_attr_setschedpolicy(&attributs, SCHED_OTHER) != 0)
3072: {
3073: (*s_etat_processus).erreur_systeme = d_es_processus;
3074: return;
3075: }
3076: # endif
3077:
3078: # ifdef PTHREAD_EXPLICIT_SCHED
3079: if (pthread_attr_setinheritsched(&attributs, PTHREAD_EXPLICIT_SCHED) != 0)
3080: {
3081: (*s_etat_processus).erreur_systeme = d_es_processus;
3082: return;
3083: }
3084: # endif
3085:
3086: # ifdef PTHREAD_SCOPE_SYSTEM
3087: if (pthread_attr_setscope(&attributs, PTHREAD_SCOPE_SYSTEM) != 0)
3088: {
3089: (*s_etat_processus).erreur_systeme = d_es_processus;
3090: return;
3091: }
3092: # endif
3093:
3094: if (pthread_attr_destroy(&attributs) != 0)
3095: {
3096: (*s_etat_processus).erreur_systeme = d_es_processus;
3097: return;
3098: }
3099:
3100: if (pthread_create(&((*s_queue_signaux).thread_signaux), &attributs,
3101: thread_surveillance_signaux, s_etat_processus) != 0)
3102: {
3103: (*s_etat_processus).erreur_systeme = d_es_processus;
3104: return;
3105: }
3106:
3107: return;
3108: }
3109:
3110:
3111: /*
3112: ================================================================================
3113: Fonction libérant le segment de mémoire partagée destiné à contenir
3114: la queue des signaux.
3115: ================================================================================
3116: Entrée : structure de description du processus
3117: --------------------------------------------------------------------------------
3118: Sortie : Néant
3119: --------------------------------------------------------------------------------
3120: Effet de bord : Néant
3121: ================================================================================
3122: */
3123:
3124: void
3125: liberation_queue_signaux(struct_processus *s_etat_processus)
3126: {
3127: // Incrémenter le sémaphore pour être sûr de le débloquer.
3128:
3129: (*s_queue_signaux).requete_arret = d_vrai;
3130:
3131: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
3132: sem_post(&((*s_queue_signaux).signalisation));
3133: # else
3134: sem_post(semaphore_signalisation);
3135: # endif
3136:
3137: pthread_join((*s_queue_signaux).thread_signaux, NULL);
3138:
3139: # ifdef IPCS_SYSV // SystemV
3140: # ifndef OS2
3141: if (shmdt(s_queue_signaux) == -1)
3142: {
3143: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3144: return;
3145: }
3146: # else // OS/2
3147: # endif
3148: # else // POSIX
3149: # ifndef SEMAPHORES_NOMMES
3150: sem_close(&((*s_queue_signaux).semaphore));
3151: sem_close(&((*s_queue_signaux).signalisation));
3152: # else
3153: sem_close(semaphore_queue_signaux);
3154: sem_close(semaphore_signalisation);
3155: # endif
3156:
3157: if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
3158: {
3159: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3160: return;
3161: }
3162:
3163: close(f_queue_signaux);
3164: # endif
3165:
3166: return;
3167: }
3168:
3169:
3170: /*
3171: ================================================================================
3172: Fonction détruisant le segment de mémoire partagée destiné à contenir
3173: la queue des signaux.
3174: ================================================================================
3175: Entrée : structure de description du processus
3176: --------------------------------------------------------------------------------
3177: Sortie : Néant
3178: --------------------------------------------------------------------------------
3179: Effet de bord : Néant
3180: ================================================================================
3181: */
3182:
3183: void
3184: destruction_queue_signaux(struct_processus *s_etat_processus)
3185: {
3186: # ifndef OS2
3187: unsigned char *nom;
3188: # endif
3189:
3190: // Incrémenter le sémaphore pour être sûr de le débloquer.
3191:
3192: (*s_queue_signaux).requete_arret = d_vrai;
3193:
3194: # if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
3195: sem_post(&((*s_queue_signaux).signalisation));
3196: # else
3197: sem_post(semaphore_signalisation);
3198: # endif
3199:
3200: pthread_join((*s_queue_signaux).thread_signaux, NULL);
3201:
3202: # ifdef IPCS_SYSV // SystemV
3203: # ifndef OS2
3204: // Il faut commencer par éliminer le sémaphore.
3205:
3206: if (semctl((*s_queue_signaux).semaphore.sem, 0, IPC_RMID) == -1)
3207: {
3208: (*s_etat_processus).erreur_systeme = d_es_processus;
3209: return;
3210: }
3211:
3212: unlink((*s_queue_signaux).semaphore.path);
3213: free((*s_queue_signaux).semaphore.path);
3214:
3215: if (semctl((*s_queue_signaux).signalisation.sem, 0, IPC_RMID) == -1)
3216: {
3217: (*s_etat_processus).erreur_systeme = d_es_processus;
3218: return;
3219: }
3220:
3221: unlink((*s_queue_signaux).signalisation.path);
3222: free((*s_queue_signaux).signalisation.path);
3223:
3224: if (shmdt(s_queue_signaux) == -1)
3225: {
3226: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3227: return;
3228: }
3229:
3230: if (shmctl(f_queue_signaux, IPC_RMID, 0) == -1)
3231: {
3232: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3233: return;
3234: }
3235:
3236: if ((nom = nom_segment((*s_etat_processus)
3237: .chemin_fichiers_temporaires, getpid())) == NULL)
3238: {
3239: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3240: return;
3241: }
3242:
3243: unlink(nom);
3244: free(nom);
3245: # else
3246: sem_close(&((*s_queue_signaux).semaphore));
3247: sem_destroy(&((*s_queue_signaux).semaphore));
3248:
3249: sem_close(&((*s_queue_signaux).signalisation));
3250: sem_destroy(&((*s_queue_signaux).signalisation));
3251:
3252: if (DosFreeMem(s_queue_signaux) != 0)
3253: {
3254: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3255: return;
3256: }
3257: # endif
3258: # else // POSIX
3259: # ifndef SEMAPHORES_NOMMES
3260: sem_close(&((*s_queue_signaux).semaphore));
3261: sem_destroy(&((*s_queue_signaux).semaphore));
3262:
3263: sem_close(&((*s_queue_signaux).signalisation));
3264: sem_destroy(&((*s_queue_signaux).signalisation));
3265: # else
3266: sem_close(semaphore_queue_signaux);
3267: sem_destroy2(semaphore_queue_signaux, getpid(), SEM_QUEUE);
3268:
3269: sem_close(semaphore_signalisation);
3270: sem_destroy2(semaphore_signalisation, getpid(), SEM_SIGNALISATION);
3271: # endif
3272:
3273: if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
3274: {
3275: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3276: return;
3277: }
3278:
3279: if ((nom = nom_segment(NULL, getpid())) == NULL)
3280: {
3281: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3282: return;
3283: }
3284:
3285: close(f_queue_signaux);
3286:
3287: if (shm_unlink(nom) != 0)
3288: {
3289: free(nom);
3290: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3291: return;
3292: }
3293:
3294: free(nom);
3295: # endif
3296:
3297: return;
3298: }
3299:
3300: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>