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