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

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

CVSweb interface <joel.bertrand@systella.fr>