File:  [local] / rpl / src / interruptions.c
Revision 1.125: download - view: text, annotated - select for diffs - revision graph
Tue May 21 12:10:12 2013 UTC (10 years, 11 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Retrait d'un pipe inutile. Simplification de la gestion des interruptions SWI
et du système SEND/RECV.

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

CVSweb interface <joel.bertrand@systella.fr>