File:  [local] / rpl / src / interruptions.c
Revision 1.133: download - view: text, annotated - select for diffs - revision graph
Tue May 28 22:09:55 2013 UTC (10 years, 11 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Corrections de mutexes... Suite et presque fin.

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

CVSweb interface <joel.bertrand@systella.fr>