File:  [local] / rpl / src / interruptions.c
Revision 1.167: download - view: text, annotated - select for diffs - revision graph
Wed Mar 9 22:12:06 2016 UTC (8 years, 1 month ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Cohérence.

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

CVSweb interface <joel.bertrand@systella.fr>