File:  [local] / rpl / src / interruptions.c
Revision 1.206: download - view: text, annotated - select for diffs - revision graph
Fri Jan 10 11:15:50 2020 UTC (4 years, 3 months ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_32, HEAD
Modification du copyright.

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

CVSweb interface <joel.bertrand@systella.fr>