--- rpl/src/instructions_d5.c 2010/01/26 15:22:44 1.1 +++ rpl/src/instructions_d5.c 2010/06/18 08:30:50 1.28 @@ -1,6 +1,6 @@ /* ================================================================================ - RPL/2 (R) version 4.0.9 + RPL/2 (R) version 4.0.16 Copyright (C) 1989-2010 Dr. BERTRAND Joël This file is part of RPL/2. @@ -838,6 +838,7 @@ instruction_detach(struct_processus *s_e 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; @@ -1062,6 +1063,12 @@ instruction_detach(struct_processus *s_e 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; @@ -1176,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; } @@ -1290,21 +1315,79 @@ instruction_detach(struct_processus *s_e * Processus fils */ + 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); + } + +# 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); + + 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); + + 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) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + } + sem_trywait((*s_etat_processus).semaphore_fork); +# endif + +# 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; } @@ -1343,6 +1426,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) { @@ -1404,6 +1504,7 @@ instruction_detach(struct_processus *s_e } } + BUG(1, uprintf("Process management error line %d\n", __LINE__)); exit(EXIT_FAILURE); } @@ -1433,9 +1534,12 @@ instruction_detach(struct_processus *s_e } } + 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) { @@ -1463,6 +1567,7 @@ instruction_detach(struct_processus *s_e } } + BUG(1, uprintf("Process management error line %d\n", __LINE__)); exit(EXIT_FAILURE); } @@ -1482,6 +1587,9 @@ instruction_detach(struct_processus *s_e (*s_etat_processus).nombre_interruptions_non_affectees = 0; (*s_etat_processus).processus_detache = d_vrai; + liberation(s_etat_processus, (*s_etat_processus).at_exit); + (*s_etat_processus).at_exit = NULL; + for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++) { liberation(s_etat_processus, @@ -1505,24 +1613,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,11 +1682,118 @@ 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; + } + } + + 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, + 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; + } + } + + BUG(1, uprintf("Process management error line %d\n", __LINE__)); + exit(EXIT_FAILURE); + } /* * Initialisation de la pile système @@ -1658,6 +1855,7 @@ instruction_detach(struct_processus *s_e } } + BUG(1, uprintf("Process management error line %d\n", __LINE__)); exit(EXIT_FAILURE); } @@ -1709,6 +1907,7 @@ instruction_detach(struct_processus *s_e } } + BUG(1, uprintf("Process management error line %d\n", __LINE__)); exit(EXIT_FAILURE); } @@ -1760,7 +1959,14 @@ instruction_detach(struct_processus *s_e l_element_suivant = (*l_element_courant).suivant; fclose((*((struct_descripteur_fichier *) - (*l_element_courant).donnee)).descripteur); + (*l_element_courant).donnee)).descripteur_c); + + if ((*((struct_descripteur_fichier *) + (*l_element_courant).donnee)).type != 'C') + { + sqlite3_close((*((struct_descripteur_fichier *) + (*l_element_courant).donnee)).descripteur_sqlite); + } free((*((struct_descripteur_fichier *) (*l_element_courant) .donnee)).nom); @@ -1774,17 +1980,26 @@ instruction_detach(struct_processus *s_e * Destruction des piles de connecteurs SQL */ +/* +================================================================================ + À 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; while(l_element_courant != NULL) { 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; + /* * On ne détruit pas les sockets car il faut utiliser DETACH * pour traiter plusieurs connexions simultanées sur les sockets @@ -1799,6 +2014,22 @@ instruction_detach(struct_processus *s_e sigpending(&set); + 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] Évaluation de l'objet détaché\n", getpid()); + } + else + { + printf("[%d] Évaluation of detached object\n", getpid()); + } + } + } + if ((*s_etat_processus).erreur_systeme == d_es) { if (variable_partagee == d_faux) @@ -1812,6 +2043,22 @@ instruction_detach(struct_processus *s_e d_ex_erreur_evaluation; } } + else + { + 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 { @@ -1824,11 +2071,27 @@ instruction_detach(struct_processus *s_e d_ex_erreur_evaluation; } } + else + { + if ((*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; + } + } + } liberation(s_etat_processus, s_copie); } } + liberation(s_etat_processus, (*s_etat_processus).at_exit); + l_element_courant = (*s_etat_processus).liste_mutexes; while(l_element_courant != NULL) { @@ -1979,7 +2242,14 @@ instruction_detach(struct_processus *s_e l_element_suivant = (*l_element_courant).suivant; fclose((*((struct_descripteur_fichier *) - (*l_element_courant).donnee)).descripteur); + (*l_element_courant).donnee)).descripteur_c); + + if ((*((struct_descripteur_fichier *) + (*l_element_courant).donnee)).type != 'C') + { + sqlite3_close((*((struct_descripteur_fichier *) + (*l_element_courant).donnee)).descripteur_sqlite); + } if (((*((struct_descripteur_fichier *) (*l_element_courant) .donnee)).pid == getpid()) && @@ -2048,9 +2318,18 @@ instruction_detach(struct_processus *s_e } else { - kill((*(*((struct_processus_fils *) - (*(*l_element_courant).donnee).objet)).thread).pid, - SIGFSTOP); + if ((*s_etat_processus).arret_depuis_abort == -1) + { + kill((*(*((struct_processus_fils *) + (*(*l_element_courant).donnee).objet)).thread) + .pid, SIGFABORT); + } + else + { + kill((*(*((struct_processus_fils *) + (*(*l_element_courant).donnee).objet)).thread) + .pid, SIGFSTOP); + } } } else @@ -2097,9 +2376,18 @@ instruction_detach(struct_processus *s_e } else { - pthread_kill((*(*((struct_processus_fils *) - (*(*l_element_courant).donnee).objet)).thread) - .tid, SIGFSTOP); + if ((*s_etat_processus).arret_depuis_abort == -1) + { + pthread_kill((*(*((struct_processus_fils *) + (*(*l_element_courant).donnee).objet)) + .thread).tid, SIGFABORT); + } + else + { + pthread_kill((*(*((struct_processus_fils *) + (*(*l_element_courant).donnee).objet)) + .thread).tid, SIGFSTOP); + } } } @@ -2127,11 +2415,6 @@ instruction_detach(struct_processus *s_e l_element_courant = (struct_liste_chainee *) (*s_etat_processus).l_base_pile_processus; - if ((*s_etat_processus).nombre_interruptions_non_affectees != 0) - { - affectation_interruptions_logicielles(s_etat_processus); - } - registre_stop = (*s_etat_processus) .var_volatile_traitement_retarde_stop; (*s_etat_processus).var_volatile_traitement_retarde_stop = 1; @@ -2214,6 +2497,12 @@ instruction_detach(struct_processus *s_e } pthread_mutex_unlock(&((*s_etat_processus).mutex)); + + if ((*s_etat_processus).nombre_interruptions_non_affectees != 0) + { + affectation_interruptions_logicielles(s_etat_processus); + } + nanosleep(&attente, NULL); pthread_mutex_lock(&((*s_etat_processus).mutex)); } @@ -2515,9 +2804,13 @@ 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); - free((*s_etat_processus).definitions_chainees); +# endif + free((*s_etat_processus).definitions_chainees); free((*s_etat_processus).nom_fichier_historique); for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++) @@ -2560,56 +2853,43 @@ instruction_detach(struct_processus *s_e 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 free((*s_etat_processus).localisation); - free(s_etat_processus); 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(); - exit(EXIT_SUCCESS); - } - else - { - (*s_etat_processus).erreur_systeme = d_es_processus; - 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; + free(s_etat_processus); - /* - * 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. - */ +# ifdef DEBUG_MEMOIRE + debug_memoire_verification(); + analyse_post_mortem(); +# endif - if ((s_objet_systeme = copie_objet(s_etat_processus, s_objet, 'O')) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; + exit(EXIT_SUCCESS); } - - if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0) + else { (*s_etat_processus).erreur_systeme = d_es_processus; return;