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

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

CVSweb interface <joel.bertrand@systella.fr>