File:  [local] / rpl / src / interruptions.c
Revision 1.6: download - view: text, annotated - select for diffs - revision graph
Tue Mar 9 10:18:49 2010 UTC (14 years, 1 month ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_0_13, rpl-4_0_12, HEAD
En route pour la 4.0.13.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.0.13
    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:     while(sem_wait(&semaphore_liste_threads) == -1)
   86:     {
   87:         if (errno != EINTR)
   88:         {
   89:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
   90:             sigpending(&set);
   91: 
   92:             (*s_etat_processus).erreur_systeme = d_es_processus;
   93:             return;
   94:         }
   95:     }
   96: 
   97:     if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
   98:             == NULL)
   99:     {
  100:         sem_post(&semaphore_liste_threads);
  101:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  102:         sigpending(&set);
  103: 
  104:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  105:         return;
  106:     }
  107: 
  108:     (*l_nouvel_objet).suivant = liste_threads;
  109: 
  110:     if (((*l_nouvel_objet).donnee = malloc(sizeof(struct_thread))) == NULL)
  111:     {
  112:         sem_post(&semaphore_liste_threads);
  113:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  114:         sigpending(&set);
  115: 
  116:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  117:         return;
  118:     }
  119: 
  120:     (*((struct_thread *) (*l_nouvel_objet).donnee)).pid = getpid();
  121:     (*((struct_thread *) (*l_nouvel_objet).donnee)).tid = pthread_self();
  122:     (*((struct_thread *) (*l_nouvel_objet).donnee)).thread_principal =
  123:             thread_principal;
  124:     (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus =
  125:             s_etat_processus;
  126: 
  127:     liste_threads = l_nouvel_objet;
  128: 
  129:     if (sem_post(&semaphore_liste_threads) != 0)
  130:     {
  131:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  132:         sigpending(&set);
  133: 
  134:         (*s_etat_processus).erreur_systeme = d_es_processus;
  135:         return;
  136:     }
  137: 
  138:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  139:     sigpending(&set);
  140:     return;
  141: }
  142: 
  143: void
  144: insertion_thread_surveillance(struct_processus *s_etat_processus,
  145:         struct_descripteur_thread *s_argument_thread)
  146: {
  147:     sigset_t                                    oldset;
  148:     sigset_t                                    set;
  149: 
  150:     volatile struct_liste_chainee_volatile      *l_nouvel_objet;
  151: 
  152:     sigfillset(&set);
  153:     pthread_sigmask(SIG_BLOCK, &set, &oldset);
  154: 
  155:     while(sem_wait(&semaphore_liste_threads) == -1)
  156:     {
  157:         if (errno != EINTR)
  158:         {
  159:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  160:             sigpending(&set);
  161: 
  162:             (*s_etat_processus).erreur_systeme = d_es_processus;
  163:             return;
  164:         }
  165:     }
  166: 
  167:     if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
  168:             == NULL)
  169:     {
  170:         sem_post(&semaphore_liste_threads);
  171:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  172:         sigpending(&set);
  173: 
  174:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  175:         return;
  176:     }
  177: 
  178:     (*l_nouvel_objet).suivant = liste_threads_surveillance;
  179:     (*l_nouvel_objet).donnee = (void *) s_argument_thread;
  180: 
  181:     liste_threads_surveillance = l_nouvel_objet;
  182: 
  183:     if (sem_post(&semaphore_liste_threads) != 0)
  184:     {
  185:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  186:         sigpending(&set);
  187: 
  188:         (*s_etat_processus).erreur_systeme = d_es_processus;
  189:         return;
  190:     }
  191: 
  192:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  193:     sigpending(&set);
  194:     return;
  195: }
  196: 
  197: void
  198: retrait_thread(struct_processus *s_etat_processus)
  199: {
  200:     sigset_t                                oldset;
  201:     sigset_t                                set;
  202: 
  203:     volatile struct_liste_chainee_volatile  *l_element_precedent;
  204:     volatile struct_liste_chainee_volatile  *l_element_courant;
  205: 
  206:     sigfillset(&set);
  207:     pthread_sigmask(SIG_BLOCK, &set, &oldset);
  208: 
  209:     while(sem_wait(&semaphore_liste_threads) == -1)
  210:     {
  211:         if (errno != EINTR)
  212:         {
  213:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  214:             sigpending(&set);
  215: 
  216:             (*s_etat_processus).erreur_systeme = d_es_processus;
  217:             return;
  218:         }
  219:     }
  220: 
  221:     l_element_precedent = NULL;
  222:     l_element_courant = liste_threads;
  223: 
  224:     while(l_element_courant != NULL)
  225:     {
  226:         if (((*((struct_thread *) (*l_element_courant).donnee)).pid
  227:                 == getpid()) && (pthread_equal((*((struct_thread *)
  228:                 (*l_element_courant).donnee)).tid, pthread_self()) != 0))
  229:         {
  230:             break;
  231:         }
  232: 
  233:         l_element_precedent = l_element_courant;
  234:         l_element_courant = (*l_element_courant).suivant;
  235:     }
  236: 
  237:     if (l_element_courant == NULL)
  238:     {
  239:         sem_post(&semaphore_liste_threads);
  240:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  241:         sigpending(&set);
  242: 
  243:         (*s_etat_processus).erreur_systeme = d_es_processus;
  244:         return;
  245:     }
  246: 
  247:     if (l_element_precedent == NULL)
  248:     {
  249:         liste_threads = (*l_element_courant).suivant;
  250:     }
  251:     else
  252:     {
  253:         (*l_element_precedent).suivant = (*l_element_courant).suivant;
  254:     }
  255: 
  256:     free((void *) (*l_element_courant).donnee);
  257:     free((struct_liste_chainee_volatile *) l_element_courant);
  258: 
  259:     if (pthread_setspecific(semaphore_fork_processus_courant, NULL) != 0)
  260:     {
  261:         (*s_etat_processus).erreur_systeme = d_es_processus;
  262: 
  263:         sem_post(&semaphore_liste_threads);
  264:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  265:         sigpending(&set);
  266:         return;
  267:     }
  268: 
  269:     if (sem_post(&semaphore_liste_threads) != 0)
  270:     {
  271:         (*s_etat_processus).erreur_systeme = d_es_processus;
  272: 
  273:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  274:         sigpending(&set);
  275:         return;
  276:     }
  277: 
  278:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  279:     sigpending(&set);
  280:     return;
  281: }
  282: 
  283: void
  284: retrait_thread_surveillance(struct_processus *s_etat_processus,
  285:         struct_descripteur_thread *s_argument_thread)
  286: {
  287:     sigset_t                                set;
  288:     sigset_t                                oldset;
  289: 
  290:     volatile struct_liste_chainee_volatile  *l_element_precedent;
  291:     volatile struct_liste_chainee_volatile  *l_element_courant;
  292: 
  293:     sigfillset(&set);
  294:     pthread_sigmask(SIG_BLOCK, &set, &oldset);
  295: 
  296:     while(sem_wait(&semaphore_liste_threads) == -1)
  297:     {
  298:         if (errno != EINTR)
  299:         {
  300:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  301:             sigpending(&set);
  302: 
  303:             (*s_etat_processus).erreur_systeme = d_es_processus;
  304:             return;
  305:         }
  306:     }
  307: 
  308:     l_element_precedent = NULL;
  309:     l_element_courant = liste_threads_surveillance;
  310: 
  311:     while(l_element_courant != NULL)
  312:     {
  313:         if ((*l_element_courant).donnee == (void *) s_argument_thread)
  314:         {
  315:             break;
  316:         }
  317: 
  318:         l_element_precedent = l_element_courant;
  319:         l_element_courant = (*l_element_courant).suivant;
  320:     }
  321: 
  322:     if (l_element_courant == NULL)
  323:     {
  324:         sem_post(&semaphore_liste_threads);
  325:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  326:         sigpending(&set);
  327: 
  328:         (*s_etat_processus).erreur_systeme = d_es_processus;
  329:         return;
  330:     }
  331: 
  332:     if (l_element_precedent == NULL)
  333:     {
  334:         liste_threads_surveillance = (*l_element_courant).suivant;
  335:     }
  336:     else
  337:     {
  338:         (*l_element_precedent).suivant = (*l_element_courant).suivant;
  339:     }
  340: 
  341:     free((struct_liste_chainee_volatile *) l_element_courant);
  342: 
  343:     if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)
  344:     {
  345:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  346:         sigpending(&set);
  347: 
  348:         (*s_etat_processus).erreur_systeme = d_es_processus;
  349:         return;
  350:     }
  351: 
  352:     (*s_argument_thread).nombre_references--;
  353: 
  354:     BUG((*s_argument_thread).nombre_references < 0,
  355:             printf("(*s_argument_thread).nombre_references = %d\n",
  356:             (int) (*s_argument_thread).nombre_references));
  357: 
  358:     if ((*s_argument_thread).nombre_references == 0)
  359:     {
  360:         if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
  361:         {
  362:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  363:             sigpending(&set);
  364: 
  365:             (*s_etat_processus).erreur_systeme = d_es_processus;
  366:             return;
  367:         }
  368: 
  369:         pthread_mutex_destroy(&((*s_argument_thread).mutex));
  370:         free(s_argument_thread);
  371:     }
  372:     else
  373:     {
  374:         if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
  375:         {
  376:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  377:             sigpending(&set);
  378: 
  379:             (*s_etat_processus).erreur_systeme = d_es_processus;
  380:             return;
  381:         }
  382:     }
  383: 
  384:     if (sem_post(&semaphore_liste_threads) != 0)
  385:     {
  386:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  387:         sigpending(&set);
  388: 
  389:         (*s_etat_processus).erreur_systeme = d_es_processus;
  390:         return;
  391:     }
  392: 
  393:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  394:     sigpending(&set);
  395:     return;
  396: }
  397: 
  398: void
  399: verrouillage_threads_concurrents(struct_processus *s_etat_processus)
  400: {
  401:     volatile struct_liste_chainee_volatile  *l_element_courant;
  402: 
  403:     while(sem_wait(&semaphore_liste_threads) == -1)
  404:     {
  405:         if (errno != EINTR)
  406:         {
  407:             (*s_etat_processus).erreur_systeme = d_es_processus;
  408:             return;
  409:         }
  410:     }
  411: 
  412:     l_element_courant = liste_threads;
  413: 
  414:     while(l_element_courant != NULL)
  415:     {
  416:         if (((*((struct_thread *) (*l_element_courant).donnee)).pid
  417:                 == getpid()) && (pthread_equal((*((struct_thread *)
  418:                 (*l_element_courant).donnee)).tid, pthread_self()) == 0))
  419:         {
  420:             while(sem_wait(&((*(*((struct_thread *) (*l_element_courant)
  421:                     .donnee)).s_etat_processus).semaphore_fork)) == -1)
  422:             {
  423:                 if (errno != EINTR)
  424:                 {
  425:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  426:                     return;
  427:                 }
  428:             }
  429:         }
  430: 
  431:         l_element_courant = (*l_element_courant).suivant;
  432:     }
  433: 
  434:     return;
  435: }
  436: 
  437: void
  438: deverrouillage_threads_concurrents(struct_processus *s_etat_processus)
  439: {
  440:     volatile struct_liste_chainee_volatile  *l_element_courant;
  441: 
  442:     l_element_courant = liste_threads;
  443: 
  444:     while(l_element_courant != NULL)
  445:     {
  446:         if (((*((struct_thread *) (*l_element_courant).donnee)).pid
  447:                 == getpid()) && (pthread_equal((*((struct_thread *)
  448:                 (*l_element_courant).donnee)).tid, pthread_self()) == 0))
  449:         {
  450:             if (sem_post(&((*(*((struct_thread *)
  451:                     (*l_element_courant).donnee)).s_etat_processus)
  452:                     .semaphore_fork)) != 0)
  453:             {
  454:                 if (sem_post(&semaphore_liste_threads) != 0)
  455:                 {
  456:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  457:                     return;
  458:                 }
  459: 
  460:                 (*s_etat_processus).erreur_systeme = d_es_processus;
  461:                 return;
  462:             }
  463:         }
  464: 
  465:         l_element_courant = (*l_element_courant).suivant;
  466:     }
  467: 
  468:     if (sem_post(&semaphore_liste_threads) != 0)
  469:     {
  470:         (*s_etat_processus).erreur_systeme = d_es_processus;
  471:         return;
  472:     }
  473: 
  474:     return;
  475: }
  476: 
  477: void
  478: liberation_threads(struct_processus *s_etat_processus)
  479: {
  480:     logical1                                    suppression_variables_partagees;
  481: 
  482:     sigset_t                                    oldset;
  483:     sigset_t                                    set;
  484: 
  485:     struct_descripteur_thread                   *s_argument_thread;
  486: 
  487:     struct_processus                            *candidat;
  488: 
  489:     unsigned long                               i;
  490: 
  491:     void                                        *element_candidat;
  492:     void                                        *element_courant;
  493:     void                                        *element_suivant;
  494: 
  495:     volatile struct_liste_chainee_volatile      *l_element_courant;
  496:     volatile struct_liste_chainee_volatile      *l_element_suivant;
  497: 
  498:     sigfillset(&set);
  499:     pthread_sigmask(SIG_BLOCK, &set, &oldset);
  500: 
  501:     while(sem_wait(&semaphore_liste_threads) == -1)
  502:     {
  503:         if (errno != EINTR)
  504:         {
  505:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  506:             (*s_etat_processus).erreur_systeme = d_es_processus;
  507:             return;
  508:         }
  509:     }
  510: 
  511:     l_element_courant = liste_threads;
  512:     suppression_variables_partagees = d_faux;
  513: 
  514:     while(l_element_courant != NULL)
  515:     {
  516:         if ((*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus
  517:                 != s_etat_processus)
  518:         {
  519:             candidat = s_etat_processus;
  520:             s_etat_processus = (*((struct_thread *)
  521:                     (*l_element_courant).donnee)).s_etat_processus;
  522:             free((*s_etat_processus).localisation);
  523: 
  524:             // (*s_etat_processus).instruction_courante peut pointer sur
  525:             // n'importe quoi (une instruction courante ou un champ d'une
  526:             // structure objet). On ne le libère pas quitte à avoir une
  527:             // petite fuite mémoire dans le processus fils.
  528: 
  529:             if ((*s_etat_processus).instruction_courante != NULL)
  530:             {
  531:                 //free((*s_etat_processus).instruction_courante);
  532:             }
  533: 
  534:             close((*s_etat_processus).pipe_acquittement);
  535:             close((*s_etat_processus).pipe_donnees);
  536:             close((*s_etat_processus).pipe_injections);
  537:             close((*s_etat_processus).pipe_nombre_injections);
  538:             close((*s_etat_processus).pipe_interruptions);
  539:             close((*s_etat_processus).pipe_nombre_objets_attente);
  540:             close((*s_etat_processus).pipe_nombre_interruptions_attente);
  541: 
  542:             if ((*s_etat_processus).nom_fichier_impression != NULL)
  543:             {
  544:                 free((*s_etat_processus).nom_fichier_impression);
  545:             }
  546: 
  547:             while((*s_etat_processus).fichiers_graphiques != NULL)
  548:             {
  549:                 free((*(*s_etat_processus).fichiers_graphiques).nom);
  550: 
  551:                 if ((*(*s_etat_processus).fichiers_graphiques).legende != NULL)
  552:                 {
  553:                     free((*(*s_etat_processus).fichiers_graphiques).legende);
  554:                 }
  555: 
  556:                 element_courant = (*s_etat_processus).fichiers_graphiques;
  557:                 (*s_etat_processus).fichiers_graphiques =
  558:                         (*(*s_etat_processus).fichiers_graphiques).suivant;
  559: 
  560:                 free(element_courant);
  561:             }
  562: 
  563:             if ((*s_etat_processus).entree_standard != NULL)
  564:             {
  565:                 pclose((*s_etat_processus).entree_standard);
  566:             }
  567: 
  568:             if ((*s_etat_processus).generateur_aleatoire != NULL)
  569:             {
  570:                 liberation_generateur_aleatoire(s_etat_processus);
  571:             }
  572: 
  573:             if ((*s_etat_processus).instruction_derniere_erreur != NULL)
  574:             {
  575:                 free((*s_etat_processus).instruction_derniere_erreur);
  576:                 (*s_etat_processus).instruction_derniere_erreur = NULL;
  577:             }
  578: 
  579:             element_courant = (void *) (*s_etat_processus)
  580:                     .l_base_pile_processus;
  581:             while(element_courant != NULL)
  582:             {
  583:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  584:                         element_courant)).donnee).mutex));
  585:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  586:                         element_courant)).donnee).mutex));
  587:                 liberation(s_etat_processus,
  588:                         (*((struct_liste_chainee *) element_courant)).donnee);
  589:                 element_suivant = (*((struct_liste_chainee *) element_courant))
  590:                         .suivant;
  591:                 free((struct_liste_chainee *) element_courant);
  592:                 element_courant = element_suivant;
  593:             }
  594: 
  595:             pthread_mutex_trylock(&((*(*s_etat_processus).indep).mutex));
  596:             pthread_mutex_unlock(&((*(*s_etat_processus).indep).mutex));
  597:             liberation(s_etat_processus, (*s_etat_processus).indep);
  598: 
  599:             pthread_mutex_trylock(&((*(*s_etat_processus).depend).mutex));
  600:             pthread_mutex_unlock(&((*(*s_etat_processus).depend).mutex));
  601:             liberation(s_etat_processus, (*s_etat_processus).depend);
  602: 
  603:             free((*s_etat_processus).label_x);
  604:             free((*s_etat_processus).label_y);
  605:             free((*s_etat_processus).label_z);
  606:             free((*s_etat_processus).titre);
  607:             free((*s_etat_processus).legende);
  608: 
  609:             pthread_mutex_trylock(&((*(*s_etat_processus)
  610:                     .parametres_courbes_de_niveau).mutex));
  611:             pthread_mutex_unlock(&((*(*s_etat_processus)
  612:                     .parametres_courbes_de_niveau).mutex));
  613:             liberation(s_etat_processus, (*s_etat_processus)
  614:                     .parametres_courbes_de_niveau);
  615: 
  616:             for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++)
  617:             {
  618:                 if ((*s_etat_processus).corps_interruptions[i] != NULL)
  619:                 {
  620:                     pthread_mutex_trylock(&((*(*s_etat_processus)
  621:                             .corps_interruptions[i]).mutex));
  622:                     pthread_mutex_unlock(&((*(*s_etat_processus)
  623:                             .corps_interruptions[i]).mutex));
  624: 
  625:                     liberation(s_etat_processus,
  626:                             (*s_etat_processus).corps_interruptions[i]);
  627:                 }
  628: 
  629:                 element_courant = (*s_etat_processus)
  630:                         .pile_origine_interruptions[i];
  631: 
  632:                 while(element_courant != NULL)
  633:                 {
  634:                     element_suivant = (*((struct_liste_chainee *)
  635:                             element_courant)).suivant;
  636: 
  637:                     pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  638:                             element_courant)).donnee).mutex));
  639:                     pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  640:                             element_courant)).donnee).mutex));
  641: 
  642:                     liberation(s_etat_processus,
  643:                             (*((struct_liste_chainee *) element_courant))
  644:                             .donnee);
  645:                     free(element_courant);
  646: 
  647:                     element_courant = element_suivant;
  648:                 }
  649:             }
  650: 
  651:             for(i = 0; i < (*s_etat_processus).nombre_variables; i++)
  652:             {
  653:                 pthread_mutex_trylock(&((*(*s_etat_processus)
  654:                         .s_liste_variables[i].objet).mutex));
  655:                 pthread_mutex_unlock(&((*(*s_etat_processus)
  656:                         .s_liste_variables[i].objet).mutex));
  657: 
  658:                 // Les variables de niveau 0 sont des définitions qui
  659:                 // ne sont pas copiées entre threads.
  660:                 if ((*s_etat_processus).s_liste_variables[i].niveau > 0)
  661:                 {
  662:                     liberation(s_etat_processus,
  663:                             (*s_etat_processus).s_liste_variables[i].objet);
  664:                 }
  665: 
  666:                 free((*s_etat_processus).s_liste_variables[i].nom);
  667:             }
  668: 
  669:             free((*s_etat_processus).s_liste_variables);
  670: 
  671:             for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)
  672:             {
  673:                 pthread_mutex_trylock(&((*(*s_etat_processus)
  674:                         .s_liste_variables_statiques[i].objet).mutex));
  675:                 pthread_mutex_unlock(&((*(*s_etat_processus)
  676:                         .s_liste_variables_statiques[i].objet).mutex));
  677: 
  678:                 liberation(s_etat_processus, (*s_etat_processus)
  679:                         .s_liste_variables_statiques[i].objet);
  680:                 free((*s_etat_processus).s_liste_variables_statiques[i].nom);
  681:             }
  682: 
  683:             free((*s_etat_processus).s_liste_variables_statiques);
  684: 
  685:             // Ne peut être effacé qu'une seule fois
  686:             if (suppression_variables_partagees == d_faux)
  687:             {
  688:                 suppression_variables_partagees = d_vrai;
  689: 
  690:                 for(i = 0; i < (*(*s_etat_processus)
  691:                         .s_liste_variables_partagees).nombre_variables; i++)
  692:                 {
  693:                     pthread_mutex_trylock(&((*(*(*s_etat_processus)
  694:                             .s_liste_variables_partagees).table[i].objet)
  695:                             .mutex));
  696:                     pthread_mutex_unlock(&((*(*(*s_etat_processus)
  697:                             .s_liste_variables_partagees).table[i].objet)
  698:                             .mutex));
  699: 
  700:                     liberation(s_etat_processus, (*(*s_etat_processus)
  701:                             .s_liste_variables_partagees).table[i].objet);
  702:                     free((*(*s_etat_processus).s_liste_variables_partagees)
  703:                             .table[i].nom);
  704:                 }
  705: 
  706:                 if ((*(*s_etat_processus).s_liste_variables_partagees).table
  707:                         != NULL)
  708:                 {
  709:                     free((struct_variable_partagee *) (*(*s_etat_processus)
  710:                             .s_liste_variables_partagees).table);
  711:                 }
  712: 
  713:                 pthread_mutex_trylock(&((*(*s_etat_processus)
  714:                         .s_liste_variables_partagees).mutex));
  715:                 pthread_mutex_unlock(&((*(*s_etat_processus)
  716:                         .s_liste_variables_partagees).mutex));
  717:             }
  718: 
  719:             element_courant = (*s_etat_processus).l_base_pile;
  720:             while(element_courant != NULL)
  721:             {
  722:                 element_suivant = (*((struct_liste_chainee *)
  723:                         element_courant)).suivant;
  724: 
  725:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  726:                         element_courant)).donnee).mutex));
  727:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  728:                         element_courant)).donnee).mutex));
  729: 
  730:                 liberation(s_etat_processus,
  731:                         (*((struct_liste_chainee *)
  732:                         element_courant)).donnee);
  733:                 free((struct_liste_chainee *) element_courant);
  734: 
  735:                 element_courant = element_suivant;
  736:             }
  737: 
  738:             element_courant = (*s_etat_processus).l_base_pile_contextes;
  739:             while(element_courant != NULL)
  740:             {
  741:                 element_suivant = (*((struct_liste_chainee *)
  742:                         element_courant)).suivant;
  743: 
  744:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  745:                         element_courant)).donnee).mutex));
  746:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  747:                         element_courant)).donnee).mutex));
  748:                 liberation(s_etat_processus, (*((struct_liste_chainee *)
  749:                         element_courant)).donnee);
  750:                 free((struct_liste_chainee *) element_courant);
  751: 
  752:                 element_courant = element_suivant;
  753:             }
  754: 
  755:             element_courant = (*s_etat_processus).l_base_pile_taille_contextes;
  756:             while(element_courant != NULL)
  757:             {
  758:                 element_suivant = (*((struct_liste_chainee *)
  759:                         element_courant)).suivant;
  760: 
  761:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  762:                         element_courant)).donnee).mutex));
  763:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  764:                         element_courant)).donnee).mutex));
  765:                 liberation(s_etat_processus,
  766:                         (*((struct_liste_chainee *)
  767:                         element_courant)).donnee);
  768:                 free((struct_liste_chainee *) element_courant);
  769: 
  770:                 element_courant = element_suivant;
  771:             }
  772: 
  773:             for(i = 0; i < (*s_etat_processus).nombre_instructions_externes;
  774:                     i++)
  775:             {
  776:                 free((*s_etat_processus).s_instructions_externes[i].nom);
  777:                 free((*s_etat_processus).s_instructions_externes[i]
  778:                         .nom_bibliotheque);
  779:             }
  780: 
  781:             if ((*s_etat_processus).nombre_instructions_externes != 0)
  782:             {
  783:                 free((*s_etat_processus).s_instructions_externes);
  784:             }
  785: 
  786:             element_courant = (*s_etat_processus).s_bibliotheques;
  787:             while(element_courant != NULL)
  788:             {
  789:                 element_suivant = (*((struct_liste_chainee *)
  790:                         element_courant)).suivant;
  791: 
  792:                 element_candidat = (*candidat).s_bibliotheques;
  793:                 while(element_candidat != NULL)
  794:                 {
  795:                     if (((*((struct_bibliotheque *) (*((struct_liste_chainee *)
  796:                             element_courant)).donnee))
  797:                             .descripteur == (*((struct_bibliotheque *)
  798:                             (*((struct_liste_chainee *) element_candidat))
  799:                             .donnee)).descripteur) &&
  800:                             ((*((struct_bibliotheque *)
  801:                             (*((struct_liste_chainee *) element_courant))
  802:                             .donnee)).pid == (*((struct_bibliotheque *)
  803:                             (*((struct_liste_chainee *) element_candidat))
  804:                             .donnee)).pid) && (pthread_equal(
  805:                             (*((struct_bibliotheque *)
  806:                             (*((struct_liste_chainee *) element_courant))
  807:                             .donnee)).tid, (*((struct_bibliotheque *)
  808:                             (*((struct_liste_chainee *) element_candidat))
  809:                             .donnee)).tid) != 0))
  810:                     {
  811:                         break;
  812:                     }
  813: 
  814:                     element_candidat = (*((struct_liste_chainee *)
  815:                             element_candidat)).suivant;
  816:                 }
  817: 
  818:                 if (element_candidat == NULL)
  819:                 {
  820:                     dlclose((*((struct_bibliotheque *)
  821:                             (*((struct_liste_chainee *) element_courant))
  822:                             .donnee)).descripteur);
  823:                 }
  824: 
  825:                 free((*((struct_bibliotheque *)
  826:                         (*((struct_liste_chainee *)
  827:                         element_courant)).donnee)).nom);
  828:                 free((*((struct_liste_chainee *) element_courant)).donnee);
  829:                 free(element_courant);
  830: 
  831:                 element_courant = element_suivant;
  832:             }
  833: 
  834:             element_courant = (*s_etat_processus).l_base_pile_last;
  835:             while(element_courant != NULL)
  836:             {
  837:                 element_suivant = (*((struct_liste_chainee *)
  838:                         element_courant)).suivant;
  839: 
  840:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  841:                         element_courant)).donnee).mutex));
  842:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  843:                         element_courant)).donnee).mutex));
  844:                 liberation(s_etat_processus,
  845:                         (*((struct_liste_chainee *) element_courant)).donnee);
  846:                 free(element_courant);
  847: 
  848:                 element_courant = element_suivant;
  849:             }
  850: 
  851:             element_courant = (*s_etat_processus).l_base_pile_systeme;
  852:             while(element_courant != NULL)
  853:             {
  854:                 element_suivant = (*((struct_liste_pile_systeme *)
  855:                         element_courant)).suivant;
  856: 
  857:                 if ((*((struct_liste_pile_systeme *)
  858:                         element_courant)).indice_boucle != NULL)
  859:                 {
  860:                     pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
  861:                             element_courant)).indice_boucle).mutex));
  862:                     pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
  863:                             element_courant)).indice_boucle).mutex));
  864:                 }
  865: 
  866:                 liberation(s_etat_processus,
  867:                         (*((struct_liste_pile_systeme *)
  868:                         element_courant)).indice_boucle);
  869: 
  870:                 if ((*((struct_liste_pile_systeme *)
  871:                         element_courant)).limite_indice_boucle != NULL)
  872:                 {
  873:                     pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
  874:                             element_courant)).limite_indice_boucle).mutex));
  875:                     pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
  876:                             element_courant)).limite_indice_boucle).mutex));
  877:                 }
  878: 
  879:                 liberation(s_etat_processus,
  880:                         (*((struct_liste_pile_systeme *)
  881:                         element_courant)).limite_indice_boucle);
  882: 
  883:                 if ((*((struct_liste_pile_systeme *)
  884:                         element_courant)).objet_de_test != NULL)
  885:                 {
  886:                     pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
  887:                             element_courant)).objet_de_test).mutex));
  888:                     pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
  889:                             element_courant)).objet_de_test).mutex));
  890:                 }
  891: 
  892:                 liberation(s_etat_processus,
  893:                         (*((struct_liste_pile_systeme *)
  894:                         element_courant)).objet_de_test);
  895: 
  896:                 if ((*((struct_liste_pile_systeme *)
  897:                         element_courant)).nom_variable != NULL)
  898:                 {
  899:                     free((*((struct_liste_pile_systeme *)
  900:                             element_courant)).nom_variable);
  901:                 }
  902: 
  903:                 free(element_courant);
  904: 
  905:                 element_courant = element_suivant;
  906:             }
  907: 
  908:             element_courant = (*s_etat_processus).s_fichiers;
  909:             while(element_courant != NULL)
  910:             {
  911:                 element_suivant = (*((struct_liste_chainee *)
  912:                         element_courant)).suivant;
  913: 
  914:                 element_candidat = (*candidat).s_fichiers;
  915:                 while(element_candidat != NULL)
  916:                 {
  917:                     if (((*((struct_descripteur_fichier *)
  918:                             (*((struct_liste_chainee *) element_courant))
  919:                             .donnee)).pid ==
  920:                             (*((struct_descripteur_fichier *)
  921:                             (*((struct_liste_chainee *) element_candidat))
  922:                             .donnee)).pid) && (pthread_equal(
  923:                             (*((struct_descripteur_fichier *)
  924:                             (*((struct_liste_chainee *) element_courant))
  925:                             .donnee)).tid, (*((struct_descripteur_fichier *)
  926:                             (*((struct_liste_chainee *) element_candidat))
  927:                             .donnee)).tid) != 0))
  928:                     {
  929:                         if ((*((struct_descripteur_fichier *)
  930:                                 (*((struct_liste_chainee *) element_courant))
  931:                                 .donnee)).type ==
  932:                                 (*((struct_descripteur_fichier *)
  933:                                 (*((struct_liste_chainee *) element_candidat))
  934:                                 .donnee)).type)
  935:                         {
  936:                             if ((*((struct_descripteur_fichier *)
  937:                                     (*((struct_liste_chainee *)
  938:                                     element_candidat)).donnee)).type == 'C')
  939:                             {
  940:                                 if ((*((struct_descripteur_fichier *)
  941:                                         (*((struct_liste_chainee *)
  942:                                         element_courant)).donnee))
  943:                                         .descripteur_c ==
  944:                                         (*((struct_descripteur_fichier *)
  945:                                         (*((struct_liste_chainee *)
  946:                                         element_candidat)).donnee))
  947:                                         .descripteur_c)
  948:                                 {
  949:                                     break;
  950:                                 }
  951:                             }
  952:                             else
  953:                             {
  954:                                 if (((*((struct_descripteur_fichier *)
  955:                                         (*((struct_liste_chainee *)
  956:                                         element_courant)).donnee))
  957:                                         .descripteur_sqlite ==
  958:                                         (*((struct_descripteur_fichier *)
  959:                                         (*((struct_liste_chainee *)
  960:                                         element_candidat)).donnee))
  961:                                         .descripteur_sqlite) &&
  962:                                         ((*((struct_descripteur_fichier *)
  963:                                         (*((struct_liste_chainee *)
  964:                                         element_courant)).donnee))
  965:                                         .descripteur_c ==
  966:                                         (*((struct_descripteur_fichier *)
  967:                                         (*((struct_liste_chainee *)
  968:                                         element_candidat)).donnee))
  969:                                         .descripteur_c))
  970:                                 {
  971:                                     break;
  972:                                 }
  973:                             }
  974:                         }
  975:                     }
  976: 
  977:                     element_candidat = (*((struct_liste_chainee *)
  978:                             element_candidat)).suivant;
  979:                 }
  980: 
  981:                 if (element_candidat == NULL)
  982:                 {
  983:                     fclose((*((struct_descripteur_fichier *)
  984:                             (*((struct_liste_chainee *) element_courant))
  985:                             .donnee)).descripteur_c);
  986: 
  987:                     if ((*((struct_descripteur_fichier *)
  988:                             (*((struct_liste_chainee *) element_courant))
  989:                             .donnee)).type != 'C')
  990:                     {
  991:                         sqlite3_close((*((struct_descripteur_fichier *)
  992:                                 (*((struct_liste_chainee *) element_courant))
  993:                                 .donnee)).descripteur_sqlite);
  994:                     }
  995:                 }
  996: 
  997:                 free((*((struct_descripteur_fichier *)
  998:                         (*((struct_liste_chainee *)
  999:                         element_courant)).donnee)).nom);
 1000:                 free((struct_descripteur_fichier *)
 1001:                         (*((struct_liste_chainee *)
 1002:                         element_courant)).donnee);
 1003:                 free(element_courant);
 1004: 
 1005:                 element_courant = element_suivant;
 1006:             }
 1007: 
 1008:             element_courant = (*s_etat_processus).s_sockets;
 1009:             while(element_courant != NULL)
 1010:             {
 1011:                 element_suivant = (*((struct_liste_chainee *)
 1012:                         element_courant)).suivant;
 1013: 
 1014:                 element_candidat = (*candidat).s_sockets;
 1015:                 while(element_candidat != NULL)
 1016:                 {
 1017:                     if (((*((struct_socket *)
 1018:                             (*((struct_liste_chainee *) element_courant))
 1019:                             .donnee)).socket == (*((struct_socket *)
 1020:                             (*((struct_liste_chainee *) element_candidat))
 1021:                             .donnee)).socket) &&
 1022:                             ((*((struct_socket *)
 1023:                             (*((struct_liste_chainee *) element_courant))
 1024:                             .donnee)).pid == (*((struct_socket *)
 1025:                             (*((struct_liste_chainee *) element_candidat))
 1026:                             .donnee)).pid) && (pthread_equal(
 1027:                             (*((struct_socket *)
 1028:                             (*((struct_liste_chainee *) element_courant))
 1029:                             .donnee)).tid, (*((struct_socket *)
 1030:                             (*((struct_liste_chainee *) element_candidat))
 1031:                             .donnee)).tid) != 0))
 1032:                     {
 1033:                         break;
 1034:                     }
 1035: 
 1036:                     element_candidat = (*((struct_liste_chainee *)
 1037:                             element_candidat)).suivant;
 1038:                 }
 1039: 
 1040:                 if (element_candidat == NULL)
 1041:                 {
 1042:                     if ((*((struct_socket *) (*((struct_liste_chainee *)
 1043:                             element_courant)).donnee)).socket_connectee
 1044:                             == d_vrai)
 1045:                     {
 1046:                         shutdown((*((struct_socket *)
 1047:                                 (*((struct_liste_chainee *) element_courant))
 1048:                                 .donnee)).socket, SHUT_RDWR);
 1049:                     }
 1050: 
 1051:                     close((*((struct_socket *)
 1052:                             (*((struct_liste_chainee *) element_courant))
 1053:                             .donnee)).socket);
 1054:                 }
 1055: 
 1056:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
 1057:                         element_courant)).donnee).mutex));
 1058:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
 1059:                         element_courant)).donnee).mutex));
 1060: 
 1061:                 liberation(s_etat_processus,
 1062:                         (*((struct_liste_chainee *)
 1063:                         element_courant)).donnee);
 1064:                 free(element_courant);
 1065: 
 1066:                 element_courant = element_suivant;
 1067:             }
 1068: 
 1069:             element_courant = (*s_etat_processus).s_connecteurs_sql;
 1070:             while(element_courant != NULL)
 1071:             {
 1072:                 element_suivant = (*((struct_liste_chainee *)
 1073:                         element_courant)).suivant;
 1074: 
 1075:                 element_candidat = (*candidat).s_connecteurs_sql;
 1076:                 while(element_candidat != NULL)
 1077:                 {
 1078:                     if (((
 1079: #ifdef MYSQL_SUPPORT
 1080:                             ((*((struct_connecteur_sql *)
 1081:                             (*((struct_liste_chainee *) element_courant))
 1082:                             .donnee)).descripteur.mysql ==
 1083:                             (*((struct_connecteur_sql *)
 1084:                             (*((struct_liste_chainee *) element_candidat))
 1085:                             .donnee)).descripteur.mysql)
 1086:                             &&
 1087:                             (strcmp((*((struct_connecteur_sql *)
 1088:                             (*((struct_liste_chainee *) element_courant))
 1089:                             .donnee)).type, "MYSQL") == 0)
 1090:                             &&
 1091:                             (strcmp((*((struct_connecteur_sql *)
 1092:                             (*((struct_liste_chainee *) element_candidat))
 1093:                             .donnee)).type, "MYSQL") == 0)
 1094: #else
 1095:                             0
 1096: #endif
 1097:                             ) || (
 1098: #ifdef POSTGRESQL_SUPPORT
 1099:                             ((*((struct_connecteur_sql *)
 1100:                             (*((struct_liste_chainee *) element_courant))
 1101:                             .donnee)).descripteur.postgresql ==
 1102:                             (*((struct_connecteur_sql *)
 1103:                             (*((struct_liste_chainee *) element_candidat))
 1104:                             .donnee)).descripteur.postgresql)
 1105:                             &&
 1106:                             (strcmp((*((struct_connecteur_sql *)
 1107:                             (*((struct_liste_chainee *) element_courant))
 1108:                             .donnee)).type, "POSTGRESQL") == 0)
 1109:                             &&
 1110:                             (strcmp((*((struct_connecteur_sql *)
 1111:                             (*((struct_liste_chainee *) element_candidat))
 1112:                             .donnee)).type, "POSTGRESQL") == 0)
 1113: #else
 1114:                             0
 1115: #endif
 1116:                             )) &&
 1117:                             ((*((struct_connecteur_sql *)
 1118:                             (*((struct_liste_chainee *) element_courant))
 1119:                             .donnee)).pid == (*((struct_connecteur_sql *)
 1120:                             (*((struct_liste_chainee *) element_candidat))
 1121:                             .donnee)).pid) && (pthread_equal(
 1122:                             (*((struct_connecteur_sql *)
 1123:                             (*((struct_liste_chainee *) element_courant))
 1124:                             .donnee)).tid, (*((struct_connecteur_sql *)
 1125:                             (*((struct_liste_chainee *) element_candidat))
 1126:                             .donnee)).tid) != 0))
 1127:                     {
 1128:                         break;
 1129:                     }
 1130: 
 1131:                     element_candidat = (*((struct_liste_chainee *)
 1132:                             element_candidat)).suivant;
 1133:                 }
 1134: 
 1135:                 if (element_candidat == NULL)
 1136:                 {
 1137:                     sqlclose((*((struct_liste_chainee *) element_courant))
 1138:                             .donnee);
 1139:                 }
 1140: 
 1141:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
 1142:                         element_courant)).donnee).mutex));
 1143:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
 1144:                         element_courant)).donnee).mutex));
 1145: 
 1146:                 liberation(s_etat_processus, (*((struct_liste_chainee *)
 1147:                         element_courant)).donnee);
 1148:                 free(element_courant);
 1149: 
 1150:                 element_courant = element_suivant;
 1151:             }
 1152: 
 1153:             element_courant = (*s_etat_processus).s_marques;
 1154:             while(element_courant != NULL)
 1155:             {
 1156:                 free((*((struct_marque *) element_courant)).label);
 1157:                 free((*((struct_marque *) element_courant)).position);
 1158:                 element_suivant = (*((struct_marque *) element_courant))
 1159:                         .suivant;
 1160:                 free(element_courant);
 1161:                 element_courant = element_suivant;
 1162:             }
 1163: 
 1164:             liberation_allocateur(s_etat_processus);
 1165: 
 1166:             sem_post(&((*s_etat_processus).semaphore_fork));
 1167:             sem_destroy(&((*s_etat_processus).semaphore_fork));
 1168: 
 1169:             free(s_etat_processus);
 1170: 
 1171:             s_etat_processus = candidat;
 1172:         }
 1173: 
 1174:         l_element_suivant = (*l_element_courant).suivant;
 1175: 
 1176:         free((struct_thread *) (*l_element_courant).donnee);
 1177:         free((struct_liste_chainee *) l_element_courant);
 1178: 
 1179:         l_element_courant = l_element_suivant;
 1180:     }
 1181: 
 1182:     liste_threads = NULL;
 1183: 
 1184:     l_element_courant = liste_threads_surveillance;
 1185: 
 1186:     while(l_element_courant != NULL)
 1187:     {
 1188:         s_argument_thread = (struct_descripteur_thread *)
 1189:                 (*l_element_courant).donnee;
 1190: 
 1191:         close((*s_argument_thread).pipe_objets[0]);
 1192:         close((*s_argument_thread).pipe_acquittement[1]);
 1193:         close((*s_argument_thread).pipe_injections[1]);
 1194:         close((*s_argument_thread).pipe_nombre_injections[1]);
 1195:         close((*s_argument_thread).pipe_nombre_objets_attente[0]);
 1196:         close((*s_argument_thread).pipe_interruptions[0]);
 1197:         close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);
 1198: 
 1199:         if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)
 1200:         {
 1201:             (*s_etat_processus).erreur_systeme = d_es_processus;
 1202:             return;
 1203:         }
 1204: 
 1205:         (*s_argument_thread).nombre_references--;
 1206: 
 1207:         BUG((*s_argument_thread).nombre_references < 0,
 1208:                 printf("(*s_argument_thread).nombre_references = %d\n",
 1209:                 (int) (*s_argument_thread).nombre_references));
 1210: 
 1211:         if ((*s_argument_thread).nombre_references == 0)
 1212:         {
 1213:             if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
 1214:             {
 1215:                 (*s_etat_processus).erreur_systeme = d_es_processus;
 1216:                 return;
 1217:             }
 1218: 
 1219:             pthread_mutex_destroy(&((*s_argument_thread).mutex));
 1220:             free(s_argument_thread);
 1221:         }
 1222:         else
 1223:         {
 1224:             if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
 1225:             {
 1226:                 (*s_etat_processus).erreur_systeme = d_es_processus;
 1227:                 return;
 1228:             }
 1229:         }
 1230: 
 1231:         l_element_suivant = (*l_element_courant).suivant;
 1232:         free((struct_liste_chainee *) l_element_courant);
 1233:         l_element_courant = l_element_suivant;
 1234:     }
 1235: 
 1236:     liste_threads_surveillance = NULL;
 1237: 
 1238:     if (sem_post(&semaphore_liste_threads) != 0)
 1239:     {
 1240:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1241:         (*s_etat_processus).erreur_systeme = d_es_processus;
 1242:         return;
 1243:     }
 1244: 
 1245:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1246:     sigpending(&set);
 1247:     return;
 1248: }
 1249: 
 1250: static struct_processus *
 1251: recherche_thread(pid_t pid, pthread_t tid)
 1252: {
 1253:     volatile struct_liste_chainee_volatile      *l_element_courant;
 1254: 
 1255:     struct_processus                            *s_etat_processus;
 1256: 
 1257:     l_element_courant = liste_threads;
 1258: 
 1259:     while(l_element_courant != NULL)
 1260:     {
 1261:         if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee))
 1262:                 .tid, tid) != 0) && ((*((struct_thread *)
 1263:                 (*l_element_courant).donnee)).pid == pid))
 1264:         {
 1265:             break;
 1266:         }
 1267: 
 1268:         l_element_courant = (*l_element_courant).suivant;
 1269:     }
 1270: 
 1271:     if (l_element_courant == NULL)
 1272:     {
 1273:         /*
 1274:          * Le processus n'existe plus. On ne distribue aucun signal.
 1275:          */
 1276: 
 1277:         return(NULL);
 1278:     }
 1279: 
 1280:     s_etat_processus = (*((struct_thread *)
 1281:             (*l_element_courant).donnee)).s_etat_processus;
 1282: 
 1283:     return(s_etat_processus);
 1284: }
 1285: 
 1286: static logical1
 1287: recherche_thread_principal(pid_t pid, pthread_t *thread)
 1288: {
 1289:     volatile struct_liste_chainee_volatile      *l_element_courant;
 1290: 
 1291:     l_element_courant = liste_threads;
 1292: 
 1293:     while(l_element_courant != NULL)
 1294:     {
 1295:         if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal
 1296:                 == d_vrai) && ((*((struct_thread *)
 1297:                 (*l_element_courant).donnee)).pid == pid))
 1298:         {
 1299:             break;
 1300:         }
 1301: 
 1302:         l_element_courant = (*l_element_courant).suivant;
 1303:     }
 1304: 
 1305:     if (l_element_courant == NULL)
 1306:     {
 1307:         /*
 1308:          * Le processus n'existe plus. On ne distribue aucun signal.
 1309:          */
 1310: 
 1311:         return(d_faux);
 1312:     }
 1313: 
 1314:     (*thread) = (*((struct_thread *) (*l_element_courant).donnee)).tid;
 1315: 
 1316:     return(d_vrai);
 1317: }
 1318: 
 1319: 
 1320: /*
 1321: ================================================================================
 1322:   Procédures de gestion des signaux d'interruption
 1323: ================================================================================
 1324:   Entrée : variable globale
 1325: --------------------------------------------------------------------------------
 1326:   Sortie : variable globale modifiée
 1327: --------------------------------------------------------------------------------
 1328:   Effets de bord : néant
 1329: ================================================================================
 1330: */
 1331: 
 1332: // Les routines suivantes sont uniquement appelées depuis les gestionnaires
 1333: // des signaux asynchrones. Elles de doivent pas bloquer dans le cas où
 1334: // les sémaphores sont déjà bloqués par un gestionnaire de signal.
 1335: 
 1336: static inline void
 1337: verrouillage_gestionnaire_signaux()
 1338: {
 1339:     int         semaphore;
 1340: 
 1341:     sigset_t    oldset;
 1342:     sigset_t    set;
 1343: 
 1344:     sem_t       *sem;
 1345: 
 1346:     if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
 1347:             != NULL)
 1348:     {
 1349:         if (sem_post(sem) != 0)
 1350:         {
 1351:             BUG(1, uprintf("Lock error !\n"));
 1352:             return;
 1353:         }
 1354:     }
 1355: 
 1356:     // Il faut respecteur l'atomicité des deux opérations suivantes !
 1357: 
 1358:     sigfillset(&set);
 1359:     pthread_sigmask(SIG_BLOCK, &set, &oldset);
 1360: 
 1361:     while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
 1362:     {
 1363:         if (errno != EINTR)
 1364:         {
 1365:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1366:             BUG(1, uprintf("Unlock error !\n"));
 1367:             return;
 1368:         }
 1369:     }
 1370: 
 1371:     if (sem_post(&semaphore_gestionnaires_signaux) == -1)
 1372:     {
 1373:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1374:         BUG(1, uprintf("Lock error !\n"));
 1375:         return;
 1376:     }
 1377: 
 1378:     if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
 1379:     {
 1380:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1381:         BUG(1, uprintf("Lock error !\n"));
 1382:         return;
 1383:     }
 1384: 
 1385:     if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
 1386:     {
 1387:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1388:         BUG(1, uprintf("Unlock error !\n"));
 1389:         return;
 1390:     }
 1391: 
 1392:     if (semaphore == 1)
 1393:     {
 1394:         // Le semaphore ne peut être pris par le thread qui a appelé
 1395:         // le gestionnaire de signal car le signal est bloqué par ce thread
 1396:         // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que
 1397:         // par un thread concurrent. On essaye donc de le bloquer jusqu'à
 1398:         // ce que ce soit possible.
 1399: 
 1400:         while(sem_trywait(&semaphore_liste_threads) == -1)
 1401:         {
 1402:             if ((errno != EINTR) && (errno != EAGAIN))
 1403:             {
 1404:                 pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1405: 
 1406:                 while(sem_wait(sem) == -1)
 1407:                 {
 1408:                     if (errno != EINTR)
 1409:                     {
 1410:                         BUG(1, uprintf("Lock error !\n"));
 1411:                         return;
 1412:                     }
 1413:                 }
 1414: 
 1415:                 BUG(1, uprintf("Lock error !\n"));
 1416:                 return;
 1417:             }
 1418: 
 1419:             sched_yield();
 1420:         }
 1421:     }
 1422: 
 1423:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1424:     sigpending(&set);
 1425: 
 1426:     return;
 1427: }
 1428: 
 1429: static inline void
 1430: deverrouillage_gestionnaire_signaux()
 1431: {
 1432:     int         semaphore;
 1433: 
 1434:     sem_t       *sem;
 1435: 
 1436:     sigset_t    oldset;
 1437:     sigset_t    set;
 1438: 
 1439:     // Il faut respecteur l'atomicité des deux opérations suivantes !
 1440: 
 1441:     sigfillset(&set);
 1442:     pthread_sigmask(SIG_BLOCK, &set, &oldset);
 1443: 
 1444:     while(sem_wait(&semaphore_gestionnaires_signaux_atomique) == -1)
 1445:     {
 1446:         if (errno != EINTR)
 1447:         {
 1448:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1449:             BUG(1, uprintf("Unlock error !\n"));
 1450:             return;
 1451:         }
 1452:     }
 1453: 
 1454:     if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
 1455:     {
 1456:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1457:         BUG(1, uprintf("Unlock error !\n"));
 1458:         return;
 1459:     }
 1460: 
 1461:     while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
 1462:     {
 1463:         if (errno != EINTR)
 1464:         {
 1465:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1466:             BUG(1, uprintf("Unlock error !\n"));
 1467:             return;
 1468:         }
 1469:     }
 1470: 
 1471:     if (sem_post(&semaphore_gestionnaires_signaux_atomique) != 0)
 1472:     {
 1473:         pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1474:         BUG(1, uprintf("Unlock error !\n"));
 1475:         return;
 1476:     }
 1477: 
 1478:     if ((sem = pthread_getspecific(semaphore_fork_processus_courant))
 1479:             != NULL)
 1480:     {
 1481:         while(sem_wait(sem) == -1)
 1482:         {
 1483:             if (errno != EINTR)
 1484:             {
 1485:                 pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1486:                 BUG(1, uprintf("Unlock error !\n"));
 1487:                 return;
 1488:             }
 1489:         }
 1490:     }
 1491: 
 1492:     if (semaphore == 1)
 1493:     {
 1494:         if (sem_post(&semaphore_liste_threads) != 0)
 1495:         {
 1496:             pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1497: 
 1498:             BUG(1, uprintf("Unlock error !\n"));
 1499:             return;
 1500:         }
 1501:     }
 1502: 
 1503:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 1504:     sigpending(&set);
 1505: 
 1506:     return;
 1507: }
 1508: 
 1509: void
 1510: interruption1(int signal, siginfo_t *siginfo, void *context)
 1511: {
 1512:     pthread_t               thread;
 1513: 
 1514:     struct_processus        *s_etat_processus;
 1515: 
 1516:     volatile sig_atomic_t   exclusion = 0;
 1517: 
 1518:     verrouillage_gestionnaire_signaux();
 1519: 
 1520:     switch(signal)
 1521:     {
 1522:         case SIGALRM :
 1523:         {
 1524:             if ((*siginfo).si_pid == getpid())
 1525:             {
 1526:                 if ((s_etat_processus = recherche_thread(getpid(),
 1527:                         pthread_self())) == NULL)
 1528:                 {
 1529:                     deverrouillage_gestionnaire_signaux();
 1530:                     return;
 1531:                 }
 1532: 
 1533:                 if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1534:                 {
 1535:                     printf("[%d] SIGALRM (thread %llu)\n", (int) getpid(),
 1536:                             (unsigned long long) pthread_self());
 1537:                     fflush(stdout);
 1538:                 }
 1539: 
 1540:                 if ((*s_etat_processus).pid_processus_pere != getpid())
 1541:                 {
 1542:                     kill((*s_etat_processus).pid_processus_pere, signal);
 1543:                 }
 1544:                 else
 1545:                 {
 1546:                     (*s_etat_processus).var_volatile_alarme = -1;
 1547:                     (*s_etat_processus).var_volatile_requete_arret = -1;
 1548:                 }
 1549:             }
 1550:             else
 1551:             {
 1552:                 if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 1553:                 {
 1554:                     pthread_kill(thread, signal);
 1555:                 }
 1556:             }
 1557: 
 1558:             break;
 1559:         }
 1560: 
 1561:         case SIGINT :
 1562:         {
 1563:             /*
 1564:              * Une vieille spécification POSIX permet au pointeur siginfo
 1565:              * d'être nul dans le cas d'un ^C envoyé depuis le clavier.
 1566:              * Solaris suit en particulier cette spécification.
 1567:              */
 1568: 
 1569:             if (siginfo == NULL)
 1570:             {
 1571:                 kill(getpid(), signal);
 1572:             }
 1573:             else if ((*siginfo).si_pid == getpid())
 1574:             {
 1575:                 if ((s_etat_processus = recherche_thread(getpid(),
 1576:                         pthread_self())) == NULL)
 1577:                 {
 1578:                     deverrouillage_gestionnaire_signaux();
 1579:                     return;
 1580:                 }
 1581: 
 1582:                 if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1583:                 {
 1584:                     printf("[%d] SIGINT (thread %llu)\n", (int) getpid(),
 1585:                             (unsigned long long) pthread_self());
 1586:                     fflush(stdout);
 1587:                 }
 1588: 
 1589:                 if ((*s_etat_processus).pid_processus_pere != getpid())
 1590:                 {
 1591:                     kill((*s_etat_processus).pid_processus_pere, signal);
 1592:                 }
 1593:                 else
 1594:                 {
 1595:                     (*s_etat_processus).var_volatile_traitement_sigint = -1;
 1596: 
 1597:                     while(exclusion == 1);
 1598:                     exclusion = 1;
 1599: 
 1600:                     if ((*s_etat_processus).var_volatile_requete_arret == -1)
 1601:                     {
 1602:                         deverrouillage_gestionnaire_signaux();
 1603:                         exclusion = 0;
 1604:                         return;
 1605:                     }
 1606: 
 1607:                     if (strncmp(getenv("LANG"), "fr", 2) == 0)
 1608:                     {
 1609:                         printf("+++Interruption\n");
 1610:                     }
 1611:                     else
 1612:                     {
 1613:                         printf("+++Interrupt\n");
 1614:                     }
 1615: 
 1616:                     fflush(stdout);
 1617: 
 1618:                     (*s_etat_processus).var_volatile_requete_arret = -1;
 1619:                     (*s_etat_processus).var_volatile_alarme = -1;
 1620: 
 1621:                     exclusion = 0;
 1622:                 }
 1623:             }
 1624:             else
 1625:             {
 1626:                 if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 1627:                 {
 1628:                     pthread_kill(thread, signal);
 1629:                 }
 1630:             }
 1631: 
 1632:             break;
 1633:         }
 1634: 
 1635:         default :
 1636:         {
 1637:             BUG(1, uprintf("[%d] Unknown signal %d in this context\n",
 1638:                     (int) getpid(), signal));
 1639:             break;
 1640:         }
 1641:     }
 1642: 
 1643:     deverrouillage_gestionnaire_signaux();
 1644:     return;
 1645: }
 1646: 
 1647: void
 1648: interruption2(int signal, siginfo_t *siginfo, void *context)
 1649: {
 1650:     pthread_t               thread;
 1651:     struct_processus        *s_etat_processus;
 1652: 
 1653:     verrouillage_gestionnaire_signaux();
 1654: 
 1655:     if (siginfo == NULL)
 1656:     {
 1657:         /*
 1658:          * Le signal SIGFSTP provient de la mort du processus de contrôle.
 1659:          * Sous certains systèmes (Linux...), la mort du terminal de contrôle
 1660:          * se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
 1661:          * (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
 1662:          * non initialisée (pointeur NULL) issue de TERMIO.
 1663:          */
 1664: 
 1665:         if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 1666:         {
 1667:             pthread_kill(thread, SIGHUP);
 1668:             deverrouillage_gestionnaire_signaux();
 1669:             return;
 1670:         }
 1671:     }
 1672:     else if ((*siginfo).si_pid == getpid())
 1673:     {
 1674:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 1675:                 == NULL)
 1676:         {
 1677:             deverrouillage_gestionnaire_signaux();
 1678:             return;
 1679:         }
 1680: 
 1681:         /*
 1682:          *  0 => fonctionnement normal
 1683:          * -1 => requête
 1684:          *  1 => requête acceptée en attente de traitement
 1685:          */
 1686: 
 1687:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1688:         {
 1689:             printf("[%d] SIGTSTP (thread %llu)\n", (int) getpid(),
 1690:                     (unsigned long long) pthread_self());
 1691:             fflush(stdout);
 1692:         }
 1693: 
 1694:         if ((*s_etat_processus).var_volatile_processus_pere == 0)
 1695:         {
 1696:             kill((*s_etat_processus).pid_processus_pere, signal);
 1697:         }
 1698:         else
 1699:         {
 1700:             (*s_etat_processus).var_volatile_requete_arret2 = -1;
 1701:         }
 1702:     }
 1703:     else
 1704:     {
 1705:         // Envoi d'un signal au thread maître du groupe.
 1706: 
 1707:         if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 1708:         {
 1709:             pthread_kill(thread, SIGTSTP);
 1710:             deverrouillage_gestionnaire_signaux();
 1711:             return;
 1712:         }
 1713:     }
 1714: 
 1715:     deverrouillage_gestionnaire_signaux();
 1716:     return;
 1717: }
 1718: 
 1719: void
 1720: interruption3(int signal, siginfo_t *siginfo, void *context)
 1721: {
 1722:     struct_processus        *s_etat_processus;
 1723: 
 1724:     static int              compteur = 0;
 1725: 
 1726:     verrouillage_gestionnaire_signaux();
 1727: 
 1728:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 1729:     {
 1730:         deverrouillage_gestionnaire_signaux();
 1731:         return;
 1732:     }
 1733: 
 1734:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1735:     {
 1736:         printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),
 1737:                 (unsigned long long) pthread_self());
 1738:         fflush(stdout);
 1739:     }
 1740: 
 1741:     if ((*s_etat_processus).var_volatile_recursivite == -1)
 1742:     {
 1743:         // Segfault dans un appel de fonction récursive
 1744:         deverrouillage_gestionnaire_signaux();
 1745:         longjmp(contexte, -1);
 1746:     }
 1747:     else
 1748:     {
 1749:         // Segfault dans une routine interne
 1750:         if (strncmp(getenv("LANG"), "fr", 2) == 0)
 1751:         {
 1752:             printf("+++Système : Violation d'accès (dépassement de pile)\n");
 1753:         }
 1754:         else
 1755:         {
 1756:             printf("+++System : Access violation (stack overflow)\n");
 1757:         }
 1758: 
 1759:         fflush(stdout);
 1760: 
 1761:         compteur++;
 1762: 
 1763:         if (compteur > 1)
 1764:         {
 1765:             deverrouillage_gestionnaire_signaux();
 1766:             exit(EXIT_FAILURE);
 1767:         }
 1768:         else
 1769:         {
 1770:             deverrouillage_gestionnaire_signaux();
 1771:             longjmp(contexte_initial, -1);
 1772:         }
 1773:     }
 1774: 
 1775:     deverrouillage_gestionnaire_signaux();
 1776:     return;
 1777: }
 1778: 
 1779: void
 1780: interruption4(int signal, siginfo_t *siginfo, void *context)
 1781: {
 1782:     struct_processus        *s_etat_processus;
 1783: 
 1784:     verrouillage_gestionnaire_signaux();
 1785: 
 1786:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 1787:     {
 1788:         deverrouillage_gestionnaire_signaux();
 1789:         return;
 1790:     }
 1791: 
 1792:     /*
 1793:      * Démarrage d'un processus fils ou gestion de SIGCONT (SUSPEND)
 1794:      */
 1795: 
 1796:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1797:     {
 1798:         printf("[%d] SIGSTART/SIGCONT (thread %llu)\n", (int) getpid(),
 1799:                 (unsigned long long) pthread_self());
 1800:         fflush(stdout);
 1801:     }
 1802: 
 1803:     deverrouillage_gestionnaire_signaux();
 1804:     return;
 1805: }
 1806: 
 1807: void
 1808: interruption5(int signal, siginfo_t *siginfo, void *context)
 1809: {
 1810:     pthread_t               thread;
 1811:     struct_processus        *s_etat_processus;
 1812: 
 1813:     verrouillage_gestionnaire_signaux();
 1814: 
 1815:     if ((*siginfo).si_pid == getpid())
 1816:     {
 1817:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 1818:                 == NULL)
 1819:         {
 1820:             deverrouillage_gestionnaire_signaux();
 1821:             return;
 1822:         }
 1823: 
 1824:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1825:         {
 1826:             printf("[%d] SIGFSTOP (thread %llu)\n", (int) getpid(),
 1827:                     (unsigned long long) pthread_self());
 1828:             fflush(stdout);
 1829:         }
 1830: 
 1831:         /*
 1832:          * var_globale_traitement_retarde_stop :
 1833:          *  0 -> traitement immédiat
 1834:          *  1 -> traitement retardé (aucun signal reçu)
 1835:          * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
 1836:          */
 1837: 
 1838:         if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
 1839:         {
 1840:             (*s_etat_processus).var_volatile_requete_arret = -1;
 1841:         }
 1842:         else
 1843:         {
 1844:             (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
 1845:         }
 1846:     }
 1847:     else
 1848:     {
 1849:         // Envoi d'un signal au thread maître du groupe.
 1850: 
 1851:         if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 1852:         {
 1853:             pthread_kill(thread, SIGFSTOP);
 1854:             deverrouillage_gestionnaire_signaux();
 1855:             return;
 1856:         }
 1857:     }
 1858: 
 1859:     deverrouillage_gestionnaire_signaux();
 1860:     return;
 1861: }
 1862: 
 1863: void
 1864: interruption6(int signal, siginfo_t *siginfo, void *context)
 1865: {
 1866:     struct_processus        *s_etat_processus;
 1867: 
 1868:     verrouillage_gestionnaire_signaux();
 1869: 
 1870:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 1871:     {
 1872:         deverrouillage_gestionnaire_signaux();
 1873:         return;
 1874:     }
 1875: 
 1876:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1877:     {
 1878:         printf("[%d] SIGINJECT/SIGQUIT (thread %llu)\n", (int) getpid(),
 1879:                 (unsigned long long) pthread_self());
 1880:         fflush(stdout);
 1881:     }
 1882: 
 1883:     deverrouillage_gestionnaire_signaux();
 1884:     return;
 1885: }
 1886: 
 1887: void
 1888: interruption7(int signal, siginfo_t *siginfo, void *context)
 1889: {
 1890:     struct_processus        *s_etat_processus;
 1891: 
 1892:     verrouillage_gestionnaire_signaux();
 1893: 
 1894:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 1895:     {
 1896:         deverrouillage_gestionnaire_signaux();
 1897:         return;
 1898:     }
 1899: 
 1900:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1901:     {
 1902:         printf("[%d] SIGPIPE (thread %llu)\n", (int) getpid(),
 1903:                 (unsigned long long) pthread_self());
 1904:         fflush(stdout);
 1905:     }
 1906: 
 1907:     (*s_etat_processus).var_volatile_requete_arret = -1;
 1908:     deverrouillage_gestionnaire_signaux();
 1909: 
 1910:     BUG(1, printf("[%d] SIGPIPE\n", (int) getpid()));
 1911:     return;
 1912: }
 1913: 
 1914: void
 1915: interruption8(int signal, siginfo_t *siginfo, void *context)
 1916: {
 1917:     pthread_t               thread;
 1918:     struct_processus        *s_etat_processus;
 1919: 
 1920:     verrouillage_gestionnaire_signaux();
 1921: 
 1922:     if ((*siginfo).si_pid == getpid())
 1923:     {
 1924:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 1925:                 == NULL)
 1926:         {
 1927:             deverrouillage_gestionnaire_signaux();
 1928:             return;
 1929:         }
 1930: 
 1931:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1932:         {
 1933:             printf("[%d] SIGURG (thread %llu)\n", (int) getpid(),
 1934:                     (unsigned long long) pthread_self());
 1935:             fflush(stdout);
 1936:         }
 1937: 
 1938:         (*s_etat_processus).var_volatile_alarme = -1;
 1939:         (*s_etat_processus).var_volatile_requete_arret = -1;
 1940:     }
 1941:     else
 1942:     {
 1943:         // Envoi d'un signal au thread maître du groupe.
 1944: 
 1945:         if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 1946:         {
 1947:             pthread_kill(thread, SIGURG);
 1948:             deverrouillage_gestionnaire_signaux();
 1949:             return;
 1950:         }
 1951:     }
 1952: 
 1953:     deverrouillage_gestionnaire_signaux();
 1954:     return;
 1955: }
 1956: 
 1957: void
 1958: interruption9(int signal, siginfo_t *siginfo, void *context)
 1959: {
 1960:     struct_processus        *s_etat_processus;
 1961: 
 1962:     verrouillage_gestionnaire_signaux();
 1963: 
 1964:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 1965:     {
 1966:         deverrouillage_gestionnaire_signaux();
 1967:         return;
 1968:     }
 1969: 
 1970:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1971:     {
 1972:         printf("[%d] SIGABORT/SIGPROF (thread %llu)\n", (int) getpid(),
 1973:                 (unsigned long long) pthread_self());
 1974:         fflush(stdout);
 1975:     }
 1976: 
 1977:     pthread_kill((*s_etat_processus).tid_processus_pere, SIGFSTOP);
 1978:     deverrouillage_gestionnaire_signaux();
 1979:     return;
 1980: }
 1981: 
 1982: void
 1983: interruption10(int signal, siginfo_t *siginfo, void *context)
 1984: {
 1985:     file                    *fichier;
 1986: 
 1987:     struct_processus        *s_etat_processus;
 1988: 
 1989:     unsigned char           nom[8 + 64 + 1];
 1990: 
 1991:     verrouillage_gestionnaire_signaux();
 1992: 
 1993:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 1994:     {
 1995:         deverrouillage_gestionnaire_signaux();
 1996:         return;
 1997:     }
 1998: 
 1999:     snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
 2000:             (unsigned long) pthread_self());
 2001: 
 2002:     if ((fichier = fopen(nom, "w+")) != NULL)
 2003:     {
 2004:         fclose(fichier);
 2005: 
 2006:         freopen(nom, "w", stdout);
 2007:         freopen(nom, "w", stderr);
 2008:     }
 2009: 
 2010:     freopen("/dev/null", "r", stdin);
 2011: 
 2012:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2013:     {
 2014:         printf("[%d] SIGHUP (thread %llu)\n", (int) getpid(),
 2015:                 (unsigned long long) pthread_self());
 2016:         fflush(stdout);
 2017:     }
 2018: 
 2019:     deverrouillage_gestionnaire_signaux();
 2020:     return;
 2021: }
 2022: 
 2023: void
 2024: traitement_exceptions_gsl(const char *reason, const char *file,
 2025:         int line, int gsl_errno)
 2026: {
 2027:     struct_processus        *s_etat_processus;
 2028: 
 2029:     verrouillage_gestionnaire_signaux();
 2030: 
 2031:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2032:     {
 2033:         deverrouillage_gestionnaire_signaux();
 2034:         return;
 2035:     }
 2036: 
 2037:     (*s_etat_processus).var_volatile_exception_gsl = gsl_errno;
 2038:     deverrouillage_gestionnaire_signaux();
 2039:     return;
 2040: }
 2041: 
 2042: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>