--- rpl/src/gestion_objets.c 2017/06/28 09:20:31 1.131 +++ rpl/src/gestion_objets.c 2020/01/10 11:15:42 1.148 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.1.27 - Copyright (C) 1989-2017 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.32 + Copyright (C) 1989-2020 Dr. BERTRAND Joël This file is part of RPL/2. @@ -106,6 +106,7 @@ initialisation_allocateur(struct_process (*s_etat_processus).pointeur_int = 0; (*s_etat_processus).pointeur_mat = 0; (*s_etat_processus).pointeur_nom = 0; + (*s_etat_processus).pointeur_rec = 0; (*s_etat_processus).pointeur_rel = 0; (*s_etat_processus).pointeur_tab = 0; (*s_etat_processus).pointeur_vec = 0; @@ -141,6 +142,8 @@ liberation_allocateur(struct_processus * free((*s_etat_processus).objets_mat[i++])); for(i = 0; i < (*s_etat_processus).pointeur_nom; free((*s_etat_processus).objets_nom[i++])); + for(i = 0; i < (*s_etat_processus).pointeur_rec; + free((*s_etat_processus).objets_rec[i++])); for(i = 0; i < (*s_etat_processus).pointeur_rel; free((*s_etat_processus).objets_rel[i++])); for(i = 0; i < (*s_etat_processus).pointeur_tab; @@ -343,6 +346,8 @@ allocation(struct_processus *s_etat_proc } (*s_objet).type = type; + (*s_objet).extension_type = 0; + (*s_objet).descripteur_bibliotheque = NULL; switch(type) { @@ -434,6 +439,12 @@ allocation(struct_processus *s_etat_proc break; } + case EXT : + { + // Aucune allocation + break; + } + case FCT : { if ((*s_etat_processus).pointeur_fct > 0) @@ -615,6 +626,28 @@ allocation(struct_processus *s_etat_proc break; } + case REC : + { + if ((*s_etat_processus).pointeur_rec > 0) + { + (*s_objet).objet = (*s_etat_processus).objets_rec + [--(*s_etat_processus).pointeur_rec]; + } + else + { + if (((*s_objet).objet = malloc(sizeof(struct_record))) + == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + free(s_objet); + return(NULL); + } + } + + break; + } + case REL : { if ((*s_etat_processus).pointeur_rel > 0) @@ -821,6 +854,8 @@ liberation(struct_processus *s_etat_proc struct_liste_chainee *l_element_suivant; integer8 i; + integer8 (*__type_drop)(struct_processus *, + void **); if (s_objet == NULL) { @@ -1263,6 +1298,31 @@ liberation(struct_processus *s_etat_proc break; } + case REC : + { + liberation(s_etat_processus, + (*((struct_record *) (*s_objet).objet)).noms); + liberation(s_etat_processus, + (*((struct_record *) (*s_objet).objet)).donnees); + + if (decrementation_atomique(s_objet) > 0) + { + return; + } + + if ((*s_etat_processus).pointeur_rec < TAILLE_CACHE) + { + (*s_etat_processus).objets_rec + [(*s_etat_processus).pointeur_rec++] = (*s_objet).objet; + } + else + { + free((struct_record *) ((*s_objet).objet)); + } + + break; + } + case REL : { if (decrementation_atomique(s_objet) > 0) @@ -1493,6 +1553,57 @@ liberation(struct_processus *s_etat_proc break; } + case EXT: + { + if (decrementation_atomique(s_objet) > 0) + { + return; + } + + // Appel de la fonction de liberation associée à l'objet + // externe. Le descripteur de bibliothèque est directement + // associé à la structure objet. + + l_element_courant = (*s_etat_processus).s_bibliotheques; + + while(l_element_courant != NULL) + { + if ((*((struct_bibliotheque *) (*l_element_courant).donnee)) + .descripteur == (*s_objet).descripteur_bibliotheque) + { + if ((__type_drop = dlsym((*s_objet) + .descripteur_bibliotheque, "__type_drop")) == NULL) + { + // La fonction de libération n'existe pas dans la + // bibliothèque. + + (*s_etat_processus).erreur_execution = + d_ex_type_externe_drop; + } + else + { + if (__type_drop(s_etat_processus, (void **) &s_objet) + == 0) + { + (*s_etat_processus).erreur_execution = + d_ex_type_externe_drop; + } + } + + break; + } + + l_element_courant = (*l_element_courant).suivant; + } + + if (l_element_courant == NULL) + { + (*s_etat_processus).erreur_execution = d_ex_type_externe_drop; + } + + break; + } + default : { if (pthread_mutex_unlock(&((*s_objet).mutex)) != 0) @@ -1591,6 +1702,7 @@ copie_objet(struct_processus *s_etat_pro integer8 i; integer8 j; + integer8 (*__type_dup)(struct_processus *, void **); if (pthread_mutex_lock(&((*s_objet).mutex)) != 0) { @@ -2372,6 +2484,46 @@ copie_objet(struct_processus *s_etat_pro break; } + case REC : + { + if (type != 'P') + { + if ((s_nouvel_objet = allocation(s_etat_processus, REC)) + == NULL) + { + return(NULL); + } + + if (((*((struct_record *) (*s_nouvel_objet).objet)).noms = + copie_objet(s_etat_processus, (*((struct_record *) + (*s_objet).objet)).noms, 'P')) == NULL) + { + return(NULL); + } + + if (((*((struct_record *) (*s_nouvel_objet).objet)).donnees = + copie_objet(s_etat_processus, (*((struct_record *) + (*s_objet).objet)).donnees, type)) == NULL) + { + return(NULL); + } + } + else + { + incrementation_atomique(s_objet); + (*((struct_record *) (*s_objet).objet)).noms = + copie_objet(s_etat_processus, (*((struct_record *) + (*s_objet).objet)).noms, 'P'); + (*((struct_record *) (*s_objet).objet)).donnees = + copie_objet(s_etat_processus, (*((struct_record *) + (*s_objet).objet)).donnees, 'P'); + + return(s_objet); + } + + break; + } + case REL : { if (type != 'O') @@ -2812,6 +2964,59 @@ copie_objet(struct_processus *s_etat_pro break; } + case EXT: + { + if (type != 'O') + { + incrementation_atomique(s_objet); + return(s_objet); + } + + // Appel de la fonction de duplication associée à l'objet + // externe. Le descripteur de bibliothèque est directement + // associé à la structure objet. + + l_element_courant = (*s_etat_processus).s_bibliotheques; + + while(l_element_courant != NULL) + { + if ((*((struct_bibliotheque *) (*l_element_courant).donnee)) + .descripteur == (*s_objet).descripteur_bibliotheque) + { + if ((__type_dup = dlsym((*s_objet).descripteur_bibliotheque, + "__type_dup")) == NULL) + { + // La fonction de duplication n'existe pas dans la + // bibliothèque. + + (*s_etat_processus).erreur_execution = + d_ex_type_externe_dup; + return(NULL); + } + + s_nouvel_objet = s_objet; + + if (__type_dup(s_etat_processus, (void **) &s_nouvel_objet) + == 0) + { + return(NULL); + } + + break; + } + + l_element_courant = (*l_element_courant).suivant; + } + + if (l_element_courant == NULL) + { + (*s_etat_processus).erreur_execution = d_ex_type_externe_dup; + return(NULL); + } + + break; + } + default : { return(NULL); @@ -2869,8 +3074,33 @@ copie_etat_processus(struct_processus *s return(NULL); } + + if (pthread_mutex_lock(&((*s_etat_processus).mutex_interruptions)) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return(NULL); + } + + if (pthread_mutex_lock(&((*s_etat_processus).mutex_signaux)) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return(NULL); + } + (*s_nouvel_etat_processus) = (*s_etat_processus); + if (pthread_mutex_unlock(&((*s_etat_processus).mutex_signaux)) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return(NULL); + } + + if (pthread_mutex_unlock(&((*s_etat_processus).mutex_interruptions)) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return(NULL); + } + // On réinitialise les allocateurs. pthread_mutexattr_init(&attributs_mutex); @@ -3736,6 +3966,13 @@ debug_memoire_ajout(size_t taille, const sizeof(unsigned char))) == NULL) { pthread_mutex_unlock(&mutex_allocation); + + uprintf("[%d-%llu] ILLEGAL POINTER (malloc) $%016X\n", + getpid(), (unsigned long long) pthread_self(), NULL); +# ifdef __BACKTRACE + BACKTRACE(PROFONDEUR_PILE); +# endif + return(NULL); } @@ -3796,8 +4033,9 @@ debug_memoire_modification(void *pointeu { pthread_mutex_unlock(&mutex_allocation); - uprintf("[%d-%llu] ILLEGAL POINTER (realloc)\n", - getpid(), (unsigned long long) pthread_self()); + uprintf("[%d-%llu] ILLEGAL POINTER (realloc) $%016X\n", + getpid(), (unsigned long long) pthread_self(), + pointeur); # ifdef __BACKTRACE BACKTRACE(PROFONDEUR_PILE); # endif @@ -3893,8 +4131,8 @@ debug_memoire_retrait(void *pointeur) if (element_courant == NULL) { - uprintf("[%d-%llu] ILLEGAL POINTER (free)\n", - getpid(), (unsigned long long) pthread_self()); + uprintf("[%d-%llu] ILLEGAL POINTER (free) $%016X\n", + getpid(), (unsigned long long) pthread_self(), pointeur); # ifdef __BACKTRACE BACKTRACE(PROFONDEUR_PILE); # endif @@ -4011,7 +4249,7 @@ debug_memoire_verification() } pid_t -debug_fork() +debug_fork(struct_processus *s_etat_processus) { pid_t pid;