File:  [local] / rpl / src / interruptions.c
Revision 1.128: download - view: text, annotated - select for diffs - revision graph
Wed May 22 12:05:42 2013 UTC (10 years, 11 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Autre correction d'accès concurrents.

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

CVSweb interface <joel.bertrand@systella.fr>