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