File:  [local] / rpl / src / interruptions.c
Revision 1.105: download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 15:27:45 2012 UTC (11 years, 6 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Début de la refonte des signaux pour NetBSD.

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

CVSweb interface <joel.bertrand@systella.fr>