File:  [local] / rpl / src / interruptions.c
Revision 1.129: download - view: text, annotated - select for diffs - revision graph
Wed May 22 13:40:12 2013 UTC (10 years, 11 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Correction de l'ordre de verrouillage de mutexes.

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

CVSweb interface <joel.bertrand@systella.fr>