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