1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.31
4: Copyright (C) 1989-2019 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) != 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) != 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) != 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);
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);
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);
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);
508: (*s_etat_processus).erreur_systeme = d_es_processus;
509: return;
510: }
511: }
512:
513: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
514: {
515: (*s_etat_processus).erreur_systeme = d_es_processus;
516: return;
517: }
518:
519: 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: l_element_courant = liste_threads_surveillance;
1384:
1385: while(l_element_courant != NULL)
1386: {
1387: s_argument_thread = (struct_descripteur_thread *)
1388: (*l_element_courant).donnee;
1389:
1390: if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
1391: != 0)
1392: {
1393: (*s_etat_processus).erreur_systeme = d_es_processus;
1394: pthread_mutex_unlock(&mutex_liste_threads);
1395: return;
1396: }
1397:
1398: (*s_argument_thread).nombre_references--;
1399:
1400: BUG((*s_argument_thread).nombre_references < 0,
1401: printf("(*s_argument_thread).nombre_references = %d\n",
1402: (int) (*s_argument_thread).nombre_references));
1403:
1404: if ((*s_argument_thread).nombre_references == 0)
1405: {
1406: close((*s_argument_thread).pipe_objets[0]);
1407: close((*s_argument_thread).pipe_acquittement[1]);
1408: close((*s_argument_thread).pipe_injections[1]);
1409: close((*s_argument_thread).pipe_nombre_injections[1]);
1410: close((*s_argument_thread).pipe_nombre_elements_attente[0]);
1411: close((*s_argument_thread).pipe_interruptions[0]);
1412:
1413: if (pthread_mutex_unlock(&((*s_argument_thread)
1414: .mutex_nombre_references)) != 0)
1415: {
1416: (*s_etat_processus).erreur_systeme = d_es_processus;
1417: pthread_mutex_unlock(&mutex_liste_threads);
1418: return;
1419: }
1420:
1421: pthread_mutex_destroy(&((*s_argument_thread).mutex));
1422: pthread_mutex_destroy(&((*s_argument_thread)
1423: .mutex_nombre_references));
1424:
1425: if ((*s_argument_thread).processus_detache == d_faux)
1426: {
1427: if ((*s_argument_thread).destruction_objet == d_vrai)
1428: {
1429: liberation(s_etat_processus, (*s_argument_thread).argument);
1430: }
1431: }
1432:
1433: free(s_argument_thread);
1434: }
1435: else
1436: {
1437: if (pthread_mutex_unlock(&((*s_argument_thread)
1438: .mutex_nombre_references)) != 0)
1439: {
1440: (*s_etat_processus).erreur_systeme = d_es_processus;
1441: pthread_mutex_unlock(&mutex_liste_threads);
1442: return;
1443: }
1444: }
1445:
1446: l_element_suivant = (*l_element_courant).suivant;
1447: free((struct_liste_chainee *) l_element_courant);
1448: l_element_courant = l_element_suivant;
1449: }
1450:
1451: liste_threads_surveillance = NULL;
1452:
1453: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1454: {
1455: (*s_etat_processus).erreur_systeme = d_es_processus;
1456: return;
1457: }
1458:
1459: return;
1460: }
1461:
1462: static struct_processus *
1463: recherche_thread(pid_t pid, pthread_t tid)
1464: {
1465: volatile struct_liste_chainee_volatile *l_element_courant;
1466:
1467: struct_processus *s_etat_processus;
1468:
1469: if (pthread_mutex_lock(&mutex_liste_threads) != 0)
1470: {
1471: return(NULL);
1472: }
1473:
1474: l_element_courant = liste_threads;
1475:
1476: while(l_element_courant != NULL)
1477: {
1478: if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee))
1479: .tid, tid) != 0) && ((*((struct_thread *)
1480: (*l_element_courant).donnee)).pid == pid))
1481: {
1482: break;
1483: }
1484:
1485: l_element_courant = (*l_element_courant).suivant;
1486: }
1487:
1488: if (l_element_courant == NULL)
1489: {
1490: /*
1491: * Le processus n'existe plus. On ne distribue aucun signal.
1492: */
1493:
1494: pthread_mutex_unlock(&mutex_liste_threads);
1495: return(NULL);
1496: }
1497:
1498: s_etat_processus = (*((struct_thread *)
1499: (*l_element_courant).donnee)).s_etat_processus;
1500:
1501: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1502: {
1503: return(NULL);
1504: }
1505:
1506: return(s_etat_processus);
1507: }
1508:
1509: static struct_processus *
1510: recherche_thread_principal(pid_t pid)
1511: {
1512: volatile struct_liste_chainee_volatile *l_element_courant;
1513:
1514: l_element_courant = liste_threads;
1515:
1516: while(l_element_courant != NULL)
1517: {
1518: if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal
1519: == d_vrai) && ((*((struct_thread *)
1520: (*l_element_courant).donnee)).pid == pid))
1521: {
1522: break;
1523: }
1524:
1525: l_element_courant = (*l_element_courant).suivant;
1526: }
1527:
1528: if (l_element_courant == NULL)
1529: {
1530: /*
1531: * Le processus n'existe plus. On ne distribue aucun signal.
1532: */
1533:
1534: return(NULL);
1535: }
1536:
1537: return((*((struct_thread *) (*l_element_courant).donnee))
1538: .s_etat_processus);
1539: }
1540:
1541:
1542: /*
1543: ================================================================================
1544: Procédures de gestion des signaux d'interruption
1545: ================================================================================
1546: Entrée : variable globale
1547: --------------------------------------------------------------------------------
1548: Sortie : variable globale modifiée
1549: --------------------------------------------------------------------------------
1550: Effets de bord : néant
1551: ================================================================================
1552: */
1553:
1554: // Les routines suivantes sont uniquement appelées depuis les gestionnaires
1555: // des signaux asynchrones. Elles ne doivent pas bloquer dans le cas où
1556: // les sémaphores sont déjà bloqués par un gestionnaire de signal.
1557:
1558: static inline void
1559: verrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
1560: {
1561: # ifndef SEMAPHORES_NOMMES
1562: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
1563: # else
1564: if (sem_post((*s_etat_processus).semaphore_fork) != 0)
1565: # endif
1566: {
1567: BUG(1, uprintf("Lock error !\n"));
1568: return;
1569: }
1570:
1571: return;
1572: }
1573:
1574: static inline void
1575: deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
1576: {
1577: # ifndef SEMAPHORES_NOMMES
1578: while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
1579: # else
1580: while(sem_wait((*s_etat_processus).semaphore_fork) != 0)
1581: # endif
1582: {
1583: if (errno != EINTR)
1584: {
1585: BUG(1, uprintf("Unlock error !\n"));
1586: return;
1587: }
1588: }
1589:
1590: return;
1591: }
1592:
1593: /*
1594: ================================================================================
1595: Fonctions de gestion des signaux dans les threads.
1596:
1597: Lorsqu'un processus reçoit un signal, il appelle le gestionnaire de signal
1598: associé qui ne fait qu'envoyer au travers de write() le signal
1599: reçus dans un pipe. Un second thread est bloqué sur ce pipe et
1600: effectue le traitement adéquat pour le signal donné.
1601: ================================================================================
1602: */
1603:
1604: #define test_signal(signal) \
1605: if (signal_test == SIGTEST) { signal_test = signal; return; }
1606:
1607: static int pipe_signaux;
1608:
1609: logical1
1610: lancement_thread_signaux(struct_processus *s_etat_processus)
1611: {
1612: pthread_attr_t attributs;
1613:
1614: if (pipe((*s_etat_processus).pipe_signaux) != 0)
1615: {
1616: (*s_etat_processus).erreur_systeme = d_es_processus;
1617: return(d_erreur);
1618: }
1619:
1620: pipe_signaux = (*s_etat_processus).pipe_signaux[1];
1621:
1622: if (pthread_attr_init(&attributs) != 0)
1623: {
1624: (*s_etat_processus).erreur_systeme = d_es_processus;
1625: return(d_erreur);
1626: }
1627:
1628: if (pthread_attr_setdetachstate(&attributs, PTHREAD_CREATE_JOINABLE) != 0)
1629: {
1630: (*s_etat_processus).erreur_systeme = d_es_processus;
1631: return(d_erreur);
1632: }
1633:
1634: if (pthread_create(&((*s_etat_processus).thread_signaux), &attributs,
1635: thread_signaux, s_etat_processus) != 0)
1636: {
1637: (*s_etat_processus).erreur_systeme = d_es_processus;
1638: return(d_erreur);
1639: }
1640:
1641: if (pthread_attr_destroy(&attributs) != 0)
1642: {
1643: (*s_etat_processus).erreur_systeme = d_es_processus;
1644: return(d_erreur);
1645: }
1646:
1647: return(d_absence_erreur);
1648: }
1649:
1650: logical1
1651: arret_thread_signaux(struct_processus *s_etat_processus)
1652: {
1653: unsigned char signal;
1654: ssize_t n;
1655:
1656: signal = (unsigned char ) (rpl_sigmax & 0xFF);
1657:
1658: do
1659: {
1660: n = write_atomic(s_etat_processus, (*s_etat_processus).pipe_signaux[1],
1661: &signal, sizeof(signal));
1662:
1663: if (n < 0)
1664: {
1665: return(d_erreur);
1666: }
1667: } while(n != 1);
1668:
1669: pthread_join((*s_etat_processus).thread_signaux, NULL);
1670:
1671: close((*s_etat_processus).pipe_signaux[1]);
1672: return(d_absence_erreur);
1673: }
1674:
1675: void *
1676: thread_signaux(void *argument)
1677: {
1678: int *pipe;
1679:
1680: sigset_t masque;
1681:
1682: struct pollfd fds;
1683:
1684: struct_processus *s_etat_processus;
1685:
1686: unsigned char signal;
1687:
1688: s_etat_processus = (struct_processus *) argument;
1689: pipe = (*s_etat_processus).pipe_signaux;
1690: fds.fd = pipe[0];
1691: fds.events = POLLIN;
1692:
1693: sigfillset(&masque);
1694: pthread_sigmask(SIG_BLOCK, &masque, NULL);
1695:
1696: do
1697: {
1698: fds.revents = 0;
1699:
1700: while(poll(&fds, 1, -1) == -1)
1701: {
1702: if (errno != EINTR)
1703: {
1704: close((*s_etat_processus).pipe_signaux[0]);
1705: pthread_exit(NULL);
1706: }
1707: }
1708:
1709: if (read_atomic(s_etat_processus, fds.fd, &signal, 1) != 1)
1710: {
1711: close((*s_etat_processus).pipe_signaux[0]);
1712: pthread_exit(NULL);
1713: }
1714:
1715: if (signal != (0xFF & rpl_sigmax))
1716: {
1717: envoi_signal_processus(getpid(), signal, d_faux);
1718: // Un signal SIGUSR2 est envoyé par le thread de surveillance
1719: // des signaux jusqu'à ce que les signaux soient tous traités.
1720: }
1721: } while(signal != (0xFF & rpl_sigmax));
1722:
1723: close((*s_etat_processus).pipe_signaux[0]);
1724: pthread_exit(NULL);
1725: }
1726:
1727:
1728: static inline void
1729: _write(int fd, const void *buf, size_t count)
1730: {
1731: ssize_t ios;
1732:
1733: while((ios = write(fd, buf, count)) == -1)
1734: {
1735: if (errno != EINTR)
1736: {
1737: break;
1738: }
1739: }
1740:
1741: return;
1742: }
1743:
1744:
1745: // Récupération des signaux
1746: // - SIGINT (arrêt au clavier)
1747: // - SIGTERM (signal d'arrêt en provenance du système)
1748:
1749: void
1750: interruption1(int signal)
1751: {
1752: unsigned char signal_tronque;
1753:
1754: test_signal(signal);
1755:
1756: switch(signal)
1757: {
1758: case SIGINT:
1759: signal_tronque = (unsigned char) (rpl_sigint & 0xFF);
1760: _write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
1761: break;
1762:
1763: case SIGTERM:
1764: signal_tronque = (unsigned char) (rpl_sigterm & 0xFF);
1765: _write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
1766: break;
1767:
1768: case SIGUSR1:
1769: signal_tronque = (unsigned char) (rpl_sigalrm & 0xFF);
1770: _write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
1771: break;
1772:
1773: default:
1774: // SIGUSR2
1775: break;
1776: }
1777:
1778: return;
1779: }
1780:
1781: // Récupération des signaux
1782: // - SIGFSTP
1783: //
1784: // ATTENTION :
1785: // Le signal SIGFSTP provient de la mort du processus de contrôle.
1786: // Sous certains systèmes (Linux...), la mort du terminal de contrôle
1787: // se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
1788: // (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
1789: // non initialisée (pointeur NULL) issue de TERMIO.
1790:
1791: void
1792: interruption2(int signal)
1793: {
1794: unsigned char signal_tronque;
1795:
1796: test_signal(signal);
1797:
1798: signal_tronque = (unsigned char) (rpl_sigtstp & 0xFF);
1799: _write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
1800:
1801: return;
1802: }
1803:
1804: void
1805: interruption3(int signal)
1806: {
1807: // Si on passe par ici, c'est qu'il est impossible de récupérer
1808: // l'erreur d'accès à la mémoire. On sort donc du programme quitte à
1809: // ce qu'il reste des processus orphelins.
1810:
1811: unsigned char message_1[] = "+++System : Uncaught access violation\n"
1812: "+++System : Aborting !\n";
1813: unsigned char message_2[] = "+++System : Stack overflow\n"
1814: "+++System : Aborting !\n";
1815:
1816: test_signal(signal);
1817:
1818: if (pid_processus_pere == getpid())
1819: {
1820: kill(pid_processus_pere, SIGUSR1);
1821: }
1822:
1823: # pragma GCC diagnostic push
1824: # pragma GCC diagnostic ignored "-Wunused-result"
1825:
1826: if (signal != SIGUSR2)
1827: {
1828: write(STDERR_FILENO, message_1, strlen(message_1));
1829: }
1830: else
1831: {
1832: write(STDERR_FILENO, message_2, strlen(message_2));
1833: }
1834:
1835: # pragma GCC diagnostic pop
1836:
1837: _exit(EXIT_FAILURE);
1838: }
1839:
1840: // Récupération des signaux
1841: // - SIGHUP
1842:
1843: void
1844: interruption4(int signal)
1845: {
1846: unsigned char signal_tronque;
1847:
1848: test_signal(signal);
1849:
1850: signal_tronque = (unsigned char) (rpl_sighup & 0xFF);
1851: _write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
1852:
1853: return;
1854: }
1855:
1856: // Récupération des signaux
1857: // - SIGPIPE
1858:
1859: void
1860: interruption5(int signal)
1861: {
1862: unsigned char message[] = "+++System : SIGPIPE\n"
1863: "+++System : Aborting !\n";
1864: unsigned char signal_tronque;
1865:
1866: test_signal(signal);
1867:
1868: # pragma GCC diagnostic push
1869: # pragma GCC diagnostic ignored "-Wunused-result"
1870:
1871: if (pid_processus_pere == getpid())
1872: {
1873: signal_tronque = (unsigned char) (rpl_sigalrm & 0xFF);
1874: _write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
1875: }
1876:
1877: write(STDERR_FILENO, message, strlen(message));
1878:
1879: # pragma GCC diagnostic pop
1880:
1881: return;
1882: }
1883:
1884: inline static void
1885: signal_alrm(struct_processus *s_etat_processus, pid_t pid)
1886: {
1887: struct_processus *s_thread_principal;
1888:
1889: verrouillage_gestionnaire_signaux(s_etat_processus);
1890:
1891: if (pid == getpid())
1892: {
1893: // Si pid est égal à getpid(), le signal à traiter est issu
1894: // du même processus que celui qui va le traiter, mais d'un thread
1895: // différent.
1896:
1897: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1898: {
1899: printf("[%d] RPL/SIGALRM (thread %llu)\n", (int) getpid(),
1900: (unsigned long long) pthread_self());
1901: fflush(stdout);
1902: }
1903:
1904: if ((*s_etat_processus).pid_processus_pere != getpid())
1905: {
1906: // On n'est pas dans le processus père, on remonte le signal.
1907: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1908: rpl_sigalrm, d_faux);
1909: }
1910: else
1911: {
1912: // On est dans le processus père, on effectue un arrêt d'urgence.
1913: (*s_etat_processus).var_volatile_alarme = -1;
1914: (*s_etat_processus).var_volatile_requete_arret = -1;
1915: }
1916: }
1917: else
1918: {
1919: // Le signal est issu d'un processus différent. On recherche le
1920: // thread principal pour remonter le signal.
1921:
1922: if ((s_thread_principal = recherche_thread_principal(getpid()))
1923: != NULL)
1924: {
1925: envoi_signal_contexte(s_thread_principal, rpl_sigalrm);
1926: }
1927: }
1928:
1929: deverrouillage_gestionnaire_signaux(s_etat_processus);
1930: return;
1931: }
1932:
1933: inline static void
1934: signal_term(struct_processus *s_etat_processus, pid_t pid)
1935: {
1936: struct_processus *s_thread_principal;
1937: pthread_mutex_t exclusion = PTHREAD_MUTEX_INITIALIZER;
1938:
1939: verrouillage_gestionnaire_signaux(s_etat_processus);
1940:
1941: if (pid == getpid())
1942: {
1943: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1944: {
1945: printf("[%d] RPL/SIGTERM (thread %llu)\n", (int) getpid(),
1946: (unsigned long long) pthread_self());
1947: fflush(stdout);
1948: }
1949:
1950: if ((*s_etat_processus).pid_processus_pere != getpid())
1951: {
1952: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1953: rpl_sigterm, d_faux);
1954: }
1955: else
1956: {
1957: (*s_etat_processus).var_volatile_traitement_sigint = -1;
1958:
1959: pthread_mutex_lock(&exclusion);
1960:
1961: if ((*s_etat_processus).var_volatile_requete_arret == -1)
1962: {
1963: deverrouillage_gestionnaire_signaux(s_etat_processus);
1964: pthread_mutex_unlock(&exclusion);
1965: return;
1966: }
1967:
1968: (*s_etat_processus).var_volatile_requete_arret = -1;
1969: (*s_etat_processus).var_volatile_alarme = -1;
1970:
1971: pthread_mutex_unlock(&exclusion);
1972: }
1973: }
1974: else
1975: {
1976: if ((s_thread_principal = recherche_thread_principal(getpid()))
1977: != NULL)
1978: {
1979: envoi_signal_contexte(s_thread_principal, rpl_sigterm);
1980: }
1981: }
1982:
1983: deverrouillage_gestionnaire_signaux(s_etat_processus);
1984: return;
1985: }
1986:
1987: inline static void
1988: signal_int(struct_processus *s_etat_processus, pid_t pid)
1989: {
1990: struct_processus *s_thread_principal;
1991: pthread_mutex_t exclusion = PTHREAD_MUTEX_INITIALIZER;
1992:
1993: verrouillage_gestionnaire_signaux(s_etat_processus);
1994:
1995: if (pid == getpid())
1996: {
1997: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1998: {
1999: printf("[%d] RPL/SIGINT (thread %llu)\n", (int) getpid(),
2000: (unsigned long long) pthread_self());
2001: fflush(stdout);
2002: }
2003:
2004: if ((*s_etat_processus).pid_processus_pere != getpid())
2005: {
2006: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
2007: rpl_sigint, d_faux);
2008: }
2009: else
2010: {
2011: (*s_etat_processus).var_volatile_traitement_sigint = -1;
2012:
2013: pthread_mutex_lock(&exclusion);
2014:
2015: if ((*s_etat_processus).var_volatile_requete_arret == -1)
2016: {
2017: deverrouillage_gestionnaire_signaux(s_etat_processus);
2018: pthread_mutex_unlock(&exclusion);
2019: return;
2020: }
2021:
2022: if ((*s_etat_processus).langue == 'F')
2023: {
2024: printf("+++Interruption\n");
2025: }
2026: else
2027: {
2028: printf("+++Interrupt\n");
2029: }
2030:
2031: fflush(stdout);
2032:
2033: (*s_etat_processus).var_volatile_requete_arret = -1;
2034: (*s_etat_processus).var_volatile_alarme = -1;
2035:
2036: pthread_mutex_unlock(&exclusion);
2037: }
2038: }
2039: else
2040: {
2041: if ((s_thread_principal = recherche_thread_principal(getpid()))
2042: != NULL)
2043: {
2044: envoi_signal_contexte(s_thread_principal, rpl_sigint);
2045: }
2046: }
2047:
2048: deverrouillage_gestionnaire_signaux(s_etat_processus);
2049: return;
2050: }
2051:
2052: static inline void
2053: signal_tstp(struct_processus *s_etat_processus, pid_t pid)
2054: {
2055: struct_processus *s_thread_principal;
2056:
2057: verrouillage_gestionnaire_signaux(s_etat_processus);
2058:
2059: if (pid == getpid())
2060: {
2061: /*
2062: * 0 => fonctionnement normal
2063: * -1 => requête
2064: * 1 => requête acceptée en attente de traitement
2065: */
2066:
2067: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2068: {
2069: printf("[%d] RPL/SIGTSTP (thread %llu)\n", (int) getpid(),
2070: (unsigned long long) pthread_self());
2071: fflush(stdout);
2072: }
2073:
2074: if ((*s_etat_processus).var_volatile_processus_pere == 0)
2075: {
2076: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
2077: rpl_sigtstp, d_faux);
2078: }
2079: else
2080: {
2081: (*s_etat_processus).var_volatile_requete_arret2 = -1;
2082: }
2083: }
2084: else
2085: {
2086: // Envoi d'un signal au thread maître du groupe.
2087:
2088: if ((s_thread_principal = recherche_thread_principal(getpid()))
2089: != NULL)
2090: {
2091: envoi_signal_contexte(s_thread_principal, rpl_sigtstp);
2092: }
2093: }
2094:
2095: deverrouillage_gestionnaire_signaux(s_etat_processus);
2096: return;
2097: }
2098:
2099: static void
2100: sortie_interruption_depassement_pile(void *arg1, void *arg2, void *arg3)
2101: {
2102: switch((*((volatile int *) arg1)))
2103: {
2104: case 1:
2105: longjmp(contexte_ecriture, -1);
2106: break;
2107:
2108: case 2:
2109: longjmp(contexte_impression, -1);
2110: break;
2111: }
2112:
2113: return;
2114: }
2115:
2116: #ifdef HAVE_SIGSEGV_RECOVERY
2117: void
2118: interruption_depassement_pile(int urgence, stackoverflow_context_t scp)
2119: {
2120: if ((urgence == 0) && (routine_recursive != 0))
2121: {
2122: // On peut tenter de récupérer le dépassement de pile. Si la variable
2123: // 'routine_recursive' est non nulle, on récupère l'erreur.
2124:
2125: sigsegv_leave_handler(sortie_interruption_depassement_pile,
2126: (void *) &routine_recursive, NULL, NULL);
2127: }
2128:
2129: // Ici, la panique est totale et il vaut mieux quitter l'application.
2130: interruption3(SIGUSR2);
2131: return;
2132: }
2133: #endif
2134:
2135: int
2136: interruption_violation_access(void *adresse_fautive, int gravite)
2137: {
2138: unsigned char message[] = "+++System : Trying to catch access "
2139: "violation\n";
2140:
2141: static int compteur_erreur = 0;
2142:
2143: if ((gravite == 0) && (routine_recursive != 0))
2144: {
2145: // Il peut s'agir d'un dépassement de pile.
2146:
2147: # ifdef HAVE_SIGSEGV_RECOVERY
2148: sigsegv_leave_handler(sortie_interruption_depassement_pile,
2149: (void *) &routine_recursive, NULL, NULL);
2150: # else
2151: sortie_interruption_depassement_pile((void *) &routine_recursive,
2152: NULL, NULL);
2153: # endif
2154: }
2155:
2156: // On est dans une bonne vieille violation d'accès. On essaie
2157: // de fermer au mieux l'application.
2158:
2159: compteur_erreur++;
2160:
2161: if (compteur_erreur >= 2)
2162: {
2163: // Erreurs multiples, on arrête l'application.
2164: interruption3(SIGSEGV);
2165: return(0);
2166: }
2167:
2168: # pragma GCC diagnostic push
2169: # pragma GCC diagnostic ignored "-Wunused-result"
2170:
2171: write(STDERR_FILENO, message, strlen(message));
2172:
2173: # pragma GCC diagnostic pop
2174:
2175: if (pid_processus_pere == getpid())
2176: {
2177: longjmp(contexte_initial, -1);
2178: return(1);
2179: }
2180: else
2181: {
2182: longjmp(contexte_processus, -1);
2183: return(1);
2184: }
2185:
2186: // On renvoie 0 parce qu'on décline toute responsabilité quant à la
2187: // suite des événements...
2188: return(0);
2189: }
2190:
2191: // Traitement de rpl_sigstart
2192:
2193: static inline void
2194: signal_start(struct_processus *s_etat_processus, pid_t pid)
2195: {
2196: struct_processus *s_thread_principal;
2197:
2198: verrouillage_gestionnaire_signaux(s_etat_processus);
2199:
2200: if (pid == getpid())
2201: {
2202: (*s_etat_processus).demarrage_fils = d_vrai;
2203: }
2204: else
2205: {
2206: // Envoi d'un signal au thread maître du groupe.
2207:
2208: if ((s_thread_principal = recherche_thread_principal(getpid()))
2209: != NULL)
2210: {
2211: envoi_signal_contexte(s_thread_principal, rpl_sigstart);
2212: }
2213: }
2214:
2215: deverrouillage_gestionnaire_signaux(s_etat_processus);
2216: return;
2217: }
2218:
2219: // Traitement de rpl_sigcont
2220:
2221: static inline void
2222: signal_cont(struct_processus *s_etat_processus, pid_t pid)
2223: {
2224: struct_processus *s_thread_principal;
2225:
2226: verrouillage_gestionnaire_signaux(s_etat_processus);
2227:
2228: if (pid == getpid())
2229: {
2230: (*s_etat_processus).redemarrage_processus = d_vrai;
2231: }
2232: else
2233: {
2234: // Envoi d'un signal au thread maître du groupe.
2235:
2236: if ((s_thread_principal = recherche_thread_principal(getpid()))
2237: != NULL)
2238: {
2239: envoi_signal_contexte(s_thread_principal, rpl_sigcont);
2240: }
2241: }
2242:
2243: deverrouillage_gestionnaire_signaux(s_etat_processus);
2244: return;
2245: }
2246:
2247: // Traitement de rpl_sigstop
2248:
2249: static inline void
2250: signal_stop(struct_processus *s_etat_processus, pid_t pid)
2251: {
2252: struct_processus *s_thread_principal;
2253:
2254: verrouillage_gestionnaire_signaux(s_etat_processus);
2255:
2256: if (pid == getpid())
2257: {
2258: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2259: {
2260: printf("[%d] RPL/SIGSTOP (thread %llu)\n", (int) getpid(),
2261: (unsigned long long) pthread_self());
2262: fflush(stdout);
2263: }
2264:
2265: /*
2266: * var_globale_traitement_retarde_stop :
2267: * 0 -> traitement immédiat
2268: * 1 -> traitement retardé (aucun signal reçu)
2269: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2270: */
2271:
2272: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
2273: {
2274: (*s_etat_processus).var_volatile_requete_arret = -1;
2275: }
2276: else
2277: {
2278: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
2279: }
2280: }
2281: else
2282: {
2283: // Envoi d'un signal au thread maître du groupe.
2284:
2285: if ((s_thread_principal = recherche_thread_principal(getpid()))
2286: != NULL)
2287: {
2288: envoi_signal_contexte(s_thread_principal, rpl_sigstop);
2289: }
2290: }
2291:
2292: deverrouillage_gestionnaire_signaux(s_etat_processus);
2293: return;
2294: }
2295:
2296: // Traitement de rpl_siginject
2297:
2298: static inline void
2299: signal_inject(struct_processus *s_etat_processus, pid_t pid)
2300: {
2301: verrouillage_gestionnaire_signaux(s_etat_processus);
2302:
2303: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2304: {
2305: deverrouillage_gestionnaire_signaux(s_etat_processus);
2306: return;
2307: }
2308:
2309: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2310: {
2311: printf("[%d] RPL/SIGINJECT (thread %llu)\n", (int) getpid(),
2312: (unsigned long long) pthread_self());
2313: fflush(stdout);
2314: }
2315:
2316: deverrouillage_gestionnaire_signaux(s_etat_processus);
2317: return;
2318: }
2319:
2320:
2321: static inline void
2322: signal_urg(struct_processus *s_etat_processus, pid_t pid)
2323: {
2324: struct_processus *s_thread_principal;
2325:
2326: verrouillage_gestionnaire_signaux(s_etat_processus);
2327:
2328: if (pid == getpid())
2329: {
2330: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2331: {
2332: printf("[%d] RPL/SIGURG (thread %llu)\n", (int) getpid(),
2333: (unsigned long long) pthread_self());
2334: fflush(stdout);
2335: }
2336:
2337: (*s_etat_processus).var_volatile_alarme = -1;
2338: (*s_etat_processus).var_volatile_requete_arret = -1;
2339: }
2340: else
2341: {
2342: // Envoi d'un signal au thread maître du groupe.
2343:
2344: if ((s_thread_principal = recherche_thread_principal(getpid()))
2345: != NULL)
2346: {
2347: envoi_signal_contexte(s_thread_principal, rpl_sigurg);
2348: }
2349: }
2350:
2351: deverrouillage_gestionnaire_signaux(s_etat_processus);
2352: return;
2353: }
2354:
2355: // Traitement de rpl_sigabort
2356:
2357: static inline void
2358: signal_abort(struct_processus *s_etat_processus, pid_t pid)
2359: {
2360: struct_processus *s_thread_principal;
2361:
2362: verrouillage_gestionnaire_signaux(s_etat_processus);
2363:
2364: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2365: {
2366: deverrouillage_gestionnaire_signaux(s_etat_processus);
2367: return;
2368: }
2369:
2370: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2371: {
2372: printf("[%d] RPL/SIGABORT (thread %llu)\n", (int) getpid(),
2373: (unsigned long long) pthread_self());
2374: fflush(stdout);
2375: }
2376:
2377: if (pid == getpid())
2378: {
2379: (*s_etat_processus).arret_depuis_abort = -1;
2380:
2381: /*
2382: * var_globale_traitement_retarde_stop :
2383: * 0 -> traitement immédiat
2384: * 1 -> traitement retardé (aucun signal reçu)
2385: * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
2386: */
2387:
2388: if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
2389: {
2390: (*s_etat_processus).var_volatile_requete_arret = -1;
2391: }
2392: else
2393: {
2394: (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
2395: }
2396: }
2397: else
2398: {
2399: (*s_etat_processus).arret_depuis_abort = -1;
2400:
2401: // Envoi d'un signal au thread maître du groupe.
2402:
2403: if ((s_thread_principal = recherche_thread_principal(getpid()))
2404: != NULL)
2405: {
2406: envoi_signal_contexte(s_thread_principal, rpl_sigabort);
2407: }
2408: }
2409:
2410: deverrouillage_gestionnaire_signaux(s_etat_processus);
2411: return;
2412: }
2413:
2414:
2415: static inline void
2416: signal_hup(struct_processus *s_etat_processus, pid_t pid)
2417: {
2418: file *fichier;
2419:
2420: unsigned char nom[8 + 64 + 1];
2421:
2422: verrouillage_gestionnaire_signaux(s_etat_processus);
2423:
2424: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2425: {
2426: deverrouillage_gestionnaire_signaux(s_etat_processus);
2427: return;
2428: }
2429:
2430: snprintf(nom, 8 + 64 + 1, "rpl-out-%llu-%llu",
2431: (unsigned long long) getpid(),
2432: (unsigned long long) pthread_self());
2433:
2434: # pragma GCC diagnostic push
2435: # pragma GCC diagnostic ignored "-Wunused-result"
2436:
2437: if ((fichier = fopen(nom, "w+")) != NULL)
2438: {
2439: fclose(fichier);
2440:
2441: freopen(nom, "w", stdout);
2442: freopen(nom, "w", stderr);
2443: }
2444:
2445: freopen("/dev/null", "r", stdin);
2446:
2447: # pragma GCC diagnostic pop
2448:
2449: if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
2450: {
2451: printf("[%d] RPL/SIGHUP (thread %llu)\n", (int) getpid(),
2452: (unsigned long long) pthread_self());
2453: fflush(stdout);
2454: }
2455:
2456: deverrouillage_gestionnaire_signaux(s_etat_processus);
2457: return;
2458: }
2459:
2460: void
2461: traitement_exceptions_gsl(const char *reason, const char *file,
2462: int line, int gsl_errno)
2463: {
2464: code_erreur_gsl = gsl_errno;
2465: envoi_signal_processus(getpid(), rpl_sigexcept, d_faux);
2466: return;
2467: }
2468:
2469: static inline void
2470: signal_except(struct_processus *s_etat_processus, pid_t pid)
2471: {
2472: verrouillage_gestionnaire_signaux(s_etat_processus);
2473:
2474: if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
2475: {
2476: deverrouillage_gestionnaire_signaux(s_etat_processus);
2477: return;
2478: }
2479:
2480: (*s_etat_processus).var_volatile_exception_gsl = code_erreur_gsl;
2481: deverrouillage_gestionnaire_signaux(s_etat_processus);
2482:
2483: return;
2484: }
2485:
2486: static inline void
2487: envoi_interruptions(struct_processus *s_etat_processus, enum signaux_rpl signal,
2488: pid_t pid_source)
2489: {
2490: switch(signal)
2491: {
2492: case rpl_signull:
2493: break;
2494:
2495: case rpl_sigint:
2496: signal_int(s_etat_processus, pid_source);
2497: break;
2498:
2499: case rpl_sigterm:
2500: signal_term(s_etat_processus, pid_source);
2501: break;
2502:
2503: case rpl_sigstart:
2504: signal_start(s_etat_processus, pid_source);
2505: break;
2506:
2507: case rpl_sigcont:
2508: signal_cont(s_etat_processus, pid_source);
2509: break;
2510:
2511: case rpl_sigstop:
2512: signal_stop(s_etat_processus, pid_source);
2513: break;
2514:
2515: case rpl_sigabort:
2516: signal_abort(s_etat_processus, pid_source);
2517: break;
2518:
2519: case rpl_sigurg:
2520: signal_urg(s_etat_processus, pid_source);
2521: break;
2522:
2523: case rpl_siginject:
2524: signal_inject(s_etat_processus, pid_source);
2525: break;
2526:
2527: case rpl_sigalrm:
2528: signal_alrm(s_etat_processus, pid_source);
2529: break;
2530:
2531: case rpl_sighup:
2532: signal_hup(s_etat_processus, pid_source);
2533: break;
2534:
2535: case rpl_sigtstp:
2536: signal_tstp(s_etat_processus, pid_source);
2537: break;
2538:
2539: case rpl_sigexcept:
2540: signal_except(s_etat_processus, pid_source);
2541: break;
2542:
2543: default:
2544: if ((*s_etat_processus).langue == 'F')
2545: {
2546: printf("+++System : Signal inconnu (%d) !\n", signal);
2547: }
2548: else
2549: {
2550: printf("+++System : Spurious signal (%d) !\n", signal);
2551: }
2552:
2553: break;
2554: }
2555:
2556: return;
2557: }
2558:
2559: void
2560: scrutation_interruptions(struct_processus *s_etat_processus)
2561: {
2562: // Interruptions qui arrivent sur le processus depuis un
2563: // processus externe.
2564:
2565: // Les pointeurs de lecture pointent sur les prochains éléments
2566: // à lire. Les pointeurs d'écriture pointent sur les prochains éléments à
2567: // écrire.
2568:
2569: if (sem_trywait(semaphore_queue_signaux) == 0)
2570: {
2571: while((*s_queue_signaux).pointeur_lecture !=
2572: (*s_queue_signaux).pointeur_ecriture)
2573: {
2574: // Il y a un signal en attente dans le segment partagé. On le
2575: // traite.
2576:
2577: envoi_interruptions(s_etat_processus,
2578: (*s_queue_signaux).queue[(*s_queue_signaux)
2579: .pointeur_lecture].signal, (*s_queue_signaux).queue
2580: [(*s_queue_signaux).pointeur_lecture].pid);
2581: (*s_queue_signaux).pointeur_lecture =
2582: ((*s_queue_signaux).pointeur_lecture + 1)
2583: % LONGUEUR_QUEUE_SIGNAUX;
2584:
2585: # ifndef IPCS_SYSV
2586: if (msync(s_queue_signaux, sizeof(s_queue_signaux),
2587: MS_ASYNC | MS_INVALIDATE) != 0)
2588: {
2589: sem_post(semaphore_queue_signaux);
2590: (*s_etat_processus).erreur_systeme = d_es_processus;
2591: return;
2592: }
2593: # endif
2594:
2595: while(sem_wait(semaphore_signalisation) != 0)
2596: {
2597: if (errno != EINTR)
2598: {
2599: (*s_etat_processus).erreur_systeme = d_es_processus;
2600: return;
2601: }
2602: }
2603: }
2604:
2605: sem_post(semaphore_queue_signaux);
2606: }
2607:
2608: // Interruptions qui arrivent depuis le groupe courant de threads.
2609:
2610: if (pthread_mutex_trylock(&mutex_liste_threads) == 0)
2611: {
2612: if (pthread_mutex_trylock(&((*s_etat_processus).mutex_signaux)) == 0)
2613: {
2614: while((*s_etat_processus).pointeur_signal_lecture !=
2615: (*s_etat_processus).pointeur_signal_ecriture)
2616: {
2617: // Il y a un signal dans la queue du thread courant.
2618: // On le traite.
2619:
2620: envoi_interruptions(s_etat_processus,
2621: (*s_etat_processus).signaux_en_queue
2622: [(*s_etat_processus).pointeur_signal_lecture],
2623: getpid());
2624: (*s_etat_processus).pointeur_signal_lecture =
2625: ((*s_etat_processus).pointeur_signal_lecture + 1)
2626: % LONGUEUR_QUEUE_SIGNAUX;
2627:
2628: while(sem_wait(semaphore_signalisation) != 0)
2629: {
2630: if (errno != EINTR)
2631: {
2632: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
2633: {
2634: (*s_etat_processus).erreur_systeme = d_es_processus;
2635: return;
2636: }
2637:
2638: (*s_etat_processus).erreur_systeme = d_es_processus;
2639: return;
2640: }
2641: }
2642: }
2643:
2644: pthread_mutex_unlock(&((*s_etat_processus).mutex_signaux));
2645: }
2646:
2647: pthread_mutex_unlock(&mutex_liste_threads);
2648: }
2649:
2650: return;
2651: }
2652:
2653:
2654: /*
2655: ================================================================================
2656: Fonction renvoyant le nom du segment de mémoire partagée en fonction
2657: du pid du processus.
2658: ================================================================================
2659: Entrée : Chemin absolue servant de racine, pid du processus
2660: --------------------------------------------------------------------------------
2661: Sortie : NULL ou nom du segment
2662: --------------------------------------------------------------------------------
2663: Effet de bord : Néant
2664: ================================================================================
2665: */
2666:
2667: static unsigned char *
2668: nom_segment(unsigned char *chemin, pid_t pid)
2669: {
2670: unsigned char *fichier;
2671:
2672: # ifdef IPCS_SYSV // !POSIX
2673: # ifndef OS2 // !OS2
2674:
2675: if ((fichier = sys_malloc((strlen(chemin) + 1 + 256 + 1) *
2676: sizeof(unsigned char))) == NULL)
2677: {
2678: return(NULL);
2679: }
2680:
2681: sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);
2682: # else // OS2
2683: if ((fichier = sys_malloc((10 + 256 + 1) * sizeof(unsigned char)))
2684: == NULL)
2685: {
2686: return(NULL);
2687: }
2688:
2689: sprintf(fichier, "\\SHAREMEM\\RPL-SIGQUEUES-%d", (int) pid);
2690: # endif // OS2
2691: # else // POSIX
2692:
2693: if ((fichier = sys_malloc((1 + 256 + 1) *
2694: sizeof(unsigned char))) == NULL)
2695: {
2696: return(NULL);
2697: }
2698:
2699: sprintf(fichier, "/RPL-SIGQUEUES-%d", (int) pid);
2700: # endif
2701:
2702: return(fichier);
2703: }
2704:
2705:
2706: /*
2707: ================================================================================
2708: Fonctions d'envoi d'un signal à un thread ou à un processus.
2709: ================================================================================
2710: Entrée : processus et signal
2711: --------------------------------------------------------------------------------
2712: Sortie : erreur
2713: --------------------------------------------------------------------------------
2714: Effet de bord : Néant
2715: ================================================================================
2716: */
2717:
2718: int
2719: envoi_signal_processus(pid_t pid, enum signaux_rpl signal,
2720: logical1 test_ouverture)
2721: {
2722: # ifndef OS2
2723: int segment;
2724: # endif
2725:
2726: # ifndef IPCS_SYSV
2727: sem_t *semaphore;
2728: sem_t *signalisation;
2729: # else
2730: sem_t *semaphore;
2731: sem_t *signalisation;
2732: # ifndef OS2
2733: int desc;
2734: key_t clef;
2735: # endif
2736: # endif
2737:
2738: struct_queue_signaux *queue;
2739:
2740: struct timespec attente;
2741:
2742: unsigned char *nom;
2743:
2744: // Il s'agit d'ouvrir le segment de mémoire partagée, de le projeter en
2745: // mémoire puis d'y inscrire le signal à traiter.
2746:
2747: if (pid == getpid())
2748: {
2749: // Le signal est envoyé au même processus.
2750:
2751: if (s_queue_signaux == NULL)
2752: {
2753: return(1);
2754: }
2755:
2756: while(sem_wait(semaphore_queue_signaux) != 0)
2757: {
2758: if (errno != EINTR)
2759: {
2760: return(1);
2761: }
2762: }
2763:
2764: (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture]
2765: .pid = pid;
2766: (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture]
2767: .signal = signal;
2768:
2769: (*s_queue_signaux).pointeur_ecriture =
2770: ((*s_queue_signaux).pointeur_ecriture + 1)
2771: % LONGUEUR_QUEUE_SIGNAUX;
2772:
2773: # ifndef IPCS_SYSV
2774: if (msync(s_queue_signaux, sizeof(s_queue_signaux),
2775: MS_ASYNC | MS_INVALIDATE) != 0)
2776: {
2777: sem_post(semaphore_queue_signaux);
2778: return(1);
2779: }
2780: # endif
2781:
2782: if (sem_post(semaphore_queue_signaux) != 0)
2783: {
2784: return(1);
2785: }
2786:
2787: if (sem_post(semaphore_signalisation) != 0)
2788: {
2789: return(1);
2790: }
2791: }
2792: else
2793: {
2794: // Le signal est envoyé depuis un processus distinct.
2795:
2796: # ifdef IPCS_SYSV
2797: if ((nom = nom_segment(racine_segment, pid)) == NULL)
2798: {
2799: return(1);
2800: }
2801:
2802: # ifndef OS2 // SysV
2803: if (test_ouverture == d_vrai)
2804: {
2805: attente.tv_sec = 0;
2806: attente.tv_nsec = GRANULARITE_us * 1000;
2807:
2808: while((desc = open(nom, O_RDWR)) == -1)
2809: {
2810: nanosleep(&attente, NULL);
2811: INCR_GRANULARITE(attente.tv_nsec);
2812: }
2813: }
2814: else
2815: {
2816: if ((desc = open(nom, O_RDWR)) == -1)
2817: {
2818: sys_free(nom);
2819: return(1);
2820: }
2821: }
2822:
2823: close(desc);
2824:
2825: if ((clef = ftok(nom, 1)) == -1)
2826: {
2827: sys_free(nom);
2828: return(1);
2829: }
2830:
2831: sys_free(nom);
2832:
2833: if ((segment = shmget(clef, sizeof(struct_queue_signaux), 0))
2834: == -1)
2835: {
2836: return(1);
2837: }
2838:
2839: queue = shmat(segment, NULL, 0);
2840: # else // OS/2
2841: if (test_ouverture == d_vrai)
2842: {
2843: attente.tv_sec = 0;
2844: attente.tv_nsec = GRANULARITE_us * 1000;
2845:
2846: while(DosGetNamedSharedMem((PVOID) &queue, nom,
2847: PAG_WRITE | PAG_READ) != 0)
2848: {
2849: nanosleep(&attente, NULL);
2850: INCR_GRANULARITE(attente.tv_nsec);
2851: }
2852: }
2853: else
2854: {
2855: if (DosGetNamedSharedMem((PVOID) &queue, nom,
2856: PAG_WRITE | PAG_READ) != 0)
2857: {
2858: sys_free(nom);
2859: return(1);
2860: }
2861: }
2862:
2863: sys_free(nom);
2864: # endif
2865: # else // POSIX
2866: if ((nom = nom_segment(racine_segment, pid)) == NULL)
2867: {
2868: return(1);
2869: }
2870:
2871: if (test_ouverture == d_vrai)
2872: {
2873: attente.tv_sec = 0;
2874: attente.tv_nsec = GRANULARITE_us * 1000;
2875:
2876: while((segment = shm_open(nom, O_RDWR, 0)) == -1)
2877: {
2878: nanosleep(&attente, NULL);
2879: INCR_GRANULARITE(attente.tv_nsec);
2880: }
2881: }
2882: else
2883: {
2884: if ((segment = shm_open(nom, O_RDWR, 0)) == -1)
2885: {
2886: sys_free(nom);
2887: return(1);
2888: }
2889: }
2890:
2891: sys_free(nom);
2892:
2893: if ((queue = mmap(NULL, sizeof(struct_queue_signaux),
2894: PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0)) ==
2895: MAP_FAILED)
2896: {
2897: close(segment);
2898: return(1);
2899: }
2900: # endif
2901:
2902: // À ce moment, le segment de mémoire partagée est projeté
2903: // dans l'espace du processus.
2904:
2905: if ((semaphore = sem_open2(pid, SEM_QUEUE)) == SEM_FAILED)
2906: {
2907: # ifndef IPCS_SYSV // POSIX
2908: if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
2909: {
2910: munmap(queue, sizeof(struct_queue_signaux));
2911: close(segment);
2912: return(1);
2913: }
2914:
2915: if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
2916: {
2917: close(segment);
2918: return(1);
2919: }
2920:
2921: close(segment);
2922: # else // IPCS_SYSV
2923: # ifndef OS2 // SysV
2924: if (shmdt(queue) != 0)
2925: {
2926: return(1);
2927: }
2928: # else // OS/2
2929: // Pendant de DosGetNamedSHaredMem()
2930: # endif
2931: # endif
2932: return(1);
2933: }
2934:
2935: if ((signalisation = sem_open2(pid, SEM_SIGNALISATION))
2936: == SEM_FAILED)
2937: {
2938: # ifndef IPCS_SYSV // POSIX
2939: if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
2940: {
2941: munmap(queue, sizeof(struct_queue_signaux));
2942: close(segment);
2943: sem_close(semaphore);
2944: return(1);
2945: }
2946:
2947: if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
2948: {
2949: close(segment);
2950: sem_close(semaphore);
2951: return(1);
2952: }
2953:
2954: close(segment);
2955: # else // IPCS_SYSV
2956: # ifndef OS2 // SysV
2957: if (shmdt(queue) != 0)
2958: {
2959: sem_close(semaphore);
2960: return(1);
2961: }
2962: # else // OS/2
2963: // Pendant de DosGetNamedSHaredMem()
2964: # endif
2965: # endif
2966:
2967: sem_close(semaphore);
2968: return(1);
2969: }
2970:
2971: while(sem_wait(semaphore) != 0)
2972: {
2973: if (errno != EINTR)
2974: {
2975: # ifndef IPCS_SYSV // POSIX
2976: if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE)
2977: != 0)
2978: {
2979: munmap(queue, sizeof(struct_queue_signaux));
2980: sem_close(semaphore);
2981: sem_close(signalisation);
2982: close(segment);
2983: return(1);
2984: }
2985:
2986: if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
2987: {
2988: sem_close(semaphore);
2989: sem_close(signalisation);
2990: close(segment);
2991: return(1);
2992: }
2993:
2994: close(segment);
2995: # else // IPCS_SYSV
2996: # ifndef OS2 // SysV
2997: if (shmdt(queue) != 0)
2998: {
2999: sem_close(semaphore);
3000: sem_close(signalisation);
3001: return(1);
3002: }
3003: # else // OS/2
3004: // Pendant de DosGetNamedSHaredMem()
3005: # endif
3006: # endif
3007:
3008: sem_close(semaphore);
3009: sem_close(signalisation);
3010: return(1);
3011: }
3012: }
3013:
3014: (*queue).queue[(*queue).pointeur_ecriture].pid = getpid();
3015: (*queue).queue[(*queue).pointeur_ecriture].signal = signal;
3016:
3017: (*queue).pointeur_ecriture = ((*queue).pointeur_ecriture + 1)
3018: % LONGUEUR_QUEUE_SIGNAUX;
3019:
3020: if (sem_post(semaphore) != 0)
3021: {
3022: # ifndef IPCS_SYSV // POSIX
3023: if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
3024: {
3025: munmap(queue, sizeof(struct_queue_signaux));
3026: close(segment);
3027: sem_close(semaphore);
3028: sem_close(signalisation);
3029: return(1);
3030: }
3031:
3032: if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
3033: {
3034: close(segment);
3035: sem_close(semaphore);
3036: sem_close(signalisation);
3037: return(1);
3038: }
3039:
3040: close(segment);
3041: # else // IPCS_SYSV
3042: # ifndef OS2 // SysV
3043: if (shmdt(queue) != 0)
3044: {
3045: sem_close(semaphore);
3046: sem_close(signalisation);
3047: return(1);
3048: }
3049: # else // OS/2
3050: // Pendant de DosGetNamedSHaredMem()
3051: # endif
3052: # endif
3053:
3054: sem_close(semaphore);
3055: sem_close(signalisation);
3056: return(1);
3057: }
3058:
3059: if (sem_close(semaphore) != 0)
3060: {
3061: # ifndef IPCS_SYSV // POSIX
3062: if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
3063: {
3064: munmap(queue, sizeof(struct_queue_signaux));
3065: close(segment);
3066: sem_close(signalisation);
3067: return(1);
3068: }
3069:
3070: if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
3071: {
3072: close(segment);
3073: sem_close(signalisation);
3074: return(1);
3075: }
3076:
3077: close(segment);
3078: # else // IPCS_SYSV
3079: # ifndef OS2 // SysV
3080: if (shmdt(queue) != 0)
3081: {
3082: sem_close(signalisation);
3083: return(1);
3084: }
3085: # else // OS/2
3086: // Pendant de DosGetNamedSHaredMem()
3087: # endif
3088: # endif
3089:
3090: sem_close(signalisation);
3091: return(1);
3092: }
3093:
3094: if (sem_post(signalisation) != 0)
3095: {
3096: # ifndef IPCS_SYSV // POSIX
3097: if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
3098: {
3099: munmap(queue, sizeof(struct_queue_signaux));
3100: close(segment);
3101: sem_close(signalisation);
3102: return(1);
3103: }
3104:
3105: if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
3106: {
3107: close(segment);
3108: sem_close(signalisation);
3109: return(1);
3110: }
3111:
3112: close(segment);
3113: # else // IPCS_SYSV
3114: # ifndef OS2 // SysV
3115: if (shmdt(queue) != 0)
3116: {
3117: sem_close(signalisation);
3118: return(1);
3119: }
3120: # else // OS/2
3121: // Pendant de DosGetNamedSHaredMem()
3122: # endif
3123: # endif
3124:
3125: sem_close(signalisation);
3126: return(1);
3127: }
3128:
3129: if (sem_close(signalisation) != 0)
3130: {
3131: # ifndef IPCS_SYSV // POSIX
3132: if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
3133: {
3134: munmap(queue, sizeof(struct_queue_signaux));
3135: close(segment);
3136: return(1);
3137: }
3138:
3139: if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
3140: {
3141: close(segment);
3142: return(1);
3143: }
3144:
3145: close(segment);
3146: # else // IPCS_SYSV
3147: # ifndef OS2 // SysV
3148: if (shmdt(queue) != 0)
3149: {
3150: return(1);
3151: }
3152: # else // OS/2
3153: // Pendant de DosGetNamedSHaredMem()
3154: # endif
3155: # endif
3156:
3157: return(1);
3158: }
3159:
3160: # ifndef IPCS_SYSV // POSIX
3161: if (msync(queue, sizeof(queue), MS_ASYNC | MS_INVALIDATE) != 0)
3162: {
3163: munmap(queue, sizeof(struct_queue_signaux));
3164: close(segment);
3165: return(1);
3166: }
3167:
3168: if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
3169: {
3170: close(segment);
3171: return(1);
3172: }
3173:
3174: close(segment);
3175: # else // IPCS_SYSV
3176: # ifndef OS2 // SysV
3177: if (shmdt(queue) != 0)
3178: {
3179: return(1);
3180: }
3181: # else // OS/2
3182: // Pendant de DosGetNamedSHaredMem()
3183: # endif
3184: # endif
3185: }
3186:
3187: return(0);
3188: }
3189:
3190: int
3191: envoi_signal_thread(struct_processus *s_contexte,
3192: pthread_t tid, enum signaux_rpl signal)
3193: {
3194: // Un signal est envoyé d'un thread à un autre thread du même processus.
3195:
3196: int ios;
3197:
3198: struct timespec attente;
3199:
3200: volatile struct_liste_chainee_volatile *l_element_courant;
3201:
3202: struct_processus *s_etat_processus;
3203:
3204: if (s_contexte != NULL)
3205: {
3206: attente.tv_sec = 0;
3207: attente.tv_nsec = GRANULARITE_us * 1000;
3208:
3209: while((ios = pthread_mutex_trylock(&mutex_liste_threads)) != 0)
3210: {
3211: if (ios != EBUSY)
3212: {
3213: return(1);
3214: }
3215:
3216: if (sem_post(&((*s_contexte).semaphore_fork)) != 0)
3217: {
3218: return(1);
3219: }
3220:
3221: nanosleep(&attente, NULL);
3222: INCR_GRANULARITE(attente.tv_nsec);
3223:
3224: while(sem_wait(&((*s_contexte).semaphore_fork)) != 0)
3225: {
3226: if (errno != EINTR)
3227: {
3228: return(1);
3229: }
3230: }
3231: }
3232: }
3233: else
3234: {
3235: if (pthread_mutex_lock(&mutex_liste_threads) != 0)
3236: {
3237: return(1);
3238: }
3239: }
3240:
3241: l_element_courant = liste_threads;
3242:
3243: while(l_element_courant != NULL)
3244: {
3245: if (((*((struct_thread *) (*l_element_courant).donnee)).pid
3246: == getpid()) && (pthread_equal((*((struct_thread *)
3247: (*l_element_courant).donnee)).tid, tid) != 0))
3248: {
3249: break;
3250: }
3251:
3252: l_element_courant = (*l_element_courant).suivant;
3253: }
3254:
3255: if (l_element_courant == NULL)
3256: {
3257: pthread_mutex_unlock(&mutex_liste_threads);
3258: return(1);
3259: }
3260:
3261: s_etat_processus = (*((struct_thread *) (*l_element_courant).donnee))
3262: .s_etat_processus;
3263:
3264: if (pthread_mutex_lock(&((*s_etat_processus).mutex_signaux)) != 0)
3265: {
3266: pthread_mutex_unlock(&mutex_liste_threads);
3267: return(1);
3268: }
3269:
3270: (*s_etat_processus).signaux_en_queue
3271: [(*s_etat_processus).pointeur_signal_ecriture] = signal;
3272: (*s_etat_processus).pointeur_signal_ecriture =
3273: ((*s_etat_processus).pointeur_signal_ecriture + 1)
3274: % LONGUEUR_QUEUE_SIGNAUX;
3275:
3276: if (pthread_mutex_unlock(&((*s_etat_processus).mutex_signaux)) != 0)
3277: {
3278: pthread_mutex_unlock(&mutex_liste_threads);
3279: return(1);
3280: }
3281:
3282: if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
3283: {
3284: return(1);
3285: }
3286:
3287: if (sem_post(semaphore_signalisation) != 0)
3288: {
3289: return(1);
3290: }
3291:
3292: return(0);
3293: }
3294:
3295: int
3296: envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,
3297: enum signaux_rpl signal)
3298: {
3299: pthread_mutex_lock(&((*s_etat_processus_a_signaler).mutex_signaux));
3300: (*s_etat_processus_a_signaler).signaux_en_queue
3301: [(*s_etat_processus_a_signaler).pointeur_signal_ecriture] =
3302: signal;
3303: (*s_etat_processus_a_signaler).pointeur_signal_ecriture =
3304: ((*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1)
3305: % LONGUEUR_QUEUE_SIGNAUX;
3306: pthread_mutex_unlock(&((*s_etat_processus_a_signaler).mutex_signaux));
3307:
3308: if (sem_post(semaphore_signalisation) != 0)
3309: {
3310: return(1);
3311: }
3312:
3313: return(0);
3314: }
3315:
3316:
3317: /*
3318: ================================================================================
3319: Fonction créant un segment de mémoire partagée destiné à contenir
3320: la queue des signaux.
3321: ================================================================================
3322: Entrée : structure de description du processus
3323: --------------------------------------------------------------------------------
3324: Sortie : Néant
3325: --------------------------------------------------------------------------------
3326: Effet de bord : Néant
3327: ================================================================================
3328: */
3329:
3330: void
3331: creation_queue_signaux(struct_processus *s_etat_processus)
3332: {
3333: pthread_attr_t attributs;
3334:
3335: unsigned char *nom;
3336:
3337: racine_segment = (*s_etat_processus).chemin_fichiers_temporaires;
3338:
3339: # ifndef IPCS_SYSV // POSIX
3340: if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
3341: getpid())) == NULL)
3342: {
3343: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3344: return;
3345: }
3346:
3347: if ((f_queue_signaux = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,
3348: S_IRUSR | S_IWUSR)) == -1)
3349: {
3350: if (errno != EEXIST)
3351: {
3352: sys_free(nom);
3353: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3354: return;
3355: }
3356:
3357: if ((*s_etat_processus).langue == 'F')
3358: {
3359: printf("+++Attention : Le segment de mémoire %s préexiste !\n",
3360: nom);
3361: }
3362: else
3363: {
3364: printf("+++Warning: %s memory segment preexists!\n", nom);
3365: }
3366:
3367: if ((f_queue_signaux = shm_open(nom, O_RDWR | O_CREAT | O_TRUNC,
3368: S_IRUSR | S_IWUSR)) == -1)
3369: {
3370: sys_free(nom);
3371: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3372: return;
3373: }
3374: }
3375:
3376: if (ftruncate(f_queue_signaux, sizeof(struct_queue_signaux)) == -1)
3377: {
3378: sys_free(nom);
3379: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3380: return;
3381: }
3382:
3383: s_queue_signaux = mmap(NULL, sizeof(struct_queue_signaux),
3384: PROT_READ | PROT_WRITE, MAP_SHARED, f_queue_signaux, 0);
3385:
3386: if (((void *) s_queue_signaux) == ((void *) -1))
3387: {
3388: if (shm_unlink(nom) == -1)
3389: {
3390: sys_free(nom);
3391: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3392: return;
3393: }
3394:
3395: sys_free(nom);
3396: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3397: return;
3398: }
3399:
3400: sys_free(nom);
3401:
3402: if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE))
3403: == SEM_FAILED)
3404: {
3405: (*s_etat_processus).erreur_systeme = d_es_processus;
3406: return;
3407: }
3408:
3409: if ((semaphore_signalisation = sem_init2(0, getpid(),
3410: SEM_SIGNALISATION)) == SEM_FAILED)
3411: {
3412: (*s_etat_processus).erreur_systeme = d_es_processus;
3413: return;
3414: }
3415:
3416: if ((semaphore_arret_signalisation = sem_init2(1, getpid(),
3417: SEM_ARRET_SIGNALISATION)) == SEM_FAILED)
3418: {
3419: (*s_etat_processus).erreur_systeme = d_es_processus;
3420: return;
3421: }
3422:
3423: (*s_queue_signaux).pointeur_lecture = 0;
3424: (*s_queue_signaux).pointeur_ecriture = 0;
3425:
3426: (*s_queue_signaux).requete_arret = d_faux;
3427:
3428: if (msync(s_queue_signaux, sizeof(struct_queue_signaux),
3429: MS_ASYNC | MS_INVALIDATE) != 0)
3430: {
3431: (*s_etat_processus).erreur_systeme = d_es_processus;
3432: return;
3433: }
3434: # else // IPCS_SYSV
3435: # ifndef OS2
3436: int segment;
3437: int support;
3438:
3439: key_t clef;
3440:
3441: // Création d'un segment de données associé au PID du processus
3442: // courant
3443:
3444: if ((nom = nom_segment((*s_etat_processus)
3445: .chemin_fichiers_temporaires, getpid())) == NULL)
3446: {
3447: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3448: return;
3449: }
3450:
3451: if ((support = open(nom, O_RDWR | O_CREAT | O_EXCL,
3452: S_IRUSR | S_IWUSR)) == -1)
3453: {
3454: (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
3455: return;
3456: }
3457:
3458: if ((clef = ftok(nom, 1)) == -1)
3459: {
3460: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3461: return;
3462: }
3463:
3464: close(support);
3465: sys_free(nom);
3466:
3467: if ((segment = shmget(clef, sizeof(struct_queue_signaux),
3468: IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)
3469: {
3470: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3471: return;
3472: }
3473:
3474: s_queue_signaux = shmat(segment, NULL, 0);
3475: f_queue_signaux = segment;
3476:
3477: if (((void *) s_queue_signaux) == ((void *) -1))
3478: {
3479: if (shmctl(f_queue_signaux, IPC_RMID, 0) == -1)
3480: {
3481: (*s_etat_processus).erreur_systeme =
3482: d_es_allocation_memoire;
3483: return;
3484: }
3485:
3486: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3487: return;
3488: }
3489:
3490: if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE))
3491: == SEM_FAILED)
3492: {
3493: (*s_etat_processus).erreur_systeme = d_es_processus;
3494: return;
3495: }
3496:
3497: if ((semaphore_signalisation = sem_init2(0, getpid(),
3498: SEM_SIGNALISATION)) == SEM_FAILED)
3499: {
3500: (*s_etat_processus).erreur_systeme = d_es_processus;
3501: return;
3502: }
3503:
3504: if ((semaphore_arret_signalisation = sem_init2(1, getpid(),
3505: SEM_ARRET_SIGNALISATION)) == SEM_FAILED)
3506: {
3507: (*s_etat_processus).erreur_systeme = d_es_processus;
3508: return;
3509: }
3510:
3511: (*s_queue_signaux).pointeur_lecture = 0;
3512: (*s_queue_signaux).pointeur_ecriture = 0;
3513: (*s_queue_signaux).requete_arret = d_faux;
3514: # else // OS/2
3515: if ((nom = nom_segment(NULL, getpid())) == NULL)
3516: {
3517: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3518: return;
3519: }
3520:
3521: if (DosAllocSharedMem((PVOID) &s_queue_signaux, nom,
3522: sizeof(struct_queue_signaux),
3523: PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
3524: {
3525: sys_free(nom);
3526: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3527: return;
3528: }
3529:
3530: sys_free(nom);
3531:
3532: sem_init(&((*s_queue_signaux).semaphore), 1, 1);
3533: sem_init(&((*s_queue_signaux).signalisation), 1, 0);
3534: sem_init(&((*s_queue_signaux).arret_signalisation), 1, 1);
3535:
3536: (*s_queue_signaux).pointeur_lecture = 0;
3537: (*s_queue_signaux).pointeur_ecriture = 0;
3538: (*s_queue_signaux).requete_arret = d_faux;
3539: # endif
3540: # endif
3541:
3542: (*s_queue_signaux).controle = getpid();
3543:
3544: if (lancement_thread_signaux(s_etat_processus) == d_erreur)
3545: {
3546: (*s_etat_processus).erreur_systeme = d_es_processus;
3547: return;
3548: }
3549:
3550: // Lancement du thread de récupération des signaux.
3551:
3552: if (pthread_attr_init(&attributs) != 0)
3553: {
3554: (*s_etat_processus).erreur_systeme = d_es_processus;
3555: return;
3556: }
3557:
3558: if (pthread_attr_setdetachstate(&attributs,
3559: PTHREAD_CREATE_JOINABLE) != 0)
3560: {
3561: (*s_etat_processus).erreur_systeme = d_es_processus;
3562: return;
3563: }
3564:
3565: if (pthread_create(&((*s_queue_signaux).thread_signaux), &attributs,
3566: thread_surveillance_signaux, s_etat_processus) != 0)
3567: {
3568: (*s_etat_processus).erreur_systeme = d_es_processus;
3569: return;
3570: }
3571:
3572: if (pthread_attr_destroy(&attributs) != 0)
3573: {
3574: (*s_etat_processus).erreur_systeme = d_es_processus;
3575: return;
3576: }
3577:
3578: # ifndef IPCS_SYSV
3579: if (msync(s_queue_signaux, sizeof(s_queue_signaux),
3580: MS_ASYNC | MS_INVALIDATE) != 0)
3581: {
3582: (*s_etat_processus).erreur_systeme = d_es_processus;
3583: return;
3584: }
3585: # endif
3586:
3587: return;
3588: }
3589:
3590:
3591: /*
3592: ================================================================================
3593: Fonction libérant le segment de mémoire partagée destiné à contenir
3594: la queue des signaux.
3595: ================================================================================
3596: Entrée : structure de description du processus
3597: --------------------------------------------------------------------------------
3598: Sortie : Néant
3599: --------------------------------------------------------------------------------
3600: Effet de bord : Néant
3601: ================================================================================
3602: */
3603:
3604: void
3605: liberation_queue_signaux(struct_processus *s_etat_processus)
3606: {
3607: # ifdef IPCS_SYSV // SystemV
3608: # ifndef OS2
3609: if (shmdt(s_queue_signaux) == -1)
3610: {
3611: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3612: return;
3613: }
3614: # else // OS/2
3615: # endif
3616: # else // POSIX
3617: sem_close(semaphore_queue_signaux);
3618: sem_close(semaphore_signalisation);
3619: sem_close(semaphore_arret_signalisation);
3620:
3621: if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
3622: {
3623: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3624: return;
3625: }
3626:
3627: close(f_queue_signaux);
3628: # endif
3629:
3630: return;
3631: }
3632:
3633:
3634: /*
3635: ================================================================================
3636: Fonction détruisant le segment de mémoire partagée destiné à contenir
3637: la queue des signaux.
3638: ================================================================================
3639: Entrée : structure de description du processus
3640: --------------------------------------------------------------------------------
3641: Sortie : Néant
3642: --------------------------------------------------------------------------------
3643: Effet de bord : Néant
3644: ================================================================================
3645: */
3646:
3647: void
3648: destruction_queue_signaux(struct_processus *s_etat_processus)
3649: {
3650: # ifndef OS2
3651: unsigned char *nom;
3652: # endif
3653:
3654: // On dépile les interruptions pour arrêter les SIGUSR2 sur
3655: // le processus courant.
3656:
3657: scrutation_interruptions(s_etat_processus);
3658:
3659: while(sem_wait(semaphore_arret_signalisation) != 0)
3660: {
3661: if (errno != EINTR)
3662: {
3663: (*s_etat_processus).erreur_systeme = d_es_processus;
3664: return;
3665: }
3666: }
3667:
3668: (*s_queue_signaux).requete_arret = d_vrai;
3669:
3670: # ifndef IPCS_SYSV
3671: msync(s_queue_signaux, sizeof(s_queue_signaux), MS_ASYNC | MS_INVALIDATE);
3672: # endif
3673:
3674: sem_post(semaphore_arret_signalisation);
3675:
3676: // Incrémenter le sémaphore pour être sûr de le débloquer.
3677:
3678: sem_post(semaphore_signalisation);
3679:
3680: if ((*s_queue_signaux).controle == getpid())
3681: {
3682: pthread_join((*s_queue_signaux).thread_signaux, NULL);
3683: }
3684: else
3685: {
3686: (*s_etat_processus).erreur_systeme = d_es_processus;
3687: return;
3688: }
3689:
3690: arret_thread_signaux(s_etat_processus);
3691:
3692: # ifdef IPCS_SYSV // SystemV
3693: # ifndef OS2
3694: // Il faut commencer par éliminer le sémaphore.
3695:
3696: if (semctl((*semaphore_queue_signaux).sem, 0, IPC_RMID) == -1)
3697: {
3698: (*s_etat_processus).erreur_systeme = d_es_processus;
3699: return;
3700: }
3701:
3702: unlink((*semaphore_queue_signaux).path);
3703: sys_free((*semaphore_queue_signaux).path);
3704:
3705: if (semctl((*semaphore_signalisation).sem, 0, IPC_RMID) == -1)
3706: {
3707: (*s_etat_processus).erreur_systeme = d_es_processus;
3708: return;
3709: }
3710:
3711: unlink((*semaphore_signalisation).path);
3712: sys_free((*semaphore_signalisation).path);
3713:
3714: if (semctl((*semaphore_arret_signalisation).sem, 0, IPC_RMID) == -1)
3715: {
3716: (*s_etat_processus).erreur_systeme = d_es_processus;
3717: return;
3718: }
3719:
3720: unlink((*semaphore_arret_signalisation).path);
3721: sys_free((*semaphore_arret_signalisation).path);
3722:
3723: if (shmdt(s_queue_signaux) == -1)
3724: {
3725: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3726: return;
3727: }
3728:
3729: if (shmctl(f_queue_signaux, IPC_RMID, 0) == -1)
3730: {
3731: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3732: return;
3733: }
3734:
3735: if ((nom = nom_segment((*s_etat_processus)
3736: .chemin_fichiers_temporaires, getpid())) == NULL)
3737: {
3738: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3739: return;
3740: }
3741:
3742: unlink(nom);
3743: sys_free(nom);
3744: # else
3745: sem_close(&((*s_queue_signaux).semaphore));
3746: sem_destroy(&((*s_queue_signaux).semaphore));
3747:
3748: sem_close(&((*s_queue_signaux).signalisation));
3749: sem_destroy(&((*s_queue_signaux).signalisation));
3750:
3751: sem_close(&((*s_queue_signaux).arret_signalisation));
3752: sem_destroy(&((*s_queue_signaux).arret_signalisation));
3753:
3754: if (DosFreeMem(s_queue_signaux) != 0)
3755: {
3756: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3757: return;
3758: }
3759: # endif
3760: # else // POSIX
3761: sem_destroy2(semaphore_queue_signaux, getpid(), SEM_QUEUE);
3762: sem_destroy2(semaphore_signalisation, getpid(), SEM_SIGNALISATION);
3763: sem_destroy2(semaphore_arret_signalisation, getpid(),
3764: SEM_ARRET_SIGNALISATION);
3765:
3766: if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
3767: {
3768: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3769: return;
3770: }
3771:
3772: if ((nom = nom_segment(NULL, getpid())) == NULL)
3773: {
3774: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3775: return;
3776: }
3777:
3778: close(f_queue_signaux);
3779:
3780: if (shm_unlink(nom) != 0)
3781: {
3782: sys_free(nom);
3783: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3784: return;
3785: }
3786:
3787: sys_free(nom);
3788: # endif
3789:
3790: return;
3791: }
3792:
3793: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>