File:  [local] / rpl / src / interruptions.c
Revision 1.113: download - view: text, annotated - select for diffs - revision graph
Wed Dec 19 09:58:27 2012 UTC (11 years, 4 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Changement des dates du copyright.

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

CVSweb interface <joel.bertrand@systella.fr>