File:  [local] / rpl / src / interruptions.c
Revision 1.51: download - view: text, annotated - select for diffs - revision graph
Tue Jun 21 07:45:27 2011 UTC (12 years, 10 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Merge de la branche 4_0 sur HEAD.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.0.prerelease.1
    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: #if 0
  807:             for(i = 0; i < (*s_etat_processus).nombre_variables; i++)
  808:             {
  809:                 pthread_mutex_trylock(&((*(*s_etat_processus)
  810:                         .s_liste_variables[i].objet).mutex));
  811:                 pthread_mutex_unlock(&((*(*s_etat_processus)
  812:                         .s_liste_variables[i].objet).mutex));
  813: 
  814:                 // Les variables de niveau 0 sont des définitions qui
  815:                 // ne sont pas copiées entre threads.
  816:                 if ((*s_etat_processus).s_liste_variables[i].niveau > 0)
  817:                 {
  818:                     liberation(s_etat_processus,
  819:                             (*s_etat_processus).s_liste_variables[i].objet);
  820:                 }
  821: 
  822:                 free((*s_etat_processus).s_liste_variables[i].nom);
  823:             }
  824: 
  825:             free((*s_etat_processus).s_liste_variables);
  826: #endif
  827: 
  828:             for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)
  829:             {
  830:                 pthread_mutex_trylock(&((*(*s_etat_processus)
  831:                         .s_liste_variables_statiques[i].objet).mutex));
  832:                 pthread_mutex_unlock(&((*(*s_etat_processus)
  833:                         .s_liste_variables_statiques[i].objet).mutex));
  834: 
  835:                 liberation(s_etat_processus, (*s_etat_processus)
  836:                         .s_liste_variables_statiques[i].objet);
  837:                 free((*s_etat_processus).s_liste_variables_statiques[i].nom);
  838:             }
  839: 
  840:             free((*s_etat_processus).s_liste_variables_statiques);
  841: 
  842:             // Ne peut être effacé qu'une seule fois
  843:             if (suppression_variables_partagees == d_faux)
  844:             {
  845:                 suppression_variables_partagees = d_vrai;
  846: 
  847:                 for(i = 0; i < (*(*s_etat_processus)
  848:                         .s_liste_variables_partagees).nombre_variables; i++)
  849:                 {
  850:                     pthread_mutex_trylock(&((*(*(*s_etat_processus)
  851:                             .s_liste_variables_partagees).table[i].objet)
  852:                             .mutex));
  853:                     pthread_mutex_unlock(&((*(*(*s_etat_processus)
  854:                             .s_liste_variables_partagees).table[i].objet)
  855:                             .mutex));
  856: 
  857:                     liberation(s_etat_processus, (*(*s_etat_processus)
  858:                             .s_liste_variables_partagees).table[i].objet);
  859:                     free((*(*s_etat_processus).s_liste_variables_partagees)
  860:                             .table[i].nom);
  861:                 }
  862: 
  863:                 if ((*(*s_etat_processus).s_liste_variables_partagees).table
  864:                         != NULL)
  865:                 {
  866:                     free((struct_variable_partagee *) (*(*s_etat_processus)
  867:                             .s_liste_variables_partagees).table);
  868:                 }
  869: 
  870:                 pthread_mutex_trylock(&((*(*s_etat_processus)
  871:                         .s_liste_variables_partagees).mutex));
  872:                 pthread_mutex_unlock(&((*(*s_etat_processus)
  873:                         .s_liste_variables_partagees).mutex));
  874:             }
  875: 
  876:             element_courant = (*s_etat_processus).l_base_pile;
  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: 
  887:                 liberation(s_etat_processus,
  888:                         (*((struct_liste_chainee *)
  889:                         element_courant)).donnee);
  890:                 free((struct_liste_chainee *) element_courant);
  891: 
  892:                 element_courant = element_suivant;
  893:             }
  894: 
  895:             element_courant = (*s_etat_processus).l_base_pile_contextes;
  896:             while(element_courant != NULL)
  897:             {
  898:                 element_suivant = (*((struct_liste_chainee *)
  899:                         element_courant)).suivant;
  900: 
  901:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  902:                         element_courant)).donnee).mutex));
  903:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  904:                         element_courant)).donnee).mutex));
  905:                 liberation(s_etat_processus, (*((struct_liste_chainee *)
  906:                         element_courant)).donnee);
  907:                 free((struct_liste_chainee *) element_courant);
  908: 
  909:                 element_courant = element_suivant;
  910:             }
  911: 
  912:             element_courant = (*s_etat_processus).l_base_pile_taille_contextes;
  913:             while(element_courant != NULL)
  914:             {
  915:                 element_suivant = (*((struct_liste_chainee *)
  916:                         element_courant)).suivant;
  917: 
  918:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  919:                         element_courant)).donnee).mutex));
  920:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  921:                         element_courant)).donnee).mutex));
  922:                 liberation(s_etat_processus,
  923:                         (*((struct_liste_chainee *)
  924:                         element_courant)).donnee);
  925:                 free((struct_liste_chainee *) element_courant);
  926: 
  927:                 element_courant = element_suivant;
  928:             }
  929: 
  930:             for(i = 0; i < (*s_etat_processus).nombre_instructions_externes;
  931:                     i++)
  932:             {
  933:                 free((*s_etat_processus).s_instructions_externes[i].nom);
  934:                 free((*s_etat_processus).s_instructions_externes[i]
  935:                         .nom_bibliotheque);
  936:             }
  937: 
  938:             if ((*s_etat_processus).nombre_instructions_externes != 0)
  939:             {
  940:                 free((*s_etat_processus).s_instructions_externes);
  941:             }
  942: 
  943:             element_courant = (*s_etat_processus).s_bibliotheques;
  944:             while(element_courant != NULL)
  945:             {
  946:                 element_suivant = (*((struct_liste_chainee *)
  947:                         element_courant)).suivant;
  948: 
  949:                 element_candidat = (*candidat).s_bibliotheques;
  950:                 while(element_candidat != NULL)
  951:                 {
  952:                     if (((*((struct_bibliotheque *) (*((struct_liste_chainee *)
  953:                             element_courant)).donnee))
  954:                             .descripteur == (*((struct_bibliotheque *)
  955:                             (*((struct_liste_chainee *) element_candidat))
  956:                             .donnee)).descripteur) &&
  957:                             ((*((struct_bibliotheque *)
  958:                             (*((struct_liste_chainee *) element_courant))
  959:                             .donnee)).pid == (*((struct_bibliotheque *)
  960:                             (*((struct_liste_chainee *) element_candidat))
  961:                             .donnee)).pid) && (pthread_equal(
  962:                             (*((struct_bibliotheque *)
  963:                             (*((struct_liste_chainee *) element_courant))
  964:                             .donnee)).tid, (*((struct_bibliotheque *)
  965:                             (*((struct_liste_chainee *) element_candidat))
  966:                             .donnee)).tid) != 0))
  967:                     {
  968:                         break;
  969:                     }
  970: 
  971:                     element_candidat = (*((struct_liste_chainee *)
  972:                             element_candidat)).suivant;
  973:                 }
  974: 
  975:                 if (element_candidat == NULL)
  976:                 {
  977:                     dlclose((*((struct_bibliotheque *)
  978:                             (*((struct_liste_chainee *) element_courant))
  979:                             .donnee)).descripteur);
  980:                 }
  981: 
  982:                 free((*((struct_bibliotheque *)
  983:                         (*((struct_liste_chainee *)
  984:                         element_courant)).donnee)).nom);
  985:                 free((*((struct_liste_chainee *) element_courant)).donnee);
  986:                 free(element_courant);
  987: 
  988:                 element_courant = element_suivant;
  989:             }
  990: 
  991:             element_courant = (*s_etat_processus).l_base_pile_last;
  992:             while(element_courant != NULL)
  993:             {
  994:                 element_suivant = (*((struct_liste_chainee *)
  995:                         element_courant)).suivant;
  996: 
  997:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  998:                         element_courant)).donnee).mutex));
  999:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
 1000:                         element_courant)).donnee).mutex));
 1001:                 liberation(s_etat_processus,
 1002:                         (*((struct_liste_chainee *) element_courant)).donnee);
 1003:                 free(element_courant);
 1004: 
 1005:                 element_courant = element_suivant;
 1006:             }
 1007: 
 1008:             element_courant = (*s_etat_processus).l_base_pile_systeme;
 1009:             while(element_courant != NULL)
 1010:             {
 1011:                 element_suivant = (*((struct_liste_pile_systeme *)
 1012:                         element_courant)).suivant;
 1013: 
 1014:                 if ((*((struct_liste_pile_systeme *)
 1015:                         element_courant)).indice_boucle != NULL)
 1016:                 {
 1017:                     pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
 1018:                             element_courant)).indice_boucle).mutex));
 1019:                     pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
 1020:                             element_courant)).indice_boucle).mutex));
 1021:                 }
 1022: 
 1023:                 liberation(s_etat_processus,
 1024:                         (*((struct_liste_pile_systeme *)
 1025:                         element_courant)).indice_boucle);
 1026: 
 1027:                 if ((*((struct_liste_pile_systeme *)
 1028:                         element_courant)).limite_indice_boucle != NULL)
 1029:                 {
 1030:                     pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
 1031:                             element_courant)).limite_indice_boucle).mutex));
 1032:                     pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
 1033:                             element_courant)).limite_indice_boucle).mutex));
 1034:                 }
 1035: 
 1036:                 liberation(s_etat_processus,
 1037:                         (*((struct_liste_pile_systeme *)
 1038:                         element_courant)).limite_indice_boucle);
 1039: 
 1040:                 if ((*((struct_liste_pile_systeme *)
 1041:                         element_courant)).objet_de_test != NULL)
 1042:                 {
 1043:                     pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
 1044:                             element_courant)).objet_de_test).mutex));
 1045:                     pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
 1046:                             element_courant)).objet_de_test).mutex));
 1047:                 }
 1048: 
 1049:                 liberation(s_etat_processus,
 1050:                         (*((struct_liste_pile_systeme *)
 1051:                         element_courant)).objet_de_test);
 1052: 
 1053:                 if ((*((struct_liste_pile_systeme *)
 1054:                         element_courant)).nom_variable != NULL)
 1055:                 {
 1056:                     free((*((struct_liste_pile_systeme *)
 1057:                             element_courant)).nom_variable);
 1058:                 }
 1059: 
 1060:                 free(element_courant);
 1061: 
 1062:                 element_courant = element_suivant;
 1063:             }
 1064: 
 1065:             element_courant = (*s_etat_processus).s_fichiers;
 1066:             while(element_courant != NULL)
 1067:             {
 1068:                 element_suivant = (*((struct_liste_chainee *)
 1069:                         element_courant)).suivant;
 1070: 
 1071:                 element_candidat = (*candidat).s_fichiers;
 1072:                 while(element_candidat != NULL)
 1073:                 {
 1074:                     if (((*((struct_descripteur_fichier *)
 1075:                             (*((struct_liste_chainee *) element_courant))
 1076:                             .donnee)).pid ==
 1077:                             (*((struct_descripteur_fichier *)
 1078:                             (*((struct_liste_chainee *) element_candidat))
 1079:                             .donnee)).pid) && (pthread_equal(
 1080:                             (*((struct_descripteur_fichier *)
 1081:                             (*((struct_liste_chainee *) element_courant))
 1082:                             .donnee)).tid, (*((struct_descripteur_fichier *)
 1083:                             (*((struct_liste_chainee *) element_candidat))
 1084:                             .donnee)).tid) != 0))
 1085:                     {
 1086:                         if ((*((struct_descripteur_fichier *)
 1087:                                 (*((struct_liste_chainee *) element_courant))
 1088:                                 .donnee)).type ==
 1089:                                 (*((struct_descripteur_fichier *)
 1090:                                 (*((struct_liste_chainee *) element_candidat))
 1091:                                 .donnee)).type)
 1092:                         {
 1093:                             if ((*((struct_descripteur_fichier *)
 1094:                                     (*((struct_liste_chainee *)
 1095:                                     element_candidat)).donnee)).type == 'C')
 1096:                             {
 1097:                                 if ((*((struct_descripteur_fichier *)
 1098:                                         (*((struct_liste_chainee *)
 1099:                                         element_courant)).donnee))
 1100:                                         .descripteur_c ==
 1101:                                         (*((struct_descripteur_fichier *)
 1102:                                         (*((struct_liste_chainee *)
 1103:                                         element_candidat)).donnee))
 1104:                                         .descripteur_c)
 1105:                                 {
 1106:                                     break;
 1107:                                 }
 1108:                             }
 1109:                             else
 1110:                             {
 1111:                                 if (((*((struct_descripteur_fichier *)
 1112:                                         (*((struct_liste_chainee *)
 1113:                                         element_courant)).donnee))
 1114:                                         .descripteur_sqlite ==
 1115:                                         (*((struct_descripteur_fichier *)
 1116:                                         (*((struct_liste_chainee *)
 1117:                                         element_candidat)).donnee))
 1118:                                         .descripteur_sqlite) &&
 1119:                                         ((*((struct_descripteur_fichier *)
 1120:                                         (*((struct_liste_chainee *)
 1121:                                         element_courant)).donnee))
 1122:                                         .descripteur_c ==
 1123:                                         (*((struct_descripteur_fichier *)
 1124:                                         (*((struct_liste_chainee *)
 1125:                                         element_candidat)).donnee))
 1126:                                         .descripteur_c))
 1127:                                 {
 1128:                                     break;
 1129:                                 }
 1130:                             }
 1131:                         }
 1132:                     }
 1133: 
 1134:                     element_candidat = (*((struct_liste_chainee *)
 1135:                             element_candidat)).suivant;
 1136:                 }
 1137: 
 1138:                 if (element_candidat == NULL)
 1139:                 {
 1140:                     fclose((*((struct_descripteur_fichier *)
 1141:                             (*((struct_liste_chainee *) element_courant))
 1142:                             .donnee)).descripteur_c);
 1143: 
 1144:                     if ((*((struct_descripteur_fichier *)
 1145:                             (*((struct_liste_chainee *) element_courant))
 1146:                             .donnee)).type != 'C')
 1147:                     {
 1148:                         sqlite3_close((*((struct_descripteur_fichier *)
 1149:                                 (*((struct_liste_chainee *) element_courant))
 1150:                                 .donnee)).descripteur_sqlite);
 1151:                     }
 1152:                 }
 1153: 
 1154:                 free((*((struct_descripteur_fichier *)
 1155:                         (*((struct_liste_chainee *)
 1156:                         element_courant)).donnee)).nom);
 1157:                 free((struct_descripteur_fichier *)
 1158:                         (*((struct_liste_chainee *)
 1159:                         element_courant)).donnee);
 1160:                 free(element_courant);
 1161: 
 1162:                 element_courant = element_suivant;
 1163:             }
 1164: 
 1165:             element_courant = (*s_etat_processus).s_sockets;
 1166:             while(element_courant != NULL)
 1167:             {
 1168:                 element_suivant = (*((struct_liste_chainee *)
 1169:                         element_courant)).suivant;
 1170: 
 1171:                 element_candidat = (*candidat).s_sockets;
 1172:                 while(element_candidat != NULL)
 1173:                 {
 1174:                     if (((*((struct_socket *)
 1175:                             (*((struct_liste_chainee *) element_courant))
 1176:                             .donnee)).socket == (*((struct_socket *)
 1177:                             (*((struct_liste_chainee *) element_candidat))
 1178:                             .donnee)).socket) &&
 1179:                             ((*((struct_socket *)
 1180:                             (*((struct_liste_chainee *) element_courant))
 1181:                             .donnee)).pid == (*((struct_socket *)
 1182:                             (*((struct_liste_chainee *) element_candidat))
 1183:                             .donnee)).pid) && (pthread_equal(
 1184:                             (*((struct_socket *)
 1185:                             (*((struct_liste_chainee *) element_courant))
 1186:                             .donnee)).tid, (*((struct_socket *)
 1187:                             (*((struct_liste_chainee *) element_candidat))
 1188:                             .donnee)).tid) != 0))
 1189:                     {
 1190:                         break;
 1191:                     }
 1192: 
 1193:                     element_candidat = (*((struct_liste_chainee *)
 1194:                             element_candidat)).suivant;
 1195:                 }
 1196: 
 1197:                 if (element_candidat == NULL)
 1198:                 {
 1199:                     if ((*((struct_socket *) (*((struct_liste_chainee *)
 1200:                             element_courant)).donnee)).socket_connectee
 1201:                             == d_vrai)
 1202:                     {
 1203:                         shutdown((*((struct_socket *)
 1204:                                 (*((struct_liste_chainee *) element_courant))
 1205:                                 .donnee)).socket, SHUT_RDWR);
 1206:                     }
 1207: 
 1208:                     close((*((struct_socket *)
 1209:                             (*((struct_liste_chainee *) element_courant))
 1210:                             .donnee)).socket);
 1211:                 }
 1212: 
 1213:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
 1214:                         element_courant)).donnee).mutex));
 1215:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
 1216:                         element_courant)).donnee).mutex));
 1217: 
 1218:                 liberation(s_etat_processus,
 1219:                         (*((struct_liste_chainee *)
 1220:                         element_courant)).donnee);
 1221:                 free(element_courant);
 1222: 
 1223:                 element_courant = element_suivant;
 1224:             }
 1225: 
 1226: /*
 1227: ================================================================================
 1228:   À noter : on ne ferme pas la connexion car la conséquence immédiate est
 1229:   une destruction de l'objet pour le processus père.
 1230: ================================================================================
 1231: 
 1232:             element_courant = (*s_etat_processus).s_connecteurs_sql;
 1233:             while(element_courant != NULL)
 1234:             {
 1235:                 element_suivant = (*((struct_liste_chainee *)
 1236:                         element_courant)).suivant;
 1237: 
 1238:                 element_candidat = (*candidat).s_connecteurs_sql;
 1239:                 while(element_candidat != NULL)
 1240:                 {
 1241:                     if (((
 1242: #ifdef MYSQL_SUPPORT
 1243:                             ((*((struct_connecteur_sql *)
 1244:                             (*((struct_liste_chainee *) element_courant))
 1245:                             .donnee)).descripteur.mysql ==
 1246:                             (*((struct_connecteur_sql *)
 1247:                             (*((struct_liste_chainee *) element_candidat))
 1248:                             .donnee)).descripteur.mysql)
 1249:                             &&
 1250:                             (strcmp((*((struct_connecteur_sql *)
 1251:                             (*((struct_liste_chainee *) element_courant))
 1252:                             .donnee)).type, "MYSQL") == 0)
 1253:                             &&
 1254:                             (strcmp((*((struct_connecteur_sql *)
 1255:                             (*((struct_liste_chainee *) element_candidat))
 1256:                             .donnee)).type, "MYSQL") == 0)
 1257: #else
 1258:                             0
 1259: #endif
 1260:                             ) || (
 1261: #ifdef POSTGRESQL_SUPPORT
 1262:                             ((*((struct_connecteur_sql *)
 1263:                             (*((struct_liste_chainee *) element_courant))
 1264:                             .donnee)).descripteur.postgresql ==
 1265:                             (*((struct_connecteur_sql *)
 1266:                             (*((struct_liste_chainee *) element_candidat))
 1267:                             .donnee)).descripteur.postgresql)
 1268:                             &&
 1269:                             (strcmp((*((struct_connecteur_sql *)
 1270:                             (*((struct_liste_chainee *) element_courant))
 1271:                             .donnee)).type, "POSTGRESQL") == 0)
 1272:                             &&
 1273:                             (strcmp((*((struct_connecteur_sql *)
 1274:                             (*((struct_liste_chainee *) element_candidat))
 1275:                             .donnee)).type, "POSTGRESQL") == 0)
 1276: #else
 1277:                             0
 1278: #endif
 1279:                             )) &&
 1280:                             ((*((struct_connecteur_sql *)
 1281:                             (*((struct_liste_chainee *) element_courant))
 1282:                             .donnee)).pid == (*((struct_connecteur_sql *)
 1283:                             (*((struct_liste_chainee *) element_candidat))
 1284:                             .donnee)).pid) && (pthread_equal(
 1285:                             (*((struct_connecteur_sql *)
 1286:                             (*((struct_liste_chainee *) element_courant))
 1287:                             .donnee)).tid, (*((struct_connecteur_sql *)
 1288:                             (*((struct_liste_chainee *) element_candidat))
 1289:                             .donnee)).tid) != 0))
 1290:                     {
 1291:                         break;
 1292:                     }
 1293: 
 1294:                     element_candidat = (*((struct_liste_chainee *)
 1295:                             element_candidat)).suivant;
 1296:                 }
 1297: 
 1298:                 if (element_candidat == NULL)
 1299:                 {
 1300:                     sqlclose((*((struct_liste_chainee *) element_courant))
 1301:                             .donnee);
 1302:                 }
 1303: 
 1304:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
 1305:                         element_courant)).donnee).mutex));
 1306:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
 1307:                         element_courant)).donnee).mutex));
 1308: 
 1309:                 liberation(s_etat_processus, (*((struct_liste_chainee *)
 1310:                         element_courant)).donnee);
 1311:                 free(element_courant);
 1312: 
 1313:                 element_courant = element_suivant;
 1314:             }
 1315: */
 1316: 
 1317:             (*s_etat_processus).s_connecteurs_sql = NULL;
 1318: 
 1319:             element_courant = (*s_etat_processus).s_marques;
 1320:             while(element_courant != NULL)
 1321:             {
 1322:                 free((*((struct_marque *) element_courant)).label);
 1323:                 free((*((struct_marque *) element_courant)).position);
 1324:                 element_suivant = (*((struct_marque *) element_courant))
 1325:                         .suivant;
 1326:                 free(element_courant);
 1327:                 element_courant = element_suivant;
 1328:             }
 1329: 
 1330:             liberation_allocateur(s_etat_processus);
 1331: 
 1332: #           ifndef SEMAPHORES_NOMMES
 1333:             sem_post(&((*s_etat_processus).semaphore_fork));
 1334:             sem_destroy(&((*s_etat_processus).semaphore_fork));
 1335: #           else
 1336:             sem_post((*s_etat_processus).semaphore_fork);
 1337:             sem_destroy2((*s_etat_processus).semaphore_fork, sem_fork);
 1338: #           endif
 1339: 
 1340:             free(s_etat_processus);
 1341: 
 1342:             s_etat_processus = candidat;
 1343:         }
 1344: 
 1345:         l_element_suivant = (*l_element_courant).suivant;
 1346: 
 1347:         free((struct_thread *) (*l_element_courant).donnee);
 1348:         free((struct_liste_chainee *) l_element_courant);
 1349: 
 1350:         l_element_courant = l_element_suivant;
 1351:     }
 1352: 
 1353:     liste_threads = NULL;
 1354: 
 1355:     l_element_courant = liste_threads_surveillance;
 1356: 
 1357:     while(l_element_courant != NULL)
 1358:     {
 1359:         s_argument_thread = (struct_descripteur_thread *)
 1360:                 (*l_element_courant).donnee;
 1361: 
 1362:         if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
 1363:                 != 0)
 1364:         {
 1365:             (*s_etat_processus).erreur_systeme = d_es_processus;
 1366:             sem_post(&semaphore_liste_threads);
 1367:             return;
 1368:         }
 1369: 
 1370:         (*s_argument_thread).nombre_references--;
 1371: 
 1372:         BUG((*s_argument_thread).nombre_references < 0,
 1373:                 printf("(*s_argument_thread).nombre_references = %d\n",
 1374:                 (int) (*s_argument_thread).nombre_references));
 1375: 
 1376:         if ((*s_argument_thread).nombre_references == 0)
 1377:         {
 1378:             close((*s_argument_thread).pipe_objets[0]);
 1379:             close((*s_argument_thread).pipe_acquittement[1]);
 1380:             close((*s_argument_thread).pipe_injections[1]);
 1381:             close((*s_argument_thread).pipe_nombre_injections[1]);
 1382:             close((*s_argument_thread).pipe_nombre_objets_attente[0]);
 1383:             close((*s_argument_thread).pipe_interruptions[0]);
 1384:             close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);
 1385: 
 1386:             if (pthread_mutex_unlock(&((*s_argument_thread)
 1387:                     .mutex_nombre_references)) != 0)
 1388:             {
 1389:                 (*s_etat_processus).erreur_systeme = d_es_processus;
 1390:                 sem_post(&semaphore_liste_threads);
 1391:                 return;
 1392:             }
 1393: 
 1394:             pthread_mutex_destroy(&((*s_argument_thread).mutex));
 1395:             pthread_mutex_destroy(&((*s_argument_thread)
 1396:                     .mutex_nombre_references));
 1397: 
 1398:             if ((*s_argument_thread).processus_detache == d_faux)
 1399:             {
 1400:                 if ((*s_argument_thread).destruction_objet == d_vrai)
 1401:                 {
 1402:                     liberation(s_etat_processus, (*s_argument_thread).argument);
 1403:                 }
 1404:             }
 1405: 
 1406:             free(s_argument_thread);
 1407:         }
 1408:         else
 1409:         {
 1410:             if (pthread_mutex_unlock(&((*s_argument_thread)
 1411:                     .mutex_nombre_references)) != 0)
 1412:             {
 1413:                 (*s_etat_processus).erreur_systeme = d_es_processus;
 1414:                 sem_post(&semaphore_liste_threads);
 1415:                 return;
 1416:             }
 1417:         }
 1418: 
 1419:         l_element_suivant = (*l_element_courant).suivant;
 1420:         free((struct_liste_chainee *) l_element_courant);
 1421:         l_element_courant = l_element_suivant;
 1422:     }
 1423: 
 1424:     liste_threads_surveillance = NULL;
 1425: 
 1426: #   ifndef SEMAPHORES_NOMMES
 1427:     if (sem_post(&semaphore_liste_threads) != 0)
 1428: #   else
 1429:     if (sem_post(semaphore_liste_threads) != 0)
 1430: #   endif
 1431:     {
 1432:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1433:         (*s_etat_processus).erreur_systeme = d_es_processus;
 1434:         return;
 1435:     }
 1436: 
 1437:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1438:     sigpending(&set);
 1439:     return;
 1440: }
 1441: 
 1442: static struct_processus *
 1443: recherche_thread(pid_t pid, pthread_t tid)
 1444: {
 1445:     volatile struct_liste_chainee_volatile      *l_element_courant;
 1446: 
 1447:     struct_processus                            *s_etat_processus;
 1448: 
 1449:     l_element_courant = liste_threads;
 1450: 
 1451:     while(l_element_courant != NULL)
 1452:     {
 1453:         if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee))
 1454:                 .tid, tid) != 0) && ((*((struct_thread *)
 1455:                 (*l_element_courant).donnee)).pid == pid))
 1456:         {
 1457:             break;
 1458:         }
 1459: 
 1460:         l_element_courant = (*l_element_courant).suivant;
 1461:     }
 1462: 
 1463:     if (l_element_courant == NULL)
 1464:     {
 1465:         /*
 1466:          * Le processus n'existe plus. On ne distribue aucun signal.
 1467:          */
 1468: 
 1469:         return(NULL);
 1470:     }
 1471: 
 1472:     s_etat_processus = (*((struct_thread *)
 1473:             (*l_element_courant).donnee)).s_etat_processus;
 1474: 
 1475:     return(s_etat_processus);
 1476: }
 1477: 
 1478: static logical1
 1479: recherche_thread_principal(pid_t pid, pthread_t *thread)
 1480: {
 1481:     volatile struct_liste_chainee_volatile      *l_element_courant;
 1482: 
 1483:     l_element_courant = liste_threads;
 1484: 
 1485:     while(l_element_courant != NULL)
 1486:     {
 1487:         if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal
 1488:                 == d_vrai) && ((*((struct_thread *)
 1489:                 (*l_element_courant).donnee)).pid == pid))
 1490:         {
 1491:             break;
 1492:         }
 1493: 
 1494:         l_element_courant = (*l_element_courant).suivant;
 1495:     }
 1496: 
 1497:     if (l_element_courant == NULL)
 1498:     {
 1499:         /*
 1500:          * Le processus n'existe plus. On ne distribue aucun signal.
 1501:          */
 1502: 
 1503:         return(d_faux);
 1504:     }
 1505: 
 1506:     (*thread) = (*((struct_thread *) (*l_element_courant).donnee)).tid;
 1507: 
 1508:     return(d_vrai);
 1509: }
 1510: 
 1511: 
 1512: /*
 1513: ================================================================================
 1514:   Procédures de gestion des signaux d'interruption
 1515: ================================================================================
 1516:   Entrée : variable globale
 1517: --------------------------------------------------------------------------------
 1518:   Sortie : variable globale modifiée
 1519: --------------------------------------------------------------------------------
 1520:   Effets de bord : néant
 1521: ================================================================================
 1522: */
 1523: 
 1524: // Les routines suivantes sont uniquement appelées depuis les gestionnaires
 1525: // des signaux asynchrones. Elles ne doivent pas bloquer dans le cas où
 1526: // les sémaphores sont déjà bloqués par un gestionnaire de signal.
 1527: 
 1528: static inline void
 1529: verrouillage_gestionnaire_signaux()
 1530: {
 1531:     int         semaphore;
 1532: 
 1533:     sigset_t    oldset;
 1534:     sigset_t    set;
 1535: 
 1536:     sem_t       *sem;
 1537: 
 1538:     if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
 1539:             != NULL)
 1540:     {
 1541:         if (sem_post(sem) != 0)
 1542:         {
 1543:             BUG(1, uprintf("Lock error !\n"));
 1544:             return;
 1545:         }
 1546:     }
 1547: 
 1548:     // Il faut respecteur l'atomicité des deux opérations suivantes !
 1549: 
 1550:     sigfillset(&set);
 1551:     pthread_sigmask(SIG_BLOCK, &set, &oldset);
 1552: 
 1553: #   ifndef SEMAPHORES_NOMMES
 1554:     while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
 1555: #   else
 1556:     while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)
 1557: #   endif
 1558:     {
 1559:         if (errno != EINTR)
 1560:         {
 1561:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1562:             BUG(1, uprintf("Unlock error !\n"));
 1563:             return;
 1564:         }
 1565:     }
 1566: 
 1567: #   ifndef SEMAPHORES_NOMMES
 1568:     if (sem_post(&semaphore_gestionnaires_signaux) == -1)
 1569: #   else
 1570:     if (sem_post(semaphore_gestionnaires_signaux) == -1)
 1571: #   endif
 1572:     {
 1573:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1574:         BUG(1, uprintf("Lock error !\n"));
 1575:         return;
 1576:     }
 1577: 
 1578: #   ifndef SEMAPHORES_NOMMES
 1579:     if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
 1580: #   else
 1581:     if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
 1582: #   endif
 1583:     {
 1584:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1585:         BUG(1, uprintf("Lock error !\n"));
 1586:         return;
 1587:     }
 1588: 
 1589: #   ifndef SEMAPHORES_NOMMES
 1590:     if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
 1591: #   else
 1592:     if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)
 1593: #   endif
 1594:     {
 1595:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1596:         BUG(1, uprintf("Unlock error !\n"));
 1597:         return;
 1598:     }
 1599: 
 1600:     if (semaphore == 1)
 1601:     {
 1602:         // Le semaphore ne peut être pris par le thread qui a appelé
 1603:         // le gestionnaire de signal car le signal est bloqué par ce thread
 1604:         // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que
 1605:         // par un thread concurrent. On essaye donc de le bloquer jusqu'à
 1606:         // ce que ce soit possible.
 1607: 
 1608: #       ifndef SEMAPHORES_NOMMES
 1609:         while(sem_wait(&semaphore_liste_threads) == -1)
 1610: #       else
 1611:         while(sem_wait(semaphore_liste_threads) == -1)
 1612: #       endif
 1613:         {
 1614:             if (errno != EINTR)
 1615:             {
 1616:                 pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1617: 
 1618:                 while(sem_wait(sem) == -1)
 1619:                 {
 1620:                     if (errno != EINTR)
 1621:                     {
 1622:                         BUG(1, uprintf("Lock error !\n"));
 1623:                         return;
 1624:                     }
 1625:                 }
 1626: 
 1627:                 BUG(1, uprintf("Lock error !\n"));
 1628:                 return;
 1629:             }
 1630:         }
 1631:     }
 1632: 
 1633:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1634:     sigpending(&set);
 1635: 
 1636:     return;
 1637: }
 1638: 
 1639: static inline void
 1640: deverrouillage_gestionnaire_signaux()
 1641: {
 1642:     int         semaphore;
 1643: 
 1644:     sem_t       *sem;
 1645: 
 1646:     sigset_t    oldset;
 1647:     sigset_t    set;
 1648: 
 1649:     // Il faut respecteur l'atomicité des deux opérations suivantes !
 1650: 
 1651:     sigfillset(&set);
 1652:     pthread_sigmask(SIG_BLOCK, &set, &oldset);
 1653: 
 1654: #   ifndef SEMAPHORES_NOMMES
 1655:     while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
 1656: #   else
 1657:     while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)
 1658: #   endif
 1659:     {
 1660:         if (errno != EINTR)
 1661:         {
 1662:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1663:             BUG(1, uprintf("Unlock error !\n"));
 1664:             return;
 1665:         }
 1666:     }
 1667: 
 1668: #   ifndef SEMAPHORES_NOMMES
 1669:     if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
 1670: #   else
 1671:     if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
 1672: #   endif
 1673:     {
 1674:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1675:         BUG(1, uprintf("Unlock error !\n"));
 1676:         return;
 1677:     }
 1678: 
 1679: #   ifndef SEMAPHORES_NOMMES
 1680:     while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
 1681: #   else
 1682:     while(sem_wait(semaphore_gestionnaires_signaux) == -1)
 1683: #   endif
 1684:     {
 1685:         if (errno != EINTR)
 1686:         {
 1687:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1688:             BUG(1, uprintf("Unlock error !\n"));
 1689:             return;
 1690:         }
 1691:     }
 1692: 
 1693: #   ifndef SEMAPHORES_NOMMES
 1694:     if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
 1695: #   else
 1696:     if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)
 1697: #   endif
 1698:     {
 1699:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1700:         BUG(1, uprintf("Unlock error !\n"));
 1701:         return;
 1702:     }
 1703: 
 1704:     if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
 1705:             != NULL)
 1706:     {
 1707:         while(sem_wait(sem) == -1)
 1708:         {
 1709:             if (errno != EINTR)
 1710:             {
 1711:                 pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1712:                 BUG(1, uprintf("Unlock error !\n"));
 1713:                 return;
 1714:             }
 1715:         }
 1716:     }
 1717: 
 1718:     if (semaphore == 1)
 1719:     {
 1720: #       ifndef SEMAPHORES_NOMMES
 1721:         if (sem_post(&semaphore_liste_threads) != 0)
 1722: #       else
 1723:         if (sem_post(semaphore_liste_threads) != 0)
 1724: #       endif
 1725:         {
 1726:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1727: 
 1728:             BUG(1, uprintf("Unlock error !\n"));
 1729:             return;
 1730:         }
 1731:     }
 1732: 
 1733:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1734:     sigpending(&set);
 1735: 
 1736:     return;
 1737: }
 1738: 
 1739: void
 1740: interruption1(SIGHANDLER_ARGS)
 1741: {
 1742:     pid_t                   pid;
 1743: 
 1744:     pthread_t               thread;
 1745: 
 1746:     struct_processus        *s_etat_processus;
 1747: 
 1748:     volatile sig_atomic_t   exclusion = 0;
 1749: 
 1750:     verrouillage_gestionnaire_signaux();
 1751: 
 1752: #   ifdef _BROKEN_SIGINFO
 1753:     if ((signal == SIGINT) || (signal == SIGTERM))
 1754:     {
 1755:         // Si l'interruption provient du clavier, il n'y a pas eu d'appel
 1756:         // à queue_in().
 1757: 
 1758:         pid = getpid();
 1759:     }
 1760:     else
 1761:     {
 1762:         pid = origine_signal(signal);
 1763:     }
 1764: #   else
 1765:     if (siginfo != NULL)
 1766:     {
 1767:         pid = (*siginfo).si_pid;
 1768:     }
 1769:     else
 1770:     {
 1771:         pid = getpid();
 1772:     }
 1773: #   endif
 1774: 
 1775:     switch(signal)
 1776:     {
 1777:         case SIGALRM :
 1778:         {
 1779:             if (pid == getpid())
 1780:             {
 1781:                 if ((s_etat_processus = recherche_thread(getpid(),
 1782:                         pthread_self())) == NULL)
 1783:                 {
 1784:                     deverrouillage_gestionnaire_signaux();
 1785:                      return;
 1786:                 }
 1787: 
 1788:                 if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1789:                 {
 1790:                     printf("[%d] SIGALRM (thread %llu)\n", (int) getpid(),
 1791:                             (unsigned long long) pthread_self());
 1792:                     fflush(stdout);
 1793:                 }
 1794: 
 1795:                 if ((*s_etat_processus).pid_processus_pere != getpid())
 1796:                 {
 1797:                     kill((*s_etat_processus).pid_processus_pere, signal);
 1798:                 }
 1799:                 else
 1800:                 {
 1801:                     (*s_etat_processus).var_volatile_alarme = -1;
 1802:                     (*s_etat_processus).var_volatile_requete_arret = -1;
 1803:                 }
 1804:             }
 1805:             else
 1806:             {
 1807:                 if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 1808:                 {
 1809:                     pthread_kill(thread, signal);
 1810:                 }
 1811:             }
 1812: 
 1813:             break;
 1814:         }
 1815: 
 1816:         case SIGINT :
 1817:         case SIGTERM :
 1818:         {
 1819:             /*
 1820:              * Une vieille spécification POSIX permet au pointeur siginfo
 1821:              * d'être nul dans le cas d'un ^C envoyé depuis le clavier.
 1822:              * Solaris suit en particulier cette spécification.
 1823:              */
 1824: 
 1825: #           ifndef _BROKEN_SIGINFO
 1826:             if (siginfo == NULL)
 1827:             {
 1828:                 kill(getpid(), signal);
 1829:             }
 1830:             else
 1831: #           endif
 1832:             if (pid == getpid())
 1833:             {
 1834:                 if ((s_etat_processus = recherche_thread(getpid(),
 1835:                         pthread_self())) == NULL)
 1836:                 {
 1837:                     deverrouillage_gestionnaire_signaux();
 1838:                     return;
 1839:                 }
 1840: 
 1841:                 if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1842:                 {
 1843:                     if (signal == SIGINT)
 1844:                     {
 1845:                         printf("[%d] SIGINT (thread %llu)\n", (int) getpid(),
 1846:                                 (unsigned long long) pthread_self());
 1847:                     }
 1848:                     else
 1849:                     {
 1850:                         printf("[%d] SIGTERM (thread %llu)\n", (int) getpid(),
 1851:                                 (unsigned long long) pthread_self());
 1852:                     }
 1853: 
 1854:                     fflush(stdout);
 1855:                 }
 1856: 
 1857:                 if ((*s_etat_processus).pid_processus_pere != getpid())
 1858:                 {
 1859:                     kill((*s_etat_processus).pid_processus_pere, signal);
 1860:                 }
 1861:                 else
 1862:                 {
 1863:                     (*s_etat_processus).var_volatile_traitement_sigint = -1;
 1864: 
 1865:                     while(exclusion == 1);
 1866:                     exclusion = 1;
 1867: 
 1868:                     if ((*s_etat_processus).var_volatile_requete_arret == -1)
 1869:                     {
 1870:                         deverrouillage_gestionnaire_signaux();
 1871:                         exclusion = 0;
 1872:                         return;
 1873:                     }
 1874: 
 1875:                     if (signal == SIGINT)
 1876:                     {
 1877:                         if (strncmp(getenv("LANG"), "fr", 2) == 0)
 1878:                         {
 1879:                             printf("+++Interruption\n");
 1880:                         }
 1881:                         else
 1882:                         {
 1883:                             printf("+++Interrupt\n");
 1884:                         }
 1885: 
 1886:                         fflush(stdout);
 1887:                     }
 1888: 
 1889:                     (*s_etat_processus).var_volatile_requete_arret = -1;
 1890:                     (*s_etat_processus).var_volatile_alarme = -1;
 1891: 
 1892:                     exclusion = 0;
 1893:                 }
 1894:             }
 1895:             else
 1896:             {
 1897:                 if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 1898:                 {
 1899:                     pthread_kill(thread, signal);
 1900:                 }
 1901:             }
 1902: 
 1903:             break;
 1904:         }
 1905: 
 1906:         default :
 1907:         {
 1908:             BUG(1, uprintf("[%d] Unknown signal %d in this context\n",
 1909:                     (int) getpid(), signal));
 1910:             break;
 1911:         }
 1912:     }
 1913: 
 1914:     deverrouillage_gestionnaire_signaux();
 1915:     return;
 1916: }
 1917: 
 1918: void
 1919: interruption2(SIGHANDLER_ARGS)
 1920: {
 1921:     pid_t                   pid;
 1922: 
 1923:     pthread_t               thread;
 1924: 
 1925:     struct_processus        *s_etat_processus;
 1926: 
 1927:     verrouillage_gestionnaire_signaux();
 1928: 
 1929: #   ifdef _BROKEN_SIGINFO
 1930:     pid = origine_signal(signal);
 1931: #   else
 1932:     if (siginfo != NULL)
 1933:     {
 1934:         pid = (*siginfo).si_pid;
 1935:     }
 1936:     else
 1937:     {
 1938:         pid = getpid();
 1939:     }
 1940: #   endif
 1941: 
 1942: #   ifndef _BROKEN_SIGINFO
 1943:     if (siginfo == NULL)
 1944:     {
 1945:         /*
 1946:          * Le signal SIGFSTP provient de la mort du processus de contrôle.
 1947:          * Sous certains systèmes (Linux...), la mort du terminal de contrôle
 1948:          * se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
 1949:          * (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
 1950:          * non initialisée (pointeur NULL) issue de TERMIO.
 1951:          */
 1952: 
 1953:         if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 1954:         {
 1955:             pthread_kill(thread, SIGHUP);
 1956:             deverrouillage_gestionnaire_signaux();
 1957:             return;
 1958:         }
 1959:     }
 1960:     else
 1961: #   endif
 1962:     if (pid == getpid())
 1963:     {
 1964:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 1965:                 == NULL)
 1966:         {
 1967:             deverrouillage_gestionnaire_signaux();
 1968:             return;
 1969:         }
 1970: 
 1971:         /*
 1972:          *  0 => fonctionnement normal
 1973:          * -1 => requête
 1974:          *  1 => requête acceptée en attente de traitement
 1975:          */
 1976: 
 1977:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1978:         {
 1979:             printf("[%d] SIGTSTP (thread %llu)\n", (int) getpid(),
 1980:                     (unsigned long long) pthread_self());
 1981:             fflush(stdout);
 1982:         }
 1983: 
 1984:         if ((*s_etat_processus).var_volatile_processus_pere == 0)
 1985:         {
 1986:             kill((*s_etat_processus).pid_processus_pere, signal);
 1987:         }
 1988:         else
 1989:         {
 1990:             (*s_etat_processus).var_volatile_requete_arret2 = -1;
 1991:         }
 1992:     }
 1993:     else
 1994:     {
 1995:         // Envoi d'un signal au thread maître du groupe.
 1996: 
 1997:         if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 1998:         {
 1999:             pthread_kill(thread, SIGTSTP);
 2000:             deverrouillage_gestionnaire_signaux();
 2001:             return;
 2002:         }
 2003:     }
 2004: 
 2005:     deverrouillage_gestionnaire_signaux();
 2006:     return;
 2007: }
 2008: 
 2009: void
 2010: interruption3(SIGHANDLER_ARGS)
 2011: {
 2012:     pid_t                   pid;
 2013: 
 2014:     struct_processus        *s_etat_processus;
 2015: 
 2016:     static int              compteur = 0;
 2017: 
 2018:     verrouillage_gestionnaire_signaux();
 2019: 
 2020: #   ifdef _BROKEN_SIGINFO
 2021:     pid = origine_signal(signal);
 2022: #   else
 2023:     pid = (*siginfo).si_pid;
 2024: #   endif
 2025: 
 2026:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2027:     {
 2028:         deverrouillage_gestionnaire_signaux();
 2029:         return;
 2030:     }
 2031: 
 2032:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2033:     {
 2034:         printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),
 2035:                 (unsigned long long) pthread_self());
 2036:         fflush(stdout);
 2037:     }
 2038: 
 2039:     if ((*s_etat_processus).var_volatile_recursivite == -1)
 2040:     {
 2041:         // Segfault dans un appel de fonction récursive
 2042:         deverrouillage_gestionnaire_signaux();
 2043:         longjmp(contexte, -1);
 2044:     }
 2045:     else
 2046:     {
 2047:         // Segfault dans une routine interne
 2048:         if (strncmp(getenv("LANG"), "fr", 2) == 0)
 2049:         {
 2050:             printf("+++Système : Violation d'accès (dépassement de pile)\n");
 2051:         }
 2052:         else
 2053:         {
 2054:             printf("+++System : Access violation (stack overflow)\n");
 2055:         }
 2056: 
 2057:         fflush(stdout);
 2058: 
 2059:         compteur++;
 2060: 
 2061:         if (compteur > 1)
 2062:         {
 2063:             deverrouillage_gestionnaire_signaux();
 2064:             exit(EXIT_FAILURE);
 2065:         }
 2066:         else
 2067:         {
 2068:             deverrouillage_gestionnaire_signaux();
 2069:             longjmp(contexte_initial, -1);
 2070:         }
 2071:     }
 2072: 
 2073:     deverrouillage_gestionnaire_signaux();
 2074:     return;
 2075: }
 2076: 
 2077: void
 2078: interruption4(SIGHANDLER_ARGS)
 2079: {
 2080:     pid_t                   pid;
 2081: 
 2082:     struct_processus        *s_etat_processus;
 2083: 
 2084:     verrouillage_gestionnaire_signaux();
 2085: 
 2086: #   ifdef _BROKEN_SIGINFO
 2087:     pid = origine_signal(signal);
 2088: #   else
 2089:     pid = (*siginfo).si_pid;
 2090: #   endif
 2091: 
 2092:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2093:     {
 2094:         deverrouillage_gestionnaire_signaux();
 2095:         return;
 2096:     }
 2097: 
 2098:     /*
 2099:      * Démarrage d'un processus fils ou gestion de SIGCONT (SUSPEND)
 2100:      */
 2101: 
 2102:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2103:     {
 2104:         printf("[%d] SIGSTART/SIGCONT (thread %llu)\n", (int) getpid(),
 2105:                 (unsigned long long) pthread_self());
 2106:         fflush(stdout);
 2107:     }
 2108: 
 2109:     deverrouillage_gestionnaire_signaux();
 2110:     return;
 2111: }
 2112: 
 2113: void
 2114: interruption5(SIGHANDLER_ARGS)
 2115: {
 2116:     pid_t                   pid;
 2117: 
 2118:     pthread_t               thread;
 2119: 
 2120:     struct_processus        *s_etat_processus;
 2121: 
 2122:     verrouillage_gestionnaire_signaux();
 2123: 
 2124: #   ifdef _BROKEN_SIGINFO
 2125:     pid = origine_signal(signal);
 2126: #   else
 2127:     pid = (*siginfo).si_pid;
 2128: #   endif
 2129: 
 2130:     if (pid == getpid())
 2131:     {
 2132:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 2133:                 == NULL)
 2134:         {
 2135:             deverrouillage_gestionnaire_signaux();
 2136:             return;
 2137:         }
 2138: 
 2139:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2140:         {
 2141:             printf("[%d] SIGFSTOP (thread %llu)\n", (int) getpid(),
 2142:                     (unsigned long long) pthread_self());
 2143:             fflush(stdout);
 2144:         }
 2145: 
 2146:         /*
 2147:          * var_globale_traitement_retarde_stop :
 2148:          *  0 -> traitement immédiat
 2149:          *  1 -> traitement retardé (aucun signal reçu)
 2150:          * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
 2151:          */
 2152: 
 2153:         if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
 2154:         {
 2155:             (*s_etat_processus).var_volatile_requete_arret = -1;
 2156:         }
 2157:         else
 2158:         {
 2159:             (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
 2160:         }
 2161:     }
 2162:     else
 2163:     {
 2164:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 2165:                 == NULL)
 2166:         {
 2167:             deverrouillage_gestionnaire_signaux();
 2168:             return;
 2169:         }
 2170: 
 2171:         // Envoi d'un signal au thread maître du groupe.
 2172: 
 2173:         if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 2174:         {
 2175:             pthread_kill(thread, signal);
 2176:             deverrouillage_gestionnaire_signaux();
 2177:             return;
 2178:         }
 2179:     }
 2180: 
 2181:     deverrouillage_gestionnaire_signaux();
 2182:     return;
 2183: }
 2184: 
 2185: void
 2186: interruption6(SIGHANDLER_ARGS)
 2187: {
 2188:     pid_t                   pid;
 2189: 
 2190:     struct_processus        *s_etat_processus;
 2191: 
 2192:     verrouillage_gestionnaire_signaux();
 2193: 
 2194: #   ifdef _BROKEN_SIGINFO
 2195:     pid = origine_signal(signal);
 2196: #   else
 2197:     pid = (*siginfo).si_pid;
 2198: #   endif
 2199: 
 2200:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2201:     {
 2202:         deverrouillage_gestionnaire_signaux();
 2203:         return;
 2204:     }
 2205: 
 2206:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2207:     {
 2208:         printf("[%d] SIGINJECT/SIGQUIT (thread %llu)\n", (int) getpid(),
 2209:                 (unsigned long long) pthread_self());
 2210:         fflush(stdout);
 2211:     }
 2212: 
 2213:     deverrouillage_gestionnaire_signaux();
 2214:     return;
 2215: }
 2216: 
 2217: void
 2218: interruption7(SIGHANDLER_ARGS)
 2219: {
 2220:     pid_t                   pid;
 2221: 
 2222:     struct_processus        *s_etat_processus;
 2223: 
 2224:     verrouillage_gestionnaire_signaux();
 2225: 
 2226: #   ifdef _BROKEN_SIGINFO
 2227:     pid = origine_signal(signal);
 2228: #   else
 2229:     pid = (*siginfo).si_pid;
 2230: #   endif
 2231: 
 2232:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2233:     {
 2234:         deverrouillage_gestionnaire_signaux();
 2235:         return;
 2236:     }
 2237: 
 2238:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2239:     {
 2240:         printf("[%d] SIGPIPE (thread %llu)\n", (int) getpid(),
 2241:                 (unsigned long long) pthread_self());
 2242:         fflush(stdout);
 2243:     }
 2244: 
 2245:     (*s_etat_processus).var_volatile_requete_arret = -1;
 2246:     deverrouillage_gestionnaire_signaux();
 2247: 
 2248:     BUG(1, printf("[%d] SIGPIPE\n", (int) getpid()));
 2249:     return;
 2250: }
 2251: 
 2252: void
 2253: interruption8(SIGHANDLER_ARGS)
 2254: {
 2255:     pid_t                   pid;
 2256: 
 2257:     pthread_t               thread;
 2258: 
 2259:     struct_processus        *s_etat_processus;
 2260: 
 2261:     verrouillage_gestionnaire_signaux();
 2262: 
 2263: #   ifdef _BROKEN_SIGINFO
 2264:     pid = origine_signal(signal);
 2265: #   else
 2266:     pid = (*siginfo).si_pid;
 2267: #   endif
 2268: 
 2269:     if (pid == getpid())
 2270:     {
 2271:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 2272:                 == NULL)
 2273:         {
 2274:             deverrouillage_gestionnaire_signaux();
 2275:             return;
 2276:         }
 2277: 
 2278:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2279:         {
 2280:             printf("[%d] SIGURG (thread %llu)\n", (int) getpid(),
 2281:                     (unsigned long long) pthread_self());
 2282:             fflush(stdout);
 2283:         }
 2284: 
 2285:         (*s_etat_processus).var_volatile_alarme = -1;
 2286:         (*s_etat_processus).var_volatile_requete_arret = -1;
 2287:     }
 2288:     else
 2289:     {
 2290:         // Envoi d'un signal au thread maître du groupe.
 2291: 
 2292:         if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 2293:         {
 2294:             pthread_kill(thread, SIGURG);
 2295:             deverrouillage_gestionnaire_signaux();
 2296:             return;
 2297:         }
 2298:     }
 2299: 
 2300:     deverrouillage_gestionnaire_signaux();
 2301:     return;
 2302: }
 2303: 
 2304: void
 2305: interruption9(SIGHANDLER_ARGS)
 2306: {
 2307:     pid_t                   pid;
 2308: 
 2309:     struct_processus        *s_etat_processus;
 2310: 
 2311:     verrouillage_gestionnaire_signaux();
 2312: 
 2313: #   ifdef _BROKEN_SIGINFO
 2314:     pid = origine_signal(signal);
 2315: #   else
 2316:     pid = (*siginfo).si_pid;
 2317: #   endif
 2318: 
 2319:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2320:     {
 2321:         deverrouillage_gestionnaire_signaux();
 2322:         return;
 2323:     }
 2324: 
 2325:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2326:     {
 2327:         printf("[%d] SIGABORT/SIGPROF (thread %llu)\n", (int) getpid(),
 2328:                 (unsigned long long) pthread_self());
 2329:         fflush(stdout);
 2330:     }
 2331: 
 2332: #   ifdef _BROKEN_SIGINFO
 2333:     if (queue_in(getpid(), signal) != 0)
 2334:     {
 2335:         return;
 2336:     }
 2337: 
 2338:     deverrouillage_gestionnaire_signaux();
 2339:     interruption11(signal);
 2340: #   else
 2341:     deverrouillage_gestionnaire_signaux();
 2342:     interruption11(signal, siginfo, context);
 2343: #   endif
 2344:     return;
 2345: }
 2346: 
 2347: void
 2348: interruption10(SIGHANDLER_ARGS)
 2349: {
 2350:     file                    *fichier;
 2351: 
 2352:     pid_t                   pid;
 2353: 
 2354:     struct_processus        *s_etat_processus;
 2355: 
 2356:     unsigned char           nom[8 + 64 + 1];
 2357: 
 2358:     verrouillage_gestionnaire_signaux();
 2359: 
 2360: #   ifdef _BROKEN_SIGINFO
 2361:     pid = origine_signal(signal);
 2362: #   else
 2363:     pid = (*siginfo).si_pid;
 2364: #   endif
 2365: 
 2366:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2367:     {
 2368:         deverrouillage_gestionnaire_signaux();
 2369:         return;
 2370:     }
 2371: 
 2372:     snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
 2373:             (unsigned long) pthread_self());
 2374: 
 2375:     if ((fichier = fopen(nom, "w+")) != NULL)
 2376:     {
 2377:         fclose(fichier);
 2378: 
 2379:         freopen(nom, "w", stdout);
 2380:         freopen(nom, "w", stderr);
 2381:     }
 2382: 
 2383:     freopen("/dev/null", "r", stdin);
 2384: 
 2385:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2386:     {
 2387:         printf("[%d] SIGHUP (thread %llu)\n", (int) getpid(),
 2388:                 (unsigned long long) pthread_self());
 2389:         fflush(stdout);
 2390:     }
 2391: 
 2392:     deverrouillage_gestionnaire_signaux();
 2393:     return;
 2394: }
 2395: 
 2396: void
 2397: interruption11(SIGHANDLER_ARGS)
 2398: {
 2399:     pid_t                   pid;
 2400: 
 2401:     pthread_t               thread;
 2402: 
 2403:     struct_processus        *s_etat_processus;
 2404: 
 2405:     verrouillage_gestionnaire_signaux();
 2406: 
 2407: #   ifdef _BROKEN_SIGINFO
 2408:     pid = origine_signal(signal);
 2409: #   else
 2410:     pid = (*siginfo).si_pid;
 2411: #   endif
 2412: 
 2413:     if (pid == getpid())
 2414:     {
 2415:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 2416:                 == NULL)
 2417:         {
 2418:             deverrouillage_gestionnaire_signaux();
 2419:             return;
 2420:         }
 2421: 
 2422:         (*s_etat_processus).arret_depuis_abort = -1;
 2423: 
 2424:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2425:         {
 2426:             printf("[%d] SIGFABORT (thread %llu)\n", (int) getpid(),
 2427:                     (unsigned long long) pthread_self());
 2428:             fflush(stdout);
 2429:         }
 2430: 
 2431:         /*
 2432:          * var_globale_traitement_retarde_stop :
 2433:          *  0 -> traitement immédiat
 2434:          *  1 -> traitement retardé (aucun signal reçu)
 2435:          * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
 2436:          */
 2437: 
 2438:         if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
 2439:         {
 2440:             (*s_etat_processus).var_volatile_requete_arret = -1;
 2441:         }
 2442:         else
 2443:         {
 2444:             (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
 2445:         }
 2446:     }
 2447:     else
 2448:     {
 2449:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 2450:                 == NULL)
 2451:         {
 2452:             deverrouillage_gestionnaire_signaux();
 2453:             return;
 2454:         }
 2455: 
 2456:         (*s_etat_processus).arret_depuis_abort = -1;
 2457: 
 2458:         // Envoi d'un signal au thread maître du groupe.
 2459: 
 2460:         if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 2461:         {
 2462:             pthread_kill(thread, signal);
 2463:             deverrouillage_gestionnaire_signaux();
 2464:             return;
 2465:         }
 2466:     }
 2467: 
 2468:     deverrouillage_gestionnaire_signaux();
 2469:     return;
 2470: }
 2471: 
 2472: void
 2473: traitement_exceptions_gsl(const char *reason, const char *file,
 2474:         int line, int gsl_errno)
 2475: {
 2476:     struct_processus        *s_etat_processus;
 2477: 
 2478:     verrouillage_gestionnaire_signaux();
 2479: 
 2480:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2481:     {
 2482:         deverrouillage_gestionnaire_signaux();
 2483:         return;
 2484:     }
 2485: 
 2486:     (*s_etat_processus).var_volatile_exception_gsl = gsl_errno;
 2487:     deverrouillage_gestionnaire_signaux();
 2488:     return;
 2489: }
 2490: 
 2491: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>