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