--- rpl/src/interruptions.c 2010/04/30 15:01:14 1.13 +++ rpl/src/interruptions.c 2010/08/13 21:00:37 1.29 @@ -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 @@ -1657,6 +1733,10 @@ interruption1(int signal, siginfo_t *sig volatile sig_atomic_t exclusion = 0; +# ifdef _BROKEN_SIGINFO + (*siginfo).si_pid=getpid(); +# endif + verrouillage_gestionnaire_signaux(); switch(signal) @@ -1792,6 +1872,10 @@ interruption2(int signal, siginfo_t *sig pthread_t thread; struct_processus *s_etat_processus; +# ifdef _BROKEN_SIGINFO + (*siginfo).si_pid=getpid(); +# endif + verrouillage_gestionnaire_signaux(); if (siginfo == NULL) @@ -1865,6 +1949,10 @@ interruption3(int signal, siginfo_t *sig static int compteur = 0; +# ifdef _BROKEN_SIGINFO + (*siginfo).si_pid=getpid(); +# endif + verrouillage_gestionnaire_signaux(); if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) @@ -1923,6 +2011,10 @@ interruption4(int signal, siginfo_t *sig { struct_processus *s_etat_processus; +# ifdef _BROKEN_SIGINFO + (*siginfo).si_pid=getpid(); +# endif + verrouillage_gestionnaire_signaux(); if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) @@ -1952,6 +2044,10 @@ interruption5(int signal, siginfo_t *sig pthread_t thread; struct_processus *s_etat_processus; +# ifdef _BROKEN_SIGINFO + (*siginfo).si_pid=getpid(); +# endif + verrouillage_gestionnaire_signaux(); if ((*siginfo).si_pid == getpid()) @@ -1963,25 +2059,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 +2091,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) @@ -2033,6 +2110,10 @@ interruption6(int signal, siginfo_t *sig { struct_processus *s_etat_processus; +# ifdef _BROKEN_SIGINFO + (*siginfo).si_pid=getpid(); +# endif + verrouillage_gestionnaire_signaux(); if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) @@ -2057,6 +2138,10 @@ interruption7(int signal, siginfo_t *sig { struct_processus *s_etat_processus; +# ifdef _BROKEN_SIGINFO + (*siginfo).si_pid=getpid(); +# endif + verrouillage_gestionnaire_signaux(); if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) @@ -2085,6 +2170,10 @@ interruption8(int signal, siginfo_t *sig pthread_t thread; struct_processus *s_etat_processus; +# ifdef _BROKEN_SIGINFO + (*siginfo).si_pid=getpid(); +# endif + verrouillage_gestionnaire_signaux(); if ((*siginfo).si_pid == getpid()) @@ -2127,6 +2216,10 @@ interruption9(int signal, siginfo_t *sig { struct_processus *s_etat_processus; +# ifdef _BROKEN_SIGINFO + (*siginfo).si_pid=getpid(); +# endif + verrouillage_gestionnaire_signaux(); if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) @@ -2142,8 +2235,8 @@ interruption9(int signal, siginfo_t *sig fflush(stdout); } - pthread_kill((*s_etat_processus).tid_processus_pere, SIGFABORT); deverrouillage_gestionnaire_signaux(); + interruption11(signal, siginfo, context); return; } @@ -2156,6 +2249,10 @@ interruption10(int signal, siginfo_t *si unsigned char nom[8 + 64 + 1]; +# ifdef _BROKEN_SIGINFO + (*siginfo).si_pid=getpid(); +# endif + verrouillage_gestionnaire_signaux(); if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) @@ -2185,6 +2282,77 @@ interruption10(int signal, siginfo_t *si } deverrouillage_gestionnaire_signaux(); + return; +} + +void +interruption11(int signal, siginfo_t *siginfo, void *context) +{ + pthread_t thread; + struct_processus *s_etat_processus; + +# ifdef _BROKEN_SIGINFO + (*siginfo).si_pid=getpid(); +# endif + + verrouillage_gestionnaire_signaux(); + + if ((*siginfo).si_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; }