File:  [local] / rpl / src / interruptions.c
Revision 1.67: download - view: text, annotated - select for diffs - revision graph
Wed Sep 14 14:34:28 2011 UTC (12 years, 7 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Première série de patches pour rendre la gestion des signaux propre.

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

CVSweb interface <joel.bertrand@systella.fr>