File:  [local] / rpl / src / interruptions.c
Revision 1.110: download - view: text, annotated - select for diffs - revision graph
Thu Dec 13 16:59:42 2012 UTC (11 years, 4 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Première série de patches pour inclure les variables partagées dans
l'arbre des variables. Attention, le résultat ne compile pas.

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

CVSweb interface <joel.bertrand@systella.fr>