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

1.1       bertrand    1: /*
                      2: ================================================================================
1.124     bertrand    3:   RPL/2 (R) version 4.1.14
1.117     bertrand    4:   Copyright (C) 1989-2013 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: static volatile struct_liste_chainee_volatile  *liste_threads
                     56:        = NULL;
                     57: static volatile struct_liste_chainee_volatile  *liste_threads_surveillance
                     58:        = NULL;
1.68      bertrand   59: static volatile int                                code_erreur_gsl = 0;
                     60: 
1.75      bertrand   61: unsigned char                                  *racine_segment;
1.69      bertrand   62: 
1.68      bertrand   63: static pthread_mutex_t                         mutex_interruptions
                     64:        = PTHREAD_MUTEX_INITIALIZER;
1.1       bertrand   65: 
1.96      bertrand   66: static void *
1.95      bertrand   67: thread_surveillance_signaux(void *argument)
                     68: {
1.96      bertrand   69:    // Cette fonction est lancée dans un thread créé par processus pour
                     70:    // gérer le cas des appels système qui seraient bloqués lors de l'arrivée du
                     71:    // signal SIGALRM. Les processus externes n'envoient plus un signal au
                     72:    // processus ou au thread à signaler mais positionnent les informations
                     73:    // nécessaires dans la queue des signaux et incrémentent le sémaphore.
                     74:    // Le sémaphore est décrémenté lorsque le signal est effectivement traité.
                     75: 
                     76:    int                                     nombre_signaux_envoyes;
                     77: 
                     78:    struct_processus                        *s_etat_processus;
                     79: 
                     80:    struct timespec                         attente;
                     81: 
                     82:    volatile struct_liste_chainee_volatile  *l_element_courant;
                     83: 
1.115     bertrand   84:    sigset_t                                set;
                     85: 
                     86:    sigfillset(&set);
                     87:    pthread_sigmask(SIG_BLOCK, &set, NULL);
                     88: 
1.96      bertrand   89:    s_etat_processus = (struct_processus *) argument;
                     90: 
                     91:    for(;;)
                     92:    {
                     93:        attente.tv_sec = 0;
                     94:        attente.tv_nsec = GRANULARITE_us * 1000;
                     95: 
1.100     bertrand   96: #      if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
1.96      bertrand   97:        if (sem_wait(&(*s_queue_signaux).signalisation) == 0)
                     98: #      else
1.109     bertrand   99:        if (sem_wait(semaphore_signalisation) == 0)
1.96      bertrand  100: #      endif
                    101:        {
1.100     bertrand  102: #          if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
1.97      bertrand  103:            sem_post(&(*s_queue_signaux).signalisation);
                    104: #          else
                    105:            sem_post(semaphore_signalisation);
                    106: #          endif
                    107: 
1.114     bertrand  108:            if ((*s_queue_signaux).requete_arret == d_vrai)
                    109:            {
                    110:                break;
                    111:            }
                    112: 
1.96      bertrand  113:            nombre_signaux_envoyes = 0;
1.97      bertrand  114:            sched_yield();
1.96      bertrand  115: 
                    116:            // Dans un premier temps, on verrouille la queue des signaux
                    117:            // affectée au processus courant pour vérifier s'il y a quelque
                    118:            // chose à traiter.
                    119: 
1.100     bertrand  120: #          if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
1.96      bertrand  121:            sem_wait(&(*s_queue_signaux).semaphore);
                    122: #          else
                    123:            sem_wait(semaphore_queue_signaux);
                    124: #          endif
                    125: 
                    126:            if ((*s_queue_signaux).pointeur_lecture !=
                    127:                    (*s_queue_signaux).pointeur_ecriture)
                    128:            {
1.106     bertrand  129:                // Attention : raise() envoit le signal au thread appelant !
                    130:                // kill() l'envoie au processus appelant, donc dans notre
                    131:                // cas à un thread aléatoire du processus, ce qui nous
                    132:                // convient tout à fait puisqu'il s'agit de débloquer les
                    133:                // appels système lents.
                    134: 
1.96      bertrand  135:                nombre_signaux_envoyes++;
1.106     bertrand  136:                kill(getpid(), SIGALRM);
1.96      bertrand  137:            }
                    138: 
1.100     bertrand  139: #          if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
1.96      bertrand  140:            sem_post(&(*s_queue_signaux).semaphore);
                    141: #          else
                    142:            sem_post(semaphore_queue_signaux);
                    143: #          endif
                    144: 
                    145:            // Dans un second temps, on balaye toutes les queues de signaux
                    146:            // des threads du processus courant.
                    147: 
                    148:            pthread_mutex_lock(&mutex_liste_threads);
                    149:            l_element_courant = liste_threads;
                    150: 
                    151:            while(l_element_courant != NULL)
                    152:            {
                    153:                if ((*((struct_thread *) (*l_element_courant).donnee)).pid
                    154:                        == getpid())
                    155:                {
                    156:                    if ((*(*((struct_thread *) (*l_element_courant).donnee))
                    157:                            .s_etat_processus).pointeur_signal_ecriture !=
                    158:                            (*(*((struct_thread *) (*l_element_courant).donnee))
                    159:                            .s_etat_processus).pointeur_signal_lecture)
                    160:                    {
                    161:                        nombre_signaux_envoyes++;
                    162:                        pthread_kill((*((struct_thread *) (*l_element_courant)
                    163:                                .donnee)).tid, SIGALRM);
                    164:                    }
                    165:                }
                    166: 
                    167:                l_element_courant = (*l_element_courant).suivant;
                    168:            }
                    169: 
                    170:            pthread_mutex_unlock(&mutex_liste_threads);
                    171: 
                    172:            // Nanosleep
                    173: 
                    174:            if (nombre_signaux_envoyes > 0)
                    175:            {
                    176:                nanosleep(&attente, NULL);
                    177:            }
                    178:        }
                    179:        else
                    180:        {
1.108     bertrand  181:            if (errno != EINTR)
                    182:            {
                    183:                (*s_etat_processus).erreur_systeme = d_es_processus;
                    184:            }
1.96      bertrand  185:        }
                    186:    }
                    187: 
1.95      bertrand  188:    pthread_exit(NULL);
                    189: }
                    190: 
1.1       bertrand  191: void
                    192: modification_pid_thread_pere(struct_processus *s_etat_processus)
                    193: {
                    194:    // La variable existe toujours et aucun thread concurrent ne peut
                    195:    // la modifier puisque cette routine ne peut être appelée que depuis
                    196:    // DAEMON.
                    197: 
                    198:    (*((struct_thread *) (*liste_threads).donnee)).pid =
                    199:            (*s_etat_processus).pid_processus_pere;
                    200: 
                    201:    return;
                    202: }
                    203: 
                    204: void
                    205: insertion_thread(struct_processus *s_etat_processus, logical1 thread_principal)
                    206: {
                    207:    volatile struct_liste_chainee_volatile      *l_nouvel_objet;
                    208: 
                    209:    if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
                    210:            == NULL)
                    211:    {
                    212:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    213:        return;
                    214:    }
                    215: 
                    216:    if (((*l_nouvel_objet).donnee = malloc(sizeof(struct_thread))) == NULL)
                    217:    {
                    218:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    219:        return;
                    220:    }
                    221: 
                    222:    (*((struct_thread *) (*l_nouvel_objet).donnee)).pid = getpid();
                    223:    (*((struct_thread *) (*l_nouvel_objet).donnee)).tid = pthread_self();
                    224:    (*((struct_thread *) (*l_nouvel_objet).donnee)).thread_principal =
                    225:            thread_principal;
                    226:    (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus =
                    227:            s_etat_processus;
                    228: 
1.68      bertrand  229:    if (pthread_mutex_lock(&mutex_liste_threads) != 0)
1.13      bertrand  230:    {
1.68      bertrand  231:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    232:        return;
1.13      bertrand  233:    }
                    234: 
                    235:    (*l_nouvel_objet).suivant = liste_threads;
1.1       bertrand  236:    liste_threads = l_nouvel_objet;
                    237: 
1.68      bertrand  238:    if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1.1       bertrand  239:    {
                    240:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    241:        return;
                    242:    }
                    243: 
                    244:    return;
                    245: }
                    246: 
                    247: void
                    248: insertion_thread_surveillance(struct_processus *s_etat_processus,
                    249:        struct_descripteur_thread *s_argument_thread)
                    250: {
                    251:    volatile struct_liste_chainee_volatile      *l_nouvel_objet;
                    252: 
1.13      bertrand  253:    if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
                    254:            == NULL)
                    255:    {
                    256:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    257:        return;
                    258:    }
                    259: 
1.68      bertrand  260:    if (pthread_mutex_lock(&mutex_liste_threads) != 0)
1.1       bertrand  261:    {
1.68      bertrand  262:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    263:        return;
1.1       bertrand  264:    }
                    265: 
1.40      bertrand  266:    pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references));
1.21      bertrand  267:    (*s_argument_thread).nombre_references++;
1.40      bertrand  268:    pthread_mutex_unlock(&((*s_argument_thread).mutex_nombre_references));
1.22      bertrand  269: 
1.1       bertrand  270:    (*l_nouvel_objet).suivant = liste_threads_surveillance;
                    271:    (*l_nouvel_objet).donnee = (void *) s_argument_thread;
                    272: 
                    273:    liste_threads_surveillance = l_nouvel_objet;
                    274: 
1.68      bertrand  275:    if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1.1       bertrand  276:    {
                    277:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    278:        return;
                    279:    }
                    280: 
                    281:    return;
                    282: }
                    283: 
                    284: void
                    285: retrait_thread(struct_processus *s_etat_processus)
                    286: {
                    287:    volatile struct_liste_chainee_volatile  *l_element_precedent;
                    288:    volatile struct_liste_chainee_volatile  *l_element_courant;
                    289: 
1.68      bertrand  290:    if (pthread_mutex_lock(&mutex_liste_threads) != 0)
1.1       bertrand  291:    {
1.68      bertrand  292:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    293:        return;
1.1       bertrand  294:    }
                    295: 
                    296:    l_element_precedent = NULL;
                    297:    l_element_courant = liste_threads;
                    298: 
                    299:    while(l_element_courant != NULL)
                    300:    {
                    301:        if (((*((struct_thread *) (*l_element_courant).donnee)).pid
                    302:                == getpid()) && (pthread_equal((*((struct_thread *)
                    303:                (*l_element_courant).donnee)).tid, pthread_self()) != 0))
                    304:        {
                    305:            break;
                    306:        }
                    307: 
                    308:        l_element_precedent = l_element_courant;
                    309:        l_element_courant = (*l_element_courant).suivant;
                    310:    }
                    311: 
                    312:    if (l_element_courant == NULL)
                    313:    {
1.68      bertrand  314:        pthread_mutex_unlock(&mutex_liste_threads);
1.1       bertrand  315:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    316:        return;
                    317:    }
                    318: 
                    319:    if (l_element_precedent == NULL)
                    320:    {
                    321:        liste_threads = (*l_element_courant).suivant;
                    322:    }
                    323:    else
                    324:    {
                    325:        (*l_element_precedent).suivant = (*l_element_courant).suivant;
                    326:    }
                    327: 
1.68      bertrand  328:    if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1.1       bertrand  329:    {
                    330:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    331:        return;
                    332:    }
                    333: 
1.97      bertrand  334:    // Le thread ne peut plus traiter de signaux explicites. Il convient
                    335:    // alors de corriger le sémaphore pour annuler les signaux en attente.
                    336: 
                    337:    while((*(*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus)
                    338:            .pointeur_signal_ecriture != (*(*((struct_thread *)
                    339:            (*l_element_courant).donnee)).s_etat_processus)
                    340:            .pointeur_signal_lecture)
                    341:    {
1.100     bertrand  342: #      if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
1.108     bertrand  343:        while(sem_wait(&((*s_queue_signaux).signalisation)) != 0)
1.97      bertrand  344: #      else
1.108     bertrand  345:        while(sem_wait(semaphore_signalisation) != 0)
1.97      bertrand  346: #      endif
1.108     bertrand  347:        {
                    348:            if (errno != EINTR)
                    349:            {
                    350:                (*s_etat_processus).erreur_systeme = d_es_processus;
                    351:                return;
                    352:            }
                    353:        }
1.97      bertrand  354: 
                    355:        (*(*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus)
                    356:                .pointeur_signal_lecture = ((*(*((struct_thread *)
                    357:                (*l_element_courant).donnee)).s_etat_processus)
                    358:                .pointeur_signal_lecture + 1) % LONGUEUR_QUEUE_SIGNAUX;
                    359:    }
                    360: 
1.13      bertrand  361:    free((void *) (*l_element_courant).donnee);
                    362:    free((struct_liste_chainee_volatile *) l_element_courant);
                    363: 
1.1       bertrand  364:    return;
                    365: }
                    366: 
                    367: void
                    368: retrait_thread_surveillance(struct_processus *s_etat_processus,
                    369:        struct_descripteur_thread *s_argument_thread)
                    370: {
                    371:    volatile struct_liste_chainee_volatile  *l_element_precedent;
                    372:    volatile struct_liste_chainee_volatile  *l_element_courant;
                    373: 
1.68      bertrand  374:    if (pthread_mutex_lock(&mutex_liste_threads) != 0)
1.1       bertrand  375:    {
1.68      bertrand  376:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    377:        return;
1.1       bertrand  378:    }
                    379: 
                    380:    l_element_precedent = NULL;
                    381:    l_element_courant = liste_threads_surveillance;
                    382: 
                    383:    while(l_element_courant != NULL)
                    384:    {
                    385:        if ((*l_element_courant).donnee == (void *) s_argument_thread)
                    386:        {
                    387:            break;
                    388:        }
                    389: 
                    390:        l_element_precedent = l_element_courant;
                    391:        l_element_courant = (*l_element_courant).suivant;
                    392:    }
                    393: 
                    394:    if (l_element_courant == NULL)
                    395:    {
1.68      bertrand  396:        pthread_mutex_unlock(&mutex_liste_threads);
1.1       bertrand  397:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    398:        return;
                    399:    }
                    400: 
                    401:    if (l_element_precedent == NULL)
                    402:    {
                    403:        liste_threads_surveillance = (*l_element_courant).suivant;
                    404:    }
                    405:    else
                    406:    {
                    407:        (*l_element_precedent).suivant = (*l_element_courant).suivant;
                    408:    }
                    409: 
1.40      bertrand  410:    if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
                    411:            != 0)
1.1       bertrand  412:    {
1.68      bertrand  413:        pthread_mutex_unlock(&mutex_liste_threads);
1.1       bertrand  414:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    415:        return;
                    416:    }
                    417: 
                    418:    (*s_argument_thread).nombre_references--;
                    419: 
                    420:    BUG((*s_argument_thread).nombre_references < 0,
                    421:            printf("(*s_argument_thread).nombre_references = %d\n",
                    422:            (int) (*s_argument_thread).nombre_references));
                    423: 
                    424:    if ((*s_argument_thread).nombre_references == 0)
                    425:    {
1.40      bertrand  426:        if (pthread_mutex_unlock(&((*s_argument_thread)
                    427:                .mutex_nombre_references)) != 0)
1.1       bertrand  428:        {
1.68      bertrand  429:            pthread_mutex_unlock(&mutex_liste_threads);
1.1       bertrand  430:            (*s_etat_processus).erreur_systeme = d_es_processus;
                    431:            return;
                    432:        }
                    433: 
                    434:        pthread_mutex_destroy(&((*s_argument_thread).mutex));
1.40      bertrand  435:        pthread_mutex_destroy(&((*s_argument_thread).mutex_nombre_references));
1.1       bertrand  436:        free(s_argument_thread);
                    437:    }
                    438:    else
                    439:    {
1.40      bertrand  440:        if (pthread_mutex_unlock(&((*s_argument_thread)
                    441:                .mutex_nombre_references)) != 0)
1.1       bertrand  442:        {
1.68      bertrand  443:            pthread_mutex_unlock(&mutex_liste_threads);
1.1       bertrand  444:            (*s_etat_processus).erreur_systeme = d_es_processus;
                    445:            return;
                    446:        }
                    447:    }
                    448: 
1.68      bertrand  449:    if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1.1       bertrand  450:    {
                    451:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    452:        return;
                    453:    }
                    454: 
1.13      bertrand  455:    free((struct_liste_chainee_volatile *) l_element_courant);
1.1       bertrand  456:    return;
                    457: }
                    458: 
                    459: void
                    460: verrouillage_threads_concurrents(struct_processus *s_etat_processus)
                    461: {
                    462:    volatile struct_liste_chainee_volatile  *l_element_courant;
                    463: 
1.68      bertrand  464:    if (pthread_mutex_lock(&mutex_liste_threads) != 0)
1.1       bertrand  465:    {
1.68      bertrand  466:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    467:        return;
1.1       bertrand  468:    }
                    469: 
                    470:    l_element_courant = liste_threads;
                    471: 
                    472:    while(l_element_courant != NULL)
                    473:    {
                    474:        if (((*((struct_thread *) (*l_element_courant).donnee)).pid
                    475:                == getpid()) && (pthread_equal((*((struct_thread *)
                    476:                (*l_element_courant).donnee)).tid, pthread_self()) == 0))
                    477:        {
1.79      bertrand  478: #          ifndef SEMAPHORES_NOMMES
                    479:                while(sem_wait(&((*(*((struct_thread *) (*l_element_courant)
                    480:                        .donnee)).s_etat_processus).semaphore_fork)) == -1)
                    481: #          else
                    482:                while(sem_wait((*(*((struct_thread *) (*l_element_courant)
                    483:                        .donnee)).s_etat_processus).semaphore_fork) == -1)
                    484: #          endif
1.1       bertrand  485:            {
1.68      bertrand  486:                (*s_etat_processus).erreur_systeme = d_es_processus;
                    487:                return;
1.1       bertrand  488:            }
                    489:        }
                    490: 
                    491:        l_element_courant = (*l_element_courant).suivant;
                    492:    }
                    493: 
                    494:    return;
                    495: }
                    496: 
                    497: void
                    498: deverrouillage_threads_concurrents(struct_processus *s_etat_processus)
                    499: {
                    500:    volatile struct_liste_chainee_volatile  *l_element_courant;
                    501: 
                    502:    l_element_courant = liste_threads;
                    503: 
                    504:    while(l_element_courant != NULL)
                    505:    {
                    506:        if (((*((struct_thread *) (*l_element_courant).donnee)).pid
                    507:                == getpid()) && (pthread_equal((*((struct_thread *)
                    508:                (*l_element_courant).donnee)).tid, pthread_self()) == 0))
                    509:        {
1.79      bertrand  510: #          ifndef SEMAPHORES_NOMMES
                    511:                if (sem_post(&((*(*((struct_thread *)
                    512:                        (*l_element_courant).donnee)).s_etat_processus)
                    513:                        .semaphore_fork)) != 0)
                    514: #          else
                    515:                if (sem_post((*(*((struct_thread *)
                    516:                        (*l_element_courant).donnee)).s_etat_processus)
                    517:                        .semaphore_fork) != 0)
                    518: #          endif
1.1       bertrand  519:            {
1.68      bertrand  520:                if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1.8       bertrand  521:                {
                    522:                    (*s_etat_processus).erreur_systeme = d_es_processus;
                    523:                    return;
                    524:                }
1.1       bertrand  525: 
                    526:                (*s_etat_processus).erreur_systeme = d_es_processus;
                    527:                return;
                    528:            }
                    529:        }
                    530: 
                    531:        l_element_courant = (*l_element_courant).suivant;
                    532:    }
                    533: 
1.68      bertrand  534:    if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1.1       bertrand  535:    {
                    536:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    537:        return;
                    538:    }
                    539: 
                    540:    return;
                    541: }
                    542: 
                    543: void
                    544: liberation_threads(struct_processus *s_etat_processus)
                    545: {
                    546:    logical1                                    suppression_variables_partagees;
                    547: 
                    548:    struct_descripteur_thread                   *s_argument_thread;
                    549: 
                    550:    struct_processus                            *candidat;
                    551: 
1.111     bertrand  552:    struct_liste_variables_partagees            *l_element_partage_courant;
                    553:    struct_liste_variables_partagees            *l_element_partage_suivant;
                    554: 
                    555:    struct_liste_variables_statiques            *l_element_statique_courant;
                    556:    struct_liste_variables_statiques            *l_element_statique_suivant;
                    557: 
1.121     bertrand  558:    integer8                                    i;
1.1       bertrand  559: 
                    560:    void                                        *element_candidat;
                    561:    void                                        *element_courant;
                    562:    void                                        *element_suivant;
                    563: 
                    564:    volatile struct_liste_chainee_volatile      *l_element_courant;
                    565:    volatile struct_liste_chainee_volatile      *l_element_suivant;
                    566: 
1.68      bertrand  567:    if (pthread_mutex_lock(&mutex_liste_threads) == -1)
1.1       bertrand  568:    {
1.68      bertrand  569:        (*s_etat_processus).erreur_systeme = d_es_processus;
                    570:        return;
1.1       bertrand  571:    }
                    572: 
                    573:    l_element_courant = liste_threads;
                    574:    suppression_variables_partagees = d_faux;
                    575: 
                    576:    while(l_element_courant != NULL)
                    577:    {
                    578:        if ((*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus
                    579:                != s_etat_processus)
                    580:        {
                    581:            candidat = s_etat_processus;
                    582:            s_etat_processus = (*((struct_thread *)
                    583:                    (*l_element_courant).donnee)).s_etat_processus;
                    584:            free((*s_etat_processus).localisation);
                    585: 
                    586:            // (*s_etat_processus).instruction_courante peut pointer sur
                    587:            // n'importe quoi (une instruction courante ou un champ d'une
                    588:            // structure objet). On ne le libère pas quitte à avoir une
                    589:            // petite fuite mémoire dans le processus fils.
                    590: 
                    591:            if ((*s_etat_processus).instruction_courante != NULL)
                    592:            {
                    593:                //free((*s_etat_processus).instruction_courante);
                    594:            }
                    595: 
                    596:            close((*s_etat_processus).pipe_acquittement);
                    597:            close((*s_etat_processus).pipe_donnees);
                    598:            close((*s_etat_processus).pipe_injections);
                    599:            close((*s_etat_processus).pipe_nombre_injections);
                    600:            close((*s_etat_processus).pipe_interruptions);
1.125     bertrand  601:            close((*s_etat_processus).pipe_nombre_elements_attente);
1.1       bertrand  602: 
1.13      bertrand  603:            liberation(s_etat_processus, (*s_etat_processus).at_exit);
                    604: 
1.1       bertrand  605:            if ((*s_etat_processus).nom_fichier_impression != NULL)
                    606:            {
                    607:                free((*s_etat_processus).nom_fichier_impression);
                    608:            }
                    609: 
                    610:            while((*s_etat_processus).fichiers_graphiques != NULL)
                    611:            {
                    612:                free((*(*s_etat_processus).fichiers_graphiques).nom);
                    613: 
                    614:                if ((*(*s_etat_processus).fichiers_graphiques).legende != NULL)
                    615:                {
                    616:                    free((*(*s_etat_processus).fichiers_graphiques).legende);
                    617:                }
                    618: 
                    619:                element_courant = (*s_etat_processus).fichiers_graphiques;
                    620:                (*s_etat_processus).fichiers_graphiques =
                    621:                        (*(*s_etat_processus).fichiers_graphiques).suivant;
                    622: 
                    623:                free(element_courant);
                    624:            }
                    625: 
                    626:            if ((*s_etat_processus).entree_standard != NULL)
                    627:            {
                    628:                pclose((*s_etat_processus).entree_standard);
                    629:            }
                    630: 
                    631:            if ((*s_etat_processus).generateur_aleatoire != NULL)
                    632:            {
                    633:                liberation_generateur_aleatoire(s_etat_processus);
                    634:            }
                    635: 
                    636:            if ((*s_etat_processus).instruction_derniere_erreur != NULL)
                    637:            {
                    638:                free((*s_etat_processus).instruction_derniere_erreur);
                    639:                (*s_etat_processus).instruction_derniere_erreur = NULL;
                    640:            }
                    641: 
                    642:            element_courant = (void *) (*s_etat_processus)
                    643:                    .l_base_pile_processus;
                    644:            while(element_courant != NULL)
                    645:            {
1.20      bertrand  646:                s_argument_thread = (struct_descripteur_thread *)
                    647:                        (*((struct_liste_chainee *) element_courant)).donnee;
                    648: 
1.40      bertrand  649:                if (pthread_mutex_lock(&((*s_argument_thread)
                    650:                        .mutex_nombre_references)) != 0)
1.20      bertrand  651:                {
                    652:                    (*s_etat_processus).erreur_systeme = d_es_processus;
1.68      bertrand  653:                    pthread_mutex_unlock(&mutex_liste_threads);
1.20      bertrand  654:                    return;
                    655:                }
                    656: 
                    657:                (*s_argument_thread).nombre_references--;
                    658: 
                    659:                BUG((*s_argument_thread).nombre_references < 0,
                    660:                        printf("(*s_argument_thread).nombre_references = %d\n",
                    661:                        (int) (*s_argument_thread).nombre_references));
                    662: 
                    663:                if ((*s_argument_thread).nombre_references == 0)
                    664:                {
                    665:                    close((*s_argument_thread).pipe_objets[0]);
                    666:                    close((*s_argument_thread).pipe_acquittement[1]);
                    667:                    close((*s_argument_thread).pipe_injections[1]);
                    668:                    close((*s_argument_thread).pipe_nombre_injections[1]);
1.125     bertrand  669:                    close((*s_argument_thread).pipe_nombre_elements_attente[0]);
1.20      bertrand  670:                    close((*s_argument_thread).pipe_interruptions[0]);
                    671: 
1.40      bertrand  672:                    if (pthread_mutex_unlock(&((*s_argument_thread)
                    673:                            .mutex_nombre_references)) != 0)
1.20      bertrand  674:                    {
                    675:                        (*s_etat_processus).erreur_systeme = d_es_processus;
1.68      bertrand  676:                        pthread_mutex_unlock(&mutex_liste_threads);
1.20      bertrand  677:                        return;
                    678:                    }
                    679: 
                    680:                    pthread_mutex_destroy(&((*s_argument_thread).mutex));
1.40      bertrand  681:                    pthread_mutex_destroy(&((*s_argument_thread)
                    682:                            .mutex_nombre_references));
1.20      bertrand  683: 
                    684:                    if ((*s_argument_thread).processus_detache == d_faux)
                    685:                    {
                    686:                        if ((*s_argument_thread).destruction_objet == d_vrai)
                    687:                        {
                    688:                            liberation(s_etat_processus, (*s_argument_thread)
                    689:                                    .argument);
                    690:                        }
                    691:                    }
                    692: 
                    693:                    free(s_argument_thread);
                    694:                }
                    695:                else
                    696:                {
1.40      bertrand  697:                    if (pthread_mutex_unlock(&((*s_argument_thread)
                    698:                            .mutex_nombre_references)) != 0)
1.20      bertrand  699:                    {
                    700:                        (*s_etat_processus).erreur_systeme = d_es_processus;
1.68      bertrand  701:                        pthread_mutex_unlock(&mutex_liste_threads);
1.20      bertrand  702:                        return;
                    703:                    }
                    704:                }
                    705: 
1.1       bertrand  706:                element_suivant = (*((struct_liste_chainee *) element_courant))
                    707:                        .suivant;
1.20      bertrand  708:                free(element_courant);
1.1       bertrand  709:                element_courant = element_suivant;
                    710:            }
                    711: 
1.20      bertrand  712:            (*s_etat_processus).l_base_pile_processus = NULL;
                    713: 
1.1       bertrand  714:            pthread_mutex_trylock(&((*(*s_etat_processus).indep).mutex));
                    715:            pthread_mutex_unlock(&((*(*s_etat_processus).indep).mutex));
                    716:            liberation(s_etat_processus, (*s_etat_processus).indep);
                    717: 
                    718:            pthread_mutex_trylock(&((*(*s_etat_processus).depend).mutex));
                    719:            pthread_mutex_unlock(&((*(*s_etat_processus).depend).mutex));
                    720:            liberation(s_etat_processus, (*s_etat_processus).depend);
                    721: 
                    722:            free((*s_etat_processus).label_x);
                    723:            free((*s_etat_processus).label_y);
                    724:            free((*s_etat_processus).label_z);
                    725:            free((*s_etat_processus).titre);
                    726:            free((*s_etat_processus).legende);
                    727: 
                    728:            pthread_mutex_trylock(&((*(*s_etat_processus)
                    729:                    .parametres_courbes_de_niveau).mutex));
                    730:            pthread_mutex_unlock(&((*(*s_etat_processus)
                    731:                    .parametres_courbes_de_niveau).mutex));
                    732:            liberation(s_etat_processus, (*s_etat_processus)
                    733:                    .parametres_courbes_de_niveau);
                    734: 
                    735:            for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++)
                    736:            {
                    737:                if ((*s_etat_processus).corps_interruptions[i] != NULL)
                    738:                {
                    739:                    pthread_mutex_trylock(&((*(*s_etat_processus)
                    740:                            .corps_interruptions[i]).mutex));
                    741:                    pthread_mutex_unlock(&((*(*s_etat_processus)
                    742:                            .corps_interruptions[i]).mutex));
                    743: 
                    744:                    liberation(s_etat_processus,
                    745:                            (*s_etat_processus).corps_interruptions[i]);
                    746:                }
                    747: 
                    748:                element_courant = (*s_etat_processus)
                    749:                        .pile_origine_interruptions[i];
                    750: 
                    751:                while(element_courant != NULL)
                    752:                {
                    753:                    element_suivant = (*((struct_liste_chainee *)
                    754:                            element_courant)).suivant;
                    755: 
                    756:                    pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
                    757:                            element_courant)).donnee).mutex));
                    758:                    pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
                    759:                            element_courant)).donnee).mutex));
                    760: 
                    761:                    liberation(s_etat_processus,
                    762:                            (*((struct_liste_chainee *) element_courant))
                    763:                            .donnee);
                    764:                    free(element_courant);
                    765: 
                    766:                    element_courant = element_suivant;
                    767:                }
                    768:            }
                    769: 
1.110     bertrand  770:            // ne peut être effacé qu'une seule fois
1.1       bertrand  771:            if (suppression_variables_partagees == d_faux)
                    772:            {
                    773:                suppression_variables_partagees = d_vrai;
                    774: 
1.110     bertrand  775:                liberation_arbre_variables_partagees(s_etat_processus,
1.111     bertrand  776:                        (*(*s_etat_processus).s_arbre_variables_partagees));
                    777: 
                    778:                l_element_partage_courant = (*(*s_etat_processus)
                    779:                        .l_liste_variables_partagees);
                    780: 
                    781:                while(l_element_partage_courant != NULL)
                    782:                {
                    783:                    l_element_partage_suivant =
                    784:                            (*l_element_partage_courant).suivant;
                    785:                    free(l_element_partage_courant);
                    786:                    l_element_partage_courant = l_element_partage_suivant;
                    787:                }
1.110     bertrand  788:            }
1.1       bertrand  789: 
1.110     bertrand  790:            liberation_arbre_variables(s_etat_processus,
                    791:                    (*s_etat_processus).s_arbre_variables, d_faux);
1.1       bertrand  792: 
1.111     bertrand  793:            l_element_statique_courant = (*s_etat_processus)
                    794:                    .l_liste_variables_statiques;
                    795: 
                    796:            while(l_element_statique_courant != NULL)
                    797:            {
                    798:                l_element_statique_suivant =
                    799:                    (*l_element_statique_courant).suivant;
                    800:                free(l_element_statique_courant);
                    801:                l_element_statique_courant = l_element_statique_suivant;
                    802:            }
                    803: 
1.1       bertrand  804:            element_courant = (*s_etat_processus).l_base_pile;
                    805:            while(element_courant != NULL)
                    806:            {
                    807:                element_suivant = (*((struct_liste_chainee *)
                    808:                        element_courant)).suivant;
                    809: 
                    810:                pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
                    811:                        element_courant)).donnee).mutex));
                    812:                pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
                    813:                        element_courant)).donnee).mutex));
                    814: 
                    815:                liberation(s_etat_processus,
                    816:                        (*((struct_liste_chainee *)
                    817:                        element_courant)).donnee);
                    818:                free((struct_liste_chainee *) element_courant);
                    819: 
                    820:                element_courant = element_suivant;
                    821:            }
                    822: 
                    823:            element_courant = (*s_etat_processus).l_base_pile_contextes;
                    824:            while(element_courant != NULL)
                    825:            {
                    826:                element_suivant = (*((struct_liste_chainee *)
                    827:                        element_courant)).suivant;
                    828: 
                    829:                pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
                    830:                        element_courant)).donnee).mutex));
                    831:                pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
                    832:                        element_courant)).donnee).mutex));
                    833:                liberation(s_etat_processus, (*((struct_liste_chainee *)
                    834:                        element_courant)).donnee);
                    835:                free((struct_liste_chainee *) element_courant);
                    836: 
                    837:                element_courant = element_suivant;
                    838:            }
                    839: 
                    840:            element_courant = (*s_etat_processus).l_base_pile_taille_contextes;
                    841:            while(element_courant != NULL)
                    842:            {
                    843:                element_suivant = (*((struct_liste_chainee *)
                    844:                        element_courant)).suivant;
                    845: 
                    846:                pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
                    847:                        element_courant)).donnee).mutex));
                    848:                pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
                    849:                        element_courant)).donnee).mutex));
                    850:                liberation(s_etat_processus,
                    851:                        (*((struct_liste_chainee *)
                    852:                        element_courant)).donnee);
                    853:                free((struct_liste_chainee *) element_courant);
                    854: 
                    855:                element_courant = element_suivant;
                    856:            }
                    857: 
                    858:            for(i = 0; i < (*s_etat_processus).nombre_instructions_externes;
                    859:                    i++)
                    860:            {
                    861:                free((*s_etat_processus).s_instructions_externes[i].nom);
                    862:                free((*s_etat_processus).s_instructions_externes[i]
                    863:                        .nom_bibliotheque);
                    864:            }
                    865: 
                    866:            if ((*s_etat_processus).nombre_instructions_externes != 0)
                    867:            {
                    868:                free((*s_etat_processus).s_instructions_externes);
                    869:            }
                    870: 
                    871:            element_courant = (*s_etat_processus).s_bibliotheques;
                    872:            while(element_courant != NULL)
                    873:            {
                    874:                element_suivant = (*((struct_liste_chainee *)
                    875:                        element_courant)).suivant;
                    876: 
                    877:                element_candidat = (*candidat).s_bibliotheques;
                    878:                while(element_candidat != NULL)
                    879:                {
                    880:                    if (((*((struct_bibliotheque *) (*((struct_liste_chainee *)
                    881:                            element_courant)).donnee))
                    882:                            .descripteur == (*((struct_bibliotheque *)
                    883:                            (*((struct_liste_chainee *) element_candidat))
                    884:                            .donnee)).descripteur) &&
                    885:                            ((*((struct_bibliotheque *)
                    886:                            (*((struct_liste_chainee *) element_courant))
                    887:                            .donnee)).pid == (*((struct_bibliotheque *)
                    888:                            (*((struct_liste_chainee *) element_candidat))
                    889:                            .donnee)).pid) && (pthread_equal(
                    890:                            (*((struct_bibliotheque *)
                    891:                            (*((struct_liste_chainee *) element_courant))
                    892:                            .donnee)).tid, (*((struct_bibliotheque *)
                    893:                            (*((struct_liste_chainee *) element_candidat))
                    894:                            .donnee)).tid) != 0))
                    895:                    {
                    896:                        break;
                    897:                    }
                    898: 
                    899:                    element_candidat = (*((struct_liste_chainee *)
                    900:                            element_candidat)).suivant;
                    901:                }
                    902: 
                    903:                if (element_candidat == NULL)
                    904:                {
                    905:                    dlclose((*((struct_bibliotheque *)
                    906:                            (*((struct_liste_chainee *) element_courant))
                    907:                            .donnee)).descripteur);
                    908:                }
                    909: 
                    910:                free((*((struct_bibliotheque *)
                    911:                        (*((struct_liste_chainee *)
                    912:                        element_courant)).donnee)).nom);
                    913:                free((*((struct_liste_chainee *) element_courant)).donnee);
                    914:                free(element_courant);
                    915: 
                    916:                element_courant = element_suivant;
                    917:            }
                    918: 
                    919:            element_courant = (*s_etat_processus).l_base_pile_last;
                    920:            while(element_courant != NULL)
                    921:            {
                    922:                element_suivant = (*((struct_liste_chainee *)
                    923:                        element_courant)).suivant;
                    924: 
                    925:                pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
                    926:                        element_courant)).donnee).mutex));
                    927:                pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
                    928:                        element_courant)).donnee).mutex));
                    929:                liberation(s_etat_processus,
                    930:                        (*((struct_liste_chainee *) element_courant)).donnee);
                    931:                free(element_courant);
                    932: 
                    933:                element_courant = element_suivant;
                    934:            }
                    935: 
                    936:            element_courant = (*s_etat_processus).l_base_pile_systeme;
                    937:            while(element_courant != NULL)
                    938:            {
                    939:                element_suivant = (*((struct_liste_pile_systeme *)
                    940:                        element_courant)).suivant;
                    941: 
                    942:                if ((*((struct_liste_pile_systeme *)
                    943:                        element_courant)).indice_boucle != NULL)
                    944:                {
                    945:                    pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
                    946:                            element_courant)).indice_boucle).mutex));
                    947:                    pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
                    948:                            element_courant)).indice_boucle).mutex));
                    949:                }
                    950: 
                    951:                liberation(s_etat_processus,
                    952:                        (*((struct_liste_pile_systeme *)
                    953:                        element_courant)).indice_boucle);
                    954: 
                    955:                if ((*((struct_liste_pile_systeme *)
                    956:                        element_courant)).limite_indice_boucle != NULL)
                    957:                {
                    958:                    pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
                    959:                            element_courant)).limite_indice_boucle).mutex));
                    960:                    pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
                    961:                            element_courant)).limite_indice_boucle).mutex));
                    962:                }
                    963: 
                    964:                liberation(s_etat_processus,
                    965:                        (*((struct_liste_pile_systeme *)
                    966:                        element_courant)).limite_indice_boucle);
                    967: 
                    968:                if ((*((struct_liste_pile_systeme *)
                    969:                        element_courant)).objet_de_test != NULL)
                    970:                {
                    971:                    pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
                    972:                            element_courant)).objet_de_test).mutex));
                    973:                    pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
                    974:                            element_courant)).objet_de_test).mutex));
                    975:                }
                    976: 
                    977:                liberation(s_etat_processus,
                    978:                        (*((struct_liste_pile_systeme *)
                    979:                        element_courant)).objet_de_test);
                    980: 
                    981:                if ((*((struct_liste_pile_systeme *)
                    982:                        element_courant)).nom_variable != NULL)
                    983:                {
                    984:                    free((*((struct_liste_pile_systeme *)
                    985:                            element_courant)).nom_variable);
                    986:                }
                    987: 
                    988:                free(element_courant);
                    989: 
                    990:                element_courant = element_suivant;
                    991:            }
                    992: 
                    993:            element_courant = (*s_etat_processus).s_fichiers;
                    994:            while(element_courant != NULL)
                    995:            {
                    996:                element_suivant = (*((struct_liste_chainee *)
                    997:                        element_courant)).suivant;
                    998: 
                    999:                element_candidat = (*candidat).s_fichiers;
                   1000:                while(element_candidat != NULL)
                   1001:                {
                   1002:                    if (((*((struct_descripteur_fichier *)
                   1003:                            (*((struct_liste_chainee *) element_courant))
                   1004:                            .donnee)).pid ==
                   1005:                            (*((struct_descripteur_fichier *)
                   1006:                            (*((struct_liste_chainee *) element_candidat))
                   1007:                            .donnee)).pid) && (pthread_equal(
                   1008:                            (*((struct_descripteur_fichier *)
                   1009:                            (*((struct_liste_chainee *) element_courant))
                   1010:                            .donnee)).tid, (*((struct_descripteur_fichier *)
                   1011:                            (*((struct_liste_chainee *) element_candidat))
                   1012:                            .donnee)).tid) != 0))
                   1013:                    {
1.5       bertrand 1014:                        if ((*((struct_descripteur_fichier *)
                   1015:                                (*((struct_liste_chainee *) element_courant))
                   1016:                                .donnee)).type ==
                   1017:                                (*((struct_descripteur_fichier *)
                   1018:                                (*((struct_liste_chainee *) element_candidat))
                   1019:                                .donnee)).type)
                   1020:                        {
                   1021:                            if ((*((struct_descripteur_fichier *)
                   1022:                                    (*((struct_liste_chainee *)
                   1023:                                    element_candidat)).donnee)).type == 'C')
                   1024:                            {
                   1025:                                if ((*((struct_descripteur_fichier *)
                   1026:                                        (*((struct_liste_chainee *)
                   1027:                                        element_courant)).donnee))
                   1028:                                        .descripteur_c ==
                   1029:                                        (*((struct_descripteur_fichier *)
                   1030:                                        (*((struct_liste_chainee *)
                   1031:                                        element_candidat)).donnee))
                   1032:                                        .descripteur_c)
                   1033:                                {
                   1034:                                    break;
                   1035:                                }
                   1036:                            }
                   1037:                            else
                   1038:                            {
                   1039:                                if (((*((struct_descripteur_fichier *)
                   1040:                                        (*((struct_liste_chainee *)
                   1041:                                        element_courant)).donnee))
                   1042:                                        .descripteur_sqlite ==
                   1043:                                        (*((struct_descripteur_fichier *)
                   1044:                                        (*((struct_liste_chainee *)
                   1045:                                        element_candidat)).donnee))
                   1046:                                        .descripteur_sqlite) &&
                   1047:                                        ((*((struct_descripteur_fichier *)
                   1048:                                        (*((struct_liste_chainee *)
                   1049:                                        element_courant)).donnee))
                   1050:                                        .descripteur_c ==
                   1051:                                        (*((struct_descripteur_fichier *)
                   1052:                                        (*((struct_liste_chainee *)
                   1053:                                        element_candidat)).donnee))
                   1054:                                        .descripteur_c))
                   1055:                                {
                   1056:                                    break;
                   1057:                                }
                   1058:                            }
                   1059:                        }
1.1       bertrand 1060:                    }
                   1061: 
                   1062:                    element_candidat = (*((struct_liste_chainee *)
                   1063:                            element_candidat)).suivant;
                   1064:                }
                   1065: 
                   1066:                if (element_candidat == NULL)
                   1067:                {
                   1068:                    fclose((*((struct_descripteur_fichier *)
                   1069:                            (*((struct_liste_chainee *) element_courant))
1.5       bertrand 1070:                            .donnee)).descripteur_c);
                   1071: 
                   1072:                    if ((*((struct_descripteur_fichier *)
                   1073:                            (*((struct_liste_chainee *) element_courant))
                   1074:                            .donnee)).type != 'C')
                   1075:                    {
                   1076:                        sqlite3_close((*((struct_descripteur_fichier *)
                   1077:                                (*((struct_liste_chainee *) element_courant))
                   1078:                                .donnee)).descripteur_sqlite);
                   1079:                    }
1.1       bertrand 1080:                }
                   1081: 
                   1082:                free((*((struct_descripteur_fichier *)
                   1083:                        (*((struct_liste_chainee *)
                   1084:                        element_courant)).donnee)).nom);
                   1085:                free((struct_descripteur_fichier *)
                   1086:                        (*((struct_liste_chainee *)
                   1087:                        element_courant)).donnee);
                   1088:                free(element_courant);
                   1089: 
                   1090:                element_courant = element_suivant;
                   1091:            }
                   1092: 
                   1093:            element_courant = (*s_etat_processus).s_sockets;
                   1094:            while(element_courant != NULL)
                   1095:            {
                   1096:                element_suivant = (*((struct_liste_chainee *)
                   1097:                        element_courant)).suivant;
                   1098: 
                   1099:                element_candidat = (*candidat).s_sockets;
                   1100:                while(element_candidat != NULL)
                   1101:                {
                   1102:                    if (((*((struct_socket *)
                   1103:                            (*((struct_liste_chainee *) element_courant))
                   1104:                            .donnee)).socket == (*((struct_socket *)
                   1105:                            (*((struct_liste_chainee *) element_candidat))
                   1106:                            .donnee)).socket) &&
                   1107:                            ((*((struct_socket *)
                   1108:                            (*((struct_liste_chainee *) element_courant))
                   1109:                            .donnee)).pid == (*((struct_socket *)
                   1110:                            (*((struct_liste_chainee *) element_candidat))
                   1111:                            .donnee)).pid) && (pthread_equal(
                   1112:                            (*((struct_socket *)
                   1113:                            (*((struct_liste_chainee *) element_courant))
                   1114:                            .donnee)).tid, (*((struct_socket *)
                   1115:                            (*((struct_liste_chainee *) element_candidat))
                   1116:                            .donnee)).tid) != 0))
                   1117:                    {
                   1118:                        break;
                   1119:                    }
                   1120: 
                   1121:                    element_candidat = (*((struct_liste_chainee *)
                   1122:                            element_candidat)).suivant;
                   1123:                }
                   1124: 
                   1125:                if (element_candidat == NULL)
                   1126:                {
                   1127:                    if ((*((struct_socket *) (*((struct_liste_chainee *)
                   1128:                            element_courant)).donnee)).socket_connectee
                   1129:                            == d_vrai)
                   1130:                    {
                   1131:                        shutdown((*((struct_socket *)
                   1132:                                (*((struct_liste_chainee *) element_courant))
                   1133:                                .donnee)).socket, SHUT_RDWR);
                   1134:                    }
                   1135: 
                   1136:                    close((*((struct_socket *)
                   1137:                            (*((struct_liste_chainee *) element_courant))
                   1138:                            .donnee)).socket);
                   1139:                }
                   1140: 
                   1141:                pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
                   1142:                        element_courant)).donnee).mutex));
                   1143:                pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
                   1144:                        element_courant)).donnee).mutex));
                   1145: 
                   1146:                liberation(s_etat_processus,
                   1147:                        (*((struct_liste_chainee *)
                   1148:                        element_courant)).donnee);
                   1149:                free(element_courant);
                   1150: 
                   1151:                element_courant = element_suivant;
                   1152:            }
                   1153: 
1.14      bertrand 1154: /*
                   1155: ================================================================================
                   1156:   À noter : on ne ferme pas la connexion car la conséquence immédiate est
                   1157:   une destruction de l'objet pour le processus père.
                   1158: ================================================================================
                   1159: 
1.1       bertrand 1160:            element_courant = (*s_etat_processus).s_connecteurs_sql;
                   1161:            while(element_courant != NULL)
                   1162:            {
                   1163:                element_suivant = (*((struct_liste_chainee *)
                   1164:                        element_courant)).suivant;
                   1165: 
                   1166:                element_candidat = (*candidat).s_connecteurs_sql;
                   1167:                while(element_candidat != NULL)
                   1168:                {
                   1169:                    if (((
                   1170: #ifdef MYSQL_SUPPORT
                   1171:                            ((*((struct_connecteur_sql *)
                   1172:                            (*((struct_liste_chainee *) element_courant))
                   1173:                            .donnee)).descripteur.mysql ==
                   1174:                            (*((struct_connecteur_sql *)
                   1175:                            (*((struct_liste_chainee *) element_candidat))
                   1176:                            .donnee)).descripteur.mysql)
                   1177:                            &&
                   1178:                            (strcmp((*((struct_connecteur_sql *)
                   1179:                            (*((struct_liste_chainee *) element_courant))
                   1180:                            .donnee)).type, "MYSQL") == 0)
                   1181:                            &&
                   1182:                            (strcmp((*((struct_connecteur_sql *)
                   1183:                            (*((struct_liste_chainee *) element_candidat))
                   1184:                            .donnee)).type, "MYSQL") == 0)
                   1185: #else
                   1186:                            0
                   1187: #endif
                   1188:                            ) || (
                   1189: #ifdef POSTGRESQL_SUPPORT
                   1190:                            ((*((struct_connecteur_sql *)
                   1191:                            (*((struct_liste_chainee *) element_courant))
                   1192:                            .donnee)).descripteur.postgresql ==
                   1193:                            (*((struct_connecteur_sql *)
                   1194:                            (*((struct_liste_chainee *) element_candidat))
                   1195:                            .donnee)).descripteur.postgresql)
                   1196:                            &&
                   1197:                            (strcmp((*((struct_connecteur_sql *)
                   1198:                            (*((struct_liste_chainee *) element_courant))
                   1199:                            .donnee)).type, "POSTGRESQL") == 0)
                   1200:                            &&
                   1201:                            (strcmp((*((struct_connecteur_sql *)
                   1202:                            (*((struct_liste_chainee *) element_candidat))
                   1203:                            .donnee)).type, "POSTGRESQL") == 0)
                   1204: #else
                   1205:                            0
                   1206: #endif
                   1207:                            )) &&
                   1208:                            ((*((struct_connecteur_sql *)
                   1209:                            (*((struct_liste_chainee *) element_courant))
                   1210:                            .donnee)).pid == (*((struct_connecteur_sql *)
                   1211:                            (*((struct_liste_chainee *) element_candidat))
                   1212:                            .donnee)).pid) && (pthread_equal(
                   1213:                            (*((struct_connecteur_sql *)
                   1214:                            (*((struct_liste_chainee *) element_courant))
                   1215:                            .donnee)).tid, (*((struct_connecteur_sql *)
                   1216:                            (*((struct_liste_chainee *) element_candidat))
                   1217:                            .donnee)).tid) != 0))
                   1218:                    {
                   1219:                        break;
                   1220:                    }
                   1221: 
                   1222:                    element_candidat = (*((struct_liste_chainee *)
                   1223:                            element_candidat)).suivant;
                   1224:                }
                   1225: 
                   1226:                if (element_candidat == NULL)
                   1227:                {
                   1228:                    sqlclose((*((struct_liste_chainee *) element_courant))
                   1229:                            .donnee);
                   1230:                }
                   1231: 
                   1232:                pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
                   1233:                        element_courant)).donnee).mutex));
                   1234:                pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
                   1235:                        element_courant)).donnee).mutex));
                   1236: 
                   1237:                liberation(s_etat_processus, (*((struct_liste_chainee *)
                   1238:                        element_courant)).donnee);
                   1239:                free(element_courant);
                   1240: 
                   1241:                element_courant = element_suivant;
                   1242:            }
1.14      bertrand 1243: */
1.1       bertrand 1244: 
1.15      bertrand 1245:            (*s_etat_processus).s_connecteurs_sql = NULL;
                   1246: 
1.1       bertrand 1247:            element_courant = (*s_etat_processus).s_marques;
                   1248:            while(element_courant != NULL)
                   1249:            {
                   1250:                free((*((struct_marque *) element_courant)).label);
                   1251:                free((*((struct_marque *) element_courant)).position);
                   1252:                element_suivant = (*((struct_marque *) element_courant))
                   1253:                        .suivant;
                   1254:                free(element_courant);
                   1255:                element_courant = element_suivant;
                   1256:            }
                   1257: 
                   1258:            liberation_allocateur(s_etat_processus);
                   1259: 
1.79      bertrand 1260: #          ifndef SEMAPHORES_NOMMES
                   1261:                sem_post(&((*s_etat_processus).semaphore_fork));
                   1262:                sem_destroy(&((*s_etat_processus).semaphore_fork));
                   1263: #          else
                   1264:                sem_post((*s_etat_processus).semaphore_fork);
1.80      bertrand 1265:                sem_close((*s_etat_processus).semaphore_fork);
1.79      bertrand 1266: #          endif
1.1       bertrand 1267: 
1.59      bertrand 1268:            liberation_contexte_cas(s_etat_processus);
1.1       bertrand 1269:            free(s_etat_processus);
                   1270: 
                   1271:            s_etat_processus = candidat;
                   1272:        }
                   1273: 
                   1274:        l_element_suivant = (*l_element_courant).suivant;
                   1275: 
                   1276:        free((struct_thread *) (*l_element_courant).donnee);
                   1277:        free((struct_liste_chainee *) l_element_courant);
                   1278: 
                   1279:        l_element_courant = l_element_suivant;
                   1280:    }
                   1281: 
                   1282:    liste_threads = NULL;
                   1283: 
                   1284:    l_element_courant = liste_threads_surveillance;
                   1285: 
                   1286:    while(l_element_courant != NULL)
                   1287:    {
                   1288:        s_argument_thread = (struct_descripteur_thread *)
                   1289:                (*l_element_courant).donnee;
                   1290: 
1.40      bertrand 1291:        if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
                   1292:                != 0)
1.1       bertrand 1293:        {
                   1294:            (*s_etat_processus).erreur_systeme = d_es_processus;
1.68      bertrand 1295:            pthread_mutex_unlock(&mutex_liste_threads);
1.1       bertrand 1296:            return;
                   1297:        }
                   1298: 
                   1299:        (*s_argument_thread).nombre_references--;
                   1300: 
                   1301:        BUG((*s_argument_thread).nombre_references < 0,
                   1302:                printf("(*s_argument_thread).nombre_references = %d\n",
                   1303:                (int) (*s_argument_thread).nombre_references));
                   1304: 
                   1305:        if ((*s_argument_thread).nombre_references == 0)
                   1306:        {
1.20      bertrand 1307:            close((*s_argument_thread).pipe_objets[0]);
                   1308:            close((*s_argument_thread).pipe_acquittement[1]);
                   1309:            close((*s_argument_thread).pipe_injections[1]);
                   1310:            close((*s_argument_thread).pipe_nombre_injections[1]);
1.125     bertrand 1311:            close((*s_argument_thread).pipe_nombre_elements_attente[0]);
1.20      bertrand 1312:            close((*s_argument_thread).pipe_interruptions[0]);
                   1313: 
1.40      bertrand 1314:            if (pthread_mutex_unlock(&((*s_argument_thread)
                   1315:                    .mutex_nombre_references)) != 0)
1.1       bertrand 1316:            {
                   1317:                (*s_etat_processus).erreur_systeme = d_es_processus;
1.68      bertrand 1318:                pthread_mutex_unlock(&mutex_liste_threads);
1.1       bertrand 1319:                return;
                   1320:            }
                   1321: 
                   1322:            pthread_mutex_destroy(&((*s_argument_thread).mutex));
1.40      bertrand 1323:            pthread_mutex_destroy(&((*s_argument_thread)
                   1324:                    .mutex_nombre_references));
1.20      bertrand 1325: 
                   1326:            if ((*s_argument_thread).processus_detache == d_faux)
                   1327:            {
                   1328:                if ((*s_argument_thread).destruction_objet == d_vrai)
                   1329:                {
                   1330:                    liberation(s_etat_processus, (*s_argument_thread).argument);
                   1331:                }
                   1332:            }
                   1333: 
1.1       bertrand 1334:            free(s_argument_thread);
                   1335:        }
                   1336:        else
                   1337:        {
1.40      bertrand 1338:            if (pthread_mutex_unlock(&((*s_argument_thread)
                   1339:                    .mutex_nombre_references)) != 0)
1.1       bertrand 1340:            {
                   1341:                (*s_etat_processus).erreur_systeme = d_es_processus;
1.68      bertrand 1342:                pthread_mutex_unlock(&mutex_liste_threads);
1.1       bertrand 1343:                return;
                   1344:            }
                   1345:        }
                   1346: 
                   1347:        l_element_suivant = (*l_element_courant).suivant;
                   1348:        free((struct_liste_chainee *) l_element_courant);
                   1349:        l_element_courant = l_element_suivant;
                   1350:    }
                   1351: 
                   1352:    liste_threads_surveillance = NULL;
                   1353: 
1.68      bertrand 1354:    if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1.1       bertrand 1355:    {
                   1356:        (*s_etat_processus).erreur_systeme = d_es_processus;
                   1357:        return;
                   1358:    }
                   1359: 
                   1360:    return;
                   1361: }
                   1362: 
                   1363: static struct_processus *
                   1364: recherche_thread(pid_t pid, pthread_t tid)
                   1365: {
                   1366:    volatile struct_liste_chainee_volatile      *l_element_courant;
                   1367: 
                   1368:    struct_processus                            *s_etat_processus;
                   1369: 
                   1370:    l_element_courant = liste_threads;
                   1371: 
                   1372:    while(l_element_courant != NULL)
                   1373:    {
                   1374:        if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee))
                   1375:                .tid, tid) != 0) && ((*((struct_thread *)
                   1376:                (*l_element_courant).donnee)).pid == pid))
                   1377:        {
                   1378:            break;
                   1379:        }
                   1380: 
                   1381:        l_element_courant = (*l_element_courant).suivant;
                   1382:    }
                   1383: 
                   1384:    if (l_element_courant == NULL)
                   1385:    {
                   1386:        /*
                   1387:         * Le processus n'existe plus. On ne distribue aucun signal.
                   1388:         */
                   1389: 
                   1390:        return(NULL);
                   1391:    }
                   1392: 
                   1393:    s_etat_processus = (*((struct_thread *)
                   1394:            (*l_element_courant).donnee)).s_etat_processus;
                   1395: 
                   1396:    return(s_etat_processus);
                   1397: }
                   1398: 
1.66      bertrand 1399: static struct_processus *
                   1400: recherche_thread_principal(pid_t pid)
1.1       bertrand 1401: {
                   1402:    volatile struct_liste_chainee_volatile      *l_element_courant;
                   1403: 
                   1404:    l_element_courant = liste_threads;
                   1405: 
                   1406:    while(l_element_courant != NULL)
                   1407:    {
                   1408:        if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal
                   1409:                == d_vrai) && ((*((struct_thread *)
                   1410:                (*l_element_courant).donnee)).pid == pid))
                   1411:        {
                   1412:            break;
                   1413:        }
                   1414: 
                   1415:        l_element_courant = (*l_element_courant).suivant;
                   1416:    }
                   1417: 
                   1418:    if (l_element_courant == NULL)
                   1419:    {
                   1420:        /*
                   1421:         * Le processus n'existe plus. On ne distribue aucun signal.
                   1422:         */
                   1423: 
1.66      bertrand 1424:        return(NULL);
1.1       bertrand 1425:    }
                   1426: 
1.66      bertrand 1427:    return((*((struct_thread *) (*l_element_courant).donnee))
                   1428:            .s_etat_processus);
1.1       bertrand 1429: }
                   1430: 
                   1431: 
                   1432: /*
                   1433: ================================================================================
                   1434:   Procédures de gestion des signaux d'interruption
                   1435: ================================================================================
                   1436:   Entrée : variable globale
                   1437: --------------------------------------------------------------------------------
                   1438:   Sortie : variable globale modifiée
                   1439: --------------------------------------------------------------------------------
                   1440:   Effets de bord : néant
                   1441: ================================================================================
                   1442: */
                   1443: 
                   1444: // Les routines suivantes sont uniquement appelées depuis les gestionnaires
1.17      bertrand 1445: // des signaux asynchrones. Elles ne doivent pas bloquer dans le cas où
1.1       bertrand 1446: // les sémaphores sont déjà bloqués par un gestionnaire de signal.
                   1447: 
                   1448: static inline void
1.68      bertrand 1449: verrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
1.1       bertrand 1450: {
                   1451:    int         semaphore;
                   1452: 
1.79      bertrand 1453: #  ifndef SEMAPHORES_NOMMES
1.77      bertrand 1454:    if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
1.79      bertrand 1455: #  else
                   1456:    if (sem_post((*s_etat_processus).semaphore_fork) != 0)
                   1457: #  endif
1.1       bertrand 1458:    {
1.68      bertrand 1459:        BUG(1, uprintf("Lock error !\n"));
                   1460:        return;
1.1       bertrand 1461:    }
                   1462: 
                   1463:    // Il faut respecteur l'atomicité des deux opérations suivantes !
                   1464: 
1.68      bertrand 1465:    if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) != 0)
1.1       bertrand 1466:    {
1.79      bertrand 1467: #      ifndef SEMAPHORES_NOMMES
1.77      bertrand 1468:        sem_wait(&((*s_etat_processus).semaphore_fork));
1.79      bertrand 1469: #      else
                   1470:        sem_wait((*s_etat_processus).semaphore_fork);
                   1471: #      endif
1.68      bertrand 1472:        BUG(1, uprintf("Unlock error !\n"));
                   1473:        return;
1.1       bertrand 1474:    }
                   1475: 
1.8       bertrand 1476: #  ifndef SEMAPHORES_NOMMES
1.1       bertrand 1477:    if (sem_post(&semaphore_gestionnaires_signaux) == -1)
1.8       bertrand 1478: #  else
                   1479:    if (sem_post(semaphore_gestionnaires_signaux) == -1)
                   1480: #  endif
1.1       bertrand 1481:    {
1.79      bertrand 1482: #      ifndef SEMAPHORES_NOMMES
1.77      bertrand 1483:        sem_wait(&((*s_etat_processus).semaphore_fork));
1.79      bertrand 1484: #      else
                   1485:        sem_wait((*s_etat_processus).semaphore_fork);
                   1486: #      endif
1.1       bertrand 1487:        BUG(1, uprintf("Lock error !\n"));
                   1488:        return;
                   1489:    }
                   1490: 
1.8       bertrand 1491: #  ifndef SEMAPHORES_NOMMES
1.1       bertrand 1492:    if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1.8       bertrand 1493: #  else
                   1494:    if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
                   1495: #  endif
1.1       bertrand 1496:    {
1.79      bertrand 1497: #      ifndef SEMAPHORES_NOMMES
1.77      bertrand 1498:        sem_wait(&((*s_etat_processus).semaphore_fork));
1.79      bertrand 1499: #      else
                   1500:        sem_wait((*s_etat_processus).semaphore_fork);
                   1501: #      endif
1.1       bertrand 1502:        BUG(1, uprintf("Lock error !\n"));
                   1503:        return;
                   1504:    }
                   1505: 
1.68      bertrand 1506:    if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)
1.1       bertrand 1507:    {
1.79      bertrand 1508: #      ifndef SEMAPHORES_NOMMES
1.77      bertrand 1509:        sem_wait(&((*s_etat_processus).semaphore_fork));
1.79      bertrand 1510: #      else
                   1511:        sem_wait((*s_etat_processus).semaphore_fork);
                   1512: #      endif
1.1       bertrand 1513:        BUG(1, uprintf("Unlock error !\n"));
                   1514:        return;
                   1515:    }
                   1516: 
                   1517:    if (semaphore == 1)
                   1518:    {
                   1519:        // Le semaphore ne peut être pris par le thread qui a appelé
                   1520:        // le gestionnaire de signal car le signal est bloqué par ce thread
                   1521:        // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que
                   1522:        // par un thread concurrent. On essaye donc de le bloquer jusqu'à
                   1523:        // ce que ce soit possible.
                   1524: 
1.68      bertrand 1525:        if (pthread_mutex_lock(&mutex_liste_threads) != 0)
1.1       bertrand 1526:        {
1.80      bertrand 1527: #          ifndef SEMAPHORES_NOMMES
1.77      bertrand 1528:            sem_wait(&((*s_etat_processus).semaphore_fork));
1.80      bertrand 1529: #          else
                   1530:            sem_wait((*s_etat_processus).semaphore_fork);
                   1531: #          endif
1.68      bertrand 1532:            BUG(1, uprintf("Lock error !\n"));
                   1533:            return;
1.1       bertrand 1534:        }
                   1535:    }
                   1536: 
                   1537:    return;
                   1538: }
                   1539: 
                   1540: static inline void
1.68      bertrand 1541: deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
1.1       bertrand 1542: {
                   1543:    int         semaphore;
                   1544: 
                   1545:    // Il faut respecteur l'atomicité des deux opérations suivantes !
                   1546: 
1.68      bertrand 1547:    if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) == -1)
1.1       bertrand 1548:    {
1.79      bertrand 1549: #      ifndef SEMAPHORES_NOMMES
1.77      bertrand 1550:        sem_wait(&((*s_etat_processus).semaphore_fork));
1.79      bertrand 1551: #      else
                   1552:        sem_wait((*s_etat_processus).semaphore_fork);
                   1553: #      endif
1.68      bertrand 1554:        BUG(1, uprintf("Unlock error !\n"));
                   1555:        return;
1.1       bertrand 1556:    }
                   1557: 
1.8       bertrand 1558: #  ifndef SEMAPHORES_NOMMES
1.1       bertrand 1559:    if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
1.8       bertrand 1560: #  else
                   1561:    if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
                   1562: #  endif
1.1       bertrand 1563:    {
1.79      bertrand 1564: #      ifndef SEMAPHORES_NOMMES
1.77      bertrand 1565:        sem_wait(&((*s_etat_processus).semaphore_fork));
1.79      bertrand 1566: #      else
                   1567:        sem_wait((*s_etat_processus).semaphore_fork);
                   1568: #      endif
1.1       bertrand 1569:        BUG(1, uprintf("Unlock error !\n"));
                   1570:        return;
                   1571:    }
                   1572: 
1.8       bertrand 1573: #  ifndef SEMAPHORES_NOMMES
1.1       bertrand 1574:    while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
1.8       bertrand 1575: #  else
                   1576:    while(sem_wait(semaphore_gestionnaires_signaux) == -1)
                   1577: #  endif
1.1       bertrand 1578:    {
                   1579:        if (errno != EINTR)
                   1580:        {
1.79      bertrand 1581: #          ifndef SEMAPHORES_NOMMES
1.77      bertrand 1582:            sem_wait(&((*s_etat_processus).semaphore_fork));
1.79      bertrand 1583: #          else
                   1584:            sem_wait((*s_etat_processus).semaphore_fork);
                   1585: #          endif
1.1       bertrand 1586:            BUG(1, uprintf("Unlock error !\n"));
                   1587:            return;
                   1588:        }
                   1589:    }
                   1590: 
1.68      bertrand 1591:    if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)
1.1       bertrand 1592:    {
1.79      bertrand 1593: #      ifndef SEMAPHORES_NOMMES
1.77      bertrand 1594:        sem_wait(&((*s_etat_processus).semaphore_fork));
1.79      bertrand 1595: #      else
                   1596:        sem_wait((*s_etat_processus).semaphore_fork);
                   1597: #      endif
1.1       bertrand 1598:        BUG(1, uprintf("Unlock error !\n"));
                   1599:        return;
                   1600:    }
                   1601: 
1.79      bertrand 1602: #  ifndef SEMAPHORES_NOMMES
1.78      bertrand 1603:    while(sem_wait(&((*s_etat_processus).semaphore_fork)) != 0)
1.79      bertrand 1604: #  else
                   1605:    while(sem_wait((*s_etat_processus).semaphore_fork) != 0)
                   1606: #  endif
1.1       bertrand 1607:    {
1.79      bertrand 1608:        if (errno != EINTR)
                   1609:        {
                   1610:            BUG(1, uprintf("Unlock error !\n"));
                   1611:            return;
                   1612:        }
1.1       bertrand 1613:    }
                   1614: 
                   1615:    if (semaphore == 1)
                   1616:    {
1.68      bertrand 1617:        if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
1.1       bertrand 1618:        {
                   1619:            BUG(1, uprintf("Unlock error !\n"));
                   1620:            return;
                   1621:        }
                   1622:    }
                   1623: 
                   1624:    return;
                   1625: }
                   1626: 
1.106     bertrand 1627: /*
                   1628: ================================================================================
                   1629:   Fonctions de gestion des signaux dans les threads.
                   1630: 
                   1631:   Lorsqu'un processus reçoit un signal, il appelle le gestionnaire de signal
                   1632:   associé qui ne fait qu'envoyer au travers de write() le signal
                   1633:   reçus dans un pipe. Un second thread est bloqué sur ce pipe et
                   1634:   effectue le traitement adéquat pour le signal donné.
                   1635: ================================================================================
                   1636: */
                   1637: 
1.65      bertrand 1638: #define test_signal(signal) \
1.67      bertrand 1639:    if (signal_test == SIGTEST) { signal_test = signal; return; }
1.66      bertrand 1640: 
1.106     bertrand 1641: static int         pipe_signaux;
                   1642: 
                   1643: logical1
                   1644: lancement_thread_signaux(struct_processus *s_etat_processus)
                   1645: {
                   1646:    pthread_attr_t                  attributs;
                   1647: 
                   1648:    void                            *argument;
                   1649: 
                   1650:    if (pipe((*s_etat_processus).pipe_signaux) != 0)
                   1651:    {
                   1652:        (*s_etat_processus).erreur_systeme = d_es_processus;
                   1653:        return(d_erreur);
                   1654:    }
                   1655: 
                   1656:    pipe_signaux = (*s_etat_processus).pipe_signaux[1];
                   1657: 
                   1658:    if (pthread_attr_init(&attributs) != 0)
                   1659:    {
                   1660:        (*s_etat_processus).erreur_systeme = d_es_processus;
                   1661:        return(d_erreur);
                   1662:    }
                   1663: 
                   1664:    if (pthread_attr_setdetachstate(&attributs, PTHREAD_CREATE_JOINABLE) != 0)
                   1665:    {
                   1666:        (*s_etat_processus).erreur_systeme = d_es_processus;
                   1667:        return(d_erreur);
                   1668:    }
                   1669: 
                   1670:    argument = (*s_etat_processus).pipe_signaux;
                   1671: 
                   1672:    if (pthread_create(&((*s_etat_processus).thread_signaux), &attributs,
                   1673:            thread_signaux, argument) != 0)
                   1674:    {
                   1675:        (*s_etat_processus).erreur_systeme = d_es_processus;
                   1676:        return(d_erreur);
                   1677:    }
                   1678: 
                   1679:    return(d_absence_erreur);
                   1680: }
                   1681: 
                   1682: logical1
                   1683: arret_thread_signaux(struct_processus *s_etat_processus)
                   1684: {
                   1685:    unsigned char       signal;
                   1686:    ssize_t             n;
                   1687: 
                   1688:    signal = (unsigned char ) (rpl_sigmax & 0xFF);
                   1689: 
                   1690:    do
                   1691:    {
                   1692:        n = write((*s_etat_processus).pipe_signaux[1], &signal, sizeof(signal));
                   1693: 
                   1694:        if (n < 0)
                   1695:        {
                   1696:            return(d_erreur);
                   1697:        }
                   1698:    } while(n != 1);
                   1699: 
                   1700:    pthread_join((*s_etat_processus).thread_signaux, NULL);
                   1701: 
                   1702:    close((*s_etat_processus).pipe_signaux[0]);
                   1703:    close((*s_etat_processus).pipe_signaux[1]);
                   1704: 
                   1705:    return(d_absence_erreur);
                   1706: }
                   1707: 
                   1708: void *
                   1709: thread_signaux(void *argument)
                   1710: {
                   1711:    int                     *pipe;
                   1712: 
                   1713:    sigset_t                masque;
                   1714: 
                   1715:    struct pollfd           fds;
                   1716: 
                   1717:    unsigned char           signal;
                   1718: 
                   1719:    pipe = (int *) argument;
                   1720:    fds.fd = pipe[0];
                   1721:    fds.events = POLLIN;
                   1722:    fds.revents = 0;
                   1723: 
                   1724:    sigfillset(&masque);
                   1725:    pthread_sigmask(SIG_BLOCK, &masque, NULL);
                   1726: 
                   1727:    do
                   1728:    {
                   1729:        if (poll(&fds, 1, -1) == -1)
                   1730:        {
                   1731:            pthread_exit(NULL);
                   1732:        }
                   1733: 
                   1734:        read(fds.fd, &signal, 1);
                   1735: 
                   1736:        if (signal != (0xFF & rpl_sigmax))
                   1737:        {
                   1738:            envoi_signal_processus(getpid(), signal);
                   1739:            // Un signal SIGALRM est envoyé par le thread de surveillance
                   1740:            // des signaux jusqu'à ce que les signaux soient tous traités.
                   1741:        }
                   1742:    } while(signal != (0xFF & rpl_sigmax));
                   1743: 
                   1744:    pthread_exit(NULL);
                   1745: }
                   1746: 
1.67      bertrand 1747: // Récupération des signaux
1.99      bertrand 1748: // - SIGINT  (arrêt au clavier)
1.67      bertrand 1749: // - SIGTERM (signal d'arrêt en provenance du système)
1.65      bertrand 1750: 
1.67      bertrand 1751: void
                   1752: interruption1(int signal)
1.30      bertrand 1753: {
1.106     bertrand 1754:    unsigned char       signal_tronque;
                   1755: 
1.67      bertrand 1756:    test_signal(signal);
1.30      bertrand 1757: 
1.67      bertrand 1758:    switch(signal)
1.31      bertrand 1759:    {
1.67      bertrand 1760:        case SIGINT:
1.106     bertrand 1761:            signal_tronque = (unsigned char) (rpl_sigint & 0xFF);
                   1762:            write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
1.67      bertrand 1763:            break;
1.66      bertrand 1764: 
1.67      bertrand 1765:        case SIGTERM:
1.106     bertrand 1766:            signal_tronque = (unsigned char) (rpl_sigterm & 0xFF);
                   1767:            write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
1.67      bertrand 1768:            break;
1.31      bertrand 1769: 
1.81      bertrand 1770:        case SIGUSR1:
1.106     bertrand 1771:            signal_tronque = (unsigned char) (rpl_sigalrm & 0xFF);
                   1772:            write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
1.67      bertrand 1773:            break;
1.105     bertrand 1774: 
                   1775:        default:
                   1776:            // SIGALRM
                   1777:            break;
1.31      bertrand 1778:    }
1.66      bertrand 1779: 
1.67      bertrand 1780:    return;
1.66      bertrand 1781: }
                   1782: 
1.106     bertrand 1783: // Récupération des signaux
                   1784: // - SIGFSTP
                   1785: //
                   1786: // ATTENTION :
                   1787: // Le signal SIGFSTP provient de la mort du processus de contrôle.
                   1788: // Sous certains systèmes (Linux...), la mort du terminal de contrôle
                   1789: // se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
                   1790: // (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
                   1791: // non initialisée (pointeur NULL) issue de TERMIO.
                   1792: 
                   1793: void
                   1794: interruption2(int signal)
                   1795: {
                   1796:    unsigned char       signal_tronque;
                   1797: 
                   1798:    test_signal(signal);
                   1799: 
                   1800:    signal_tronque = (unsigned char) (rpl_sigtstp & 0xFF);
                   1801:    write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
                   1802:    return;
                   1803: }
                   1804: 
                   1805: void
                   1806: interruption3(int signal)
                   1807: {
                   1808:    // Si on passe par ici, c'est qu'il est impossible de récupérer
                   1809:    // l'erreur d'accès à la mémoire. On sort donc du programme quitte à
                   1810:    // ce qu'il reste des processus orphelins.
                   1811: 
                   1812:    unsigned char       message_1[] = "+++System : Uncaught access violation\n"
                   1813:                                "+++System : Aborting !\n";
                   1814:    unsigned char       message_2[] = "+++System : Stack overflow\n"
                   1815:                                "+++System : Aborting !\n";
                   1816: 
                   1817:    test_signal(signal);
                   1818: 
                   1819:    if (pid_processus_pere == getpid())
                   1820:    {
                   1821:        kill(pid_processus_pere, SIGUSR1);
                   1822:    }
                   1823: 
                   1824:    if (signal != SIGUSR2)
                   1825:    {
                   1826:        write(STDERR_FILENO, message_1, strlen(message_1));
                   1827:    }
                   1828:    else
                   1829:    {
                   1830:        write(STDERR_FILENO, message_2, strlen(message_2));
                   1831:    }
                   1832: 
                   1833:    _exit(EXIT_FAILURE);
                   1834: }
                   1835: 
                   1836: // Récupération des signaux
                   1837: // - SIGHUP
                   1838: 
                   1839: void
                   1840: interruption4(int signal)
                   1841: {
                   1842:    unsigned char       signal_tronque;
                   1843: 
                   1844:    test_signal(signal);
                   1845: 
                   1846:    signal_tronque = (unsigned char) (rpl_sighup & 0xFF);
                   1847:    write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
                   1848:    return;
                   1849: }
                   1850: 
                   1851: // Récupération des signaux
                   1852: // - SIGPIPE
                   1853: 
                   1854: void
                   1855: interruption5(int signal)
                   1856: {
                   1857:    unsigned char       message[] = "+++System : SIGPIPE\n"
                   1858:                                "+++System : Aborting !\n";
                   1859:    unsigned char       signal_tronque;
                   1860: 
                   1861:    test_signal(signal);
                   1862: 
                   1863:    if (pid_processus_pere == getpid())
                   1864:    {
                   1865:        signal_tronque = (unsigned char) (rpl_sigalrm & 0xFF);
                   1866:        write(pipe_signaux, &signal_tronque, sizeof(signal_tronque));
                   1867:    }
                   1868: 
                   1869:    write(STDERR_FILENO, message, strlen(message));
                   1870:    return;
                   1871: }
                   1872: 
1.67      bertrand 1873: inline static void
                   1874: signal_alrm(struct_processus *s_etat_processus, pid_t pid)
1.66      bertrand 1875: {
1.67      bertrand 1876:    struct_processus        *s_thread_principal;
1.66      bertrand 1877: 
1.68      bertrand 1878:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.67      bertrand 1879: 
                   1880:    if (pid == getpid())
                   1881:    {
                   1882:        // Si pid est égal à getpid(), le signal à traiter est issu
                   1883:        // du même processus que celui qui va le traiter, mais d'un thread
                   1884:        // différent.
1.66      bertrand 1885: 
1.67      bertrand 1886:        if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
1.66      bertrand 1887:        {
1.67      bertrand 1888:            printf("[%d] RPL/SIGALRM (thread %llu)\n", (int) getpid(),
                   1889:                    (unsigned long long) pthread_self());
                   1890:            fflush(stdout);
                   1891:        }
1.66      bertrand 1892: 
1.67      bertrand 1893:        if ((*s_etat_processus).pid_processus_pere != getpid())
                   1894:        {
                   1895:            // On n'est pas dans le processus père, on remonte le signal.
                   1896:            envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                   1897:                    rpl_sigalrm);
1.66      bertrand 1898:        }
                   1899:        else
                   1900:        {
1.67      bertrand 1901:            // On est dans le processus père, on effectue un arrêt d'urgence.
                   1902:            (*s_etat_processus).var_volatile_alarme = -1;
                   1903:            (*s_etat_processus).var_volatile_requete_arret = -1;
1.66      bertrand 1904:        }
1.67      bertrand 1905:    }
                   1906:    else
                   1907:    {
                   1908:        // Le signal est issu d'un processus différent. On recherche le
                   1909:        // thread principal pour remonter le signal.
1.66      bertrand 1910: 
1.67      bertrand 1911:        if ((s_thread_principal = recherche_thread_principal(getpid()))
                   1912:                != NULL)
1.66      bertrand 1913:        {
1.67      bertrand 1914:            envoi_signal_contexte(s_thread_principal, rpl_sigalrm);
1.66      bertrand 1915:        }
1.67      bertrand 1916:    }
1.29      bertrand 1917: 
1.68      bertrand 1918:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.66      bertrand 1919:    return;
                   1920: }
                   1921: 
1.67      bertrand 1922: inline static void
                   1923: signal_term(struct_processus *s_etat_processus, pid_t pid)
1.66      bertrand 1924: {
1.67      bertrand 1925:    struct_processus        *s_thread_principal;
1.97      bertrand 1926:    pthread_mutex_t         exclusion = PTHREAD_MUTEX_INITIALIZER;
1.66      bertrand 1927: 
1.68      bertrand 1928:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.66      bertrand 1929: 
1.67      bertrand 1930:    if (pid == getpid())
1.1       bertrand 1931:    {
1.67      bertrand 1932:        if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
                   1933:        {
                   1934:            printf("[%d] RPL/SIGTERM (thread %llu)\n", (int) getpid(),
                   1935:                    (unsigned long long) pthread_self());
                   1936:            fflush(stdout);
                   1937:        }
                   1938: 
                   1939:        if ((*s_etat_processus).pid_processus_pere != getpid())
                   1940:        {
                   1941:            envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                   1942:                    rpl_sigterm);
                   1943:        }
                   1944:        else
1.1       bertrand 1945:        {
1.67      bertrand 1946:            (*s_etat_processus).var_volatile_traitement_sigint = -1;
                   1947: 
1.97      bertrand 1948:            pthread_mutex_lock(&exclusion);
1.1       bertrand 1949: 
1.67      bertrand 1950:            if ((*s_etat_processus).var_volatile_requete_arret == -1)
1.1       bertrand 1951:            {
1.68      bertrand 1952:                deverrouillage_gestionnaire_signaux(s_etat_processus);
1.97      bertrand 1953:                pthread_mutex_unlock(&exclusion);
1.67      bertrand 1954:                return;
1.1       bertrand 1955:            }
                   1956: 
1.67      bertrand 1957:            (*s_etat_processus).var_volatile_requete_arret = -1;
                   1958:            (*s_etat_processus).var_volatile_alarme = -1;
                   1959: 
1.97      bertrand 1960:            pthread_mutex_unlock(&exclusion);
1.1       bertrand 1961:        }
1.67      bertrand 1962:    }
                   1963:    else
                   1964:    {
                   1965:        if ((s_thread_principal = recherche_thread_principal(getpid()))
                   1966:                != NULL)
1.1       bertrand 1967:        {
1.67      bertrand 1968:            envoi_signal_contexte(s_thread_principal, rpl_sigterm);
                   1969:        }
                   1970:    }
1.44      bertrand 1971: 
1.68      bertrand 1972:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.67      bertrand 1973:    return;
                   1974: }
1.1       bertrand 1975: 
1.67      bertrand 1976: inline static void
                   1977: signal_int(struct_processus *s_etat_processus, pid_t pid)
                   1978: {
                   1979:    struct_processus        *s_thread_principal;
                   1980:    volatile sig_atomic_t   exclusion = 0;
1.1       bertrand 1981: 
1.68      bertrand 1982:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 1983: 
1.67      bertrand 1984:    if (pid == getpid())
                   1985:    {
                   1986:        if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
                   1987:        {
                   1988:            printf("[%d] RPL/SIGINT (thread %llu)\n", (int) getpid(),
                   1989:                    (unsigned long long) pthread_self());
                   1990:            fflush(stdout);
                   1991:        }
1.1       bertrand 1992: 
1.67      bertrand 1993:        if ((*s_etat_processus).pid_processus_pere != getpid())
                   1994:        {
                   1995:            envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                   1996:                    rpl_sigint);
                   1997:        }
                   1998:        else
                   1999:        {
                   2000:            (*s_etat_processus).var_volatile_traitement_sigint = -1;
1.44      bertrand 2001: 
1.67      bertrand 2002:            while(exclusion == 1);
                   2003:            exclusion = 1;
1.1       bertrand 2004: 
1.67      bertrand 2005:            if ((*s_etat_processus).var_volatile_requete_arret == -1)
                   2006:            {
1.68      bertrand 2007:                deverrouillage_gestionnaire_signaux(s_etat_processus);
1.67      bertrand 2008:                exclusion = 0;
                   2009:                return;
                   2010:            }
1.1       bertrand 2011: 
1.67      bertrand 2012:            if ((*s_etat_processus).langue == 'F')
                   2013:            {
                   2014:                printf("+++Interruption\n");
1.1       bertrand 2015:            }
                   2016:            else
                   2017:            {
1.67      bertrand 2018:                printf("+++Interrupt\n");
1.1       bertrand 2019:            }
                   2020: 
1.67      bertrand 2021:            fflush(stdout);
                   2022: 
                   2023:            (*s_etat_processus).var_volatile_requete_arret = -1;
                   2024:            (*s_etat_processus).var_volatile_alarme = -1;
                   2025: 
                   2026:            exclusion = 0;
1.1       bertrand 2027:        }
1.67      bertrand 2028:    }
                   2029:    else
                   2030:    {
                   2031:        if ((s_thread_principal = recherche_thread_principal(getpid()))
                   2032:                != NULL)
1.1       bertrand 2033:        {
1.67      bertrand 2034:            envoi_signal_contexte(s_thread_principal, rpl_sigint);
1.1       bertrand 2035:        }
                   2036:    }
                   2037: 
1.68      bertrand 2038:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 2039:    return;
                   2040: }
                   2041: 
1.67      bertrand 2042: static inline void
                   2043: signal_tstp(struct_processus *s_etat_processus, pid_t pid)
1.66      bertrand 2044: {
                   2045:    struct_processus        *s_thread_principal;
                   2046: 
1.68      bertrand 2047:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 2048: 
1.30      bertrand 2049:    if (pid == getpid())
1.1       bertrand 2050:    {
                   2051:        /*
                   2052:         *  0 => fonctionnement normal
                   2053:         * -1 => requête
                   2054:         *  1 => requête acceptée en attente de traitement
                   2055:         */
                   2056: 
                   2057:        if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
                   2058:        {
1.67      bertrand 2059:            printf("[%d] RPL/SIGTSTP (thread %llu)\n", (int) getpid(),
1.1       bertrand 2060:                    (unsigned long long) pthread_self());
                   2061:            fflush(stdout);
                   2062:        }
                   2063: 
                   2064:        if ((*s_etat_processus).var_volatile_processus_pere == 0)
                   2065:        {
1.67      bertrand 2066:            envoi_signal_processus((*s_etat_processus).pid_processus_pere,
                   2067:                    rpl_sigtstp);
1.1       bertrand 2068:        }
                   2069:        else
                   2070:        {
                   2071:            (*s_etat_processus).var_volatile_requete_arret2 = -1;
                   2072:        }
                   2073:    }
                   2074:    else
                   2075:    {
                   2076:        // Envoi d'un signal au thread maître du groupe.
                   2077: 
1.66      bertrand 2078:        if ((s_thread_principal = recherche_thread_principal(getpid()))
                   2079:                != NULL)
1.1       bertrand 2080:        {
1.67      bertrand 2081:            envoi_signal_contexte(s_thread_principal, rpl_sigtstp);
1.1       bertrand 2082:        }
                   2083:    }
                   2084: 
1.68      bertrand 2085:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 2086:    return;
                   2087: }
                   2088: 
1.81      bertrand 2089: static void
                   2090: sortie_interruption_depassement_pile(void *arg1, void *arg2, void *arg3)
1.66      bertrand 2091: {
1.81      bertrand 2092:    switch((*((volatile int *) arg1)))
                   2093:    {
                   2094:        case 1:
                   2095:            longjmp(contexte_ecriture, -1);
                   2096:            break;
1.63      bertrand 2097: 
1.81      bertrand 2098:        case 2:
                   2099:            longjmp(contexte_impression, -1);
                   2100:            break;
                   2101:    }
1.1       bertrand 2102: 
1.81      bertrand 2103:    return;
                   2104: }
1.32      bertrand 2105: 
1.81      bertrand 2106: void
                   2107: interruption_depassement_pile(int urgence, stackoverflow_context_t scp)
                   2108: {
                   2109:    if ((urgence == 0) && (routine_recursive != 0))
1.1       bertrand 2110:    {
1.81      bertrand 2111:        // On peut tenter de récupérer le dépassement de pile. Si la variable
                   2112:        // 'routine_recursive' est non nulle, on récupère l'erreur.
1.1       bertrand 2113: 
1.81      bertrand 2114:        sigsegv_leave_handler(sortie_interruption_depassement_pile,
                   2115:                (void *) &routine_recursive, NULL, NULL);
1.1       bertrand 2116:    }
                   2117: 
1.81      bertrand 2118:    // Ici, la panique est totale et il vaut mieux quitter l'application.
                   2119:    interruption3(SIGUSR2);
                   2120:    return;
                   2121: }
1.1       bertrand 2122: 
1.81      bertrand 2123: int
                   2124: interruption_violation_access(void *adresse_fautive, int gravite)
                   2125: {
                   2126:    unsigned char       message[] = "+++System : Trying to catch access "
                   2127:                                "violation\n";
1.63      bertrand 2128: 
1.85      bertrand 2129:    static int          compteur_erreur = 0;
1.63      bertrand 2130: 
1.81      bertrand 2131:    if ((gravite == 0) && (routine_recursive != 0))
                   2132:    {
                   2133:        // Il peut s'agir d'un dépassement de pile.
1.63      bertrand 2134: 
1.81      bertrand 2135:        sigsegv_leave_handler(sortie_interruption_depassement_pile,
                   2136:                (void *) &routine_recursive, NULL, NULL);
                   2137:    }
1.63      bertrand 2138: 
1.81      bertrand 2139:    // On est dans une bonne vieille violation d'accès. On essaie
                   2140:    // de fermer au mieux l'application.
1.63      bertrand 2141: 
1.81      bertrand 2142:    compteur_erreur++;
1.63      bertrand 2143: 
1.81      bertrand 2144:    if (compteur_erreur >= 2)
                   2145:    {
                   2146:        // Erreurs multiples, on arrête l'application.
                   2147:        interruption3(SIGSEGV);
                   2148:        return(0);
                   2149:    }
1.63      bertrand 2150: 
1.86      bertrand 2151:    write(STDERR_FILENO, message, strlen(message));
1.63      bertrand 2152: 
1.81      bertrand 2153:    if (pid_processus_pere == getpid())
                   2154:    {
                   2155:        longjmp(contexte_initial, -1);
                   2156:        return(1);
                   2157:    }
                   2158:    else
                   2159:    {
                   2160:        longjmp(contexte_processus, -1);
                   2161:        return(1);
1.1       bertrand 2162:    }
                   2163: 
1.81      bertrand 2164:    // On renvoie 0 parce qu'on décline toute responsabilité quant à la
                   2165:    // suite des événements...
                   2166:    return(0);
1.1       bertrand 2167: }
1.67      bertrand 2168: 
                   2169: // Traitement de rpl_sigstart
1.1       bertrand 2170: 
1.67      bertrand 2171: static inline void
                   2172: signal_start(struct_processus *s_etat_processus, pid_t pid)
1.1       bertrand 2173: {
1.69      bertrand 2174:    struct_processus        *s_thread_principal;
                   2175: 
                   2176:    verrouillage_gestionnaire_signaux(s_etat_processus);
                   2177: 
                   2178:    if (pid == getpid())
                   2179:    {
                   2180:        (*s_etat_processus).demarrage_fils = d_vrai;
                   2181:    }
                   2182:    else
                   2183:    {
                   2184:        // Envoi d'un signal au thread maître du groupe.
                   2185: 
                   2186:        if ((s_thread_principal = recherche_thread_principal(getpid()))
                   2187:                != NULL)
                   2188:        {
                   2189:            envoi_signal_contexte(s_thread_principal, rpl_sigstart);
                   2190:        }
                   2191:    }
                   2192: 
                   2193:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.67      bertrand 2194:    return;
                   2195: }
1.32      bertrand 2196: 
1.67      bertrand 2197: // Traitement de rpl_sigcont
1.1       bertrand 2198: 
1.67      bertrand 2199: static inline void
                   2200: signal_cont(struct_processus *s_etat_processus, pid_t pid)
                   2201: {
1.69      bertrand 2202:    struct_processus        *s_thread_principal;
                   2203: 
                   2204:    verrouillage_gestionnaire_signaux(s_etat_processus);
                   2205: 
                   2206:    if (pid == getpid())
                   2207:    {
                   2208:        (*s_etat_processus).redemarrage_processus = d_vrai;
                   2209:    }
                   2210:    else
                   2211:    {
                   2212:        // Envoi d'un signal au thread maître du groupe.
                   2213: 
                   2214:        if ((s_thread_principal = recherche_thread_principal(getpid()))
                   2215:                != NULL)
                   2216:        {
                   2217:            envoi_signal_contexte(s_thread_principal, rpl_sigcont);
                   2218:        }
                   2219:    }
                   2220: 
                   2221:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 2222:    return;
                   2223: }
                   2224: 
1.67      bertrand 2225: // Traitement de rpl_sigstop
                   2226: 
                   2227: static inline void
                   2228: signal_stop(struct_processus *s_etat_processus, pid_t pid)
1.1       bertrand 2229: {
1.67      bertrand 2230:    struct_processus        *s_thread_principal;
1.1       bertrand 2231: 
1.68      bertrand 2232:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.32      bertrand 2233: 
1.30      bertrand 2234:    if (pid == getpid())
1.1       bertrand 2235:    {
                   2236:        if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
                   2237:        {
1.69      bertrand 2238:            printf("[%d] RPL/SIGSTOP (thread %llu)\n", (int) getpid(),
1.16      bertrand 2239:                    (unsigned long long) pthread_self());
                   2240:            fflush(stdout);
1.1       bertrand 2241:        }
                   2242: 
                   2243:        /*
                   2244:         * var_globale_traitement_retarde_stop :
                   2245:         *  0 -> traitement immédiat
                   2246:         *  1 -> traitement retardé (aucun signal reçu)
                   2247:         * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
                   2248:         */
                   2249: 
1.11      bertrand 2250:        if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
1.1       bertrand 2251:        {
1.11      bertrand 2252:            (*s_etat_processus).var_volatile_requete_arret = -1;
1.1       bertrand 2253:        }
                   2254:        else
                   2255:        {
1.11      bertrand 2256:            (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
1.1       bertrand 2257:        }
                   2258:    }
                   2259:    else
                   2260:    {
                   2261:        // Envoi d'un signal au thread maître du groupe.
                   2262: 
1.67      bertrand 2263:        if ((s_thread_principal = recherche_thread_principal(getpid()))
                   2264:                != NULL)
1.1       bertrand 2265:        {
1.67      bertrand 2266:            envoi_signal_contexte(s_thread_principal, rpl_sigstop);
1.1       bertrand 2267:        }
                   2268:    }
                   2269: 
1.68      bertrand 2270:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 2271:    return;
                   2272: }
                   2273: 
1.67      bertrand 2274: // Traitement de rpl_siginject
                   2275: 
                   2276: static inline void
                   2277: signal_inject(struct_processus *s_etat_processus, pid_t pid)
1.1       bertrand 2278: {
1.68      bertrand 2279:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.32      bertrand 2280: 
1.1       bertrand 2281:    if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
                   2282:    {
1.68      bertrand 2283:        deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 2284:        return;
                   2285:    }
                   2286: 
                   2287:    if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
                   2288:    {
1.67      bertrand 2289:        printf("[%d] RPL/SIGINJECT (thread %llu)\n", (int) getpid(),
1.1       bertrand 2290:                (unsigned long long) pthread_self());
                   2291:        fflush(stdout);
                   2292:    }
                   2293: 
1.68      bertrand 2294:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 2295:    return;
                   2296: }
                   2297: 
                   2298: 
1.67      bertrand 2299: static inline void
                   2300: signal_urg(struct_processus *s_etat_processus, pid_t pid)
1.1       bertrand 2301: {
1.67      bertrand 2302:    struct_processus        *s_thread_principal;
1.30      bertrand 2303: 
1.68      bertrand 2304:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.32      bertrand 2305: 
1.30      bertrand 2306:    if (pid == getpid())
1.1       bertrand 2307:    {
                   2308:        if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
                   2309:        {
1.67      bertrand 2310:            printf("[%d] RPL/SIGURG (thread %llu)\n", (int) getpid(),
1.1       bertrand 2311:                    (unsigned long long) pthread_self());
                   2312:            fflush(stdout);
                   2313:        }
                   2314: 
                   2315:        (*s_etat_processus).var_volatile_alarme = -1;
                   2316:        (*s_etat_processus).var_volatile_requete_arret = -1;
                   2317:    }
                   2318:    else
                   2319:    {
                   2320:        // Envoi d'un signal au thread maître du groupe.
                   2321: 
1.67      bertrand 2322:        if ((s_thread_principal = recherche_thread_principal(getpid()))
                   2323:                != NULL)
1.1       bertrand 2324:        {
1.67      bertrand 2325:            envoi_signal_contexte(s_thread_principal, rpl_sigurg);
1.1       bertrand 2326:        }
                   2327:    }
                   2328: 
1.68      bertrand 2329:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 2330:    return;
                   2331: }
                   2332: 
1.67      bertrand 2333: // Traitement de rpl_sigabort
                   2334: 
                   2335: static inline void
                   2336: signal_abort(struct_processus *s_etat_processus, pid_t pid)
1.1       bertrand 2337: {
1.67      bertrand 2338:    struct_processus        *s_thread_principal;
1.1       bertrand 2339: 
1.68      bertrand 2340:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.32      bertrand 2341: 
1.1       bertrand 2342:    if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
                   2343:    {
1.68      bertrand 2344:        deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 2345:        return;
                   2346:    }
                   2347: 
                   2348:    if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
                   2349:    {
1.67      bertrand 2350:        printf("[%d] RPL/SIGABORT (thread %llu)\n", (int) getpid(),
1.1       bertrand 2351:                (unsigned long long) pthread_self());
                   2352:        fflush(stdout);
                   2353:    }
                   2354: 
1.67      bertrand 2355:    if (pid == getpid())
1.30      bertrand 2356:    {
1.67      bertrand 2357:        (*s_etat_processus).arret_depuis_abort = -1;
                   2358: 
                   2359:        /*
                   2360:         * var_globale_traitement_retarde_stop :
                   2361:         *  0 -> traitement immédiat
                   2362:         *  1 -> traitement retardé (aucun signal reçu)
                   2363:         * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
                   2364:         */
                   2365: 
                   2366:        if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
                   2367:        {
                   2368:            (*s_etat_processus).var_volatile_requete_arret = -1;
                   2369:        }
                   2370:        else
                   2371:        {
                   2372:            (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
                   2373:        }
                   2374:    }
                   2375:    else
                   2376:    {
                   2377:        (*s_etat_processus).arret_depuis_abort = -1;
                   2378: 
                   2379:        // Envoi d'un signal au thread maître du groupe.
                   2380: 
                   2381:        if ((s_thread_principal = recherche_thread_principal(getpid()))
                   2382:                != NULL)
                   2383:        {
                   2384:            envoi_signal_contexte(s_thread_principal, rpl_sigabort);
                   2385:        }
                   2386:    }
                   2387: 
1.68      bertrand 2388:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.67      bertrand 2389:    return;
                   2390: }
                   2391: 
                   2392: 
                   2393: static inline void
                   2394: signal_hup(struct_processus *s_etat_processus, pid_t pid)
1.1       bertrand 2395: {
                   2396:    file                    *fichier;
                   2397: 
                   2398:    unsigned char           nom[8 + 64 + 1];
                   2399: 
1.68      bertrand 2400:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.32      bertrand 2401: 
1.1       bertrand 2402:    if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
                   2403:    {
1.68      bertrand 2404:        deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 2405:        return;
                   2406:    }
                   2407: 
1.122     bertrand 2408:    snprintf(nom, 8 + 64 + 1, "rpl-out-%llu-%llu",
                   2409:            (unsigned long long) getpid(),
                   2410:            (unsigned long long) pthread_self());
1.1       bertrand 2411: 
                   2412:    if ((fichier = fopen(nom, "w+")) != NULL)
                   2413:    {
                   2414:        fclose(fichier);
                   2415: 
1.86      bertrand 2416:        freopen(nom, "w", stdout);
                   2417:        freopen(nom, "w", stderr);
1.1       bertrand 2418:    }
                   2419: 
1.86      bertrand 2420:    freopen("/dev/null", "r", stdin);
1.1       bertrand 2421: 
                   2422:    if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
                   2423:    {
1.69      bertrand 2424:        printf("[%d] RPL/SIGHUP (thread %llu)\n", (int) getpid(),
1.1       bertrand 2425:                (unsigned long long) pthread_self());
                   2426:        fflush(stdout);
                   2427:    }
                   2428: 
1.68      bertrand 2429:    deverrouillage_gestionnaire_signaux(s_etat_processus);
1.1       bertrand 2430:    return;
                   2431: }
                   2432: 
                   2433: void
1.67      bertrand 2434: traitement_exceptions_gsl(const char *reason, const char *file,
                   2435:        int line, int gsl_errno)
                   2436: {
1.68      bertrand 2437:    code_erreur_gsl = gsl_errno;
                   2438:    envoi_signal_processus(getpid(), rpl_sigexcept);
                   2439:    return;
                   2440: }
1.67      bertrand 2441: 
1.68      bertrand 2442: static inline void
                   2443: signal_except(struct_processus *s_etat_processus, pid_t pid)
                   2444: {
                   2445:    verrouillage_gestionnaire_signaux(s_etat_processus);
1.67      bertrand 2446: 
                   2447:    if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
                   2448:    {
1.68      bertrand 2449:        deverrouillage_gestionnaire_signaux(s_etat_processus);
1.67      bertrand 2450:        return;
                   2451:    }
                   2452: 
1.68      bertrand 2453:    (*s_etat_processus).var_volatile_exception_gsl = code_erreur_gsl;
                   2454:    deverrouillage_gestionnaire_signaux(s_etat_processus);
                   2455: 
1.67      bertrand 2456:    return;
                   2457: }
                   2458: 
                   2459: static inline void
                   2460: envoi_interruptions(struct_processus *s_etat_processus, enum signaux_rpl signal,
                   2461:        pid_t pid_source)
1.16      bertrand 2462: {
1.67      bertrand 2463:    switch(signal)
                   2464:    {
1.69      bertrand 2465:        case rpl_signull:
                   2466:            break;
                   2467: 
1.67      bertrand 2468:        case rpl_sigint:
                   2469:            signal_int(s_etat_processus, pid_source);
                   2470:            break;
                   2471: 
                   2472:        case rpl_sigterm:
                   2473:            signal_term(s_etat_processus, pid_source);
                   2474:            break;
                   2475: 
                   2476:        case rpl_sigstart:
                   2477:            signal_start(s_etat_processus, pid_source);
                   2478:            break;
                   2479: 
                   2480:        case rpl_sigcont:
                   2481:            signal_cont(s_etat_processus, pid_source);
                   2482:            break;
                   2483: 
                   2484:        case rpl_sigstop:
                   2485:            signal_stop(s_etat_processus, pid_source);
                   2486:            break;
1.30      bertrand 2487: 
1.67      bertrand 2488:        case rpl_sigabort:
                   2489:            signal_abort(s_etat_processus, pid_source);
                   2490:            break;
                   2491: 
                   2492:        case rpl_sigurg:
                   2493:            signal_urg(s_etat_processus, pid_source);
                   2494:            break;
                   2495: 
                   2496:        case rpl_siginject:
                   2497:            signal_inject(s_etat_processus, pid_source);
                   2498:            break;
                   2499: 
                   2500:        case rpl_sigalrm:
                   2501:            signal_alrm(s_etat_processus, pid_source);
                   2502:            break;
                   2503: 
                   2504:        case rpl_sighup:
                   2505:            signal_hup(s_etat_processus, pid_source);
                   2506:            break;
                   2507: 
                   2508:        case rpl_sigtstp:
                   2509:            signal_tstp(s_etat_processus, pid_source);
                   2510:            break;
                   2511: 
1.68      bertrand 2512:        case rpl_sigexcept:
                   2513:            signal_except(s_etat_processus, pid_source);
                   2514:            break;
                   2515: 
1.67      bertrand 2516:        default:
1.69      bertrand 2517:            if ((*s_etat_processus).langue == 'F')
                   2518:            {
1.107     bertrand 2519:                printf("+++System : Signal inconnu (%d) !\n", signal);
1.69      bertrand 2520:            }
                   2521:            else
                   2522:            {
1.107     bertrand 2523:                printf("+++System : Spurious signal (%d) !\n", signal);
1.69      bertrand 2524:            }
                   2525: 
1.67      bertrand 2526:            break;
                   2527:    }
1.30      bertrand 2528: 
1.67      bertrand 2529:    return;
                   2530: }
1.16      bertrand 2531: 
1.67      bertrand 2532: void
                   2533: scrutation_interruptions(struct_processus *s_etat_processus)
                   2534: {
                   2535:    // Interruptions qui arrivent sur le processus depuis un
                   2536:    // processus externe.
1.32      bertrand 2537: 
1.68      bertrand 2538:    // Les pointeurs de lecture pointent sur les prochains éléments
                   2539:    // à lire. Les pointeurs d'écriture pointent sur les prochains éléments à
                   2540:    // écrire.
                   2541: 
1.100     bertrand 2542: #  if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
1.72      bertrand 2543:        if (sem_trywait(&((*s_queue_signaux).semaphore)) == 0)
                   2544: #  else
                   2545:        if (sem_trywait(semaphore_queue_signaux) == 0)
                   2546: #  endif
1.68      bertrand 2547:    {
1.94      bertrand 2548:        while((*s_queue_signaux).pointeur_lecture !=
1.68      bertrand 2549:                (*s_queue_signaux).pointeur_ecriture)
                   2550:        {
                   2551:            // Il y a un signal en attente dans le segment partagé. On le
                   2552:            // traite.
                   2553: 
                   2554:            envoi_interruptions(s_etat_processus,
                   2555:                    (*s_queue_signaux).queue[(*s_queue_signaux)
                   2556:                    .pointeur_lecture].signal, (*s_queue_signaux).queue
                   2557:                    [(*s_queue_signaux).pointeur_lecture].pid);
                   2558:            (*s_queue_signaux).pointeur_lecture =
                   2559:                    ((*s_queue_signaux).pointeur_lecture + 1)
                   2560:                    % LONGUEUR_QUEUE_SIGNAUX;
1.96      bertrand 2561: 
1.100     bertrand 2562: #          if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
1.108     bertrand 2563:            while(sem_wait(&((*s_queue_signaux).signalisation)) != 0)
1.96      bertrand 2564: #          else
1.108     bertrand 2565:            while(sem_wait(semaphore_signalisation) != 0)
1.96      bertrand 2566: #          endif
1.108     bertrand 2567:            {
                   2568:                if (errno != EINTR)
                   2569:                {
                   2570:                    (*s_etat_processus).erreur_systeme = d_es_processus;
                   2571:                    return;
                   2572:                }
                   2573:            }
1.68      bertrand 2574:        }
                   2575: 
1.100     bertrand 2576: #      if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
1.72      bertrand 2577:            sem_post(&((*s_queue_signaux).semaphore));
                   2578: #      else
                   2579:            sem_post(semaphore_queue_signaux);
                   2580: #      endif
1.68      bertrand 2581:    }
                   2582: 
1.67      bertrand 2583:    // Interruptions qui arrivent depuis le groupe courant de threads.
1.29      bertrand 2584: 
1.68      bertrand 2585:    if (pthread_mutex_trylock(&mutex_interruptions) == 0)
1.16      bertrand 2586:    {
1.94      bertrand 2587:        while((*s_etat_processus).pointeur_signal_lecture !=
1.68      bertrand 2588:                (*s_etat_processus).pointeur_signal_ecriture)
                   2589:        {
                   2590:            // Il y a un signal dans la queue du thread courant. On le traite.
                   2591: 
                   2592:            envoi_interruptions(s_etat_processus,
                   2593:                    (*s_etat_processus).signaux_en_queue
                   2594:                    [(*s_etat_processus).pointeur_signal_lecture],
                   2595:                    getpid());
                   2596:            (*s_etat_processus).pointeur_signal_lecture =
                   2597:                    ((*s_etat_processus).pointeur_signal_lecture + 1)
                   2598:                    % LONGUEUR_QUEUE_SIGNAUX;
1.96      bertrand 2599: 
1.100     bertrand 2600: #          if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
1.108     bertrand 2601:            while(sem_wait(&((*s_queue_signaux).signalisation)) != 0)
1.96      bertrand 2602: #          else
1.108     bertrand 2603:            while(sem_wait(semaphore_signalisation) != 0)
1.96      bertrand 2604: #          endif
1.108     bertrand 2605:            {
                   2606:                if (errno != EINTR)
                   2607:                {
                   2608:                    (*s_etat_processus).erreur_systeme = d_es_processus;
                   2609:                    return;
                   2610:                }
                   2611:            }
1.68      bertrand 2612:        }
                   2613: 
                   2614:        pthread_mutex_unlock(&mutex_interruptions);
1.67      bertrand 2615:    }
                   2616: 
                   2617:    return;
                   2618: }
                   2619: 
1.69      bertrand 2620: /*
                   2621: ================================================================================
                   2622:   Fonction renvoyant le nom du segment de mémoire partagée en fonction
                   2623:   du pid du processus.
                   2624: ================================================================================
                   2625:   Entrée : Chemin absolue servant de racine, pid du processus
                   2626: --------------------------------------------------------------------------------
                   2627:   Sortie : NULL ou nom du segment
                   2628: --------------------------------------------------------------------------------
                   2629:   Effet de bord : Néant
                   2630: ================================================================================
                   2631: */
                   2632: 
                   2633: static unsigned char *
                   2634: nom_segment(unsigned char *chemin, pid_t pid)
                   2635: {
                   2636:    unsigned char               *fichier;
                   2637: 
                   2638: #  ifdef IPCS_SYSV // !POSIX
                   2639: #      ifndef OS2 // !OS2
1.84      bertrand 2640: 
1.69      bertrand 2641:            if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) *
                   2642:                    sizeof(unsigned char))) == NULL)
                   2643:            {
                   2644:                return(NULL);
                   2645:            }
                   2646: 
                   2647:            sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);
                   2648: #      else // OS2
                   2649:            if ((fichier = malloc((10 + 256 + 1) * sizeof(unsigned char)))
                   2650:                    == NULL)
                   2651:            {
                   2652:                return(NULL);
                   2653:            }
                   2654: 
                   2655:            sprintf(fichier, "\\SHAREMEM\\RPL-SIGQUEUES-%d", (int) pid);
                   2656: #      endif // OS2
                   2657: #  else // POSIX
                   2658: 
                   2659:        if ((fichier = malloc((1 + 256 + 1) *
                   2660:                sizeof(unsigned char))) == NULL)
                   2661:        {
                   2662:            return(NULL);
                   2663:        }
                   2664: 
                   2665:        sprintf(fichier, "/RPL-SIGQUEUES-%d", (int) pid);
                   2666: #  endif
                   2667: 
                   2668:    return(fichier);
                   2669: }
                   2670: 
                   2671: 
1.71      bertrand 2672: /*
                   2673: ================================================================================
                   2674:   Fonctions d'envoi d'un signal à un thread ou à un processus.
                   2675: ================================================================================
                   2676:   Entrée : processus et signal
                   2677: --------------------------------------------------------------------------------
                   2678:   Sortie : erreur
                   2679: --------------------------------------------------------------------------------
                   2680:   Effet de bord : Néant
                   2681: ================================================================================
                   2682: */
                   2683: 
1.67      bertrand 2684: int
                   2685: envoi_signal_processus(pid_t pid, enum signaux_rpl signal)
                   2686: {
1.83      bertrand 2687: #  ifndef OS2
                   2688:        int                         segment;
                   2689: #  endif
1.69      bertrand 2690: 
1.75      bertrand 2691: #  ifndef IPCS_SYSV
                   2692: #      ifdef SEMAPHORES_NOMMES
                   2693:            sem_t                   *semaphore;
1.97      bertrand 2694:            sem_t                   *signalisation;
1.75      bertrand 2695: #      endif
                   2696: #  else
1.83      bertrand 2697: #      ifndef OS2
                   2698:            int                     desc;
                   2699:            key_t                   clef;
                   2700: #      endif
1.75      bertrand 2701: #  endif
1.72      bertrand 2702: 
1.69      bertrand 2703:    struct_queue_signaux            *queue;
                   2704: 
                   2705:    unsigned char                   *nom;
                   2706: 
1.67      bertrand 2707:    // Il s'agit d'ouvrir le segment de mémoire partagée, de le projeter en
                   2708:    // mémoire puis d'y inscrire le signal à traiter.
                   2709: 
1.69      bertrand 2710:    if (pid == getpid())
                   2711:    {
                   2712:        // Le signal est envoyé au même processus.
                   2713: 
                   2714:        if (s_queue_signaux == NULL)
                   2715:        {
                   2716:            return(1);
                   2717:        }
                   2718: 
1.100     bertrand 2719: #      if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
1.78      bertrand 2720:            while(sem_wait(&((*s_queue_signaux).semaphore)) != 0)
1.72      bertrand 2721: #      else
1.78      bertrand 2722:            while(sem_wait(semaphore_queue_signaux) != 0)
1.72      bertrand 2723: #      endif
1.69      bertrand 2724:        {
1.78      bertrand 2725:            if (errno != EINTR)
                   2726:            {
                   2727:                return(1);
                   2728:            }
1.69      bertrand 2729:        }
                   2730: 
                   2731:        (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture]
                   2732:                .pid = pid;
                   2733:        (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture]
                   2734:                .signal = signal;
                   2735: 
                   2736:        (*s_queue_signaux).pointeur_ecriture =
                   2737:                ((*s_queue_signaux).pointeur_ecriture + 1)
                   2738:                % LONGUEUR_QUEUE_SIGNAUX;
                   2739: 
1.100     bertrand 2740: #      if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
1.72      bertrand 2741:            if (sem_post(&((*s_queue_signaux).semaphore)) != 0)
                   2742: #      else
                   2743:            if (sem_post(semaphore_queue_signaux) != 0)
                   2744: #      endif
1.69      bertrand 2745:        {
                   2746:            return(1);
                   2747:        }
1.97      bertrand 2748: 
1.100     bertrand 2749: #      if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
1.97      bertrand 2750:            if (sem_post(&((*s_queue_signaux).signalisation)) != 0)
                   2751: #      else
                   2752:            if (sem_post(semaphore_signalisation) != 0)
                   2753: #      endif
                   2754:        {
                   2755:            return(1);
                   2756:        }
1.69      bertrand 2757:    }
                   2758:    else
                   2759:    {
                   2760:        // Le signal est envoyé depuis un processus distinct.
                   2761: 
1.75      bertrand 2762: #      ifdef IPCS_SYSV
1.76      bertrand 2763:            if ((nom = nom_segment(racine_segment, pid)) == NULL)
1.75      bertrand 2764:            {
                   2765:                return(1);
                   2766:            }
                   2767: 
1.83      bertrand 2768: #          ifndef OS2 // SysV
                   2769:                if ((desc = open(nom, O_RDWR)) == -1)
                   2770:                {
                   2771:                    free(nom);
                   2772:                    return(1);
                   2773:                }
                   2774: 
                   2775:                close(desc);
1.75      bertrand 2776: 
1.83      bertrand 2777:                if ((clef = ftok(nom, 1)) == -1)
                   2778:                {
                   2779:                    free(nom);
                   2780:                    return(1);
                   2781:                }
1.75      bertrand 2782: 
                   2783:                free(nom);
1.69      bertrand 2784: 
1.83      bertrand 2785:                if ((segment = shmget(clef, sizeof(struct_queue_signaux), 0))
                   2786:                        == -1)
                   2787:                {
                   2788:                    return(1);
                   2789:                }
1.69      bertrand 2790: 
1.83      bertrand 2791:                queue = shmat(segment, NULL, 0);
                   2792: #          else // OS/2
                   2793:                if (DosGetNamedSharedMem((PVOID) &queue, nom,
                   2794:                        PAG_WRITE | PAG_READ) != 0)
                   2795:                {
                   2796:                    free(nom);
                   2797:                    return(1);
                   2798:                }
1.69      bertrand 2799: 
1.83      bertrand 2800:                free(nom);
                   2801: #          endif
1.75      bertrand 2802: #      else // POSIX
                   2803:            if ((nom = nom_segment(racine_segment, pid)) == NULL)
                   2804:            {
                   2805:                return(1);
                   2806:            }
1.69      bertrand 2807: 
1.75      bertrand 2808:            if ((segment = shm_open(nom, O_RDWR, 0)) == -1)
1.72      bertrand 2809:            {
1.75      bertrand 2810:                free(nom);
1.72      bertrand 2811:                return(1);
                   2812:            }
1.75      bertrand 2813: 
                   2814:            free(nom);
                   2815: 
                   2816:            if ((queue = mmap(NULL, sizeof(struct_queue_signaux),
                   2817:                    PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0)) ==
                   2818:                    MAP_FAILED)
1.72      bertrand 2819:            {
1.75      bertrand 2820:                close(segment);
1.72      bertrand 2821:                return(1);
                   2822:            }
1.75      bertrand 2823: #      endif
1.72      bertrand 2824: 
1.75      bertrand 2825:            // À ce moment, le segment de mémoire partagée est projeté
                   2826:            // dans l'espace du processus.
                   2827: 
                   2828: #      ifndef IPCS_SYSV // POSIX
                   2829: #          ifndef SEMAPHORES_NOMMES
1.78      bertrand 2830:                while(sem_wait(&((*queue).semaphore)) != 0)
1.75      bertrand 2831:                {
1.78      bertrand 2832:                    if (errno != EINTR)
                   2833:                    {
                   2834:                        return(1);
                   2835:                    }
1.75      bertrand 2836:                }
                   2837: #          else
1.80      bertrand 2838:                if ((semaphore = sem_open2(pid, SEM_QUEUE)) == SEM_FAILED)
1.75      bertrand 2839:                {
                   2840:                    return(1);
                   2841:                }
                   2842: 
1.97      bertrand 2843:                if ((signalisation = sem_open2(pid, SEM_SIGNALISATION))
                   2844:                        == SEM_FAILED)
                   2845:                {
                   2846:                    return(1);
                   2847:                }
                   2848: 
1.78      bertrand 2849:                while(sem_wait(semaphore) != 0)
1.75      bertrand 2850:                {
1.78      bertrand 2851:                    if (errno != EINTR)
                   2852:                    {
                   2853:                        sem_close(semaphore);
1.97      bertrand 2854:                        sem_close(signalisation);
1.78      bertrand 2855:                        return(1);
                   2856:                    }
1.75      bertrand 2857:                }
                   2858: #          endif
                   2859: #      else // IPCS_SYSV
1.78      bertrand 2860:            while(sem_wait(&((*queue).semaphore)) != 0)
1.72      bertrand 2861:            {
1.78      bertrand 2862:                if (errno != EINTR)
                   2863:                {
                   2864:                    return(1);
                   2865:                }
1.72      bertrand 2866:            }
                   2867: #      endif
1.69      bertrand 2868: 
                   2869:        (*queue).queue[(*queue).pointeur_ecriture].pid = getpid();
                   2870:        (*queue).queue[(*queue).pointeur_ecriture].signal = signal;
                   2871: 
                   2872:        (*queue).pointeur_ecriture = ((*queue).pointeur_ecriture + 1)
                   2873:                % LONGUEUR_QUEUE_SIGNAUX;
                   2874: 
1.75      bertrand 2875: #      ifndef IPCS_SYSV // POSIX
                   2876: #          ifndef SEMAPHORES_NOMMES
                   2877:                if (sem_post(&((*queue).semaphore)) != 0)
                   2878:                {
                   2879:                    return(1);
                   2880:                }
1.97      bertrand 2881: 
                   2882:                if (sem_post(&((*queue).signalisation)) != 0)
                   2883:                {
                   2884:                    return(1);
                   2885:                }
1.75      bertrand 2886: #          else
                   2887:                if (sem_post(semaphore) != 0)
                   2888:                {
                   2889:                    sem_close(semaphore);
1.97      bertrand 2890:                    sem_close(signalisation);
1.75      bertrand 2891:                    return(1);
                   2892:                }
                   2893: 
                   2894:                if (sem_close(semaphore) != 0)
                   2895:                {
                   2896:                    return(1);
                   2897:                }
1.97      bertrand 2898: 
                   2899:                if (sem_post(signalisation) != 0)
                   2900:                {
                   2901:                    sem_close(signalisation);
                   2902:                    return(1);
                   2903:                }
                   2904: 
                   2905:                if (sem_close(signalisation) != 0)
                   2906:                {
                   2907:                    return(1);
                   2908:                }
                   2909: 
1.75      bertrand 2910: #          endif
                   2911: 
                   2912:            if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
1.72      bertrand 2913:            {
1.75      bertrand 2914:                close(segment);
1.72      bertrand 2915:                return(1);
                   2916:            }
1.75      bertrand 2917: #      else // IPCS_SYSV
                   2918:            if (sem_post(&((*queue).semaphore)) != 0)
1.72      bertrand 2919:            {
                   2920:                return(1);
                   2921:            }
                   2922: 
1.97      bertrand 2923:            if (sem_post(&((*queue).signalisation)) != 0)
                   2924:            {
                   2925:                return(1);
                   2926:            }
                   2927: 
1.83      bertrand 2928: #          ifndef OS2 // SysV
                   2929:                if (shmdt(queue) != 0)
                   2930:                {
                   2931:                    return(1);
                   2932:                }
                   2933: #          else // OS/2
                   2934:                // Pendant de DosGetNamedSHaredMem()
                   2935: #          endif
1.72      bertrand 2936: #      endif
1.69      bertrand 2937:    }
                   2938: 
1.67      bertrand 2939:    return(0);
                   2940: }
                   2941: 
                   2942: int
                   2943: envoi_signal_thread(pthread_t tid, enum signaux_rpl signal)
                   2944: {
                   2945:    // Un signal est envoyé d'un thread à un autre thread du même processus.
                   2946: 
1.68      bertrand 2947:    volatile struct_liste_chainee_volatile  *l_element_courant;
                   2948: 
                   2949:    struct_processus                        *s_etat_processus;
                   2950: 
1.123     bertrand 2951:    if (pthread_mutex_lock(&mutex_interruptions) != 0)
                   2952:    {
                   2953:        pthread_mutex_unlock(&mutex_liste_threads);
                   2954:        return(1);
                   2955:    }
                   2956: 
1.68      bertrand 2957:    if (pthread_mutex_lock(&mutex_liste_threads) != 0)
                   2958:    {
                   2959:        return(1);
                   2960:    }
                   2961: 
                   2962:    l_element_courant = liste_threads;
                   2963: 
                   2964:    while(l_element_courant != NULL)
                   2965:    {
                   2966:        if (((*((struct_thread *) (*l_element_courant).donnee)).pid
                   2967:                == getpid()) && (pthread_equal((*((struct_thread *)
                   2968:                (*l_element_courant).donnee)).tid, tid) != 0))
                   2969:        {
                   2970:            break;
                   2971:        }
                   2972: 
                   2973:        l_element_courant = (*l_element_courant).suivant;
                   2974:    }
                   2975: 
                   2976:    if (l_element_courant == NULL)
                   2977:    {
                   2978:        pthread_mutex_unlock(&mutex_liste_threads);
                   2979:        return(1);
                   2980:    }
                   2981: 
                   2982:    s_etat_processus = (*((struct_thread *) (*l_element_courant).donnee))
                   2983:            .s_etat_processus;
                   2984: 
                   2985:    (*s_etat_processus).signaux_en_queue
                   2986:            [(*s_etat_processus).pointeur_signal_ecriture] = signal;
                   2987:    (*s_etat_processus).pointeur_signal_ecriture =
                   2988:            ((*s_etat_processus).pointeur_signal_ecriture + 1)
                   2989:            % LONGUEUR_QUEUE_SIGNAUX;
                   2990: 
                   2991:    if (pthread_mutex_unlock(&mutex_interruptions) != 0)
                   2992:    {
                   2993:        pthread_mutex_unlock(&mutex_liste_threads);
                   2994:        return(1);
                   2995:    }
                   2996: 
                   2997:    if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
                   2998:    {
                   2999:        return(1);
                   3000:    }
                   3001: 
1.100     bertrand 3002: #  if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
1.97      bertrand 3003:    if (sem_post(&((*s_queue_signaux).signalisation)) != 0)
                   3004:    {
                   3005:        return(1);
                   3006:    }
                   3007: #  else
                   3008:    if (sem_post(semaphore_signalisation) != 0)
                   3009:    {
                   3010:        return(1);
                   3011:    }
                   3012: #  endif
1.89      bertrand 3013: 
1.67      bertrand 3014:    return(0);
                   3015: }
                   3016: 
                   3017: int
                   3018: envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,
                   3019:        enum signaux_rpl signal)
                   3020: {
1.68      bertrand 3021:    pthread_mutex_lock(&mutex_interruptions);
1.67      bertrand 3022:    (*s_etat_processus_a_signaler).signaux_en_queue
1.68      bertrand 3023:            [(*s_etat_processus_a_signaler).pointeur_signal_ecriture] =
1.67      bertrand 3024:            signal;
1.68      bertrand 3025:    (*s_etat_processus_a_signaler).pointeur_signal_ecriture =
                   3026:            ((*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1)
                   3027:            % LONGUEUR_QUEUE_SIGNAUX;
                   3028:    pthread_mutex_unlock(&mutex_interruptions);
1.67      bertrand 3029: 
1.100     bertrand 3030: #  if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
1.97      bertrand 3031:    if (sem_post(&((*s_queue_signaux).signalisation)) != 0)
                   3032:    {
                   3033:        return(1);
                   3034:    }
                   3035: #  else
                   3036:    if (sem_post(semaphore_signalisation) != 0)
                   3037:    {
                   3038:        return(1);
                   3039:    }
                   3040: #  endif
1.89      bertrand 3041: 
1.67      bertrand 3042:    return(0);
                   3043: }
                   3044: 
                   3045: 
                   3046: /*
                   3047: ================================================================================
                   3048:   Fonction créant un segment de mémoire partagée destiné à contenir
                   3049:   la queue des signaux.
                   3050: ================================================================================
                   3051:   Entrée : structure de description du processus
                   3052: --------------------------------------------------------------------------------
                   3053:   Sortie : Néant
                   3054: --------------------------------------------------------------------------------
                   3055:   Effet de bord : Néant
                   3056: ================================================================================
                   3057: */
                   3058: 
                   3059: void
                   3060: creation_queue_signaux(struct_processus *s_etat_processus)
                   3061: {
1.96      bertrand 3062:    pthread_attr_t                  attributs;
                   3063: 
1.67      bertrand 3064:    unsigned char                   *nom;
                   3065: 
1.69      bertrand 3066:    racine_segment = (*s_etat_processus).chemin_fichiers_temporaires;
                   3067: 
1.67      bertrand 3068: #  ifndef IPCS_SYSV // POSIX
1.71      bertrand 3069:        if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
                   3070:                getpid())) == NULL)
                   3071:        {
                   3072:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   3073:            return;
                   3074:        }
1.16      bertrand 3075: 
1.71      bertrand 3076:        if ((f_queue_signaux = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,
                   3077:                S_IRUSR | S_IWUSR)) == -1)
                   3078:        {
                   3079:            free(nom);
                   3080:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   3081:            return;
                   3082:        }
1.16      bertrand 3083: 
1.71      bertrand 3084:        if (ftruncate(f_queue_signaux, sizeof(struct_queue_signaux)) == -1)
                   3085:        {
                   3086:            free(nom);
                   3087:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   3088:            return;
                   3089:        }
1.16      bertrand 3090: 
1.71      bertrand 3091:        s_queue_signaux = mmap(NULL, sizeof(struct_queue_signaux),
                   3092:                PROT_READ | PROT_WRITE, MAP_SHARED, f_queue_signaux, 0);
1.67      bertrand 3093: 
1.71      bertrand 3094:        if (((void *) s_queue_signaux) == ((void *) -1))
                   3095:        {
                   3096:            if (shm_unlink(nom) == -1)
                   3097:            {
                   3098:                free(nom);
                   3099:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   3100:                return;
                   3101:            }
1.67      bertrand 3102: 
                   3103:            free(nom);
                   3104:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1.16      bertrand 3105:            return;
                   3106:        }
                   3107: 
1.67      bertrand 3108:        free(nom);
1.75      bertrand 3109: 
1.71      bertrand 3110: #      ifndef SEMAPHORES_NOMMES
                   3111:            sem_init(&((*s_queue_signaux).semaphore), 1, 1);
1.96      bertrand 3112:            sem_init(&((*s_queue_signaux).signalisation), 1, 0);
1.71      bertrand 3113: #      else
1.80      bertrand 3114:            if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE))
1.72      bertrand 3115:                    == SEM_FAILED)
1.71      bertrand 3116:            {
                   3117:                (*s_etat_processus).erreur_systeme = d_es_processus;
                   3118:                return;
                   3119:            }
1.96      bertrand 3120: 
                   3121:            if ((semaphore_signalisation = sem_init2(1, getpid(),
                   3122:                    SEM_SIGNALISATION)) == SEM_FAILED)
                   3123:            {
                   3124:                (*s_etat_processus).erreur_systeme = d_es_processus;
                   3125:                return;
                   3126:            }
1.71      bertrand 3127: #      endif
1.67      bertrand 3128: 
1.71      bertrand 3129:        (*s_queue_signaux).pointeur_lecture = 0;
                   3130:        (*s_queue_signaux).pointeur_ecriture = 0;
1.96      bertrand 3131:        (*s_queue_signaux).requete_arret = d_faux;
1.67      bertrand 3132: 
1.71      bertrand 3133:        if (msync(s_queue_signaux, sizeof(struct_queue_signaux), 0))
1.16      bertrand 3134:        {
1.71      bertrand 3135:            (*s_etat_processus).erreur_systeme = d_es_processus;
1.16      bertrand 3136:            return;
                   3137:        }
1.75      bertrand 3138: #  else // IPCS_SYSV
1.71      bertrand 3139: #      ifndef OS2
1.75      bertrand 3140:            int                             segment;
                   3141:            int                             support;
1.71      bertrand 3142: 
                   3143:            key_t                           clef;
1.67      bertrand 3144: 
1.71      bertrand 3145:            // Création d'un segment de données associé au PID du processus
                   3146:            // courant
1.16      bertrand 3147: 
1.71      bertrand 3148:            if ((nom = nom_segment((*s_etat_processus)
                   3149:                    .chemin_fichiers_temporaires, getpid())) == NULL)
                   3150:            {
                   3151:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   3152:                return;
                   3153:            }
                   3154: 
1.76      bertrand 3155:            if ((support = open(nom, O_RDWR | O_CREAT | O_EXCL,
1.75      bertrand 3156:                    S_IRUSR | S_IWUSR)) == -1)
1.71      bertrand 3157:            {
                   3158:                (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
                   3159:                return;
                   3160:            }
                   3161: 
                   3162:            if ((clef = ftok(nom, 1)) == -1)
                   3163:            {
                   3164:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   3165:                return;
                   3166:            }
1.1       bertrand 3167: 
1.75      bertrand 3168:            close(support);
1.71      bertrand 3169:            free(nom);
1.1       bertrand 3170: 
1.75      bertrand 3171:            if ((segment = shmget(clef, sizeof(struct_queue_signaux),
1.71      bertrand 3172:                    IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)
                   3173:            {
                   3174:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   3175:                return;
                   3176:            }
                   3177: 
1.75      bertrand 3178:            s_queue_signaux = shmat(segment, NULL, 0);
                   3179:            f_queue_signaux = segment;
1.71      bertrand 3180: 
1.75      bertrand 3181:            if (((void *) s_queue_signaux) == ((void *) -1))
1.71      bertrand 3182:            {
1.75      bertrand 3183:                if (shmctl(f_queue_signaux, IPC_RMID, 0) == -1)
1.71      bertrand 3184:                {
                   3185:                    (*s_etat_processus).erreur_systeme =
                   3186:                            d_es_allocation_memoire;
                   3187:                    return;
                   3188:                }
                   3189: 
                   3190:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   3191:                return;
                   3192:            }
1.75      bertrand 3193: 
                   3194:            sem_init(&((*s_queue_signaux).semaphore), 1, 1);
1.96      bertrand 3195:            sem_init(&((*s_queue_signaux).signalisation), 1, 0);
1.75      bertrand 3196:            (*s_queue_signaux).pointeur_lecture = 0;
                   3197:            (*s_queue_signaux).pointeur_ecriture = 0;
1.96      bertrand 3198:            (*s_queue_signaux).requete_arret = d_faux;
1.71      bertrand 3199: #      else // OS/2
                   3200:            if ((nom = nom_segment(NULL, getpid())) == NULL)
                   3201:            {
                   3202:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   3203:                return;
                   3204:            }
                   3205: 
1.83      bertrand 3206:            if (DosAllocSharedMem((PVOID) &s_queue_signaux, nom,
                   3207:                    sizeof(struct_queue_signaux),
1.71      bertrand 3208:                    PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
                   3209:            {
                   3210:                free(nom);
                   3211:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   3212:                return;
                   3213:            }
1.67      bertrand 3214: 
1.71      bertrand 3215:            free(nom);
1.83      bertrand 3216: 
                   3217:            sem_init(&((*s_queue_signaux).semaphore), 1, 1);
1.96      bertrand 3218:            sem_init(&((*s_queue_signaux).signalisation), 1, 0);
1.83      bertrand 3219:            (*s_queue_signaux).pointeur_lecture = 0;
                   3220:            (*s_queue_signaux).pointeur_ecriture = 0;
1.96      bertrand 3221:            (*s_queue_signaux).requete_arret = d_faux;
1.71      bertrand 3222: #      endif
1.67      bertrand 3223: #  endif
                   3224: 
1.96      bertrand 3225:    // Lancement du thread de récupération des signaux.
                   3226: 
                   3227:    if (pthread_attr_init(&attributs) != 0)
                   3228:    {
                   3229:        (*s_etat_processus).erreur_systeme = d_es_processus;
                   3230:        return;
                   3231:    }
                   3232: 
                   3233:    if (pthread_attr_setdetachstate(&attributs,
                   3234:            PTHREAD_CREATE_JOINABLE) != 0)
                   3235:    {
                   3236:        (*s_etat_processus).erreur_systeme = d_es_processus;
                   3237:        return;
                   3238:    }
                   3239: 
                   3240: #  ifdef SCHED_OTHER
                   3241:    if (pthread_attr_setschedpolicy(&attributs, SCHED_OTHER) != 0)
                   3242:    {
                   3243:        (*s_etat_processus).erreur_systeme = d_es_processus;
                   3244:        return;
                   3245:    }
                   3246: #  endif
                   3247: 
                   3248: #  ifdef PTHREAD_EXPLICIT_SCHED
                   3249:    if (pthread_attr_setinheritsched(&attributs, PTHREAD_EXPLICIT_SCHED) != 0)
                   3250:    {
                   3251:        (*s_etat_processus).erreur_systeme = d_es_processus;
                   3252:        return;
                   3253:    }
                   3254: #  endif
                   3255: 
                   3256: #  ifdef PTHREAD_SCOPE_SYSTEM
                   3257:    if (pthread_attr_setscope(&attributs, PTHREAD_SCOPE_SYSTEM) != 0)
                   3258:    {
                   3259:        (*s_etat_processus).erreur_systeme = d_es_processus;
                   3260:        return;
                   3261:    }
                   3262: #  endif
                   3263: 
                   3264:    if (pthread_attr_destroy(&attributs) != 0)
                   3265:    {
                   3266:        (*s_etat_processus).erreur_systeme = d_es_processus;
                   3267:        return;
                   3268:    }
                   3269: 
                   3270:    if (pthread_create(&((*s_queue_signaux).thread_signaux), &attributs,
                   3271:            thread_surveillance_signaux, s_etat_processus) != 0)
                   3272:    {
                   3273:        (*s_etat_processus).erreur_systeme = d_es_processus;
                   3274:        return;
                   3275:    }
                   3276: 
1.1       bertrand 3277:    return;
                   3278: }
                   3279: 
1.67      bertrand 3280: 
                   3281: /*
                   3282: ================================================================================
                   3283:   Fonction libérant le segment de mémoire partagée destiné à contenir
                   3284:   la queue des signaux.
                   3285: ================================================================================
                   3286:   Entrée : structure de description du processus
                   3287: --------------------------------------------------------------------------------
                   3288:   Sortie : Néant
                   3289: --------------------------------------------------------------------------------
                   3290:   Effet de bord : Néant
                   3291: ================================================================================
                   3292: */
                   3293: 
                   3294: void
                   3295: liberation_queue_signaux(struct_processus *s_etat_processus)
1.66      bertrand 3296: {
1.96      bertrand 3297:    // Incrémenter le sémaphore pour être sûr de le débloquer.
                   3298: 
                   3299:    (*s_queue_signaux).requete_arret = d_vrai;
                   3300: 
1.100     bertrand 3301: #  if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
1.96      bertrand 3302:    sem_post(&((*s_queue_signaux).signalisation));
                   3303: #  else
                   3304:    sem_post(semaphore_signalisation);
                   3305: #  endif
                   3306: 
                   3307:    pthread_join((*s_queue_signaux).thread_signaux, NULL);
                   3308: 
1.67      bertrand 3309: #  ifdef IPCS_SYSV // SystemV
                   3310: #      ifndef OS2
1.75      bertrand 3311:            if (shmdt(s_queue_signaux) == -1)
                   3312:            {
                   3313:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   3314:                return;
                   3315:            }
1.67      bertrand 3316: #      else // OS/2
                   3317: #      endif
                   3318: #  else // POSIX
1.72      bertrand 3319: #      ifndef SEMAPHORES_NOMMES
1.126   ! bertrand 3320:            // Rien à faire, les sémaphores sont anonymes.
1.72      bertrand 3321: #      else
                   3322:            sem_close(semaphore_queue_signaux);
1.96      bertrand 3323:            sem_close(semaphore_signalisation);
1.72      bertrand 3324: #      endif
1.70      bertrand 3325: 
1.67      bertrand 3326:        if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
1.66      bertrand 3327:        {
1.67      bertrand 3328:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   3329:            return;
1.66      bertrand 3330:        }
1.69      bertrand 3331: 
                   3332:        close(f_queue_signaux);
1.67      bertrand 3333: #  endif
1.66      bertrand 3334: 
                   3335:    return;
                   3336: }
                   3337: 
1.67      bertrand 3338: 
                   3339: /*
                   3340: ================================================================================
                   3341:   Fonction détruisant le segment de mémoire partagée destiné à contenir
                   3342:   la queue des signaux.
                   3343: ================================================================================
                   3344:   Entrée : structure de description du processus
                   3345: --------------------------------------------------------------------------------
                   3346:   Sortie : Néant
                   3347: --------------------------------------------------------------------------------
                   3348:   Effet de bord : Néant
                   3349: ================================================================================
                   3350: */
                   3351: 
1.66      bertrand 3352: void
1.67      bertrand 3353: destruction_queue_signaux(struct_processus *s_etat_processus)
1.66      bertrand 3354: {
1.83      bertrand 3355: #  ifndef OS2
                   3356:        unsigned char       *nom;
                   3357: #  endif
1.66      bertrand 3358: 
1.99      bertrand 3359:    // Incrémenter le sémaphore pour être sûr de le débloquer.
                   3360: 
                   3361:    (*s_queue_signaux).requete_arret = d_vrai;
                   3362: 
1.100     bertrand 3363: #  if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
1.99      bertrand 3364:    sem_post(&((*s_queue_signaux).signalisation));
                   3365: #  else
                   3366:    sem_post(semaphore_signalisation);
                   3367: #  endif
                   3368: 
                   3369:    pthread_join((*s_queue_signaux).thread_signaux, NULL);
                   3370: 
1.67      bertrand 3371: #  ifdef IPCS_SYSV // SystemV
1.71      bertrand 3372: #      ifndef OS2
1.75      bertrand 3373:            // Il faut commencer par éliminer le sémaphore.
                   3374: 
                   3375:            if (semctl((*s_queue_signaux).semaphore.sem, 0, IPC_RMID) == -1)
                   3376:            {
                   3377:                (*s_etat_processus).erreur_systeme = d_es_processus;
                   3378:                return;
                   3379:            }
                   3380: 
                   3381:            unlink((*s_queue_signaux).semaphore.path);
1.96      bertrand 3382:            free((*s_queue_signaux).semaphore.path);
                   3383: 
                   3384:            if (semctl((*s_queue_signaux).signalisation.sem, 0, IPC_RMID) == -1)
                   3385:            {
                   3386:                (*s_etat_processus).erreur_systeme = d_es_processus;
                   3387:                return;
                   3388:            }
                   3389: 
                   3390:            unlink((*s_queue_signaux).signalisation.path);
                   3391:            free((*s_queue_signaux).signalisation.path);
1.75      bertrand 3392: 
                   3393:            if (shmdt(s_queue_signaux) == -1)
1.71      bertrand 3394:            {
                   3395:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   3396:                return;
                   3397:            }
                   3398: 
1.75      bertrand 3399:            if (shmctl(f_queue_signaux, IPC_RMID, 0) == -1)
1.71      bertrand 3400:            {
                   3401:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   3402:                return;
                   3403:            }
                   3404: 
                   3405:            if ((nom = nom_segment((*s_etat_processus)
                   3406:                    .chemin_fichiers_temporaires, getpid())) == NULL)
                   3407:            {
                   3408:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   3409:                return;
                   3410:            }
1.66      bertrand 3411: 
1.71      bertrand 3412:            unlink(nom);
                   3413:            free(nom);
                   3414: #      else
1.83      bertrand 3415:            sem_close(&((*s_queue_signaux).semaphore));
                   3416:            sem_destroy(&((*s_queue_signaux).semaphore));
                   3417: 
1.96      bertrand 3418:            sem_close(&((*s_queue_signaux).signalisation));
                   3419:            sem_destroy(&((*s_queue_signaux).signalisation));
                   3420: 
1.83      bertrand 3421:            if (DosFreeMem(s_queue_signaux) != 0)
1.71      bertrand 3422:            {
                   3423:                (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   3424:                return;
                   3425:            }
                   3426: #      endif
1.67      bertrand 3427: #  else // POSIX
1.72      bertrand 3428: #      ifndef SEMAPHORES_NOMMES
                   3429:            sem_destroy(&((*s_queue_signaux).semaphore));
1.96      bertrand 3430:            sem_destroy(&((*s_queue_signaux).signalisation));
1.72      bertrand 3431: #      else
                   3432:            sem_close(semaphore_queue_signaux);
1.80      bertrand 3433:            sem_destroy2(semaphore_queue_signaux, getpid(), SEM_QUEUE);
1.96      bertrand 3434: 
                   3435:            sem_close(semaphore_signalisation);
                   3436:            sem_destroy2(semaphore_signalisation, getpid(), SEM_SIGNALISATION);
1.72      bertrand 3437: #      endif
1.67      bertrand 3438: 
1.70      bertrand 3439:        if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
                   3440:        {
                   3441:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   3442:            return;
                   3443:        }
                   3444: 
                   3445:        if ((nom = nom_segment(NULL, getpid())) == NULL)
                   3446:        {
                   3447:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   3448:            return;
                   3449:        }
1.66      bertrand 3450: 
1.70      bertrand 3451:        close(f_queue_signaux);
1.66      bertrand 3452: 
1.70      bertrand 3453:        if (shm_unlink(nom) != 0)
                   3454:        {
                   3455:            free(nom);
                   3456:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                   3457:            return;
                   3458:        }
1.69      bertrand 3459: 
1.67      bertrand 3460:        free(nom);
                   3461: #  endif
                   3462: 
1.66      bertrand 3463:    return;
                   3464: }
                   3465: 
1.1       bertrand 3466: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>