--- rpl/src/interruptions.c 2010/08/17 11:59:28 1.30 +++ rpl/src/interruptions.c 2010/08/25 09:06:49 1.35 @@ -1726,21 +1726,25 @@ deverrouillage_gestionnaire_signaux() #ifdef _BROKEN_SIGINFO +#define longueur_queue 256 +#define nombre_queues 13 + static int *fifos; +static int markov; static int segment; -static int segment_mutexes; -static int longueur_queue; -static int nombre_queues; - -static pthread_mutex_t *mutexes; +static sem_t *semaphores[nombre_queues]; +static sem_t *semaphore_global; +#ifdef IPCS_SYSV static unsigned char *chemin = NULL; +#endif unsigned char * nom_segment(unsigned char *chemin, pid_t pid) { unsigned char *fichier; +# ifdef IPCS_SYSV if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) * sizeof(unsigned char))) == NULL) { @@ -1748,27 +1752,35 @@ nom_segment(unsigned char *chemin, pid_t } sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid); +# else + if ((fichier = malloc((1 + 256 + 1) * + sizeof(unsigned char))) == NULL) + { + return(NULL); + } + + sprintf(fichier, "/RPL-SIGQUEUES-%d", (int) pid); +# endif return(fichier); } unsigned char * -nom_segment_mutexes(unsigned char *chemin, pid_t pid) +nom_semaphore(pid_t pid, int queue) { unsigned char *fichier; - if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) * - sizeof(unsigned char))) == NULL) + if ((fichier = malloc((256 + 1) * sizeof(unsigned char))) == NULL) { return(NULL); } - sprintf(fichier, "%s/RPL-SIGMUTEXES-%d", chemin, (int) pid); + sprintf(fichier, "/RPL-SIGESMAPHORES-%d-%d", (int) pid, queue); return(fichier); } -int +inline int queue_de_signal(int signal) { switch(signal) @@ -1795,6 +1807,10 @@ queue_de_signal(int signal) return(9); case SIGFABORT: return(10); + case SIGSEGV: + return(11); + case SIGBUS: + return(12); } return(-1); @@ -1803,21 +1819,66 @@ queue_de_signal(int signal) void creation_fifos_signaux(struct_processus *s_etat_processus) { - file *desc; + /* + * Signaux utilisés + * SIGINT, SIGTSTP, SIGCONT, SIGURG, SIGPIPE, SIGALRM, SIGFSTOP, + * SIGSTART, SIGINJECT, SIGABORT, SIGFABORT + */ int i; - key_t clef; + unsigned char *nom; - pthread_mutexattr_t attributs_mutex; +# ifndef IPCS_SYSV // POSIX - unsigned char *nom; + if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires, + getpid())) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } - /* - * Signaux utilisés - * SIGINT, SIGTSTP, SIGCONT, SIGURG, SIGPIPE, SIGALRM, SIGFSTOP, - * SIGSTART, SIGINJECT, SIGABORT, SIGFABORT - */ + if ((segment = shm_open(nom, O_RDWR | O_CREAT | O_EXCL, + S_IRUSR | S_IWUSR)) == -1) + { + free(nom); + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if (ftruncate(segment, nombre_queues * ((2 * longueur_queue) + 4) * + sizeof(int)) == -1) + { + free(nom); + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + fifos = mmap(NULL, nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int), + PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0); + close(segment); + + if (((void *) fifos) == ((void *) -1)) + { + if (shm_unlink(nom) == -1) + { + free(nom); + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + free(nom); + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + free(nom); + +# else // SystemV + + file *desc; + + key_t clef; // Création d'un segment de données associé au PID du processus courant @@ -1830,19 +1891,6 @@ creation_fifos_signaux(struct_processus 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; @@ -1860,7 +1908,7 @@ creation_fifos_signaux(struct_processus free(nom); if ((segment = shmget(clef, - nombre_queues * (longueur_queue + 4) * sizeof(int), + nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int), IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -1871,10 +1919,28 @@ creation_fifos_signaux(struct_processus if (((void *) fifos) == ((void *) -1)) { + if (shmctl(segment, IPC_RMID, 0) == -1) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } +# endif + + /* + * 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) + * 4 + (2) + 1 ) 4 + 2 * (2) : horodatage en centième de secondes. + */ + for(i = 0; i < nombre_queues; i++) { fifos[(i * (longueur_queue + 4))] = 0; @@ -1883,78 +1949,92 @@ creation_fifos_signaux(struct_processus 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; - } + // Création des sémaphores : un sémaphore par signal et par queue + // plus un sémaphore global pour tous les threads. - if ((desc = fopen(nom, "w")) == NULL) + for(i = 0; i < nombre_queues; i++) { - (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; - return; - } + if ((nom = nom_semaphore(getpid(), i)) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } - fclose(desc); + // Le sémaphore est créé en écrasant si nécessaire un sémaphore + // préexistant. Comme le nom du sémaphore contient l'identifiant du + // processus, il est anormal d'avoir un sémaphore de même nom + // préexistant. - if ((clef = ftok(nom, 1)) == -1) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; + if ((semaphores[i] = sem_open(nom, O_CREAT, S_IRUSR | S_IWUSR, + 1)) == SEM_FAILED) + { + (*s_etat_processus).erreur_systeme = d_es_semaphore; + return; + } + + free(nom); } - free(nom); - if ((segment_mutexes = shmget(clef, - nombre_queues * sizeof(pthread_mutex_t), - IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1) + if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } - mutexes = shmat(segment_mutexes, NULL, 0); - - if (((void *) mutexes) == ((void *) -1)) + if ((semaphore_global = sem_open(nom, O_CREAT, S_IRUSR | S_IWUSR, + 1)) == SEM_FAILED) { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + (*s_etat_processus).erreur_systeme = d_es_semaphore; 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. - */ + free(nom); - pthread_mutexattr_init(&attributs_mutex); - pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL); + markov = 0; - 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) { + int i; + +# ifdef IPCS_SYSV // SystemV + if (shmdt(fifos) == -1) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } - if (shmdt(mutexes) == -1) +# else // POSIX + + if (munmap(fifos, nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int)) + != 0) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } +# endif + + for(i = 0; i < nombre_queues; i++) + { + if (sem_close(semaphores[i]) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_semaphore; + return; + } + } + + if (sem_close(semaphore_global) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_semaphore; + return; + } + return; } @@ -1962,8 +2042,11 @@ void destruction_fifos_signaux(struct_processus *s_etat_processus) { int i; + unsigned char *nom; +# ifdef IPCS_SYSV // SystemV + if (shmdt(fifos) == -1) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; @@ -1976,144 +2059,312 @@ destruction_fifos_signaux(struct_process return; } - for(i = 0; i < nombre_queues; i++) + if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires, + getpid())) == NULL) { - pthread_mutex_destroy(&(mutexes[i])); + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; } - if (shmdt(mutexes) == -1) + unlink(nom); + free(nom); + +# else // POSIX + + if (munmap(fifos, nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int)) + != 0) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } - if (shmctl(segment_mutexes, IPC_RMID, 0) == -1) + if ((nom = nom_segment(NULL, getpid())) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } - if ((nom = nom_segment_mutexes((*s_etat_processus) - .chemin_fichiers_temporaires, getpid())) == NULL) + if (shm_unlink(nom) != 0) { + free(nom); (*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) +# endif + + for(i = 0; i < nombre_queues; i++) + { + if ((nom = nom_semaphore(getpid(), i)) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if (sem_unlink(nom) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_semaphore; + return; + } + + free(nom); + } + + if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } - unlink(nom); + if (sem_unlink(nom) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_semaphore; + return; + } + free(nom); return; } +inline int +horodatage() +{ + int ts; + + struct timeval tv; + + gettimeofday(&tv, NULL); + ts = (int) ((tv.tv_sec * 100) + (tv.tv_usec / 10000)); + + return(ts); +} + int queue_in(pid_t pid, int signal) { + int queue; int *base; int *buffer; - int *projection_fifos; - int queue; + int horodatage_initial; int identifiant; + int *projection_fifos; - key_t clef; + sem_t *semaphore; - pthread_mutex_t *projection_mutexes; + queue = queue_de_signal(signal); unsigned char *nom; - queue = queue_de_signal(signal); +# ifndef IPCS_SYSV // Ouverture des projections - if ((nom = nom_segment(chemin, pid)) == NULL) + if ((nom = nom_segment(NULL, pid)) == NULL) { return(-1); } - if ((clef = ftok(nom, 1)) == -1) + // Dans le cas de SIGSTART, premier signal envoyé à un processus fils, + // il convient d'attendre que le fichier support soit effectivement + // accessible. Dans tous les autres cas, ce fichier doit exister. S'il + // n'existe plus, le processus associé n'existe plus. + + if (signal == SIGSTART) + { + horodatage_initial = horodatage(); + + while((identifiant = shm_open(nom, O_RDWR, S_IRUSR | S_IWUSR)) == -1) + { + if (abs(horodatage_initial - horodatage()) > 500) + { + return(-1); + } + } + } + else + { + if ((identifiant = shm_open(nom, O_RDWR, S_IRUSR | S_IWUSR)) == -1) + { + return(-1); + } + } + + projection_fifos = mmap(NULL, nombre_queues * ((2 * longueur_queue) + 4) + * sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, identifiant, 0); + close(identifiant); + + if (((void *) projection_fifos) == ((void *) -1)) { - free(nom); return(-1); } - free(nom); +# else // Traitement à l'aide d'IPCS SystemV + + key_t clef; - while((identifiant = shmget(clef, - nombre_queues * (longueur_queue + 4) * sizeof(int), - S_IRUSR | S_IWUSR)) == -1); + struct stat s_stat; - projection_fifos = shmat(identifiant, NULL, 0); + // Ouverture des projections - if ((nom = nom_segment_mutexes(chemin, pid)) == NULL) + if ((nom = nom_segment(chemin, pid)) == NULL) { return(-1); } + // Dans le cas de SIGSTART, premier signal envoyé à un processus fils, + // il convient d'attendre que le fichier support soit effectivement + // accessible. Dans tous les autres cas, ce fichier doit exister. S'il + // n'existe plus, le processus associé n'existe plus. + + if (signal == SIGSTART) + { + // On attend que le fichier sois présent + + horodatage_initial = horodatage(); + + while(stat(nom, &s_stat) != 0) + { + if (abs(horodatage_initial - horodatage()) > 500) + { + 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); + if (signal == SIGSTART) + { + while((identifiant = shmget(clef, + nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int), + S_IRUSR | S_IWUSR)) == -1); + } + else + { + if ((identifiant = shmget(clef, + nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int), + S_IRUSR | S_IWUSR)) == -1) + { + return(-1); + } + } + + projection_fifos = shmat(identifiant, NULL, 0); + + if (((void *) projection_fifos) == ((void *) -1)) + { + return(-1); + } - projection_mutexes = shmat(identifiant, NULL, 0); +# endif - if (pthread_mutex_lock(&(projection_mutexes[queue])) != 0) + if ((nom = nom_semaphore(pid, queue)) == NULL) { +# ifdef IPCS_SYSV + shmdt(projection_fifos); +# else + munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4) + * sizeof(int)); +# endif return(-1); } + while((semaphore = sem_open(nom, 0)) == SEM_FAILED); + free(nom); + + while(sem_wait(semaphore) != 0) + { + if (errno != EINTR) + { +# ifdef IPCS_SYSV + shmdt(projection_fifos); +# else + munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4) + * sizeof(int)); +# endif + 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 restants - // base[3] contient le nombre d'éléments non lus if (base[3] <= 0) { - pthread_mutex_unlock(&(projection_mutexes[queue])); - shmdt(projection_mutexes); + sem_post(semaphore); + sem_close(semaphore); +# ifdef IPCS_SYSV shmdt(projection_fifos); +# else + munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4) + * sizeof(int)); +# endif return(-1); } base[3]--; - if (pthread_mutex_unlock(&(projection_mutexes[queue])) != 0) + // base[1] contient le prochain élément à écrire + + buffer[base[1] + (nombre_queues * base[2])] = horodatage(); + buffer[base[1]++] = (int) pid; + base[1] %= base[2]; + + if (sem_post(semaphore) != 0) { - shmdt(projection_mutexes); +# ifdef IPCS_SYSV shmdt(projection_fifos); +# else + munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4) + * sizeof(int)); +# endif + sem_close(semaphore); return(-1); } + sem_close(semaphore); + // Fermeture des projections - shmdt(projection_mutexes); +# ifdef IPCS_SYSV shmdt(projection_fifos); +# else + munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4) + * sizeof(int)); +# endif + return(0); } +inline int +chaine_markov(int markov, int delta) +{ + double memoire = 0.9; + int valeur; + + valeur = (int) ((memoire * markov) + ((1 - memoire) * delta)); + valeur = (valeur < 10) ? 10 : valeur; + + return(valeur); +} + pid_t origine_signal(int signal) { + logical1 drapeau; + int *base; int *buffer; + int delta; int pid; int queue; @@ -2122,27 +2373,69 @@ origine_signal(int signal) BUG(queue == -1, uprintf("[%d] Unknown signal %d in this context\n", (int) getpid(), signal)); - if (pthread_mutex_lock(&(mutexes[queue])) != 0) + while(sem_wait(semaphores[queue]) != 0) { - perror("lock"); - return(-1); + if (errno != EINTR) + { + return(-1); + } } + // On retire les interruptions anciennes qui ont été ratées sauf s'il + // s'agit de la dernière dans la queue. + base = &(fifos[(longueur_queue + 4) * queue]); buffer = &(base[4]); - pid = buffer[base[0]++]; - base[0] %= base[2]; - base[3]++; - if (base[3] > base[2]) + if (base[3] == (base[2] - 1)) { - uprintf("Base\n"); - pthread_mutex_unlock(&(mutexes[queue])); - return(-1); + delta = abs(horodatage() - + buffer[base[0] + (nombre_queues * base[2])]); + // Une seule interruption dans la queue. + pid = buffer[base[0]++]; + base[0] %= base[2]; + base[3]++; + + markov = chaine_markov(markov, delta); + } + else if (base[3] >= base[2]) + { + // Aucune interruption n'est dans la queue. + // On a retiré trop d'interruptions de la queue. + + // (base[3] - base[2]) + 1 : nombre d'interruptions manquantes + // base[0] - 1 : dernière interruption lue + pid = buffer[((((base[0] + base[2] - 1) % base[2]) + - ((base[3] - base[2]) + 1)) + base[2]) % base[2]]; + } + else + { + // Plusieurs interruptions à distribuer. + drapeau = d_vrai; + + do + { + delta = abs(horodatage() - + buffer[base[0] + (nombre_queues * base[2])]); + pid = buffer[base[0]++]; + base[0] %= base[2]; + base[3]++; + + if ((delta > (2 * markov)) && (base[3] < base[2])) + { + drapeau = d_vrai; + } + else + { + drapeau = d_faux; + } + } while(drapeau == d_vrai); + + markov = chaine_markov(markov, delta); } - if (pthread_mutex_unlock(&(mutexes[queue])) != 0) + + if (sem_post(semaphores[queue]) != 0) { - perror("unlock"); return(-1); } @@ -2162,14 +2455,24 @@ interruption1(SIGHANDLER_ARGS) volatile sig_atomic_t exclusion = 0; + verrouillage_gestionnaire_signaux(); + # ifdef _BROKEN_SIGINFO - pid = origine_signal(signal); + 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 : @@ -2309,14 +2612,14 @@ interruption2(SIGHANDLER_ARGS) struct_processus *s_etat_processus; + verrouillage_gestionnaire_signaux(); + # ifdef _BROKEN_SIGINFO pid = origine_signal(signal); # else pid = (*siginfo).si_pid; # endif - verrouillage_gestionnaire_signaux(); - # ifndef _BROKEN_SIGINFO if (siginfo == NULL) { @@ -2393,14 +2696,14 @@ interruption3(SIGHANDLER_ARGS) static int compteur = 0; + verrouillage_gestionnaire_signaux(); + # 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) { deverrouillage_gestionnaire_signaux(); @@ -2459,14 +2762,14 @@ interruption4(SIGHANDLER_ARGS) struct_processus *s_etat_processus; + verrouillage_gestionnaire_signaux(); + # 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) { deverrouillage_gestionnaire_signaux(); @@ -2497,14 +2800,14 @@ interruption5(SIGHANDLER_ARGS) struct_processus *s_etat_processus; + verrouillage_gestionnaire_signaux(); + # 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())) @@ -2567,14 +2870,14 @@ interruption6(SIGHANDLER_ARGS) struct_processus *s_etat_processus; + verrouillage_gestionnaire_signaux(); + # 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) { deverrouillage_gestionnaire_signaux(); @@ -2599,14 +2902,14 @@ interruption7(SIGHANDLER_ARGS) struct_processus *s_etat_processus; + verrouillage_gestionnaire_signaux(); + # 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) { deverrouillage_gestionnaire_signaux(); @@ -2636,14 +2939,14 @@ interruption8(SIGHANDLER_ARGS) struct_processus *s_etat_processus; + verrouillage_gestionnaire_signaux(); + # 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())) @@ -2686,14 +2989,14 @@ interruption9(SIGHANDLER_ARGS) struct_processus *s_etat_processus; + verrouillage_gestionnaire_signaux(); + # 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) { deverrouillage_gestionnaire_signaux(); @@ -2707,16 +3010,16 @@ interruption9(SIGHANDLER_ARGS) fflush(stdout); } - deverrouillage_gestionnaire_signaux(); - # ifdef _BROKEN_SIGINFO if (queue_in(getpid(), signal) != 0) { return; } + deverrouillage_gestionnaire_signaux(); interruption11(signal); # else + deverrouillage_gestionnaire_signaux(); interruption11(signal, siginfo, context); # endif return; @@ -2733,14 +3036,14 @@ interruption10(SIGHANDLER_ARGS) unsigned char nom[8 + 64 + 1]; + verrouillage_gestionnaire_signaux(); + # 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) { deverrouillage_gestionnaire_signaux(); @@ -2780,14 +3083,14 @@ interruption11(SIGHANDLER_ARGS) struct_processus *s_etat_processus; + verrouillage_gestionnaire_signaux(); + # 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())) @@ -2872,37 +3175,103 @@ traitement_exceptions_gsl(const char *re #undef pthread_kill int -rpl_kill(pid_t pid, int signal) +kill_broken_siginfo(pid_t pid, int signal) { + int ios; + + sem_t *semaphore; + + unsigned char *nom; + /* * Lorsqu'on veut interrompre le processus pid, on ouvre le segment * correspondant au processus en question et ou ajoute le pid dans la * queue. + * + * Le sémaphore global à tous les threads d'un même processus sert + * à garantir que les signaux seront traités dans l'ordre de ce qui est + * effectivement mis dans la queue. */ - if (signal != 0) + // Sémaphore acquis + + if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL) + { + return(-1); + } + + while((semaphore = sem_open(nom, 0)) == SEM_FAILED); + free(nom); + + while(sem_wait(semaphore) != 0) + { + if (errno != EINTR) + { + return(-1); + } + } + + if ((signal != 0) && (signal != SIGINT)) { if (queue_in(pid, signal) != 0) { + sem_post(semaphore); + sem_close(semaphore); return(-1); } } - return(kill(pid, signal)); + ios = kill(pid, signal); + + // Sémaphore relâché + + sem_post(semaphore); + sem_close(semaphore); + + return(ios); } int -rpl_pthread_kill(pthread_t tid, int signal) +pthread_kill_broken_siginfo(pthread_t tid, int signal) { - if (signal != 0) + int ios; + + sem_t *semaphore; + + unsigned char *nom; + + if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL) + { + return(-1); + } + + while((semaphore = sem_open(nom, 0)) == SEM_FAILED); + free(nom); + + while(sem_wait(semaphore) != 0) + { + if (errno != EINTR) + { + return(-1); + } + } + + if ((signal != 0) && (signal != SIGINT)) { if (queue_in(getpid(), signal) != 0) { + sem_post(semaphore); + sem_close(semaphore); return(-1); } } - return(pthread_kill(tid, signal)); + ios = pthread_kill(tid, signal); + + sem_post(semaphore); + sem_close(semaphore); + + return(ios); } #endif