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