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