--- rpl/src/instructions_d5.c 2010/06/04 07:48:20 1.25 +++ rpl/src/instructions_d5.c 2011/07/22 07:38:37 1.59 @@ -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.1 + 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" /* @@ -931,8 +931,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) @@ -943,13 +942,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) @@ -1017,11 +1013,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); @@ -1172,6 +1166,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) { /* @@ -1183,15 +1183,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; } @@ -1257,6 +1275,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; @@ -1275,6 +1295,8 @@ 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; @@ -1297,6 +1319,11 @@ instruction_detach(struct_processus *s_e * Processus fils */ +# ifdef _BROKEN_SIGINFO + liberation_fifos_signaux(s_etat_processus); + creation_fifos_signaux(s_etat_processus); +# endif + if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_debug_processus) != 0) @@ -1486,6 +1513,10 @@ instruction_detach(struct_processus *s_e } } +# ifdef _BROKEN_SIGINFO + destruction_fifos_signaux(s_etat_processus); +# endif + BUG(1, uprintf("Process management error line %d\n", __LINE__)); exit(EXIT_FAILURE); } @@ -1516,10 +1547,16 @@ instruction_detach(struct_processus *s_e } } +# ifdef _BROKEN_SIGINFO + destruction_fifos_signaux(s_etat_processus); +# endif + 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) { @@ -1547,6 +1584,10 @@ instruction_detach(struct_processus *s_e } } +# ifdef _BROKEN_SIGINFO + destruction_fifos_signaux(s_etat_processus); +# endif + BUG(1, uprintf("Process management error line %d\n", __LINE__)); exit(EXIT_FAILURE); } @@ -1558,6 +1599,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. @@ -1569,6 +1611,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++) { @@ -1692,21 +1737,30 @@ instruction_detach(struct_processus *s_e } } +# ifdef _BROKEN_SIGINFO + destruction_fifos_signaux(s_etat_processus); +# endif + 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 *) - (*l_element_courant).donnee; + (*((struct_processus_fils *) (*(*l_element_courant).donnee) + .objet)).thread; (*s_argument_thread2).nombre_references--; BUG((*s_argument_thread2).nombre_references < 0, - printf("(*s_argument_thread).nombre_references = %d\n", +# ifdef _BROKEN_SIGINFO + destruction_fifos_signaux(s_etat_processus), +# endif + printf("(*s_argument_thread2).nombre_references = %d\n", (int) (*s_argument_thread2).nombre_references)); if ((*s_argument_thread2).nombre_references == 0) @@ -1732,6 +1786,8 @@ instruction_detach(struct_processus *s_e } free(s_argument_thread2); + free((*(*l_element_courant).donnee).objet); + free((*l_element_courant).donnee); } l_element_suivant = (*l_element_courant).suivant; @@ -1767,6 +1823,10 @@ instruction_detach(struct_processus *s_e } } +# ifdef _BROKEN_SIGINFO + destruction_fifos_signaux(s_etat_processus); +# endif + BUG(1, uprintf("Process management error line %d\n", __LINE__)); exit(EXIT_FAILURE); } @@ -1831,6 +1891,10 @@ instruction_detach(struct_processus *s_e } } +# ifdef _BROKEN_SIGINFO + destruction_fifos_signaux(s_etat_processus); +# endif + BUG(1, uprintf("Process management error line %d\n", __LINE__)); exit(EXIT_FAILURE); } @@ -1883,6 +1947,10 @@ instruction_detach(struct_processus *s_e } } +# ifdef _BROKEN_SIGINFO + destruction_fifos_signaux(s_etat_processus); +# endif + BUG(1, uprintf("Process management error line %d\n", __LINE__)); exit(EXIT_FAILURE); } @@ -2067,6 +2135,7 @@ instruction_detach(struct_processus *s_e } 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) @@ -2430,6 +2499,10 @@ instruction_detach(struct_processus *s_e registre_stop; } +# ifdef _BROKEN_SIGINFO + destruction_fifos_signaux(s_etat_processus); +# endif + (*s_etat_processus).erreur_systeme = d_es_signal; exit(EXIT_FAILURE); } @@ -2464,6 +2537,10 @@ instruction_detach(struct_processus *s_e if (sigaction(SIGPIPE, ®istre, NULL) != 0) { +# ifdef _BROKEN_SIGINFO + destruction_fifos_signaux(s_etat_processus); +# endif + pthread_mutex_unlock(&((*s_etat_processus).mutex)); (*s_etat_processus).erreur_systeme = d_es_signal; @@ -2605,14 +2682,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++) { @@ -2780,12 +2852,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); @@ -2825,6 +2891,7 @@ 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); @@ -2856,6 +2923,10 @@ instruction_detach(struct_processus *s_e clear_history(); +# ifdef _BROKEN_SIGINFO + destruction_fifos_signaux(s_etat_processus); +# endif + free(s_etat_processus); # ifdef DEBUG_MEMOIRE @@ -2871,40 +2942,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é. @@ -2969,6 +3006,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)) @@ -2980,6 +3020,7 @@ 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.