Annotation of rpl/src/interruptions.c, revision 1.68

1.1       bertrand    1: /*
                      2: ================================================================================
1.60      bertrand    3:   RPL/2 (R) version 4.1.3
1.45      bertrand    4:   Copyright (C) 1989-2011 Dr. BERTRAND Joël
1.1       bertrand    5: 
                      6:   This file is part of RPL/2.
                      7: 
                      8:   RPL/2 is free software; you can redistribute it and/or modify it
                      9:   under the terms of the CeCILL V2 License as published by the french
                     10:   CEA, CNRS and INRIA.
                     11:  
                     12:   RPL/2 is distributed in the hope that it will be useful, but WITHOUT
                     13:   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
                     14:   FITNESS FOR A PARTICULAR PURPOSE.  See the CeCILL V2 License
                     15:   for more details.
                     16:  
                     17:   You should have received a copy of the CeCILL License
                     18:   along with RPL/2. If not, write to info@cecill.info.
                     19: ================================================================================
                     20: */
                     21: 
                     22: 
1.27      bertrand   23: #include "rpl-conv.h"
1.1       bertrand   24: 
                     25: 
                     26: /*
                     27: ================================================================================
                     28:   Procédures de gestion par thread des variables issues des gestionnaires
                     29:   de signaux
                     30: ================================================================================
                     31:   Entrée : variable globale
                     32: --------------------------------------------------------------------------------
                     33:   Sortie : variable globale modifiée
                     34: --------------------------------------------------------------------------------
                     35:   Effets de bord : néant
                     36: ================================================================================
                     37: */
                     38: 
                     39: typedef struct thread
                     40: {
                     41:    pid_t               pid;
                     42:    pthread_t           tid;
                     43: 
                     44:    logical1            thread_principal;
                     45: 
                     46:    struct_processus    *s_etat_processus;
                     47: } struct_thread;
                     48: 
                     49: typedef struct liste_chainee_volatile
                     50: {
                     51:    volatile struct liste_chainee_volatile  *suivant;
                     52:    volatile void                           *donnee;
                     53: } struct_liste_chainee_volatile;
                     54: 
                     55: 
                     56: static volatile struct_liste_chainee_volatile  *liste_threads
                     57:        = NULL;
                     58: static volatile struct_liste_chainee_volatile  *liste_threads_surveillance
                     59:        = NULL;
1.68    ! bertrand   60: static volatile int                                code_erreur_gsl = 0;
        !            61: 
        !            62: static pthread_mutex_t                         mutex_interruptions
        !            63:        = PTHREAD_MUTEX_INITIALIZER;
1.1       bertrand   64: 
                     65: void
                     66: modification_pid_thread_pere(struct_processus *s_etat_processus)
                     67: {
                     68:    // La variable existe toujours et aucun thread concurrent ne peut
                     69:    // la modifier puisque cette routine ne peut être appelée que depuis
                     70:    // DAEMON.
                     71: 
                     72:    (*((struct_thread *) (*liste_threads).donnee)).pid =
                     73:            (*s_etat_processus).pid_processus_pere;
                     74: 
                     75:    return;
                     76: }
                     77: 
                     78: void
                     79: insertion_thread(struct_processus *s_etat_processus, logical1 thread_principal)
                     80: {
                     81:    volatile struct_liste_chainee_volatile      *l_nouvel_objet;
                     82: 
                     83:    if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
                     84:            == NULL)
                     85:    {
                     86:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                     87:        return;
                     88:    }
                     89: 
                     90:    if (((*l_nouvel_objet).donnee = malloc(sizeof(struct_thread))) == NULL)
                     91:    {
                     92:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                     93:        return;
                     94:    }
                     95: 
                     96:    (*((struct_thread *) (*l_nouvel_objet).donnee)).pid = getpid();
                     97:    (*((struct_thread *) (*l_nouvel_objet).donnee)).tid = pthread_self();
                     98:    (*((struct_thread *) (*l_nouvel_objet).donnee)).thread_principal =
                     99:            thread_principal;
                    100:    (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus =
                    101:            s_etat_processus;
                    102: 
1.68    ! bertrand  103:    if (pthread_mutex_lock(&mutex_liste_threads) != 0)
1.13      bertrand  104:    {
1.68    ! bertrand  105:        (*s_etat_processus).erreur_systeme = d_es_processus;
        !           106:        return;
1.13      bertrand  107:    }
                    108: 
                    109:    (*l_nouvel_objet).suivant = liste_threads;
1.1       bertrand  110:    liste_threads = l_nouvel_objet;
                    111: 
1.68    ! bertrand  112:    if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1.1       bertrand  113:    {
                    114:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    115:        return;
                    116:    }
                    117: 
                    118:    return;
                    119: }
                    120: 
                    121: void
                    122: insertion_thread_surveillance(struct_processus *s_etat_processus,
                    123:        struct_descripteur_thread *s_argument_thread)
                    124: {
                    125:    volatile struct_liste_chainee_volatile      *l_nouvel_objet;
                    126: 
1.13      bertrand  127:    if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
                    128:            == NULL)
                    129:    {
                    130:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    131:        return;
                    132:    }
                    133: 
1.68    ! bertrand  134:    if (pthread_mutex_lock(&mutex_liste_threads) != 0)
1.1       bertrand  135:    {
1.68    ! bertrand  136:        (*s_etat_processus).erreur_systeme = d_es_processus;
        !           137:        return;
1.1       bertrand  138:    }
                    139: 
1.40      bertrand  140:    pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references));
1.21      bertrand  141:    (*s_argument_thread).nombre_references++;
1.40      bertrand  142:    pthread_mutex_unlock(&((*s_argument_thread).mutex_nombre_references));
1.22      bertrand  143: 
1.1       bertrand  144:    (*l_nouvel_objet).suivant = liste_threads_surveillance;
                    145:    (*l_nouvel_objet).donnee = (void *) s_argument_thread;
                    146: 
                    147:    liste_threads_surveillance = l_nouvel_objet;
                    148: 
1.68    ! bertrand  149:    if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1.1       bertrand  150:    {
                    151:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    152:        return;
                    153:    }
                    154: 
                    155:    return;
                    156: }
                    157: 
                    158: void
                    159: retrait_thread(struct_processus *s_etat_processus)
                    160: {
                    161:    volatile struct_liste_chainee_volatile  *l_element_precedent;
                    162:    volatile struct_liste_chainee_volatile  *l_element_courant;
                    163: 
1.68    ! bertrand  164:    if (pthread_mutex_lock(&mutex_liste_threads) != 0)
1.1       bertrand  165:    {
1.68    ! bertrand  166:        (*s_etat_processus).erreur_systeme = d_es_processus;
        !           167:        return;
1.1       bertrand  168:    }
                    169: 
                    170:    l_element_precedent = NULL;
                    171:    l_element_courant = liste_threads;
                    172: 
                    173:    while(l_element_courant != NULL)
                    174:    {
                    175:        if (((*((struct_thread *) (*l_element_courant).donnee)).pid
                    176:                == getpid()) && (pthread_equal((*((struct_thread *)
                    177:                (*l_element_courant).donnee)).tid, pthread_self()) != 0))
                    178:        {
                    179:            break;
                    180:        }
                    181: 
                    182:        l_element_precedent = l_element_courant;
                    183:        l_element_courant = (*l_element_courant).suivant;
                    184:    }
                    185: 
                    186:    if (l_element_courant == NULL)
                    187:    {
1.68    ! bertrand  188:        pthread_mutex_unlock(&mutex_liste_threads);
1.1       bertrand  189:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    190:        return;
                    191:    }
                    192: 
                    193:    if (l_element_precedent == NULL)
                    194:    {
                    195:        liste_threads = (*l_element_courant).suivant;
                    196:    }
                    197:    else
                    198:    {
                    199:        (*l_element_precedent).suivant = (*l_element_courant).suivant;
                    200:    }
                    201: 
1.68    ! bertrand  202:    if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1.1       bertrand  203:    {
                    204:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    205:        return;
                    206:    }
                    207: 
1.13      bertrand  208:    free((void *) (*l_element_courant).donnee);
                    209:    free((struct_liste_chainee_volatile *) l_element_courant);
                    210: 
1.1       bertrand  211:    return;
                    212: }
                    213: 
                    214: void
                    215: retrait_thread_surveillance(struct_processus *s_etat_processus,
                    216:        struct_descripteur_thread *s_argument_thread)
                    217: {
                    218:    volatile struct_liste_chainee_volatile  *l_element_precedent;
                    219:    volatile struct_liste_chainee_volatile  *l_element_courant;
                    220: 
1.68    ! bertrand  221:    if (pthread_mutex_lock(&mutex_liste_threads) != 0)
1.1       bertrand  222:    {
1.68    ! bertrand  223:        (*s_etat_processus).erreur_systeme = d_es_processus;
        !           224:        return;
1.1       bertrand  225:    }
                    226: 
                    227:    l_element_precedent = NULL;
                    228:    l_element_courant = liste_threads_surveillance;
                    229: 
                    230:    while(l_element_courant != NULL)
                    231:    {
                    232:        if ((*l_element_courant).donnee == (void *) s_argument_thread)
                    233:        {
                    234:            break;
                    235:        }
                    236: 
                    237:        l_element_precedent = l_element_courant;
                    238:        l_element_courant = (*l_element_courant).suivant;
                    239:    }
                    240: 
                    241:    if (l_element_courant == NULL)
                    242:    {
1.68    ! bertrand  243:        pthread_mutex_unlock(&mutex_liste_threads);
1.1       bertrand  244:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    245:        return;
                    246:    }
                    247: 
                    248:    if (l_element_precedent == NULL)
                    249:    {
                    250:        liste_threads_surveillance = (*l_element_courant).suivant;
                    251:    }
                    252:    else
                    253:    {
                    254:        (*l_element_precedent).suivant = (*l_element_courant).suivant;
                    255:    }
                    256: 
1.40      bertrand  257:    if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
                    258:            != 0)
1.1       bertrand  259:    {
1.68    ! bertrand  260:        pthread_mutex_unlock(&mutex_liste_threads);
1.1       bertrand  261:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    262:        return;
                    263:    }
                    264: 
                    265:    (*s_argument_thread).nombre_references--;
                    266: 
                    267:    BUG((*s_argument_thread).nombre_references < 0,
                    268:            printf("(*s_argument_thread).nombre_references = %d\n",
                    269:            (int) (*s_argument_thread).nombre_references));
                    270: 
                    271:    if ((*s_argument_thread).nombre_references == 0)
                    272:    {
1.40      bertrand  273:        if (pthread_mutex_unlock(&((*s_argument_thread)
                    274:                .mutex_nombre_references)) != 0)
1.1       bertrand  275:        {
1.68    ! bertrand  276:            pthread_mutex_unlock(&mutex_liste_threads);
1.1       bertrand  277:            (*s_etat_processus).erreur_systeme = d_es_processus;
                    278:            return;
                    279:        }
                    280: 
                    281:        pthread_mutex_destroy(&((*s_argument_thread).mutex));
1.40      bertrand  282:        pthread_mutex_destroy(&((*s_argument_thread).mutex_nombre_references));
1.1       bertrand  283:        free(s_argument_thread);
                    284:    }
                    285:    else
                    286:    {
1.40      bertrand  287:        if (pthread_mutex_unlock(&((*s_argument_thread)
                    288:                .mutex_nombre_references)) != 0)
1.1       bertrand  289:        {
1.68    ! bertrand  290:            pthread_mutex_unlock(&mutex_liste_threads);
1.1       bertrand  291:            (*s_etat_processus).erreur_systeme = d_es_processus;
                    292:            return;
                    293:        }
                    294:    }
                    295: 
1.68    ! bertrand  296:    if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1.1       bertrand  297:    {
                    298:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    299:        return;
                    300:    }
                    301: 
1.13      bertrand  302:    free((struct_liste_chainee_volatile *) l_element_courant);
1.1       bertrand  303:    return;
                    304: }
                    305: 
                    306: void
                    307: verrouillage_threads_concurrents(struct_processus *s_etat_processus)
                    308: {
                    309:    volatile struct_liste_chainee_volatile  *l_element_courant;
                    310: 
1.68    ! bertrand  311:    if (pthread_mutex_lock(&mutex_liste_threads) != 0)
1.1       bertrand  312:    {
1.68    ! bertrand  313:        (*s_etat_processus).erreur_systeme = d_es_processus;
        !           314:        return;
1.1       bertrand  315:    }
                    316: 
                    317:    l_element_courant = liste_threads;
                    318: 
                    319:    while(l_element_courant != NULL)
                    320:    {
                    321:        if (((*((struct_thread *) (*l_element_courant).donnee)).pid
                    322:                == getpid()) && (pthread_equal((*((struct_thread *)
                    323:                (*l_element_courant).donnee)).tid, pthread_self()) == 0))
                    324:        {
1.68    ! bertrand  325:            if (pthread_mutex_lock(&((*(*((struct_thread *) (*l_element_courant)
        !           326:                    .donnee)).s_etat_processus).mutex_fork)) == -1)
1.1       bertrand  327:            {
1.68    ! bertrand  328:                (*s_etat_processus).erreur_systeme = d_es_processus;
        !           329:                return;
1.1       bertrand  330:            }
                    331:        }
                    332: 
                    333:        l_element_courant = (*l_element_courant).suivant;
                    334:    }
                    335: 
                    336:    return;
                    337: }
                    338: 
                    339: void
                    340: deverrouillage_threads_concurrents(struct_processus *s_etat_processus)
                    341: {
                    342:    volatile struct_liste_chainee_volatile  *l_element_courant;
                    343: 
                    344:    l_element_courant = liste_threads;
                    345: 
                    346:    while(l_element_courant != NULL)
                    347:    {
                    348:        if (((*((struct_thread *) (*l_element_courant).donnee)).pid
                    349:                == getpid()) && (pthread_equal((*((struct_thread *)
                    350:                (*l_element_courant).donnee)).tid, pthread_self()) == 0))
                    351:        {
1.68    ! bertrand  352:            if (pthread_mutex_unlock(&((*(*((struct_thread *)
1.1       bertrand  353:                    (*l_element_courant).donnee)).s_etat_processus)
1.68    ! bertrand  354:                    .mutex_fork)) != 0)
1.1       bertrand  355:            {
1.68    ! bertrand  356:                if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1.8       bertrand  357:                {
                    358:                    (*s_etat_processus).erreur_systeme = d_es_processus;
                    359:                    return;
                    360:                }
1.1       bertrand  361: 
                    362:                (*s_etat_processus).erreur_systeme = d_es_processus;
                    363:                return;
                    364:            }
                    365:        }
                    366: 
                    367:        l_element_courant = (*l_element_courant).suivant;
                    368:    }
                    369: 
1.68    ! bertrand  370:    if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1.1       bertrand  371:    {
                    372:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    373:        return;
                    374:    }
                    375: 
                    376:    return;
                    377: }
                    378: 
                    379: void
                    380: liberation_threads(struct_processus *s_etat_processus)
                    381: {
                    382:    logical1                                    suppression_variables_partagees;
                    383: 
                    384:    struct_descripteur_thread                   *s_argument_thread;
                    385: 
                    386:    struct_processus                            *candidat;
                    387: 
                    388:    unsigned long                               i;
                    389: 
                    390:    void                                        *element_candidat;
                    391:    void                                        *element_courant;
                    392:    void                                        *element_suivant;
                    393: 
                    394:    volatile struct_liste_chainee_volatile      *l_element_courant;
                    395:    volatile struct_liste_chainee_volatile      *l_element_suivant;
                    396: 
1.68    ! bertrand  397:    if (pthread_mutex_lock(&mutex_liste_threads) == -1)
1.1       bertrand  398:    {
1.68    ! bertrand  399:        (*s_etat_processus).erreur_systeme = d_es_processus;
        !           400:        return;
1.1       bertrand  401:    }
                    402: 
                    403:    l_element_courant = liste_threads;
                    404:    suppression_variables_partagees = d_faux;
                    405: 
                    406:    while(l_element_courant != NULL)
                    407:    {
                    408:        if ((*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus
                    409:                != s_etat_processus)
                    410:        {
                    411:            candidat = s_etat_processus;
                    412:            s_etat_processus = (*((struct_thread *)
                    413:                    (*l_element_courant).donnee)).s_etat_processus;
                    414:            free((*s_etat_processus).localisation);
                    415: 
                    416:            // (*s_etat_processus).instruction_courante peut pointer sur
                    417:            // n'importe quoi (une instruction courante ou un champ d'une
                    418:            // structure objet). On ne le libère pas quitte à avoir une
                    419:            // petite fuite mémoire dans le processus fils.
                    420: 
                    421:            if ((*s_etat_processus).instruction_courante != NULL)
                    422:            {
                    423:                //free((*s_etat_processus).instruction_courante);
                    424:            }
                    425: 
                    426:            close((*s_etat_processus).pipe_acquittement);
                    427:            close((*s_etat_processus).pipe_donnees);
                    428:            close((*s_etat_processus).pipe_injections);
                    429:            close((*s_etat_processus).pipe_nombre_injections);
                    430:            close((*s_etat_processus).pipe_interruptions);
                    431:            close((*s_etat_processus).pipe_nombre_objets_attente);
                    432:            close((*s_etat_processus).pipe_nombre_interruptions_attente);
                    433: 
1.13      bertrand  434:            liberation(s_etat_processus, (*s_etat_processus).at_exit);
                    435: 
1.1       bertrand  436:            if ((*s_etat_processus).nom_fichier_impression != NULL)
                    437:            {
                    438:                free((*s_etat_processus).nom_fichier_impression);
                    439:            }
                    440: 
                    441:            while((*s_etat_processus).fichiers_graphiques != NULL)
                    442:            {
                    443:                free((*(*s_etat_processus).fichiers_graphiques).nom);
                    444: 
                    445:                if ((*(*s_etat_processus).fichiers_graphiques).legende != NULL)
                    446:                {
                    447:                    free((*(*s_etat_processus).fichiers_graphiques).legende);
                    448:                }
                    449: 
                    450:                element_courant = (*s_etat_processus).fichiers_graphiques;
                    451:                (*s_etat_processus).fichiers_graphiques =
                    452:                        (*(*s_etat_processus).fichiers_graphiques).suivant;
                    453: 
                    454:                free(element_courant);
                    455:            }
                    456: 
                    457:            if ((*s_etat_processus).entree_standard != NULL)
                    458:            {
                    459:                pclose((*s_etat_processus).entree_standard);
                    460:            }
                    461: 
                    462:            if ((*s_etat_processus).generateur_aleatoire != NULL)
                    463:            {
                    464:                liberation_generateur_aleatoire(s_etat_processus);
                    465:            }
                    466: 
                    467:            if ((*s_etat_processus).instruction_derniere_erreur != NULL)
                    468:            {
                    469:                free((*s_etat_processus).instruction_derniere_erreur);
                    470:                (*s_etat_processus).instruction_derniere_erreur = NULL;
                    471:            }
                    472: 
                    473:            element_courant = (void *) (*s_etat_processus)
                    474:                    .l_base_pile_processus;
                    475:            while(element_courant != NULL)
                    476:            {
1.20      bertrand  477:                s_argument_thread = (struct_descripteur_thread *)
                    478:                        (*((struct_liste_chainee *) element_courant)).donnee;
                    479: 
1.40      bertrand  480:                if (pthread_mutex_lock(&((*s_argument_thread)
                    481:                        .mutex_nombre_references)) != 0)
1.20      bertrand  482:                {
                    483:                    (*s_etat_processus).erreur_systeme = d_es_processus;
1.68    ! bertrand  484:                    pthread_mutex_unlock(&mutex_liste_threads);
1.20      bertrand  485:                    return;
                    486:                }
                    487: 
                    488:                (*s_argument_thread).nombre_references--;
                    489: 
                    490:                BUG((*s_argument_thread).nombre_references < 0,
                    491:                        printf("(*s_argument_thread).nombre_references = %d\n",
                    492:                        (int) (*s_argument_thread).nombre_references));
                    493: 
                    494:                if ((*s_argument_thread).nombre_references == 0)
                    495:                {
                    496:                    close((*s_argument_thread).pipe_objets[0]);
                    497:                    close((*s_argument_thread).pipe_acquittement[1]);
                    498:                    close((*s_argument_thread).pipe_injections[1]);
                    499:                    close((*s_argument_thread).pipe_nombre_injections[1]);
                    500:                    close((*s_argument_thread).pipe_nombre_objets_attente[0]);
                    501:                    close((*s_argument_thread).pipe_interruptions[0]);
                    502:                    close((*s_argument_thread)
                    503:                            .pipe_nombre_interruptions_attente[0]);
                    504: 
1.40      bertrand  505:                    if (pthread_mutex_unlock(&((*s_argument_thread)
                    506:                            .mutex_nombre_references)) != 0)
1.20      bertrand  507:                    {
                    508:                        (*s_etat_processus).erreur_systeme = d_es_processus;
1.68    ! bertrand  509:                        pthread_mutex_unlock(&mutex_liste_threads);
1.20      bertrand  510:                        return;
                    511:                    }
                    512: 
                    513:                    pthread_mutex_destroy(&((*s_argument_thread).mutex));
1.40      bertrand  514:                    pthread_mutex_destroy(&((*s_argument_thread)
                    515:                            .mutex_nombre_references));
1.20      bertrand  516: 
                    517:                    if ((*s_argument_thread).processus_detache == d_faux)
                    518:                    {
                    519:                        if ((*s_argument_thread).destruction_objet == d_vrai)
                    520:                        {
                    521:                            liberation(s_etat_processus, (*s_argument_thread)
                    522:                                    .argument);
                    523:                        }
                    524:                    }
                    525: 
                    526:                    free(s_argument_thread);
                    527:                }
                    528:                else
                    529:                {
1.40      bertrand  530:                    if (pthread_mutex_unlock(&((*s_argument_thread)
                    531:                            .mutex_nombre_references)) != 0)
1.20      bertrand  532:                    {
                    533:                        (*s_etat_processus).erreur_systeme = d_es_processus;
1.68    ! bertrand  534:                        pthread_mutex_unlock(&mutex_liste_threads);
1.20      bertrand  535:                        return;
                    536:                    }
                    537:                }
                    538: 
1.1       bertrand  539:                element_suivant = (*((struct_liste_chainee *) element_courant))
                    540:                        .suivant;
1.20      bertrand  541:                free(element_courant);
1.1       bertrand  542:                element_courant = element_suivant;
                    543:            }
                    544: 
1.20      bertrand  545:            (*s_etat_processus).l_base_pile_processus = NULL;
                    546: 
1.1       bertrand  547:            pthread_mutex_trylock(&((*(*s_etat_processus).indep).mutex));
                    548:            pthread_mutex_unlock(&((*(*s_etat_processus).indep).mutex));
                    549:            liberation(s_etat_processus, (*s_etat_processus).indep);
                    550: 
                    551:            pthread_mutex_trylock(&((*(*s_etat_processus).depend).mutex));
                    552:            pthread_mutex_unlock(&((*(*s_etat_processus).depend).mutex));
                    553:            liberation(s_etat_processus, (*s_etat_processus).depend);
                    554: 
                    555:            free((*s_etat_processus).label_x);
                    556:            free((*s_etat_processus).label_y);
                    557:            free((*s_etat_processus).label_z);
                    558:            free((*s_etat_processus).titre);
                    559:            free((*s_etat_processus).legende);
                    560: 
                    561:            pthread_mutex_trylock(&((*(*s_etat_processus)
                    562:                    .parametres_courbes_de_niveau).mutex));
                    563:            pthread_mutex_unlock(&((*(*s_etat_processus)
                    564:                    .parametres_courbes_de_niveau).mutex));
                    565:            liberation(s_etat_processus, (*s_etat_processus)
                    566:                    .parametres_courbes_de_niveau);
                    567: 
                    568:            for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++)
                    569:            {
                    570:                if ((*s_etat_processus).corps_interruptions[i] != NULL)
                    571:                {
                    572:                    pthread_mutex_trylock(&((*(*s_etat_processus)
                    573:                            .corps_interruptions[i]).mutex));
                    574:                    pthread_mutex_unlock(&((*(*s_etat_processus)
                    575:                            .corps_interruptions[i]).mutex));
                    576: 
                    577:                    liberation(s_etat_processus,
                    578:                            (*s_etat_processus).corps_interruptions[i]);
                    579:                }
                    580: 
                    581:                element_courant = (*s_etat_processus)
                    582:                        .pile_origine_interruptions[i];
                    583: 
                    584:                while(element_courant != NULL)
                    585:                {
                    586:                    element_suivant = (*((struct_liste_chainee *)
                    587:                            element_courant)).suivant;
                    588: 
                    589:                    pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
                    590:                            element_courant)).donnee).mutex));
                    591:                    pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
                    592:                            element_courant)).donnee).mutex));
                    593: 
                    594:                    liberation(s_etat_processus,
                    595:                            (*((struct_liste_chainee *) element_courant))
                    596:                            .donnee);
                    597:                    free(element_courant);
                    598: 
                    599:                    element_courant = element_suivant;
                    600:                }
                    601:            }
                    602: 
1.52      bertrand  603:            liberation_arbre_variables(s_etat_processus,
                    604:                    (*s_etat_processus).s_arbre_variables, d_faux);
1.1       bertrand  605: 
                    606:            for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)
                    607:            {
                    608:                pthread_mutex_trylock(&((*(*s_etat_processus)
                    609:                        .s_liste_variables_statiques[i].objet).mutex));
                    610:                pthread_mutex_unlock(&((*(*s_etat_processus)
                    611:                        .s_liste_variables_statiques[i].objet).mutex));
                    612: 
                    613:                liberation(s_etat_processus, (*s_etat_processus)
                    614:                        .s_liste_variables_statiques[i].objet);
                    615:                free((*s_etat_processus).s_liste_variables_statiques[i].nom);
                    616:            }
                    617: 
                    618:            free((*s_etat_processus).s_liste_variables_statiques);
                    619: 
                    620:            // Ne peut être effacé qu'une seule fois
                    621:            if (suppression_variables_partagees == d_faux)
                    622:            {
                    623:                suppression_variables_partagees = d_vrai;
                    624: 
                    625:                for(i = 0; i < (*(*s_etat_processus)
                    626:                        .s_liste_variables_partagees).nombre_variables; i++)
                    627:                {
                    628:                    pthread_mutex_trylock(&((*(*(*s_etat_processus)
                    629:                            .s_liste_variables_partagees).table[i].objet)
                    630:                            .mutex));
                    631:                    pthread_mutex_unlock(&((*(*(*s_etat_processus)
                    632:                            .s_liste_variables_partagees).table[i].objet)
                    633:                            .mutex));
                    634: 
                    635:                    liberation(s_etat_processus, (*(*s_etat_processus)
                    636:                            .s_liste_variables_partagees).table[i].objet);
                    637:                    free((*(*s_etat_processus).s_liste_variables_partagees)
                    638:                            .table[i].nom);
                    639:                }
                    640: 
                    641:                if ((*(*s_etat_processus).s_liste_variables_partagees).table
                    642:                        != NULL)
                    643:                {
                    644:                    free((struct_variable_partagee *) (*(*s_etat_processus)
                    645:                            .s_liste_variables_partagees).table);
                    646:                }
                    647: 
                    648:                pthread_mutex_trylock(&((*(*s_etat_processus)
                    649:                        .s_liste_variables_partagees).mutex));
                    650:                pthread_mutex_unlock(&((*(*s_etat_processus)
                    651:                        .s_liste_variables_partagees).mutex));
                    652:            }
                    653: 
                    654:            element_courant = (*s_etat_processus).l_base_pile;
                    655:            while(element_courant != NULL)
                    656:            {
                    657:                element_suivant = (*((struct_liste_chainee *)
                    658:                        element_courant)).suivant;
                    659: 
                    660:                pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
                    661:                        element_courant)).donnee).mutex));
                    662:                pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
                    663:                        element_courant)).donnee).mutex));
                    664: 
                    665:                liberation(s_etat_processus,
                    666:                        (*((struct_liste_chainee *)
                    667:                        element_courant)).donnee);
                    668:                free((struct_liste_chainee *) element_courant);
                    669: 
                    670:                element_courant = element_suivant;
                    671:            }
                    672: 
                    673:            element_courant = (*s_etat_processus).l_base_pile_contextes;
                    674:            while(element_courant != NULL)
                    675:            {
                    676:                element_suivant = (*((struct_liste_chainee *)
                    677:                        element_courant)).suivant;
                    678: 
                    679:                pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
                    680:                        element_courant)).donnee).mutex));
                    681:                pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
                    682:                        element_courant)).donnee).mutex));
                    683:                liberation(s_etat_processus, (*((struct_liste_chainee *)
                    684:                        element_courant)).donnee);
                    685:                free((struct_liste_chainee *) element_courant);
                    686: 
                    687:                element_courant = element_suivant;
                    688:            }
                    689: 
                    690:            element_courant = (*s_etat_processus).l_base_pile_taille_contextes;
                    691:            while(element_courant != NULL)
                    692:            {
                    693:                element_suivant = (*((struct_liste_chainee *)
                    694:                        element_courant)).suivant;
                    695: 
                    696:                pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
                    697:                        element_courant)).donnee).mutex));
                    698:                pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
                    699:                        element_courant)).donnee).mutex));
                    700:                liberation(s_etat_processus,
                    701:                        (*((struct_liste_chainee *)
                    702:                        element_courant)).donnee);
                    703:                free((struct_liste_chainee *) element_courant);
                    704: 
                    705:                element_courant = element_suivant;
                    706:            }
                    707: 
                    708:            for(i = 0; i < (*s_etat_processus).nombre_instructions_externes;
                    709:                    i++)
                    710:            {
                    711:                free((*s_etat_processus).s_instructions_externes[i].nom);
                    712:                free((*s_etat_processus).s_instructions_externes[i]
                    713:                        .nom_bibliotheque);
                    714:            }
                    715: 
                    716:            if ((*s_etat_processus).nombre_instructions_externes != 0)
                    717:            {
                    718:                free((*s_etat_processus).s_instructions_externes);
                    719:            }
                    720: 
                    721:            element_courant = (*s_etat_processus).s_bibliotheques;
                    722:            while(element_courant != NULL)
                    723:            {
                    724:                element_suivant = (*((struct_liste_chainee *)
                    725:                        element_courant)).suivant;
                    726: 
                    727:                element_candidat = (*candidat).s_bibliotheques;
                    728:                while(element_candidat != NULL)
                    729:                {
                    730:                    if (((*((struct_bibliotheque *) (*((struct_liste_chainee *)
                    731:                            element_courant)).donnee))
                    732:                            .descripteur == (*((struct_bibliotheque *)
                    733:                            (*((struct_liste_chainee *) element_candidat))
                    734:                            .donnee)).descripteur) &&
                    735:                            ((*((struct_bibliotheque *)
                    736:                            (*((struct_liste_chainee *) element_courant))
                    737:                            .donnee)).pid == (*((struct_bibliotheque *)
                    738:                            (*((struct_liste_chainee *) element_candidat))
                    739:                            .donnee)).pid) && (pthread_equal(
                    740:                            (*((struct_bibliotheque *)
                    741:                            (*((struct_liste_chainee *) element_courant))
                    742:                            .donnee)).tid, (*((struct_bibliotheque *)
                    743:                            (*((struct_liste_chainee *) element_candidat))
                    744:                            .donnee)).tid) != 0))
                    745:                    {
                    746:                        break;
                    747:                    }
                    748: 
                    749:                    element_candidat = (*((struct_liste_chainee *)
                    750:                            element_candidat)).suivant;
                    751:                }
                    752: 
                    753:                if (element_candidat == NULL)
                    754:                {
                    755:                    dlclose((*((struct_bibliotheque *)
                    756:                            (*((struct_liste_chainee *) element_courant))
                    757:                            .donnee)).descripteur);
                    758:                }
                    759: 
                    760:                free((*((struct_bibliotheque *)
                    761:                        (*((struct_liste_chainee *)
                    762:                        element_courant)).donnee)).nom);
                    763:                free((*((struct_liste_chainee *) element_courant)).donnee);
                    764:                free(element_courant);
                    765: 
                    766:                element_courant = element_suivant;
                    767:            }
                    768: 
                    769:            element_courant = (*s_etat_processus).l_base_pile_last;
                    770:            while(element_courant != NULL)
                    771:            {
                    772:                element_suivant = (*((struct_liste_chainee *)
                    773:                        element_courant)).suivant;
                    774: 
                    775:                pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
                    776:                        element_courant)).donnee).mutex));
                    777:                pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
                    778:                        element_courant)).donnee).mutex));
                    779:                liberation(s_etat_processus,
                    780:                        (*((struct_liste_chainee *) element_courant)).donnee);
                    781:                free(element_courant);
                    782: 
                    783:                element_courant = element_suivant;
                    784:            }
                    785: 
                    786:            element_courant = (*s_etat_processus).l_base_pile_systeme;
                    787:            while(element_courant != NULL)
                    788:            {
                    789:                element_suivant = (*((struct_liste_pile_systeme *)
                    790:                        element_courant)).suivant;
                    791: 
                    792:                if ((*((struct_liste_pile_systeme *)
                    793:                        element_courant)).indice_boucle != NULL)
                    794:                {
                    795:                    pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
                    796:                            element_courant)).indice_boucle).mutex));
                    797:                    pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
                    798:                            element_courant)).indice_boucle).mutex));
                    799:                }
                    800: 
                    801:                liberation(s_etat_processus,
                    802:                        (*((struct_liste_pile_systeme *)
                    803:                        element_courant)).indice_boucle);
                    804: 
                    805:                if ((*((struct_liste_pile_systeme *)
                    806:                        element_courant)).limite_indice_boucle != NULL)
                    807:                {
                    808:                    pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
                    809:                            element_courant)).limite_indice_boucle).mutex));
                    810:                    pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
                    811:                            element_courant)).limite_indice_boucle).mutex));
                    812:                }
                    813: 
                    814:                liberation(s_etat_processus,
                    815:                        (*((struct_liste_pile_systeme *)
                    816:                        element_courant)).limite_indice_boucle);
                    817: 
                    818:                if ((*((struct_liste_pile_systeme *)
                    819:                        element_courant)).objet_de_test != NULL)
                    820:                {
                    821:                    pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
                    822:                            element_courant)).objet_de_test).mutex));
                    823:                    pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
                    824:                            element_courant)).objet_de_test).mutex));
                    825:                }
                    826: 
                    827:                liberation(s_etat_processus,
                    828:                        (*((struct_liste_pile_systeme *)
                    829:                        element_courant)).objet_de_test);
                    830: 
                    831:                if ((*((struct_liste_pile_systeme *)
                    832:                        element_courant)).nom_variable != NULL)
                    833:                {
                    834:                    free((*((struct_liste_pile_systeme *)
                    835:                            element_courant)).nom_variable);
                    836:                }
                    837: 
                    838:                free(element_courant);
                    839: 
                    840:                element_courant = element_suivant;
                    841:            }
                    842: 
                    843:            element_courant = (*s_etat_processus).s_fichiers;
                    844:            while(element_courant != NULL)
                    845:            {
                    846:                element_suivant = (*((struct_liste_chainee *)
                    847:                        element_courant)).suivant;
                    848: 
                    849:                element_candidat = (*candidat).s_fichiers;
                    850:                while(element_candidat != NULL)
                    851:                {
                    852:                    if (((*((struct_descripteur_fichier *)
                    853:                            (*((struct_liste_chainee *) element_courant))
                    854:                            .donnee)).pid ==
                    855:                            (*((struct_descripteur_fichier *)
                    856:                            (*((struct_liste_chainee *) element_candidat))
                    857:                            .donnee)).pid) && (pthread_equal(
                    858:                            (*((struct_descripteur_fichier *)
                    859:                            (*((struct_liste_chainee *) element_courant))
                    860:                            .donnee)).tid, (*((struct_descripteur_fichier *)
                    861:                            (*((struct_liste_chainee *) element_candidat))
                    862:                            .donnee)).tid) != 0))
                    863:                    {
1.5       bertrand  864:                        if ((*((struct_descripteur_fichier *)
                    865:                                (*((struct_liste_chainee *) element_courant))
                    866:                                .donnee)).type ==
                    867:                                (*((struct_descripteur_fichier *)
                    868:                                (*((struct_liste_chainee *) element_candidat))
                    869:                                .donnee)).type)
                    870:                        {
                    871:                            if ((*((struct_descripteur_fichier *)
                    872:                                    (*((struct_liste_chainee *)
                    873:                                    element_candidat)).donnee)).type == 'C')
                    874:                            {
                    875:                                if ((*((struct_descripteur_fichier *)
                    876:                                        (*((struct_liste_chainee *)
                    877:                                        element_courant)).donnee))
                    878:                                        .descripteur_c ==
                    879:                                        (*((struct_descripteur_fichier *)
                    880:                                        (*((struct_liste_chainee *)
                    881:                                        element_candidat)).donnee))
                    882:                                        .descripteur_c)
                    883:                                {
                    884:                                    break;
                    885:                                }
                    886:                            }
                    887:                            else
                    888:                            {
                    889:                                if (((*((struct_descripteur_fichier *)
                    890:                                        (*((struct_liste_chainee *)
                    891:                                        element_courant)).donnee))
                    892:                                        .descripteur_sqlite ==
                    893:                                        (*((struct_descripteur_fichier *)
                    894:                                        (*((struct_liste_chainee *)
                    895:                                        element_candidat)).donnee))
                    896:                                        .descripteur_sqlite) &&
                    897:                                        ((*((struct_descripteur_fichier *)
                    898:                                        (*((struct_liste_chainee *)
                    899:                                        element_courant)).donnee))
                    900:                                        .descripteur_c ==
                    901:                                        (*((struct_descripteur_fichier *)
                    902:                                        (*((struct_liste_chainee *)
                    903:                                        element_candidat)).donnee))
                    904:                                        .descripteur_c))
                    905:                                {
                    906:                                    break;
                    907:                                }
                    908:                            }
                    909:                        }
1.1       bertrand  910:                    }
                    911: 
                    912:                    element_candidat = (*((struct_liste_chainee *)
                    913:                            element_candidat)).suivant;
                    914:                }
                    915: 
                    916:                if (element_candidat == NULL)
                    917:                {
                    918:                    fclose((*((struct_descripteur_fichier *)
                    919:                            (*((struct_liste_chainee *) element_courant))
1.5       bertrand  920:                            .donnee)).descripteur_c);
                    921: 
                    922:                    if ((*((struct_descripteur_fichier *)
                    923:                            (*((struct_liste_chainee *) element_courant))
                    924:                            .donnee)).type != 'C')
                    925:                    {
                    926:                        sqlite3_close((*((struct_descripteur_fichier *)
                    927:                                (*((struct_liste_chainee *) element_courant))
                    928:                                .donnee)).descripteur_sqlite);
                    929:                    }
1.1       bertrand  930:                }
                    931: 
                    932:                free((*((struct_descripteur_fichier *)
                    933:                        (*((struct_liste_chainee *)
                    934:                        element_courant)).donnee)).nom);
                    935:                free((struct_descripteur_fichier *)
                    936:                        (*((struct_liste_chainee *)
                    937:                        element_courant)).donnee);
                    938:                free(element_courant);
                    939: 
                    940:                element_courant = element_suivant;
                    941:            }
                    942: 
                    943:            element_courant = (*s_etat_processus).s_sockets;
                    944:            while(element_courant != NULL)
                    945:            {
                    946:                element_suivant = (*((struct_liste_chainee *)
                    947:                        element_courant)).suivant;
                    948: 
                    949:                element_candidat = (*candidat).s_sockets;
                    950:                while(element_candidat != NULL)
                    951:                {
                    952:                    if (((*((struct_socket *)
                    953:                            (*((struct_liste_chainee *) element_courant))
                    954:                            .donnee)).socket == (*((struct_socket *)
                    955:                            (*((struct_liste_chainee *) element_candidat))
                    956:                            .donnee)).socket) &&
                    957:                            ((*((struct_socket *)
                    958:                            (*((struct_liste_chainee *) element_courant))
                    959:                            .donnee)).pid == (*((struct_socket *)
                    960:                            (*((struct_liste_chainee *) element_candidat))
                    961:                            .donnee)).pid) && (pthread_equal(
                    962:                            (*((struct_socket *)
                    963:                            (*((struct_liste_chainee *) element_courant))
                    964:                            .donnee)).tid, (*((struct_socket *)
                    965:                            (*((struct_liste_chainee *) element_candidat))
                    966:                            .donnee)).tid) != 0))
                    967:                    {
                    968:                        break;
                    969:                    }
                    970: 
                    971:                    element_candidat = (*((struct_liste_chainee *)
                    972:                            element_candidat)).suivant;
                    973:                }
                    974: 
                    975:                if (element_candidat == NULL)
                    976:                {
                    977:                    if ((*((struct_socket *) (*((struct_liste_chainee *)
                    978:                            element_courant)).donnee)).socket_connectee
                    979:                            == d_vrai)
                    980:                    {
                    981:                        shutdown((*((struct_socket *)
                    982:                                (*((struct_liste_chainee *) element_courant))
                    983:                                .donnee)).socket, SHUT_RDWR);
                    984:                    }
                    985: 
                    986:                    close((*((struct_socket *)
                    987:                            (*((struct_liste_chainee *) element_courant))
                    988:                            .donnee)).socket);
                    989:                }
                    990: 
                    991:                pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
                    992:                        element_courant)).donnee).mutex));
                    993:                pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
                    994:                        element_courant)).donnee).mutex));
                    995: 
                    996:                liberation(s_etat_processus,
                    997:                        (*((struct_liste_chainee *)
                    998:                        element_courant)).donnee);
                    999:                free(element_courant);
                   1000: 
                   1001:                element_courant = element_suivant;
                   1002:            }
                   1003: 
1.14      bertrand 1004: /*
                   1005: ================================================================================
                   1006:   À noter : on ne ferme pas la connexion car la conséquence immédiate est
                   1007:   une destruction de l'objet pour le processus père.
                   1008: ================================================================================
                   1009: 
1.1       bertrand 1010:            element_courant = (*s_etat_processus).s_connecteurs_sql;
                   1011:            while(element_courant != NULL)
                   1012:            {
                   1013:                element_suivant = (*((struct_liste_chainee *)
                   1014:                        element_courant)).suivant;
                   1015: 
                   1016:                element_candidat = (*candidat).s_connecteurs_sql;
                   1017:                while(element_candidat != NULL)
                   1018:                {
                   1019:                    if (((
                   1020: #ifdef MYSQL_SUPPORT
                   1021:                            ((*((struct_connecteur_sql *)
                   1022:                            (*((struct_liste_chainee *) element_courant))
                   1023:                            .donnee)).descripteur.mysql ==
                   1024:                            (*((struct_connecteur_sql *)
                   1025:                            (*((struct_liste_chainee *) element_candidat))
                   1026:                            .donnee)).descripteur.mysql)
                   1027:                            &&
                   1028:                            (strcmp((*((struct_connecteur_sql *)
                   1029:                            (*((struct_liste_chainee *) element_courant))
                   1030:                            .donnee)).type, "MYSQL") == 0)
                   1031:                            &&
                   1032:                            (strcmp((*((struct_connecteur_sql *)
                   1033:                            (*((struct_liste_chainee *) element_candidat))
                   1034:                            .donnee)).type, "MYSQL") == 0)
                   1035: #else
                   1036:                            0
                   1037: #endif
                   1038:                            ) || (
                   1039: #ifdef POSTGRESQL_SUPPORT
                   1040:                            ((*((struct_connecteur_sql *)
                   1041:                            (*((struct_liste_chainee *) element_courant))
                   1042:                            .donnee)).descripteur.postgresql ==
                   1043:                            (*((struct_connecteur_sql *)
                   1044:                            (*((struct_liste_chainee *) element_candidat))
                   1045:                            .donnee)).descripteur.postgresql)
                   1046:                            &&
                   1047:                            (strcmp((*((struct_connecteur_sql *)
                   1048:                            (*((struct_liste_chainee *) element_courant))
                   1049:                            .donnee)).type, "POSTGRESQL") == 0)
                   1050:                            &&
                   1051:                            (strcmp((*((struct_connecteur_sql *)
                   1052:                            (*((struct_liste_chainee *) element_candidat))
                   1053:                            .donnee)).type, "POSTGRESQL") == 0)
                   1054: #else
                   1055:                            0
                   1056: #endif
                   1057:                            )) &&
                   1058:                            ((*((struct_connecteur_sql *)
                   1059:                            (*((struct_liste_chainee *) element_courant))
                   1060:                            .donnee)).pid == (*((struct_connecteur_sql *)
                   1061:                            (*((struct_liste_chainee *) element_candidat))
                   1062:                            .donnee)).pid) && (pthread_equal(
                   1063:                            (*((struct_connecteur_sql *)
                   1064:                            (*((struct_liste_chainee *) element_courant))
                   1065:                            .donnee)).tid, (*((struct_connecteur_sql *)
                   1066:                            (*((struct_liste_chainee *) element_candidat))
                   1067:                            .donnee)).tid) != 0))
                   1068:                    {
                   1069:                        break;
                   1070:                    }
                   1071: 
                   1072:                    element_candidat = (*((struct_liste_chainee *)
                   1073:                            element_candidat)).suivant;
                   1074:                }
                   1075: 
                   1076:                if (element_candidat == NULL)
                   1077:                {
                   1078:                    sqlclose((*((struct_liste_chainee *) element_courant))
                   1079:                            .donnee);
                   1080:                }
                   1081: 
                   1082:                pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
                   1083:                        element_courant)).donnee).mutex));
                   1084:                pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
                   1085:                        element_courant)).donnee).mutex));
                   1086: 
                   1087:                liberation(s_etat_processus, (*((struct_liste_chainee *)
                   1088:                        element_courant)).donnee);
                   1089:                free(element_courant);
                   1090: 
                   1091:                element_courant = element_suivant;
                   1092:            }
1.14      bertrand 1093: */
1.1       bertrand 1094: 
1.15      bertrand 1095:            (*s_etat_processus).s_connecteurs_sql = NULL;
                   1096: 
1.1       bertrand 1097:            element_courant = (*s_etat_processus).s_marques;
                   1098:            while(element_courant != NULL)
                   1099:            {
                   1100:                free((*((struct_marque *) element_courant)).label);
                   1101:                free((*((struct_marque *) element_courant)).position);
                   1102:                element_suivant = (*((struct_marque *) element_courant))
                   1103:                        .suivant;
                   1104:                free(element_courant);
                   1105:                element_courant = element_suivant;
                   1106:            }
                   1107: 
                   1108:            liberation_allocateur(s_etat_processus);
                   1109: 
1.68    ! bertrand 1110:            pthread_mutex_unlock(&((*s_etat_processus).mutex_fork));
        !          1111:            pthread_mutex_destroy(&((*s_etat_processus).mutex_fork));
1.1       bertrand 1112: 
1.59      bertrand 1113:            liberation_contexte_cas(s_etat_processus);
1.1       bertrand 1114:            free(s_etat_processus);
                   1115: 
                   1116:            s_etat_processus = candidat;
                   1117:        }
                   1118: 
                   1119:        l_element_suivant = (*l_element_courant).suivant;
                   1120: 
                   1121:        free((struct_thread *) (*l_element_courant).donnee);
                   1122:        free((struct_liste_chainee *) l_element_courant);
                   1123: 
                   1124:        l_element_courant = l_element_suivant;
                   1125:    }
                   1126: 
                   1127:    liste_threads = NULL;
                   1128: 
                   1129:    l_element_courant = liste_threads_surveillance;
                   1130: 
                   1131:    while(l_element_courant != NULL)
                   1132:    {
                   1133:        s_argument_thread = (struct_descripteur_thread *)
                   1134:                (*l_element_courant).donnee;
                   1135: 
1.40      bertrand 1136:        if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
                   1137:                != 0)
1.1       bertrand 1138:        {
                   1139:            (*s_etat_processus).erreur_systeme = d_es_processus;
1.68    ! bertrand 1140:            pthread_mutex_unlock(&mutex_liste_threads);
1.1       bertrand 1141:            return;
                   1142:        }
                   1143: 
                   1144:        (*s_argument_thread).nombre_references--;
                   1145: 
                   1146:        BUG((*s_argument_thread).nombre_references < 0,
                   1147:                printf("(*s_argument_thread).nombre_references = %d\n",
                   1148:                (int) (*s_argument_thread).nombre_references));
                   1149: 
                   1150:        if ((*s_argument_thread).nombre_references == 0)
                   1151:        {
1.20      bertrand 1152:            close((*s_argument_thread).pipe_objets[0]);
                   1153:            close((*s_argument_thread).pipe_acquittement[1]);
                   1154:            close((*s_argument_thread).pipe_injections[1]);
                   1155:            close((*s_argument_thread).pipe_nombre_injections[1]);
                   1156:            close((*s_argument_thread).pipe_nombre_objets_attente[0]);
                   1157:            close((*s_argument_thread).pipe_interruptions[0]);
                   1158:            close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);
                   1159: 
1.40      bertrand 1160:            if (pthread_mutex_unlock(&((*s_argument_thread)
                   1161:                    .mutex_nombre_references)) != 0)
1.1       bertrand 1162:            {
                   1163:                (*s_etat_processus).erreur_systeme = d_es_processus;
1.68    ! bertrand 1164:                pthread_mutex_unlock(&mutex_liste_threads);
1.1       bertrand 1165:                return;
                   1166:            }
                   1167: 
                   1168:            pthread_mutex_destroy(&((*s_argument_thread).mutex));
1.40      bertrand 1169:            pthread_mutex_destroy(&((*s_argument_thread)
                   1170:                    .mutex_nombre_references));
1.20      bertrand 1171: 
                   1172:            if ((*s_argument_thread).processus_detache == d_faux)
                   1173:            {
                   1174:                if ((*s_argument_thread).destruction_objet == d_vrai)
                   1175:                {
                   1176:                    liberation(s_etat_processus, (*s_argument_thread).argument);
                   1177:                }
                   1178:            }
                   1179: 
1.1       bertrand 1180:            free(s_argument_thread);
                   1181:        }
                   1182:        else
                   1183:        {
1.40      bertrand 1184:            if (pthread_mutex_unlock(&((*s_argument_thread)
                   1185:                    .mutex_nombre_references)) != 0)
1.1       bertrand 1186:            {
                   1187:                (*s_etat_processus).erreur_systeme = d_es_processus;
1.68    ! bertrand 1188:                pthread_mutex_unlock(&mutex_liste_threads);
1.1       bertrand 1189:                return;
                   1190:            }
                   1191:        }
                   1192: 
                   1193:        l_element_suivant = (*l_element_courant).suivant;
                   1194:        free((struct_liste_chainee *) l_element_courant);
                   1195:        l_element_courant = l_element_suivant;
                   1196:    }
                   1197: 
                   1198:    liste_threads_surveillance = NULL;
                   1199: 
1.68    ! bertrand 1200:    if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1.1       bertrand 1201:    {
                   1202:        (*s_etat_processus).erreur_systeme = d_es_processus;
                   1203:        return;
                   1204:    }
                   1205: 
                   1206:    return;
                   1207: }
                   1208: 
                   1209: static struct_processus *
                   1210: recherche_thread(pid_t pid, pthread_t tid)
                   1211: {
                   1212:    volatile struct_liste_chainee_volatile      *l_element_courant;
                   1213: 
                   1214:    struct_processus                            *s_etat_processus;
                   1215: 
                   1216:    l_element_courant = liste_threads;
                   1217: 
                   1218:    while(l_element_courant != NULL)
                   1219:    {
                   1220:        if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee))
                   1221:                .tid, tid) != 0) && ((*((struct_thread *)
                   1222:                (*l_element_courant).donnee)).pid == pid))
                   1223:        {
                   1224:            break;
                   1225:        }
                   1226: 
                   1227:        l_element_courant = (*l_element_courant).suivant;
                   1228:    }
                   1229: 
                   1230:    if (l_element_courant == NULL)
                   1231:    {
                   1232:        /*
                   1233:         * Le processus n'existe plus. On ne distribue aucun signal.
                   1234:         */
                   1235: 
                   1236:        return(NULL);
                   1237:    }
                   1238: 
                   1239:    s_etat_processus = (*((struct_thread *)
                   1240:            (*l_element_courant).donnee)).s_etat_processus;
                   1241: 
                   1242:    return(s_etat_processus);
                   1243: }
                   1244: 
1.66      bertrand 1245: static struct_processus *
                   1246: recherche_thread_principal(pid_t pid)
1.1       bertrand 1247: {
                   1248:    volatile struct_liste_chainee_volatile      *l_element_courant;
                   1249: 
                   1250:    l_element_courant = liste_threads;
                   1251: 
                   1252:    while(l_element_courant != NULL)
                   1253:    {
                   1254:        if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal
                   1255:                == d_vrai) && ((*((struct_thread *)
                   1256:                (*l_element_courant).donnee)).pid == pid))
                   1257:        {
                   1258:            break;
                   1259:        }
                   1260: 
                   1261:        l_element_courant = (*l_element_courant).suivant;
                   1262:    }
                   1263: 
                   1264:    if (l_element_courant == NULL)
                   1265:    {
                   1266:        /*
                   1267:         * Le processus n'existe plus. On ne distribue aucun signal.
                   1268:         */
                   1269: 
1.66      bertrand 1270:        return(NULL);
1.1       bertrand 1271:    }
                   1272: 
1.66      bertrand 1273:    return((*((struct_thread *) (*l_element_courant).donnee))
                   1274:            .s_etat_processus);
1.1       bertrand 1275: }
                   1276: 
                   1277: 
                   1278: /*
                   1279: ================================================================================
                   1280:   Procédures de gestion des signaux d'interruption
                   1281: ================================================================================
                   1282:   Entrée : variable globale
                   1283: --------------------------------------------------------------------------------
                   1284:   Sortie : variable globale modifiée
                   1285: --------------------------------------------------------------------------------
                   1286:   Effets de bord : néant
                   1287: ================================================================================
                   1288: */
                   1289: 
                   1290: // Les routines suivantes sont uniquement appelées depuis les gestionnaires
1.17      bertrand 1291: // des signaux asynchrones. Elles ne doivent pas bloquer dans le cas où
1.1       bertrand 1292: // les sémaphores sont déjà bloqués par un gestionnaire de signal.
                   1293: 
                   1294: static inline void
1.68    ! bertrand 1295: verrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
1.1       bertrand 1296: {
                   1297:    int         semaphore;
                   1298: 
1.68    ! bertrand 1299:    if (pthread_mutex_unlock(&((*s_etat_processus).mutex_fork)) != 0)
1.1       bertrand 1300:    {
1.68    ! bertrand 1301:        BUG(1, uprintf("Lock error !\n"));
        !          1302:        return;
1.1       bertrand 1303:    }
                   1304: 
                   1305:    // Il faut respecteur l'atomicité des deux opérations suivantes !
                   1306: 
1.68    ! bertrand 1307:    if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) != 0)
1.1       bertrand 1308:    {
1.68    ! bertrand 1309:        pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
        !          1310:        BUG(1, uprintf("Unlock error !\n"));
        !          1311:        return;
1.1       bertrand 1312:    }
                   1313: 
1.8       bertrand 1314: #  ifndef SEMAPHORES_NOMMES
1.1       bertrand 1315:    if (sem_post(&semaphore_gestionnaires_signaux) == -1)
1.8       bertrand 1316: #  else
                   1317:    if (sem_post(semaphore_gestionnaires_signaux) == -1)
                   1318: #  endif
1.1       bertrand 1319:    {
1.68    ! bertrand 1320:        pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
1.1       bertrand 1321:        BUG(1, uprintf("Lock error !\n"));
                   1322:        return;
                   1323:    }
                   1324: 
1.8       bertrand 1325: #  ifndef SEMAPHORES_NOMMES
1.1       bertrand 1326:    if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1.8       bertrand 1327: #  else
                   1328:    if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
                   1329: #  endif
1.1       bertrand 1330:    {
1.68    ! bertrand 1331:        pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
1.1       bertrand 1332:        BUG(1, uprintf("Lock error !\n"));
                   1333:        return;
                   1334:    }
                   1335: 
1.68    ! bertrand 1336:    if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)
1.1       bertrand 1337:    {
1.68    ! bertrand 1338:        pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
1.1       bertrand 1339:        BUG(1, uprintf("Unlock error !\n"));
                   1340:        return;
                   1341:    }
                   1342: 
                   1343:    if (semaphore == 1)
                   1344:    {
                   1345:        // Le semaphore ne peut être pris par le thread qui a appelé
                   1346:        // le gestionnaire de signal car le signal est bloqué par ce thread
                   1347:        // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que
                   1348:        // par un thread concurrent. On essaye donc de le bloquer jusqu'à
                   1349:        // ce que ce soit possible.
                   1350: 
1.68    ! bertrand 1351:        if (pthread_mutex_lock(&mutex_liste_threads) != 0)
1.1       bertrand 1352:        {
1.68    ! bertrand 1353:            pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
        !          1354:            BUG(1, uprintf("Lock error !\n"));
        !          1355:            return;
1.1       bertrand 1356:        }
                   1357:    }
                   1358: 
                   1359:    return;
                   1360: }
                   1361: 
                   1362: static inline void
1.68    ! bertrand 1363: deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
1.1       bertrand 1364: {
                   1365:    int         semaphore;
                   1366: 
                   1367:    // Il faut respecteur l'atomicité des deux opérations suivantes !
                   1368: 
1.68    ! bertrand 1369:    if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) == -1)
1.1       bertrand 1370:    {
1.68    ! bertrand 1371:        pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
        !          1372:        BUG(1, uprintf("Unlock error !\n"));
        !          1373:        return;
1.1       bertrand 1374:    }
                   1375: 
1.8       bertrand 1376: #  ifndef SEMAPHORES_NOMMES
1.1       bertrand 1377:    if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1.8       bertrand 1378: #  else
                   1379:    if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
                   1380: #  endif
1.1       bertrand 1381:    {
1.68    ! bertrand 1382:        pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
1.1       bertrand 1383:        BUG(1, uprintf("Unlock error !\n"));
                   1384:        return;
                   1385:    }
                   1386: 
1.8       bertrand 1387: #  ifndef SEMAPHORES_NOMMES
1.1       bertrand 1388:    while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
1.8       bertrand 1389: #  else
                   1390:    while(sem_wait(semaphore_gestionnaires_signaux) == -1)
                   1391: #  endif
1.1       bertrand 1392:    {
                   1393:        if (errno != EINTR)
                   1394:        {
1.68    ! bertrand 1395:            pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
1.1       bertrand 1396:            BUG(1, uprintf("Unlock error !\n"));
                   1397:            return;
                   1398:        }
                   1399:    }
                   1400: 
1.68    ! bertrand 1401:    if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)
1.1       bertrand 1402:    {
1.68    ! bertrand 1403:        pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
1.1       bertrand 1404:        BUG(1, uprintf("Unlock error !\n"));
                   1405:        return;
                   1406:    }
                   1407: 
1.68    ! bertrand 1408:    if (pthread_mutex_lock(&((*s_etat_processus).mutex_fork)) != 0)
1.1       bertrand 1409:    {
1.68    ! bertrand 1410:        BUG(1, uprintf("Unlock error !\n"));
        !          1411:        return;
1.1       bertrand 1412:    }
                   1413: 
                   1414:    if (semaphore == 1)
                   1415:    {
1.68    ! bertrand 1416:        if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1.1       bertrand 1417:        {
                   1418:            BUG(1, uprintf("Unlock error !\n"));
                   1419:            return;
                   1420:        }
                   1421:    }
                   1422: 
                   1423:    return;
                   1424: }
                   1425: 
1.65      bertrand 1426: #define test_signal(signal) \
1.67      bertrand 1427:    if (signal_test == SIGTEST) { signal_test = signal; return; }
1.66      bertrand 1428: 
1.67      bertrand 1429: // Récupération des signaux
                   1430: // - SIGINT    (arrêt au clavier)
                   1431: // - SIGTERM (signal d'arrêt en provenance du système)
1.65      bertrand 1432: 
1.67      bertrand 1433: void
                   1434: interruption1(int signal)
1.30      bertrand 1435: {
1.67      bertrand 1436:    test_signal(signal);
1.30      bertrand 1437: 
1.67      bertrand 1438:    switch(signal)
1.31      bertrand 1439:    {
1.67      bertrand 1440:        case SIGINT:
                   1441:            envoi_signal_processus(getpid(), rpl_sigint);
                   1442:            break;
1.66      bertrand 1443: 
1.67      bertrand 1444:        case SIGTERM:
                   1445:            envoi_signal_processus(getpid(), rpl_sigterm);
                   1446:            break;
1.31      bertrand 1447: 
1.67      bertrand 1448:        case SIGALRM:
                   1449:            envoi_signal_processus(getpid(), rpl_sigalrm);
                   1450:            break;
1.31      bertrand 1451:    }
1.66      bertrand 1452: 
1.67      bertrand 1453:    return;
1.66      bertrand 1454: }
                   1455: 
1.67      bertrand 1456: inline static void
                   1457: signal_alrm(struct_processus *s_etat_processus, pid_t pid)
1.66      bertrand 1458: {
1.67      bertrand 1459:    struct_processus        *s_thread_principal;
1.66      bertrand 1460: 
1.68    ! bertrand 1461:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.67      bertrand 1462: 
                   1463:    if (pid == getpid())
                   1464:    {
                   1465:        // Si pid est égal à getpid(), le signal à traiter est issu
                   1466:        // du même processus que celui qui va le traiter, mais d'un thread
                   1467:        // différent.
1.66      bertrand 1468: 
1.67      bertrand 1469:        if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1.66      bertrand 1470:        {
1.67      bertrand 1471:            printf("[%d] RPL/SIGALRM (thread %llu)\n", (int) getpid(),
                   1472:                    (unsigned long long) pthread_self());
                   1473:            fflush(stdout);
                   1474:        }
1.66      bertrand 1475: 
1.67      bertrand 1476:        if ((*s_etat_processus).pid_processus_pere != getpid())
                   1477:        {
                   1478:            // On n'est pas dans le processus père, on remonte le signal.
                   1479:            envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                   1480:                    rpl_sigalrm);
1.66      bertrand 1481:        }
                   1482:        else
                   1483:        {
1.67      bertrand 1484:            // On est dans le processus père, on effectue un arrêt d'urgence.
                   1485:            (*s_etat_processus).var_volatile_alarme = -1;
                   1486:            (*s_etat_processus).var_volatile_requete_arret = -1;
1.66      bertrand 1487:        }
1.67      bertrand 1488:    }
                   1489:    else
                   1490:    {
                   1491:        // Le signal est issu d'un processus différent. On recherche le
                   1492:        // thread principal pour remonter le signal.
1.66      bertrand 1493: 
1.67      bertrand 1494:        if ((s_thread_principal = recherche_thread_principal(getpid()))
                   1495:                != NULL)
1.66      bertrand 1496:        {
1.67      bertrand 1497:            envoi_signal_contexte(s_thread_principal, rpl_sigalrm);
1.66      bertrand 1498:        }
1.67      bertrand 1499:    }
1.29      bertrand 1500: 
1.68    ! bertrand 1501:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.66      bertrand 1502:    return;
                   1503: }
                   1504: 
1.67      bertrand 1505: inline static void
                   1506: signal_term(struct_processus *s_etat_processus, pid_t pid)
1.66      bertrand 1507: {
1.67      bertrand 1508:    struct_processus        *s_thread_principal;
1.66      bertrand 1509:    volatile sig_atomic_t   exclusion = 0;
                   1510: 
1.68    ! bertrand 1511:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.66      bertrand 1512: 
1.67      bertrand 1513:    if (pid == getpid())
1.1       bertrand 1514:    {
1.67      bertrand 1515:        if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
                   1516:        {
                   1517:            printf("[%d] RPL/SIGTERM (thread %llu)\n", (int) getpid(),
                   1518:                    (unsigned long long) pthread_self());
                   1519:            fflush(stdout);
                   1520:        }
                   1521: 
                   1522:        if ((*s_etat_processus).pid_processus_pere != getpid())
                   1523:        {
                   1524:            envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                   1525:                    rpl_sigterm);
                   1526:        }
                   1527:        else
1.1       bertrand 1528:        {
1.67      bertrand 1529:            (*s_etat_processus).var_volatile_traitement_sigint = -1;
                   1530: 
                   1531:            while(exclusion == 1);
                   1532:            exclusion = 1;
1.1       bertrand 1533: 
1.67      bertrand 1534:            if ((*s_etat_processus).var_volatile_requete_arret == -1)
1.1       bertrand 1535:            {
1.68    ! bertrand 1536:                deverrouillage_gestionnaire_signaux(s_etat_processus);
1.67      bertrand 1537:                exclusion = 0;
                   1538:                return;
1.1       bertrand 1539:            }
                   1540: 
1.67      bertrand 1541:            (*s_etat_processus).var_volatile_requete_arret = -1;
                   1542:            (*s_etat_processus).var_volatile_alarme = -1;
                   1543: 
                   1544:            exclusion = 0;
1.1       bertrand 1545:        }
1.67      bertrand 1546:    }
                   1547:    else
                   1548:    {
                   1549:        if ((s_thread_principal = recherche_thread_principal(getpid()))
                   1550:                != NULL)
1.1       bertrand 1551:        {
1.67      bertrand 1552:            envoi_signal_contexte(s_thread_principal, rpl_sigterm);
                   1553:        }
                   1554:    }
1.44      bertrand 1555: 
1.68    ! bertrand 1556:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.67      bertrand 1557:    return;
                   1558: }
1.1       bertrand 1559: 
1.67      bertrand 1560: inline static void
                   1561: signal_int(struct_processus *s_etat_processus, pid_t pid)
                   1562: {
                   1563:    struct_processus        *s_thread_principal;
                   1564:    volatile sig_atomic_t   exclusion = 0;
1.1       bertrand 1565: 
1.68    ! bertrand 1566:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 1567: 
1.67      bertrand 1568:    if (pid == getpid())
                   1569:    {
                   1570:        if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
                   1571:        {
                   1572:            printf("[%d] RPL/SIGINT (thread %llu)\n", (int) getpid(),
                   1573:                    (unsigned long long) pthread_self());
                   1574:            fflush(stdout);
                   1575:        }
1.1       bertrand 1576: 
1.67      bertrand 1577:        if ((*s_etat_processus).pid_processus_pere != getpid())
                   1578:        {
                   1579:            envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                   1580:                    rpl_sigint);
                   1581:        }
                   1582:        else
                   1583:        {
                   1584:            (*s_etat_processus).var_volatile_traitement_sigint = -1;
1.44      bertrand 1585: 
1.67      bertrand 1586:            while(exclusion == 1);
                   1587:            exclusion = 1;
1.1       bertrand 1588: 
1.67      bertrand 1589:            if ((*s_etat_processus).var_volatile_requete_arret == -1)
                   1590:            {
1.68    ! bertrand 1591:                deverrouillage_gestionnaire_signaux(s_etat_processus);
1.67      bertrand 1592:                exclusion = 0;
                   1593:                return;
                   1594:            }
1.1       bertrand 1595: 
1.67      bertrand 1596:            if ((*s_etat_processus).langue == 'F')
                   1597:            {
                   1598:                printf("+++Interruption\n");
1.1       bertrand 1599:            }
                   1600:            else
                   1601:            {
1.67      bertrand 1602:                printf("+++Interrupt\n");
1.1       bertrand 1603:            }
                   1604: 
1.67      bertrand 1605:            fflush(stdout);
                   1606: 
                   1607:            (*s_etat_processus).var_volatile_requete_arret = -1;
                   1608:            (*s_etat_processus).var_volatile_alarme = -1;
                   1609: 
                   1610:            exclusion = 0;
1.1       bertrand 1611:        }
1.67      bertrand 1612:    }
                   1613:    else
                   1614:    {
                   1615:        if ((s_thread_principal = recherche_thread_principal(getpid()))
                   1616:                != NULL)
1.1       bertrand 1617:        {
1.67      bertrand 1618:            envoi_signal_contexte(s_thread_principal, rpl_sigint);
1.1       bertrand 1619:        }
                   1620:    }
                   1621: 
1.68    ! bertrand 1622:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 1623:    return;
                   1624: }
                   1625: 
1.67      bertrand 1626: // Récupération des signaux
                   1627: // - SIGFSTP
                   1628: //
                   1629: // ATTENTION :
                   1630: // Le signal SIGFSTP provient de la mort du processus de contrôle.
                   1631: // Sous certains systèmes (Linux...), la mort du terminal de contrôle
                   1632: // se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
                   1633: // (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
                   1634: // non initialisée (pointeur NULL) issue de TERMIO.
                   1635: 
1.1       bertrand 1636: void
1.67      bertrand 1637: interruption2(int signal)
1.1       bertrand 1638: {
1.65      bertrand 1639:    test_signal(signal);
1.67      bertrand 1640:    envoi_signal_processus(getpid(), rpl_sigtstp);
1.66      bertrand 1641:    return;
                   1642: }
                   1643: 
1.67      bertrand 1644: static inline void
                   1645: signal_tstp(struct_processus *s_etat_processus, pid_t pid)
1.66      bertrand 1646: {
                   1647:    struct_processus        *s_thread_principal;
                   1648: 
1.68    ! bertrand 1649:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 1650: 
1.30      bertrand 1651:    if (pid == getpid())
1.1       bertrand 1652:    {
                   1653:        /*
                   1654:         *  0 => fonctionnement normal
                   1655:         * -1 => requête
                   1656:         *  1 => requête acceptée en attente de traitement
                   1657:         */
                   1658: 
                   1659:        if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
                   1660:        {
1.67      bertrand 1661:            printf("[%d] RPL/SIGTSTP (thread %llu)\n", (int) getpid(),
1.1       bertrand 1662:                    (unsigned long long) pthread_self());
                   1663:            fflush(stdout);
                   1664:        }
                   1665: 
                   1666:        if ((*s_etat_processus).var_volatile_processus_pere == 0)
                   1667:        {
1.67      bertrand 1668:            envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                   1669:                    rpl_sigtstp);
1.1       bertrand 1670:        }
                   1671:        else
                   1672:        {
                   1673:            (*s_etat_processus).var_volatile_requete_arret2 = -1;
                   1674:        }
                   1675:    }
                   1676:    else
                   1677:    {
                   1678:        // Envoi d'un signal au thread maître du groupe.
                   1679: 
1.66      bertrand 1680:        if ((s_thread_principal = recherche_thread_principal(getpid()))
                   1681:                != NULL)
1.1       bertrand 1682:        {
1.67      bertrand 1683:            envoi_signal_contexte(s_thread_principal, rpl_sigtstp);
1.1       bertrand 1684:        }
                   1685:    }
                   1686: 
1.68    ! bertrand 1687:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 1688:    return;
                   1689: }
                   1690: 
                   1691: void
1.67      bertrand 1692: interruption3(int signal)
1.1       bertrand 1693: {
1.66      bertrand 1694:    // Si on passe par ici, c'est qu'il est impossible de récupérer
                   1695:    // l'erreur d'accès à la mémoire. On sort donc du programme quitte à
                   1696:    // ce qu'il reste des processus orphelins.
                   1697: 
                   1698:    unsigned char       message[] = "+++System : Uncaught access violation\n"
1.67      bertrand 1699:                                "+++System : Aborting !\n";
                   1700: 
                   1701:    test_signal(signal);
1.66      bertrand 1702: 
                   1703:    if (pid_processus_pere == getpid())
                   1704:    {
                   1705:        kill(pid_processus_pere, SIGALRM);
                   1706:    }
                   1707: 
                   1708:    write(STDERR_FILENO, message, strlen(message));
                   1709:    _exit(EXIT_FAILURE);
                   1710: }
                   1711: 
1.67      bertrand 1712: #if 0
                   1713: // Utiliser libsigsegv
1.66      bertrand 1714: void INTERRUPTION3_A_FIXER()
                   1715: {
1.63      bertrand 1716:    pthread_t               thread;
                   1717: 
1.1       bertrand 1718:    struct_processus        *s_etat_processus;
                   1719: 
1.65      bertrand 1720:    test_signal(signal);
1.68    ! bertrand 1721:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.32      bertrand 1722: 
1.1       bertrand 1723:    if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
                   1724:    {
1.68    ! bertrand 1725:        deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 1726:        return;
                   1727:    }
                   1728: 
                   1729:    if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
                   1730:    {
                   1731:        printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),
                   1732:                (unsigned long long) pthread_self());
                   1733:        fflush(stdout);
                   1734:    }
                   1735: 
                   1736:    if ((*s_etat_processus).var_volatile_recursivite == -1)
                   1737:    {
                   1738:        // Segfault dans un appel de fonction récursive
1.68    ! bertrand 1739:        deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 1740:        longjmp(contexte, -1);
                   1741:    }
                   1742:    else
                   1743:    {
                   1744:        // Segfault dans une routine interne
                   1745:        if (strncmp(getenv("LANG"), "fr", 2) == 0)
                   1746:        {
1.63      bertrand 1747:            printf("+++Système : Violation d'accès\n");
1.1       bertrand 1748:        }
                   1749:        else
                   1750:        {
1.63      bertrand 1751:            printf("+++System : Access violation\n");
1.1       bertrand 1752:        }
                   1753: 
                   1754:        fflush(stdout);
                   1755: 
1.63      bertrand 1756:        (*s_etat_processus).compteur_violation_d_acces++;
1.1       bertrand 1757: 
1.63      bertrand 1758:        if ((*s_etat_processus).compteur_violation_d_acces > 1)
1.1       bertrand 1759:        {
1.63      bertrand 1760:            // On vient de récupérer plus d'une erreur de segmentation
                   1761:            // dans le même processus ou le même thread. L'erreur n'est pas
                   1762:            // récupérable et on sort autoritairement du programme. Il peut
                   1763:            // rester des processus orphelins en attente !
                   1764: 
                   1765:            if (strncmp(getenv("LANG"), "fr", 2) == 0)
                   1766:            {
1.64      bertrand 1767:                printf("+++Système : Violation d'accès, tentative de "
                   1768:                        "terminaison de la tâche\n");
                   1769:                printf("             (defauts multiples)\n");
1.63      bertrand 1770:            }
                   1771:            else
                   1772:            {
1.64      bertrand 1773:                printf("+++System : Access violation, trying to kill task "
                   1774:                        "(multiple defaults)\n");
1.63      bertrand 1775:            }
                   1776: 
                   1777:            fflush(stdout);
                   1778: 
1.68    ! bertrand 1779:            deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 1780:            exit(EXIT_FAILURE);
                   1781:        }
                   1782:        else
                   1783:        {
1.63      bertrand 1784:            // Première erreur de segmentation. On essaie de terminer
                   1785:            // proprement le thread ou le processus. Le signal ne peut être
                   1786:            // envoyé que depuis le même processus.
                   1787: 
                   1788:            if (recherche_thread_principal(getpid(), &thread) == d_vrai)
                   1789:            {
                   1790:                if (pthread_equal(thread, pthread_self()) != 0)
                   1791:                {
1.68    ! bertrand 1792:                    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.63      bertrand 1793: 
                   1794:                    if ((*s_etat_processus).pid_processus_pere != getpid())
                   1795:                    {
                   1796:                        // On est dans le thread principal d'un processus.
                   1797: 
                   1798:                        longjmp(contexte_processus, -1);
                   1799:                    }
                   1800:                    else
                   1801:                    {
                   1802:                        // On est dans le thread principal du processus
                   1803:                        // père.
                   1804: 
                   1805:                        longjmp(contexte_initial, -1);
                   1806:                    }
                   1807:                }
                   1808:                else
                   1809:                {
                   1810:                    // On est dans un thread fils d'un thread principal.
                   1811: 
1.68    ! bertrand 1812:                    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.63      bertrand 1813:                    longjmp(contexte_thread, -1);
                   1814:                }
                   1815:            }
                   1816: 
                   1817:            // Là, on ramasse les miettes puisque le thread n'existe plus
                   1818:            // dans la base (corruption de la mémoire).
                   1819: 
1.68    ! bertrand 1820:            deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 1821:            longjmp(contexte_initial, -1);
                   1822:        }
                   1823:    }
                   1824: 
1.68    ! bertrand 1825:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 1826:    return;
                   1827: }
1.67      bertrand 1828: #endif
                   1829: 
                   1830: // Traitement de rpl_sigstart
1.1       bertrand 1831: 
1.67      bertrand 1832: static inline void
                   1833: signal_start(struct_processus *s_etat_processus, pid_t pid)
1.1       bertrand 1834: {
1.67      bertrand 1835:    (*s_etat_processus).demarrage_fils = d_vrai;
                   1836:    return;
                   1837: }
1.32      bertrand 1838: 
1.67      bertrand 1839: // Traitement de rpl_sigcont
1.1       bertrand 1840: 
1.67      bertrand 1841: static inline void
                   1842: signal_cont(struct_processus *s_etat_processus, pid_t pid)
                   1843: {
                   1844:    (*s_etat_processus).redemarrage_processus = d_vrai;
1.1       bertrand 1845:    return;
                   1846: }
                   1847: 
1.67      bertrand 1848: // Traitement de rpl_sigstop
                   1849: 
                   1850: static inline void
                   1851: signal_stop(struct_processus *s_etat_processus, pid_t pid)
1.1       bertrand 1852: {
1.67      bertrand 1853:    struct_processus        *s_thread_principal;
1.1       bertrand 1854: 
1.68    ! bertrand 1855:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.32      bertrand 1856: 
1.30      bertrand 1857:    if (pid == getpid())
1.1       bertrand 1858:    {
                   1859:        if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
                   1860:                == NULL)
                   1861:        {
1.68    ! bertrand 1862:            deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 1863:            return;
                   1864:        }
                   1865: 
                   1866:        if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
                   1867:        {
1.67      bertrand 1868:            printf("[%d] RPL/SIGFSTOP (thread %llu)\n", (int) getpid(),
1.16      bertrand 1869:                    (unsigned long long) pthread_self());
                   1870:            fflush(stdout);
1.1       bertrand 1871:        }
                   1872: 
                   1873:        /*
                   1874:         * var_globale_traitement_retarde_stop :
                   1875:         *  0 -> traitement immédiat
                   1876:         *  1 -> traitement retardé (aucun signal reçu)
                   1877:         * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
                   1878:         */
                   1879: 
1.11      bertrand 1880:        if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
1.1       bertrand 1881:        {
1.11      bertrand 1882:            (*s_etat_processus).var_volatile_requete_arret = -1;
1.1       bertrand 1883:        }
                   1884:        else
                   1885:        {
1.11      bertrand 1886:            (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
1.1       bertrand 1887:        }
                   1888:    }
                   1889:    else
                   1890:    {
1.11      bertrand 1891:        if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
                   1892:                == NULL)
                   1893:        {
1.68    ! bertrand 1894:            deverrouillage_gestionnaire_signaux(s_etat_processus);
1.11      bertrand 1895:            return;
                   1896:        }
                   1897: 
1.1       bertrand 1898:        // Envoi d'un signal au thread maître du groupe.
                   1899: 
1.67      bertrand 1900:        if ((s_thread_principal = recherche_thread_principal(getpid()))
                   1901:                != NULL)
1.1       bertrand 1902:        {
1.67      bertrand 1903:            envoi_signal_contexte(s_thread_principal, rpl_sigstop);
1.1       bertrand 1904:        }
                   1905:    }
                   1906: 
1.68    ! bertrand 1907:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 1908:    return;
                   1909: }
                   1910: 
1.67      bertrand 1911: // Traitement de rpl_siginject
                   1912: 
                   1913: static inline void
                   1914: signal_inject(struct_processus *s_etat_processus, pid_t pid)
1.1       bertrand 1915: {
1.68    ! bertrand 1916:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.32      bertrand 1917: 
1.1       bertrand 1918:    if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
                   1919:    {
1.68    ! bertrand 1920:        deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 1921:        return;
                   1922:    }
                   1923: 
                   1924:    if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
                   1925:    {
1.67      bertrand 1926:        printf("[%d] RPL/SIGINJECT (thread %llu)\n", (int) getpid(),
1.1       bertrand 1927:                (unsigned long long) pthread_self());
                   1928:        fflush(stdout);
                   1929:    }
                   1930: 
1.68    ! bertrand 1931:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 1932:    return;
                   1933: }
                   1934: 
1.67      bertrand 1935: // Récupération des signaux
                   1936: // - SIGPIPE
                   1937: 
1.1       bertrand 1938: void
1.67      bertrand 1939: interruption5(int signal)
1.1       bertrand 1940: {
1.67      bertrand 1941:    unsigned char       message[] = "+++System : SIGPIPE\n"
                   1942:                                "+++System : Aborting !\n";
1.1       bertrand 1943: 
1.65      bertrand 1944:    test_signal(signal);
1.32      bertrand 1945: 
1.67      bertrand 1946:    if (pid_processus_pere == getpid())
1.1       bertrand 1947:    {
1.67      bertrand 1948:        envoi_signal_processus(pid_processus_pere, rpl_sigalrm);
1.1       bertrand 1949:    }
                   1950: 
1.67      bertrand 1951:    write(STDERR_FILENO, message, strlen(message));
1.1       bertrand 1952:    return;
                   1953: }
                   1954: 
1.67      bertrand 1955: static inline void
                   1956: signal_urg(struct_processus *s_etat_processus, pid_t pid)
1.1       bertrand 1957: {
1.67      bertrand 1958:    struct_processus        *s_thread_principal;
1.30      bertrand 1959: 
1.68    ! bertrand 1960:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.32      bertrand 1961: 
1.30      bertrand 1962:    if (pid == getpid())
1.1       bertrand 1963:    {
                   1964:        if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
                   1965:                == NULL)
                   1966:        {
1.68    ! bertrand 1967:            deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 1968:            return;
                   1969:        }
                   1970: 
                   1971:        if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
                   1972:        {
1.67      bertrand 1973:            printf("[%d] RPL/SIGURG (thread %llu)\n", (int) getpid(),
1.1       bertrand 1974:                    (unsigned long long) pthread_self());
                   1975:            fflush(stdout);
                   1976:        }
                   1977: 
                   1978:        (*s_etat_processus).var_volatile_alarme = -1;
                   1979:        (*s_etat_processus).var_volatile_requete_arret = -1;
                   1980:    }
                   1981:    else
                   1982:    {
                   1983:        // Envoi d'un signal au thread maître du groupe.
                   1984: 
1.67      bertrand 1985:        if ((s_thread_principal = recherche_thread_principal(getpid()))
                   1986:                != NULL)
1.1       bertrand 1987:        {
1.67      bertrand 1988:            envoi_signal_contexte(s_thread_principal, rpl_sigurg);
1.1       bertrand 1989:        }
                   1990:    }
                   1991: 
1.68    ! bertrand 1992:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 1993:    return;
                   1994: }
                   1995: 
1.67      bertrand 1996: // Traitement de rpl_sigabort
                   1997: 
                   1998: static inline void
                   1999: signal_abort(struct_processus *s_etat_processus, pid_t pid)
1.1       bertrand 2000: {
1.67      bertrand 2001:    struct_processus        *s_thread_principal;
1.1       bertrand 2002: 
1.68    ! bertrand 2003:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.32      bertrand 2004: 
1.1       bertrand 2005:    if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
                   2006:    {
1.68    ! bertrand 2007:        deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 2008:        return;
                   2009:    }
                   2010: 
                   2011:    if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
                   2012:    {
1.67      bertrand 2013:        printf("[%d] RPL/SIGABORT (thread %llu)\n", (int) getpid(),
1.1       bertrand 2014:                (unsigned long long) pthread_self());
                   2015:        fflush(stdout);
                   2016:    }
                   2017: 
1.67      bertrand 2018:    if (pid == getpid())
1.30      bertrand 2019:    {
1.67      bertrand 2020:        if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
                   2021:                == NULL)
                   2022:        {
1.68    ! bertrand 2023:            deverrouillage_gestionnaire_signaux(s_etat_processus);
1.67      bertrand 2024:            return;
                   2025:        }
1.30      bertrand 2026: 
1.67      bertrand 2027:        (*s_etat_processus).arret_depuis_abort = -1;
                   2028: 
                   2029:        if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
                   2030:        {
                   2031:            printf("[%d] SIGFABORT (thread %llu)\n", (int) getpid(),
                   2032:                    (unsigned long long) pthread_self());
                   2033:            fflush(stdout);
                   2034:        }
                   2035: 
                   2036:        /*
                   2037:         * var_globale_traitement_retarde_stop :
                   2038:         *  0 -> traitement immédiat
                   2039:         *  1 -> traitement retardé (aucun signal reçu)
                   2040:         * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
                   2041:         */
                   2042: 
                   2043:        if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
                   2044:        {
                   2045:            (*s_etat_processus).var_volatile_requete_arret = -1;
                   2046:        }
                   2047:        else
                   2048:        {
                   2049:            (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
                   2050:        }
                   2051:    }
                   2052:    else
                   2053:    {
                   2054:        if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
                   2055:                == NULL)
                   2056:        {
1.68    ! bertrand 2057:            deverrouillage_gestionnaire_signaux(s_etat_processus);
1.67      bertrand 2058:            return;
                   2059:        }
                   2060: 
                   2061:        (*s_etat_processus).arret_depuis_abort = -1;
                   2062: 
                   2063:        // Envoi d'un signal au thread maître du groupe.
                   2064: 
                   2065:        if ((s_thread_principal = recherche_thread_principal(getpid()))
                   2066:                != NULL)
                   2067:        {
                   2068:            envoi_signal_contexte(s_thread_principal, rpl_sigabort);
                   2069:        }
                   2070:    }
                   2071: 
1.68    ! bertrand 2072:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.67      bertrand 2073:    return;
                   2074: }
                   2075: 
                   2076: // Récupération des signaux
                   2077: // - SIGHUP
1.1       bertrand 2078: 
                   2079: void
1.67      bertrand 2080: interruption4(int signal)
                   2081: {
                   2082:    test_signal(signal);
                   2083:    envoi_signal_processus(getpid(), rpl_sighup);
                   2084:    return;
                   2085: }
                   2086: 
                   2087: static inline void
                   2088: signal_hup(struct_processus *s_etat_processus, pid_t pid)
1.1       bertrand 2089: {
                   2090:    file                    *fichier;
                   2091: 
                   2092:    unsigned char           nom[8 + 64 + 1];
                   2093: 
1.68    ! bertrand 2094:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.32      bertrand 2095: 
1.1       bertrand 2096:    if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
                   2097:    {
1.68    ! bertrand 2098:        deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 2099:        return;
                   2100:    }
                   2101: 
                   2102:    snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
                   2103:            (unsigned long) pthread_self());
                   2104: 
                   2105:    if ((fichier = fopen(nom, "w+")) != NULL)
                   2106:    {
                   2107:        fclose(fichier);
                   2108: 
                   2109:        freopen(nom, "w", stdout);
                   2110:        freopen(nom, "w", stderr);
                   2111:    }
                   2112: 
                   2113:    freopen("/dev/null", "r", stdin);
                   2114: 
                   2115:    if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
                   2116:    {
                   2117:        printf("[%d] SIGHUP (thread %llu)\n", (int) getpid(),
                   2118:                (unsigned long long) pthread_self());
                   2119:        fflush(stdout);
                   2120:    }
                   2121: 
1.68    ! bertrand 2122:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 2123:    return;
                   2124: }
                   2125: 
                   2126: void
1.67      bertrand 2127: traitement_exceptions_gsl(const char *reason, const char *file,
                   2128:        int line, int gsl_errno)
                   2129: {
1.68    ! bertrand 2130:    code_erreur_gsl = gsl_errno;
        !          2131:    envoi_signal_processus(getpid(), rpl_sigexcept);
        !          2132:    return;
        !          2133: }
1.67      bertrand 2134: 
1.68    ! bertrand 2135: static inline void
        !          2136: signal_except(struct_processus *s_etat_processus, pid_t pid)
        !          2137: {
        !          2138:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.67      bertrand 2139: 
                   2140:    if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
                   2141:    {
1.68    ! bertrand 2142:        deverrouillage_gestionnaire_signaux(s_etat_processus);
1.67      bertrand 2143:        return;
                   2144:    }
                   2145: 
1.68    ! bertrand 2146:    (*s_etat_processus).var_volatile_exception_gsl = code_erreur_gsl;
        !          2147:    deverrouillage_gestionnaire_signaux(s_etat_processus);
        !          2148: 
1.67      bertrand 2149:    return;
                   2150: }
                   2151: 
                   2152: static inline void
                   2153: envoi_interruptions(struct_processus *s_etat_processus, enum signaux_rpl signal,
                   2154:        pid_t pid_source)
1.16      bertrand 2155: {
1.67      bertrand 2156:    unsigned char       message[] = "+++System : Spurious signa !\n";
                   2157: 
                   2158:    switch(signal)
                   2159:    {
                   2160:        case rpl_sigint:
                   2161:            signal_int(s_etat_processus, pid_source);
                   2162:            break;
                   2163: 
                   2164:        case rpl_sigterm:
                   2165:            signal_term(s_etat_processus, pid_source);
                   2166:            break;
                   2167: 
                   2168:        case rpl_sigstart:
                   2169:            signal_start(s_etat_processus, pid_source);
                   2170:            break;
                   2171: 
                   2172:        case rpl_sigcont:
                   2173:            signal_cont(s_etat_processus, pid_source);
                   2174:            break;
                   2175: 
                   2176:        case rpl_sigstop:
                   2177:            signal_stop(s_etat_processus, pid_source);
                   2178:            break;
1.30      bertrand 2179: 
1.67      bertrand 2180:        case rpl_sigabort:
                   2181:            signal_abort(s_etat_processus, pid_source);
                   2182:            break;
                   2183: 
                   2184:        case rpl_sigurg:
                   2185:            signal_urg(s_etat_processus, pid_source);
                   2186:            break;
                   2187: 
                   2188:        case rpl_siginject:
                   2189:            signal_inject(s_etat_processus, pid_source);
                   2190:            break;
                   2191: 
                   2192:        case rpl_sigalrm:
                   2193:            signal_alrm(s_etat_processus, pid_source);
                   2194:            break;
                   2195: 
                   2196:        case rpl_sighup:
                   2197:            signal_hup(s_etat_processus, pid_source);
                   2198:            break;
                   2199: 
                   2200:        case rpl_sigtstp:
                   2201:            signal_tstp(s_etat_processus, pid_source);
                   2202:            break;
                   2203: 
1.68    ! bertrand 2204:        case rpl_sigexcept:
        !          2205:            signal_except(s_etat_processus, pid_source);
        !          2206:            break;
        !          2207: 
1.67      bertrand 2208:        default:
                   2209:            write(STDERR_FILENO, message, strlen(message));
                   2210:            break;
                   2211:    }
1.30      bertrand 2212: 
1.67      bertrand 2213:    return;
                   2214: }
1.16      bertrand 2215: 
1.67      bertrand 2216: void
                   2217: scrutation_interruptions(struct_processus *s_etat_processus)
                   2218: {
                   2219:    // Interruptions qui arrivent sur le processus depuis un
                   2220:    // processus externe.
1.32      bertrand 2221: 
1.68    ! bertrand 2222:    // Les pointeurs de lecture pointent sur les prochains éléments
        !          2223:    // à lire. Les pointeurs d'écriture pointent sur les prochains éléments à
        !          2224:    // écrire.
        !          2225: 
        !          2226:    if (pthread_mutex_trylock(&((*s_queue_signaux).mutex)) == 0)
        !          2227:    {
        !          2228:        if ((*s_queue_signaux).pointeur_lecture !=
        !          2229:                (*s_queue_signaux).pointeur_ecriture)
        !          2230:        {
        !          2231:            // Il y a un signal en attente dans le segment partagé. On le
        !          2232:            // traite.
        !          2233: 
        !          2234:            envoi_interruptions(s_etat_processus,
        !          2235:                    (*s_queue_signaux).queue[(*s_queue_signaux)
        !          2236:                    .pointeur_lecture].signal, (*s_queue_signaux).queue
        !          2237:                    [(*s_queue_signaux).pointeur_lecture].pid);
        !          2238:            (*s_queue_signaux).pointeur_lecture =
        !          2239:                    ((*s_queue_signaux).pointeur_lecture + 1)
        !          2240:                    % LONGUEUR_QUEUE_SIGNAUX;
        !          2241:        }
        !          2242: 
        !          2243:        pthread_mutex_unlock(&((*s_queue_signaux).mutex));
        !          2244:    }
        !          2245: 
1.67      bertrand 2246:    // Interruptions qui arrivent depuis le groupe courant de threads.
1.29      bertrand 2247: 
1.68    ! bertrand 2248:    if (pthread_mutex_trylock(&mutex_interruptions) == 0)
1.16      bertrand 2249:    {
1.68    ! bertrand 2250:        if ((*s_etat_processus).pointeur_signal_lecture !=
        !          2251:                (*s_etat_processus).pointeur_signal_ecriture)
        !          2252:        {
        !          2253:            // Il y a un signal dans la queue du thread courant. On le traite.
        !          2254: 
        !          2255:            envoi_interruptions(s_etat_processus,
        !          2256:                    (*s_etat_processus).signaux_en_queue
        !          2257:                    [(*s_etat_processus).pointeur_signal_lecture],
        !          2258:                    getpid());
        !          2259:            (*s_etat_processus).pointeur_signal_lecture =
        !          2260:                    ((*s_etat_processus).pointeur_signal_lecture + 1)
        !          2261:                    % LONGUEUR_QUEUE_SIGNAUX;
        !          2262:        }
        !          2263: 
        !          2264:        pthread_mutex_unlock(&mutex_interruptions);
1.67      bertrand 2265:    }
                   2266: 
                   2267:    return;
                   2268: }
                   2269: 
                   2270: int
                   2271: envoi_signal_processus(pid_t pid, enum signaux_rpl signal)
                   2272: {
                   2273:    // Il s'agit d'ouvrir le segment de mémoire partagée, de le projeter en
                   2274:    // mémoire puis d'y inscrire le signal à traiter.
                   2275: 
                   2276:    return(0);
                   2277: }
                   2278: 
                   2279: int
                   2280: envoi_signal_thread(pthread_t tid, enum signaux_rpl signal)
                   2281: {
                   2282:    // Un signal est envoyé d'un thread à un autre thread du même processus.
                   2283: 
1.68    ! bertrand 2284:    volatile struct_liste_chainee_volatile  *l_element_courant;
        !          2285: 
        !          2286:    struct_processus                        *s_etat_processus;
        !          2287: 
        !          2288:    if (pthread_mutex_lock(&mutex_liste_threads) != 0)
        !          2289:    {
        !          2290:        return(1);
        !          2291:    }
        !          2292: 
        !          2293:    l_element_courant = liste_threads;
        !          2294: 
        !          2295:    while(l_element_courant != NULL)
        !          2296:    {
        !          2297:        if (((*((struct_thread *) (*l_element_courant).donnee)).pid
        !          2298:                == getpid()) && (pthread_equal((*((struct_thread *)
        !          2299:                (*l_element_courant).donnee)).tid, tid) != 0))
        !          2300:        {
        !          2301:            break;
        !          2302:        }
        !          2303: 
        !          2304:        l_element_courant = (*l_element_courant).suivant;
        !          2305:    }
        !          2306: 
        !          2307:    if (l_element_courant == NULL)
        !          2308:    {
        !          2309:        pthread_mutex_unlock(&mutex_liste_threads);
        !          2310:        return(1);
        !          2311:    }
        !          2312: 
        !          2313:    if (pthread_mutex_lock(&mutex_interruptions) != 0)
        !          2314:    {
        !          2315:        pthread_mutex_unlock(&mutex_liste_threads);
        !          2316:        return(1);
        !          2317:    }
        !          2318: 
        !          2319:    s_etat_processus = (*((struct_thread *) (*l_element_courant).donnee))
        !          2320:            .s_etat_processus;
        !          2321: 
        !          2322:    (*s_etat_processus).signaux_en_queue
        !          2323:            [(*s_etat_processus).pointeur_signal_ecriture] = signal;
        !          2324:    (*s_etat_processus).pointeur_signal_ecriture =
        !          2325:            ((*s_etat_processus).pointeur_signal_ecriture + 1)
        !          2326:            % LONGUEUR_QUEUE_SIGNAUX;
        !          2327: 
        !          2328:    if (pthread_mutex_unlock(&mutex_interruptions) != 0)
        !          2329:    {
        !          2330:        pthread_mutex_unlock(&mutex_liste_threads);
        !          2331:        return(1);
        !          2332:    }
        !          2333: 
        !          2334:    if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
        !          2335:    {
        !          2336:        return(1);
        !          2337:    }
        !          2338: 
1.67      bertrand 2339:    return(0);
                   2340: }
                   2341: 
                   2342: int
                   2343: envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,
                   2344:        enum signaux_rpl signal)
                   2345: {
1.68    ! bertrand 2346:    pthread_mutex_lock(&mutex_interruptions);
1.67      bertrand 2347:    (*s_etat_processus_a_signaler).signaux_en_queue
1.68    ! bertrand 2348:            [(*s_etat_processus_a_signaler).pointeur_signal_ecriture] =
1.67      bertrand 2349:            signal;
1.68    ! bertrand 2350:    (*s_etat_processus_a_signaler).pointeur_signal_ecriture =
        !          2351:            ((*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1)
        !          2352:            % LONGUEUR_QUEUE_SIGNAUX;
        !          2353:    pthread_mutex_unlock(&mutex_interruptions);
1.67      bertrand 2354: 
                   2355:    return(0);
                   2356: }
                   2357: 
                   2358: 
                   2359: /*
                   2360: ================================================================================
                   2361:   Fonction renvoyant le nom du segment de mémoire partagée en fonction
                   2362:   du pid du processus.
                   2363: ================================================================================
                   2364:   Entrée : Chemin absolue servant de racine, pid du processus
                   2365: --------------------------------------------------------------------------------
                   2366:   Sortie : NULL ou nom du segment
                   2367: --------------------------------------------------------------------------------
                   2368:   Effet de bord : Néant
                   2369: ================================================================================
                   2370: */
                   2371: 
                   2372: static unsigned char *
                   2373: nom_segment(unsigned char *chemin, pid_t pid)
                   2374: {
                   2375:    unsigned char               *fichier;
                   2376: 
                   2377: #  ifdef IPCS_SYSV // !POSIX
                   2378: #      ifndef OS2 // !OS2
                   2379: 
                   2380:            if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) *
                   2381:                    sizeof(unsigned char))) == NULL)
                   2382:            {
                   2383:                return(NULL);
                   2384:            }
                   2385: 
                   2386:            sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);
                   2387: #      else // OS2
                   2388:            if ((fichier = malloc((10 + 256 + 1) * sizeof(unsigned char)))
                   2389:                    == NULL)
                   2390:            {
                   2391:                return(NULL);
                   2392:            }
                   2393: 
                   2394:            sprintf(fichier, "\\SHAREMEM\\RPL-SIGQUEUES-%d", (int) pid);
                   2395: #      endif // OS2
                   2396: #  else // POSIX
                   2397: 
                   2398:        if ((fichier = malloc((1 + 256 + 1) *
                   2399:                sizeof(unsigned char))) == NULL)
1.16      bertrand 2400:        {
1.67      bertrand 2401:            return(NULL);
1.16      bertrand 2402:        }
                   2403: 
1.67      bertrand 2404:        sprintf(fichier, "/RPL-SIGQUEUES-%d", (int) pid);
                   2405: #  endif
                   2406: 
                   2407:    return(fichier);
                   2408: }
                   2409: 
                   2410: 
                   2411: /*
                   2412: ================================================================================
                   2413:   Fonction créant un segment de mémoire partagée destiné à contenir
                   2414:   la queue des signaux.
                   2415: ================================================================================
                   2416:   Entrée : structure de description du processus
                   2417: --------------------------------------------------------------------------------
                   2418:   Sortie : Néant
                   2419: --------------------------------------------------------------------------------
                   2420:   Effet de bord : Néant
                   2421: ================================================================================
                   2422: */
                   2423: 
                   2424: void
                   2425: creation_queue_signaux(struct_processus *s_etat_processus)
                   2426: {
                   2427:    int                             segment;
                   2428: 
                   2429:    pthread_mutexattr_t             attributs_mutex;
                   2430: 
                   2431:    unsigned char                   *nom;
                   2432: 
                   2433: #  ifndef IPCS_SYSV // POSIX
1.16      bertrand 2434: 
1.67      bertrand 2435:    if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
                   2436:            getpid())) == NULL)
                   2437:    {
                   2438:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2439:        return;
                   2440:    }
1.16      bertrand 2441: 
1.67      bertrand 2442:    if ((segment = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,
                   2443:            S_IRUSR | S_IWUSR)) == -1)
                   2444:    {
                   2445:        free(nom);
                   2446:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2447:        return;
                   2448:    }
1.16      bertrand 2449: 
1.67      bertrand 2450:    if (ftruncate(segment, sizeof(struct_queue_signaux)) == -1)
                   2451:    {
                   2452:        free(nom);
                   2453:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2454:        return;
1.16      bertrand 2455:    }
1.67      bertrand 2456: 
                   2457:    s_queue_signaux = mmap(NULL, sizeof(struct_queue_signaux),
                   2458:            PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0);
                   2459:    close(segment);
                   2460: 
                   2461:    if (((void *) s_queue_signaux) == ((void *) -1))
1.16      bertrand 2462:    {
1.67      bertrand 2463:        if (shm_unlink(nom) == -1)
1.16      bertrand 2464:        {
1.67      bertrand 2465:            free(nom);
                   2466:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1.16      bertrand 2467:            return;
                   2468:        }
                   2469: 
1.67      bertrand 2470:        free(nom);
                   2471:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2472:        return;
                   2473:    }
                   2474: 
                   2475:    free(nom);
                   2476: 
                   2477:    pthread_mutexattr_init(&attributs_mutex);
                   2478:    pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL);
                   2479:    pthread_mutex_init(&((*s_queue_signaux).mutex), &attributs_mutex);
                   2480:    pthread_mutexattr_destroy(&attributs_mutex);
                   2481: 
                   2482:    (*s_queue_signaux).pointeur_lecture = 0;
                   2483:    (*s_queue_signaux).pointeur_ecriture = 0;
                   2484: 
                   2485: #  else // SystemV
                   2486: #  ifndef OS2
                   2487: 
                   2488:    file                            *desc;
                   2489: 
                   2490:    key_t                           clef;
                   2491: 
                   2492:    // Création d'un segment de données associé au PID du processus courant
                   2493: 
                   2494:    chemin = (*s_etat_processus).chemin_fichiers_temporaires;
                   2495: 
                   2496:    if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
                   2497:            getpid())) == NULL)
                   2498:    {
                   2499:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2500:        return;
                   2501:    }
                   2502: 
                   2503:    if ((desc = fopen(nom, "w")) == NULL)
                   2504:    {
                   2505:        (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
                   2506:        return;
                   2507:    }
                   2508: 
                   2509:    fclose(desc);
                   2510: 
                   2511:    if ((clef = ftok(nom, 1)) == -1)
                   2512:    {
                   2513:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2514:        return;
                   2515:    }
                   2516: 
                   2517:    free(nom);
                   2518: 
                   2519:    if ((segment = shmget(clef,
                   2520:            nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
                   2521:            IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)
                   2522:    {
                   2523:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2524:        return;
                   2525:    }
1.16      bertrand 2526: 
1.67      bertrand 2527:    fifos = shmat(segment, NULL, 0);
1.16      bertrand 2528: 
1.67      bertrand 2529:    if (((void *) fifos) == ((void *) -1))
                   2530:    {
                   2531:        if (shmctl(segment, IPC_RMID, 0) == -1)
1.16      bertrand 2532:        {
1.67      bertrand 2533:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1.16      bertrand 2534:            return;
                   2535:        }
1.67      bertrand 2536: 
                   2537:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2538:        return;
1.16      bertrand 2539:    }
                   2540: 
1.67      bertrand 2541: #  else
1.16      bertrand 2542: 
1.67      bertrand 2543:    if ((nom = nom_segment(NULL, getpid())) == NULL)
                   2544:    {
                   2545:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2546:        return;
                   2547:    }
1.1       bertrand 2548: 
1.67      bertrand 2549:    if (DosAllocSharedMem(&ptr_os2, nom, nombre_queues *
                   2550:            ((2 * longueur_queue) + 4) * sizeof(int),
                   2551:            PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
1.1       bertrand 2552:    {
1.67      bertrand 2553:        free(nom);
                   2554:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1.1       bertrand 2555:        return;
                   2556:    }
                   2557: 
1.67      bertrand 2558:    free(nom);
                   2559:    fifos = ptr_os2;
                   2560: 
                   2561: #  endif
                   2562: #  endif
                   2563: 
1.1       bertrand 2564:    return;
                   2565: }
                   2566: 
1.67      bertrand 2567: 
                   2568: /*
                   2569: ================================================================================
                   2570:   Fonction libérant le segment de mémoire partagée destiné à contenir
                   2571:   la queue des signaux.
                   2572: ================================================================================
                   2573:   Entrée : structure de description du processus
                   2574: --------------------------------------------------------------------------------
                   2575:   Sortie : Néant
                   2576: --------------------------------------------------------------------------------
                   2577:   Effet de bord : Néant
                   2578: ================================================================================
                   2579: */
                   2580: 
                   2581: void
                   2582: liberation_queue_signaux(struct_processus *s_etat_processus)
1.66      bertrand 2583: {
1.67      bertrand 2584: #  ifdef IPCS_SYSV // SystemV
                   2585: #      ifndef OS2
                   2586: #      else // OS/2
                   2587: #      endif
                   2588: #  else // POSIX
                   2589:        if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
1.66      bertrand 2590:        {
1.67      bertrand 2591:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2592:            return;
1.66      bertrand 2593:        }
1.67      bertrand 2594: #  endif
1.66      bertrand 2595: 
                   2596:    return;
                   2597: }
                   2598: 
1.67      bertrand 2599: 
                   2600: /*
                   2601: ================================================================================
                   2602:   Fonction détruisant le segment de mémoire partagée destiné à contenir
                   2603:   la queue des signaux.
                   2604: ================================================================================
                   2605:   Entrée : structure de description du processus
                   2606: --------------------------------------------------------------------------------
                   2607:   Sortie : Néant
                   2608: --------------------------------------------------------------------------------
                   2609:   Effet de bord : Néant
                   2610: ================================================================================
                   2611: */
                   2612: 
1.66      bertrand 2613: void
1.67      bertrand 2614: destruction_queue_signaux(struct_processus *s_etat_processus)
1.66      bertrand 2615: {
1.67      bertrand 2616:    unsigned char       *nom;
1.66      bertrand 2617: 
1.67      bertrand 2618: #  ifdef IPCS_SYSV // SystemV
                   2619: #  ifndef OS2
1.66      bertrand 2620: 
1.67      bertrand 2621:    if (shmdt(fifos) == -1)
1.66      bertrand 2622:    {
1.67      bertrand 2623:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1.66      bertrand 2624:        return;
                   2625:    }
                   2626: 
1.67      bertrand 2627:    if (shmctl(segment, IPC_RMID, 0) == -1)
1.66      bertrand 2628:    {
1.67      bertrand 2629:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2630:        return;
                   2631:    }
                   2632: 
                   2633:    if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
                   2634:            getpid())) == NULL)
                   2635:    {
                   2636:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2637:        return;
                   2638:    }
                   2639: 
                   2640:    unlink(nom);
                   2641:    free(nom);
                   2642: 
                   2643: #  else
1.66      bertrand 2644: 
1.67      bertrand 2645:    if (DosFreeMem(fifos) != 0)
                   2646:    {
                   2647:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2648:        return;
1.66      bertrand 2649:    }
                   2650: 
1.67      bertrand 2651: #  endif
                   2652: #  else // POSIX
                   2653: 
                   2654:    if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
1.66      bertrand 2655:    {
1.67      bertrand 2656:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1.66      bertrand 2657:        return;
                   2658:    }
                   2659: 
1.67      bertrand 2660:    if ((nom = nom_segment(NULL, getpid())) == NULL)
                   2661:    {
                   2662:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2663:        return;
                   2664:    }
1.66      bertrand 2665: 
1.67      bertrand 2666:    if (shm_unlink(nom) != 0)
1.66      bertrand 2667:    {
1.67      bertrand 2668:        free(nom);
                   2669:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   2670:        return;
1.66      bertrand 2671:    }
                   2672: 
1.67      bertrand 2673:    free(nom);
                   2674: 
                   2675: #  endif
                   2676: 
1.66      bertrand 2677:    return;
                   2678: }
                   2679: 
1.1       bertrand 2680: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>