File:  [local] / rpl / src / interruptions.c
Revision 1.33: download - view: text, annotated - select for diffs - revision graph
Sun Aug 22 16:38:36 2010 UTC (13 years, 8 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Patches pour les systèmes qui cassent siginfo_t.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.0.18
    4:   Copyright (C) 1989-2010 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));
  187:     (*s_argument_thread).nombre_references++;
  188:     pthread_mutex_unlock(&((*s_argument_thread).mutex));
  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)) != 0)
  382:     {
  383: #       ifndef SEMAPHORES_NOMMES
  384:         sem_post(&semaphore_liste_threads);
  385: #       else
  386:         sem_post(semaphore_liste_threads);
  387: #       endif
  388:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  389:         sigpending(&set);
  390: 
  391:         (*s_etat_processus).erreur_systeme = d_es_processus;
  392:         return;
  393:     }
  394: 
  395:     (*s_argument_thread).nombre_references--;
  396: 
  397:     BUG((*s_argument_thread).nombre_references < 0,
  398:             printf("(*s_argument_thread).nombre_references = %d\n",
  399:             (int) (*s_argument_thread).nombre_references));
  400: 
  401:     if ((*s_argument_thread).nombre_references == 0)
  402:     {
  403:         if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
  404:         {
  405: #           ifndef SEMAPHORES_NOMMES
  406:             sem_post(&semaphore_liste_threads);
  407: #           else
  408:             sem_post(semaphore_liste_threads);
  409: #           endif
  410:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  411:             sigpending(&set);
  412: 
  413:             (*s_etat_processus).erreur_systeme = d_es_processus;
  414:             return;
  415:         }
  416: 
  417:         pthread_mutex_destroy(&((*s_argument_thread).mutex));
  418:         free(s_argument_thread);
  419:     }
  420:     else
  421:     {
  422:         if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
  423:         {
  424: #           ifndef SEMAPHORES_NOMMES
  425:             sem_post(&semaphore_liste_threads);
  426: #           else
  427:             sem_post(semaphore_liste_threads);
  428: #           endif
  429:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  430:             sigpending(&set);
  431: 
  432:             (*s_etat_processus).erreur_systeme = d_es_processus;
  433:             return;
  434:         }
  435:     }
  436: 
  437: #   ifndef SEMAPHORES_NOMMES
  438:     if (sem_post(&semaphore_liste_threads) != 0)
  439: #   else
  440:     if (sem_post(semaphore_liste_threads) != 0)
  441: #   endif
  442:     {
  443:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  444:         sigpending(&set);
  445: 
  446:         (*s_etat_processus).erreur_systeme = d_es_processus;
  447:         return;
  448:     }
  449: 
  450:     free((struct_liste_chainee_volatile *) l_element_courant);
  451: 
  452:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  453:     sigpending(&set);
  454: 
  455:     return;
  456: }
  457: 
  458: void
  459: verrouillage_threads_concurrents(struct_processus *s_etat_processus)
  460: {
  461:     volatile struct_liste_chainee_volatile  *l_element_courant;
  462: 
  463: #   ifndef SEMAPHORES_NOMMES
  464:     while(sem_wait(&semaphore_liste_threads) == -1)
  465: #   else
  466:     while(sem_wait(semaphore_liste_threads) == -1)
  467: #   endif
  468:     {
  469:         if (errno != EINTR)
  470:         {
  471:             (*s_etat_processus).erreur_systeme = d_es_processus;
  472:             return;
  473:         }
  474:     }
  475: 
  476:     l_element_courant = liste_threads;
  477: 
  478:     while(l_element_courant != NULL)
  479:     {
  480:         if (((*((struct_thread *) (*l_element_courant).donnee)).pid
  481:                 == getpid()) && (pthread_equal((*((struct_thread *)
  482:                 (*l_element_courant).donnee)).tid, pthread_self()) == 0))
  483:         {
  484: #           ifndef SEMAPHORES_NOMMES
  485:             while(sem_wait(&((*(*((struct_thread *) (*l_element_courant)
  486:                     .donnee)).s_etat_processus).semaphore_fork)) == -1)
  487: #           else
  488:             while(sem_wait((*(*((struct_thread *) (*l_element_courant)
  489:                     .donnee)).s_etat_processus).semaphore_fork) == -1)
  490: #           endif
  491:             {
  492:                 if (errno != EINTR)
  493:                 {
  494:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  495:                     return;
  496:                 }
  497:             }
  498:         }
  499: 
  500:         l_element_courant = (*l_element_courant).suivant;
  501:     }
  502: 
  503:     return;
  504: }
  505: 
  506: void
  507: deverrouillage_threads_concurrents(struct_processus *s_etat_processus)
  508: {
  509:     volatile struct_liste_chainee_volatile  *l_element_courant;
  510: 
  511:     l_element_courant = liste_threads;
  512: 
  513:     while(l_element_courant != NULL)
  514:     {
  515:         if (((*((struct_thread *) (*l_element_courant).donnee)).pid
  516:                 == getpid()) && (pthread_equal((*((struct_thread *)
  517:                 (*l_element_courant).donnee)).tid, pthread_self()) == 0))
  518:         {
  519: #           ifndef SEMAPHORES_NOMMES
  520:             if (sem_post(&((*(*((struct_thread *)
  521:                     (*l_element_courant).donnee)).s_etat_processus)
  522:                     .semaphore_fork)) != 0)
  523: #           else
  524:             if (sem_post((*(*((struct_thread *)
  525:                     (*l_element_courant).donnee)).s_etat_processus)
  526:                     .semaphore_fork) != 0)
  527: #           endif
  528:             {
  529: #               ifndef SEMAPHORES_NOMMES
  530:                 if (sem_post(&semaphore_liste_threads) != 0)
  531:                 {
  532:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  533:                     return;
  534:                 }
  535: #               else
  536:                 if (sem_post(semaphore_liste_threads) != 0)
  537:                 {
  538:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  539:                     return;
  540:                 }
  541: #               endif
  542: 
  543:                 (*s_etat_processus).erreur_systeme = d_es_processus;
  544:                 return;
  545:             }
  546:         }
  547: 
  548:         l_element_courant = (*l_element_courant).suivant;
  549:     }
  550: 
  551: #   ifndef SEMAPHORES_NOMMES
  552:     if (sem_post(&semaphore_liste_threads) != 0)
  553: #   else
  554:     if (sem_post(semaphore_liste_threads) != 0)
  555: #   endif
  556:     {
  557:         (*s_etat_processus).erreur_systeme = d_es_processus;
  558:         return;
  559:     }
  560: 
  561:     return;
  562: }
  563: 
  564: void
  565: liberation_threads(struct_processus *s_etat_processus)
  566: {
  567:     logical1                                    suppression_variables_partagees;
  568: 
  569:     sigset_t                                    oldset;
  570:     sigset_t                                    set;
  571: 
  572:     struct_descripteur_thread                   *s_argument_thread;
  573: 
  574:     struct_processus                            *candidat;
  575: 
  576:     unsigned long                               i;
  577: 
  578:     void                                        *element_candidat;
  579:     void                                        *element_courant;
  580:     void                                        *element_suivant;
  581: 
  582:     volatile struct_liste_chainee_volatile      *l_element_courant;
  583:     volatile struct_liste_chainee_volatile      *l_element_suivant;
  584: 
  585:     sigfillset(&set);
  586:     pthread_sigmask(SIG_BLOCK, &set, &oldset);
  587: 
  588: #   ifndef SEMAPHORES_NOMMES
  589:     while(sem_wait(&semaphore_liste_threads) == -1)
  590: #   else
  591:     while(sem_wait(semaphore_liste_threads) == -1)
  592: #   endif
  593:     {
  594:         if (errno != EINTR)
  595:         {
  596:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  597:             (*s_etat_processus).erreur_systeme = d_es_processus;
  598:             return;
  599:         }
  600:     }
  601: 
  602:     l_element_courant = liste_threads;
  603:     suppression_variables_partagees = d_faux;
  604: 
  605:     while(l_element_courant != NULL)
  606:     {
  607:         if ((*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus
  608:                 != s_etat_processus)
  609:         {
  610:             candidat = s_etat_processus;
  611:             s_etat_processus = (*((struct_thread *)
  612:                     (*l_element_courant).donnee)).s_etat_processus;
  613:             free((*s_etat_processus).localisation);
  614: 
  615:             // (*s_etat_processus).instruction_courante peut pointer sur
  616:             // n'importe quoi (une instruction courante ou un champ d'une
  617:             // structure objet). On ne le libère pas quitte à avoir une
  618:             // petite fuite mémoire dans le processus fils.
  619: 
  620:             if ((*s_etat_processus).instruction_courante != NULL)
  621:             {
  622:                 //free((*s_etat_processus).instruction_courante);
  623:             }
  624: 
  625:             close((*s_etat_processus).pipe_acquittement);
  626:             close((*s_etat_processus).pipe_donnees);
  627:             close((*s_etat_processus).pipe_injections);
  628:             close((*s_etat_processus).pipe_nombre_injections);
  629:             close((*s_etat_processus).pipe_interruptions);
  630:             close((*s_etat_processus).pipe_nombre_objets_attente);
  631:             close((*s_etat_processus).pipe_nombre_interruptions_attente);
  632: 
  633:             liberation(s_etat_processus, (*s_etat_processus).at_exit);
  634: 
  635:             if ((*s_etat_processus).nom_fichier_impression != NULL)
  636:             {
  637:                 free((*s_etat_processus).nom_fichier_impression);
  638:             }
  639: 
  640:             while((*s_etat_processus).fichiers_graphiques != NULL)
  641:             {
  642:                 free((*(*s_etat_processus).fichiers_graphiques).nom);
  643: 
  644:                 if ((*(*s_etat_processus).fichiers_graphiques).legende != NULL)
  645:                 {
  646:                     free((*(*s_etat_processus).fichiers_graphiques).legende);
  647:                 }
  648: 
  649:                 element_courant = (*s_etat_processus).fichiers_graphiques;
  650:                 (*s_etat_processus).fichiers_graphiques =
  651:                         (*(*s_etat_processus).fichiers_graphiques).suivant;
  652: 
  653:                 free(element_courant);
  654:             }
  655: 
  656:             if ((*s_etat_processus).entree_standard != NULL)
  657:             {
  658:                 pclose((*s_etat_processus).entree_standard);
  659:             }
  660: 
  661:             if ((*s_etat_processus).generateur_aleatoire != NULL)
  662:             {
  663:                 liberation_generateur_aleatoire(s_etat_processus);
  664:             }
  665: 
  666:             if ((*s_etat_processus).instruction_derniere_erreur != NULL)
  667:             {
  668:                 free((*s_etat_processus).instruction_derniere_erreur);
  669:                 (*s_etat_processus).instruction_derniere_erreur = NULL;
  670:             }
  671: 
  672:             element_courant = (void *) (*s_etat_processus)
  673:                     .l_base_pile_processus;
  674:             while(element_courant != NULL)
  675:             {
  676:                 s_argument_thread = (struct_descripteur_thread *)
  677:                         (*((struct_liste_chainee *) element_courant)).donnee;
  678: 
  679:                 if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)
  680:                 {
  681:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  682:                     sem_post(&semaphore_liste_threads);
  683:                     return;
  684:                 }
  685: 
  686:                 (*s_argument_thread).nombre_references--;
  687: 
  688:                 BUG((*s_argument_thread).nombre_references < 0,
  689:                         printf("(*s_argument_thread).nombre_references = %d\n",
  690:                         (int) (*s_argument_thread).nombre_references));
  691: 
  692:                 if ((*s_argument_thread).nombre_references == 0)
  693:                 {
  694:                     close((*s_argument_thread).pipe_objets[0]);
  695:                     close((*s_argument_thread).pipe_acquittement[1]);
  696:                     close((*s_argument_thread).pipe_injections[1]);
  697:                     close((*s_argument_thread).pipe_nombre_injections[1]);
  698:                     close((*s_argument_thread).pipe_nombre_objets_attente[0]);
  699:                     close((*s_argument_thread).pipe_interruptions[0]);
  700:                     close((*s_argument_thread)
  701:                             .pipe_nombre_interruptions_attente[0]);
  702: 
  703:                     if (pthread_mutex_unlock(&((*s_argument_thread).mutex))
  704:                             != 0)
  705:                     {
  706:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  707:                         sem_post(&semaphore_liste_threads);
  708:                         return;
  709:                     }
  710: 
  711:                     pthread_mutex_destroy(&((*s_argument_thread).mutex));
  712: 
  713:                     if ((*s_argument_thread).processus_detache == d_faux)
  714:                     {
  715:                         if ((*s_argument_thread).destruction_objet == d_vrai)
  716:                         {
  717:                             liberation(s_etat_processus, (*s_argument_thread)
  718:                                     .argument);
  719:                         }
  720:                     }
  721: 
  722:                     free(s_argument_thread);
  723:                 }
  724:                 else
  725:                 {
  726:                     if (pthread_mutex_unlock(&((*s_argument_thread).mutex))
  727:                             != 0)
  728:                     {
  729:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  730:                         sem_post(&semaphore_liste_threads);
  731:                         return;
  732:                     }
  733:                 }
  734: 
  735:                 element_suivant = (*((struct_liste_chainee *) element_courant))
  736:                         .suivant;
  737:                 free(element_courant);
  738:                 element_courant = element_suivant;
  739:             }
  740: 
  741:             (*s_etat_processus).l_base_pile_processus = NULL;
  742: 
  743:             pthread_mutex_trylock(&((*(*s_etat_processus).indep).mutex));
  744:             pthread_mutex_unlock(&((*(*s_etat_processus).indep).mutex));
  745:             liberation(s_etat_processus, (*s_etat_processus).indep);
  746: 
  747:             pthread_mutex_trylock(&((*(*s_etat_processus).depend).mutex));
  748:             pthread_mutex_unlock(&((*(*s_etat_processus).depend).mutex));
  749:             liberation(s_etat_processus, (*s_etat_processus).depend);
  750: 
  751:             free((*s_etat_processus).label_x);
  752:             free((*s_etat_processus).label_y);
  753:             free((*s_etat_processus).label_z);
  754:             free((*s_etat_processus).titre);
  755:             free((*s_etat_processus).legende);
  756: 
  757:             pthread_mutex_trylock(&((*(*s_etat_processus)
  758:                     .parametres_courbes_de_niveau).mutex));
  759:             pthread_mutex_unlock(&((*(*s_etat_processus)
  760:                     .parametres_courbes_de_niveau).mutex));
  761:             liberation(s_etat_processus, (*s_etat_processus)
  762:                     .parametres_courbes_de_niveau);
  763: 
  764:             for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++)
  765:             {
  766:                 if ((*s_etat_processus).corps_interruptions[i] != NULL)
  767:                 {
  768:                     pthread_mutex_trylock(&((*(*s_etat_processus)
  769:                             .corps_interruptions[i]).mutex));
  770:                     pthread_mutex_unlock(&((*(*s_etat_processus)
  771:                             .corps_interruptions[i]).mutex));
  772: 
  773:                     liberation(s_etat_processus,
  774:                             (*s_etat_processus).corps_interruptions[i]);
  775:                 }
  776: 
  777:                 element_courant = (*s_etat_processus)
  778:                         .pile_origine_interruptions[i];
  779: 
  780:                 while(element_courant != NULL)
  781:                 {
  782:                     element_suivant = (*((struct_liste_chainee *)
  783:                             element_courant)).suivant;
  784: 
  785:                     pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  786:                             element_courant)).donnee).mutex));
  787:                     pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  788:                             element_courant)).donnee).mutex));
  789: 
  790:                     liberation(s_etat_processus,
  791:                             (*((struct_liste_chainee *) element_courant))
  792:                             .donnee);
  793:                     free(element_courant);
  794: 
  795:                     element_courant = element_suivant;
  796:                 }
  797:             }
  798: 
  799:             for(i = 0; i < (*s_etat_processus).nombre_variables; i++)
  800:             {
  801:                 pthread_mutex_trylock(&((*(*s_etat_processus)
  802:                         .s_liste_variables[i].objet).mutex));
  803:                 pthread_mutex_unlock(&((*(*s_etat_processus)
  804:                         .s_liste_variables[i].objet).mutex));
  805: 
  806:                 // Les variables de niveau 0 sont des définitions qui
  807:                 // ne sont pas copiées entre threads.
  808:                 if ((*s_etat_processus).s_liste_variables[i].niveau > 0)
  809:                 {
  810:                     liberation(s_etat_processus,
  811:                             (*s_etat_processus).s_liste_variables[i].objet);
  812:                 }
  813: 
  814:                 free((*s_etat_processus).s_liste_variables[i].nom);
  815:             }
  816: 
  817:             free((*s_etat_processus).s_liste_variables);
  818: 
  819:             for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)
  820:             {
  821:                 pthread_mutex_trylock(&((*(*s_etat_processus)
  822:                         .s_liste_variables_statiques[i].objet).mutex));
  823:                 pthread_mutex_unlock(&((*(*s_etat_processus)
  824:                         .s_liste_variables_statiques[i].objet).mutex));
  825: 
  826:                 liberation(s_etat_processus, (*s_etat_processus)
  827:                         .s_liste_variables_statiques[i].objet);
  828:                 free((*s_etat_processus).s_liste_variables_statiques[i].nom);
  829:             }
  830: 
  831:             free((*s_etat_processus).s_liste_variables_statiques);
  832: 
  833:             // Ne peut être effacé qu'une seule fois
  834:             if (suppression_variables_partagees == d_faux)
  835:             {
  836:                 suppression_variables_partagees = d_vrai;
  837: 
  838:                 for(i = 0; i < (*(*s_etat_processus)
  839:                         .s_liste_variables_partagees).nombre_variables; i++)
  840:                 {
  841:                     pthread_mutex_trylock(&((*(*(*s_etat_processus)
  842:                             .s_liste_variables_partagees).table[i].objet)
  843:                             .mutex));
  844:                     pthread_mutex_unlock(&((*(*(*s_etat_processus)
  845:                             .s_liste_variables_partagees).table[i].objet)
  846:                             .mutex));
  847: 
  848:                     liberation(s_etat_processus, (*(*s_etat_processus)
  849:                             .s_liste_variables_partagees).table[i].objet);
  850:                     free((*(*s_etat_processus).s_liste_variables_partagees)
  851:                             .table[i].nom);
  852:                 }
  853: 
  854:                 if ((*(*s_etat_processus).s_liste_variables_partagees).table
  855:                         != NULL)
  856:                 {
  857:                     free((struct_variable_partagee *) (*(*s_etat_processus)
  858:                             .s_liste_variables_partagees).table);
  859:                 }
  860: 
  861:                 pthread_mutex_trylock(&((*(*s_etat_processus)
  862:                         .s_liste_variables_partagees).mutex));
  863:                 pthread_mutex_unlock(&((*(*s_etat_processus)
  864:                         .s_liste_variables_partagees).mutex));
  865:             }
  866: 
  867:             element_courant = (*s_etat_processus).l_base_pile;
  868:             while(element_courant != NULL)
  869:             {
  870:                 element_suivant = (*((struct_liste_chainee *)
  871:                         element_courant)).suivant;
  872: 
  873:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  874:                         element_courant)).donnee).mutex));
  875:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  876:                         element_courant)).donnee).mutex));
  877: 
  878:                 liberation(s_etat_processus,
  879:                         (*((struct_liste_chainee *)
  880:                         element_courant)).donnee);
  881:                 free((struct_liste_chainee *) element_courant);
  882: 
  883:                 element_courant = element_suivant;
  884:             }
  885: 
  886:             element_courant = (*s_etat_processus).l_base_pile_contextes;
  887:             while(element_courant != NULL)
  888:             {
  889:                 element_suivant = (*((struct_liste_chainee *)
  890:                         element_courant)).suivant;
  891: 
  892:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  893:                         element_courant)).donnee).mutex));
  894:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  895:                         element_courant)).donnee).mutex));
  896:                 liberation(s_etat_processus, (*((struct_liste_chainee *)
  897:                         element_courant)).donnee);
  898:                 free((struct_liste_chainee *) element_courant);
  899: 
  900:                 element_courant = element_suivant;
  901:             }
  902: 
  903:             element_courant = (*s_etat_processus).l_base_pile_taille_contextes;
  904:             while(element_courant != NULL)
  905:             {
  906:                 element_suivant = (*((struct_liste_chainee *)
  907:                         element_courant)).suivant;
  908: 
  909:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  910:                         element_courant)).donnee).mutex));
  911:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  912:                         element_courant)).donnee).mutex));
  913:                 liberation(s_etat_processus,
  914:                         (*((struct_liste_chainee *)
  915:                         element_courant)).donnee);
  916:                 free((struct_liste_chainee *) element_courant);
  917: 
  918:                 element_courant = element_suivant;
  919:             }
  920: 
  921:             for(i = 0; i < (*s_etat_processus).nombre_instructions_externes;
  922:                     i++)
  923:             {
  924:                 free((*s_etat_processus).s_instructions_externes[i].nom);
  925:                 free((*s_etat_processus).s_instructions_externes[i]
  926:                         .nom_bibliotheque);
  927:             }
  928: 
  929:             if ((*s_etat_processus).nombre_instructions_externes != 0)
  930:             {
  931:                 free((*s_etat_processus).s_instructions_externes);
  932:             }
  933: 
  934:             element_courant = (*s_etat_processus).s_bibliotheques;
  935:             while(element_courant != NULL)
  936:             {
  937:                 element_suivant = (*((struct_liste_chainee *)
  938:                         element_courant)).suivant;
  939: 
  940:                 element_candidat = (*candidat).s_bibliotheques;
  941:                 while(element_candidat != NULL)
  942:                 {
  943:                     if (((*((struct_bibliotheque *) (*((struct_liste_chainee *)
  944:                             element_courant)).donnee))
  945:                             .descripteur == (*((struct_bibliotheque *)
  946:                             (*((struct_liste_chainee *) element_candidat))
  947:                             .donnee)).descripteur) &&
  948:                             ((*((struct_bibliotheque *)
  949:                             (*((struct_liste_chainee *) element_courant))
  950:                             .donnee)).pid == (*((struct_bibliotheque *)
  951:                             (*((struct_liste_chainee *) element_candidat))
  952:                             .donnee)).pid) && (pthread_equal(
  953:                             (*((struct_bibliotheque *)
  954:                             (*((struct_liste_chainee *) element_courant))
  955:                             .donnee)).tid, (*((struct_bibliotheque *)
  956:                             (*((struct_liste_chainee *) element_candidat))
  957:                             .donnee)).tid) != 0))
  958:                     {
  959:                         break;
  960:                     }
  961: 
  962:                     element_candidat = (*((struct_liste_chainee *)
  963:                             element_candidat)).suivant;
  964:                 }
  965: 
  966:                 if (element_candidat == NULL)
  967:                 {
  968:                     dlclose((*((struct_bibliotheque *)
  969:                             (*((struct_liste_chainee *) element_courant))
  970:                             .donnee)).descripteur);
  971:                 }
  972: 
  973:                 free((*((struct_bibliotheque *)
  974:                         (*((struct_liste_chainee *)
  975:                         element_courant)).donnee)).nom);
  976:                 free((*((struct_liste_chainee *) element_courant)).donnee);
  977:                 free(element_courant);
  978: 
  979:                 element_courant = element_suivant;
  980:             }
  981: 
  982:             element_courant = (*s_etat_processus).l_base_pile_last;
  983:             while(element_courant != NULL)
  984:             {
  985:                 element_suivant = (*((struct_liste_chainee *)
  986:                         element_courant)).suivant;
  987: 
  988:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  989:                         element_courant)).donnee).mutex));
  990:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  991:                         element_courant)).donnee).mutex));
  992:                 liberation(s_etat_processus,
  993:                         (*((struct_liste_chainee *) element_courant)).donnee);
  994:                 free(element_courant);
  995: 
  996:                 element_courant = element_suivant;
  997:             }
  998: 
  999:             element_courant = (*s_etat_processus).l_base_pile_systeme;
 1000:             while(element_courant != NULL)
 1001:             {
 1002:                 element_suivant = (*((struct_liste_pile_systeme *)
 1003:                         element_courant)).suivant;
 1004: 
 1005:                 if ((*((struct_liste_pile_systeme *)
 1006:                         element_courant)).indice_boucle != NULL)
 1007:                 {
 1008:                     pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
 1009:                             element_courant)).indice_boucle).mutex));
 1010:                     pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
 1011:                             element_courant)).indice_boucle).mutex));
 1012:                 }
 1013: 
 1014:                 liberation(s_etat_processus,
 1015:                         (*((struct_liste_pile_systeme *)
 1016:                         element_courant)).indice_boucle);
 1017: 
 1018:                 if ((*((struct_liste_pile_systeme *)
 1019:                         element_courant)).limite_indice_boucle != NULL)
 1020:                 {
 1021:                     pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
 1022:                             element_courant)).limite_indice_boucle).mutex));
 1023:                     pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
 1024:                             element_courant)).limite_indice_boucle).mutex));
 1025:                 }
 1026: 
 1027:                 liberation(s_etat_processus,
 1028:                         (*((struct_liste_pile_systeme *)
 1029:                         element_courant)).limite_indice_boucle);
 1030: 
 1031:                 if ((*((struct_liste_pile_systeme *)
 1032:                         element_courant)).objet_de_test != NULL)
 1033:                 {
 1034:                     pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
 1035:                             element_courant)).objet_de_test).mutex));
 1036:                     pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
 1037:                             element_courant)).objet_de_test).mutex));
 1038:                 }
 1039: 
 1040:                 liberation(s_etat_processus,
 1041:                         (*((struct_liste_pile_systeme *)
 1042:                         element_courant)).objet_de_test);
 1043: 
 1044:                 if ((*((struct_liste_pile_systeme *)
 1045:                         element_courant)).nom_variable != NULL)
 1046:                 {
 1047:                     free((*((struct_liste_pile_systeme *)
 1048:                             element_courant)).nom_variable);
 1049:                 }
 1050: 
 1051:                 free(element_courant);
 1052: 
 1053:                 element_courant = element_suivant;
 1054:             }
 1055: 
 1056:             element_courant = (*s_etat_processus).s_fichiers;
 1057:             while(element_courant != NULL)
 1058:             {
 1059:                 element_suivant = (*((struct_liste_chainee *)
 1060:                         element_courant)).suivant;
 1061: 
 1062:                 element_candidat = (*candidat).s_fichiers;
 1063:                 while(element_candidat != NULL)
 1064:                 {
 1065:                     if (((*((struct_descripteur_fichier *)
 1066:                             (*((struct_liste_chainee *) element_courant))
 1067:                             .donnee)).pid ==
 1068:                             (*((struct_descripteur_fichier *)
 1069:                             (*((struct_liste_chainee *) element_candidat))
 1070:                             .donnee)).pid) && (pthread_equal(
 1071:                             (*((struct_descripteur_fichier *)
 1072:                             (*((struct_liste_chainee *) element_courant))
 1073:                             .donnee)).tid, (*((struct_descripteur_fichier *)
 1074:                             (*((struct_liste_chainee *) element_candidat))
 1075:                             .donnee)).tid) != 0))
 1076:                     {
 1077:                         if ((*((struct_descripteur_fichier *)
 1078:                                 (*((struct_liste_chainee *) element_courant))
 1079:                                 .donnee)).type ==
 1080:                                 (*((struct_descripteur_fichier *)
 1081:                                 (*((struct_liste_chainee *) element_candidat))
 1082:                                 .donnee)).type)
 1083:                         {
 1084:                             if ((*((struct_descripteur_fichier *)
 1085:                                     (*((struct_liste_chainee *)
 1086:                                     element_candidat)).donnee)).type == 'C')
 1087:                             {
 1088:                                 if ((*((struct_descripteur_fichier *)
 1089:                                         (*((struct_liste_chainee *)
 1090:                                         element_courant)).donnee))
 1091:                                         .descripteur_c ==
 1092:                                         (*((struct_descripteur_fichier *)
 1093:                                         (*((struct_liste_chainee *)
 1094:                                         element_candidat)).donnee))
 1095:                                         .descripteur_c)
 1096:                                 {
 1097:                                     break;
 1098:                                 }
 1099:                             }
 1100:                             else
 1101:                             {
 1102:                                 if (((*((struct_descripteur_fichier *)
 1103:                                         (*((struct_liste_chainee *)
 1104:                                         element_courant)).donnee))
 1105:                                         .descripteur_sqlite ==
 1106:                                         (*((struct_descripteur_fichier *)
 1107:                                         (*((struct_liste_chainee *)
 1108:                                         element_candidat)).donnee))
 1109:                                         .descripteur_sqlite) &&
 1110:                                         ((*((struct_descripteur_fichier *)
 1111:                                         (*((struct_liste_chainee *)
 1112:                                         element_courant)).donnee))
 1113:                                         .descripteur_c ==
 1114:                                         (*((struct_descripteur_fichier *)
 1115:                                         (*((struct_liste_chainee *)
 1116:                                         element_candidat)).donnee))
 1117:                                         .descripteur_c))
 1118:                                 {
 1119:                                     break;
 1120:                                 }
 1121:                             }
 1122:                         }
 1123:                     }
 1124: 
 1125:                     element_candidat = (*((struct_liste_chainee *)
 1126:                             element_candidat)).suivant;
 1127:                 }
 1128: 
 1129:                 if (element_candidat == NULL)
 1130:                 {
 1131:                     fclose((*((struct_descripteur_fichier *)
 1132:                             (*((struct_liste_chainee *) element_courant))
 1133:                             .donnee)).descripteur_c);
 1134: 
 1135:                     if ((*((struct_descripteur_fichier *)
 1136:                             (*((struct_liste_chainee *) element_courant))
 1137:                             .donnee)).type != 'C')
 1138:                     {
 1139:                         sqlite3_close((*((struct_descripteur_fichier *)
 1140:                                 (*((struct_liste_chainee *) element_courant))
 1141:                                 .donnee)).descripteur_sqlite);
 1142:                     }
 1143:                 }
 1144: 
 1145:                 free((*((struct_descripteur_fichier *)
 1146:                         (*((struct_liste_chainee *)
 1147:                         element_courant)).donnee)).nom);
 1148:                 free((struct_descripteur_fichier *)
 1149:                         (*((struct_liste_chainee *)
 1150:                         element_courant)).donnee);
 1151:                 free(element_courant);
 1152: 
 1153:                 element_courant = element_suivant;
 1154:             }
 1155: 
 1156:             element_courant = (*s_etat_processus).s_sockets;
 1157:             while(element_courant != NULL)
 1158:             {
 1159:                 element_suivant = (*((struct_liste_chainee *)
 1160:                         element_courant)).suivant;
 1161: 
 1162:                 element_candidat = (*candidat).s_sockets;
 1163:                 while(element_candidat != NULL)
 1164:                 {
 1165:                     if (((*((struct_socket *)
 1166:                             (*((struct_liste_chainee *) element_courant))
 1167:                             .donnee)).socket == (*((struct_socket *)
 1168:                             (*((struct_liste_chainee *) element_candidat))
 1169:                             .donnee)).socket) &&
 1170:                             ((*((struct_socket *)
 1171:                             (*((struct_liste_chainee *) element_courant))
 1172:                             .donnee)).pid == (*((struct_socket *)
 1173:                             (*((struct_liste_chainee *) element_candidat))
 1174:                             .donnee)).pid) && (pthread_equal(
 1175:                             (*((struct_socket *)
 1176:                             (*((struct_liste_chainee *) element_courant))
 1177:                             .donnee)).tid, (*((struct_socket *)
 1178:                             (*((struct_liste_chainee *) element_candidat))
 1179:                             .donnee)).tid) != 0))
 1180:                     {
 1181:                         break;
 1182:                     }
 1183: 
 1184:                     element_candidat = (*((struct_liste_chainee *)
 1185:                             element_candidat)).suivant;
 1186:                 }
 1187: 
 1188:                 if (element_candidat == NULL)
 1189:                 {
 1190:                     if ((*((struct_socket *) (*((struct_liste_chainee *)
 1191:                             element_courant)).donnee)).socket_connectee
 1192:                             == d_vrai)
 1193:                     {
 1194:                         shutdown((*((struct_socket *)
 1195:                                 (*((struct_liste_chainee *) element_courant))
 1196:                                 .donnee)).socket, SHUT_RDWR);
 1197:                     }
 1198: 
 1199:                     close((*((struct_socket *)
 1200:                             (*((struct_liste_chainee *) element_courant))
 1201:                             .donnee)).socket);
 1202:                 }
 1203: 
 1204:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
 1205:                         element_courant)).donnee).mutex));
 1206:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
 1207:                         element_courant)).donnee).mutex));
 1208: 
 1209:                 liberation(s_etat_processus,
 1210:                         (*((struct_liste_chainee *)
 1211:                         element_courant)).donnee);
 1212:                 free(element_courant);
 1213: 
 1214:                 element_courant = element_suivant;
 1215:             }
 1216: 
 1217: /*
 1218: ================================================================================
 1219:   À noter : on ne ferme pas la connexion car la conséquence immédiate est
 1220:   une destruction de l'objet pour le processus père.
 1221: ================================================================================
 1222: 
 1223:             element_courant = (*s_etat_processus).s_connecteurs_sql;
 1224:             while(element_courant != NULL)
 1225:             {
 1226:                 element_suivant = (*((struct_liste_chainee *)
 1227:                         element_courant)).suivant;
 1228: 
 1229:                 element_candidat = (*candidat).s_connecteurs_sql;
 1230:                 while(element_candidat != NULL)
 1231:                 {
 1232:                     if (((
 1233: #ifdef MYSQL_SUPPORT
 1234:                             ((*((struct_connecteur_sql *)
 1235:                             (*((struct_liste_chainee *) element_courant))
 1236:                             .donnee)).descripteur.mysql ==
 1237:                             (*((struct_connecteur_sql *)
 1238:                             (*((struct_liste_chainee *) element_candidat))
 1239:                             .donnee)).descripteur.mysql)
 1240:                             &&
 1241:                             (strcmp((*((struct_connecteur_sql *)
 1242:                             (*((struct_liste_chainee *) element_courant))
 1243:                             .donnee)).type, "MYSQL") == 0)
 1244:                             &&
 1245:                             (strcmp((*((struct_connecteur_sql *)
 1246:                             (*((struct_liste_chainee *) element_candidat))
 1247:                             .donnee)).type, "MYSQL") == 0)
 1248: #else
 1249:                             0
 1250: #endif
 1251:                             ) || (
 1252: #ifdef POSTGRESQL_SUPPORT
 1253:                             ((*((struct_connecteur_sql *)
 1254:                             (*((struct_liste_chainee *) element_courant))
 1255:                             .donnee)).descripteur.postgresql ==
 1256:                             (*((struct_connecteur_sql *)
 1257:                             (*((struct_liste_chainee *) element_candidat))
 1258:                             .donnee)).descripteur.postgresql)
 1259:                             &&
 1260:                             (strcmp((*((struct_connecteur_sql *)
 1261:                             (*((struct_liste_chainee *) element_courant))
 1262:                             .donnee)).type, "POSTGRESQL") == 0)
 1263:                             &&
 1264:                             (strcmp((*((struct_connecteur_sql *)
 1265:                             (*((struct_liste_chainee *) element_candidat))
 1266:                             .donnee)).type, "POSTGRESQL") == 0)
 1267: #else
 1268:                             0
 1269: #endif
 1270:                             )) &&
 1271:                             ((*((struct_connecteur_sql *)
 1272:                             (*((struct_liste_chainee *) element_courant))
 1273:                             .donnee)).pid == (*((struct_connecteur_sql *)
 1274:                             (*((struct_liste_chainee *) element_candidat))
 1275:                             .donnee)).pid) && (pthread_equal(
 1276:                             (*((struct_connecteur_sql *)
 1277:                             (*((struct_liste_chainee *) element_courant))
 1278:                             .donnee)).tid, (*((struct_connecteur_sql *)
 1279:                             (*((struct_liste_chainee *) element_candidat))
 1280:                             .donnee)).tid) != 0))
 1281:                     {
 1282:                         break;
 1283:                     }
 1284: 
 1285:                     element_candidat = (*((struct_liste_chainee *)
 1286:                             element_candidat)).suivant;
 1287:                 }
 1288: 
 1289:                 if (element_candidat == NULL)
 1290:                 {
 1291:                     sqlclose((*((struct_liste_chainee *) element_courant))
 1292:                             .donnee);
 1293:                 }
 1294: 
 1295:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
 1296:                         element_courant)).donnee).mutex));
 1297:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
 1298:                         element_courant)).donnee).mutex));
 1299: 
 1300:                 liberation(s_etat_processus, (*((struct_liste_chainee *)
 1301:                         element_courant)).donnee);
 1302:                 free(element_courant);
 1303: 
 1304:                 element_courant = element_suivant;
 1305:             }
 1306: */
 1307: 
 1308:             (*s_etat_processus).s_connecteurs_sql = NULL;
 1309: 
 1310:             element_courant = (*s_etat_processus).s_marques;
 1311:             while(element_courant != NULL)
 1312:             {
 1313:                 free((*((struct_marque *) element_courant)).label);
 1314:                 free((*((struct_marque *) element_courant)).position);
 1315:                 element_suivant = (*((struct_marque *) element_courant))
 1316:                         .suivant;
 1317:                 free(element_courant);
 1318:                 element_courant = element_suivant;
 1319:             }
 1320: 
 1321:             liberation_allocateur(s_etat_processus);
 1322: 
 1323: #           ifndef SEMAPHORES_NOMMES
 1324:             sem_post(&((*s_etat_processus).semaphore_fork));
 1325:             sem_destroy(&((*s_etat_processus).semaphore_fork));
 1326: #           else
 1327:             sem_post((*s_etat_processus).semaphore_fork);
 1328:             sem_destroy2((*s_etat_processus).semaphore_fork, sem_fork);
 1329: #           endif
 1330: 
 1331:             free(s_etat_processus);
 1332: 
 1333:             s_etat_processus = candidat;
 1334:         }
 1335: 
 1336:         l_element_suivant = (*l_element_courant).suivant;
 1337: 
 1338:         free((struct_thread *) (*l_element_courant).donnee);
 1339:         free((struct_liste_chainee *) l_element_courant);
 1340: 
 1341:         l_element_courant = l_element_suivant;
 1342:     }
 1343: 
 1344:     liste_threads = NULL;
 1345: 
 1346:     l_element_courant = liste_threads_surveillance;
 1347: 
 1348:     while(l_element_courant != NULL)
 1349:     {
 1350:         s_argument_thread = (struct_descripteur_thread *)
 1351:                 (*l_element_courant).donnee;
 1352: 
 1353:         if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)
 1354:         {
 1355:             (*s_etat_processus).erreur_systeme = d_es_processus;
 1356:             sem_post(&semaphore_liste_threads);
 1357:             return;
 1358:         }
 1359: 
 1360:         (*s_argument_thread).nombre_references--;
 1361: 
 1362:         BUG((*s_argument_thread).nombre_references < 0,
 1363:                 printf("(*s_argument_thread).nombre_references = %d\n",
 1364:                 (int) (*s_argument_thread).nombre_references));
 1365: 
 1366:         if ((*s_argument_thread).nombre_references == 0)
 1367:         {
 1368:             close((*s_argument_thread).pipe_objets[0]);
 1369:             close((*s_argument_thread).pipe_acquittement[1]);
 1370:             close((*s_argument_thread).pipe_injections[1]);
 1371:             close((*s_argument_thread).pipe_nombre_injections[1]);
 1372:             close((*s_argument_thread).pipe_nombre_objets_attente[0]);
 1373:             close((*s_argument_thread).pipe_interruptions[0]);
 1374:             close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);
 1375: 
 1376:             if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
 1377:             {
 1378:                 (*s_etat_processus).erreur_systeme = d_es_processus;
 1379:                 sem_post(&semaphore_liste_threads);
 1380:                 return;
 1381:             }
 1382: 
 1383:             pthread_mutex_destroy(&((*s_argument_thread).mutex));
 1384: 
 1385:             if ((*s_argument_thread).processus_detache == d_faux)
 1386:             {
 1387:                 if ((*s_argument_thread).destruction_objet == d_vrai)
 1388:                 {
 1389:                     liberation(s_etat_processus, (*s_argument_thread).argument);
 1390:                 }
 1391:             }
 1392: 
 1393:             free(s_argument_thread);
 1394:         }
 1395:         else
 1396:         {
 1397:             if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
 1398:             {
 1399:                 (*s_etat_processus).erreur_systeme = d_es_processus;
 1400:                 sem_post(&semaphore_liste_threads);
 1401:                 return;
 1402:             }
 1403:         }
 1404: 
 1405:         l_element_suivant = (*l_element_courant).suivant;
 1406:         free((struct_liste_chainee *) l_element_courant);
 1407:         l_element_courant = l_element_suivant;
 1408:     }
 1409: 
 1410:     liste_threads_surveillance = NULL;
 1411: 
 1412: #   ifndef SEMAPHORES_NOMMES
 1413:     if (sem_post(&semaphore_liste_threads) != 0)
 1414: #   else
 1415:     if (sem_post(semaphore_liste_threads) != 0)
 1416: #   endif
 1417:     {
 1418:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1419:         (*s_etat_processus).erreur_systeme = d_es_processus;
 1420:         return;
 1421:     }
 1422: 
 1423:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1424:     sigpending(&set);
 1425:     return;
 1426: }
 1427: 
 1428: static struct_processus *
 1429: recherche_thread(pid_t pid, pthread_t tid)
 1430: {
 1431:     volatile struct_liste_chainee_volatile      *l_element_courant;
 1432: 
 1433:     struct_processus                            *s_etat_processus;
 1434: 
 1435:     l_element_courant = liste_threads;
 1436: 
 1437:     while(l_element_courant != NULL)
 1438:     {
 1439:         if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee))
 1440:                 .tid, tid) != 0) && ((*((struct_thread *)
 1441:                 (*l_element_courant).donnee)).pid == pid))
 1442:         {
 1443:             break;
 1444:         }
 1445: 
 1446:         l_element_courant = (*l_element_courant).suivant;
 1447:     }
 1448: 
 1449:     if (l_element_courant == NULL)
 1450:     {
 1451:         /*
 1452:          * Le processus n'existe plus. On ne distribue aucun signal.
 1453:          */
 1454: 
 1455:         return(NULL);
 1456:     }
 1457: 
 1458:     s_etat_processus = (*((struct_thread *)
 1459:             (*l_element_courant).donnee)).s_etat_processus;
 1460: 
 1461:     return(s_etat_processus);
 1462: }
 1463: 
 1464: static logical1
 1465: recherche_thread_principal(pid_t pid, pthread_t *thread)
 1466: {
 1467:     volatile struct_liste_chainee_volatile      *l_element_courant;
 1468: 
 1469:     l_element_courant = liste_threads;
 1470: 
 1471:     while(l_element_courant != NULL)
 1472:     {
 1473:         if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal
 1474:                 == d_vrai) && ((*((struct_thread *)
 1475:                 (*l_element_courant).donnee)).pid == pid))
 1476:         {
 1477:             break;
 1478:         }
 1479: 
 1480:         l_element_courant = (*l_element_courant).suivant;
 1481:     }
 1482: 
 1483:     if (l_element_courant == NULL)
 1484:     {
 1485:         /*
 1486:          * Le processus n'existe plus. On ne distribue aucun signal.
 1487:          */
 1488: 
 1489:         return(d_faux);
 1490:     }
 1491: 
 1492:     (*thread) = (*((struct_thread *) (*l_element_courant).donnee)).tid;
 1493: 
 1494:     return(d_vrai);
 1495: }
 1496: 
 1497: 
 1498: /*
 1499: ================================================================================
 1500:   Procédures de gestion des signaux d'interruption
 1501: ================================================================================
 1502:   Entrée : variable globale
 1503: --------------------------------------------------------------------------------
 1504:   Sortie : variable globale modifiée
 1505: --------------------------------------------------------------------------------
 1506:   Effets de bord : néant
 1507: ================================================================================
 1508: */
 1509: 
 1510: // Les routines suivantes sont uniquement appelées depuis les gestionnaires
 1511: // des signaux asynchrones. Elles ne doivent pas bloquer dans le cas où
 1512: // les sémaphores sont déjà bloqués par un gestionnaire de signal.
 1513: 
 1514: static inline void
 1515: verrouillage_gestionnaire_signaux()
 1516: {
 1517:     int         semaphore;
 1518: 
 1519:     sigset_t    oldset;
 1520:     sigset_t    set;
 1521: 
 1522:     sem_t       *sem;
 1523: 
 1524:     if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
 1525:             != NULL)
 1526:     {
 1527:         if (sem_post(sem) != 0)
 1528:         {
 1529:             BUG(1, uprintf("Lock error !\n"));
 1530:             return;
 1531:         }
 1532:     }
 1533: 
 1534:     // Il faut respecteur l'atomicité des deux opérations suivantes !
 1535: 
 1536:     sigfillset(&set);
 1537:     pthread_sigmask(SIG_BLOCK, &set, &oldset);
 1538: 
 1539: #   ifndef SEMAPHORES_NOMMES
 1540:     while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
 1541: #   else
 1542:     while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)
 1543: #   endif
 1544:     {
 1545:         if (errno != EINTR)
 1546:         {
 1547:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1548:             BUG(1, uprintf("Unlock error !\n"));
 1549:             return;
 1550:         }
 1551:     }
 1552: 
 1553: #   ifndef SEMAPHORES_NOMMES
 1554:     if (sem_post(&semaphore_gestionnaires_signaux) == -1)
 1555: #   else
 1556:     if (sem_post(semaphore_gestionnaires_signaux) == -1)
 1557: #   endif
 1558:     {
 1559:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1560:         BUG(1, uprintf("Lock error !\n"));
 1561:         return;
 1562:     }
 1563: 
 1564: #   ifndef SEMAPHORES_NOMMES
 1565:     if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
 1566: #   else
 1567:     if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
 1568: #   endif
 1569:     {
 1570:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1571:         BUG(1, uprintf("Lock error !\n"));
 1572:         return;
 1573:     }
 1574: 
 1575: #   ifndef SEMAPHORES_NOMMES
 1576:     if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
 1577: #   else
 1578:     if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)
 1579: #   endif
 1580:     {
 1581:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1582:         BUG(1, uprintf("Unlock error !\n"));
 1583:         return;
 1584:     }
 1585: 
 1586:     if (semaphore == 1)
 1587:     {
 1588:         // Le semaphore ne peut être pris par le thread qui a appelé
 1589:         // le gestionnaire de signal car le signal est bloqué par ce thread
 1590:         // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que
 1591:         // par un thread concurrent. On essaye donc de le bloquer jusqu'à
 1592:         // ce que ce soit possible.
 1593: 
 1594: #       ifndef SEMAPHORES_NOMMES
 1595:         while(sem_trywait(&semaphore_liste_threads) == -1)
 1596: #       else
 1597:         while(sem_trywait(semaphore_liste_threads) == -1)
 1598: #       endif
 1599:         {
 1600:             if ((errno != EINTR) && (errno != EAGAIN))
 1601:             {
 1602:                 pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1603: 
 1604:                 while(sem_wait(sem) == -1)
 1605:                 {
 1606:                     if (errno != EINTR)
 1607:                     {
 1608:                         BUG(1, uprintf("Lock error !\n"));
 1609:                         return;
 1610:                     }
 1611:                 }
 1612: 
 1613:                 BUG(1, uprintf("Lock error !\n"));
 1614:                 return;
 1615:             }
 1616: 
 1617:             sched_yield();
 1618:         }
 1619:     }
 1620: 
 1621:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1622:     sigpending(&set);
 1623: 
 1624:     return;
 1625: }
 1626: 
 1627: static inline void
 1628: deverrouillage_gestionnaire_signaux()
 1629: {
 1630:     int         semaphore;
 1631: 
 1632:     sem_t       *sem;
 1633: 
 1634:     sigset_t    oldset;
 1635:     sigset_t    set;
 1636: 
 1637:     // Il faut respecteur l'atomicité des deux opérations suivantes !
 1638: 
 1639:     sigfillset(&set);
 1640:     pthread_sigmask(SIG_BLOCK, &set, &oldset);
 1641: 
 1642: #   ifndef SEMAPHORES_NOMMES
 1643:     while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
 1644: #   else
 1645:     while(sem_wait(semaphore_gestionnaires_signaux_atomique) == -1)
 1646: #   endif
 1647:     {
 1648:         if (errno != EINTR)
 1649:         {
 1650:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1651:             BUG(1, uprintf("Unlock error !\n"));
 1652:             return;
 1653:         }
 1654:     }
 1655: 
 1656: #   ifndef SEMAPHORES_NOMMES
 1657:     if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
 1658: #   else
 1659:     if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
 1660: #   endif
 1661:     {
 1662:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1663:         BUG(1, uprintf("Unlock error !\n"));
 1664:         return;
 1665:     }
 1666: 
 1667: #   ifndef SEMAPHORES_NOMMES
 1668:     while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
 1669: #   else
 1670:     while(sem_wait(semaphore_gestionnaires_signaux) == -1)
 1671: #   endif
 1672:     {
 1673:         if (errno != EINTR)
 1674:         {
 1675:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1676:             BUG(1, uprintf("Unlock error !\n"));
 1677:             return;
 1678:         }
 1679:     }
 1680: 
 1681: #   ifndef SEMAPHORES_NOMMES
 1682:     if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
 1683: #   else
 1684:     if (sem_post(semaphore_gestionnaires_signaux_atomique) != 0)
 1685: #   endif
 1686:     {
 1687:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1688:         BUG(1, uprintf("Unlock error !\n"));
 1689:         return;
 1690:     }
 1691: 
 1692:     if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
 1693:             != NULL)
 1694:     {
 1695:         while(sem_wait(sem) == -1)
 1696:         {
 1697:             if (errno != EINTR)
 1698:             {
 1699:                 pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1700:                 BUG(1, uprintf("Unlock error !\n"));
 1701:                 return;
 1702:             }
 1703:         }
 1704:     }
 1705: 
 1706:     if (semaphore == 1)
 1707:     {
 1708: #       ifndef SEMAPHORES_NOMMES
 1709:         if (sem_post(&semaphore_liste_threads) != 0)
 1710: #       else
 1711:         if (sem_post(semaphore_liste_threads) != 0)
 1712: #       endif
 1713:         {
 1714:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1715: 
 1716:             BUG(1, uprintf("Unlock error !\n"));
 1717:             return;
 1718:         }
 1719:     }
 1720: 
 1721:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1722:     sigpending(&set);
 1723: 
 1724:     return;
 1725: }
 1726: 
 1727: #ifdef _BROKEN_SIGINFO
 1728: 
 1729: // Remplacer les mutexes par des sémaphores SysV
 1730: 
 1731: #define longueur_queue  256
 1732: #define nombre_queues   13
 1733: 
 1734: static int              *fifos;
 1735: static int              segment;
 1736: static sem_t            *semaphores[nombre_queues];
 1737: static sem_t            *semaphore_global;
 1738: 
 1739: #ifdef IPCS_SYSV
 1740: static unsigned char    *chemin = NULL;
 1741: #endif
 1742: 
 1743: unsigned char *
 1744: nom_segment(unsigned char *chemin, pid_t pid)
 1745: {
 1746:     unsigned char               *fichier;
 1747: 
 1748: #   ifdef IPCS_SYSV
 1749:     if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) *
 1750:             sizeof(unsigned char))) == NULL)
 1751:     {
 1752:         return(NULL);
 1753:     }
 1754: 
 1755:     sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);
 1756: #   else
 1757:     if ((fichier = malloc((1 + 256 + 1) *
 1758:             sizeof(unsigned char))) == NULL)
 1759:     {
 1760:         return(NULL);
 1761:     }
 1762: 
 1763:     sprintf(fichier, "/RPL-SIGQUEUES-%d", (int) pid);
 1764: #   endif
 1765: 
 1766:     return(fichier);
 1767: }
 1768: 
 1769: unsigned char *
 1770: nom_semaphore(pid_t pid, int queue)
 1771: {
 1772:     unsigned char               *fichier;
 1773: 
 1774:     if ((fichier = malloc((256 + 1) * sizeof(unsigned char))) == NULL)
 1775:     {
 1776:         return(NULL);
 1777:     }
 1778: 
 1779:     sprintf(fichier, "/RPL-SIGESMAPHORES-%d-%d", (int) pid, queue);
 1780: 
 1781:     return(fichier);
 1782: }
 1783: 
 1784: inline int
 1785: queue_de_signal(int signal)
 1786: {
 1787:     switch(signal)
 1788:     {
 1789:         case SIGINT:
 1790:             return(0);
 1791:         case SIGTSTP:
 1792:             return(1);
 1793:         case SIGCONT:
 1794:             return(2);
 1795:         case SIGURG:
 1796:             return(3);
 1797:         case SIGPIPE:
 1798:             return(4);
 1799:         case SIGALRM:
 1800:             return(5);
 1801:         case SIGFSTOP:
 1802:             return(6);
 1803:         case SIGSTART:
 1804:             return(7);
 1805:         case SIGINJECT:
 1806:             return(8);
 1807:         case SIGABORT:
 1808:             return(9);
 1809:         case SIGFABORT:
 1810:             return(10);
 1811:         case SIGSEGV:
 1812:             return(11);
 1813:         case SIGBUS:
 1814:             return(12);
 1815:     }
 1816: 
 1817:     return(-1);
 1818: }
 1819: 
 1820: void
 1821: creation_fifos_signaux(struct_processus *s_etat_processus)
 1822: {
 1823:     /*
 1824:      * Signaux utilisés
 1825:      * SIGINT, SIGTSTP, SIGCONT, SIGURG, SIGPIPE, SIGALRM, SIGFSTOP,
 1826:      * SIGSTART, SIGINJECT, SIGABORT, SIGFABORT
 1827:      */
 1828: 
 1829: #   ifndef IPCS_SYSV // POSIX
 1830: #   else // SystemV
 1831: 
 1832:     file                            *desc;
 1833: 
 1834:     int                             i;
 1835: 
 1836:     key_t                           clef;
 1837: 
 1838:     unsigned char                   *nom;
 1839: 
 1840:     // Création d'un segment de données associé au PID du processus courant
 1841: 
 1842:     chemin = (*s_etat_processus).chemin_fichiers_temporaires;
 1843: 
 1844:     if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
 1845:             getpid())) == NULL)
 1846:     {
 1847:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1848:         return;
 1849:     }
 1850: 
 1851:     if ((desc = fopen(nom, "w")) == NULL)
 1852:     {
 1853:         (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
 1854:         return;
 1855:     }
 1856: 
 1857:     fclose(desc);
 1858: 
 1859:     if ((clef = ftok(nom, 1)) == -1)
 1860:     {
 1861:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1862:         return;
 1863:     }
 1864: 
 1865:     free(nom);
 1866: 
 1867:     if ((segment = shmget(clef,
 1868:             nombre_queues * (longueur_queue + 4) * sizeof(int),
 1869:             IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)
 1870:     {
 1871:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1872:         return;
 1873:     }
 1874: 
 1875:     fifos = shmat(segment, NULL, 0);
 1876: 
 1877:     if (((void *) fifos) == ((void *) -1))
 1878:     {
 1879:         if (shmctl(segment, IPC_RMID, 0) == -1)
 1880:         {
 1881:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1882:             return;
 1883:         }
 1884: 
 1885:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1886:         return;
 1887:     }
 1888: 
 1889: #   endif
 1890: 
 1891:     /*
 1892:      * Structure d'une queue
 1893:      * 0 : pointeur en lecture sur le premier emplacement libre (int)
 1894:      * 1 : pointeur en écriture sur le premier emplacement à lire (int)
 1895:      * 2 : longueur de la queue (int)
 1896:      * 3 : éléments restants (int)
 1897:      * 4 à 4 + (2) : queue (int)
 1898:      */
 1899: 
 1900:     for(i = 0; i < nombre_queues; i++)
 1901:     {
 1902:         fifos[(i * (longueur_queue + 4))] = 0;
 1903:         fifos[(i * (longueur_queue + 4)) + 1] = 0;
 1904:         fifos[(i * (longueur_queue + 4)) + 2] = longueur_queue;
 1905:         fifos[(i * (longueur_queue + 4)) + 3] = longueur_queue;
 1906:     }
 1907: 
 1908:     // Création des sémaphores : un sémaphore par signal et par queue
 1909:     // plus un sémaphore global pour tous les threads.
 1910: 
 1911:     for(i = 0; i < nombre_queues; i++)
 1912:     {
 1913:         if ((nom = nom_semaphore(getpid(), i)) == NULL)
 1914:         {
 1915:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1916:             return;
 1917:         }
 1918: 
 1919:         // Le sémaphore est créé en écrasant si nécessaire un sémaphore
 1920:         // préexistant. Comme le nom du sémaphore contient l'identifiant du
 1921:         // processus, il est anormal d'avoir un sémaphore de même nom
 1922:         // préexistant.
 1923: 
 1924:         if ((semaphores[i] = sem_open(nom, O_CREAT, S_IRUSR | S_IWUSR,
 1925:                 1)) == SEM_FAILED)
 1926:         {
 1927:             (*s_etat_processus).erreur_systeme = d_es_semaphore;
 1928:             return;
 1929:         }
 1930: 
 1931:         free(nom);
 1932:     }
 1933: 
 1934: 
 1935:     if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
 1936:     {
 1937:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1938:         return;
 1939:     }
 1940: 
 1941:     if ((semaphore_global = sem_open(nom, O_CREAT, S_IRUSR | S_IWUSR,
 1942:             1)) == SEM_FAILED)
 1943:     {
 1944:         (*s_etat_processus).erreur_systeme = d_es_semaphore;
 1945:         return;
 1946:     }
 1947: 
 1948:     free(nom);
 1949: 
 1950:     return;
 1951: }
 1952: 
 1953: void
 1954: liberation_fifos_signaux(struct_processus *s_etat_processus)
 1955: {
 1956:     int                 i;
 1957: 
 1958:     if (shmdt(fifos) == -1)
 1959:     {
 1960:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1961:         return;
 1962:     }
 1963: 
 1964:     for(i = 0; i < nombre_queues; i++)
 1965:     {
 1966:         if (sem_close(semaphores[i]) != 0)
 1967:         {
 1968:             (*s_etat_processus).erreur_systeme = d_es_semaphore;
 1969:             return;
 1970:         }
 1971:     }
 1972: 
 1973:     if (sem_close(semaphore_global) != 0)
 1974:     {
 1975:         (*s_etat_processus).erreur_systeme = d_es_semaphore;
 1976:         return;
 1977:     }
 1978: 
 1979:     return;
 1980: }
 1981: 
 1982: void
 1983: destruction_fifos_signaux(struct_processus *s_etat_processus)
 1984: {
 1985:     int                 i;
 1986: 
 1987:     unsigned char       *nom;
 1988: 
 1989:     if (shmdt(fifos) == -1)
 1990:     {
 1991:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1992:         return;
 1993:     }
 1994: 
 1995:     if (shmctl(segment, IPC_RMID, 0) == -1)
 1996:     {
 1997:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 1998:         return;
 1999:     }
 2000: 
 2001:     if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
 2002:             getpid())) == NULL)
 2003:     {
 2004:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2005:         return;
 2006:     }
 2007: 
 2008:     unlink(nom);
 2009:     free(nom);
 2010: 
 2011:     for(i = 0; i < nombre_queues; i++)
 2012:     {
 2013:         if ((nom = nom_semaphore(getpid(), i)) == NULL)
 2014:         {
 2015:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2016:             return;
 2017:         }
 2018: 
 2019:         if (sem_unlink(nom) != 0)
 2020:         {
 2021:             (*s_etat_processus).erreur_systeme = d_es_semaphore;
 2022:             return;
 2023:         }
 2024: 
 2025:         free(nom);
 2026:     }
 2027: 
 2028:     if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
 2029:     {
 2030:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2031:         return;
 2032:     }
 2033: 
 2034:     if (sem_unlink(nom) != 0)
 2035:     {
 2036:         (*s_etat_processus).erreur_systeme = d_es_semaphore;
 2037:         return;
 2038:     }
 2039: 
 2040:     free(nom);
 2041: 
 2042:     return;
 2043: }
 2044: 
 2045: int
 2046: queue_in(pid_t pid, int signal)
 2047: {
 2048: #undef printf
 2049: // Transformer ce truc en POSIX ! On ne fait du SysV que si on n'a pas le choix
 2050: 
 2051: #   ifndef IPCS_SYSV
 2052: #   else // Traitement à l'aide d'IPCS SystemV
 2053: 
 2054:     int             *base;
 2055:     int             *buffer;
 2056:     int             *projection_fifos;
 2057:     int             queue;
 2058:     int             identifiant;
 2059: 
 2060:     key_t           clef;
 2061: 
 2062:     sem_t           *semaphore;
 2063: 
 2064:     struct stat     s_stat;
 2065: 
 2066:     unsigned char   *nom;
 2067: 
 2068:     queue = queue_de_signal(signal);
 2069: 
 2070:     // Ouverture des projections
 2071: 
 2072:     if ((nom = nom_segment(chemin, pid)) == NULL)
 2073:     {
 2074:         return(-1);
 2075:     }
 2076: 
 2077:     // Dans le cas de SIGSTART, premier signal envoyé à un processus fils,
 2078:     // il convient d'attendre que le fichier support soit effectivement
 2079:     // accessible. Dans tous les autres cas, ce fichier doit exister. S'il
 2080:     // n'existe plus, le processus associé n'existe plus.
 2081: 
 2082:     if (signal == SIGSTART)
 2083:     {
 2084:         // On attend que le fichier sois présent
 2085: 
 2086:         while(stat(nom, &s_stat) != 0);
 2087:     }
 2088: 
 2089:     if ((clef = ftok(nom, 1)) == -1)
 2090:     {
 2091:         return(-1);
 2092:     }
 2093: 
 2094:     free(nom);
 2095: 
 2096:     if (signal == SIGSTART)
 2097:     {
 2098:         while((identifiant = shmget(clef,
 2099:                 nombre_queues * (longueur_queue + 4) * sizeof(int),
 2100:                 S_IRUSR | S_IWUSR)) == -1);
 2101:     }
 2102:     else
 2103:     {
 2104:         if ((identifiant = shmget(clef,
 2105:                 nombre_queues * (longueur_queue + 4) * sizeof(int),
 2106:                 S_IRUSR | S_IWUSR)) == -1)
 2107:         {
 2108:             return(-1);
 2109:         }
 2110:     }
 2111: 
 2112:     projection_fifos = shmat(identifiant, NULL, 0);
 2113: 
 2114:     if (((void *) projection_fifos) == ((void *) -1))
 2115:     {
 2116:         return(-1);
 2117:     }
 2118: 
 2119:     if ((nom = nom_semaphore(pid, queue)) == NULL)
 2120:     {
 2121:         shmdt(projection_fifos);
 2122:         return(-1);
 2123:     }
 2124: 
 2125:     while((semaphore = sem_open(nom, 0)) == SEM_FAILED);
 2126: 
 2127:     if (sem_wait(semaphore) != 0)
 2128:     {
 2129:         shmdt(projection_fifos);
 2130:         return(-1);
 2131:     }
 2132: 
 2133:     // Il ne faut pas empiler plusieurs SIGSTART car SIGSTART peut provenir
 2134:     // de l'instruction SWI. Plusieurs threads peuvent interrompre de façon
 2135:     // asynchrone le processus père durant une phase de signaux masqués.
 2136: 
 2137:     base = &(projection_fifos[(longueur_queue + 4) * queue]);
 2138:     buffer = &(base[4]);
 2139: 
 2140:     // base[3] contient le nombre d'éléments restants
 2141: 
 2142:     if (base[3] <= 0)
 2143:     {
 2144:         sem_post(semaphore);
 2145:         sem_close(semaphore);
 2146:         shmdt(projection_fifos);
 2147:         return(-1);
 2148:     }
 2149: 
 2150:     base[3]--;
 2151: 
 2152:     // base[1] contient le prochain élément à écrire
 2153:     buffer[base[1]++] = (int) pid;
 2154:     base[1] %= base[2];
 2155: 
 2156:     if (sem_post(semaphore) != 0)
 2157:     {
 2158:         shmdt(projection_fifos);
 2159:         sem_close(semaphore);
 2160:         return(-1);
 2161:     }
 2162: 
 2163:     sem_close(semaphore);
 2164: 
 2165:     // Fermeture des projections
 2166:     shmdt(projection_fifos);
 2167: 
 2168: #   endif
 2169: 
 2170:     return(0);
 2171: }
 2172: 
 2173: pid_t
 2174: origine_signal(int signal)
 2175: {
 2176:     int             *base;
 2177:     int             *buffer;
 2178:     int             pid;
 2179:     int             queue;
 2180: 
 2181:     queue = queue_de_signal(signal);
 2182: 
 2183:     BUG(queue == -1, uprintf("[%d] Unknown signal %d in this context\n",
 2184:             (int) getpid(), signal));
 2185: 
 2186:     if (sem_wait(semaphores[queue]) != 0)
 2187:     {
 2188:         return(-1);
 2189:     }
 2190: 
 2191:     // Le signal SIGCONT peut être envoyé de façon totalement asynchrone.
 2192:     // Il peut y avoir plus de signaux envoyés que d'interruptions traitées.
 2193:     // Il convient donc de rectifier la queue lors du traitement de
 2194:     // l'interruption correspondante. Le gestionnaire étant installé sans
 2195:     // l'option NODEFER, la queue reste cohérente.
 2196: 
 2197:     if (signal == SIGCONT)
 2198:     {
 2199:         base = &(fifos[(longueur_queue + 4) * queue]);
 2200:         buffer = &(base[4]);
 2201:         base[0] = (base[1] - 1) % base[2];
 2202:         pid = buffer[base[0]++];
 2203:         base[3] = base[2];
 2204:     }
 2205:     else
 2206:     {
 2207:         base = &(fifos[(longueur_queue + 4) * queue]);
 2208:         buffer = &(base[4]);
 2209:         pid = buffer[base[0]++];
 2210:         base[0] %= base[2];
 2211:         base[3]++;
 2212:     }
 2213: 
 2214:     if (base[3] > base[2])
 2215:     {
 2216:         sem_post(semaphores[queue]);
 2217:         return(-1);
 2218:     }
 2219: 
 2220:     if (sem_post(semaphores[queue]) != 0)
 2221:     {
 2222:         return(-1);
 2223:     }
 2224: 
 2225:     return((pid_t) pid);
 2226: }
 2227: 
 2228: #endif
 2229: 
 2230: #ifdef printf
 2231: #   undef printf
 2232: #endif
 2233: 
 2234: void
 2235: interruption1(SIGHANDLER_ARGS)
 2236: {
 2237:     pid_t                   pid;
 2238: 
 2239:     pthread_t               thread;
 2240: 
 2241:     struct_processus        *s_etat_processus;
 2242: 
 2243:     volatile sig_atomic_t   exclusion = 0;
 2244: 
 2245:     verrouillage_gestionnaire_signaux();
 2246: 
 2247: #   ifdef _BROKEN_SIGINFO
 2248:     if (signal == SIGINT)
 2249:     {
 2250:         // Si l'interruption provient du clavier, il n'y a pas eu d'appel
 2251:         // à queue_in().
 2252: 
 2253:         pid = getpid();
 2254:     }
 2255:     else
 2256:     {
 2257:         pid = origine_signal(signal);
 2258:     }
 2259: #   else
 2260:     pid = (*siginfo).si_pid;
 2261: #   endif
 2262: 
 2263:     switch(signal)
 2264:     {
 2265:         case SIGALRM :
 2266:         {
 2267:             if (pid == getpid())
 2268:             {
 2269:                 if ((s_etat_processus = recherche_thread(getpid(),
 2270:                         pthread_self())) == NULL)
 2271:                 {
 2272:                     deverrouillage_gestionnaire_signaux();
 2273:                      return;
 2274:                 }
 2275: 
 2276:                 if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2277:                 {
 2278:                     printf("[%d] SIGALRM (thread %llu)\n", (int) getpid(),
 2279:                             (unsigned long long) pthread_self());
 2280:                     fflush(stdout);
 2281:                 }
 2282: 
 2283:                 if ((*s_etat_processus).pid_processus_pere != getpid())
 2284:                 {
 2285:                     kill((*s_etat_processus).pid_processus_pere, signal);
 2286:                 }
 2287:                 else
 2288:                 {
 2289:                     (*s_etat_processus).var_volatile_alarme = -1;
 2290:                     (*s_etat_processus).var_volatile_requete_arret = -1;
 2291:                 }
 2292:             }
 2293:             else
 2294:             {
 2295:                 if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 2296:                 {
 2297:                     pthread_kill(thread, signal);
 2298:                 }
 2299:             }
 2300: 
 2301:             break;
 2302:         }
 2303: 
 2304:         case SIGINT :
 2305:         {
 2306:             /*
 2307:              * Une vieille spécification POSIX permet au pointeur siginfo
 2308:              * d'être nul dans le cas d'un ^C envoyé depuis le clavier.
 2309:              * Solaris suit en particulier cette spécification.
 2310:              */
 2311: 
 2312: #           ifndef _BROKEN_SIGINFO
 2313:             if (siginfo == NULL)
 2314:             {
 2315:                 kill(getpid(), signal);
 2316:             }
 2317:             else
 2318: #           endif
 2319:             if (pid == getpid())
 2320:             {
 2321:                 if ((s_etat_processus = recherche_thread(getpid(),
 2322:                         pthread_self())) == NULL)
 2323:                 {
 2324:                     deverrouillage_gestionnaire_signaux();
 2325:                     return;
 2326:                 }
 2327: 
 2328:                 if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2329:                 {
 2330:                     printf("[%d] SIGINT (thread %llu)\n", (int) getpid(),
 2331:                             (unsigned long long) pthread_self());
 2332:                     fflush(stdout);
 2333:                 }
 2334: 
 2335:                 if ((*s_etat_processus).pid_processus_pere != getpid())
 2336:                 {
 2337:                     kill((*s_etat_processus).pid_processus_pere, signal);
 2338:                 }
 2339:                 else
 2340:                 {
 2341:                     (*s_etat_processus).var_volatile_traitement_sigint = -1;
 2342: 
 2343:                     while(exclusion == 1);
 2344:                     exclusion = 1;
 2345: 
 2346:                     if ((*s_etat_processus).var_volatile_requete_arret == -1)
 2347:                     {
 2348:                         deverrouillage_gestionnaire_signaux();
 2349:                         exclusion = 0;
 2350:                         return;
 2351:                     }
 2352: 
 2353:                     if (strncmp(getenv("LANG"), "fr", 2) == 0)
 2354:                     {
 2355:                         printf("+++Interruption\n");
 2356:                     }
 2357:                     else
 2358:                     {
 2359:                         printf("+++Interrupt\n");
 2360:                     }
 2361: 
 2362:                     fflush(stdout);
 2363: 
 2364:                     (*s_etat_processus).var_volatile_requete_arret = -1;
 2365:                     (*s_etat_processus).var_volatile_alarme = -1;
 2366: 
 2367:                     exclusion = 0;
 2368:                 }
 2369:             }
 2370:             else
 2371:             {
 2372:                 if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 2373:                 {
 2374:                     pthread_kill(thread, signal);
 2375:                 }
 2376:             }
 2377: 
 2378:             break;
 2379:         }
 2380: 
 2381:         default :
 2382:         {
 2383:             BUG(1, uprintf("[%d] Unknown signal %d in this context\n",
 2384:                     (int) getpid(), signal));
 2385:             break;
 2386:         }
 2387:     }
 2388: 
 2389:     deverrouillage_gestionnaire_signaux();
 2390:     return;
 2391: }
 2392: 
 2393: void
 2394: interruption2(SIGHANDLER_ARGS)
 2395: {
 2396:     pid_t                   pid;
 2397: 
 2398:     pthread_t               thread;
 2399: 
 2400:     struct_processus        *s_etat_processus;
 2401: 
 2402:     verrouillage_gestionnaire_signaux();
 2403: 
 2404: #   ifdef _BROKEN_SIGINFO
 2405:     pid = origine_signal(signal);
 2406: #   else
 2407:     pid = (*siginfo).si_pid;
 2408: #   endif
 2409: 
 2410: #   ifndef _BROKEN_SIGINFO
 2411:     if (siginfo == NULL)
 2412:     {
 2413:         /*
 2414:          * Le signal SIGFSTP provient de la mort du processus de contrôle.
 2415:          * Sous certains systèmes (Linux...), la mort du terminal de contrôle
 2416:          * se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
 2417:          * (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
 2418:          * non initialisée (pointeur NULL) issue de TERMIO.
 2419:          */
 2420: 
 2421:         if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 2422:         {
 2423:             pthread_kill(thread, SIGHUP);
 2424:             deverrouillage_gestionnaire_signaux();
 2425:             return;
 2426:         }
 2427:     }
 2428:     else
 2429: #   endif
 2430:     if (pid == getpid())
 2431:     {
 2432:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 2433:                 == NULL)
 2434:         {
 2435:             deverrouillage_gestionnaire_signaux();
 2436:             return;
 2437:         }
 2438: 
 2439:         /*
 2440:          *  0 => fonctionnement normal
 2441:          * -1 => requête
 2442:          *  1 => requête acceptée en attente de traitement
 2443:          */
 2444: 
 2445:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2446:         {
 2447:             printf("[%d] SIGTSTP (thread %llu)\n", (int) getpid(),
 2448:                     (unsigned long long) pthread_self());
 2449:             fflush(stdout);
 2450:         }
 2451: 
 2452:         if ((*s_etat_processus).var_volatile_processus_pere == 0)
 2453:         {
 2454:             kill((*s_etat_processus).pid_processus_pere, signal);
 2455:         }
 2456:         else
 2457:         {
 2458:             (*s_etat_processus).var_volatile_requete_arret2 = -1;
 2459:         }
 2460:     }
 2461:     else
 2462:     {
 2463:         // Envoi d'un signal au thread maître du groupe.
 2464: 
 2465:         if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 2466:         {
 2467:             pthread_kill(thread, SIGTSTP);
 2468:             deverrouillage_gestionnaire_signaux();
 2469:             return;
 2470:         }
 2471:     }
 2472: 
 2473:     deverrouillage_gestionnaire_signaux();
 2474:     return;
 2475: }
 2476: 
 2477: void
 2478: interruption3(SIGHANDLER_ARGS)
 2479: {
 2480:     pid_t                   pid;
 2481: 
 2482:     struct_processus        *s_etat_processus;
 2483: 
 2484:     static int              compteur = 0;
 2485: 
 2486:     verrouillage_gestionnaire_signaux();
 2487: 
 2488: #   ifdef _BROKEN_SIGINFO
 2489:     pid = origine_signal(signal);
 2490: #   else
 2491:     pid = (*siginfo).si_pid;
 2492: #   endif
 2493: 
 2494:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2495:     {
 2496:         deverrouillage_gestionnaire_signaux();
 2497:         return;
 2498:     }
 2499: 
 2500:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2501:     {
 2502:         printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),
 2503:                 (unsigned long long) pthread_self());
 2504:         fflush(stdout);
 2505:     }
 2506: 
 2507:     if ((*s_etat_processus).var_volatile_recursivite == -1)
 2508:     {
 2509:         // Segfault dans un appel de fonction récursive
 2510:         deverrouillage_gestionnaire_signaux();
 2511:         longjmp(contexte, -1);
 2512:     }
 2513:     else
 2514:     {
 2515:         // Segfault dans une routine interne
 2516:         if (strncmp(getenv("LANG"), "fr", 2) == 0)
 2517:         {
 2518:             printf("+++Système : Violation d'accès (dépassement de pile)\n");
 2519:         }
 2520:         else
 2521:         {
 2522:             printf("+++System : Access violation (stack overflow)\n");
 2523:         }
 2524: 
 2525:         fflush(stdout);
 2526: 
 2527:         compteur++;
 2528: 
 2529:         if (compteur > 1)
 2530:         {
 2531:             deverrouillage_gestionnaire_signaux();
 2532:             exit(EXIT_FAILURE);
 2533:         }
 2534:         else
 2535:         {
 2536:             deverrouillage_gestionnaire_signaux();
 2537:             longjmp(contexte_initial, -1);
 2538:         }
 2539:     }
 2540: 
 2541:     deverrouillage_gestionnaire_signaux();
 2542:     return;
 2543: }
 2544: 
 2545: void
 2546: interruption4(SIGHANDLER_ARGS)
 2547: {
 2548:     pid_t                   pid;
 2549: 
 2550:     struct_processus        *s_etat_processus;
 2551: 
 2552:     verrouillage_gestionnaire_signaux();
 2553: 
 2554: #   ifdef _BROKEN_SIGINFO
 2555:     pid = origine_signal(signal);
 2556: #   else
 2557:     pid = (*siginfo).si_pid;
 2558: #   endif
 2559: 
 2560:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2561:     {
 2562:         deverrouillage_gestionnaire_signaux();
 2563:         return;
 2564:     }
 2565: 
 2566:     /*
 2567:      * Démarrage d'un processus fils ou gestion de SIGCONT (SUSPEND)
 2568:      */
 2569: 
 2570:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2571:     {
 2572:         printf("[%d] SIGSTART/SIGCONT (thread %llu)\n", (int) getpid(),
 2573:                 (unsigned long long) pthread_self());
 2574:         fflush(stdout);
 2575:     }
 2576: 
 2577:     deverrouillage_gestionnaire_signaux();
 2578:     return;
 2579: }
 2580: 
 2581: void
 2582: interruption5(SIGHANDLER_ARGS)
 2583: {
 2584:     pid_t                   pid;
 2585: 
 2586:     pthread_t               thread;
 2587: 
 2588:     struct_processus        *s_etat_processus;
 2589: 
 2590:     verrouillage_gestionnaire_signaux();
 2591: 
 2592: #   ifdef _BROKEN_SIGINFO
 2593:     pid = origine_signal(signal);
 2594: #   else
 2595:     pid = (*siginfo).si_pid;
 2596: #   endif
 2597: 
 2598:     if (pid == getpid())
 2599:     {
 2600:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 2601:                 == NULL)
 2602:         {
 2603:             deverrouillage_gestionnaire_signaux();
 2604:             return;
 2605:         }
 2606: 
 2607:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2608:         {
 2609:             printf("[%d] SIGFSTOP (thread %llu)\n", (int) getpid(),
 2610:                     (unsigned long long) pthread_self());
 2611:             fflush(stdout);
 2612:         }
 2613: 
 2614:         /*
 2615:          * var_globale_traitement_retarde_stop :
 2616:          *  0 -> traitement immédiat
 2617:          *  1 -> traitement retardé (aucun signal reçu)
 2618:          * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
 2619:          */
 2620: 
 2621:         if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
 2622:         {
 2623:             (*s_etat_processus).var_volatile_requete_arret = -1;
 2624:         }
 2625:         else
 2626:         {
 2627:             (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
 2628:         }
 2629:     }
 2630:     else
 2631:     {
 2632:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 2633:                 == NULL)
 2634:         {
 2635:             deverrouillage_gestionnaire_signaux();
 2636:             return;
 2637:         }
 2638: 
 2639:         // Envoi d'un signal au thread maître du groupe.
 2640: 
 2641:         if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 2642:         {
 2643:             pthread_kill(thread, signal);
 2644:             deverrouillage_gestionnaire_signaux();
 2645:             return;
 2646:         }
 2647:     }
 2648: 
 2649:     deverrouillage_gestionnaire_signaux();
 2650:     return;
 2651: }
 2652: 
 2653: void
 2654: interruption6(SIGHANDLER_ARGS)
 2655: {
 2656:     pid_t                   pid;
 2657: 
 2658:     struct_processus        *s_etat_processus;
 2659: 
 2660:     verrouillage_gestionnaire_signaux();
 2661: 
 2662: #   ifdef _BROKEN_SIGINFO
 2663:     pid = origine_signal(signal);
 2664: #   else
 2665:     pid = (*siginfo).si_pid;
 2666: #   endif
 2667: 
 2668:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2669:     {
 2670:         deverrouillage_gestionnaire_signaux();
 2671:         return;
 2672:     }
 2673: 
 2674:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2675:     {
 2676:         printf("[%d] SIGINJECT/SIGQUIT (thread %llu)\n", (int) getpid(),
 2677:                 (unsigned long long) pthread_self());
 2678:         fflush(stdout);
 2679:     }
 2680: 
 2681:     deverrouillage_gestionnaire_signaux();
 2682:     return;
 2683: }
 2684: 
 2685: void
 2686: interruption7(SIGHANDLER_ARGS)
 2687: {
 2688:     pid_t                   pid;
 2689: 
 2690:     struct_processus        *s_etat_processus;
 2691: 
 2692:     verrouillage_gestionnaire_signaux();
 2693: 
 2694: #   ifdef _BROKEN_SIGINFO
 2695:     pid = origine_signal(signal);
 2696: #   else
 2697:     pid = (*siginfo).si_pid;
 2698: #   endif
 2699: 
 2700:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2701:     {
 2702:         deverrouillage_gestionnaire_signaux();
 2703:         return;
 2704:     }
 2705: 
 2706:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2707:     {
 2708:         printf("[%d] SIGPIPE (thread %llu)\n", (int) getpid(),
 2709:                 (unsigned long long) pthread_self());
 2710:         fflush(stdout);
 2711:     }
 2712: 
 2713:     (*s_etat_processus).var_volatile_requete_arret = -1;
 2714:     deverrouillage_gestionnaire_signaux();
 2715: 
 2716:     BUG(1, printf("[%d] SIGPIPE\n", (int) getpid()));
 2717:     return;
 2718: }
 2719: 
 2720: void
 2721: interruption8(SIGHANDLER_ARGS)
 2722: {
 2723:     pid_t                   pid;
 2724: 
 2725:     pthread_t               thread;
 2726: 
 2727:     struct_processus        *s_etat_processus;
 2728: 
 2729:     verrouillage_gestionnaire_signaux();
 2730: 
 2731: #   ifdef _BROKEN_SIGINFO
 2732:     pid = origine_signal(signal);
 2733: #   else
 2734:     pid = (*siginfo).si_pid;
 2735: #   endif
 2736: 
 2737:     if (pid == getpid())
 2738:     {
 2739:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 2740:                 == NULL)
 2741:         {
 2742:             deverrouillage_gestionnaire_signaux();
 2743:             return;
 2744:         }
 2745: 
 2746:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2747:         {
 2748:             printf("[%d] SIGURG (thread %llu)\n", (int) getpid(),
 2749:                     (unsigned long long) pthread_self());
 2750:             fflush(stdout);
 2751:         }
 2752: 
 2753:         (*s_etat_processus).var_volatile_alarme = -1;
 2754:         (*s_etat_processus).var_volatile_requete_arret = -1;
 2755:     }
 2756:     else
 2757:     {
 2758:         // Envoi d'un signal au thread maître du groupe.
 2759: 
 2760:         if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 2761:         {
 2762:             pthread_kill(thread, SIGURG);
 2763:             deverrouillage_gestionnaire_signaux();
 2764:             return;
 2765:         }
 2766:     }
 2767: 
 2768:     deverrouillage_gestionnaire_signaux();
 2769:     return;
 2770: }
 2771: 
 2772: void
 2773: interruption9(SIGHANDLER_ARGS)
 2774: {
 2775:     pid_t                   pid;
 2776: 
 2777:     struct_processus        *s_etat_processus;
 2778: 
 2779:     verrouillage_gestionnaire_signaux();
 2780: 
 2781: #   ifdef _BROKEN_SIGINFO
 2782:     pid = origine_signal(signal);
 2783: #   else
 2784:     pid = (*siginfo).si_pid;
 2785: #   endif
 2786: 
 2787:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2788:     {
 2789:         deverrouillage_gestionnaire_signaux();
 2790:         return;
 2791:     }
 2792: 
 2793:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2794:     {
 2795:         printf("[%d] SIGABORT/SIGPROF (thread %llu)\n", (int) getpid(),
 2796:                 (unsigned long long) pthread_self());
 2797:         fflush(stdout);
 2798:     }
 2799: 
 2800: #   ifdef _BROKEN_SIGINFO
 2801:     if (queue_in(getpid(), signal) != 0)
 2802:     {
 2803:         return;
 2804:     }
 2805: 
 2806:     deverrouillage_gestionnaire_signaux();
 2807:     interruption11(signal);
 2808: #   else
 2809:     deverrouillage_gestionnaire_signaux();
 2810:     interruption11(signal, siginfo, context);
 2811: #   endif
 2812:     return;
 2813: }
 2814: 
 2815: void
 2816: interruption10(SIGHANDLER_ARGS)
 2817: {
 2818:     file                    *fichier;
 2819: 
 2820:     pid_t                   pid;
 2821: 
 2822:     struct_processus        *s_etat_processus;
 2823: 
 2824:     unsigned char           nom[8 + 64 + 1];
 2825: 
 2826:     verrouillage_gestionnaire_signaux();
 2827: 
 2828: #   ifdef _BROKEN_SIGINFO
 2829:     pid = origine_signal(signal);
 2830: #   else
 2831:     pid = (*siginfo).si_pid;
 2832: #   endif
 2833: 
 2834:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2835:     {
 2836:         deverrouillage_gestionnaire_signaux();
 2837:         return;
 2838:     }
 2839: 
 2840:     snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
 2841:             (unsigned long) pthread_self());
 2842: 
 2843:     if ((fichier = fopen(nom, "w+")) != NULL)
 2844:     {
 2845:         fclose(fichier);
 2846: 
 2847:         freopen(nom, "w", stdout);
 2848:         freopen(nom, "w", stderr);
 2849:     }
 2850: 
 2851:     freopen("/dev/null", "r", stdin);
 2852: 
 2853:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2854:     {
 2855:         printf("[%d] SIGHUP (thread %llu)\n", (int) getpid(),
 2856:                 (unsigned long long) pthread_self());
 2857:         fflush(stdout);
 2858:     }
 2859: 
 2860:     deverrouillage_gestionnaire_signaux();
 2861:     return;
 2862: }
 2863: 
 2864: void
 2865: interruption11(SIGHANDLER_ARGS)
 2866: {
 2867:     pid_t                   pid;
 2868: 
 2869:     pthread_t               thread;
 2870: 
 2871:     struct_processus        *s_etat_processus;
 2872: 
 2873:     verrouillage_gestionnaire_signaux();
 2874: 
 2875: #   ifdef _BROKEN_SIGINFO
 2876:     pid = origine_signal(signal);
 2877: #   else
 2878:     pid = (*siginfo).si_pid;
 2879: #   endif
 2880: 
 2881:     if (pid == getpid())
 2882:     {
 2883:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 2884:                 == NULL)
 2885:         {
 2886:             deverrouillage_gestionnaire_signaux();
 2887:             return;
 2888:         }
 2889: 
 2890:         (*s_etat_processus).arret_depuis_abort = -1;
 2891: 
 2892:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2893:         {
 2894:             printf("[%d] SIGFABORT (thread %llu)\n", (int) getpid(),
 2895:                     (unsigned long long) pthread_self());
 2896:             fflush(stdout);
 2897:         }
 2898: 
 2899:         /*
 2900:          * var_globale_traitement_retarde_stop :
 2901:          *  0 -> traitement immédiat
 2902:          *  1 -> traitement retardé (aucun signal reçu)
 2903:          * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
 2904:          */
 2905: 
 2906:         if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
 2907:         {
 2908:             (*s_etat_processus).var_volatile_requete_arret = -1;
 2909:         }
 2910:         else
 2911:         {
 2912:             (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
 2913:         }
 2914:     }
 2915:     else
 2916:     {
 2917:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 2918:                 == NULL)
 2919:         {
 2920:             deverrouillage_gestionnaire_signaux();
 2921:             return;
 2922:         }
 2923: 
 2924:         (*s_etat_processus).arret_depuis_abort = -1;
 2925: 
 2926:         // Envoi d'un signal au thread maître du groupe.
 2927: 
 2928:         if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 2929:         {
 2930:             pthread_kill(thread, signal);
 2931:             deverrouillage_gestionnaire_signaux();
 2932:             return;
 2933:         }
 2934:     }
 2935: 
 2936:     deverrouillage_gestionnaire_signaux();
 2937:     return;
 2938: }
 2939: 
 2940: void
 2941: traitement_exceptions_gsl(const char *reason, const char *file,
 2942:         int line, int gsl_errno)
 2943: {
 2944:     struct_processus        *s_etat_processus;
 2945: 
 2946:     verrouillage_gestionnaire_signaux();
 2947: 
 2948:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2949:     {
 2950:         deverrouillage_gestionnaire_signaux();
 2951:         return;
 2952:     }
 2953: 
 2954:     (*s_etat_processus).var_volatile_exception_gsl = gsl_errno;
 2955:     deverrouillage_gestionnaire_signaux();
 2956:     return;
 2957: }
 2958: 
 2959: #ifdef _BROKEN_SIGINFO
 2960: 
 2961: #undef kill
 2962: #undef pthread_kill
 2963: 
 2964: int
 2965: kill_broken_siginfo(pid_t pid, int signal)
 2966: {
 2967:     int                 ios;
 2968: 
 2969:     sem_t               *semaphore;
 2970: 
 2971:     unsigned char       *nom;
 2972: 
 2973:     /*
 2974:      * Lorsqu'on veut interrompre le processus pid, on ouvre le segment
 2975:      * correspondant au processus en question et ou ajoute le pid dans la
 2976:      * queue.
 2977:      *
 2978:      * Le sémaphore global à tous les threads d'un même processus sert
 2979:      * à garantir que les signaux seront traités dans l'ordre de ce qui est
 2980:      * effectivement mis dans la queue.
 2981:      */
 2982: 
 2983:     // Sémaphore acquis
 2984: 
 2985:     if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
 2986:     {
 2987:         return(-1);
 2988:     }
 2989: 
 2990:     if ((semaphore = sem_open(nom, 0)) == SEM_FAILED)
 2991:     {
 2992:         free(nom);
 2993:         return(-1);
 2994:     }
 2995: 
 2996:     free(nom);
 2997: 
 2998:     if (sem_wait(semaphore) == -1)
 2999:     {
 3000:         return(-1);
 3001:     }
 3002: 
 3003:     if ((signal != 0) && (signal != SIGINT))
 3004:     {
 3005:         if (queue_in(pid, signal) != 0)
 3006:         {
 3007:             sem_post(semaphore);
 3008:             sem_close(semaphore);
 3009:             return(-1);
 3010:         }
 3011:     }
 3012: 
 3013:     ios = kill(pid, signal);
 3014: 
 3015:     // Sémaphore relâché
 3016: 
 3017:     sem_post(semaphore);
 3018:     sem_close(semaphore);
 3019: 
 3020:     return(ios);
 3021: }
 3022: 
 3023: int
 3024: pthread_kill_broken_siginfo(pthread_t tid, int signal)
 3025: {
 3026:     int                 ios;
 3027: 
 3028:     sem_t               *semaphore;
 3029: 
 3030:     unsigned char       *nom;
 3031: 
 3032:     if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
 3033:     {
 3034:         return(-1);
 3035:     }
 3036: 
 3037:     if ((semaphore = sem_open(nom, 0)) == SEM_FAILED)
 3038:     {
 3039:         free(nom);
 3040:         return(-1);
 3041:     }
 3042: 
 3043:     free(nom);
 3044: 
 3045:     if (sem_wait(semaphore) == -1)
 3046:     {
 3047:         return(-1);
 3048:     }
 3049: 
 3050:     if ((signal != 0) && (signal != SIGINT))
 3051:     {
 3052:         if (queue_in(getpid(), signal) != 0)
 3053:         {
 3054:             sem_post(semaphore);
 3055:             sem_close(semaphore);
 3056:             return(-1);
 3057:         }
 3058:     }
 3059: 
 3060:     ios = pthread_kill(tid, signal);
 3061: 
 3062:     sem_post(semaphore);
 3063:     sem_close(semaphore);
 3064: 
 3065:     return(ios);
 3066: }
 3067: 
 3068: #endif
 3069: 
 3070: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>