File:  [local] / rpl / src / interruptions.c
Revision 1.96: download - view: text, annotated - select for diffs - revision graph
Thu May 17 17:06:18 2012 UTC (11 years, 11 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Premières modifications pour l'éviction d'une 'race condition' dans la
gestion des signaux. Ne pas utiliser en l'état car il manque une décrémentation
de sémaphore.

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

CVSweb interface <joel.bertrand@systella.fr>