--- rpl/src/interruptions.c 2010/04/30 15:01:14 1.13 +++ rpl/src/interruptions.c 2010/08/17 14:15:20 1.31 @@ -1,6 +1,6 @@ /* ================================================================================ - RPL/2 (R) version 4.0.15 + RPL/2 (R) version 4.0.18 Copyright (C) 1989-2010 Dr. BERTRAND Joël This file is part of RPL/2. @@ -20,7 +20,7 @@ */ -#include "rpl.conv.h" +#include "rpl-conv.h" /* @@ -125,7 +125,6 @@ insertion_thread(struct_processus *s_eta } (*l_nouvel_objet).suivant = liste_threads; - liste_threads = l_nouvel_objet; # ifndef SEMAPHORES_NOMMES @@ -184,6 +183,10 @@ insertion_thread_surveillance(struct_pro } } + pthread_mutex_lock(&((*s_argument_thread).mutex)); + (*s_argument_thread).nombre_references++; + pthread_mutex_unlock(&((*s_argument_thread).mutex)); + (*l_nouvel_objet).suivant = liste_threads_surveillance; (*l_nouvel_objet).donnee = (void *) s_argument_thread; @@ -366,7 +369,6 @@ retrait_thread_surveillance(struct_proce return; } - // l_element_courant->donnee n'est pas bonne lorsque ça part en vrille. if (l_element_precedent == NULL) { liste_threads_surveillance = (*l_element_courant).suivant; @@ -449,6 +451,7 @@ retrait_thread_surveillance(struct_proce pthread_sigmask(SIG_SETMASK, &oldset, NULL); sigpending(&set); + return; } @@ -670,18 +673,73 @@ liberation_threads(struct_processus *s_e .l_base_pile_processus; while(element_courant != NULL) { - pthread_mutex_trylock(&((*(*((struct_liste_chainee *) - element_courant)).donnee).mutex)); - pthread_mutex_unlock(&((*(*((struct_liste_chainee *) - element_courant)).donnee).mutex)); - liberation(s_etat_processus, - (*((struct_liste_chainee *) element_courant)).donnee); + s_argument_thread = (struct_descripteur_thread *) + (*((struct_liste_chainee *) element_courant)).donnee; + + if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + sem_post(&semaphore_liste_threads); + return; + } + + (*s_argument_thread).nombre_references--; + + BUG((*s_argument_thread).nombre_references < 0, + printf("(*s_argument_thread).nombre_references = %d\n", + (int) (*s_argument_thread).nombre_references)); + + if ((*s_argument_thread).nombre_references == 0) + { + close((*s_argument_thread).pipe_objets[0]); + close((*s_argument_thread).pipe_acquittement[1]); + close((*s_argument_thread).pipe_injections[1]); + close((*s_argument_thread).pipe_nombre_injections[1]); + close((*s_argument_thread).pipe_nombre_objets_attente[0]); + close((*s_argument_thread).pipe_interruptions[0]); + close((*s_argument_thread) + .pipe_nombre_interruptions_attente[0]); + + if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) + != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + sem_post(&semaphore_liste_threads); + return; + } + + pthread_mutex_destroy(&((*s_argument_thread).mutex)); + + if ((*s_argument_thread).processus_detache == d_faux) + { + if ((*s_argument_thread).destruction_objet == d_vrai) + { + liberation(s_etat_processus, (*s_argument_thread) + .argument); + } + } + + free(s_argument_thread); + } + else + { + if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) + != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + sem_post(&semaphore_liste_threads); + return; + } + } + element_suivant = (*((struct_liste_chainee *) element_courant)) .suivant; - free((struct_liste_chainee *) element_courant); + free(element_courant); element_courant = element_suivant; } + (*s_etat_processus).l_base_pile_processus = NULL; + pthread_mutex_trylock(&((*(*s_etat_processus).indep).mutex)); pthread_mutex_unlock(&((*(*s_etat_processus).indep).mutex)); liberation(s_etat_processus, (*s_etat_processus).indep); @@ -1156,6 +1214,12 @@ liberation_threads(struct_processus *s_e element_courant = element_suivant; } +/* +================================================================================ + À noter : on ne ferme pas la connexion car la conséquence immédiate est + une destruction de l'objet pour le processus père. +================================================================================ + element_courant = (*s_etat_processus).s_connecteurs_sql; while(element_courant != NULL) { @@ -1239,6 +1303,9 @@ liberation_threads(struct_processus *s_e element_courant = element_suivant; } +*/ + + (*s_etat_processus).s_connecteurs_sql = NULL; element_courant = (*s_etat_processus).s_marques; while(element_courant != NULL) @@ -1283,14 +1350,6 @@ liberation_threads(struct_processus *s_e s_argument_thread = (struct_descripteur_thread *) (*l_element_courant).donnee; - close((*s_argument_thread).pipe_objets[0]); - close((*s_argument_thread).pipe_acquittement[1]); - close((*s_argument_thread).pipe_injections[1]); - close((*s_argument_thread).pipe_nombre_injections[1]); - close((*s_argument_thread).pipe_nombre_objets_attente[0]); - close((*s_argument_thread).pipe_interruptions[0]); - close((*s_argument_thread).pipe_nombre_interruptions_attente[0]); - if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; @@ -1306,6 +1365,14 @@ liberation_threads(struct_processus *s_e if ((*s_argument_thread).nombre_references == 0) { + close((*s_argument_thread).pipe_objets[0]); + close((*s_argument_thread).pipe_acquittement[1]); + close((*s_argument_thread).pipe_injections[1]); + close((*s_argument_thread).pipe_nombre_injections[1]); + close((*s_argument_thread).pipe_nombre_objets_attente[0]); + close((*s_argument_thread).pipe_interruptions[0]); + close((*s_argument_thread).pipe_nombre_interruptions_attente[0]); + if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; @@ -1314,6 +1381,15 @@ liberation_threads(struct_processus *s_e } pthread_mutex_destroy(&((*s_argument_thread).mutex)); + + if ((*s_argument_thread).processus_detache == d_faux) + { + if ((*s_argument_thread).destruction_objet == d_vrai) + { + liberation(s_etat_processus, (*s_argument_thread).argument); + } + } + free(s_argument_thread); } else @@ -1432,7 +1508,7 @@ recherche_thread_principal(pid_t pid, pt */ // Les routines suivantes sont uniquement appelées depuis les gestionnaires -// des signaux asynchrones. Elles de doivent pas bloquer dans le cas où +// des signaux asynchrones. Elles ne doivent pas bloquer dans le cas où // les sémaphores sont déjà bloqués par un gestionnaire de signal. static inline void @@ -1648,28 +1724,474 @@ deverrouillage_gestionnaire_signaux() return; } +#ifdef _BROKEN_SIGINFO + +static int *fifos; +static int segment; +static int segment_mutexes; +static int longueur_queue; +static int nombre_queues; + +static pthread_mutex_t *mutexes; + +static unsigned char *chemin = NULL; + +unsigned char * +nom_segment(unsigned char *chemin, pid_t pid) +{ + unsigned char *fichier; + + if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) * + sizeof(unsigned char))) == NULL) + { + return(NULL); + } + + sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid); + + return(fichier); +} + +unsigned char * +nom_segment_mutexes(unsigned char *chemin, pid_t pid) +{ + unsigned char *fichier; + + if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) * + sizeof(unsigned char))) == NULL) + { + return(NULL); + } + + sprintf(fichier, "%s/RPL-SIGMUTEXES-%d", chemin, (int) pid); + + return(fichier); +} + +int +queue_de_signal(int signal) +{ + switch(signal) + { + case SIGINT: + BUG(1, uprintf("SIGINT is not queued as it does not " + "come from program itself !\n")); + return(0); + case SIGTSTP: + return(1); + case SIGCONT: + return(2); + case SIGURG: + return(3); + case SIGPIPE: + return(4); + case SIGALRM: + return(5); + case SIGFSTOP: + return(6); + case SIGSTART: + return(7); + case SIGINJECT: + return(8); + case SIGABORT: + return(9); + case SIGFABORT: + return(10); + } + + return(-1); +} + void -interruption1(int signal, siginfo_t *siginfo, void *context) +creation_fifos_signaux(struct_processus *s_etat_processus) { + file *desc; + + int i; + + key_t clef; + + pthread_mutexattr_t attributs_mutex; + + unsigned char *nom; + + /* + * Signaux utilisés + * SIGINT, SIGTSTP, SIGCONT, SIGURG, SIGPIPE, SIGALRM, SIGFSTOP, + * SIGSTART, SIGINJECT, SIGABORT, SIGFABORT + */ + + // Création d'un segment de données associé au PID du processus courant + + chemin = (*s_etat_processus).chemin_fichiers_temporaires; + + if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires, + getpid())) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + /* + * Structure d'une queue + * 0 : pointeur en lecture sur le premier emplacement libre (int) + * 1 : pointeur en écriture sur le premier emplacement à lire (int) + * 2 : longueur de la queue (int) + * 3 : éléments restants (int) + * 4 à 4 + (2) : queue (int) + * 5 : mutex + */ + + nombre_queues = 11; + longueur_queue = 256; + + if ((desc = fopen(nom, "w")) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return; + } + + fclose(desc); + + if ((clef = ftok(nom, 1)) == -1) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + free(nom); + + if ((segment = shmget(clef, + nombre_queues * (longueur_queue + 4) * sizeof(int), + IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + fifos = shmat(segment, NULL, 0); + + if (((void *) fifos) == ((void *) -1)) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + for(i = 0; i < nombre_queues; i++) + { + fifos[(i * (longueur_queue + 4))] = 0; + fifos[(i * (longueur_queue + 4)) + 1] = 0; + fifos[(i * (longueur_queue + 4)) + 2] = longueur_queue; + fifos[(i * (longueur_queue + 4)) + 3] = longueur_queue; + } + + if ((nom = nom_segment_mutexes((*s_etat_processus) + .chemin_fichiers_temporaires, getpid())) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if ((desc = fopen(nom, "w")) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; + return; + } + + fclose(desc); + + if ((clef = ftok(nom, 1)) == -1) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + free(nom); + + if ((segment_mutexes = shmget(clef, + nombre_queues * sizeof(pthread_mutex_t), + IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + mutexes = shmat(segment_mutexes, NULL, 0); + + if (((void *) mutexes) == ((void *) -1)) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + /* + * Création et initialisation d'un mutex par queue. Ce mutex n'est pas + * dans le premier segment parce qu'il peut y avoir des problèmes + * d'alignements sur certaines architectures. + */ + + pthread_mutexattr_init(&attributs_mutex); + pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_RECURSIVE); + + for(i = 0; i < nombre_queues; i++) + { + pthread_mutex_init(&(mutexes[i]), &attributs_mutex); + } + + pthread_mutexattr_destroy(&attributs_mutex); + return; +} + +void +liberation_fifos_signaux(struct_processus *s_etat_processus) +{ + if (shmdt(fifos) == -1) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if (shmdt(mutexes) == -1) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + return; +} + +void +destruction_fifos_signaux(struct_processus *s_etat_processus) +{ + int i; + + unsigned char *nom; + + if (shmdt(fifos) == -1) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if (shmctl(segment, IPC_RMID, 0) == -1) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + for(i = 0; i < nombre_queues; i++) + { + pthread_mutex_destroy(&(mutexes[i])); + } + + if (shmdt(mutexes) == -1) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if (shmctl(segment_mutexes, IPC_RMID, 0) == -1) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if ((nom = nom_segment_mutexes((*s_etat_processus) + .chemin_fichiers_temporaires, getpid())) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + unlink(nom); + free(nom); + + if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires, + getpid())) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + unlink(nom); + free(nom); + + return; +} + +int +queue_in(pid_t pid, int signal) +{ + int *base; + int *buffer; + int *projection_fifos; + int queue; + int identifiant; + + key_t clef; + + pthread_mutex_t *projection_mutexes; + + unsigned char *nom; + + queue = queue_de_signal(signal); + + // Ouverture des projections + + if ((nom = nom_segment(chemin, pid)) == NULL) + { + return(-1); + } + + if ((clef = ftok(nom, 1)) == -1) + { + free(nom); + return(-1); + } + + free(nom); + + while((identifiant = shmget(clef, + nombre_queues * (longueur_queue + 4) * sizeof(int), + S_IRUSR | S_IWUSR)) == -1); + + projection_fifos = shmat(identifiant, NULL, 0); + + if ((nom = nom_segment_mutexes(chemin, pid)) == NULL) + { + return(-1); + } + + if ((clef = ftok(nom, 1)) == -1) + { + free(nom); + return(-1); + } + + free(nom); + + while((identifiant = shmget(clef, + nombre_queues * sizeof(pthread_mutex_t), + S_IRUSR | S_IWUSR)) == -1); + + projection_mutexes = shmat(identifiant, NULL, 0); + + if (pthread_mutex_lock(&(projection_mutexes[queue])) != 0) + { + return(-1); + } + + base = &(projection_fifos[(longueur_queue + 4) * queue]); + buffer = &(base[4]); + + // base[1] contient le prochain élément à écrire + buffer[base[1]++] = (int) pid; + base[1] %= base[2]; + + // base[3] contient le nombre d'éléments non lus + if (base[3] <= 0) + { + pthread_mutex_unlock(&(projection_mutexes[queue])); + shmdt(projection_mutexes); + shmdt(projection_fifos); + return(-1); + } + + base[3]--; + + if (pthread_mutex_unlock(&(projection_mutexes[queue])) != 0) + { + shmdt(projection_mutexes); + shmdt(projection_fifos); + return(-1); + } + + // Fermeture des projections + shmdt(projection_mutexes); + shmdt(projection_fifos); + return(0); +} + +pid_t +origine_signal(int signal) +{ + int *base; + int *buffer; + int pid; + int queue; + + queue = queue_de_signal(signal); + + BUG(queue == -1, uprintf("[%d] Unknown signal %d in this context\n", + (int) getpid(), signal)); + + if (pthread_mutex_lock(&(mutexes[queue])) != 0) + { + return(-1); + } + + base = &(fifos[(longueur_queue + 4) * queue]); + buffer = &(base[4]); + pid = buffer[base[0]++]; + base[0] %= base[2]; + base[3]++; + + if (base[3] > base[2]) + { + pthread_mutex_unlock(&(mutexes[queue])); + return(-1); + } + if (pthread_mutex_unlock(&(mutexes[queue])) != 0) + { + perror("unlock"); + return(-1); + } + + return((pid_t) pid); +} + +#endif + +void +interruption1(SIGHANDLER_ARGS) +{ + pid_t pid; + pthread_t thread; struct_processus *s_etat_processus; volatile sig_atomic_t exclusion = 0; +# ifdef _BROKEN_SIGINFO + if (signal == SIGINT) + { + // Si l'interruption provient du clavier, il n'y a pas eu d'appel + // à queue_in(). + + pid = getpid(); + } + else + { + pid = origine_signal(signal); + } +# else + pid = (*siginfo).si_pid; +# endif + verrouillage_gestionnaire_signaux(); switch(signal) { case SIGALRM : { - if ((*siginfo).si_pid == getpid()) + if (pid == getpid()) { if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) { deverrouillage_gestionnaire_signaux(); - return; + return; } if (((*s_etat_processus).type_debug & d_debug_signaux) != 0) @@ -1708,11 +2230,14 @@ interruption1(int signal, siginfo_t *sig * Solaris suit en particulier cette spécification. */ +# ifndef _BROKEN_SIGINFO if (siginfo == NULL) { kill(getpid(), signal); } - else if ((*siginfo).si_pid == getpid()) + else +# endif + if (pid == getpid()) { if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) @@ -1787,13 +2312,23 @@ interruption1(int signal, siginfo_t *sig } void -interruption2(int signal, siginfo_t *siginfo, void *context) +interruption2(SIGHANDLER_ARGS) { + pid_t pid; + pthread_t thread; + struct_processus *s_etat_processus; +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + pid = (*siginfo).si_pid; +# endif + verrouillage_gestionnaire_signaux(); +# ifndef _BROKEN_SIGINFO if (siginfo == NULL) { /* @@ -1811,7 +2346,9 @@ interruption2(int signal, siginfo_t *sig return; } } - else if ((*siginfo).si_pid == getpid()) + else +# endif + if (pid == getpid()) { if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) @@ -1859,12 +2396,20 @@ interruption2(int signal, siginfo_t *sig } void -interruption3(int signal, siginfo_t *siginfo, void *context) +interruption3(SIGHANDLER_ARGS) { + pid_t pid; + struct_processus *s_etat_processus; static int compteur = 0; +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + pid = (*siginfo).si_pid; +# endif + verrouillage_gestionnaire_signaux(); if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) @@ -1919,10 +2464,18 @@ interruption3(int signal, siginfo_t *sig } void -interruption4(int signal, siginfo_t *siginfo, void *context) +interruption4(SIGHANDLER_ARGS) { + pid_t pid; + struct_processus *s_etat_processus; +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + pid = (*siginfo).si_pid; +# endif + verrouillage_gestionnaire_signaux(); if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) @@ -1947,14 +2500,23 @@ interruption4(int signal, siginfo_t *sig } void -interruption5(int signal, siginfo_t *siginfo, void *context) +interruption5(SIGHANDLER_ARGS) { + pid_t pid; + pthread_t thread; + struct_processus *s_etat_processus; +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + pid = (*siginfo).si_pid; +# endif + verrouillage_gestionnaire_signaux(); - if ((*siginfo).si_pid == getpid()) + if (pid == getpid()) { if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) @@ -1963,25 +2525,11 @@ interruption5(int signal, siginfo_t *sig return; } - if (signal == SIGFABORT) - { - (*s_etat_processus).arret_depuis_abort = -1; - } - if (((*s_etat_processus).type_debug & d_debug_signaux) != 0) { - if (signal == SIGFSTOP) - { - printf("[%d] SIGFSTOP (thread %llu)\n", (int) getpid(), - (unsigned long long) pthread_self()); - fflush(stdout); - } - else - { - printf("[%d] SIGFABORT (thread %llu)\n", (int) getpid(), - (unsigned long long) pthread_self()); - fflush(stdout); - } + printf("[%d] SIGFSTOP (thread %llu)\n", (int) getpid(), + (unsigned long long) pthread_self()); + fflush(stdout); } /* @@ -2009,11 +2557,6 @@ interruption5(int signal, siginfo_t *sig return; } - if (signal == SIGFABORT) - { - (*s_etat_processus).arret_depuis_abort = -1; - } - // Envoi d'un signal au thread maître du groupe. if (recherche_thread_principal(getpid(), &thread) == d_vrai) @@ -2029,10 +2572,18 @@ interruption5(int signal, siginfo_t *sig } void -interruption6(int signal, siginfo_t *siginfo, void *context) +interruption6(SIGHANDLER_ARGS) { + pid_t pid; + struct_processus *s_etat_processus; +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + pid = (*siginfo).si_pid; +# endif + verrouillage_gestionnaire_signaux(); if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) @@ -2053,10 +2604,18 @@ interruption6(int signal, siginfo_t *sig } void -interruption7(int signal, siginfo_t *siginfo, void *context) +interruption7(SIGHANDLER_ARGS) { + pid_t pid; + struct_processus *s_etat_processus; +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + pid = (*siginfo).si_pid; +# endif + verrouillage_gestionnaire_signaux(); if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) @@ -2080,14 +2639,23 @@ interruption7(int signal, siginfo_t *sig } void -interruption8(int signal, siginfo_t *siginfo, void *context) +interruption8(SIGHANDLER_ARGS) { + pid_t pid; + pthread_t thread; + struct_processus *s_etat_processus; +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + pid = (*siginfo).si_pid; +# endif + verrouillage_gestionnaire_signaux(); - if ((*siginfo).si_pid == getpid()) + if (pid == getpid()) { if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) @@ -2123,10 +2691,18 @@ interruption8(int signal, siginfo_t *sig } void -interruption9(int signal, siginfo_t *siginfo, void *context) +interruption9(SIGHANDLER_ARGS) { + pid_t pid; + struct_processus *s_etat_processus; +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + pid = (*siginfo).si_pid; +# endif + verrouillage_gestionnaire_signaux(); if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) @@ -2142,20 +2718,38 @@ interruption9(int signal, siginfo_t *sig fflush(stdout); } - pthread_kill((*s_etat_processus).tid_processus_pere, SIGFABORT); deverrouillage_gestionnaire_signaux(); + +# ifdef _BROKEN_SIGINFO + if (queue_in(getpid(), signal) != 0) + { + return; + } + + interruption11(signal); +# else + interruption11(signal, siginfo, context); +# endif return; } void -interruption10(int signal, siginfo_t *siginfo, void *context) +interruption10(SIGHANDLER_ARGS) { file *fichier; + pid_t pid; + struct_processus *s_etat_processus; unsigned char nom[8 + 64 + 1]; +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + pid = (*siginfo).si_pid; +# endif + verrouillage_gestionnaire_signaux(); if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) @@ -2189,6 +2783,82 @@ interruption10(int signal, siginfo_t *si } void +interruption11(SIGHANDLER_ARGS) +{ + pid_t pid; + + pthread_t thread; + + struct_processus *s_etat_processus; + +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + pid = (*siginfo).si_pid; +# endif + + verrouillage_gestionnaire_signaux(); + + if (pid == getpid()) + { + if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) + == NULL) + { + deverrouillage_gestionnaire_signaux(); + return; + } + + (*s_etat_processus).arret_depuis_abort = -1; + + if (((*s_etat_processus).type_debug & d_debug_signaux) != 0) + { + printf("[%d] SIGFABORT (thread %llu)\n", (int) getpid(), + (unsigned long long) pthread_self()); + fflush(stdout); + } + + /* + * var_globale_traitement_retarde_stop : + * 0 -> traitement immédiat + * 1 -> traitement retardé (aucun signal reçu) + * -1 -> traitement retardé (un ou plusieurs signaux stop reçus) + */ + + if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0) + { + (*s_etat_processus).var_volatile_requete_arret = -1; + } + else + { + (*s_etat_processus).var_volatile_traitement_retarde_stop = -1; + } + } + else + { + if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) + == NULL) + { + deverrouillage_gestionnaire_signaux(); + return; + } + + (*s_etat_processus).arret_depuis_abort = -1; + + // Envoi d'un signal au thread maître du groupe. + + if (recherche_thread_principal(getpid(), &thread) == d_vrai) + { + pthread_kill(thread, signal); + deverrouillage_gestionnaire_signaux(); + return; + } + } + + deverrouillage_gestionnaire_signaux(); + return; +} + +void traitement_exceptions_gsl(const char *reason, const char *file, int line, int gsl_errno) { @@ -2207,4 +2877,45 @@ traitement_exceptions_gsl(const char *re return; } +#ifdef _BROKEN_SIGINFO + +#undef kill +#undef pthread_kill + +int +rpl_kill(pid_t pid, int signal) +{ + /* + * Lorsqu'on veut interrompre le processus pid, on ouvre le segment + * correspondant au processus en question et ou ajoute le pid dans la + * queue. + */ + + if ((signal != 0) && (signal != SIGINT)) + { + if (queue_in(pid, signal) != 0) + { + return(-1); + } + } + + return(kill(pid, signal)); +} + +int +rpl_pthread_kill(pthread_t tid, int signal) +{ + if ((signal != 0) && (signal != SIGINT)) + { + if (queue_in(getpid(), signal) != 0) + { + return(-1); + } + } + + return(pthread_kill(tid, signal)); +} + +#endif + // vim: ts=4