--- rpl/src/interruptions.c 2010/03/09 10:18:49 1.6 +++ rpl/src/interruptions.c 2011/06/27 09:05:01 1.56 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.0.13 - Copyright (C) 1989-2010 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.0 + Copyright (C) 1989-2011 Dr. BERTRAND Joël This file is part of RPL/2. @@ -20,7 +20,7 @@ */ -#include "rpl.conv.h" +#include "rpl-conv.h" /* @@ -82,22 +82,9 @@ insertion_thread(struct_processus *s_eta sigfillset(&set); pthread_sigmask(SIG_BLOCK, &set, &oldset); - while(sem_wait(&semaphore_liste_threads) == -1) - { - if (errno != EINTR) - { - pthread_sigmask(SIG_SETMASK, &oldset, NULL); - sigpending(&set); - - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } - } - if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile))) == NULL) { - sem_post(&semaphore_liste_threads); pthread_sigmask(SIG_SETMASK, &oldset, NULL); sigpending(&set); @@ -105,11 +92,8 @@ insertion_thread(struct_processus *s_eta return; } - (*l_nouvel_objet).suivant = liste_threads; - if (((*l_nouvel_objet).donnee = malloc(sizeof(struct_thread))) == NULL) { - sem_post(&semaphore_liste_threads); pthread_sigmask(SIG_SETMASK, &oldset, NULL); sigpending(&set); @@ -124,9 +108,30 @@ insertion_thread(struct_processus *s_eta (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus = s_etat_processus; +# ifndef SEMAPHORES_NOMMES + while(sem_wait(&semaphore_liste_threads) == -1) +# else + while(sem_wait(semaphore_liste_threads) == -1) +# endif + { + if (errno != EINTR) + { + pthread_sigmask(SIG_SETMASK, &oldset, NULL); + sigpending(&set); + + (*s_etat_processus).erreur_systeme = d_es_processus; + return; + } + } + + (*l_nouvel_objet).suivant = liste_threads; liste_threads = l_nouvel_objet; +# ifndef SEMAPHORES_NOMMES if (sem_post(&semaphore_liste_threads) != 0) +# else + if (sem_post(semaphore_liste_threads) != 0) +# endif { pthread_sigmask(SIG_SETMASK, &oldset, NULL); sigpending(&set); @@ -152,7 +157,21 @@ insertion_thread_surveillance(struct_pro sigfillset(&set); pthread_sigmask(SIG_BLOCK, &set, &oldset); + if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile))) + == NULL) + { + pthread_sigmask(SIG_SETMASK, &oldset, NULL); + sigpending(&set); + + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + +# ifndef SEMAPHORES_NOMMES while(sem_wait(&semaphore_liste_threads) == -1) +# else + while(sem_wait(semaphore_liste_threads) == -1) +# endif { if (errno != EINTR) { @@ -164,23 +183,20 @@ insertion_thread_surveillance(struct_pro } } - if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile))) - == NULL) - { - sem_post(&semaphore_liste_threads); - pthread_sigmask(SIG_SETMASK, &oldset, NULL); - sigpending(&set); - - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } + pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references)); + (*s_argument_thread).nombre_references++; + pthread_mutex_unlock(&((*s_argument_thread).mutex_nombre_references)); (*l_nouvel_objet).suivant = liste_threads_surveillance; (*l_nouvel_objet).donnee = (void *) s_argument_thread; liste_threads_surveillance = l_nouvel_objet; +# ifndef SEMAPHORES_NOMMES if (sem_post(&semaphore_liste_threads) != 0) +# else + if (sem_post(semaphore_liste_threads) != 0) +# endif { pthread_sigmask(SIG_SETMASK, &oldset, NULL); sigpending(&set); @@ -206,7 +222,11 @@ retrait_thread(struct_processus *s_etat_ sigfillset(&set); pthread_sigmask(SIG_BLOCK, &set, &oldset); +# ifndef SEMAPHORES_NOMMES while(sem_wait(&semaphore_liste_threads) == -1) +# else + while(sem_wait(semaphore_liste_threads) == -1) +# endif { if (errno != EINTR) { @@ -236,7 +256,11 @@ retrait_thread(struct_processus *s_etat_ if (l_element_courant == NULL) { +# ifndef SEMAPHORES_NOMMES sem_post(&semaphore_liste_threads); +# else + sem_post(semaphore_liste_threads); +# endif pthread_sigmask(SIG_SETMASK, &oldset, NULL); sigpending(&set); @@ -253,20 +277,25 @@ retrait_thread(struct_processus *s_etat_ (*l_element_precedent).suivant = (*l_element_courant).suivant; } - free((void *) (*l_element_courant).donnee); - free((struct_liste_chainee_volatile *) l_element_courant); - if (pthread_setspecific(semaphore_fork_processus_courant, NULL) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; +# ifndef SEMAPHORES_NOMMES sem_post(&semaphore_liste_threads); +# else + sem_post(semaphore_liste_threads); +# endif pthread_sigmask(SIG_SETMASK, &oldset, NULL); sigpending(&set); return; } +# ifndef SEMAPHORES_NOMMES if (sem_post(&semaphore_liste_threads) != 0) +# else + if (sem_post(semaphore_liste_threads) != 0) +# endif { (*s_etat_processus).erreur_systeme = d_es_processus; @@ -275,6 +304,9 @@ retrait_thread(struct_processus *s_etat_ return; } + free((void *) (*l_element_courant).donnee); + free((struct_liste_chainee_volatile *) l_element_courant); + pthread_sigmask(SIG_SETMASK, &oldset, NULL); sigpending(&set); return; @@ -293,7 +325,11 @@ retrait_thread_surveillance(struct_proce sigfillset(&set); pthread_sigmask(SIG_BLOCK, &set, &oldset); +# ifndef SEMAPHORES_NOMMES while(sem_wait(&semaphore_liste_threads) == -1) +# else + while(sem_wait(semaphore_liste_threads) == -1) +# endif { if (errno != EINTR) { @@ -321,7 +357,11 @@ retrait_thread_surveillance(struct_proce if (l_element_courant == NULL) { +# ifndef SEMAPHORES_NOMMES sem_post(&semaphore_liste_threads); +# else + sem_post(semaphore_liste_threads); +# endif pthread_sigmask(SIG_SETMASK, &oldset, NULL); sigpending(&set); @@ -338,10 +378,14 @@ retrait_thread_surveillance(struct_proce (*l_element_precedent).suivant = (*l_element_courant).suivant; } - free((struct_liste_chainee_volatile *) l_element_courant); - - if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0) + if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references)) + != 0) { +# ifndef SEMAPHORES_NOMMES + sem_post(&semaphore_liste_threads); +# else + sem_post(semaphore_liste_threads); +# endif pthread_sigmask(SIG_SETMASK, &oldset, NULL); sigpending(&set); @@ -357,8 +401,14 @@ retrait_thread_surveillance(struct_proce if ((*s_argument_thread).nombre_references == 0) { - if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0) + if (pthread_mutex_unlock(&((*s_argument_thread) + .mutex_nombre_references)) != 0) { +# ifndef SEMAPHORES_NOMMES + sem_post(&semaphore_liste_threads); +# else + sem_post(semaphore_liste_threads); +# endif pthread_sigmask(SIG_SETMASK, &oldset, NULL); sigpending(&set); @@ -367,12 +417,19 @@ retrait_thread_surveillance(struct_proce } pthread_mutex_destroy(&((*s_argument_thread).mutex)); + pthread_mutex_destroy(&((*s_argument_thread).mutex_nombre_references)); free(s_argument_thread); } else { - if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0) + if (pthread_mutex_unlock(&((*s_argument_thread) + .mutex_nombre_references)) != 0) { +# ifndef SEMAPHORES_NOMMES + sem_post(&semaphore_liste_threads); +# else + sem_post(semaphore_liste_threads); +# endif pthread_sigmask(SIG_SETMASK, &oldset, NULL); sigpending(&set); @@ -381,7 +438,11 @@ retrait_thread_surveillance(struct_proce } } +# ifndef SEMAPHORES_NOMMES if (sem_post(&semaphore_liste_threads) != 0) +# else + if (sem_post(semaphore_liste_threads) != 0) +# endif { pthread_sigmask(SIG_SETMASK, &oldset, NULL); sigpending(&set); @@ -390,8 +451,11 @@ retrait_thread_surveillance(struct_proce return; } + free((struct_liste_chainee_volatile *) l_element_courant); + pthread_sigmask(SIG_SETMASK, &oldset, NULL); sigpending(&set); + return; } @@ -400,7 +464,11 @@ verrouillage_threads_concurrents(struct_ { volatile struct_liste_chainee_volatile *l_element_courant; +# ifndef SEMAPHORES_NOMMES while(sem_wait(&semaphore_liste_threads) == -1) +# else + while(sem_wait(semaphore_liste_threads) == -1) +# endif { if (errno != EINTR) { @@ -417,8 +485,13 @@ verrouillage_threads_concurrents(struct_ == getpid()) && (pthread_equal((*((struct_thread *) (*l_element_courant).donnee)).tid, pthread_self()) == 0)) { +# ifndef SEMAPHORES_NOMMES while(sem_wait(&((*(*((struct_thread *) (*l_element_courant) .donnee)).s_etat_processus).semaphore_fork)) == -1) +# else + while(sem_wait((*(*((struct_thread *) (*l_element_courant) + .donnee)).s_etat_processus).semaphore_fork) == -1) +# endif { if (errno != EINTR) { @@ -447,15 +520,29 @@ deverrouillage_threads_concurrents(struc == getpid()) && (pthread_equal((*((struct_thread *) (*l_element_courant).donnee)).tid, pthread_self()) == 0)) { +# ifndef SEMAPHORES_NOMMES if (sem_post(&((*(*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus) .semaphore_fork)) != 0) +# else + if (sem_post((*(*((struct_thread *) + (*l_element_courant).donnee)).s_etat_processus) + .semaphore_fork) != 0) +# endif { +# ifndef SEMAPHORES_NOMMES if (sem_post(&semaphore_liste_threads) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } +# else + if (sem_post(semaphore_liste_threads) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return; + } +# endif (*s_etat_processus).erreur_systeme = d_es_processus; return; @@ -465,7 +552,11 @@ deverrouillage_threads_concurrents(struc l_element_courant = (*l_element_courant).suivant; } +# ifndef SEMAPHORES_NOMMES if (sem_post(&semaphore_liste_threads) != 0) +# else + if (sem_post(semaphore_liste_threads) != 0) +# endif { (*s_etat_processus).erreur_systeme = d_es_processus; return; @@ -498,7 +589,11 @@ liberation_threads(struct_processus *s_e sigfillset(&set); pthread_sigmask(SIG_BLOCK, &set, &oldset); +# ifndef SEMAPHORES_NOMMES while(sem_wait(&semaphore_liste_threads) == -1) +# else + while(sem_wait(semaphore_liste_threads) == -1) +# endif { if (errno != EINTR) { @@ -539,6 +634,8 @@ liberation_threads(struct_processus *s_e close((*s_etat_processus).pipe_nombre_objets_attente); close((*s_etat_processus).pipe_nombre_interruptions_attente); + liberation(s_etat_processus, (*s_etat_processus).at_exit); + if ((*s_etat_processus).nom_fichier_impression != NULL) { free((*s_etat_processus).nom_fichier_impression); @@ -580,18 +677,76 @@ 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_nombre_references)) != 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_nombre_references)) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + sem_post(&semaphore_liste_threads); + return; + } + + pthread_mutex_destroy(&((*s_argument_thread).mutex)); + pthread_mutex_destroy(&((*s_argument_thread) + .mutex_nombre_references)); + + 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_nombre_references)) != 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); @@ -648,25 +803,8 @@ liberation_threads(struct_processus *s_e } } - for(i = 0; i < (*s_etat_processus).nombre_variables; i++) - { - pthread_mutex_trylock(&((*(*s_etat_processus) - .s_liste_variables[i].objet).mutex)); - pthread_mutex_unlock(&((*(*s_etat_processus) - .s_liste_variables[i].objet).mutex)); - - // Les variables de niveau 0 sont des définitions qui - // ne sont pas copiées entre threads. - if ((*s_etat_processus).s_liste_variables[i].niveau > 0) - { - liberation(s_etat_processus, - (*s_etat_processus).s_liste_variables[i].objet); - } - - free((*s_etat_processus).s_liste_variables[i].nom); - } - - free((*s_etat_processus).s_liste_variables); + liberation_arbre_variables(s_etat_processus, + (*s_etat_processus).s_arbre_variables, d_faux); for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++) { @@ -1066,6 +1204,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) { @@ -1149,6 +1293,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) @@ -1163,8 +1310,13 @@ liberation_threads(struct_processus *s_e liberation_allocateur(s_etat_processus); +# ifndef SEMAPHORES_NOMMES sem_post(&((*s_etat_processus).semaphore_fork)); sem_destroy(&((*s_etat_processus).semaphore_fork)); +# else + sem_post((*s_etat_processus).semaphore_fork); + sem_destroy2((*s_etat_processus).semaphore_fork, sem_fork); +# endif free(s_etat_processus); @@ -1188,17 +1340,11 @@ 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) + if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references)) + != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; + sem_post(&semaphore_liste_threads); return; } @@ -1210,20 +1356,43 @@ liberation_threads(struct_processus *s_e if ((*s_argument_thread).nombre_references == 0) { - if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 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_nombre_references)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; + sem_post(&semaphore_liste_threads); return; } pthread_mutex_destroy(&((*s_argument_thread).mutex)); + pthread_mutex_destroy(&((*s_argument_thread) + .mutex_nombre_references)); + + 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) + if (pthread_mutex_unlock(&((*s_argument_thread) + .mutex_nombre_references)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; + sem_post(&semaphore_liste_threads); return; } } @@ -1235,7 +1404,11 @@ liberation_threads(struct_processus *s_e liste_threads_surveillance = NULL; +# ifndef SEMAPHORES_NOMMES if (sem_post(&semaphore_liste_threads) != 0) +# else + if (sem_post(semaphore_liste_threads) != 0) +# endif { pthread_sigmask(SIG_SETMASK, &oldset, NULL); (*s_etat_processus).erreur_systeme = d_es_processus; @@ -1330,7 +1503,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 @@ -1358,7 +1531,11 @@ verrouillage_gestionnaire_signaux() sigfillset(&set); pthread_sigmask(SIG_BLOCK, &set, &oldset); +# ifndef SEMAPHORES_NOMMES while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1) +# else + while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1) +# endif { if (errno != EINTR) { @@ -1368,21 +1545,33 @@ verrouillage_gestionnaire_signaux() } } +# ifndef SEMAPHORES_NOMMES if (sem_post(&semaphore_gestionnaires_signaux) == -1) +# else + if (sem_post(semaphore_gestionnaires_signaux) == -1) +# endif { pthread_sigmask(SIG_SETMASK, &oldset, NULL); BUG(1, uprintf("Lock error !\n")); return; } +# ifndef SEMAPHORES_NOMMES if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0) +# else + if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0) +# endif { pthread_sigmask(SIG_SETMASK, &oldset, NULL); BUG(1, uprintf("Lock error !\n")); return; } +# ifndef SEMAPHORES_NOMMES if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0) +# else + if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0) +# endif { pthread_sigmask(SIG_SETMASK, &oldset, NULL); BUG(1, uprintf("Unlock error !\n")); @@ -1397,9 +1586,13 @@ verrouillage_gestionnaire_signaux() // par un thread concurrent. On essaye donc de le bloquer jusqu'à // ce que ce soit possible. - while(sem_trywait(&semaphore_liste_threads) == -1) +# ifndef SEMAPHORES_NOMMES + while(sem_wait(&semaphore_liste_threads) == -1) +# else + while(sem_wait(semaphore_liste_threads) == -1) +# endif { - if ((errno != EINTR) && (errno != EAGAIN)) + if (errno != EINTR) { pthread_sigmask(SIG_SETMASK, &oldset, NULL); @@ -1415,8 +1608,6 @@ verrouillage_gestionnaire_signaux() BUG(1, uprintf("Lock error !\n")); return; } - - sched_yield(); } } @@ -1441,7 +1632,11 @@ deverrouillage_gestionnaire_signaux() sigfillset(&set); pthread_sigmask(SIG_BLOCK, &set, &oldset); +# ifndef SEMAPHORES_NOMMES while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1) +# else + while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1) +# endif { if (errno != EINTR) { @@ -1451,14 +1646,22 @@ deverrouillage_gestionnaire_signaux() } } +# ifndef SEMAPHORES_NOMMES if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0) +# else + if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0) +# endif { pthread_sigmask(SIG_SETMASK, &oldset, NULL); BUG(1, uprintf("Unlock error !\n")); return; } +# ifndef SEMAPHORES_NOMMES while(sem_wait(&semaphore_gestionnaires_signaux) == -1) +# else + while(sem_wait(semaphore_gestionnaires_signaux) == -1) +# endif { if (errno != EINTR) { @@ -1468,7 +1671,11 @@ deverrouillage_gestionnaire_signaux() } } +# ifndef SEMAPHORES_NOMMES if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0) +# else + if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0) +# endif { pthread_sigmask(SIG_SETMASK, &oldset, NULL); BUG(1, uprintf("Unlock error !\n")); @@ -1491,7 +1698,11 @@ deverrouillage_gestionnaire_signaux() if (semaphore == 1) { +# ifndef SEMAPHORES_NOMMES if (sem_post(&semaphore_liste_threads) != 0) +# else + if (sem_post(semaphore_liste_threads) != 0) +# endif { pthread_sigmask(SIG_SETMASK, &oldset, NULL); @@ -1507,8 +1718,10 @@ deverrouillage_gestionnaire_signaux() } void -interruption1(int signal, siginfo_t *siginfo, void *context) +interruption1(SIGHANDLER_ARGS) { + pid_t pid; + pthread_t thread; struct_processus *s_etat_processus; @@ -1517,17 +1730,40 @@ interruption1(int signal, siginfo_t *sig verrouillage_gestionnaire_signaux(); +# ifdef _BROKEN_SIGINFO + if ((signal == SIGINT) || (signal == SIGTERM)) + { + // Si l'interruption provient du clavier, il n'y a pas eu d'appel + // à queue_in(). + + pid = getpid(); + } + else + { + pid = origine_signal(signal); + } +# else + if (siginfo != NULL) + { + pid = (*siginfo).si_pid; + } + else + { + pid = getpid(); + } +# endif + 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) @@ -1559,6 +1795,7 @@ interruption1(int signal, siginfo_t *sig } case SIGINT : + case SIGTERM : { /* * Une vieille spécification POSIX permet au pointeur siginfo @@ -1566,11 +1803,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) @@ -1581,8 +1821,17 @@ interruption1(int signal, siginfo_t *sig if (((*s_etat_processus).type_debug & d_debug_signaux) != 0) { - printf("[%d] SIGINT (thread %llu)\n", (int) getpid(), - (unsigned long long) pthread_self()); + if (signal == SIGINT) + { + printf("[%d] SIGINT (thread %llu)\n", (int) getpid(), + (unsigned long long) pthread_self()); + } + else + { + printf("[%d] SIGTERM (thread %llu)\n", (int) getpid(), + (unsigned long long) pthread_self()); + } + fflush(stdout); } @@ -1604,16 +1853,19 @@ interruption1(int signal, siginfo_t *sig return; } - if (strncmp(getenv("LANG"), "fr", 2) == 0) - { - printf("+++Interruption\n"); - } - else + if (signal == SIGINT) { - printf("+++Interrupt\n"); - } + if (strncmp(getenv("LANG"), "fr", 2) == 0) + { + printf("+++Interruption\n"); + } + else + { + printf("+++Interrupt\n"); + } - fflush(stdout); + fflush(stdout); + } (*s_etat_processus).var_volatile_requete_arret = -1; (*s_etat_processus).var_volatile_alarme = -1; @@ -1645,13 +1897,30 @@ 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; verrouillage_gestionnaire_signaux(); +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + if (siginfo != NULL) + { + pid = (*siginfo).si_pid; + } + else + { + pid = getpid(); + } +# endif + +# ifndef _BROKEN_SIGINFO if (siginfo == NULL) { /* @@ -1669,7 +1938,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) @@ -1717,14 +1988,22 @@ 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; verrouillage_gestionnaire_signaux(); +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + pid = (*siginfo).si_pid; +# endif + if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) { deverrouillage_gestionnaire_signaux(); @@ -1777,12 +2056,20 @@ 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; verrouillage_gestionnaire_signaux(); +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + pid = (*siginfo).si_pid; +# endif + if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) { deverrouillage_gestionnaire_signaux(); @@ -1805,14 +2092,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; verrouillage_gestionnaire_signaux(); - if ((*siginfo).si_pid == getpid()) +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + pid = (*siginfo).si_pid; +# endif + + if (pid == getpid()) { if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) @@ -1846,11 +2142,18 @@ interruption5(int signal, siginfo_t *sig } else { + if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) + == NULL) + { + deverrouillage_gestionnaire_signaux(); + return; + } + // Envoi d'un signal au thread maître du groupe. if (recherche_thread_principal(getpid(), &thread) == d_vrai) { - pthread_kill(thread, SIGFSTOP); + pthread_kill(thread, signal); deverrouillage_gestionnaire_signaux(); return; } @@ -1861,12 +2164,20 @@ 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; verrouillage_gestionnaire_signaux(); +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + pid = (*siginfo).si_pid; +# endif + if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) { deverrouillage_gestionnaire_signaux(); @@ -1885,12 +2196,20 @@ 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; verrouillage_gestionnaire_signaux(); +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + pid = (*siginfo).si_pid; +# endif + if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) { deverrouillage_gestionnaire_signaux(); @@ -1912,14 +2231,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; verrouillage_gestionnaire_signaux(); - if ((*siginfo).si_pid == getpid()) +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + pid = (*siginfo).si_pid; +# endif + + if (pid == getpid()) { if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) @@ -1955,12 +2283,20 @@ 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; verrouillage_gestionnaire_signaux(); +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + pid = (*siginfo).si_pid; +# endif + if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) { deverrouillage_gestionnaire_signaux(); @@ -1974,22 +2310,40 @@ interruption9(int signal, siginfo_t *sig fflush(stdout); } - pthread_kill((*s_etat_processus).tid_processus_pere, SIGFSTOP); +# 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; } 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]; verrouillage_gestionnaire_signaux(); +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + pid = (*siginfo).si_pid; +# endif + if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) { deverrouillage_gestionnaire_signaux(); @@ -2017,6 +2371,82 @@ interruption10(int signal, siginfo_t *si } deverrouillage_gestionnaire_signaux(); + return; +} + +void +interruption11(SIGHANDLER_ARGS) +{ + pid_t pid; + + pthread_t thread; + + struct_processus *s_etat_processus; + + verrouillage_gestionnaire_signaux(); + +# ifdef _BROKEN_SIGINFO + pid = origine_signal(signal); +# else + pid = (*siginfo).si_pid; +# endif + + 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; }