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