File:  [local] / rpl / src / interruptions.c
Revision 1.104: download - view: text, annotated - select for diffs - revision graph
Fri Oct 5 13:12:39 2012 UTC (11 years, 6 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Seconde série de patches pour intégrer les variables statiques à l'arbre
des variables. Cela compile sans warning mais n'a pas été testé. Au passage, la
condition de dépassement des puissances entières d'un argument réel ou complexe
a été corrigée.

    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: 
 1634:     return;
 1635: }
 1636: 
 1637: inline static void
 1638: signal_alrm(struct_processus *s_etat_processus, pid_t pid)
 1639: {
 1640:     struct_processus        *s_thread_principal;
 1641: 
 1642:     verrouillage_gestionnaire_signaux(s_etat_processus);
 1643: 
 1644:     if (pid == getpid())
 1645:     {
 1646:         // Si pid est égal à getpid(), le signal à traiter est issu
 1647:         // du même processus que celui qui va le traiter, mais d'un thread
 1648:         // différent.
 1649: 
 1650:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1651:         {
 1652:             printf("[%d] RPL/SIGALRM (thread %llu)\n", (int) getpid(),
 1653:                     (unsigned long long) pthread_self());
 1654:             fflush(stdout);
 1655:         }
 1656: 
 1657:         if ((*s_etat_processus).pid_processus_pere != getpid())
 1658:         {
 1659:             // On n'est pas dans le processus père, on remonte le signal.
 1660:             envoi_signal_processus((*s_etat_processus).pid_processus_pere,
 1661:                     rpl_sigalrm);
 1662:         }
 1663:         else
 1664:         {
 1665:             // On est dans le processus père, on effectue un arrêt d'urgence.
 1666:             (*s_etat_processus).var_volatile_alarme = -1;
 1667:             (*s_etat_processus).var_volatile_requete_arret = -1;
 1668:         }
 1669:     }
 1670:     else
 1671:     {
 1672:         // Le signal est issu d'un processus différent. On recherche le
 1673:         // thread principal pour remonter le signal.
 1674: 
 1675:         if ((s_thread_principal = recherche_thread_principal(getpid()))
 1676:                 != NULL)
 1677:         {
 1678:             envoi_signal_contexte(s_thread_principal, rpl_sigalrm);
 1679:         }
 1680:     }
 1681: 
 1682:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 1683:     return;
 1684: }
 1685: 
 1686: inline static void
 1687: signal_term(struct_processus *s_etat_processus, pid_t pid)
 1688: {
 1689:     struct_processus        *s_thread_principal;
 1690:     pthread_mutex_t         exclusion = PTHREAD_MUTEX_INITIALIZER;
 1691: 
 1692:     verrouillage_gestionnaire_signaux(s_etat_processus);
 1693: 
 1694:     if (pid == getpid())
 1695:     {
 1696:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1697:         {
 1698:             printf("[%d] RPL/SIGTERM (thread %llu)\n", (int) getpid(),
 1699:                     (unsigned long long) pthread_self());
 1700:             fflush(stdout);
 1701:         }
 1702: 
 1703:         if ((*s_etat_processus).pid_processus_pere != getpid())
 1704:         {
 1705:             envoi_signal_processus((*s_etat_processus).pid_processus_pere,
 1706:                     rpl_sigterm);
 1707:         }
 1708:         else
 1709:         {
 1710:             (*s_etat_processus).var_volatile_traitement_sigint = -1;
 1711: 
 1712:             pthread_mutex_lock(&exclusion);
 1713: 
 1714:             if ((*s_etat_processus).var_volatile_requete_arret == -1)
 1715:             {
 1716:                 deverrouillage_gestionnaire_signaux(s_etat_processus);
 1717:                 pthread_mutex_unlock(&exclusion);
 1718:                 return;
 1719:             }
 1720: 
 1721:             (*s_etat_processus).var_volatile_requete_arret = -1;
 1722:             (*s_etat_processus).var_volatile_alarme = -1;
 1723: 
 1724:             pthread_mutex_unlock(&exclusion);
 1725:         }
 1726:     }
 1727:     else
 1728:     {
 1729:         if ((s_thread_principal = recherche_thread_principal(getpid()))
 1730:                 != NULL)
 1731:         {
 1732:             envoi_signal_contexte(s_thread_principal, rpl_sigterm);
 1733:         }
 1734:     }
 1735: 
 1736:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 1737:     return;
 1738: }
 1739: 
 1740: inline static void
 1741: signal_int(struct_processus *s_etat_processus, pid_t pid)
 1742: {
 1743:     struct_processus        *s_thread_principal;
 1744:     volatile sig_atomic_t   exclusion = 0;
 1745: 
 1746:     verrouillage_gestionnaire_signaux(s_etat_processus);
 1747: 
 1748:     if (pid == getpid())
 1749:     {
 1750:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1751:         {
 1752:             printf("[%d] RPL/SIGINT (thread %llu)\n", (int) getpid(),
 1753:                     (unsigned long long) pthread_self());
 1754:             fflush(stdout);
 1755:         }
 1756: 
 1757:         if ((*s_etat_processus).pid_processus_pere != getpid())
 1758:         {
 1759:             envoi_signal_processus((*s_etat_processus).pid_processus_pere,
 1760:                     rpl_sigint);
 1761:         }
 1762:         else
 1763:         {
 1764:             (*s_etat_processus).var_volatile_traitement_sigint = -1;
 1765: 
 1766:             while(exclusion == 1);
 1767:             exclusion = 1;
 1768: 
 1769:             if ((*s_etat_processus).var_volatile_requete_arret == -1)
 1770:             {
 1771:                 deverrouillage_gestionnaire_signaux(s_etat_processus);
 1772:                 exclusion = 0;
 1773:                 return;
 1774:             }
 1775: 
 1776:             if ((*s_etat_processus).langue == 'F')
 1777:             {
 1778:                 printf("+++Interruption\n");
 1779:             }
 1780:             else
 1781:             {
 1782:                 printf("+++Interrupt\n");
 1783:             }
 1784: 
 1785:             fflush(stdout);
 1786: 
 1787:             (*s_etat_processus).var_volatile_requete_arret = -1;
 1788:             (*s_etat_processus).var_volatile_alarme = -1;
 1789: 
 1790:             exclusion = 0;
 1791:         }
 1792:     }
 1793:     else
 1794:     {
 1795:         if ((s_thread_principal = recherche_thread_principal(getpid()))
 1796:                 != NULL)
 1797:         {
 1798:             envoi_signal_contexte(s_thread_principal, rpl_sigint);
 1799:         }
 1800:     }
 1801: 
 1802:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 1803:     return;
 1804: }
 1805: 
 1806: // Récupération des signaux
 1807: // - SIGFSTP
 1808: //
 1809: // ATTENTION :
 1810: // Le signal SIGFSTP provient de la mort du processus de contrôle.
 1811: // Sous certains systèmes (Linux...), la mort du terminal de contrôle
 1812: // se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
 1813: // (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
 1814: // non initialisée (pointeur NULL) issue de TERMIO.
 1815: 
 1816: void
 1817: interruption2(int signal)
 1818: {
 1819:     test_signal(signal);
 1820:     envoi_signal_processus(getpid(), rpl_sigtstp);
 1821:     return;
 1822: }
 1823: 
 1824: static inline void
 1825: signal_tstp(struct_processus *s_etat_processus, pid_t pid)
 1826: {
 1827:     struct_processus        *s_thread_principal;
 1828: 
 1829:     verrouillage_gestionnaire_signaux(s_etat_processus);
 1830: 
 1831:     if (pid == getpid())
 1832:     {
 1833:         /*
 1834:          *  0 => fonctionnement normal
 1835:          * -1 => requête
 1836:          *  1 => requête acceptée en attente de traitement
 1837:          */
 1838: 
 1839:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1840:         {
 1841:             printf("[%d] RPL/SIGTSTP (thread %llu)\n", (int) getpid(),
 1842:                     (unsigned long long) pthread_self());
 1843:             fflush(stdout);
 1844:         }
 1845: 
 1846:         if ((*s_etat_processus).var_volatile_processus_pere == 0)
 1847:         {
 1848:             envoi_signal_processus((*s_etat_processus).pid_processus_pere,
 1849:                     rpl_sigtstp);
 1850:         }
 1851:         else
 1852:         {
 1853:             (*s_etat_processus).var_volatile_requete_arret2 = -1;
 1854:         }
 1855:     }
 1856:     else
 1857:     {
 1858:         // Envoi d'un signal au thread maître du groupe.
 1859: 
 1860:         if ((s_thread_principal = recherche_thread_principal(getpid()))
 1861:                 != NULL)
 1862:         {
 1863:             envoi_signal_contexte(s_thread_principal, rpl_sigtstp);
 1864:         }
 1865:     }
 1866: 
 1867:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 1868:     return;
 1869: }
 1870: 
 1871: void
 1872: interruption3(int signal)
 1873: {
 1874:     // Si on passe par ici, c'est qu'il est impossible de récupérer
 1875:     // l'erreur d'accès à la mémoire. On sort donc du programme quitte à
 1876:     // ce qu'il reste des processus orphelins.
 1877: 
 1878:     unsigned char       message_1[] = "+++System : Uncaught access violation\n"
 1879:                                 "+++System : Aborting !\n";
 1880:     unsigned char       message_2[] = "+++System : Stack overflow\n"
 1881:                                 "+++System : Aborting !\n";
 1882: 
 1883:     test_signal(signal);
 1884: 
 1885:     if (pid_processus_pere == getpid())
 1886:     {
 1887:         kill(pid_processus_pere, SIGUSR1);
 1888:     }
 1889: 
 1890:     if (signal != SIGUSR2)
 1891:     {
 1892:         write(STDERR_FILENO, message_1, strlen(message_1));
 1893:     }
 1894:     else
 1895:     {
 1896:         write(STDERR_FILENO, message_2, strlen(message_2));
 1897:     }
 1898: 
 1899:     _exit(EXIT_FAILURE);
 1900: }
 1901: 
 1902: 
 1903: static void
 1904: sortie_interruption_depassement_pile(void *arg1, void *arg2, void *arg3)
 1905: {
 1906:     switch((*((volatile int *) arg1)))
 1907:     {
 1908:         case 1:
 1909:             longjmp(contexte_ecriture, -1);
 1910:             break;
 1911: 
 1912:         case 2:
 1913:             longjmp(contexte_impression, -1);
 1914:             break;
 1915:     }
 1916: 
 1917:     return;
 1918: }
 1919: 
 1920: 
 1921: void
 1922: interruption_depassement_pile(int urgence, stackoverflow_context_t scp)
 1923: {
 1924:     if ((urgence == 0) && (routine_recursive != 0))
 1925:     {
 1926:         // On peut tenter de récupérer le dépassement de pile. Si la variable
 1927:         // 'routine_recursive' est non nulle, on récupère l'erreur.
 1928: 
 1929:         sigsegv_leave_handler(sortie_interruption_depassement_pile,
 1930:                 (void *) &routine_recursive, NULL, NULL);
 1931:     }
 1932: 
 1933:     // Ici, la panique est totale et il vaut mieux quitter l'application.
 1934:     interruption3(SIGUSR2);
 1935:     return;
 1936: }
 1937: 
 1938: 
 1939: int
 1940: interruption_violation_access(void *adresse_fautive, int gravite)
 1941: {
 1942:     unsigned char       message[] = "+++System : Trying to catch access "
 1943:                                 "violation\n";
 1944: 
 1945:     static int          compteur_erreur = 0;
 1946: 
 1947:     if ((gravite == 0) && (routine_recursive != 0))
 1948:     {
 1949:         // Il peut s'agir d'un dépassement de pile.
 1950: 
 1951:         sigsegv_leave_handler(sortie_interruption_depassement_pile,
 1952:                 (void *) &routine_recursive, NULL, NULL);
 1953:     }
 1954: 
 1955:     // On est dans une bonne vieille violation d'accès. On essaie
 1956:     // de fermer au mieux l'application.
 1957: 
 1958:     compteur_erreur++;
 1959: 
 1960:     if (compteur_erreur >= 2)
 1961:     {
 1962:         // Erreurs multiples, on arrête l'application.
 1963:         interruption3(SIGSEGV);
 1964:         return(0);
 1965:     }
 1966: 
 1967:     write(STDERR_FILENO, message, strlen(message));
 1968: 
 1969:     if (pid_processus_pere == getpid())
 1970:     {
 1971:         longjmp(contexte_initial, -1);
 1972:         return(1);
 1973:     }
 1974:     else
 1975:     {
 1976:         longjmp(contexte_processus, -1);
 1977:         return(1);
 1978:     }
 1979: 
 1980:     // On renvoie 0 parce qu'on décline toute responsabilité quant à la
 1981:     // suite des événements...
 1982:     return(0);
 1983: }
 1984: 
 1985: // Traitement de rpl_sigstart
 1986: 
 1987: static inline void
 1988: signal_start(struct_processus *s_etat_processus, pid_t pid)
 1989: {
 1990:     struct_processus        *s_thread_principal;
 1991: 
 1992:     verrouillage_gestionnaire_signaux(s_etat_processus);
 1993: 
 1994:     if (pid == getpid())
 1995:     {
 1996:         (*s_etat_processus).demarrage_fils = d_vrai;
 1997:     }
 1998:     else
 1999:     {
 2000:         // Envoi d'un signal au thread maître du groupe.
 2001: 
 2002:         if ((s_thread_principal = recherche_thread_principal(getpid()))
 2003:                 != NULL)
 2004:         {
 2005:             envoi_signal_contexte(s_thread_principal, rpl_sigstart);
 2006:         }
 2007:     }
 2008: 
 2009:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 2010:     return;
 2011: }
 2012: 
 2013: // Traitement de rpl_sigcont
 2014: 
 2015: static inline void
 2016: signal_cont(struct_processus *s_etat_processus, pid_t pid)
 2017: {
 2018:     struct_processus        *s_thread_principal;
 2019: 
 2020:     verrouillage_gestionnaire_signaux(s_etat_processus);
 2021: 
 2022:     if (pid == getpid())
 2023:     {
 2024:         (*s_etat_processus).redemarrage_processus = d_vrai;
 2025:     }
 2026:     else
 2027:     {
 2028:         // Envoi d'un signal au thread maître du groupe.
 2029: 
 2030:         if ((s_thread_principal = recherche_thread_principal(getpid()))
 2031:                 != NULL)
 2032:         {
 2033:             envoi_signal_contexte(s_thread_principal, rpl_sigcont);
 2034:         }
 2035:     }
 2036: 
 2037:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 2038:     return;
 2039: }
 2040: 
 2041: // Traitement de rpl_sigstop
 2042: 
 2043: static inline void
 2044: signal_stop(struct_processus *s_etat_processus, pid_t pid)
 2045: {
 2046:     struct_processus        *s_thread_principal;
 2047: 
 2048:     verrouillage_gestionnaire_signaux(s_etat_processus);
 2049: 
 2050:     if (pid == getpid())
 2051:     {
 2052:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2053:         {
 2054:             printf("[%d] RPL/SIGSTOP (thread %llu)\n", (int) getpid(),
 2055:                     (unsigned long long) pthread_self());
 2056:             fflush(stdout);
 2057:         }
 2058: 
 2059:         /*
 2060:          * var_globale_traitement_retarde_stop :
 2061:          *  0 -> traitement immédiat
 2062:          *  1 -> traitement retardé (aucun signal reçu)
 2063:          * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
 2064:          */
 2065: 
 2066:         if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
 2067:         {
 2068:             (*s_etat_processus).var_volatile_requete_arret = -1;
 2069:         }
 2070:         else
 2071:         {
 2072:             (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
 2073:         }
 2074:     }
 2075:     else
 2076:     {
 2077:         // Envoi d'un signal au thread maître du groupe.
 2078: 
 2079:         if ((s_thread_principal = recherche_thread_principal(getpid()))
 2080:                 != NULL)
 2081:         {
 2082:             envoi_signal_contexte(s_thread_principal, rpl_sigstop);
 2083:         }
 2084:     }
 2085: 
 2086:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 2087:     return;
 2088: }
 2089: 
 2090: // Traitement de rpl_siginject
 2091: 
 2092: static inline void
 2093: signal_inject(struct_processus *s_etat_processus, pid_t pid)
 2094: {
 2095:     verrouillage_gestionnaire_signaux(s_etat_processus);
 2096: 
 2097:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2098:     {
 2099:         deverrouillage_gestionnaire_signaux(s_etat_processus);
 2100:         return;
 2101:     }
 2102: 
 2103:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2104:     {
 2105:         printf("[%d] RPL/SIGINJECT (thread %llu)\n", (int) getpid(),
 2106:                 (unsigned long long) pthread_self());
 2107:         fflush(stdout);
 2108:     }
 2109: 
 2110:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 2111:     return;
 2112: }
 2113: 
 2114: // Récupération des signaux
 2115: // - SIGPIPE
 2116: 
 2117: void
 2118: interruption5(int signal)
 2119: {
 2120:     unsigned char       message[] = "+++System : SIGPIPE\n"
 2121:                                 "+++System : Aborting !\n";
 2122: 
 2123:     test_signal(signal);
 2124: 
 2125:     if (pid_processus_pere == getpid())
 2126:     {
 2127:         envoi_signal_processus(pid_processus_pere, rpl_sigalrm);
 2128:     }
 2129: 
 2130:     write(STDERR_FILENO, message, strlen(message));
 2131:     return;
 2132: }
 2133: 
 2134: static inline void
 2135: signal_urg(struct_processus *s_etat_processus, pid_t pid)
 2136: {
 2137:     struct_processus        *s_thread_principal;
 2138: 
 2139:     verrouillage_gestionnaire_signaux(s_etat_processus);
 2140: 
 2141:     if (pid == getpid())
 2142:     {
 2143:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2144:         {
 2145:             printf("[%d] RPL/SIGURG (thread %llu)\n", (int) getpid(),
 2146:                     (unsigned long long) pthread_self());
 2147:             fflush(stdout);
 2148:         }
 2149: 
 2150:         (*s_etat_processus).var_volatile_alarme = -1;
 2151:         (*s_etat_processus).var_volatile_requete_arret = -1;
 2152:     }
 2153:     else
 2154:     {
 2155:         // Envoi d'un signal au thread maître du groupe.
 2156: 
 2157:         if ((s_thread_principal = recherche_thread_principal(getpid()))
 2158:                 != NULL)
 2159:         {
 2160:             envoi_signal_contexte(s_thread_principal, rpl_sigurg);
 2161:         }
 2162:     }
 2163: 
 2164:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 2165:     return;
 2166: }
 2167: 
 2168: // Traitement de rpl_sigabort
 2169: 
 2170: static inline void
 2171: signal_abort(struct_processus *s_etat_processus, pid_t pid)
 2172: {
 2173:     struct_processus        *s_thread_principal;
 2174: 
 2175:     verrouillage_gestionnaire_signaux(s_etat_processus);
 2176: 
 2177:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2178:     {
 2179:         deverrouillage_gestionnaire_signaux(s_etat_processus);
 2180:         return;
 2181:     }
 2182: 
 2183:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2184:     {
 2185:         printf("[%d] RPL/SIGABORT (thread %llu)\n", (int) getpid(),
 2186:                 (unsigned long long) pthread_self());
 2187:         fflush(stdout);
 2188:     }
 2189: 
 2190:     if (pid == getpid())
 2191:     {
 2192:         (*s_etat_processus).arret_depuis_abort = -1;
 2193: 
 2194:         /*
 2195:          * var_globale_traitement_retarde_stop :
 2196:          *  0 -> traitement immédiat
 2197:          *  1 -> traitement retardé (aucun signal reçu)
 2198:          * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
 2199:          */
 2200: 
 2201:         if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
 2202:         {
 2203:             (*s_etat_processus).var_volatile_requete_arret = -1;
 2204:         }
 2205:         else
 2206:         {
 2207:             (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
 2208:         }
 2209:     }
 2210:     else
 2211:     {
 2212:         (*s_etat_processus).arret_depuis_abort = -1;
 2213: 
 2214:         // Envoi d'un signal au thread maître du groupe.
 2215: 
 2216:         if ((s_thread_principal = recherche_thread_principal(getpid()))
 2217:                 != NULL)
 2218:         {
 2219:             envoi_signal_contexte(s_thread_principal, rpl_sigabort);
 2220:         }
 2221:     }
 2222: 
 2223:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 2224:     return;
 2225: }
 2226: 
 2227: // Récupération des signaux
 2228: // - SIGHUP
 2229: 
 2230: void
 2231: interruption4(int signal)
 2232: {
 2233:     test_signal(signal);
 2234:     envoi_signal_processus(getpid(), rpl_sighup);
 2235:     return;
 2236: }
 2237: 
 2238: static inline void
 2239: signal_hup(struct_processus *s_etat_processus, pid_t pid)
 2240: {
 2241:     file                    *fichier;
 2242: 
 2243:     unsigned char           nom[8 + 64 + 1];
 2244: 
 2245:     verrouillage_gestionnaire_signaux(s_etat_processus);
 2246: 
 2247:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2248:     {
 2249:         deverrouillage_gestionnaire_signaux(s_etat_processus);
 2250:         return;
 2251:     }
 2252: 
 2253:     snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
 2254:             (unsigned long) pthread_self());
 2255: 
 2256:     if ((fichier = fopen(nom, "w+")) != NULL)
 2257:     {
 2258:         fclose(fichier);
 2259: 
 2260:         freopen(nom, "w", stdout);
 2261:         freopen(nom, "w", stderr);
 2262:     }
 2263: 
 2264:     freopen("/dev/null", "r", stdin);
 2265: 
 2266:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2267:     {
 2268:         printf("[%d] RPL/SIGHUP (thread %llu)\n", (int) getpid(),
 2269:                 (unsigned long long) pthread_self());
 2270:         fflush(stdout);
 2271:     }
 2272: 
 2273:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 2274:     return;
 2275: }
 2276: 
 2277: void
 2278: traitement_exceptions_gsl(const char *reason, const char *file,
 2279:         int line, int gsl_errno)
 2280: {
 2281:     code_erreur_gsl = gsl_errno;
 2282:     envoi_signal_processus(getpid(), rpl_sigexcept);
 2283:     return;
 2284: }
 2285: 
 2286: static inline void
 2287: signal_except(struct_processus *s_etat_processus, pid_t pid)
 2288: {
 2289:     verrouillage_gestionnaire_signaux(s_etat_processus);
 2290: 
 2291:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2292:     {
 2293:         deverrouillage_gestionnaire_signaux(s_etat_processus);
 2294:         return;
 2295:     }
 2296: 
 2297:     (*s_etat_processus).var_volatile_exception_gsl = code_erreur_gsl;
 2298:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 2299: 
 2300:     return;
 2301: }
 2302: 
 2303: static inline void
 2304: envoi_interruptions(struct_processus *s_etat_processus, enum signaux_rpl signal,
 2305:         pid_t pid_source)
 2306: {
 2307:     switch(signal)
 2308:     {
 2309:         case rpl_signull:
 2310:             break;
 2311: 
 2312:         case rpl_sigint:
 2313:             signal_int(s_etat_processus, pid_source);
 2314:             break;
 2315: 
 2316:         case rpl_sigterm:
 2317:             signal_term(s_etat_processus, pid_source);
 2318:             break;
 2319: 
 2320:         case rpl_sigstart:
 2321:             signal_start(s_etat_processus, pid_source);
 2322:             break;
 2323: 
 2324:         case rpl_sigcont:
 2325:             signal_cont(s_etat_processus, pid_source);
 2326:             break;
 2327: 
 2328:         case rpl_sigstop:
 2329:             signal_stop(s_etat_processus, pid_source);
 2330:             break;
 2331: 
 2332:         case rpl_sigabort:
 2333:             signal_abort(s_etat_processus, pid_source);
 2334:             break;
 2335: 
 2336:         case rpl_sigurg:
 2337:             signal_urg(s_etat_processus, pid_source);
 2338:             break;
 2339: 
 2340:         case rpl_siginject:
 2341:             signal_inject(s_etat_processus, pid_source);
 2342:             break;
 2343: 
 2344:         case rpl_sigalrm:
 2345:             signal_alrm(s_etat_processus, pid_source);
 2346:             break;
 2347: 
 2348:         case rpl_sighup:
 2349:             signal_hup(s_etat_processus, pid_source);
 2350:             break;
 2351: 
 2352:         case rpl_sigtstp:
 2353:             signal_tstp(s_etat_processus, pid_source);
 2354:             break;
 2355: 
 2356:         case rpl_sigexcept:
 2357:             signal_except(s_etat_processus, pid_source);
 2358:             break;
 2359: 
 2360:         default:
 2361:             if ((*s_etat_processus).langue == 'F')
 2362:             {
 2363:                 printf("+++System : Spurious signal (%d) !\n", signal);
 2364:             }
 2365:             else
 2366:             {
 2367:                 printf("+++System : Signal inconnu (%d) !\n", signal);
 2368:             }
 2369: 
 2370:             break;
 2371:     }
 2372: 
 2373:     return;
 2374: }
 2375: 
 2376: void
 2377: scrutation_interruptions(struct_processus *s_etat_processus)
 2378: {
 2379:     // Interruptions qui arrivent sur le processus depuis un
 2380:     // processus externe.
 2381: 
 2382:     // Les pointeurs de lecture pointent sur les prochains éléments
 2383:     // à lire. Les pointeurs d'écriture pointent sur les prochains éléments à
 2384:     // écrire.
 2385: 
 2386: #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
 2387:         if (sem_trywait(&((*s_queue_signaux).semaphore)) == 0)
 2388: #   else
 2389:         if (sem_trywait(semaphore_queue_signaux) == 0)
 2390: #   endif
 2391:     {
 2392:         while((*s_queue_signaux).pointeur_lecture !=
 2393:                 (*s_queue_signaux).pointeur_ecriture)
 2394:         {
 2395:             // Il y a un signal en attente dans le segment partagé. On le
 2396:             // traite.
 2397: 
 2398:             envoi_interruptions(s_etat_processus,
 2399:                     (*s_queue_signaux).queue[(*s_queue_signaux)
 2400:                     .pointeur_lecture].signal, (*s_queue_signaux).queue
 2401:                     [(*s_queue_signaux).pointeur_lecture].pid);
 2402:             (*s_queue_signaux).pointeur_lecture =
 2403:                     ((*s_queue_signaux).pointeur_lecture + 1)
 2404:                     % LONGUEUR_QUEUE_SIGNAUX;
 2405: 
 2406: #           if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
 2407:             sem_wait(&((*s_queue_signaux).signalisation));
 2408: #           else
 2409:             sem_wait(semaphore_signalisation);
 2410: #           endif
 2411:         }
 2412: 
 2413: #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
 2414:             sem_post(&((*s_queue_signaux).semaphore));
 2415: #       else
 2416:             sem_post(semaphore_queue_signaux);
 2417: #       endif
 2418:     }
 2419: 
 2420:     // Interruptions qui arrivent depuis le groupe courant de threads.
 2421: 
 2422:     if (pthread_mutex_trylock(&mutex_interruptions) == 0)
 2423:     {
 2424:         while((*s_etat_processus).pointeur_signal_lecture !=
 2425:                 (*s_etat_processus).pointeur_signal_ecriture)
 2426:         {
 2427:             // Il y a un signal dans la queue du thread courant. On le traite.
 2428: 
 2429:             envoi_interruptions(s_etat_processus,
 2430:                     (*s_etat_processus).signaux_en_queue
 2431:                     [(*s_etat_processus).pointeur_signal_lecture],
 2432:                     getpid());
 2433:             (*s_etat_processus).pointeur_signal_lecture =
 2434:                     ((*s_etat_processus).pointeur_signal_lecture + 1)
 2435:                     % LONGUEUR_QUEUE_SIGNAUX;
 2436: 
 2437: #           if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
 2438:             sem_wait(&((*s_queue_signaux).signalisation));
 2439: #           else
 2440:             sem_wait(semaphore_signalisation);
 2441: #           endif
 2442:         }
 2443: 
 2444:         pthread_mutex_unlock(&mutex_interruptions);
 2445:     }
 2446: 
 2447:     return;
 2448: }
 2449: 
 2450: /*
 2451: ================================================================================
 2452:   Fonction renvoyant le nom du segment de mémoire partagée en fonction
 2453:   du pid du processus.
 2454: ================================================================================
 2455:   Entrée : Chemin absolue servant de racine, pid du processus
 2456: --------------------------------------------------------------------------------
 2457:   Sortie : NULL ou nom du segment
 2458: --------------------------------------------------------------------------------
 2459:   Effet de bord : Néant
 2460: ================================================================================
 2461: */
 2462: 
 2463: static unsigned char *
 2464: nom_segment(unsigned char *chemin, pid_t pid)
 2465: {
 2466:     unsigned char               *fichier;
 2467: 
 2468: #   ifdef IPCS_SYSV // !POSIX
 2469: #       ifndef OS2 // !OS2
 2470: 
 2471:             if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) *
 2472:                     sizeof(unsigned char))) == NULL)
 2473:             {
 2474:                 return(NULL);
 2475:             }
 2476: 
 2477:             sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);
 2478: #       else // OS2
 2479:             if ((fichier = malloc((10 + 256 + 1) * sizeof(unsigned char)))
 2480:                     == NULL)
 2481:             {
 2482:                 return(NULL);
 2483:             }
 2484: 
 2485:             sprintf(fichier, "\\SHAREMEM\\RPL-SIGQUEUES-%d", (int) pid);
 2486: #       endif // OS2
 2487: #   else // POSIX
 2488: 
 2489:         if ((fichier = malloc((1 + 256 + 1) *
 2490:                 sizeof(unsigned char))) == NULL)
 2491:         {
 2492:             return(NULL);
 2493:         }
 2494: 
 2495:         sprintf(fichier, "/RPL-SIGQUEUES-%d", (int) pid);
 2496: #   endif
 2497: 
 2498:     return(fichier);
 2499: }
 2500: 
 2501: 
 2502: /*
 2503: ================================================================================
 2504:   Fonctions d'envoi d'un signal à un thread ou à un processus.
 2505: ================================================================================
 2506:   Entrée : processus et signal
 2507: --------------------------------------------------------------------------------
 2508:   Sortie : erreur
 2509: --------------------------------------------------------------------------------
 2510:   Effet de bord : Néant
 2511: ================================================================================
 2512: */
 2513: 
 2514: int
 2515: envoi_signal_processus(pid_t pid, enum signaux_rpl signal)
 2516: {
 2517: #   ifndef OS2
 2518:         int                         segment;
 2519: #   endif
 2520: 
 2521: #   ifndef IPCS_SYSV
 2522: #       ifdef SEMAPHORES_NOMMES
 2523:             sem_t                   *semaphore;
 2524:             sem_t                   *signalisation;
 2525: #       endif
 2526: #   else
 2527: #       ifndef OS2
 2528:             int                     desc;
 2529:             key_t                   clef;
 2530: #       endif
 2531: #   endif
 2532: 
 2533:     struct_queue_signaux            *queue;
 2534: 
 2535:     unsigned char                   *nom;
 2536: 
 2537:     // Il s'agit d'ouvrir le segment de mémoire partagée, de le projeter en
 2538:     // mémoire puis d'y inscrire le signal à traiter.
 2539: 
 2540:     if (pid == getpid())
 2541:     {
 2542:         // Le signal est envoyé au même processus.
 2543: 
 2544:         if (s_queue_signaux == NULL)
 2545:         {
 2546:             return(1);
 2547:         }
 2548: 
 2549: #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
 2550:             while(sem_wait(&((*s_queue_signaux).semaphore)) != 0)
 2551: #       else
 2552:             while(sem_wait(semaphore_queue_signaux) != 0)
 2553: #       endif
 2554:         {
 2555:             if (errno != EINTR)
 2556:             {
 2557:                 return(1);
 2558:             }
 2559:         }
 2560: 
 2561:         (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture]
 2562:                 .pid = pid;
 2563:         (*s_queue_signaux).queue[(*s_queue_signaux).pointeur_ecriture]
 2564:                 .signal = signal;
 2565: 
 2566:         (*s_queue_signaux).pointeur_ecriture =
 2567:                 ((*s_queue_signaux).pointeur_ecriture + 1)
 2568:                 % LONGUEUR_QUEUE_SIGNAUX;
 2569: 
 2570: #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
 2571:             if (sem_post(&((*s_queue_signaux).semaphore)) != 0)
 2572: #       else
 2573:             if (sem_post(semaphore_queue_signaux) != 0)
 2574: #       endif
 2575:         {
 2576:             return(1);
 2577:         }
 2578: 
 2579: #       if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
 2580:             if (sem_post(&((*s_queue_signaux).signalisation)) != 0)
 2581: #       else
 2582:             if (sem_post(semaphore_signalisation) != 0)
 2583: #       endif
 2584:         {
 2585:             return(1);
 2586:         }
 2587:     }
 2588:     else
 2589:     {
 2590:         // Le signal est envoyé depuis un processus distinct.
 2591: 
 2592: #       ifdef IPCS_SYSV
 2593:             if ((nom = nom_segment(racine_segment, pid)) == NULL)
 2594:             {
 2595:                 return(1);
 2596:             }
 2597: 
 2598: #           ifndef OS2 // SysV
 2599:                 if ((desc = open(nom, O_RDWR)) == -1)
 2600:                 {
 2601:                     free(nom);
 2602:                     return(1);
 2603:                 }
 2604: 
 2605:                 close(desc);
 2606: 
 2607:                 if ((clef = ftok(nom, 1)) == -1)
 2608:                 {
 2609:                     free(nom);
 2610:                     return(1);
 2611:                 }
 2612: 
 2613:                 free(nom);
 2614: 
 2615:                 if ((segment = shmget(clef, sizeof(struct_queue_signaux), 0))
 2616:                         == -1)
 2617:                 {
 2618:                     return(1);
 2619:                 }
 2620: 
 2621:                 queue = shmat(segment, NULL, 0);
 2622: #           else // OS/2
 2623:                 if (DosGetNamedSharedMem((PVOID) &queue, nom,
 2624:                         PAG_WRITE | PAG_READ) != 0)
 2625:                 {
 2626:                     free(nom);
 2627:                     return(1);
 2628:                 }
 2629: 
 2630:                 free(nom);
 2631: #           endif
 2632: #       else // POSIX
 2633:             if ((nom = nom_segment(racine_segment, pid)) == NULL)
 2634:             {
 2635:                 return(1);
 2636:             }
 2637: 
 2638:             if ((segment = shm_open(nom, O_RDWR, 0)) == -1)
 2639:             {
 2640:                 free(nom);
 2641:                 return(1);
 2642:             }
 2643: 
 2644:             free(nom);
 2645: 
 2646:             if ((queue = mmap(NULL, sizeof(struct_queue_signaux),
 2647:                     PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0)) ==
 2648:                     MAP_FAILED)
 2649:             {
 2650:                 close(segment);
 2651:                 return(1);
 2652:             }
 2653: #       endif
 2654: 
 2655:             // À ce moment, le segment de mémoire partagée est projeté
 2656:             // dans l'espace du processus.
 2657: 
 2658: #       ifndef IPCS_SYSV // POSIX
 2659: #           ifndef SEMAPHORES_NOMMES
 2660:                 while(sem_wait(&((*queue).semaphore)) != 0)
 2661:                 {
 2662:                     if (errno != EINTR)
 2663:                     {
 2664:                         return(1);
 2665:                     }
 2666:                 }
 2667: #           else
 2668:                 if ((semaphore = sem_open2(pid, SEM_QUEUE)) == SEM_FAILED)
 2669:                 {
 2670:                     return(1);
 2671:                 }
 2672: 
 2673:                 if ((signalisation = sem_open2(pid, SEM_SIGNALISATION))
 2674:                         == SEM_FAILED)
 2675:                 {
 2676:                     return(1);
 2677:                 }
 2678: 
 2679:                 while(sem_wait(semaphore) != 0)
 2680:                 {
 2681:                     if (errno != EINTR)
 2682:                     {
 2683:                         sem_close(semaphore);
 2684:                         sem_close(signalisation);
 2685:                         return(1);
 2686:                     }
 2687:                 }
 2688: #           endif
 2689: #       else // IPCS_SYSV
 2690:             while(sem_wait(&((*queue).semaphore)) != 0)
 2691:             {
 2692:                 if (errno != EINTR)
 2693:                 {
 2694:                     return(1);
 2695:                 }
 2696:             }
 2697: #       endif
 2698: 
 2699:         (*queue).queue[(*queue).pointeur_ecriture].pid = getpid();
 2700:         (*queue).queue[(*queue).pointeur_ecriture].signal = signal;
 2701: 
 2702:         (*queue).pointeur_ecriture = ((*queue).pointeur_ecriture + 1)
 2703:                 % LONGUEUR_QUEUE_SIGNAUX;
 2704: 
 2705: #       ifndef IPCS_SYSV // POSIX
 2706: #           ifndef SEMAPHORES_NOMMES
 2707:                 if (sem_post(&((*queue).semaphore)) != 0)
 2708:                 {
 2709:                     return(1);
 2710:                 }
 2711: 
 2712:                 if (sem_post(&((*queue).signalisation)) != 0)
 2713:                 {
 2714:                     return(1);
 2715:                 }
 2716: #           else
 2717:                 if (sem_post(semaphore) != 0)
 2718:                 {
 2719:                     sem_close(semaphore);
 2720:                     sem_close(signalisation);
 2721:                     return(1);
 2722:                 }
 2723: 
 2724:                 if (sem_close(semaphore) != 0)
 2725:                 {
 2726:                     return(1);
 2727:                 }
 2728: 
 2729:                 if (sem_post(signalisation) != 0)
 2730:                 {
 2731:                     sem_close(signalisation);
 2732:                     return(1);
 2733:                 }
 2734: 
 2735:                 if (sem_close(signalisation) != 0)
 2736:                 {
 2737:                     return(1);
 2738:                 }
 2739: 
 2740: #           endif
 2741: 
 2742:             if (munmap(queue, sizeof(struct_queue_signaux)) != 0)
 2743:             {
 2744:                 close(segment);
 2745:                 return(1);
 2746:             }
 2747: #       else // IPCS_SYSV
 2748:             if (sem_post(&((*queue).semaphore)) != 0)
 2749:             {
 2750:                 return(1);
 2751:             }
 2752: 
 2753:             if (sem_post(&((*queue).signalisation)) != 0)
 2754:             {
 2755:                 return(1);
 2756:             }
 2757: 
 2758: #           ifndef OS2 // SysV
 2759:                 if (shmdt(queue) != 0)
 2760:                 {
 2761:                     return(1);
 2762:                 }
 2763: #           else // OS/2
 2764:                 // Pendant de DosGetNamedSHaredMem()
 2765: #           endif
 2766: #       endif
 2767:     }
 2768: 
 2769:     return(0);
 2770: }
 2771: 
 2772: int
 2773: envoi_signal_thread(pthread_t tid, enum signaux_rpl signal)
 2774: {
 2775:     // Un signal est envoyé d'un thread à un autre thread du même processus.
 2776: 
 2777:     volatile struct_liste_chainee_volatile  *l_element_courant;
 2778: 
 2779:     struct_processus                        *s_etat_processus;
 2780: 
 2781:     if (pthread_mutex_lock(&mutex_liste_threads) != 0)
 2782:     {
 2783:         return(1);
 2784:     }
 2785: 
 2786:     l_element_courant = liste_threads;
 2787: 
 2788:     while(l_element_courant != NULL)
 2789:     {
 2790:         if (((*((struct_thread *) (*l_element_courant).donnee)).pid
 2791:                 == getpid()) && (pthread_equal((*((struct_thread *)
 2792:                 (*l_element_courant).donnee)).tid, tid) != 0))
 2793:         {
 2794:             break;
 2795:         }
 2796: 
 2797:         l_element_courant = (*l_element_courant).suivant;
 2798:     }
 2799: 
 2800:     if (l_element_courant == NULL)
 2801:     {
 2802:         pthread_mutex_unlock(&mutex_liste_threads);
 2803:         return(1);
 2804:     }
 2805: 
 2806:     if (pthread_mutex_lock(&mutex_interruptions) != 0)
 2807:     {
 2808:         pthread_mutex_unlock(&mutex_liste_threads);
 2809:         return(1);
 2810:     }
 2811: 
 2812:     s_etat_processus = (*((struct_thread *) (*l_element_courant).donnee))
 2813:             .s_etat_processus;
 2814: 
 2815:     (*s_etat_processus).signaux_en_queue
 2816:             [(*s_etat_processus).pointeur_signal_ecriture] = signal;
 2817:     (*s_etat_processus).pointeur_signal_ecriture =
 2818:             ((*s_etat_processus).pointeur_signal_ecriture + 1)
 2819:             % LONGUEUR_QUEUE_SIGNAUX;
 2820: 
 2821:     if (pthread_mutex_unlock(&mutex_interruptions) != 0)
 2822:     {
 2823:         pthread_mutex_unlock(&mutex_liste_threads);
 2824:         return(1);
 2825:     }
 2826: 
 2827:     if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
 2828:     {
 2829:         return(1);
 2830:     }
 2831: 
 2832: #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
 2833:     if (sem_post(&((*s_queue_signaux).signalisation)) != 0)
 2834:     {
 2835:         return(1);
 2836:     }
 2837: #   else
 2838:     if (sem_post(semaphore_signalisation) != 0)
 2839:     {
 2840:         return(1);
 2841:     }
 2842: #   endif
 2843: 
 2844:     return(0);
 2845: }
 2846: 
 2847: int
 2848: envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,
 2849:         enum signaux_rpl signal)
 2850: {
 2851:     pthread_mutex_lock(&mutex_interruptions);
 2852:     (*s_etat_processus_a_signaler).signaux_en_queue
 2853:             [(*s_etat_processus_a_signaler).pointeur_signal_ecriture] =
 2854:             signal;
 2855:     (*s_etat_processus_a_signaler).pointeur_signal_ecriture =
 2856:             ((*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1)
 2857:             % LONGUEUR_QUEUE_SIGNAUX;
 2858:     pthread_mutex_unlock(&mutex_interruptions);
 2859: 
 2860: #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
 2861:     if (sem_post(&((*s_queue_signaux).signalisation)) != 0)
 2862:     {
 2863:         return(1);
 2864:     }
 2865: #   else
 2866:     if (sem_post(semaphore_signalisation) != 0)
 2867:     {
 2868:         return(1);
 2869:     }
 2870: #   endif
 2871: 
 2872:     return(0);
 2873: }
 2874: 
 2875: 
 2876: /*
 2877: ================================================================================
 2878:   Fonction créant un segment de mémoire partagée destiné à contenir
 2879:   la queue des signaux.
 2880: ================================================================================
 2881:   Entrée : structure de description du processus
 2882: --------------------------------------------------------------------------------
 2883:   Sortie : Néant
 2884: --------------------------------------------------------------------------------
 2885:   Effet de bord : Néant
 2886: ================================================================================
 2887: */
 2888: 
 2889: void
 2890: creation_queue_signaux(struct_processus *s_etat_processus)
 2891: {
 2892:     pthread_attr_t                  attributs;
 2893: 
 2894:     unsigned char                   *nom;
 2895: 
 2896:     racine_segment = (*s_etat_processus).chemin_fichiers_temporaires;
 2897: 
 2898: #   ifndef IPCS_SYSV // POSIX
 2899:         if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
 2900:                 getpid())) == NULL)
 2901:         {
 2902:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2903:             return;
 2904:         }
 2905: 
 2906:         if ((f_queue_signaux = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,
 2907:                 S_IRUSR | S_IWUSR)) == -1)
 2908:         {
 2909:             free(nom);
 2910:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2911:             return;
 2912:         }
 2913: 
 2914:         if (ftruncate(f_queue_signaux, sizeof(struct_queue_signaux)) == -1)
 2915:         {
 2916:             free(nom);
 2917:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2918:             return;
 2919:         }
 2920: 
 2921:         s_queue_signaux = mmap(NULL, sizeof(struct_queue_signaux),
 2922:                 PROT_READ | PROT_WRITE, MAP_SHARED, f_queue_signaux, 0);
 2923: 
 2924:         if (((void *) s_queue_signaux) == ((void *) -1))
 2925:         {
 2926:             if (shm_unlink(nom) == -1)
 2927:             {
 2928:                 free(nom);
 2929:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2930:                 return;
 2931:             }
 2932: 
 2933:             free(nom);
 2934:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2935:             return;
 2936:         }
 2937: 
 2938:         free(nom);
 2939: 
 2940: #       ifndef SEMAPHORES_NOMMES
 2941:             sem_init(&((*s_queue_signaux).semaphore), 1, 1);
 2942:             sem_init(&((*s_queue_signaux).signalisation), 1, 0);
 2943: #       else
 2944:             if ((semaphore_queue_signaux = sem_init2(1, getpid(), SEM_QUEUE))
 2945:                     == SEM_FAILED)
 2946:             {
 2947:                 (*s_etat_processus).erreur_systeme = d_es_processus;
 2948:                 return;
 2949:             }
 2950: 
 2951:             if ((semaphore_signalisation = sem_init2(1, getpid(),
 2952:                     SEM_SIGNALISATION)) == SEM_FAILED)
 2953:             {
 2954:                 (*s_etat_processus).erreur_systeme = d_es_processus;
 2955:                 return;
 2956:             }
 2957: #       endif
 2958: 
 2959:         (*s_queue_signaux).pointeur_lecture = 0;
 2960:         (*s_queue_signaux).pointeur_ecriture = 0;
 2961:         (*s_queue_signaux).requete_arret = d_faux;
 2962: 
 2963:         if (msync(s_queue_signaux, sizeof(struct_queue_signaux), 0))
 2964:         {
 2965:             (*s_etat_processus).erreur_systeme = d_es_processus;
 2966:             return;
 2967:         }
 2968: #   else // IPCS_SYSV
 2969: #       ifndef OS2
 2970:             int                             segment;
 2971:             int                             support;
 2972: 
 2973:             key_t                           clef;
 2974: 
 2975:             // Création d'un segment de données associé au PID du processus
 2976:             // courant
 2977: 
 2978:             if ((nom = nom_segment((*s_etat_processus)
 2979:                     .chemin_fichiers_temporaires, getpid())) == NULL)
 2980:             {
 2981:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2982:                 return;
 2983:             }
 2984: 
 2985:             if ((support = open(nom, O_RDWR | O_CREAT | O_EXCL,
 2986:                     S_IRUSR | S_IWUSR)) == -1)
 2987:             {
 2988:                 (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
 2989:                 return;
 2990:             }
 2991: 
 2992:             if ((clef = ftok(nom, 1)) == -1)
 2993:             {
 2994:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2995:                 return;
 2996:             }
 2997: 
 2998:             close(support);
 2999:             free(nom);
 3000: 
 3001:             if ((segment = shmget(clef, sizeof(struct_queue_signaux),
 3002:                     IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)
 3003:             {
 3004:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 3005:                 return;
 3006:             }
 3007: 
 3008:             s_queue_signaux = shmat(segment, NULL, 0);
 3009:             f_queue_signaux = segment;
 3010: 
 3011:             if (((void *) s_queue_signaux) == ((void *) -1))
 3012:             {
 3013:                 if (shmctl(f_queue_signaux, IPC_RMID, 0) == -1)
 3014:                 {
 3015:                     (*s_etat_processus).erreur_systeme =
 3016:                             d_es_allocation_memoire;
 3017:                     return;
 3018:                 }
 3019: 
 3020:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 3021:                 return;
 3022:             }
 3023: 
 3024:             sem_init(&((*s_queue_signaux).semaphore), 1, 1);
 3025:             sem_init(&((*s_queue_signaux).signalisation), 1, 0);
 3026:             (*s_queue_signaux).pointeur_lecture = 0;
 3027:             (*s_queue_signaux).pointeur_ecriture = 0;
 3028:             (*s_queue_signaux).requete_arret = d_faux;
 3029: #       else // OS/2
 3030:             if ((nom = nom_segment(NULL, getpid())) == NULL)
 3031:             {
 3032:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 3033:                 return;
 3034:             }
 3035: 
 3036:             if (DosAllocSharedMem((PVOID) &s_queue_signaux, nom,
 3037:                     sizeof(struct_queue_signaux),
 3038:                     PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
 3039:             {
 3040:                 free(nom);
 3041:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 3042:                 return;
 3043:             }
 3044: 
 3045:             free(nom);
 3046: 
 3047:             sem_init(&((*s_queue_signaux).semaphore), 1, 1);
 3048:             sem_init(&((*s_queue_signaux).signalisation), 1, 0);
 3049:             (*s_queue_signaux).pointeur_lecture = 0;
 3050:             (*s_queue_signaux).pointeur_ecriture = 0;
 3051:             (*s_queue_signaux).requete_arret = d_faux;
 3052: #       endif
 3053: #   endif
 3054: 
 3055:     // Lancement du thread de récupération des signaux.
 3056: 
 3057:     if (pthread_attr_init(&attributs) != 0)
 3058:     {
 3059:         (*s_etat_processus).erreur_systeme = d_es_processus;
 3060:         return;
 3061:     }
 3062: 
 3063:     if (pthread_attr_setdetachstate(&attributs,
 3064:             PTHREAD_CREATE_JOINABLE) != 0)
 3065:     {
 3066:         (*s_etat_processus).erreur_systeme = d_es_processus;
 3067:         return;
 3068:     }
 3069: 
 3070: #   ifdef SCHED_OTHER
 3071:     if (pthread_attr_setschedpolicy(&attributs, SCHED_OTHER) != 0)
 3072:     {
 3073:         (*s_etat_processus).erreur_systeme = d_es_processus;
 3074:         return;
 3075:     }
 3076: #   endif
 3077: 
 3078: #   ifdef PTHREAD_EXPLICIT_SCHED
 3079:     if (pthread_attr_setinheritsched(&attributs, PTHREAD_EXPLICIT_SCHED) != 0)
 3080:     {
 3081:         (*s_etat_processus).erreur_systeme = d_es_processus;
 3082:         return;
 3083:     }
 3084: #   endif
 3085: 
 3086: #   ifdef PTHREAD_SCOPE_SYSTEM
 3087:     if (pthread_attr_setscope(&attributs, PTHREAD_SCOPE_SYSTEM) != 0)
 3088:     {
 3089:         (*s_etat_processus).erreur_systeme = d_es_processus;
 3090:         return;
 3091:     }
 3092: #   endif
 3093: 
 3094:     if (pthread_attr_destroy(&attributs) != 0)
 3095:     {
 3096:         (*s_etat_processus).erreur_systeme = d_es_processus;
 3097:         return;
 3098:     }
 3099: 
 3100:     if (pthread_create(&((*s_queue_signaux).thread_signaux), &attributs,
 3101:             thread_surveillance_signaux, s_etat_processus) != 0)
 3102:     {
 3103:         (*s_etat_processus).erreur_systeme = d_es_processus;
 3104:         return;
 3105:     }
 3106: 
 3107:     return;
 3108: }
 3109: 
 3110: 
 3111: /*
 3112: ================================================================================
 3113:   Fonction libérant le segment de mémoire partagée destiné à contenir
 3114:   la queue des signaux.
 3115: ================================================================================
 3116:   Entrée : structure de description du processus
 3117: --------------------------------------------------------------------------------
 3118:   Sortie : Néant
 3119: --------------------------------------------------------------------------------
 3120:   Effet de bord : Néant
 3121: ================================================================================
 3122: */
 3123: 
 3124: void
 3125: liberation_queue_signaux(struct_processus *s_etat_processus)
 3126: {
 3127:     // Incrémenter le sémaphore pour être sûr de le débloquer.
 3128: 
 3129:     (*s_queue_signaux).requete_arret = d_vrai;
 3130: 
 3131: #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
 3132:     sem_post(&((*s_queue_signaux).signalisation));
 3133: #   else
 3134:     sem_post(semaphore_signalisation);
 3135: #   endif
 3136: 
 3137:     pthread_join((*s_queue_signaux).thread_signaux, NULL);
 3138: 
 3139: #   ifdef IPCS_SYSV // SystemV
 3140: #       ifndef OS2
 3141:             if (shmdt(s_queue_signaux) == -1)
 3142:             {
 3143:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 3144:                 return;
 3145:             }
 3146: #       else // OS/2
 3147: #       endif
 3148: #   else // POSIX
 3149: #       ifndef SEMAPHORES_NOMMES
 3150:             sem_close(&((*s_queue_signaux).semaphore));
 3151:             sem_close(&((*s_queue_signaux).signalisation));
 3152: #       else
 3153:             sem_close(semaphore_queue_signaux);
 3154:             sem_close(semaphore_signalisation);
 3155: #       endif
 3156: 
 3157:         if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
 3158:         {
 3159:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 3160:             return;
 3161:         }
 3162: 
 3163:         close(f_queue_signaux);
 3164: #   endif
 3165: 
 3166:     return;
 3167: }
 3168: 
 3169: 
 3170: /*
 3171: ================================================================================
 3172:   Fonction détruisant le segment de mémoire partagée destiné à contenir
 3173:   la queue des signaux.
 3174: ================================================================================
 3175:   Entrée : structure de description du processus
 3176: --------------------------------------------------------------------------------
 3177:   Sortie : Néant
 3178: --------------------------------------------------------------------------------
 3179:   Effet de bord : Néant
 3180: ================================================================================
 3181: */
 3182: 
 3183: void
 3184: destruction_queue_signaux(struct_processus *s_etat_processus)
 3185: {
 3186: #   ifndef OS2
 3187:         unsigned char       *nom;
 3188: #   endif
 3189: 
 3190:     // Incrémenter le sémaphore pour être sûr de le débloquer.
 3191: 
 3192:     (*s_queue_signaux).requete_arret = d_vrai;
 3193: 
 3194: #   if (!defined(SEMAPHORES_NOMMES)) || defined(IPCS_SYSV)
 3195:     sem_post(&((*s_queue_signaux).signalisation));
 3196: #   else
 3197:     sem_post(semaphore_signalisation);
 3198: #   endif
 3199: 
 3200:     pthread_join((*s_queue_signaux).thread_signaux, NULL);
 3201: 
 3202: #   ifdef IPCS_SYSV // SystemV
 3203: #       ifndef OS2
 3204:             // Il faut commencer par éliminer le sémaphore.
 3205: 
 3206:             if (semctl((*s_queue_signaux).semaphore.sem, 0, IPC_RMID) == -1)
 3207:             {
 3208:                 (*s_etat_processus).erreur_systeme = d_es_processus;
 3209:                 return;
 3210:             }
 3211: 
 3212:             unlink((*s_queue_signaux).semaphore.path);
 3213:             free((*s_queue_signaux).semaphore.path);
 3214: 
 3215:             if (semctl((*s_queue_signaux).signalisation.sem, 0, IPC_RMID) == -1)
 3216:             {
 3217:                 (*s_etat_processus).erreur_systeme = d_es_processus;
 3218:                 return;
 3219:             }
 3220: 
 3221:             unlink((*s_queue_signaux).signalisation.path);
 3222:             free((*s_queue_signaux).signalisation.path);
 3223: 
 3224:             if (shmdt(s_queue_signaux) == -1)
 3225:             {
 3226:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 3227:                 return;
 3228:             }
 3229: 
 3230:             if (shmctl(f_queue_signaux, IPC_RMID, 0) == -1)
 3231:             {
 3232:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 3233:                 return;
 3234:             }
 3235: 
 3236:             if ((nom = nom_segment((*s_etat_processus)
 3237:                     .chemin_fichiers_temporaires, getpid())) == NULL)
 3238:             {
 3239:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 3240:                 return;
 3241:             }
 3242: 
 3243:             unlink(nom);
 3244:             free(nom);
 3245: #       else
 3246:             sem_close(&((*s_queue_signaux).semaphore));
 3247:             sem_destroy(&((*s_queue_signaux).semaphore));
 3248: 
 3249:             sem_close(&((*s_queue_signaux).signalisation));
 3250:             sem_destroy(&((*s_queue_signaux).signalisation));
 3251: 
 3252:             if (DosFreeMem(s_queue_signaux) != 0)
 3253:             {
 3254:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 3255:                 return;
 3256:             }
 3257: #       endif
 3258: #   else // POSIX
 3259: #       ifndef SEMAPHORES_NOMMES
 3260:             sem_close(&((*s_queue_signaux).semaphore));
 3261:             sem_destroy(&((*s_queue_signaux).semaphore));
 3262: 
 3263:             sem_close(&((*s_queue_signaux).signalisation));
 3264:             sem_destroy(&((*s_queue_signaux).signalisation));
 3265: #       else
 3266:             sem_close(semaphore_queue_signaux);
 3267:             sem_destroy2(semaphore_queue_signaux, getpid(), SEM_QUEUE);
 3268: 
 3269:             sem_close(semaphore_signalisation);
 3270:             sem_destroy2(semaphore_signalisation, getpid(), SEM_SIGNALISATION);
 3271: #       endif
 3272: 
 3273:         if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
 3274:         {
 3275:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 3276:             return;
 3277:         }
 3278: 
 3279:         if ((nom = nom_segment(NULL, getpid())) == NULL)
 3280:         {
 3281:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 3282:             return;
 3283:         }
 3284: 
 3285:         close(f_queue_signaux);
 3286: 
 3287:         if (shm_unlink(nom) != 0)
 3288:         {
 3289:             free(nom);
 3290:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 3291:             return;
 3292:         }
 3293: 
 3294:         free(nom);
 3295: #   endif
 3296: 
 3297:     return;
 3298: }
 3299: 
 3300: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>