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