--- rpl/src/instructions_d5.c 2010/05/25 18:09:44 1.23 +++ rpl/src/instructions_d5.c 2011/09/14 17:55:59 1.68 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.0.16 - Copyright (C) 1989-2010 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.3 + 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" /* @@ -814,8 +814,6 @@ instruction_der(struct_processus *s_etat void instruction_detach(struct_processus *s_etat_processus) { - int status; - logical1 drapeau; logical1 variable_partagee; @@ -831,13 +829,12 @@ instruction_detach(struct_processus *s_e sig_atomic_t registre_stop; sigset_t oldset; - sigset_t oldset2; sigset_t set; - sigset_t set2; ssize_t longueur_ecriture; struct_descripteur_thread *s_argument_thread; + struct_descripteur_thread *s_argument_thread2; struct_liste_chainee *l_element_courant; struct_liste_chainee *l_element_precedent; @@ -930,8 +927,7 @@ instruction_detach(struct_processus *s_e if (recherche_variable(s_etat_processus, (*((struct_nom *) (*s_objet).objet)).nom) == d_vrai) { - if ((*s_etat_processus).s_liste_variables - [(*s_etat_processus).position_variable_courante].objet + if ((*(*s_etat_processus).pointeur_variable_courante).objet == NULL) { if (pthread_mutex_lock(&((*(*s_etat_processus) @@ -942,13 +938,10 @@ instruction_detach(struct_processus *s_e } if (recherche_variable_partagee(s_etat_processus, - (*s_etat_processus).s_liste_variables - [(*s_etat_processus).position_variable_courante].nom, - (*s_etat_processus).s_liste_variables - [(*s_etat_processus).position_variable_courante] - .variable_partagee, (*s_etat_processus) - .s_liste_variables[(*s_etat_processus) - .position_variable_courante].origine) == d_faux) + (*(*s_etat_processus).pointeur_variable_courante).nom, + (*(*s_etat_processus).pointeur_variable_courante) + .variable_partagee, (*(*s_etat_processus) + .pointeur_variable_courante).origine) == d_faux) { if (pthread_mutex_unlock(&((*(*s_etat_processus) .s_liste_variables_partagees).mutex)) != 0) @@ -1016,11 +1009,9 @@ instruction_detach(struct_processus *s_e } else { - if (((*(*s_etat_processus).s_liste_variables - [(*s_etat_processus).position_variable_courante].objet) - .type != RPN) && ((*(*s_etat_processus) - .s_liste_variables[(*s_etat_processus) - .position_variable_courante].objet).type != ADR)) + if (((*(*(*s_etat_processus).pointeur_variable_courante).objet) + .type != RPN) && ((*(*(*s_etat_processus) + .pointeur_variable_courante).objet).type != ADR)) { liberation(s_etat_processus, s_objet); @@ -1040,46 +1031,6 @@ instruction_detach(struct_processus *s_e } } - if (sigemptyset(&set) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } - - if (sigaddset(&set, SIGSTART) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } - - /* - * Le signal SIGFSTOP doit être traité ! - */ - - if (sigaddset(&set, SIGFSTOP) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } - - if (sigaddset(&set, SIGFABORT) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } - - if (sigaddset(&set, SIGURG) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } - - if (pthread_sigmask(SIG_BLOCK, &set, &oldset) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } - if ((s_argument_thread = malloc(sizeof(struct_descripteur_thread))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_processus; @@ -1153,15 +1104,13 @@ instruction_detach(struct_processus *s_e * de mémoire, ni libération, ni copie d'objet concurrent au fork(). */ - sigfillset(&set2); - pthread_sigmask(SIG_BLOCK, &set2, &oldset2); - + sigfillset(&set); + pthread_sigmask(SIG_BLOCK, &set, &oldset); verrouillage_threads_concurrents(s_etat_processus); (*s_argument_thread).pid = fork(); deverrouillage_threads_concurrents(s_etat_processus); - - pthread_sigmask(SIG_SETMASK, &oldset2, NULL); - sigpending(&set2); + pthread_sigmask(SIG_SETMASK, &oldset, NULL); + sigpending(&set); (*s_argument_thread).thread_pere = pthread_self(); (*s_argument_thread).processus_detache = d_vrai; @@ -1171,6 +1120,12 @@ instruction_detach(struct_processus *s_e pthread_mutex_init(&((*s_argument_thread).mutex), &attributs_mutex); pthread_mutexattr_destroy(&attributs_mutex); + pthread_mutexattr_init(&attributs_mutex); + pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&((*s_argument_thread).mutex_nombre_references), + &attributs_mutex); + pthread_mutexattr_destroy(&attributs_mutex); + if ((*s_argument_thread).pid > 0) { /* @@ -1182,15 +1137,33 @@ instruction_detach(struct_processus *s_e liberation(s_etat_processus, s_copie); } - if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) + liberation(s_etat_processus, s_objet); + + if ((s_objet = allocation(s_etat_processus, PRC)) == NULL) { - (*s_etat_processus).erreur_systeme = d_es_processus; + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } - if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) + (*((struct_processus_fils *) (*s_objet).objet)).thread = + s_argument_thread; + (*(*((struct_processus_fils *) (*s_objet).objet)).thread) + .nombre_objets_dans_pipe = 0; + (*(*((struct_processus_fils *) (*s_objet).objet)).thread) + .nombre_interruptions_dans_pipe = 0; + (*(*((struct_processus_fils *) (*s_objet).objet)).thread) + .nombre_references = 1; + + /* + * On copie l'objet plutôt que le pointeur car cet objet peut être + * accédé depuis deux threads distincts et aboutir à un blocage lors + * d'une copie. + */ + + if ((s_objet_systeme = copie_objet(s_etat_processus, s_objet, 'O')) + == NULL) { - (*s_etat_processus).erreur_systeme = d_es_processus; + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } @@ -1256,6 +1229,8 @@ instruction_detach(struct_processus *s_e return; } +# ifndef OS2 +# ifndef Cygwin if (pthread_attr_setschedpolicy(&attributs, SCHED_OTHER) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; @@ -1274,28 +1249,18 @@ instruction_detach(struct_processus *s_e (*s_etat_processus).erreur_systeme = d_es_processus; return; } +# endif +# endif (*s_argument_thread).s_etat_processus = s_etat_processus; -# ifdef DEBUG_MEMOIRE - debug_memoire_verrouillage(); -# endif - if (pthread_create(&thread_surveillance, &attributs, surveillance_processus, s_argument_thread) != 0) { -# ifdef DEBUG_MEMOIRE - debug_memoire_deverrouillage(); -# endif - (*s_etat_processus).erreur_systeme = d_es_processus; return; } -# ifdef DEBUG_MEMOIRE - debug_memoire_deverrouillage(); -# endif - if (pthread_attr_destroy(&attributs) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; @@ -1308,63 +1273,28 @@ instruction_detach(struct_processus *s_e * Processus fils */ -# ifndef SEMAPHORES_NOMMES - sem_post(&semaphore_gestionnaires_signaux); - sem_destroy(&semaphore_gestionnaires_signaux); - sem_init(&semaphore_gestionnaires_signaux, 0, 0); -# else - sem_post(semaphore_gestionnaires_signaux); - sem_destroy2(semaphore_gestionnaires_signaux, - sem_gestionnaires_signaux); + liberation_queue_signaux(s_etat_processus); + creation_queue_signaux(s_etat_processus); - if ((semaphore_gestionnaires_signaux = sem_init2(0, - sem_gestionnaires_signaux)) == SEM_FAILED) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - } -# endif - -# ifndef SEMAPHORES_NOMMES - sem_post(&semaphore_liste_threads); - sem_destroy(&semaphore_liste_threads); - sem_init(&semaphore_liste_threads, 0, 1); -# else - sem_post(semaphore_liste_threads); - sem_destroy2(semaphore_liste_threads, sem_liste_threads); + (*s_etat_processus).pointeur_signal_lecture = 0; + (*s_etat_processus).pointeur_signal_ecriture = 0; - if ((semaphore_liste_threads = sem_init2(1, - sem_liste_threads)) == SEM_FAILED) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - } -# endif - -# ifndef SEMAPHORES_NOMMES - sem_destroy(&semaphore_gestionnaires_signaux_atomique); - sem_init(&semaphore_gestionnaires_signaux_atomique, 0, 1); - sem_trywait(&((*s_etat_processus).semaphore_fork)); -# else - sem_destroy2(semaphore_gestionnaires_signaux_atomique, - sem_gestionnaires_signaux_atomique); - - if ((semaphore_gestionnaires_signaux_atomique = sem_init2(1, - sem_gestionnaires_signaux_atomique)) == SEM_FAILED) + if ((*s_etat_processus).debug == d_vrai) + if (((*s_etat_processus).type_debug & + d_debug_processus) != 0) { - (*s_etat_processus).erreur_systeme = d_es_processus; - } - - sem_trywait((*s_etat_processus).semaphore_fork); -# endif + if ((*s_etat_processus).langue == 'F') + { + printf("[%d] Lancement du processus fils %d de %d\n", + (int) getpid(), (int) getpid(), (int) ppid); + } + else + { + printf("[%d] Start child process %d from %d\n", (int) getpid(), + (int) getpid(), (int) ppid); + } -# ifndef SEMAPHORES_NOMMES - if (pthread_setspecific(semaphore_fork_processus_courant, - &((*s_etat_processus).semaphore_fork)) != 0) -# else - if (pthread_setspecific(semaphore_fork_processus_courant, - (*s_etat_processus).semaphore_fork) != 0) -# endif - { - (*s_etat_processus).erreur_systeme = d_es_processus; + fflush(stdout); } if (close((*s_argument_thread).pipe_erreurs[0]) != 0) @@ -1401,6 +1331,23 @@ instruction_detach(struct_processus *s_e (*s_etat_processus).erreur_systeme = d_es_processus; } + if ((*s_etat_processus).debug == d_vrai) + if (((*s_etat_processus).type_debug & + d_debug_processus) != 0) + { + if ((*s_etat_processus).langue == 'F') + { + printf("[%d] Libération des objets du processus père\n", + (int) getpid()); + } + else + { + printf("[%d] Freeing parent process memory\n", getpid()); + } + + fflush(stdout); + } + l_element_courant = (*s_etat_processus).liste_mutexes; while(l_element_courant != NULL) { @@ -1462,6 +1409,8 @@ instruction_detach(struct_processus *s_e } } + destruction_queue_signaux(s_etat_processus); + BUG(1, uprintf("Process management error line %d\n", __LINE__)); exit(EXIT_FAILURE); } @@ -1491,9 +1440,13 @@ instruction_detach(struct_processus *s_e } } + destruction_queue_signaux(s_etat_processus); + BUG(1, uprintf("Process management error line %d\n", __LINE__)); exit(EXIT_FAILURE); } + pthread_mutex_trylock(&((*s_etat_processus).protection_liste_mutexes)); + if (pthread_mutex_unlock(&((*s_etat_processus) .protection_liste_mutexes)) != 0) { @@ -1521,6 +1474,8 @@ instruction_detach(struct_processus *s_e } } + destruction_queue_signaux(s_etat_processus); + BUG(1, uprintf("Process management error line %d\n", __LINE__)); exit(EXIT_FAILURE); } @@ -1531,6 +1486,7 @@ instruction_detach(struct_processus *s_e } (*s_etat_processus).var_volatile_processus_pere = 0; + (*s_etat_processus).var_volatile_processus_racine = 0; // On réinitialise toutes les interruptions. @@ -1542,6 +1498,9 @@ instruction_detach(struct_processus *s_e liberation(s_etat_processus, (*s_etat_processus).at_exit); (*s_etat_processus).at_exit = NULL; + liberation(s_etat_processus, (*s_etat_processus).at_poke); + (*s_etat_processus).at_poke = NULL; + (*s_etat_processus).traitement_at_poke = 'N'; for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++) { @@ -1566,24 +1525,6 @@ instruction_detach(struct_processus *s_e (*s_etat_processus).pile_origine_interruptions[i] = NULL; } - if ((*s_etat_processus).debug == d_vrai) - if (((*s_etat_processus).type_debug & - d_debug_processus) != 0) - { - if ((*s_etat_processus).langue == 'F') - { - printf("[%d] Lancement du processus fils %d de %d\n", - (int) getpid(), (int) getpid(), (int) ppid); - } - else - { - printf("[%d] Start child process %d from %d\n", (int) getpid(), - (int) getpid(), (int) ppid); - } - - fflush(stdout); - } - /* * On bloque l'exécution du processus fils jusqu'à ce que * le père ait renseigné correctement la pile des processus. @@ -1592,21 +1533,18 @@ instruction_detach(struct_processus *s_e * renseignée. */ - if (sigpending(&set) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - } - else if (sigismember(&set, SIGSTART) == 0) + // Attente de la réception du signal rpl_sigstart. + + for((*s_etat_processus).demarrage_fils = d_faux;;) { - while(sigismember(&set, SIGSTART) == 0) - { - if (sigpending(&set) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - } + scrutation_interruptions(s_etat_processus); - nanosleep(&attente, NULL); + if ((*s_etat_processus).demarrage_fils == d_vrai) + { + break; } + + nanosleep(&attente, NULL); } (*s_etat_processus).niveau_initial = (*s_etat_processus).niveau_courant; @@ -1653,11 +1591,121 @@ instruction_detach(struct_processus *s_e } /* - * Initialisation de la pile des processus + * Initialisation de la pile des processus. Cette pile est effacée + * par liberation_threads(). */ + if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0) + { + (*s_etat_processus).erreur_systeme = d_es; + + pid_final = -2; + + while((longueur_ecriture = write_atomic(s_etat_processus, + (*s_argument_thread).pipe_nombre_interruptions_attente[1], + &pid_final, sizeof(pid_final))) != sizeof(pid_final)) + { + if (longueur_ecriture == -1) + { + break; + } + } + + while((longueur_ecriture = write_atomic(s_etat_processus, + (*s_argument_thread).pipe_nombre_objets_attente[1], + &pid_final, sizeof(pid_final))) != sizeof(pid_final)) + { + if (longueur_ecriture == -1) + { + break; + } + } + + destruction_queue_signaux(s_etat_processus); + BUG(1, uprintf("Process management error line %d\n", __LINE__)); + exit(EXIT_FAILURE); + } + + l_element_courant = (struct_liste_chainee *) + (*s_etat_processus).l_base_pile_processus; + + while(l_element_courant != NULL) + { + s_argument_thread2 = (struct_descripteur_thread *) + (*((struct_processus_fils *) (*(*l_element_courant).donnee) + .objet)).thread; + + (*s_argument_thread2).nombre_references--; + + BUG((*s_argument_thread2).nombre_references < 0, + destruction_queue_signaux(s_etat_processus), + printf("(*s_argument_thread2).nombre_references = %d\n", + (int) (*s_argument_thread2).nombre_references)); + + if ((*s_argument_thread2).nombre_references == 0) + { + close((*s_argument_thread2).pipe_objets[0]); + close((*s_argument_thread2).pipe_acquittement[1]); + close((*s_argument_thread2).pipe_injections[1]); + close((*s_argument_thread2).pipe_nombre_injections[1]); + close((*s_argument_thread2).pipe_nombre_objets_attente[0]); + close((*s_argument_thread2).pipe_interruptions[0]); + close((*s_argument_thread2) + .pipe_nombre_interruptions_attente[0]); + + pthread_mutex_destroy(&((*s_argument_thread2).mutex)); + + if ((*s_argument_thread2).processus_detache == d_faux) + { + if ((*s_argument_thread2).destruction_objet == d_vrai) + { + liberation(s_etat_processus, + (*s_argument_thread2).argument); + } + } + + free(s_argument_thread2); + free((*(*l_element_courant).donnee).objet); + free((*l_element_courant).donnee); + } + + l_element_suivant = (*l_element_courant).suivant; + free((struct_liste_chainee *) l_element_courant); + l_element_courant = l_element_suivant; + } + (*s_etat_processus).l_base_pile_processus = NULL; - // Les données associées sont déjà effacées par liberation_thread(). + + if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) + { + (*s_etat_processus).erreur_systeme = d_es; + + pid_final = -2; + + while((longueur_ecriture = write_atomic(s_etat_processus, + (*s_argument_thread).pipe_nombre_interruptions_attente[1], + &pid_final, sizeof(pid_final))) != sizeof(pid_final)) + { + if (longueur_ecriture == -1) + { + break; + } + } + + while((longueur_ecriture = write_atomic(s_etat_processus, + (*s_argument_thread).pipe_nombre_objets_attente[1], + &pid_final, sizeof(pid_final))) != sizeof(pid_final)) + { + if (longueur_ecriture == -1) + { + break; + } + } + + destruction_queue_signaux(s_etat_processus); + BUG(1, uprintf("Process management error line %d\n", __LINE__)); + exit(EXIT_FAILURE); + } /* * Initialisation de la pile système @@ -1719,6 +1767,8 @@ instruction_detach(struct_processus *s_e } } + destruction_queue_signaux(s_etat_processus); + BUG(1, uprintf("Process management error line %d\n", __LINE__)); exit(EXIT_FAILURE); } @@ -1770,6 +1820,8 @@ instruction_detach(struct_processus *s_e } } + destruction_queue_signaux(s_etat_processus); + BUG(1, uprintf("Process management error line %d\n", __LINE__)); exit(EXIT_FAILURE); } @@ -1847,6 +1899,7 @@ instruction_detach(struct_processus *s_e À noter : on ne ferme pas la connexion car la conséquence immédiate est une destruction de l'objet pour le processus père. ================================================================================ +*/ l_element_courant = (*s_etat_processus).s_connecteurs_sql; @@ -1854,11 +1907,10 @@ instruction_detach(struct_processus *s_e { l_element_suivant = (*l_element_courant).suivant; - sqlclose((*l_element_courant).donnee); +// sqlclose((*l_element_courant).donnee); liberation(s_etat_processus, (*l_element_courant).donnee); l_element_courant = l_element_suivant; } -*/ (*s_etat_processus).s_connecteurs_sql = NULL; @@ -1869,74 +1921,89 @@ instruction_detach(struct_processus *s_e (*s_etat_processus).s_fichiers = NULL; - if (pthread_sigmask(SIG_SETMASK, &oldset, NULL) != 0) + if ((*s_etat_processus).debug == d_vrai) { - (*s_etat_processus).erreur_systeme = d_es_processus; + if (((*s_etat_processus).type_debug & d_debug_processus) + != 0) + { + if ((*s_etat_processus).langue == 'F') + { + printf("[%d] Évaluation de l'objet détaché\n", getpid()); + } + else + { + printf("[%d] Évaluation of detached object\n", getpid()); + } + } } - sigpending(&set); - if ((*s_etat_processus).erreur_systeme == d_es) { - if (variable_partagee == d_faux) + if (setjmp(contexte_processus) == 0) { - if (evaluation(s_etat_processus, s_objet, 'E') == d_erreur) - { - if (((*s_etat_processus).erreur_execution == d_ex) && - ((*s_etat_processus).erreur_systeme == d_es)) - { - (*s_etat_processus).erreur_execution = - d_ex_erreur_evaluation; - } - } - else + if (variable_partagee == d_faux) { - if (((*s_etat_processus).var_volatile_alarme == 0) - && ((*s_etat_processus).arret_depuis_abort == 0) - && ((*s_etat_processus).at_exit != NULL)) + if (evaluation(s_etat_processus, s_objet, 'E') == d_erreur) { - (*s_etat_processus).var_volatile_requete_arret = 0; - - if (evaluation(s_etat_processus, - (*s_etat_processus).at_exit, 'E') == d_erreur) + if (((*s_etat_processus).erreur_execution == d_ex) && + ((*s_etat_processus).erreur_systeme == d_es)) { (*s_etat_processus).erreur_execution = d_ex_erreur_evaluation; } } - } - } - else - { - if (evaluation(s_etat_processus, s_copie, 'E') == d_erreur) - { - if (((*s_etat_processus).erreur_execution == d_ex) && - ((*s_etat_processus).erreur_systeme == d_es)) + else { - (*s_etat_processus).erreur_execution = - d_ex_erreur_evaluation; + if (((*s_etat_processus).var_volatile_alarme == 0) + && ((*s_etat_processus).arret_depuis_abort == 0) + && ((*s_etat_processus).at_exit != NULL)) + { + (*s_etat_processus).var_volatile_requete_arret = 0; + + if (evaluation(s_etat_processus, + (*s_etat_processus).at_exit, 'E') == + d_erreur) + { + (*s_etat_processus).erreur_execution = + d_ex_erreur_evaluation; + } + } } } else { - if ((*s_etat_processus).at_exit != NULL) + if (evaluation(s_etat_processus, s_copie, 'E') == d_erreur) { - (*s_etat_processus).var_volatile_requete_arret = 0; - - if (evaluation(s_etat_processus, - (*s_etat_processus).at_exit, 'E') == d_erreur) + if (((*s_etat_processus).erreur_execution == d_ex) && + ((*s_etat_processus).erreur_systeme == d_es)) { (*s_etat_processus).erreur_execution = d_ex_erreur_evaluation; } } - } + else + { + if ((*s_etat_processus).at_exit != NULL) + { + (*s_etat_processus).var_volatile_requete_arret = 0; - liberation(s_etat_processus, s_copie); + if (evaluation(s_etat_processus, + (*s_etat_processus).at_exit, 'E') == + d_erreur) + { + (*s_etat_processus).erreur_execution = + d_ex_erreur_evaluation; + } + } + } + + liberation(s_etat_processus, s_copie); + } } } liberation(s_etat_processus, (*s_etat_processus).at_exit); + liberation(s_etat_processus, (*s_etat_processus).at_poke); l_element_courant = (*s_etat_processus).liste_mutexes; while(l_element_courant != NULL) @@ -2158,23 +2225,23 @@ instruction_detach(struct_processus *s_e if ((*s_etat_processus).var_volatile_alarme != 0) { - kill((*(*((struct_processus_fils *) + envoi_signal_processus((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread).pid, - SIGURG); + rpl_sigurg); } else { if ((*s_etat_processus).arret_depuis_abort == -1) { - kill((*(*((struct_processus_fils *) + envoi_signal_processus((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread) - .pid, SIGFABORT); + .pid, rpl_sigabort); } else { - kill((*(*((struct_processus_fils *) + envoi_signal_processus((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread) - .pid, SIGFSTOP); + .pid, rpl_sigstop); } } } @@ -2216,23 +2283,23 @@ instruction_detach(struct_processus *s_e { if ((*s_etat_processus).var_volatile_alarme != 0) { - pthread_kill((*(*((struct_processus_fils *) + envoi_signal_thread((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)).thread) - .tid, SIGURG); + .tid, rpl_sigurg); } else { if ((*s_etat_processus).arret_depuis_abort == -1) { - pthread_kill((*(*((struct_processus_fils *) + envoi_signal_thread((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) - .thread).tid, SIGFABORT); + .thread).tid, rpl_sigabort); } else { - pthread_kill((*(*((struct_processus_fils *) + envoi_signal_thread((*(*((struct_processus_fils *) (*(*l_element_courant).donnee).objet)) - .thread).tid, SIGFSTOP); + .thread).tid, rpl_sigstop); } } } @@ -2256,8 +2323,6 @@ instruction_detach(struct_processus *s_e while((*s_etat_processus).l_base_pile_processus != NULL) { - status = 0; - l_element_courant = (struct_liste_chainee *) (*s_etat_processus).l_base_pile_processus; @@ -2300,6 +2365,7 @@ instruction_detach(struct_processus *s_e registre_stop; } + destruction_queue_signaux(s_etat_processus); (*s_etat_processus).erreur_systeme = d_es_signal; exit(EXIT_FAILURE); } @@ -2334,8 +2400,9 @@ instruction_detach(struct_processus *s_e if (sigaction(SIGPIPE, ®istre, NULL) != 0) { - pthread_mutex_unlock(&((*s_etat_processus).mutex)); + destruction_queue_signaux(s_etat_processus); + pthread_mutex_unlock(&((*s_etat_processus).mutex)); (*s_etat_processus).erreur_systeme = d_es_signal; exit(EXIT_FAILURE); } @@ -2475,14 +2542,9 @@ instruction_detach(struct_processus *s_e (*s_etat_processus).instruction_derniere_erreur = NULL; } - for(i = 0; i < (*s_etat_processus).nombre_variables; i++) - { - 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_vrai); + free((*s_etat_processus).pointeurs_caracteres_variables); for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++) { @@ -2650,12 +2712,6 @@ instruction_detach(struct_processus *s_e liberation(s_etat_processus, s_objet); -# ifndef Cygwin - (*s_etat_processus).pile_signal.ss_flags = SS_DISABLE; - sigaltstack(&((*s_etat_processus).pile_signal), NULL); - free((*s_etat_processus).pile_signal.ss_sp); -# endif - free((*s_etat_processus).definitions_chainees); free((*s_etat_processus).nom_fichier_historique); @@ -2695,37 +2751,19 @@ instruction_detach(struct_processus *s_e retrait_thread(s_etat_processus); pthread_mutex_destroy(&((*s_etat_processus).mutex)); + pthread_mutex_destroy(&((*s_etat_processus).mutex_allocation)); pthread_mutex_destroy(&((*s_etat_processus).protection_liste_mutexes)); - pthread_key_delete(semaphore_fork_processus_courant); - -# 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 + pthread_mutex_unlock(&((*s_etat_processus).mutex_fork)); + pthread_mutex_destroy(&((*s_etat_processus).mutex_fork)); free((*s_etat_processus).localisation); free(s_argument_thread); -# ifndef SEMAPHORES_NOMMES - sem_destroy(&semaphore_liste_threads); - sem_post(&semaphore_gestionnaires_signaux); - sem_destroy(&semaphore_gestionnaires_signaux); - sem_destroy(&semaphore_gestionnaires_signaux_atomique); -# else - sem_destroy2(semaphore_liste_threads, sem_liste_threads); - sem_post(semaphore_gestionnaires_signaux); - sem_destroy2(semaphore_gestionnaires_signaux, - sem_gestionnaires_signaux); - sem_destroy2(semaphore_gestionnaires_signaux_atomique, - sem_gestionnaires_signaux_atomique); -# endif - clear_history(); + destruction_queue_signaux(s_etat_processus); + liberation_contexte_cas(s_etat_processus); free(s_etat_processus); # ifdef DEBUG_MEMOIRE @@ -2741,40 +2779,6 @@ instruction_detach(struct_processus *s_e return; } - liberation(s_etat_processus, s_objet); - - if ((s_objet = allocation(s_etat_processus, PRC)) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - (*((struct_processus_fils *) (*s_objet).objet)).thread = s_argument_thread; - (*(*((struct_processus_fils *) (*s_objet).objet)).thread) - .nombre_objets_dans_pipe = 0; - (*(*((struct_processus_fils *) (*s_objet).objet)).thread) - .nombre_interruptions_dans_pipe = 0; - (*(*((struct_processus_fils *) (*s_objet).objet)).thread) - .nombre_references = 1; - - /* - * On copie l'objet plutôt que le pointeur car cet objet peut être - * accédé depuis deux threads distincts et aboutir à un blocage lors d'une - * copie. - */ - - if ((s_objet_systeme = copie_objet(s_etat_processus, s_objet, 'O')) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } - // Si le pid existe déjà dans la pile des processus, il s'agit forcement // d'un processus moribond. On attend donc qu'il soit effectivement // libéré. @@ -2839,6 +2843,9 @@ instruction_detach(struct_processus *s_e // Être sûr que le processus fils soit déjà présent... + attente.tv_sec = 0; + attente.tv_nsec = GRANULARITE_us * 1000; + while(kill((*s_argument_thread).pid, 0) != 0) { //if ((errno != ESRCH) && (errno != EAGAIN)) @@ -2850,26 +2857,18 @@ instruction_detach(struct_processus *s_e } nanosleep(&attente, NULL); + INCR_GRANULARITE(attente.tv_nsec); } // Le fils peut être présent sans être en attente du signal de départ. - if (kill((*s_argument_thread).pid, SIGSTART) != 0) + if (envoi_signal_processus((*s_argument_thread).pid, rpl_sigstart) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; pthread_mutex_unlock(&((*s_etat_processus).mutex)); return; } - if (pthread_sigmask(SIG_SETMASK, &oldset, NULL) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - pthread_mutex_unlock(&((*s_etat_processus).mutex)); - return; - } - - sigpending(&set); - if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus;