File:  [local] / rpl / src / interruptions.c
Revision 1.131: download - view: text, annotated - select for diffs - revision graph
Thu May 23 12:45:08 2013 UTC (10 years, 11 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Correction d'autres mutexes...

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

CVSweb interface <joel.bertrand@systella.fr>