File:  [local] / rpl / src / interruptions.c
Revision 1.138: download - view: text, annotated - select for diffs - revision graph
Tue Dec 3 09:36:15 2013 UTC (10 years, 4 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
En route pour la 4.1.17.

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

CVSweb interface <joel.bertrand@systella.fr>