File:  [local] / rpl / src / interruptions.c
Revision 1.121: download - view: text, annotated - select for diffs - revision graph
Thu Mar 21 11:30:30 2013 UTC (11 years, 1 month ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Troisième série de patches pour -Wconversion.

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

CVSweb interface <joel.bertrand@systella.fr>