File:  [local] / rpl / src / interruptions.c
Revision 1.68: download - view: text, annotated - select for diffs - revision graph
Wed Sep 14 17:55:59 2011 UTC (12 years, 8 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Suite des patches...

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.3
    4:   Copyright (C) 1989-2011 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: 
   56: static volatile struct_liste_chainee_volatile   *liste_threads
   57:         = NULL;
   58: static volatile struct_liste_chainee_volatile   *liste_threads_surveillance
   59:         = NULL;
   60: static volatile int                             code_erreur_gsl = 0;
   61: 
   62: static pthread_mutex_t                          mutex_interruptions
   63:         = PTHREAD_MUTEX_INITIALIZER;
   64: 
   65: void
   66: modification_pid_thread_pere(struct_processus *s_etat_processus)
   67: {
   68:     // La variable existe toujours et aucun thread concurrent ne peut
   69:     // la modifier puisque cette routine ne peut être appelée que depuis
   70:     // DAEMON.
   71: 
   72:     (*((struct_thread *) (*liste_threads).donnee)).pid =
   73:             (*s_etat_processus).pid_processus_pere;
   74: 
   75:     return;
   76: }
   77: 
   78: void
   79: insertion_thread(struct_processus *s_etat_processus, logical1 thread_principal)
   80: {
   81:     volatile struct_liste_chainee_volatile      *l_nouvel_objet;
   82: 
   83:     if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
   84:             == NULL)
   85:     {
   86:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
   87:         return;
   88:     }
   89: 
   90:     if (((*l_nouvel_objet).donnee = malloc(sizeof(struct_thread))) == NULL)
   91:     {
   92:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
   93:         return;
   94:     }
   95: 
   96:     (*((struct_thread *) (*l_nouvel_objet).donnee)).pid = getpid();
   97:     (*((struct_thread *) (*l_nouvel_objet).donnee)).tid = pthread_self();
   98:     (*((struct_thread *) (*l_nouvel_objet).donnee)).thread_principal =
   99:             thread_principal;
  100:     (*((struct_thread *) (*l_nouvel_objet).donnee)).s_etat_processus =
  101:             s_etat_processus;
  102: 
  103:     if (pthread_mutex_lock(&mutex_liste_threads) != 0)
  104:     {
  105:         (*s_etat_processus).erreur_systeme = d_es_processus;
  106:         return;
  107:     }
  108: 
  109:     (*l_nouvel_objet).suivant = liste_threads;
  110:     liste_threads = l_nouvel_objet;
  111: 
  112:     if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
  113:     {
  114:         (*s_etat_processus).erreur_systeme = d_es_processus;
  115:         return;
  116:     }
  117: 
  118:     return;
  119: }
  120: 
  121: void
  122: insertion_thread_surveillance(struct_processus *s_etat_processus,
  123:         struct_descripteur_thread *s_argument_thread)
  124: {
  125:     volatile struct_liste_chainee_volatile      *l_nouvel_objet;
  126: 
  127:     if ((l_nouvel_objet = malloc(sizeof(struct_liste_chainee_volatile)))
  128:             == NULL)
  129:     {
  130:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  131:         return;
  132:     }
  133: 
  134:     if (pthread_mutex_lock(&mutex_liste_threads) != 0)
  135:     {
  136:         (*s_etat_processus).erreur_systeme = d_es_processus;
  137:         return;
  138:     }
  139: 
  140:     pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references));
  141:     (*s_argument_thread).nombre_references++;
  142:     pthread_mutex_unlock(&((*s_argument_thread).mutex_nombre_references));
  143: 
  144:     (*l_nouvel_objet).suivant = liste_threads_surveillance;
  145:     (*l_nouvel_objet).donnee = (void *) s_argument_thread;
  146: 
  147:     liste_threads_surveillance = l_nouvel_objet;
  148: 
  149:     if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
  150:     {
  151:         (*s_etat_processus).erreur_systeme = d_es_processus;
  152:         return;
  153:     }
  154: 
  155:     return;
  156: }
  157: 
  158: void
  159: retrait_thread(struct_processus *s_etat_processus)
  160: {
  161:     volatile struct_liste_chainee_volatile  *l_element_precedent;
  162:     volatile struct_liste_chainee_volatile  *l_element_courant;
  163: 
  164:     if (pthread_mutex_lock(&mutex_liste_threads) != 0)
  165:     {
  166:         (*s_etat_processus).erreur_systeme = d_es_processus;
  167:         return;
  168:     }
  169: 
  170:     l_element_precedent = NULL;
  171:     l_element_courant = liste_threads;
  172: 
  173:     while(l_element_courant != NULL)
  174:     {
  175:         if (((*((struct_thread *) (*l_element_courant).donnee)).pid
  176:                 == getpid()) && (pthread_equal((*((struct_thread *)
  177:                 (*l_element_courant).donnee)).tid, pthread_self()) != 0))
  178:         {
  179:             break;
  180:         }
  181: 
  182:         l_element_precedent = l_element_courant;
  183:         l_element_courant = (*l_element_courant).suivant;
  184:     }
  185: 
  186:     if (l_element_courant == NULL)
  187:     {
  188:         pthread_mutex_unlock(&mutex_liste_threads);
  189:         (*s_etat_processus).erreur_systeme = d_es_processus;
  190:         return;
  191:     }
  192: 
  193:     if (l_element_precedent == NULL)
  194:     {
  195:         liste_threads = (*l_element_courant).suivant;
  196:     }
  197:     else
  198:     {
  199:         (*l_element_precedent).suivant = (*l_element_courant).suivant;
  200:     }
  201: 
  202:     if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
  203:     {
  204:         (*s_etat_processus).erreur_systeme = d_es_processus;
  205:         return;
  206:     }
  207: 
  208:     free((void *) (*l_element_courant).donnee);
  209:     free((struct_liste_chainee_volatile *) l_element_courant);
  210: 
  211:     return;
  212: }
  213: 
  214: void
  215: retrait_thread_surveillance(struct_processus *s_etat_processus,
  216:         struct_descripteur_thread *s_argument_thread)
  217: {
  218:     volatile struct_liste_chainee_volatile  *l_element_precedent;
  219:     volatile struct_liste_chainee_volatile  *l_element_courant;
  220: 
  221:     if (pthread_mutex_lock(&mutex_liste_threads) != 0)
  222:     {
  223:         (*s_etat_processus).erreur_systeme = d_es_processus;
  224:         return;
  225:     }
  226: 
  227:     l_element_precedent = NULL;
  228:     l_element_courant = liste_threads_surveillance;
  229: 
  230:     while(l_element_courant != NULL)
  231:     {
  232:         if ((*l_element_courant).donnee == (void *) s_argument_thread)
  233:         {
  234:             break;
  235:         }
  236: 
  237:         l_element_precedent = l_element_courant;
  238:         l_element_courant = (*l_element_courant).suivant;
  239:     }
  240: 
  241:     if (l_element_courant == NULL)
  242:     {
  243:         pthread_mutex_unlock(&mutex_liste_threads);
  244:         (*s_etat_processus).erreur_systeme = d_es_processus;
  245:         return;
  246:     }
  247: 
  248:     if (l_element_precedent == NULL)
  249:     {
  250:         liste_threads_surveillance = (*l_element_courant).suivant;
  251:     }
  252:     else
  253:     {
  254:         (*l_element_precedent).suivant = (*l_element_courant).suivant;
  255:     }
  256: 
  257:     if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
  258:             != 0)
  259:     {
  260:         pthread_mutex_unlock(&mutex_liste_threads);
  261:         (*s_etat_processus).erreur_systeme = d_es_processus;
  262:         return;
  263:     }
  264: 
  265:     (*s_argument_thread).nombre_references--;
  266: 
  267:     BUG((*s_argument_thread).nombre_references < 0,
  268:             printf("(*s_argument_thread).nombre_references = %d\n",
  269:             (int) (*s_argument_thread).nombre_references));
  270: 
  271:     if ((*s_argument_thread).nombre_references == 0)
  272:     {
  273:         if (pthread_mutex_unlock(&((*s_argument_thread)
  274:                 .mutex_nombre_references)) != 0)
  275:         {
  276:             pthread_mutex_unlock(&mutex_liste_threads);
  277:             (*s_etat_processus).erreur_systeme = d_es_processus;
  278:             return;
  279:         }
  280: 
  281:         pthread_mutex_destroy(&((*s_argument_thread).mutex));
  282:         pthread_mutex_destroy(&((*s_argument_thread).mutex_nombre_references));
  283:         free(s_argument_thread);
  284:     }
  285:     else
  286:     {
  287:         if (pthread_mutex_unlock(&((*s_argument_thread)
  288:                 .mutex_nombre_references)) != 0)
  289:         {
  290:             pthread_mutex_unlock(&mutex_liste_threads);
  291:             (*s_etat_processus).erreur_systeme = d_es_processus;
  292:             return;
  293:         }
  294:     }
  295: 
  296:     if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
  297:     {
  298:         (*s_etat_processus).erreur_systeme = d_es_processus;
  299:         return;
  300:     }
  301: 
  302:     free((struct_liste_chainee_volatile *) l_element_courant);
  303:     return;
  304: }
  305: 
  306: void
  307: verrouillage_threads_concurrents(struct_processus *s_etat_processus)
  308: {
  309:     volatile struct_liste_chainee_volatile  *l_element_courant;
  310: 
  311:     if (pthread_mutex_lock(&mutex_liste_threads) != 0)
  312:     {
  313:         (*s_etat_processus).erreur_systeme = d_es_processus;
  314:         return;
  315:     }
  316: 
  317:     l_element_courant = liste_threads;
  318: 
  319:     while(l_element_courant != NULL)
  320:     {
  321:         if (((*((struct_thread *) (*l_element_courant).donnee)).pid
  322:                 == getpid()) && (pthread_equal((*((struct_thread *)
  323:                 (*l_element_courant).donnee)).tid, pthread_self()) == 0))
  324:         {
  325:             if (pthread_mutex_lock(&((*(*((struct_thread *) (*l_element_courant)
  326:                     .donnee)).s_etat_processus).mutex_fork)) == -1)
  327:             {
  328:                 (*s_etat_processus).erreur_systeme = d_es_processus;
  329:                 return;
  330:             }
  331:         }
  332: 
  333:         l_element_courant = (*l_element_courant).suivant;
  334:     }
  335: 
  336:     return;
  337: }
  338: 
  339: void
  340: deverrouillage_threads_concurrents(struct_processus *s_etat_processus)
  341: {
  342:     volatile struct_liste_chainee_volatile  *l_element_courant;
  343: 
  344:     l_element_courant = liste_threads;
  345: 
  346:     while(l_element_courant != NULL)
  347:     {
  348:         if (((*((struct_thread *) (*l_element_courant).donnee)).pid
  349:                 == getpid()) && (pthread_equal((*((struct_thread *)
  350:                 (*l_element_courant).donnee)).tid, pthread_self()) == 0))
  351:         {
  352:             if (pthread_mutex_unlock(&((*(*((struct_thread *)
  353:                     (*l_element_courant).donnee)).s_etat_processus)
  354:                     .mutex_fork)) != 0)
  355:             {
  356:                 if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
  357:                 {
  358:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  359:                     return;
  360:                 }
  361: 
  362:                 (*s_etat_processus).erreur_systeme = d_es_processus;
  363:                 return;
  364:             }
  365:         }
  366: 
  367:         l_element_courant = (*l_element_courant).suivant;
  368:     }
  369: 
  370:     if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
  371:     {
  372:         (*s_etat_processus).erreur_systeme = d_es_processus;
  373:         return;
  374:     }
  375: 
  376:     return;
  377: }
  378: 
  379: void
  380: liberation_threads(struct_processus *s_etat_processus)
  381: {
  382:     logical1                                    suppression_variables_partagees;
  383: 
  384:     struct_descripteur_thread                   *s_argument_thread;
  385: 
  386:     struct_processus                            *candidat;
  387: 
  388:     unsigned long                               i;
  389: 
  390:     void                                        *element_candidat;
  391:     void                                        *element_courant;
  392:     void                                        *element_suivant;
  393: 
  394:     volatile struct_liste_chainee_volatile      *l_element_courant;
  395:     volatile struct_liste_chainee_volatile      *l_element_suivant;
  396: 
  397:     if (pthread_mutex_lock(&mutex_liste_threads) == -1)
  398:     {
  399:         (*s_etat_processus).erreur_systeme = d_es_processus;
  400:         return;
  401:     }
  402: 
  403:     l_element_courant = liste_threads;
  404:     suppression_variables_partagees = d_faux;
  405: 
  406:     while(l_element_courant != NULL)
  407:     {
  408:         if ((*((struct_thread *) (*l_element_courant).donnee)).s_etat_processus
  409:                 != s_etat_processus)
  410:         {
  411:             candidat = s_etat_processus;
  412:             s_etat_processus = (*((struct_thread *)
  413:                     (*l_element_courant).donnee)).s_etat_processus;
  414:             free((*s_etat_processus).localisation);
  415: 
  416:             // (*s_etat_processus).instruction_courante peut pointer sur
  417:             // n'importe quoi (une instruction courante ou un champ d'une
  418:             // structure objet). On ne le libère pas quitte à avoir une
  419:             // petite fuite mémoire dans le processus fils.
  420: 
  421:             if ((*s_etat_processus).instruction_courante != NULL)
  422:             {
  423:                 //free((*s_etat_processus).instruction_courante);
  424:             }
  425: 
  426:             close((*s_etat_processus).pipe_acquittement);
  427:             close((*s_etat_processus).pipe_donnees);
  428:             close((*s_etat_processus).pipe_injections);
  429:             close((*s_etat_processus).pipe_nombre_injections);
  430:             close((*s_etat_processus).pipe_interruptions);
  431:             close((*s_etat_processus).pipe_nombre_objets_attente);
  432:             close((*s_etat_processus).pipe_nombre_interruptions_attente);
  433: 
  434:             liberation(s_etat_processus, (*s_etat_processus).at_exit);
  435: 
  436:             if ((*s_etat_processus).nom_fichier_impression != NULL)
  437:             {
  438:                 free((*s_etat_processus).nom_fichier_impression);
  439:             }
  440: 
  441:             while((*s_etat_processus).fichiers_graphiques != NULL)
  442:             {
  443:                 free((*(*s_etat_processus).fichiers_graphiques).nom);
  444: 
  445:                 if ((*(*s_etat_processus).fichiers_graphiques).legende != NULL)
  446:                 {
  447:                     free((*(*s_etat_processus).fichiers_graphiques).legende);
  448:                 }
  449: 
  450:                 element_courant = (*s_etat_processus).fichiers_graphiques;
  451:                 (*s_etat_processus).fichiers_graphiques =
  452:                         (*(*s_etat_processus).fichiers_graphiques).suivant;
  453: 
  454:                 free(element_courant);
  455:             }
  456: 
  457:             if ((*s_etat_processus).entree_standard != NULL)
  458:             {
  459:                 pclose((*s_etat_processus).entree_standard);
  460:             }
  461: 
  462:             if ((*s_etat_processus).generateur_aleatoire != NULL)
  463:             {
  464:                 liberation_generateur_aleatoire(s_etat_processus);
  465:             }
  466: 
  467:             if ((*s_etat_processus).instruction_derniere_erreur != NULL)
  468:             {
  469:                 free((*s_etat_processus).instruction_derniere_erreur);
  470:                 (*s_etat_processus).instruction_derniere_erreur = NULL;
  471:             }
  472: 
  473:             element_courant = (void *) (*s_etat_processus)
  474:                     .l_base_pile_processus;
  475:             while(element_courant != NULL)
  476:             {
  477:                 s_argument_thread = (struct_descripteur_thread *)
  478:                         (*((struct_liste_chainee *) element_courant)).donnee;
  479: 
  480:                 if (pthread_mutex_lock(&((*s_argument_thread)
  481:                         .mutex_nombre_references)) != 0)
  482:                 {
  483:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  484:                     pthread_mutex_unlock(&mutex_liste_threads);
  485:                     return;
  486:                 }
  487: 
  488:                 (*s_argument_thread).nombre_references--;
  489: 
  490:                 BUG((*s_argument_thread).nombre_references < 0,
  491:                         printf("(*s_argument_thread).nombre_references = %d\n",
  492:                         (int) (*s_argument_thread).nombre_references));
  493: 
  494:                 if ((*s_argument_thread).nombre_references == 0)
  495:                 {
  496:                     close((*s_argument_thread).pipe_objets[0]);
  497:                     close((*s_argument_thread).pipe_acquittement[1]);
  498:                     close((*s_argument_thread).pipe_injections[1]);
  499:                     close((*s_argument_thread).pipe_nombre_injections[1]);
  500:                     close((*s_argument_thread).pipe_nombre_objets_attente[0]);
  501:                     close((*s_argument_thread).pipe_interruptions[0]);
  502:                     close((*s_argument_thread)
  503:                             .pipe_nombre_interruptions_attente[0]);
  504: 
  505:                     if (pthread_mutex_unlock(&((*s_argument_thread)
  506:                             .mutex_nombre_references)) != 0)
  507:                     {
  508:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  509:                         pthread_mutex_unlock(&mutex_liste_threads);
  510:                         return;
  511:                     }
  512: 
  513:                     pthread_mutex_destroy(&((*s_argument_thread).mutex));
  514:                     pthread_mutex_destroy(&((*s_argument_thread)
  515:                             .mutex_nombre_references));
  516: 
  517:                     if ((*s_argument_thread).processus_detache == d_faux)
  518:                     {
  519:                         if ((*s_argument_thread).destruction_objet == d_vrai)
  520:                         {
  521:                             liberation(s_etat_processus, (*s_argument_thread)
  522:                                     .argument);
  523:                         }
  524:                     }
  525: 
  526:                     free(s_argument_thread);
  527:                 }
  528:                 else
  529:                 {
  530:                     if (pthread_mutex_unlock(&((*s_argument_thread)
  531:                             .mutex_nombre_references)) != 0)
  532:                     {
  533:                         (*s_etat_processus).erreur_systeme = d_es_processus;
  534:                         pthread_mutex_unlock(&mutex_liste_threads);
  535:                         return;
  536:                     }
  537:                 }
  538: 
  539:                 element_suivant = (*((struct_liste_chainee *) element_courant))
  540:                         .suivant;
  541:                 free(element_courant);
  542:                 element_courant = element_suivant;
  543:             }
  544: 
  545:             (*s_etat_processus).l_base_pile_processus = NULL;
  546: 
  547:             pthread_mutex_trylock(&((*(*s_etat_processus).indep).mutex));
  548:             pthread_mutex_unlock(&((*(*s_etat_processus).indep).mutex));
  549:             liberation(s_etat_processus, (*s_etat_processus).indep);
  550: 
  551:             pthread_mutex_trylock(&((*(*s_etat_processus).depend).mutex));
  552:             pthread_mutex_unlock(&((*(*s_etat_processus).depend).mutex));
  553:             liberation(s_etat_processus, (*s_etat_processus).depend);
  554: 
  555:             free((*s_etat_processus).label_x);
  556:             free((*s_etat_processus).label_y);
  557:             free((*s_etat_processus).label_z);
  558:             free((*s_etat_processus).titre);
  559:             free((*s_etat_processus).legende);
  560: 
  561:             pthread_mutex_trylock(&((*(*s_etat_processus)
  562:                     .parametres_courbes_de_niveau).mutex));
  563:             pthread_mutex_unlock(&((*(*s_etat_processus)
  564:                     .parametres_courbes_de_niveau).mutex));
  565:             liberation(s_etat_processus, (*s_etat_processus)
  566:                     .parametres_courbes_de_niveau);
  567: 
  568:             for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++)
  569:             {
  570:                 if ((*s_etat_processus).corps_interruptions[i] != NULL)
  571:                 {
  572:                     pthread_mutex_trylock(&((*(*s_etat_processus)
  573:                             .corps_interruptions[i]).mutex));
  574:                     pthread_mutex_unlock(&((*(*s_etat_processus)
  575:                             .corps_interruptions[i]).mutex));
  576: 
  577:                     liberation(s_etat_processus,
  578:                             (*s_etat_processus).corps_interruptions[i]);
  579:                 }
  580: 
  581:                 element_courant = (*s_etat_processus)
  582:                         .pile_origine_interruptions[i];
  583: 
  584:                 while(element_courant != NULL)
  585:                 {
  586:                     element_suivant = (*((struct_liste_chainee *)
  587:                             element_courant)).suivant;
  588: 
  589:                     pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  590:                             element_courant)).donnee).mutex));
  591:                     pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  592:                             element_courant)).donnee).mutex));
  593: 
  594:                     liberation(s_etat_processus,
  595:                             (*((struct_liste_chainee *) element_courant))
  596:                             .donnee);
  597:                     free(element_courant);
  598: 
  599:                     element_courant = element_suivant;
  600:                 }
  601:             }
  602: 
  603:             liberation_arbre_variables(s_etat_processus,
  604:                     (*s_etat_processus).s_arbre_variables, d_faux);
  605: 
  606:             for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++)
  607:             {
  608:                 pthread_mutex_trylock(&((*(*s_etat_processus)
  609:                         .s_liste_variables_statiques[i].objet).mutex));
  610:                 pthread_mutex_unlock(&((*(*s_etat_processus)
  611:                         .s_liste_variables_statiques[i].objet).mutex));
  612: 
  613:                 liberation(s_etat_processus, (*s_etat_processus)
  614:                         .s_liste_variables_statiques[i].objet);
  615:                 free((*s_etat_processus).s_liste_variables_statiques[i].nom);
  616:             }
  617: 
  618:             free((*s_etat_processus).s_liste_variables_statiques);
  619: 
  620:             // Ne peut être effacé qu'une seule fois
  621:             if (suppression_variables_partagees == d_faux)
  622:             {
  623:                 suppression_variables_partagees = d_vrai;
  624: 
  625:                 for(i = 0; i < (*(*s_etat_processus)
  626:                         .s_liste_variables_partagees).nombre_variables; i++)
  627:                 {
  628:                     pthread_mutex_trylock(&((*(*(*s_etat_processus)
  629:                             .s_liste_variables_partagees).table[i].objet)
  630:                             .mutex));
  631:                     pthread_mutex_unlock(&((*(*(*s_etat_processus)
  632:                             .s_liste_variables_partagees).table[i].objet)
  633:                             .mutex));
  634: 
  635:                     liberation(s_etat_processus, (*(*s_etat_processus)
  636:                             .s_liste_variables_partagees).table[i].objet);
  637:                     free((*(*s_etat_processus).s_liste_variables_partagees)
  638:                             .table[i].nom);
  639:                 }
  640: 
  641:                 if ((*(*s_etat_processus).s_liste_variables_partagees).table
  642:                         != NULL)
  643:                 {
  644:                     free((struct_variable_partagee *) (*(*s_etat_processus)
  645:                             .s_liste_variables_partagees).table);
  646:                 }
  647: 
  648:                 pthread_mutex_trylock(&((*(*s_etat_processus)
  649:                         .s_liste_variables_partagees).mutex));
  650:                 pthread_mutex_unlock(&((*(*s_etat_processus)
  651:                         .s_liste_variables_partagees).mutex));
  652:             }
  653: 
  654:             element_courant = (*s_etat_processus).l_base_pile;
  655:             while(element_courant != NULL)
  656:             {
  657:                 element_suivant = (*((struct_liste_chainee *)
  658:                         element_courant)).suivant;
  659: 
  660:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  661:                         element_courant)).donnee).mutex));
  662:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  663:                         element_courant)).donnee).mutex));
  664: 
  665:                 liberation(s_etat_processus,
  666:                         (*((struct_liste_chainee *)
  667:                         element_courant)).donnee);
  668:                 free((struct_liste_chainee *) element_courant);
  669: 
  670:                 element_courant = element_suivant;
  671:             }
  672: 
  673:             element_courant = (*s_etat_processus).l_base_pile_contextes;
  674:             while(element_courant != NULL)
  675:             {
  676:                 element_suivant = (*((struct_liste_chainee *)
  677:                         element_courant)).suivant;
  678: 
  679:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  680:                         element_courant)).donnee).mutex));
  681:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  682:                         element_courant)).donnee).mutex));
  683:                 liberation(s_etat_processus, (*((struct_liste_chainee *)
  684:                         element_courant)).donnee);
  685:                 free((struct_liste_chainee *) element_courant);
  686: 
  687:                 element_courant = element_suivant;
  688:             }
  689: 
  690:             element_courant = (*s_etat_processus).l_base_pile_taille_contextes;
  691:             while(element_courant != NULL)
  692:             {
  693:                 element_suivant = (*((struct_liste_chainee *)
  694:                         element_courant)).suivant;
  695: 
  696:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  697:                         element_courant)).donnee).mutex));
  698:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  699:                         element_courant)).donnee).mutex));
  700:                 liberation(s_etat_processus,
  701:                         (*((struct_liste_chainee *)
  702:                         element_courant)).donnee);
  703:                 free((struct_liste_chainee *) element_courant);
  704: 
  705:                 element_courant = element_suivant;
  706:             }
  707: 
  708:             for(i = 0; i < (*s_etat_processus).nombre_instructions_externes;
  709:                     i++)
  710:             {
  711:                 free((*s_etat_processus).s_instructions_externes[i].nom);
  712:                 free((*s_etat_processus).s_instructions_externes[i]
  713:                         .nom_bibliotheque);
  714:             }
  715: 
  716:             if ((*s_etat_processus).nombre_instructions_externes != 0)
  717:             {
  718:                 free((*s_etat_processus).s_instructions_externes);
  719:             }
  720: 
  721:             element_courant = (*s_etat_processus).s_bibliotheques;
  722:             while(element_courant != NULL)
  723:             {
  724:                 element_suivant = (*((struct_liste_chainee *)
  725:                         element_courant)).suivant;
  726: 
  727:                 element_candidat = (*candidat).s_bibliotheques;
  728:                 while(element_candidat != NULL)
  729:                 {
  730:                     if (((*((struct_bibliotheque *) (*((struct_liste_chainee *)
  731:                             element_courant)).donnee))
  732:                             .descripteur == (*((struct_bibliotheque *)
  733:                             (*((struct_liste_chainee *) element_candidat))
  734:                             .donnee)).descripteur) &&
  735:                             ((*((struct_bibliotheque *)
  736:                             (*((struct_liste_chainee *) element_courant))
  737:                             .donnee)).pid == (*((struct_bibliotheque *)
  738:                             (*((struct_liste_chainee *) element_candidat))
  739:                             .donnee)).pid) && (pthread_equal(
  740:                             (*((struct_bibliotheque *)
  741:                             (*((struct_liste_chainee *) element_courant))
  742:                             .donnee)).tid, (*((struct_bibliotheque *)
  743:                             (*((struct_liste_chainee *) element_candidat))
  744:                             .donnee)).tid) != 0))
  745:                     {
  746:                         break;
  747:                     }
  748: 
  749:                     element_candidat = (*((struct_liste_chainee *)
  750:                             element_candidat)).suivant;
  751:                 }
  752: 
  753:                 if (element_candidat == NULL)
  754:                 {
  755:                     dlclose((*((struct_bibliotheque *)
  756:                             (*((struct_liste_chainee *) element_courant))
  757:                             .donnee)).descripteur);
  758:                 }
  759: 
  760:                 free((*((struct_bibliotheque *)
  761:                         (*((struct_liste_chainee *)
  762:                         element_courant)).donnee)).nom);
  763:                 free((*((struct_liste_chainee *) element_courant)).donnee);
  764:                 free(element_courant);
  765: 
  766:                 element_courant = element_suivant;
  767:             }
  768: 
  769:             element_courant = (*s_etat_processus).l_base_pile_last;
  770:             while(element_courant != NULL)
  771:             {
  772:                 element_suivant = (*((struct_liste_chainee *)
  773:                         element_courant)).suivant;
  774: 
  775:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  776:                         element_courant)).donnee).mutex));
  777:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  778:                         element_courant)).donnee).mutex));
  779:                 liberation(s_etat_processus,
  780:                         (*((struct_liste_chainee *) element_courant)).donnee);
  781:                 free(element_courant);
  782: 
  783:                 element_courant = element_suivant;
  784:             }
  785: 
  786:             element_courant = (*s_etat_processus).l_base_pile_systeme;
  787:             while(element_courant != NULL)
  788:             {
  789:                 element_suivant = (*((struct_liste_pile_systeme *)
  790:                         element_courant)).suivant;
  791: 
  792:                 if ((*((struct_liste_pile_systeme *)
  793:                         element_courant)).indice_boucle != NULL)
  794:                 {
  795:                     pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
  796:                             element_courant)).indice_boucle).mutex));
  797:                     pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
  798:                             element_courant)).indice_boucle).mutex));
  799:                 }
  800: 
  801:                 liberation(s_etat_processus,
  802:                         (*((struct_liste_pile_systeme *)
  803:                         element_courant)).indice_boucle);
  804: 
  805:                 if ((*((struct_liste_pile_systeme *)
  806:                         element_courant)).limite_indice_boucle != NULL)
  807:                 {
  808:                     pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
  809:                             element_courant)).limite_indice_boucle).mutex));
  810:                     pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
  811:                             element_courant)).limite_indice_boucle).mutex));
  812:                 }
  813: 
  814:                 liberation(s_etat_processus,
  815:                         (*((struct_liste_pile_systeme *)
  816:                         element_courant)).limite_indice_boucle);
  817: 
  818:                 if ((*((struct_liste_pile_systeme *)
  819:                         element_courant)).objet_de_test != NULL)
  820:                 {
  821:                     pthread_mutex_trylock(&((*(*((struct_liste_pile_systeme *)
  822:                             element_courant)).objet_de_test).mutex));
  823:                     pthread_mutex_unlock(&((*(*((struct_liste_pile_systeme *)
  824:                             element_courant)).objet_de_test).mutex));
  825:                 }
  826: 
  827:                 liberation(s_etat_processus,
  828:                         (*((struct_liste_pile_systeme *)
  829:                         element_courant)).objet_de_test);
  830: 
  831:                 if ((*((struct_liste_pile_systeme *)
  832:                         element_courant)).nom_variable != NULL)
  833:                 {
  834:                     free((*((struct_liste_pile_systeme *)
  835:                             element_courant)).nom_variable);
  836:                 }
  837: 
  838:                 free(element_courant);
  839: 
  840:                 element_courant = element_suivant;
  841:             }
  842: 
  843:             element_courant = (*s_etat_processus).s_fichiers;
  844:             while(element_courant != NULL)
  845:             {
  846:                 element_suivant = (*((struct_liste_chainee *)
  847:                         element_courant)).suivant;
  848: 
  849:                 element_candidat = (*candidat).s_fichiers;
  850:                 while(element_candidat != NULL)
  851:                 {
  852:                     if (((*((struct_descripteur_fichier *)
  853:                             (*((struct_liste_chainee *) element_courant))
  854:                             .donnee)).pid ==
  855:                             (*((struct_descripteur_fichier *)
  856:                             (*((struct_liste_chainee *) element_candidat))
  857:                             .donnee)).pid) && (pthread_equal(
  858:                             (*((struct_descripteur_fichier *)
  859:                             (*((struct_liste_chainee *) element_courant))
  860:                             .donnee)).tid, (*((struct_descripteur_fichier *)
  861:                             (*((struct_liste_chainee *) element_candidat))
  862:                             .donnee)).tid) != 0))
  863:                     {
  864:                         if ((*((struct_descripteur_fichier *)
  865:                                 (*((struct_liste_chainee *) element_courant))
  866:                                 .donnee)).type ==
  867:                                 (*((struct_descripteur_fichier *)
  868:                                 (*((struct_liste_chainee *) element_candidat))
  869:                                 .donnee)).type)
  870:                         {
  871:                             if ((*((struct_descripteur_fichier *)
  872:                                     (*((struct_liste_chainee *)
  873:                                     element_candidat)).donnee)).type == 'C')
  874:                             {
  875:                                 if ((*((struct_descripteur_fichier *)
  876:                                         (*((struct_liste_chainee *)
  877:                                         element_courant)).donnee))
  878:                                         .descripteur_c ==
  879:                                         (*((struct_descripteur_fichier *)
  880:                                         (*((struct_liste_chainee *)
  881:                                         element_candidat)).donnee))
  882:                                         .descripteur_c)
  883:                                 {
  884:                                     break;
  885:                                 }
  886:                             }
  887:                             else
  888:                             {
  889:                                 if (((*((struct_descripteur_fichier *)
  890:                                         (*((struct_liste_chainee *)
  891:                                         element_courant)).donnee))
  892:                                         .descripteur_sqlite ==
  893:                                         (*((struct_descripteur_fichier *)
  894:                                         (*((struct_liste_chainee *)
  895:                                         element_candidat)).donnee))
  896:                                         .descripteur_sqlite) &&
  897:                                         ((*((struct_descripteur_fichier *)
  898:                                         (*((struct_liste_chainee *)
  899:                                         element_courant)).donnee))
  900:                                         .descripteur_c ==
  901:                                         (*((struct_descripteur_fichier *)
  902:                                         (*((struct_liste_chainee *)
  903:                                         element_candidat)).donnee))
  904:                                         .descripteur_c))
  905:                                 {
  906:                                     break;
  907:                                 }
  908:                             }
  909:                         }
  910:                     }
  911: 
  912:                     element_candidat = (*((struct_liste_chainee *)
  913:                             element_candidat)).suivant;
  914:                 }
  915: 
  916:                 if (element_candidat == NULL)
  917:                 {
  918:                     fclose((*((struct_descripteur_fichier *)
  919:                             (*((struct_liste_chainee *) element_courant))
  920:                             .donnee)).descripteur_c);
  921: 
  922:                     if ((*((struct_descripteur_fichier *)
  923:                             (*((struct_liste_chainee *) element_courant))
  924:                             .donnee)).type != 'C')
  925:                     {
  926:                         sqlite3_close((*((struct_descripteur_fichier *)
  927:                                 (*((struct_liste_chainee *) element_courant))
  928:                                 .donnee)).descripteur_sqlite);
  929:                     }
  930:                 }
  931: 
  932:                 free((*((struct_descripteur_fichier *)
  933:                         (*((struct_liste_chainee *)
  934:                         element_courant)).donnee)).nom);
  935:                 free((struct_descripteur_fichier *)
  936:                         (*((struct_liste_chainee *)
  937:                         element_courant)).donnee);
  938:                 free(element_courant);
  939: 
  940:                 element_courant = element_suivant;
  941:             }
  942: 
  943:             element_courant = (*s_etat_processus).s_sockets;
  944:             while(element_courant != NULL)
  945:             {
  946:                 element_suivant = (*((struct_liste_chainee *)
  947:                         element_courant)).suivant;
  948: 
  949:                 element_candidat = (*candidat).s_sockets;
  950:                 while(element_candidat != NULL)
  951:                 {
  952:                     if (((*((struct_socket *)
  953:                             (*((struct_liste_chainee *) element_courant))
  954:                             .donnee)).socket == (*((struct_socket *)
  955:                             (*((struct_liste_chainee *) element_candidat))
  956:                             .donnee)).socket) &&
  957:                             ((*((struct_socket *)
  958:                             (*((struct_liste_chainee *) element_courant))
  959:                             .donnee)).pid == (*((struct_socket *)
  960:                             (*((struct_liste_chainee *) element_candidat))
  961:                             .donnee)).pid) && (pthread_equal(
  962:                             (*((struct_socket *)
  963:                             (*((struct_liste_chainee *) element_courant))
  964:                             .donnee)).tid, (*((struct_socket *)
  965:                             (*((struct_liste_chainee *) element_candidat))
  966:                             .donnee)).tid) != 0))
  967:                     {
  968:                         break;
  969:                     }
  970: 
  971:                     element_candidat = (*((struct_liste_chainee *)
  972:                             element_candidat)).suivant;
  973:                 }
  974: 
  975:                 if (element_candidat == NULL)
  976:                 {
  977:                     if ((*((struct_socket *) (*((struct_liste_chainee *)
  978:                             element_courant)).donnee)).socket_connectee
  979:                             == d_vrai)
  980:                     {
  981:                         shutdown((*((struct_socket *)
  982:                                 (*((struct_liste_chainee *) element_courant))
  983:                                 .donnee)).socket, SHUT_RDWR);
  984:                     }
  985: 
  986:                     close((*((struct_socket *)
  987:                             (*((struct_liste_chainee *) element_courant))
  988:                             .donnee)).socket);
  989:                 }
  990: 
  991:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
  992:                         element_courant)).donnee).mutex));
  993:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
  994:                         element_courant)).donnee).mutex));
  995: 
  996:                 liberation(s_etat_processus,
  997:                         (*((struct_liste_chainee *)
  998:                         element_courant)).donnee);
  999:                 free(element_courant);
 1000: 
 1001:                 element_courant = element_suivant;
 1002:             }
 1003: 
 1004: /*
 1005: ================================================================================
 1006:   À noter : on ne ferme pas la connexion car la conséquence immédiate est
 1007:   une destruction de l'objet pour le processus père.
 1008: ================================================================================
 1009: 
 1010:             element_courant = (*s_etat_processus).s_connecteurs_sql;
 1011:             while(element_courant != NULL)
 1012:             {
 1013:                 element_suivant = (*((struct_liste_chainee *)
 1014:                         element_courant)).suivant;
 1015: 
 1016:                 element_candidat = (*candidat).s_connecteurs_sql;
 1017:                 while(element_candidat != NULL)
 1018:                 {
 1019:                     if (((
 1020: #ifdef MYSQL_SUPPORT
 1021:                             ((*((struct_connecteur_sql *)
 1022:                             (*((struct_liste_chainee *) element_courant))
 1023:                             .donnee)).descripteur.mysql ==
 1024:                             (*((struct_connecteur_sql *)
 1025:                             (*((struct_liste_chainee *) element_candidat))
 1026:                             .donnee)).descripteur.mysql)
 1027:                             &&
 1028:                             (strcmp((*((struct_connecteur_sql *)
 1029:                             (*((struct_liste_chainee *) element_courant))
 1030:                             .donnee)).type, "MYSQL") == 0)
 1031:                             &&
 1032:                             (strcmp((*((struct_connecteur_sql *)
 1033:                             (*((struct_liste_chainee *) element_candidat))
 1034:                             .donnee)).type, "MYSQL") == 0)
 1035: #else
 1036:                             0
 1037: #endif
 1038:                             ) || (
 1039: #ifdef POSTGRESQL_SUPPORT
 1040:                             ((*((struct_connecteur_sql *)
 1041:                             (*((struct_liste_chainee *) element_courant))
 1042:                             .donnee)).descripteur.postgresql ==
 1043:                             (*((struct_connecteur_sql *)
 1044:                             (*((struct_liste_chainee *) element_candidat))
 1045:                             .donnee)).descripteur.postgresql)
 1046:                             &&
 1047:                             (strcmp((*((struct_connecteur_sql *)
 1048:                             (*((struct_liste_chainee *) element_courant))
 1049:                             .donnee)).type, "POSTGRESQL") == 0)
 1050:                             &&
 1051:                             (strcmp((*((struct_connecteur_sql *)
 1052:                             (*((struct_liste_chainee *) element_candidat))
 1053:                             .donnee)).type, "POSTGRESQL") == 0)
 1054: #else
 1055:                             0
 1056: #endif
 1057:                             )) &&
 1058:                             ((*((struct_connecteur_sql *)
 1059:                             (*((struct_liste_chainee *) element_courant))
 1060:                             .donnee)).pid == (*((struct_connecteur_sql *)
 1061:                             (*((struct_liste_chainee *) element_candidat))
 1062:                             .donnee)).pid) && (pthread_equal(
 1063:                             (*((struct_connecteur_sql *)
 1064:                             (*((struct_liste_chainee *) element_courant))
 1065:                             .donnee)).tid, (*((struct_connecteur_sql *)
 1066:                             (*((struct_liste_chainee *) element_candidat))
 1067:                             .donnee)).tid) != 0))
 1068:                     {
 1069:                         break;
 1070:                     }
 1071: 
 1072:                     element_candidat = (*((struct_liste_chainee *)
 1073:                             element_candidat)).suivant;
 1074:                 }
 1075: 
 1076:                 if (element_candidat == NULL)
 1077:                 {
 1078:                     sqlclose((*((struct_liste_chainee *) element_courant))
 1079:                             .donnee);
 1080:                 }
 1081: 
 1082:                 pthread_mutex_trylock(&((*(*((struct_liste_chainee *)
 1083:                         element_courant)).donnee).mutex));
 1084:                 pthread_mutex_unlock(&((*(*((struct_liste_chainee *)
 1085:                         element_courant)).donnee).mutex));
 1086: 
 1087:                 liberation(s_etat_processus, (*((struct_liste_chainee *)
 1088:                         element_courant)).donnee);
 1089:                 free(element_courant);
 1090: 
 1091:                 element_courant = element_suivant;
 1092:             }
 1093: */
 1094: 
 1095:             (*s_etat_processus).s_connecteurs_sql = NULL;
 1096: 
 1097:             element_courant = (*s_etat_processus).s_marques;
 1098:             while(element_courant != NULL)
 1099:             {
 1100:                 free((*((struct_marque *) element_courant)).label);
 1101:                 free((*((struct_marque *) element_courant)).position);
 1102:                 element_suivant = (*((struct_marque *) element_courant))
 1103:                         .suivant;
 1104:                 free(element_courant);
 1105:                 element_courant = element_suivant;
 1106:             }
 1107: 
 1108:             liberation_allocateur(s_etat_processus);
 1109: 
 1110:             pthread_mutex_unlock(&((*s_etat_processus).mutex_fork));
 1111:             pthread_mutex_destroy(&((*s_etat_processus).mutex_fork));
 1112: 
 1113:             liberation_contexte_cas(s_etat_processus);
 1114:             free(s_etat_processus);
 1115: 
 1116:             s_etat_processus = candidat;
 1117:         }
 1118: 
 1119:         l_element_suivant = (*l_element_courant).suivant;
 1120: 
 1121:         free((struct_thread *) (*l_element_courant).donnee);
 1122:         free((struct_liste_chainee *) l_element_courant);
 1123: 
 1124:         l_element_courant = l_element_suivant;
 1125:     }
 1126: 
 1127:     liste_threads = NULL;
 1128: 
 1129:     l_element_courant = liste_threads_surveillance;
 1130: 
 1131:     while(l_element_courant != NULL)
 1132:     {
 1133:         s_argument_thread = (struct_descripteur_thread *)
 1134:                 (*l_element_courant).donnee;
 1135: 
 1136:         if (pthread_mutex_lock(&((*s_argument_thread).mutex_nombre_references))
 1137:                 != 0)
 1138:         {
 1139:             (*s_etat_processus).erreur_systeme = d_es_processus;
 1140:             pthread_mutex_unlock(&mutex_liste_threads);
 1141:             return;
 1142:         }
 1143: 
 1144:         (*s_argument_thread).nombre_references--;
 1145: 
 1146:         BUG((*s_argument_thread).nombre_references < 0,
 1147:                 printf("(*s_argument_thread).nombre_references = %d\n",
 1148:                 (int) (*s_argument_thread).nombre_references));
 1149: 
 1150:         if ((*s_argument_thread).nombre_references == 0)
 1151:         {
 1152:             close((*s_argument_thread).pipe_objets[0]);
 1153:             close((*s_argument_thread).pipe_acquittement[1]);
 1154:             close((*s_argument_thread).pipe_injections[1]);
 1155:             close((*s_argument_thread).pipe_nombre_injections[1]);
 1156:             close((*s_argument_thread).pipe_nombre_objets_attente[0]);
 1157:             close((*s_argument_thread).pipe_interruptions[0]);
 1158:             close((*s_argument_thread).pipe_nombre_interruptions_attente[0]);
 1159: 
 1160:             if (pthread_mutex_unlock(&((*s_argument_thread)
 1161:                     .mutex_nombre_references)) != 0)
 1162:             {
 1163:                 (*s_etat_processus).erreur_systeme = d_es_processus;
 1164:                 pthread_mutex_unlock(&mutex_liste_threads);
 1165:                 return;
 1166:             }
 1167: 
 1168:             pthread_mutex_destroy(&((*s_argument_thread).mutex));
 1169:             pthread_mutex_destroy(&((*s_argument_thread)
 1170:                     .mutex_nombre_references));
 1171: 
 1172:             if ((*s_argument_thread).processus_detache == d_faux)
 1173:             {
 1174:                 if ((*s_argument_thread).destruction_objet == d_vrai)
 1175:                 {
 1176:                     liberation(s_etat_processus, (*s_argument_thread).argument);
 1177:                 }
 1178:             }
 1179: 
 1180:             free(s_argument_thread);
 1181:         }
 1182:         else
 1183:         {
 1184:             if (pthread_mutex_unlock(&((*s_argument_thread)
 1185:                     .mutex_nombre_references)) != 0)
 1186:             {
 1187:                 (*s_etat_processus).erreur_systeme = d_es_processus;
 1188:                 pthread_mutex_unlock(&mutex_liste_threads);
 1189:                 return;
 1190:             }
 1191:         }
 1192: 
 1193:         l_element_suivant = (*l_element_courant).suivant;
 1194:         free((struct_liste_chainee *) l_element_courant);
 1195:         l_element_courant = l_element_suivant;
 1196:     }
 1197: 
 1198:     liste_threads_surveillance = NULL;
 1199: 
 1200:     if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
 1201:     {
 1202:         (*s_etat_processus).erreur_systeme = d_es_processus;
 1203:         return;
 1204:     }
 1205: 
 1206:     return;
 1207: }
 1208: 
 1209: static struct_processus *
 1210: recherche_thread(pid_t pid, pthread_t tid)
 1211: {
 1212:     volatile struct_liste_chainee_volatile      *l_element_courant;
 1213: 
 1214:     struct_processus                            *s_etat_processus;
 1215: 
 1216:     l_element_courant = liste_threads;
 1217: 
 1218:     while(l_element_courant != NULL)
 1219:     {
 1220:         if ((pthread_equal((*((struct_thread *) (*l_element_courant).donnee))
 1221:                 .tid, tid) != 0) && ((*((struct_thread *)
 1222:                 (*l_element_courant).donnee)).pid == pid))
 1223:         {
 1224:             break;
 1225:         }
 1226: 
 1227:         l_element_courant = (*l_element_courant).suivant;
 1228:     }
 1229: 
 1230:     if (l_element_courant == NULL)
 1231:     {
 1232:         /*
 1233:          * Le processus n'existe plus. On ne distribue aucun signal.
 1234:          */
 1235: 
 1236:         return(NULL);
 1237:     }
 1238: 
 1239:     s_etat_processus = (*((struct_thread *)
 1240:             (*l_element_courant).donnee)).s_etat_processus;
 1241: 
 1242:     return(s_etat_processus);
 1243: }
 1244: 
 1245: static struct_processus *
 1246: recherche_thread_principal(pid_t pid)
 1247: {
 1248:     volatile struct_liste_chainee_volatile      *l_element_courant;
 1249: 
 1250:     l_element_courant = liste_threads;
 1251: 
 1252:     while(l_element_courant != NULL)
 1253:     {
 1254:         if (((*((struct_thread *) (*l_element_courant).donnee)).thread_principal
 1255:                 == d_vrai) && ((*((struct_thread *)
 1256:                 (*l_element_courant).donnee)).pid == pid))
 1257:         {
 1258:             break;
 1259:         }
 1260: 
 1261:         l_element_courant = (*l_element_courant).suivant;
 1262:     }
 1263: 
 1264:     if (l_element_courant == NULL)
 1265:     {
 1266:         /*
 1267:          * Le processus n'existe plus. On ne distribue aucun signal.
 1268:          */
 1269: 
 1270:         return(NULL);
 1271:     }
 1272: 
 1273:     return((*((struct_thread *) (*l_element_courant).donnee))
 1274:             .s_etat_processus);
 1275: }
 1276: 
 1277: 
 1278: /*
 1279: ================================================================================
 1280:   Procédures de gestion des signaux d'interruption
 1281: ================================================================================
 1282:   Entrée : variable globale
 1283: --------------------------------------------------------------------------------
 1284:   Sortie : variable globale modifiée
 1285: --------------------------------------------------------------------------------
 1286:   Effets de bord : néant
 1287: ================================================================================
 1288: */
 1289: 
 1290: // Les routines suivantes sont uniquement appelées depuis les gestionnaires
 1291: // des signaux asynchrones. Elles ne doivent pas bloquer dans le cas où
 1292: // les sémaphores sont déjà bloqués par un gestionnaire de signal.
 1293: 
 1294: static inline void
 1295: verrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
 1296: {
 1297:     int         semaphore;
 1298: 
 1299:     if (pthread_mutex_unlock(&((*s_etat_processus).mutex_fork)) != 0)
 1300:     {
 1301:         BUG(1, uprintf("Lock error !\n"));
 1302:         return;
 1303:     }
 1304: 
 1305:     // Il faut respecteur l'atomicité des deux opérations suivantes !
 1306: 
 1307:     if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) != 0)
 1308:     {
 1309:         pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
 1310:         BUG(1, uprintf("Unlock error !\n"));
 1311:         return;
 1312:     }
 1313: 
 1314: #   ifndef SEMAPHORES_NOMMES
 1315:     if (sem_post(&semaphore_gestionnaires_signaux) == -1)
 1316: #   else
 1317:     if (sem_post(semaphore_gestionnaires_signaux) == -1)
 1318: #   endif
 1319:     {
 1320:         pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
 1321:         BUG(1, uprintf("Lock error !\n"));
 1322:         return;
 1323:     }
 1324: 
 1325: #   ifndef SEMAPHORES_NOMMES
 1326:     if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
 1327: #   else
 1328:     if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
 1329: #   endif
 1330:     {
 1331:         pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
 1332:         BUG(1, uprintf("Lock error !\n"));
 1333:         return;
 1334:     }
 1335: 
 1336:     if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)
 1337:     {
 1338:         pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
 1339:         BUG(1, uprintf("Unlock error !\n"));
 1340:         return;
 1341:     }
 1342: 
 1343:     if (semaphore == 1)
 1344:     {
 1345:         // Le semaphore ne peut être pris par le thread qui a appelé
 1346:         // le gestionnaire de signal car le signal est bloqué par ce thread
 1347:         // dans les zones critiques. Ce sémaphore ne peut donc être bloqué que
 1348:         // par un thread concurrent. On essaye donc de le bloquer jusqu'à
 1349:         // ce que ce soit possible.
 1350: 
 1351:         if (pthread_mutex_lock(&mutex_liste_threads) != 0)
 1352:         {
 1353:             pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
 1354:             BUG(1, uprintf("Lock error !\n"));
 1355:             return;
 1356:         }
 1357:     }
 1358: 
 1359:     return;
 1360: }
 1361: 
 1362: static inline void
 1363: deverrouillage_gestionnaire_signaux(struct_processus *s_etat_processus)
 1364: {
 1365:     int         semaphore;
 1366: 
 1367:     // Il faut respecteur l'atomicité des deux opérations suivantes !
 1368: 
 1369:     if (pthread_mutex_lock(&mutex_gestionnaires_signaux_atomique) == -1)
 1370:     {
 1371:         pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
 1372:         BUG(1, uprintf("Unlock error !\n"));
 1373:         return;
 1374:     }
 1375: 
 1376: #   ifndef SEMAPHORES_NOMMES
 1377:     if (sem_getvalue(&semaphore_gestionnaires_signaux, &semaphore) != 0)
 1378: #   else
 1379:     if (sem_getvalue(semaphore_gestionnaires_signaux, &semaphore) != 0)
 1380: #   endif
 1381:     {
 1382:         pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
 1383:         BUG(1, uprintf("Unlock error !\n"));
 1384:         return;
 1385:     }
 1386: 
 1387: #   ifndef SEMAPHORES_NOMMES
 1388:     while(sem_wait(&semaphore_gestionnaires_signaux) == -1)
 1389: #   else
 1390:     while(sem_wait(semaphore_gestionnaires_signaux) == -1)
 1391: #   endif
 1392:     {
 1393:         if (errno != EINTR)
 1394:         {
 1395:             pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
 1396:             BUG(1, uprintf("Unlock error !\n"));
 1397:             return;
 1398:         }
 1399:     }
 1400: 
 1401:     if (pthread_mutex_unlock(&mutex_gestionnaires_signaux_atomique) != 0)
 1402:     {
 1403:         pthread_mutex_lock(&((*s_etat_processus).mutex_fork));
 1404:         BUG(1, uprintf("Unlock error !\n"));
 1405:         return;
 1406:     }
 1407: 
 1408:     if (pthread_mutex_lock(&((*s_etat_processus).mutex_fork)) != 0)
 1409:     {
 1410:         BUG(1, uprintf("Unlock error !\n"));
 1411:         return;
 1412:     }
 1413: 
 1414:     if (semaphore == 1)
 1415:     {
 1416:         if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
 1417:         {
 1418:             BUG(1, uprintf("Unlock error !\n"));
 1419:             return;
 1420:         }
 1421:     }
 1422: 
 1423:     return;
 1424: }
 1425: 
 1426: #define test_signal(signal) \
 1427:     if (signal_test == SIGTEST) { signal_test = signal; return; }
 1428: 
 1429: // Récupération des signaux
 1430: // - SIGINT (arrêt au clavier)
 1431: // - SIGTERM (signal d'arrêt en provenance du système)
 1432: 
 1433: void
 1434: interruption1(int signal)
 1435: {
 1436:     test_signal(signal);
 1437: 
 1438:     switch(signal)
 1439:     {
 1440:         case SIGINT:
 1441:             envoi_signal_processus(getpid(), rpl_sigint);
 1442:             break;
 1443: 
 1444:         case SIGTERM:
 1445:             envoi_signal_processus(getpid(), rpl_sigterm);
 1446:             break;
 1447: 
 1448:         case SIGALRM:
 1449:             envoi_signal_processus(getpid(), rpl_sigalrm);
 1450:             break;
 1451:     }
 1452: 
 1453:     return;
 1454: }
 1455: 
 1456: inline static void
 1457: signal_alrm(struct_processus *s_etat_processus, pid_t pid)
 1458: {
 1459:     struct_processus        *s_thread_principal;
 1460: 
 1461:     verrouillage_gestionnaire_signaux(s_etat_processus);
 1462: 
 1463:     if (pid == getpid())
 1464:     {
 1465:         // Si pid est égal à getpid(), le signal à traiter est issu
 1466:         // du même processus que celui qui va le traiter, mais d'un thread
 1467:         // différent.
 1468: 
 1469:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1470:         {
 1471:             printf("[%d] RPL/SIGALRM (thread %llu)\n", (int) getpid(),
 1472:                     (unsigned long long) pthread_self());
 1473:             fflush(stdout);
 1474:         }
 1475: 
 1476:         if ((*s_etat_processus).pid_processus_pere != getpid())
 1477:         {
 1478:             // On n'est pas dans le processus père, on remonte le signal.
 1479:             envoi_signal_processus((*s_etat_processus).pid_processus_pere,
 1480:                     rpl_sigalrm);
 1481:         }
 1482:         else
 1483:         {
 1484:             // On est dans le processus père, on effectue un arrêt d'urgence.
 1485:             (*s_etat_processus).var_volatile_alarme = -1;
 1486:             (*s_etat_processus).var_volatile_requete_arret = -1;
 1487:         }
 1488:     }
 1489:     else
 1490:     {
 1491:         // Le signal est issu d'un processus différent. On recherche le
 1492:         // thread principal pour remonter le signal.
 1493: 
 1494:         if ((s_thread_principal = recherche_thread_principal(getpid()))
 1495:                 != NULL)
 1496:         {
 1497:             envoi_signal_contexte(s_thread_principal, rpl_sigalrm);
 1498:         }
 1499:     }
 1500: 
 1501:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 1502:     return;
 1503: }
 1504: 
 1505: inline static void
 1506: signal_term(struct_processus *s_etat_processus, pid_t pid)
 1507: {
 1508:     struct_processus        *s_thread_principal;
 1509:     volatile sig_atomic_t   exclusion = 0;
 1510: 
 1511:     verrouillage_gestionnaire_signaux(s_etat_processus);
 1512: 
 1513:     if (pid == getpid())
 1514:     {
 1515:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1516:         {
 1517:             printf("[%d] RPL/SIGTERM (thread %llu)\n", (int) getpid(),
 1518:                     (unsigned long long) pthread_self());
 1519:             fflush(stdout);
 1520:         }
 1521: 
 1522:         if ((*s_etat_processus).pid_processus_pere != getpid())
 1523:         {
 1524:             envoi_signal_processus((*s_etat_processus).pid_processus_pere,
 1525:                     rpl_sigterm);
 1526:         }
 1527:         else
 1528:         {
 1529:             (*s_etat_processus).var_volatile_traitement_sigint = -1;
 1530: 
 1531:             while(exclusion == 1);
 1532:             exclusion = 1;
 1533: 
 1534:             if ((*s_etat_processus).var_volatile_requete_arret == -1)
 1535:             {
 1536:                 deverrouillage_gestionnaire_signaux(s_etat_processus);
 1537:                 exclusion = 0;
 1538:                 return;
 1539:             }
 1540: 
 1541:             (*s_etat_processus).var_volatile_requete_arret = -1;
 1542:             (*s_etat_processus).var_volatile_alarme = -1;
 1543: 
 1544:             exclusion = 0;
 1545:         }
 1546:     }
 1547:     else
 1548:     {
 1549:         if ((s_thread_principal = recherche_thread_principal(getpid()))
 1550:                 != NULL)
 1551:         {
 1552:             envoi_signal_contexte(s_thread_principal, rpl_sigterm);
 1553:         }
 1554:     }
 1555: 
 1556:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 1557:     return;
 1558: }
 1559: 
 1560: inline static void
 1561: signal_int(struct_processus *s_etat_processus, pid_t pid)
 1562: {
 1563:     struct_processus        *s_thread_principal;
 1564:     volatile sig_atomic_t   exclusion = 0;
 1565: 
 1566:     verrouillage_gestionnaire_signaux(s_etat_processus);
 1567: 
 1568:     if (pid == getpid())
 1569:     {
 1570:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1571:         {
 1572:             printf("[%d] RPL/SIGINT (thread %llu)\n", (int) getpid(),
 1573:                     (unsigned long long) pthread_self());
 1574:             fflush(stdout);
 1575:         }
 1576: 
 1577:         if ((*s_etat_processus).pid_processus_pere != getpid())
 1578:         {
 1579:             envoi_signal_processus((*s_etat_processus).pid_processus_pere,
 1580:                     rpl_sigint);
 1581:         }
 1582:         else
 1583:         {
 1584:             (*s_etat_processus).var_volatile_traitement_sigint = -1;
 1585: 
 1586:             while(exclusion == 1);
 1587:             exclusion = 1;
 1588: 
 1589:             if ((*s_etat_processus).var_volatile_requete_arret == -1)
 1590:             {
 1591:                 deverrouillage_gestionnaire_signaux(s_etat_processus);
 1592:                 exclusion = 0;
 1593:                 return;
 1594:             }
 1595: 
 1596:             if ((*s_etat_processus).langue == 'F')
 1597:             {
 1598:                 printf("+++Interruption\n");
 1599:             }
 1600:             else
 1601:             {
 1602:                 printf("+++Interrupt\n");
 1603:             }
 1604: 
 1605:             fflush(stdout);
 1606: 
 1607:             (*s_etat_processus).var_volatile_requete_arret = -1;
 1608:             (*s_etat_processus).var_volatile_alarme = -1;
 1609: 
 1610:             exclusion = 0;
 1611:         }
 1612:     }
 1613:     else
 1614:     {
 1615:         if ((s_thread_principal = recherche_thread_principal(getpid()))
 1616:                 != NULL)
 1617:         {
 1618:             envoi_signal_contexte(s_thread_principal, rpl_sigint);
 1619:         }
 1620:     }
 1621: 
 1622:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 1623:     return;
 1624: }
 1625: 
 1626: // Récupération des signaux
 1627: // - SIGFSTP
 1628: //
 1629: // ATTENTION :
 1630: // Le signal SIGFSTP provient de la mort du processus de contrôle.
 1631: // Sous certains systèmes (Linux...), la mort du terminal de contrôle
 1632: // se traduit par l'envoi d'un SIGHUP au processus. Sur d'autres
 1633: // (SunOS), le processus reçoit un SIGFSTP avec une structure siginfo
 1634: // non initialisée (pointeur NULL) issue de TERMIO.
 1635: 
 1636: void
 1637: interruption2(int signal)
 1638: {
 1639:     test_signal(signal);
 1640:     envoi_signal_processus(getpid(), rpl_sigtstp);
 1641:     return;
 1642: }
 1643: 
 1644: static inline void
 1645: signal_tstp(struct_processus *s_etat_processus, pid_t pid)
 1646: {
 1647:     struct_processus        *s_thread_principal;
 1648: 
 1649:     verrouillage_gestionnaire_signaux(s_etat_processus);
 1650: 
 1651:     if (pid == getpid())
 1652:     {
 1653:         /*
 1654:          *  0 => fonctionnement normal
 1655:          * -1 => requête
 1656:          *  1 => requête acceptée en attente de traitement
 1657:          */
 1658: 
 1659:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1660:         {
 1661:             printf("[%d] RPL/SIGTSTP (thread %llu)\n", (int) getpid(),
 1662:                     (unsigned long long) pthread_self());
 1663:             fflush(stdout);
 1664:         }
 1665: 
 1666:         if ((*s_etat_processus).var_volatile_processus_pere == 0)
 1667:         {
 1668:             envoi_signal_processus((*s_etat_processus).pid_processus_pere,
 1669:                     rpl_sigtstp);
 1670:         }
 1671:         else
 1672:         {
 1673:             (*s_etat_processus).var_volatile_requete_arret2 = -1;
 1674:         }
 1675:     }
 1676:     else
 1677:     {
 1678:         // Envoi d'un signal au thread maître du groupe.
 1679: 
 1680:         if ((s_thread_principal = recherche_thread_principal(getpid()))
 1681:                 != NULL)
 1682:         {
 1683:             envoi_signal_contexte(s_thread_principal, rpl_sigtstp);
 1684:         }
 1685:     }
 1686: 
 1687:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 1688:     return;
 1689: }
 1690: 
 1691: void
 1692: interruption3(int signal)
 1693: {
 1694:     // Si on passe par ici, c'est qu'il est impossible de récupérer
 1695:     // l'erreur d'accès à la mémoire. On sort donc du programme quitte à
 1696:     // ce qu'il reste des processus orphelins.
 1697: 
 1698:     unsigned char       message[] = "+++System : Uncaught access violation\n"
 1699:                                 "+++System : Aborting !\n";
 1700: 
 1701:     test_signal(signal);
 1702: 
 1703:     if (pid_processus_pere == getpid())
 1704:     {
 1705:         kill(pid_processus_pere, SIGALRM);
 1706:     }
 1707: 
 1708:     write(STDERR_FILENO, message, strlen(message));
 1709:     _exit(EXIT_FAILURE);
 1710: }
 1711: 
 1712: #if 0
 1713: // Utiliser libsigsegv
 1714: void INTERRUPTION3_A_FIXER()
 1715: {
 1716:     pthread_t               thread;
 1717: 
 1718:     struct_processus        *s_etat_processus;
 1719: 
 1720:     test_signal(signal);
 1721:     verrouillage_gestionnaire_signaux(s_etat_processus);
 1722: 
 1723:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 1724:     {
 1725:         deverrouillage_gestionnaire_signaux(s_etat_processus);
 1726:         return;
 1727:     }
 1728: 
 1729:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1730:     {
 1731:         printf("[%d] SIGSEGV (thread %llu)\n", (int) getpid(),
 1732:                 (unsigned long long) pthread_self());
 1733:         fflush(stdout);
 1734:     }
 1735: 
 1736:     if ((*s_etat_processus).var_volatile_recursivite == -1)
 1737:     {
 1738:         // Segfault dans un appel de fonction récursive
 1739:         deverrouillage_gestionnaire_signaux(s_etat_processus);
 1740:         longjmp(contexte, -1);
 1741:     }
 1742:     else
 1743:     {
 1744:         // Segfault dans une routine interne
 1745:         if (strncmp(getenv("LANG"), "fr", 2) == 0)
 1746:         {
 1747:             printf("+++Système : Violation d'accès\n");
 1748:         }
 1749:         else
 1750:         {
 1751:             printf("+++System : Access violation\n");
 1752:         }
 1753: 
 1754:         fflush(stdout);
 1755: 
 1756:         (*s_etat_processus).compteur_violation_d_acces++;
 1757: 
 1758:         if ((*s_etat_processus).compteur_violation_d_acces > 1)
 1759:         {
 1760:             // On vient de récupérer plus d'une erreur de segmentation
 1761:             // dans le même processus ou le même thread. L'erreur n'est pas
 1762:             // récupérable et on sort autoritairement du programme. Il peut
 1763:             // rester des processus orphelins en attente !
 1764: 
 1765:             if (strncmp(getenv("LANG"), "fr", 2) == 0)
 1766:             {
 1767:                 printf("+++Système : Violation d'accès, tentative de "
 1768:                         "terminaison de la tâche\n");
 1769:                 printf("             (defauts multiples)\n");
 1770:             }
 1771:             else
 1772:             {
 1773:                 printf("+++System : Access violation, trying to kill task "
 1774:                         "(multiple defaults)\n");
 1775:             }
 1776: 
 1777:             fflush(stdout);
 1778: 
 1779:             deverrouillage_gestionnaire_signaux(s_etat_processus);
 1780:             exit(EXIT_FAILURE);
 1781:         }
 1782:         else
 1783:         {
 1784:             // Première erreur de segmentation. On essaie de terminer
 1785:             // proprement le thread ou le processus. Le signal ne peut être
 1786:             // envoyé que depuis le même processus.
 1787: 
 1788:             if (recherche_thread_principal(getpid(), &thread) == d_vrai)
 1789:             {
 1790:                 if (pthread_equal(thread, pthread_self()) != 0)
 1791:                 {
 1792:                     deverrouillage_gestionnaire_signaux(s_etat_processus);
 1793: 
 1794:                     if ((*s_etat_processus).pid_processus_pere != getpid())
 1795:                     {
 1796:                         // On est dans le thread principal d'un processus.
 1797: 
 1798:                         longjmp(contexte_processus, -1);
 1799:                     }
 1800:                     else
 1801:                     {
 1802:                         // On est dans le thread principal du processus
 1803:                         // père.
 1804: 
 1805:                         longjmp(contexte_initial, -1);
 1806:                     }
 1807:                 }
 1808:                 else
 1809:                 {
 1810:                     // On est dans un thread fils d'un thread principal.
 1811: 
 1812:                     deverrouillage_gestionnaire_signaux(s_etat_processus);
 1813:                     longjmp(contexte_thread, -1);
 1814:                 }
 1815:             }
 1816: 
 1817:             // Là, on ramasse les miettes puisque le thread n'existe plus
 1818:             // dans la base (corruption de la mémoire).
 1819: 
 1820:             deverrouillage_gestionnaire_signaux(s_etat_processus);
 1821:             longjmp(contexte_initial, -1);
 1822:         }
 1823:     }
 1824: 
 1825:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 1826:     return;
 1827: }
 1828: #endif
 1829: 
 1830: // Traitement de rpl_sigstart
 1831: 
 1832: static inline void
 1833: signal_start(struct_processus *s_etat_processus, pid_t pid)
 1834: {
 1835:     (*s_etat_processus).demarrage_fils = d_vrai;
 1836:     return;
 1837: }
 1838: 
 1839: // Traitement de rpl_sigcont
 1840: 
 1841: static inline void
 1842: signal_cont(struct_processus *s_etat_processus, pid_t pid)
 1843: {
 1844:     (*s_etat_processus).redemarrage_processus = d_vrai;
 1845:     return;
 1846: }
 1847: 
 1848: // Traitement de rpl_sigstop
 1849: 
 1850: static inline void
 1851: signal_stop(struct_processus *s_etat_processus, pid_t pid)
 1852: {
 1853:     struct_processus        *s_thread_principal;
 1854: 
 1855:     verrouillage_gestionnaire_signaux(s_etat_processus);
 1856: 
 1857:     if (pid == getpid())
 1858:     {
 1859:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 1860:                 == NULL)
 1861:         {
 1862:             deverrouillage_gestionnaire_signaux(s_etat_processus);
 1863:             return;
 1864:         }
 1865: 
 1866:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1867:         {
 1868:             printf("[%d] RPL/SIGFSTOP (thread %llu)\n", (int) getpid(),
 1869:                     (unsigned long long) pthread_self());
 1870:             fflush(stdout);
 1871:         }
 1872: 
 1873:         /*
 1874:          * var_globale_traitement_retarde_stop :
 1875:          *  0 -> traitement immédiat
 1876:          *  1 -> traitement retardé (aucun signal reçu)
 1877:          * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
 1878:          */
 1879: 
 1880:         if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
 1881:         {
 1882:             (*s_etat_processus).var_volatile_requete_arret = -1;
 1883:         }
 1884:         else
 1885:         {
 1886:             (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
 1887:         }
 1888:     }
 1889:     else
 1890:     {
 1891:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 1892:                 == NULL)
 1893:         {
 1894:             deverrouillage_gestionnaire_signaux(s_etat_processus);
 1895:             return;
 1896:         }
 1897: 
 1898:         // Envoi d'un signal au thread maître du groupe.
 1899: 
 1900:         if ((s_thread_principal = recherche_thread_principal(getpid()))
 1901:                 != NULL)
 1902:         {
 1903:             envoi_signal_contexte(s_thread_principal, rpl_sigstop);
 1904:         }
 1905:     }
 1906: 
 1907:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 1908:     return;
 1909: }
 1910: 
 1911: // Traitement de rpl_siginject
 1912: 
 1913: static inline void
 1914: signal_inject(struct_processus *s_etat_processus, pid_t pid)
 1915: {
 1916:     verrouillage_gestionnaire_signaux(s_etat_processus);
 1917: 
 1918:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 1919:     {
 1920:         deverrouillage_gestionnaire_signaux(s_etat_processus);
 1921:         return;
 1922:     }
 1923: 
 1924:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1925:     {
 1926:         printf("[%d] RPL/SIGINJECT (thread %llu)\n", (int) getpid(),
 1927:                 (unsigned long long) pthread_self());
 1928:         fflush(stdout);
 1929:     }
 1930: 
 1931:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 1932:     return;
 1933: }
 1934: 
 1935: // Récupération des signaux
 1936: // - SIGPIPE
 1937: 
 1938: void
 1939: interruption5(int signal)
 1940: {
 1941:     unsigned char       message[] = "+++System : SIGPIPE\n"
 1942:                                 "+++System : Aborting !\n";
 1943: 
 1944:     test_signal(signal);
 1945: 
 1946:     if (pid_processus_pere == getpid())
 1947:     {
 1948:         envoi_signal_processus(pid_processus_pere, rpl_sigalrm);
 1949:     }
 1950: 
 1951:     write(STDERR_FILENO, message, strlen(message));
 1952:     return;
 1953: }
 1954: 
 1955: static inline void
 1956: signal_urg(struct_processus *s_etat_processus, pid_t pid)
 1957: {
 1958:     struct_processus        *s_thread_principal;
 1959: 
 1960:     verrouillage_gestionnaire_signaux(s_etat_processus);
 1961: 
 1962:     if (pid == getpid())
 1963:     {
 1964:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 1965:                 == NULL)
 1966:         {
 1967:             deverrouillage_gestionnaire_signaux(s_etat_processus);
 1968:             return;
 1969:         }
 1970: 
 1971:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 1972:         {
 1973:             printf("[%d] RPL/SIGURG (thread %llu)\n", (int) getpid(),
 1974:                     (unsigned long long) pthread_self());
 1975:             fflush(stdout);
 1976:         }
 1977: 
 1978:         (*s_etat_processus).var_volatile_alarme = -1;
 1979:         (*s_etat_processus).var_volatile_requete_arret = -1;
 1980:     }
 1981:     else
 1982:     {
 1983:         // Envoi d'un signal au thread maître du groupe.
 1984: 
 1985:         if ((s_thread_principal = recherche_thread_principal(getpid()))
 1986:                 != NULL)
 1987:         {
 1988:             envoi_signal_contexte(s_thread_principal, rpl_sigurg);
 1989:         }
 1990:     }
 1991: 
 1992:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 1993:     return;
 1994: }
 1995: 
 1996: // Traitement de rpl_sigabort
 1997: 
 1998: static inline void
 1999: signal_abort(struct_processus *s_etat_processus, pid_t pid)
 2000: {
 2001:     struct_processus        *s_thread_principal;
 2002: 
 2003:     verrouillage_gestionnaire_signaux(s_etat_processus);
 2004: 
 2005:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2006:     {
 2007:         deverrouillage_gestionnaire_signaux(s_etat_processus);
 2008:         return;
 2009:     }
 2010: 
 2011:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2012:     {
 2013:         printf("[%d] RPL/SIGABORT (thread %llu)\n", (int) getpid(),
 2014:                 (unsigned long long) pthread_self());
 2015:         fflush(stdout);
 2016:     }
 2017: 
 2018:     if (pid == getpid())
 2019:     {
 2020:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 2021:                 == NULL)
 2022:         {
 2023:             deverrouillage_gestionnaire_signaux(s_etat_processus);
 2024:             return;
 2025:         }
 2026: 
 2027:         (*s_etat_processus).arret_depuis_abort = -1;
 2028: 
 2029:         if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2030:         {
 2031:             printf("[%d] SIGFABORT (thread %llu)\n", (int) getpid(),
 2032:                     (unsigned long long) pthread_self());
 2033:             fflush(stdout);
 2034:         }
 2035: 
 2036:         /*
 2037:          * var_globale_traitement_retarde_stop :
 2038:          *  0 -> traitement immédiat
 2039:          *  1 -> traitement retardé (aucun signal reçu)
 2040:          * -1 -> traitement retardé (un ou plusieurs signaux stop reçus)
 2041:          */
 2042: 
 2043:         if ((*s_etat_processus).var_volatile_traitement_retarde_stop == 0)
 2044:         {
 2045:             (*s_etat_processus).var_volatile_requete_arret = -1;
 2046:         }
 2047:         else
 2048:         {
 2049:             (*s_etat_processus).var_volatile_traitement_retarde_stop = -1;
 2050:         }
 2051:     }
 2052:     else
 2053:     {
 2054:         if ((s_etat_processus = recherche_thread(getpid(), pthread_self()))
 2055:                 == NULL)
 2056:         {
 2057:             deverrouillage_gestionnaire_signaux(s_etat_processus);
 2058:             return;
 2059:         }
 2060: 
 2061:         (*s_etat_processus).arret_depuis_abort = -1;
 2062: 
 2063:         // Envoi d'un signal au thread maître du groupe.
 2064: 
 2065:         if ((s_thread_principal = recherche_thread_principal(getpid()))
 2066:                 != NULL)
 2067:         {
 2068:             envoi_signal_contexte(s_thread_principal, rpl_sigabort);
 2069:         }
 2070:     }
 2071: 
 2072:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 2073:     return;
 2074: }
 2075: 
 2076: // Récupération des signaux
 2077: // - SIGHUP
 2078: 
 2079: void
 2080: interruption4(int signal)
 2081: {
 2082:     test_signal(signal);
 2083:     envoi_signal_processus(getpid(), rpl_sighup);
 2084:     return;
 2085: }
 2086: 
 2087: static inline void
 2088: signal_hup(struct_processus *s_etat_processus, pid_t pid)
 2089: {
 2090:     file                    *fichier;
 2091: 
 2092:     unsigned char           nom[8 + 64 + 1];
 2093: 
 2094:     verrouillage_gestionnaire_signaux(s_etat_processus);
 2095: 
 2096:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2097:     {
 2098:         deverrouillage_gestionnaire_signaux(s_etat_processus);
 2099:         return;
 2100:     }
 2101: 
 2102:     snprintf(nom, 8 + 64 + 1, "rpl-out-%lu-%lu", (unsigned long) getpid(),
 2103:             (unsigned long) pthread_self());
 2104: 
 2105:     if ((fichier = fopen(nom, "w+")) != NULL)
 2106:     {
 2107:         fclose(fichier);
 2108: 
 2109:         freopen(nom, "w", stdout);
 2110:         freopen(nom, "w", stderr);
 2111:     }
 2112: 
 2113:     freopen("/dev/null", "r", stdin);
 2114: 
 2115:     if (((*s_etat_processus).type_debug & d_debug_signaux) != 0)
 2116:     {
 2117:         printf("[%d] SIGHUP (thread %llu)\n", (int) getpid(),
 2118:                 (unsigned long long) pthread_self());
 2119:         fflush(stdout);
 2120:     }
 2121: 
 2122:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 2123:     return;
 2124: }
 2125: 
 2126: void
 2127: traitement_exceptions_gsl(const char *reason, const char *file,
 2128:         int line, int gsl_errno)
 2129: {
 2130:     code_erreur_gsl = gsl_errno;
 2131:     envoi_signal_processus(getpid(), rpl_sigexcept);
 2132:     return;
 2133: }
 2134: 
 2135: static inline void
 2136: signal_except(struct_processus *s_etat_processus, pid_t pid)
 2137: {
 2138:     verrouillage_gestionnaire_signaux(s_etat_processus);
 2139: 
 2140:     if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL)
 2141:     {
 2142:         deverrouillage_gestionnaire_signaux(s_etat_processus);
 2143:         return;
 2144:     }
 2145: 
 2146:     (*s_etat_processus).var_volatile_exception_gsl = code_erreur_gsl;
 2147:     deverrouillage_gestionnaire_signaux(s_etat_processus);
 2148: 
 2149:     return;
 2150: }
 2151: 
 2152: static inline void
 2153: envoi_interruptions(struct_processus *s_etat_processus, enum signaux_rpl signal,
 2154:         pid_t pid_source)
 2155: {
 2156:     unsigned char       message[] = "+++System : Spurious signa !\n";
 2157: 
 2158:     switch(signal)
 2159:     {
 2160:         case rpl_sigint:
 2161:             signal_int(s_etat_processus, pid_source);
 2162:             break;
 2163: 
 2164:         case rpl_sigterm:
 2165:             signal_term(s_etat_processus, pid_source);
 2166:             break;
 2167: 
 2168:         case rpl_sigstart:
 2169:             signal_start(s_etat_processus, pid_source);
 2170:             break;
 2171: 
 2172:         case rpl_sigcont:
 2173:             signal_cont(s_etat_processus, pid_source);
 2174:             break;
 2175: 
 2176:         case rpl_sigstop:
 2177:             signal_stop(s_etat_processus, pid_source);
 2178:             break;
 2179: 
 2180:         case rpl_sigabort:
 2181:             signal_abort(s_etat_processus, pid_source);
 2182:             break;
 2183: 
 2184:         case rpl_sigurg:
 2185:             signal_urg(s_etat_processus, pid_source);
 2186:             break;
 2187: 
 2188:         case rpl_siginject:
 2189:             signal_inject(s_etat_processus, pid_source);
 2190:             break;
 2191: 
 2192:         case rpl_sigalrm:
 2193:             signal_alrm(s_etat_processus, pid_source);
 2194:             break;
 2195: 
 2196:         case rpl_sighup:
 2197:             signal_hup(s_etat_processus, pid_source);
 2198:             break;
 2199: 
 2200:         case rpl_sigtstp:
 2201:             signal_tstp(s_etat_processus, pid_source);
 2202:             break;
 2203: 
 2204:         case rpl_sigexcept:
 2205:             signal_except(s_etat_processus, pid_source);
 2206:             break;
 2207: 
 2208:         default:
 2209:             write(STDERR_FILENO, message, strlen(message));
 2210:             break;
 2211:     }
 2212: 
 2213:     return;
 2214: }
 2215: 
 2216: void
 2217: scrutation_interruptions(struct_processus *s_etat_processus)
 2218: {
 2219:     // Interruptions qui arrivent sur le processus depuis un
 2220:     // processus externe.
 2221: 
 2222:     // Les pointeurs de lecture pointent sur les prochains éléments
 2223:     // à lire. Les pointeurs d'écriture pointent sur les prochains éléments à
 2224:     // écrire.
 2225: 
 2226:     if (pthread_mutex_trylock(&((*s_queue_signaux).mutex)) == 0)
 2227:     {
 2228:         if ((*s_queue_signaux).pointeur_lecture !=
 2229:                 (*s_queue_signaux).pointeur_ecriture)
 2230:         {
 2231:             // Il y a un signal en attente dans le segment partagé. On le
 2232:             // traite.
 2233: 
 2234:             envoi_interruptions(s_etat_processus,
 2235:                     (*s_queue_signaux).queue[(*s_queue_signaux)
 2236:                     .pointeur_lecture].signal, (*s_queue_signaux).queue
 2237:                     [(*s_queue_signaux).pointeur_lecture].pid);
 2238:             (*s_queue_signaux).pointeur_lecture =
 2239:                     ((*s_queue_signaux).pointeur_lecture + 1)
 2240:                     % LONGUEUR_QUEUE_SIGNAUX;
 2241:         }
 2242: 
 2243:         pthread_mutex_unlock(&((*s_queue_signaux).mutex));
 2244:     }
 2245: 
 2246:     // Interruptions qui arrivent depuis le groupe courant de threads.
 2247: 
 2248:     if (pthread_mutex_trylock(&mutex_interruptions) == 0)
 2249:     {
 2250:         if ((*s_etat_processus).pointeur_signal_lecture !=
 2251:                 (*s_etat_processus).pointeur_signal_ecriture)
 2252:         {
 2253:             // Il y a un signal dans la queue du thread courant. On le traite.
 2254: 
 2255:             envoi_interruptions(s_etat_processus,
 2256:                     (*s_etat_processus).signaux_en_queue
 2257:                     [(*s_etat_processus).pointeur_signal_lecture],
 2258:                     getpid());
 2259:             (*s_etat_processus).pointeur_signal_lecture =
 2260:                     ((*s_etat_processus).pointeur_signal_lecture + 1)
 2261:                     % LONGUEUR_QUEUE_SIGNAUX;
 2262:         }
 2263: 
 2264:         pthread_mutex_unlock(&mutex_interruptions);
 2265:     }
 2266: 
 2267:     return;
 2268: }
 2269: 
 2270: int
 2271: envoi_signal_processus(pid_t pid, enum signaux_rpl signal)
 2272: {
 2273:     // Il s'agit d'ouvrir le segment de mémoire partagée, de le projeter en
 2274:     // mémoire puis d'y inscrire le signal à traiter.
 2275: 
 2276:     return(0);
 2277: }
 2278: 
 2279: int
 2280: envoi_signal_thread(pthread_t tid, enum signaux_rpl signal)
 2281: {
 2282:     // Un signal est envoyé d'un thread à un autre thread du même processus.
 2283: 
 2284:     volatile struct_liste_chainee_volatile  *l_element_courant;
 2285: 
 2286:     struct_processus                        *s_etat_processus;
 2287: 
 2288:     if (pthread_mutex_lock(&mutex_liste_threads) != 0)
 2289:     {
 2290:         return(1);
 2291:     }
 2292: 
 2293:     l_element_courant = liste_threads;
 2294: 
 2295:     while(l_element_courant != NULL)
 2296:     {
 2297:         if (((*((struct_thread *) (*l_element_courant).donnee)).pid
 2298:                 == getpid()) && (pthread_equal((*((struct_thread *)
 2299:                 (*l_element_courant).donnee)).tid, tid) != 0))
 2300:         {
 2301:             break;
 2302:         }
 2303: 
 2304:         l_element_courant = (*l_element_courant).suivant;
 2305:     }
 2306: 
 2307:     if (l_element_courant == NULL)
 2308:     {
 2309:         pthread_mutex_unlock(&mutex_liste_threads);
 2310:         return(1);
 2311:     }
 2312: 
 2313:     if (pthread_mutex_lock(&mutex_interruptions) != 0)
 2314:     {
 2315:         pthread_mutex_unlock(&mutex_liste_threads);
 2316:         return(1);
 2317:     }
 2318: 
 2319:     s_etat_processus = (*((struct_thread *) (*l_element_courant).donnee))
 2320:             .s_etat_processus;
 2321: 
 2322:     (*s_etat_processus).signaux_en_queue
 2323:             [(*s_etat_processus).pointeur_signal_ecriture] = signal;
 2324:     (*s_etat_processus).pointeur_signal_ecriture =
 2325:             ((*s_etat_processus).pointeur_signal_ecriture + 1)
 2326:             % LONGUEUR_QUEUE_SIGNAUX;
 2327: 
 2328:     if (pthread_mutex_unlock(&mutex_interruptions) != 0)
 2329:     {
 2330:         pthread_mutex_unlock(&mutex_liste_threads);
 2331:         return(1);
 2332:     }
 2333: 
 2334:     if (pthread_mutex_unlock(&mutex_liste_threads) != 0)
 2335:     {
 2336:         return(1);
 2337:     }
 2338: 
 2339:     return(0);
 2340: }
 2341: 
 2342: int
 2343: envoi_signal_contexte(struct_processus *s_etat_processus_a_signaler,
 2344:         enum signaux_rpl signal)
 2345: {
 2346:     pthread_mutex_lock(&mutex_interruptions);
 2347:     (*s_etat_processus_a_signaler).signaux_en_queue
 2348:             [(*s_etat_processus_a_signaler).pointeur_signal_ecriture] =
 2349:             signal;
 2350:     (*s_etat_processus_a_signaler).pointeur_signal_ecriture =
 2351:             ((*s_etat_processus_a_signaler).pointeur_signal_ecriture + 1)
 2352:             % LONGUEUR_QUEUE_SIGNAUX;
 2353:     pthread_mutex_unlock(&mutex_interruptions);
 2354: 
 2355:     return(0);
 2356: }
 2357: 
 2358: 
 2359: /*
 2360: ================================================================================
 2361:   Fonction renvoyant le nom du segment de mémoire partagée en fonction
 2362:   du pid du processus.
 2363: ================================================================================
 2364:   Entrée : Chemin absolue servant de racine, pid du processus
 2365: --------------------------------------------------------------------------------
 2366:   Sortie : NULL ou nom du segment
 2367: --------------------------------------------------------------------------------
 2368:   Effet de bord : Néant
 2369: ================================================================================
 2370: */
 2371: 
 2372: static unsigned char *
 2373: nom_segment(unsigned char *chemin, pid_t pid)
 2374: {
 2375:     unsigned char               *fichier;
 2376: 
 2377: #   ifdef IPCS_SYSV // !POSIX
 2378: #       ifndef OS2 // !OS2
 2379: 
 2380:             if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) *
 2381:                     sizeof(unsigned char))) == NULL)
 2382:             {
 2383:                 return(NULL);
 2384:             }
 2385: 
 2386:             sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);
 2387: #       else // OS2
 2388:             if ((fichier = malloc((10 + 256 + 1) * sizeof(unsigned char)))
 2389:                     == NULL)
 2390:             {
 2391:                 return(NULL);
 2392:             }
 2393: 
 2394:             sprintf(fichier, "\\SHAREMEM\\RPL-SIGQUEUES-%d", (int) pid);
 2395: #       endif // OS2
 2396: #   else // POSIX
 2397: 
 2398:         if ((fichier = malloc((1 + 256 + 1) *
 2399:                 sizeof(unsigned char))) == NULL)
 2400:         {
 2401:             return(NULL);
 2402:         }
 2403: 
 2404:         sprintf(fichier, "/RPL-SIGQUEUES-%d", (int) pid);
 2405: #   endif
 2406: 
 2407:     return(fichier);
 2408: }
 2409: 
 2410: 
 2411: /*
 2412: ================================================================================
 2413:   Fonction créant un segment de mémoire partagée destiné à contenir
 2414:   la queue des signaux.
 2415: ================================================================================
 2416:   Entrée : structure de description du processus
 2417: --------------------------------------------------------------------------------
 2418:   Sortie : Néant
 2419: --------------------------------------------------------------------------------
 2420:   Effet de bord : Néant
 2421: ================================================================================
 2422: */
 2423: 
 2424: void
 2425: creation_queue_signaux(struct_processus *s_etat_processus)
 2426: {
 2427:     int                             segment;
 2428: 
 2429:     pthread_mutexattr_t             attributs_mutex;
 2430: 
 2431:     unsigned char                   *nom;
 2432: 
 2433: #   ifndef IPCS_SYSV // POSIX
 2434: 
 2435:     if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
 2436:             getpid())) == NULL)
 2437:     {
 2438:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2439:         return;
 2440:     }
 2441: 
 2442:     if ((segment = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,
 2443:             S_IRUSR | S_IWUSR)) == -1)
 2444:     {
 2445:         free(nom);
 2446:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2447:         return;
 2448:     }
 2449: 
 2450:     if (ftruncate(segment, sizeof(struct_queue_signaux)) == -1)
 2451:     {
 2452:         free(nom);
 2453:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2454:         return;
 2455:     }
 2456: 
 2457:     s_queue_signaux = mmap(NULL, sizeof(struct_queue_signaux),
 2458:             PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0);
 2459:     close(segment);
 2460: 
 2461:     if (((void *) s_queue_signaux) == ((void *) -1))
 2462:     {
 2463:         if (shm_unlink(nom) == -1)
 2464:         {
 2465:             free(nom);
 2466:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2467:             return;
 2468:         }
 2469: 
 2470:         free(nom);
 2471:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2472:         return;
 2473:     }
 2474: 
 2475:     free(nom);
 2476: 
 2477:     pthread_mutexattr_init(&attributs_mutex);
 2478:     pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL);
 2479:     pthread_mutex_init(&((*s_queue_signaux).mutex), &attributs_mutex);
 2480:     pthread_mutexattr_destroy(&attributs_mutex);
 2481: 
 2482:     (*s_queue_signaux).pointeur_lecture = 0;
 2483:     (*s_queue_signaux).pointeur_ecriture = 0;
 2484: 
 2485: #   else // SystemV
 2486: #   ifndef OS2
 2487: 
 2488:     file                            *desc;
 2489: 
 2490:     key_t                           clef;
 2491: 
 2492:     // Création d'un segment de données associé au PID du processus courant
 2493: 
 2494:     chemin = (*s_etat_processus).chemin_fichiers_temporaires;
 2495: 
 2496:     if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
 2497:             getpid())) == NULL)
 2498:     {
 2499:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2500:         return;
 2501:     }
 2502: 
 2503:     if ((desc = fopen(nom, "w")) == NULL)
 2504:     {
 2505:         (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
 2506:         return;
 2507:     }
 2508: 
 2509:     fclose(desc);
 2510: 
 2511:     if ((clef = ftok(nom, 1)) == -1)
 2512:     {
 2513:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2514:         return;
 2515:     }
 2516: 
 2517:     free(nom);
 2518: 
 2519:     if ((segment = shmget(clef,
 2520:             nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
 2521:             IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)
 2522:     {
 2523:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2524:         return;
 2525:     }
 2526: 
 2527:     fifos = shmat(segment, NULL, 0);
 2528: 
 2529:     if (((void *) fifos) == ((void *) -1))
 2530:     {
 2531:         if (shmctl(segment, IPC_RMID, 0) == -1)
 2532:         {
 2533:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2534:             return;
 2535:         }
 2536: 
 2537:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2538:         return;
 2539:     }
 2540: 
 2541: #   else
 2542: 
 2543:     if ((nom = nom_segment(NULL, getpid())) == NULL)
 2544:     {
 2545:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2546:         return;
 2547:     }
 2548: 
 2549:     if (DosAllocSharedMem(&ptr_os2, nom, nombre_queues *
 2550:             ((2 * longueur_queue) + 4) * sizeof(int),
 2551:             PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
 2552:     {
 2553:         free(nom);
 2554:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2555:         return;
 2556:     }
 2557: 
 2558:     free(nom);
 2559:     fifos = ptr_os2;
 2560: 
 2561: #   endif
 2562: #   endif
 2563: 
 2564:     return;
 2565: }
 2566: 
 2567: 
 2568: /*
 2569: ================================================================================
 2570:   Fonction libérant le segment de mémoire partagée destiné à contenir
 2571:   la queue des signaux.
 2572: ================================================================================
 2573:   Entrée : structure de description du processus
 2574: --------------------------------------------------------------------------------
 2575:   Sortie : Néant
 2576: --------------------------------------------------------------------------------
 2577:   Effet de bord : Néant
 2578: ================================================================================
 2579: */
 2580: 
 2581: void
 2582: liberation_queue_signaux(struct_processus *s_etat_processus)
 2583: {
 2584: #   ifdef IPCS_SYSV // SystemV
 2585: #       ifndef OS2
 2586: #       else // OS/2
 2587: #       endif
 2588: #   else // POSIX
 2589:         if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
 2590:         {
 2591:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2592:             return;
 2593:         }
 2594: #   endif
 2595: 
 2596:     return;
 2597: }
 2598: 
 2599: 
 2600: /*
 2601: ================================================================================
 2602:   Fonction détruisant le segment de mémoire partagée destiné à contenir
 2603:   la queue des signaux.
 2604: ================================================================================
 2605:   Entrée : structure de description du processus
 2606: --------------------------------------------------------------------------------
 2607:   Sortie : Néant
 2608: --------------------------------------------------------------------------------
 2609:   Effet de bord : Néant
 2610: ================================================================================
 2611: */
 2612: 
 2613: void
 2614: destruction_queue_signaux(struct_processus *s_etat_processus)
 2615: {
 2616:     unsigned char       *nom;
 2617: 
 2618: #   ifdef IPCS_SYSV // SystemV
 2619: #   ifndef OS2
 2620: 
 2621:     if (shmdt(fifos) == -1)
 2622:     {
 2623:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2624:         return;
 2625:     }
 2626: 
 2627:     if (shmctl(segment, IPC_RMID, 0) == -1)
 2628:     {
 2629:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2630:         return;
 2631:     }
 2632: 
 2633:     if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
 2634:             getpid())) == NULL)
 2635:     {
 2636:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2637:         return;
 2638:     }
 2639: 
 2640:     unlink(nom);
 2641:     free(nom);
 2642: 
 2643: #   else
 2644: 
 2645:     if (DosFreeMem(fifos) != 0)
 2646:     {
 2647:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2648:         return;
 2649:     }
 2650: 
 2651: #   endif
 2652: #   else // POSIX
 2653: 
 2654:     if (munmap(s_queue_signaux, sizeof(struct_queue_signaux)) != 0)
 2655:     {
 2656:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2657:         return;
 2658:     }
 2659: 
 2660:     if ((nom = nom_segment(NULL, getpid())) == NULL)
 2661:     {
 2662:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2663:         return;
 2664:     }
 2665: 
 2666:     if (shm_unlink(nom) != 0)
 2667:     {
 2668:         free(nom);
 2669:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
 2670:         return;
 2671:     }
 2672: 
 2673:     free(nom);
 2674: 
 2675: #   endif
 2676: 
 2677:     return;
 2678: }
 2679: 
 2680: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>