File:  [local] / rpl / src / interruptions.c
Revision 1.106: download - view: text, annotated - select for diffs - revision graph
Sun Oct 14 21:37:11 2012 UTC (11 years, 6 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Correction d'un bug bizarre dans la gestion des signaux de NetBSD pour
les programmes compilés avec -lpthread. Le gestionnaire de signal est dans
ce cas appelé dans un thread spécifique et la causalité des instructions
en souffre fortement... Pour que cette gestion des signaux
soit la même quel que soit le système d'exploitation, j'ai séparé la
gestion des signaux en deux threads. Le gestionnaire de signal envoie
le signal de façon atomique dans un pipe. Un premier thread (par processus)
attend de l'autre côté du pipe et traite le signal. Un second thread
(par thread) regarde les signaux en attente et envoie à chaque signal
en attente un SIG_ALRM qui ne sert qu'à réveiller un hypothétique appel
système lent.

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

CVSweb interface <joel.bertrand@systella.fr>