File:  [local] / rpl / src / interruptions.c
Revision 1.107: download - view: text, annotated - select for diffs - revision graph
Mon Oct 15 12:39:54 2012 UTC (11 years, 6 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Inversion de langue dans un message d'erreur.

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

CVSweb interface <joel.bertrand@systella.fr>