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