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