File:  [local] / rpl / src / gestion_threads.c
Revision 1.111: download - view: text, annotated - select for diffs - revision graph
Thu Feb 7 21:44:14 2019 UTC (5 years, 2 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Tentative de correction d'un bug de sémaphore sous NetBSD.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.31
    4:   Copyright (C) 1989-2019 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:   Fonction de lancement d'un thread
   29: ================================================================================
   30:   Entrées : pointeur sur une structure
   31: --------------------------------------------------------------------------------
   32:   Sorties :
   33: --------------------------------------------------------------------------------
   34:   Effets de bord : néant
   35: ================================================================================
   36: */
   37: 
   38: void *
   39: lancement_thread(void *argument)
   40: {
   41:     int                                 status;
   42: 
   43:     pid_t                               ppid;
   44: 
   45:     sig_atomic_t                        registre_stop;
   46: 
   47:     ssize_t                             longueur_ecriture;
   48: 
   49:     struct_descripteur_thread           *s_argument_thread;
   50: 
   51:     struct_liste_chainee                *l_element_courant;
   52:     struct_liste_chainee                *l_element_suivant;
   53: 
   54:     struct_liste_variables_statiques    *l_element_statique_courant;
   55:     struct_liste_variables_statiques    *l_element_statique_suivant;
   56: 
   57:     struct_objet                        *s_objet_temporaire;
   58: 
   59:     struct_processus                    *s_etat_processus;
   60: 
   61:     struct sigaction                    action;
   62:     struct sigaction                    registre;
   63: 
   64:     struct timespec                     attente;
   65: 
   66:     unsigned char                       caractere;
   67:     unsigned char                       *message;
   68: 
   69:     unsigned int                        erreur;
   70: 
   71:     integer8                            i;
   72: 
   73:     attente.tv_sec = 0;
   74:     attente.tv_nsec = GRANULARITE_us * 1000;
   75: 
   76:     s_argument_thread = (struct_descripteur_thread *) argument;
   77:     s_etat_processus = (*s_argument_thread).s_nouvel_etat_processus;
   78: 
   79: #   ifndef SEMAPHORES_NOMMES
   80:         sem_init(&((*s_etat_processus).semaphore_fork), 0, 0);
   81: uprintf("[%d-%llu] Semaphore fork %p (gestion_threads.c)\n", (int) getpid(),
   82:         (unsigned long long) pthread_self(),
   83:         &((*s_etat_processus).semaphore_fork));
   84: #   else
   85:         if (((*s_etat_processus).semaphore_fork = sem_init3(0, getpid(),
   86:                 pthread_self(), SEM_FORK)) == SEM_FAILED)
   87:         {
   88:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
   89:             return(NULL);
   90:         }
   91: #   endif
   92: 
   93:     (*s_argument_thread).tid = pthread_self();
   94:     insertion_thread(s_etat_processus, d_faux);
   95: 
   96:     if (pthread_mutex_lock(&((*s_argument_thread).mutex)) != 0)
   97:     {
   98:         (*s_etat_processus).erreur_systeme = d_es_processus;
   99:         return(NULL);
  100:     }
  101: 
  102:     (*s_argument_thread).thread_actif = d_vrai;
  103: 
  104:     if (pthread_mutex_unlock(&((*s_argument_thread).mutex)) != 0)
  105:     {
  106:         (*s_etat_processus).erreur_systeme = d_es_processus;
  107:         return(NULL);
  108:     }
  109: 
  110:     // Envoi d'une donnée pour signaler le démarrage du thread au thread
  111:     // de surveillance.
  112: 
  113:     caractere = 0;
  114: 
  115:     if (write_atomic(s_etat_processus,
  116:             (*s_argument_thread).pipe_nombre_elements_attente[1],
  117:             &caractere, sizeof(caractere)) != sizeof(caractere))
  118:     {
  119:         (*s_etat_processus).erreur_systeme = d_es_processus;
  120: 
  121:         pthread_mutex_lock(&((*s_argument_thread).mutex));
  122:         pthread_mutex_unlock(&((*s_argument_thread).mutex));
  123: 
  124:         (*s_argument_thread).thread_actif = d_faux;
  125: 
  126:         while((longueur_ecriture = write_atomic(s_etat_processus,
  127:                 (*s_argument_thread).pipe_nombre_elements_attente[1],
  128:                 &caractere, sizeof(caractere))) != sizeof(caractere))
  129:         {
  130:             if (longueur_ecriture == -1)
  131:             {
  132:                 break;
  133:             }
  134:         }
  135: 
  136:         pthread_exit(NULL);
  137:     }
  138: 
  139:     if ((*s_etat_processus).evaluation_expression_compilee == 'N')
  140:     {
  141:         free((*s_etat_processus).instruction_courante);
  142:         (*s_etat_processus).instruction_courante = NULL;
  143:     }
  144: 
  145:     // Attente de la réception du signal rpl_sigstart.
  146: 
  147:     for((*s_etat_processus).demarrage_fils = d_faux;;)
  148:     {
  149:         scrutation_interruptions(s_etat_processus);
  150: 
  151:         if ((*s_etat_processus).demarrage_fils == d_vrai)
  152:         {
  153:             break;
  154:         }
  155: 
  156:         nanosleep(&attente, NULL);
  157:     }
  158: 
  159:     if ((*s_etat_processus).debug == d_vrai)
  160:         if (((*s_etat_processus).type_debug & d_debug_processus) != 0)
  161:     {
  162:         if ((*s_etat_processus).langue == 'F')
  163:         {
  164:             printf("[%d] Lancement du thread %llu\n", (int) getpid(),
  165:                     (unsigned long long) pthread_self());
  166:         }
  167:         else
  168:         {
  169:             printf("[%d] Start thread %llu\n", (int) getpid(),
  170:                     (unsigned long long) pthread_self());
  171:         }
  172: 
  173:         fflush(stdout);
  174:     }
  175: 
  176:     (*s_etat_processus).pid_erreur_processus_fils = getpid();
  177: 
  178:     // Évaluation de l'objet
  179: 
  180:     if ((*s_etat_processus).erreur_systeme == d_es)
  181:     {
  182:         if (setjmp(contexte_thread) == 0)
  183:         {
  184:             if (evaluation(s_etat_processus, (*s_argument_thread).argument, 'E')
  185:                     == d_erreur)
  186:             {
  187:                 if (((*s_etat_processus).erreur_execution == d_ex) &&
  188:                         ((*s_etat_processus).erreur_systeme == d_es))
  189:                 {
  190:                     (*s_etat_processus).erreur_execution =
  191:                             d_ex_erreur_evaluation;
  192:                 }
  193:             }
  194:             else
  195:             {
  196:                 if (((*s_etat_processus).arret_depuis_abort == 0)
  197:                         && ((*s_etat_processus).at_exit != NULL))
  198:                 {
  199:                     (*s_etat_processus).var_volatile_requete_arret = 0;
  200:                     (*s_etat_processus).var_volatile_alarme = 0;
  201:                     (*s_etat_processus).var_volatile_traitement_sigint = 0;
  202: 
  203:                     if ((*s_etat_processus).profilage == d_vrai)
  204:                     {
  205:                         profilage(s_etat_processus, "ATEXIT");
  206:                     }
  207: 
  208:                     if (evaluation(s_etat_processus,
  209:                             (*s_etat_processus).at_exit, 'E') == d_erreur)
  210:                     {
  211:                         if (((*s_etat_processus).erreur_execution == d_ex) &&
  212:                                 ((*s_etat_processus).erreur_systeme == d_es))
  213:                         {
  214:                             (*s_etat_processus).erreur_execution =
  215:                                     d_ex_erreur_evaluation;
  216:                         }
  217:                     }
  218: 
  219:                     if ((*s_etat_processus).profilage == d_vrai)
  220:                     {
  221:                         profilage(s_etat_processus, NULL);
  222:                     }
  223:                 }
  224:             }
  225:         }
  226: 
  227:         if ((*s_argument_thread).destruction_objet == d_vrai)
  228:         {
  229:             liberation(s_etat_processus, (*s_argument_thread).argument);
  230:         }
  231:     }
  232: 
  233:     if ((*s_etat_processus).presence_fusible == d_vrai)
  234:     {
  235:         pthread_cancel((*s_etat_processus).thread_fusible);
  236:     }
  237: 
  238:     caractere = 0;
  239: 
  240:     while((longueur_ecriture = write_atomic(s_etat_processus,
  241:             (*s_argument_thread).pipe_nombre_elements_attente[1],
  242:             &caractere, sizeof(caractere))) != sizeof(caractere))
  243:     {
  244:         if (longueur_ecriture == -1)
  245:         {
  246:             break;
  247:         }
  248:     }
  249: 
  250:     if ((*s_etat_processus).var_volatile_processus_pere != 0)
  251:     {
  252:         // Racine des processus atteinte
  253: 
  254:         erreur = d_ex;
  255: 
  256:         while((longueur_ecriture = write_atomic(s_etat_processus,
  257:                 (*s_argument_thread).pipe_erreurs[1], &erreur,
  258:                 sizeof((*s_etat_processus).erreur_execution))) !=
  259:                 sizeof((*s_etat_processus).erreur_execution))
  260:         {
  261:             if (longueur_ecriture == -1)
  262:             {
  263:                 break;
  264:             }
  265:         }
  266:     }
  267:     else
  268:     {
  269:         while((longueur_ecriture = write_atomic(s_etat_processus,
  270:                 (*s_argument_thread).pipe_erreurs[1],
  271:                 (int *) &((*s_etat_processus).erreur_execution),
  272:                 sizeof((*s_etat_processus).erreur_execution))) !=
  273:                 sizeof((*s_etat_processus).erreur_execution))
  274:         {
  275:             if (longueur_ecriture == -1)
  276:             {
  277:                 break;
  278:             }
  279:         }
  280:     }
  281: 
  282:     if ((*s_etat_processus).var_volatile_processus_pere != 0)
  283:     {
  284:         // Racine des processus atteinte
  285: 
  286:         erreur = d_es;
  287: 
  288:         while((longueur_ecriture = write_atomic(s_etat_processus,
  289:                 (*s_argument_thread).pipe_erreurs[1], &erreur,
  290:                 sizeof((*s_etat_processus).erreur_systeme))) !=
  291:                 sizeof((*s_etat_processus).erreur_systeme))
  292:         {
  293:             if (longueur_ecriture == -1)
  294:             {
  295:                 break;
  296:             }
  297:         }
  298:     }
  299:     else
  300:     {
  301:         while((longueur_ecriture = write_atomic(s_etat_processus,
  302:                 (*s_argument_thread).pipe_erreurs[1],
  303:                 (int *) &((*s_etat_processus).erreur_systeme),
  304:                 sizeof((*s_etat_processus).erreur_systeme))) !=
  305:                 sizeof((*s_etat_processus).erreur_systeme))
  306:         {
  307:             if (longueur_ecriture == -1)
  308:             {
  309:                 break;
  310:             }
  311:         }
  312:     }
  313: 
  314:     if ((*s_etat_processus).pid_erreur_processus_fils == 0)
  315:     {
  316:         ppid = getpid();
  317: 
  318:         while((longueur_ecriture = write_atomic(s_etat_processus,
  319:                 (*s_argument_thread).pipe_erreurs[1],
  320:                 &ppid, sizeof(ppid))) != sizeof(ppid))
  321:         {
  322:             if (longueur_ecriture == -1)
  323:             {
  324:                 break;
  325:             }
  326:         }
  327:     }
  328:     else
  329:     {
  330:         while((longueur_ecriture = write_atomic(s_etat_processus,
  331:                 (*s_argument_thread).pipe_erreurs[1],
  332:                 &((*s_etat_processus).pid_erreur_processus_fils),
  333:                 sizeof((*s_etat_processus).pid_erreur_processus_fils))) !=
  334:                 sizeof((*s_etat_processus).pid_erreur_processus_fils))
  335:         {
  336:             if (longueur_ecriture == -1)
  337:             {
  338:                 break;
  339:             }
  340:         }
  341:     }
  342: 
  343:     l_element_courant = (*s_etat_processus).s_fichiers;
  344: 
  345:     while(l_element_courant != NULL)
  346:     {
  347:         l_element_suivant = (*l_element_courant).suivant;
  348: 
  349:         if ((*((struct_descripteur_fichier *) (*l_element_courant)
  350:                 .donnee)).pid == getpid())
  351:         {
  352:             fclose((*((struct_descripteur_fichier *)
  353:                     (*l_element_courant).donnee)).descripteur_c);
  354: 
  355:             if ((*((struct_descripteur_fichier *)
  356:                     (*l_element_courant).donnee)).type != 'C')
  357:             {
  358:                 sqlite3_close((*((struct_descripteur_fichier *)
  359:                         (*l_element_courant).donnee)).descripteur_sqlite);
  360:             }
  361: 
  362:             if ((*((struct_descripteur_fichier *) (*l_element_courant)
  363:                     .donnee)).effacement == 'Y')
  364:             {
  365:                 unlink((*((struct_descripteur_fichier *)
  366:                         (*l_element_courant).donnee)).nom);
  367:             }
  368:         }
  369: 
  370:         free((*((struct_descripteur_fichier *) (*l_element_courant)
  371:                 .donnee)).nom);
  372:         free((struct_descripteur_fichier *) (*l_element_courant).donnee);
  373:         free(l_element_courant);
  374: 
  375:         l_element_courant = l_element_suivant;
  376:     }
  377: 
  378:     pthread_mutex_lock(&((*s_etat_processus).mutex_pile_processus));
  379: 
  380:     l_element_courant = (struct_liste_chainee *)
  381:             (*s_etat_processus).l_base_pile_processus;
  382: 
  383:     while(l_element_courant != NULL)
  384:     {
  385:         if ((*(*((struct_processus_fils *) (*(*l_element_courant).donnee)
  386:                 .objet)).thread).processus_detache == d_vrai)
  387:         {
  388:             if ((*s_etat_processus).debug == d_vrai)
  389:             {
  390:                 if (((*s_etat_processus).type_debug & d_debug_processus) != 0)
  391:                 {
  392:                     if ((*s_etat_processus).langue == 'F')
  393:                     {
  394:                         printf("[%d] Signalement pour arrêt du processus %d\n",
  395:                                 (int) getpid(),
  396:                                 (int) (*(*((struct_processus_fils *)
  397:                                 (*(*l_element_courant).donnee).objet)).thread)
  398:                                 .pid);
  399:                     }
  400:                     else
  401:                     {
  402:                         printf("[%d] Send stop signal to process %d\n",
  403:                                 (int) getpid(),
  404:                                 (int) (*(*((struct_processus_fils *)
  405:                                 (*(*l_element_courant).donnee).objet)).thread)
  406:                                 .pid);
  407:                     }
  408:                 }
  409:             }
  410: 
  411:             if ((*s_etat_processus).var_volatile_alarme != 0)
  412:             {
  413:                 envoi_signal_processus((*(*((struct_processus_fils *)
  414:                         (*(*l_element_courant)
  415:                         .donnee).objet)).thread).pid, rpl_sigurg, d_faux);
  416:             }
  417:             else
  418:             {
  419:                 if ((*s_etat_processus).arret_depuis_abort == -1)
  420:                 {
  421:                     envoi_signal_processus((*(*((struct_processus_fils *)
  422:                             (*(*l_element_courant)
  423:                             .donnee).objet)).thread).pid, rpl_sigabort, d_faux);
  424:                 }
  425:                 else
  426:                 {
  427:                     envoi_signal_processus((*(*((struct_processus_fils *)
  428:                             (*(*l_element_courant)
  429:                             .donnee).objet)).thread).pid, rpl_sigstop,d_faux);
  430:                 }
  431:             }
  432:         }
  433:         else
  434:         {
  435:             if ((*s_etat_processus).debug == d_vrai)
  436:             {
  437:                 if (((*s_etat_processus).type_debug & d_debug_processus) != 0)
  438:                 {
  439:                     if ((*s_etat_processus).langue == 'F')
  440:                     {
  441:                         printf("[%d] Signalement pour arrêt du thread %llu\n",
  442:                                 (int) getpid(), (unsigned long long)
  443:                                 (*(*((struct_processus_fils *)
  444:                                 (*(*l_element_courant).donnee).objet)).thread)
  445:                                 .tid);
  446:                     }
  447:                     else
  448:                     {
  449:                         printf("[%d] Send stop signal to thread %llu\n",
  450:                                 (int) getpid(), (unsigned long long)
  451:                                 (*(*((struct_processus_fils *)
  452:                                 (*(*l_element_courant).donnee).objet)).thread)
  453:                                 .tid);
  454:                     }
  455:                 }
  456:             }
  457: 
  458:             if ((*s_etat_processus).var_volatile_alarme != 0)
  459:             {
  460:                 if (pthread_mutex_lock(&((*(*((struct_processus_fils *)
  461:                         (*(*l_element_courant).donnee).objet)).thread).mutex))
  462:                         != 0)
  463:                 {
  464:                     pthread_mutex_unlock(&((*s_etat_processus)
  465:                             .mutex_pile_processus));
  466:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  467: 
  468:                     pthread_mutex_lock(&((*s_argument_thread).mutex));
  469:                     pthread_mutex_unlock(&((*s_argument_thread).mutex));
  470: 
  471:                     (*s_argument_thread).thread_actif = d_faux;
  472: 
  473:                     pthread_exit(NULL);
  474:                 }
  475: 
  476:                 if ((*(*((struct_processus_fils *)
  477:                         (*(*l_element_courant).donnee).objet)).thread)
  478:                         .thread_actif == d_vrai)
  479:                 {
  480:                     envoi_signal_thread((*(*((struct_processus_fils *)
  481:                             (*(*l_element_courant).donnee).objet)).thread).tid,
  482:                             rpl_sigurg);
  483:                 }
  484: 
  485:                 if (pthread_mutex_unlock(&((*(*((struct_processus_fils *)
  486:                         (*(*l_element_courant).donnee).objet)).thread)
  487:                         .mutex)) != 0)
  488:                 {
  489:                     pthread_mutex_unlock(&((*s_etat_processus)
  490:                             .mutex_pile_processus));
  491:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  492: 
  493:                     pthread_mutex_lock(&((*s_argument_thread).mutex));
  494:                     pthread_mutex_unlock(&((*s_argument_thread).mutex));
  495: 
  496:                     (*s_argument_thread).thread_actif = d_faux;
  497: 
  498:                     pthread_exit(NULL);
  499:                 }
  500:             }
  501:             else
  502:             {
  503:                 if (pthread_mutex_lock(&((*(*((struct_processus_fils *)
  504:                         (*(*l_element_courant).donnee).objet)).thread).mutex))
  505:                         != 0)
  506:                 {
  507:                     pthread_mutex_unlock(&((*s_etat_processus)
  508:                             .mutex_pile_processus));
  509:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  510: 
  511:                     pthread_mutex_lock(&((*s_argument_thread).mutex));
  512:                     pthread_mutex_unlock(&((*s_argument_thread).mutex));
  513: 
  514:                     (*s_argument_thread).thread_actif = d_faux;
  515: 
  516:                     pthread_exit(NULL);
  517:                 }
  518: 
  519:                 if ((*(*((struct_processus_fils *)
  520:                         (*(*l_element_courant).donnee).objet)).thread)
  521:                         .thread_actif == d_vrai)
  522:                 {
  523:                     if ((*s_etat_processus).arret_depuis_abort == -1)
  524:                     {
  525:                         envoi_signal_thread((*(*((struct_processus_fils *)
  526:                                 (*(*l_element_courant).donnee).objet)).thread)
  527:                                 .tid, rpl_sigabort);
  528:                     }
  529:                     else
  530:                     {
  531:                         envoi_signal_thread((*(*((struct_processus_fils *)
  532:                                 (*(*l_element_courant).donnee).objet)).thread)
  533:                                 .tid, rpl_sigstop);
  534:                     }
  535:                 }
  536: 
  537:                 if (pthread_mutex_unlock(&((*(*((struct_processus_fils *)
  538:                         (*(*l_element_courant).donnee).objet)).thread).mutex))
  539:                         != 0)
  540:                 {
  541:                     pthread_mutex_unlock(&((*s_etat_processus)
  542:                             .mutex_pile_processus));
  543:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  544: 
  545:                     pthread_mutex_lock(&((*s_argument_thread).mutex));
  546:                     pthread_mutex_unlock(&((*s_argument_thread).mutex));
  547: 
  548:                     (*s_argument_thread).thread_actif = d_faux;
  549: 
  550:                     pthread_exit(NULL);
  551:                 }
  552:             }
  553:         }
  554: 
  555:         l_element_courant = (*l_element_courant).suivant;
  556:     }
  557: 
  558:     /*
  559:      * Attente de la fin de tous les processus fils
  560:      */
  561: 
  562:     for(i = 0; i < d_NOMBRE_INTERRUPTIONS;
  563:             (*s_etat_processus).masque_interruptions[i++] = 'I');
  564: 
  565:     attente.tv_sec = 0;
  566:     attente.tv_nsec = GRANULARITE_us * 1000;
  567: 
  568:     while((*s_etat_processus).l_base_pile_processus != NULL)
  569:     {
  570:         status = 0;
  571: 
  572:         l_element_courant = (struct_liste_chainee *)
  573:                 (*s_etat_processus).l_base_pile_processus;
  574: 
  575:         registre_stop = (*s_etat_processus)
  576:                 .var_volatile_traitement_retarde_stop;
  577:         (*s_etat_processus).var_volatile_traitement_retarde_stop = 1;
  578: 
  579:         for(i = 0; i < (*(*((struct_processus_fils *)
  580:                 (*(*l_element_courant).donnee).objet)).thread)
  581:                 .nombre_objets_dans_pipe; i++)
  582:         {
  583:             if ((s_objet_temporaire = lecture_pipe(s_etat_processus,
  584:                     (*(*((struct_processus_fils *) (*(*l_element_courant)
  585:                     .donnee).objet)).thread).pipe_objets[0])) != NULL)
  586:             {
  587:                 liberation(s_etat_processus, s_objet_temporaire);
  588: 
  589:                 (*(*((struct_processus_fils *) (*(*l_element_courant)
  590:                         .donnee).objet)).thread).nombre_objets_dans_pipe--;
  591: 
  592:                 action.sa_handler = SIG_IGN;
  593:                 action.sa_flags = SA_ONSTACK;
  594: 
  595:                 if (sigaction(SIGPIPE, &action, &registre) != 0)
  596:                 {
  597:                     pthread_mutex_unlock(&((*s_etat_processus)
  598:                             .mutex_pile_processus));
  599: 
  600:                     if (registre_stop == 0)
  601:                     {
  602:                         if ((*s_etat_processus)
  603:                                 .var_volatile_traitement_retarde_stop
  604:                                 == -1)
  605:                         {
  606:                             (*s_etat_processus)
  607:                                     .var_volatile_requete_arret = -1;
  608:                         }
  609: 
  610:                         (*s_etat_processus)
  611:                                 .var_volatile_traitement_retarde_stop =
  612:                                 registre_stop;
  613:                     }
  614: 
  615:                     (*s_etat_processus).erreur_systeme = d_es_signal;
  616:                     exit(EXIT_FAILURE);
  617:                 }
  618: 
  619:                 while((longueur_ecriture = write_atomic(
  620:                         s_etat_processus, (*(*((struct_processus_fils *)
  621:                         (*(*l_element_courant).donnee).objet)).thread)
  622:                         .pipe_nombre_injections[1], "+",
  623:                         sizeof(unsigned char))) !=
  624:                         sizeof(unsigned char))
  625:                 {
  626:                     if (longueur_ecriture == -1)
  627:                     {
  628:                         // Le processus n'existe plus.
  629:                         break;
  630:                     }
  631:                 }
  632: 
  633:                 if (registre_stop == 0)
  634:                 {
  635:                     if ((*s_etat_processus)
  636:                             .var_volatile_traitement_retarde_stop == -1)
  637:                     {
  638:                         (*s_etat_processus).var_volatile_requete_arret
  639:                                 = -1;
  640:                     }
  641: 
  642:                     (*s_etat_processus)
  643:                             .var_volatile_traitement_retarde_stop =
  644:                             registre_stop;
  645:                 }
  646: 
  647:                 if (sigaction(SIGPIPE, &registre, NULL) != 0)
  648:                 {
  649:                     pthread_mutex_unlock(&((*s_etat_processus)
  650:                             .mutex_pile_processus));
  651: 
  652:                     (*s_etat_processus).erreur_systeme = d_es_signal;
  653:                     exit(EXIT_FAILURE);
  654:                 }
  655:             }
  656:         }
  657: 
  658:         if ((*(*((struct_processus_fils *) (*(*l_element_courant)
  659:                 .donnee).objet)).thread).processus_detache == d_vrai)
  660:         {
  661:             if (waitpid((*(*((struct_processus_fils *)
  662:                     (*(*l_element_courant).donnee).objet)).thread).pid,
  663:                     &status, WNOHANG) < 0)
  664:             {
  665:             }
  666:         }
  667: 
  668:         if (pthread_mutex_lock(&((*s_etat_processus).mutex_interruptions)) != 0)
  669:         {
  670:             pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus));
  671: 
  672:             (*s_etat_processus).erreur_systeme = d_es_processus;
  673:             exit(EXIT_FAILURE);
  674:         }
  675: 
  676:         if ((*s_etat_processus).nombre_interruptions_non_affectees != 0)
  677:         {
  678:             affectation_interruptions_logicielles(s_etat_processus);
  679:         }
  680: 
  681:         if (pthread_mutex_unlock(&((*s_etat_processus).mutex_interruptions))
  682:                 != 0)
  683:         {
  684:             pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus));
  685: 
  686:             (*s_etat_processus).erreur_systeme = d_es_processus;
  687:             exit(EXIT_FAILURE);
  688:         }
  689: 
  690:         pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus));
  691:         nanosleep(&attente, NULL);
  692:         pthread_mutex_lock(&((*s_etat_processus).mutex_pile_processus));
  693:     }
  694: 
  695:     pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus));
  696: 
  697:     l_element_courant = (*s_etat_processus).s_sockets;
  698: 
  699:     while(l_element_courant != NULL)
  700:     {
  701:         l_element_suivant = (*l_element_courant).suivant;
  702: 
  703:         /*
  704:          * Fermeture des sockets créées dans le processus courant.
  705:          */
  706: 
  707:         if (((*((struct_socket *) (*(*l_element_courant).donnee).objet))
  708:                 .pid == getpid()) && (pthread_equal((*((struct_socket *)
  709:                 (*(*l_element_courant).donnee).objet)).tid, pthread_self())
  710:                 != 0))
  711:         {
  712:             if ((*((struct_socket *) (*(*l_element_courant).donnee).objet))
  713:                     .socket_connectee == d_vrai)
  714:             {
  715:                 shutdown((*((struct_socket *) (*(*l_element_courant).donnee)
  716:                         .objet)).socket, SHUT_RDWR);
  717:             }
  718: 
  719:             close((*((struct_socket *) (*(*l_element_courant).donnee).objet))
  720:                     .socket);
  721: 
  722:             if ((*((struct_socket *) (*(*l_element_courant).donnee).objet))
  723:                     .effacement == 'Y')
  724:             {
  725:                 unlink((*((struct_socket *) (*(*l_element_courant).donnee)
  726:                         .objet)).adresse);
  727:             }
  728:         }
  729: 
  730:         liberation(s_etat_processus, (*((struct_liste_chainee *)
  731:                 l_element_courant)).donnee);
  732:         free(l_element_courant);
  733: 
  734:         l_element_courant = l_element_suivant;
  735:     }
  736: 
  737:     l_element_courant = (*s_etat_processus).s_connecteurs_sql;
  738: 
  739:     while(l_element_courant != NULL)
  740:     {
  741:         l_element_suivant = (*l_element_courant).suivant;
  742: 
  743:         /*
  744:          * Fermeture des connecteurs créés dans le processus courant.
  745:          */
  746: 
  747:         if (((*((struct_socket *) (*(*l_element_courant).donnee).objet))
  748:                 .pid == getpid()) && (pthread_equal((*((struct_socket *)
  749:                 (*(*l_element_courant).donnee).objet)).tid, pthread_self())
  750:                 != 0))
  751:         {
  752:             sqlclose((*l_element_courant).donnee);
  753:         }
  754: 
  755:         liberation(s_etat_processus, (*((struct_liste_chainee *)
  756:                 l_element_courant)).donnee);
  757:         free(l_element_courant);
  758: 
  759:         l_element_courant = l_element_suivant;
  760:     }
  761: 
  762:     if ((((*s_etat_processus).erreur_execution != d_ex) ||
  763:             ((*s_etat_processus).exception != d_ep) ||
  764:             ((*s_etat_processus).erreur_systeme != d_es)) &&
  765:             ((*s_etat_processus).var_volatile_traitement_sigint == 0))
  766:     {
  767:         printf("%s [%d]\n", message =
  768:                 messages(s_etat_processus), (int) getpid());
  769:         free(message);
  770: 
  771:         if ((*s_etat_processus).core == d_vrai)
  772:         {
  773:             printf("\n");
  774: 
  775:             if ((*s_etat_processus).langue == 'F')
  776:             {
  777:                  printf("+++Information : Génération du fichier rpl-core "
  778:                         "[%d]\n", (int) getpid());
  779:             }
  780:             else
  781:             {
  782:                 printf("+++Information : Writing rpl-core file [%d]\n",
  783:                         (int) getpid());
  784:             }
  785: 
  786:             rplcore(s_etat_processus);
  787: 
  788:             if ((*s_etat_processus).langue == 'F')
  789:             {
  790:                 printf("+++Information : Processus tracé [%d]\n",
  791:                         (int) getpid());
  792:             }
  793:             else
  794:             {
  795:                 printf("+++Information : Done [%d]\n", (int) getpid());
  796:             }
  797: 
  798:             printf("\n");
  799:             fflush(stdout);
  800:         }
  801:     }
  802: 
  803:     if ((*s_etat_processus).entree_standard != NULL)
  804:     {
  805:         pclose((*s_etat_processus).entree_standard);
  806:         (*s_etat_processus).entree_standard = NULL;
  807:     }
  808: 
  809:     if ((*s_etat_processus).fichiers_graphiques != NULL)
  810:     {
  811:         instruction_cllcd(s_etat_processus);
  812:     }
  813: 
  814:     liberation(s_etat_processus, (*s_etat_processus).indep);
  815:     liberation(s_etat_processus, (*s_etat_processus).depend);
  816: 
  817:     free((*s_etat_processus).label_x);
  818:     free((*s_etat_processus).label_y);
  819:     free((*s_etat_processus).label_z);
  820:     free((*s_etat_processus).titre);
  821:     free((*s_etat_processus).legende);
  822: 
  823:     liberation(s_etat_processus,
  824:             (*s_etat_processus).parametres_courbes_de_niveau);
  825: 
  826:     if ((*s_etat_processus).instruction_derniere_erreur != NULL)
  827:     {
  828:         free((*s_etat_processus).instruction_derniere_erreur);
  829:         (*s_etat_processus).instruction_derniere_erreur = NULL;
  830:     }
  831: 
  832:     liberation_arbre_variables(s_etat_processus,
  833:             (*s_etat_processus).s_arbre_variables, d_faux);
  834: 
  835:     l_element_statique_courant = (*s_etat_processus)
  836:             .l_liste_variables_statiques;
  837: 
  838:     while(l_element_statique_courant != NULL)
  839:     {
  840:         l_element_statique_suivant = (*l_element_statique_courant).suivant;
  841:         free(l_element_statique_courant);
  842:         l_element_statique_courant = l_element_statique_suivant;
  843:     }
  844: 
  845:     l_element_courant = (*s_etat_processus).l_base_pile;
  846:     while(l_element_courant != NULL)
  847:     {
  848:         l_element_suivant = (*l_element_courant).suivant;
  849: 
  850:         liberation(s_etat_processus, (*l_element_courant).donnee);
  851:         free(l_element_courant);
  852: 
  853:         l_element_courant = l_element_suivant;
  854:     }
  855: 
  856:     l_element_courant = (*s_etat_processus).l_base_pile_last;
  857:     while(l_element_courant != NULL)
  858:     {
  859:         l_element_suivant = (*l_element_courant).suivant;
  860: 
  861:         liberation(s_etat_processus, (*l_element_courant).donnee);
  862:         free(l_element_courant);
  863: 
  864:         l_element_courant = l_element_suivant;
  865:     }
  866: 
  867:     l_element_courant = (*s_etat_processus).l_base_pile_contextes;
  868:     while(l_element_courant != NULL)
  869:     {
  870:         l_element_suivant = (*l_element_courant).suivant;
  871: 
  872:         liberation(s_etat_processus, (*l_element_courant).donnee);
  873:         free(l_element_courant);
  874: 
  875:         l_element_courant = l_element_suivant;
  876:     }
  877: 
  878:     l_element_courant = (*s_etat_processus).l_base_pile_taille_contextes;
  879:     while(l_element_courant != NULL)
  880:     {
  881:         l_element_suivant = (*l_element_courant).suivant;
  882: 
  883:         liberation(s_etat_processus, (*l_element_courant).donnee);
  884:         free(l_element_courant);
  885: 
  886:         l_element_courant = l_element_suivant;
  887:     }
  888: 
  889:     l_element_courant = (struct_liste_chainee *)
  890:             (*s_etat_processus).l_base_pile_systeme;
  891:     while(l_element_courant != NULL)
  892:     {
  893:         l_element_suivant = (struct_liste_chainee *)
  894:                 (*((struct_liste_pile_systeme *)
  895:                 l_element_courant)).suivant;
  896: 
  897:         liberation(s_etat_processus, (*((struct_liste_pile_systeme *)
  898:                 l_element_courant)).indice_boucle);
  899:         liberation(s_etat_processus, (*((struct_liste_pile_systeme *)
  900:                 l_element_courant)).limite_indice_boucle);
  901:         liberation(s_etat_processus, (*((struct_liste_pile_systeme *)
  902:                 l_element_courant)).objet_de_test);
  903: 
  904:         if ((*((struct_liste_pile_systeme *)
  905:                 l_element_courant)).nom_variable != NULL)
  906:         {
  907:             free((*((struct_liste_pile_systeme *)
  908:                     l_element_courant)).nom_variable);
  909:         }
  910: 
  911:         free((struct_liste_pile_systeme *) l_element_courant);
  912: 
  913:         l_element_courant = l_element_suivant;
  914:     }
  915: 
  916:     l_element_courant = (*s_etat_processus).s_bibliotheques;
  917: 
  918:     while(l_element_courant != NULL)
  919:     {
  920:         l_element_suivant = (*l_element_courant).suivant;
  921: 
  922:         free((*((struct_bibliotheque *) (*l_element_courant).donnee)).nom);
  923: 
  924:         if (((*((struct_bibliotheque *) (*l_element_courant).donnee)).pid
  925:                 == getpid()) && (pthread_equal((*((struct_bibliotheque *)
  926:                 (*l_element_courant).donnee)).tid, pthread_self()) != 0))
  927:         {
  928:             dlclose((*((struct_bibliotheque *) (*l_element_courant).donnee))
  929:                     .descripteur);
  930:         }
  931: 
  932:         free((*l_element_courant).donnee);
  933:         free(l_element_courant);
  934: 
  935:         l_element_courant = l_element_suivant;
  936:     }
  937: 
  938:     for(i = 0; i < (*s_etat_processus).nombre_instructions_externes; i++)
  939:     {
  940:         free((*s_etat_processus).s_instructions_externes[i].nom);
  941:         free((*s_etat_processus).s_instructions_externes[i]
  942:                 .nom_bibliotheque);
  943:     }
  944: 
  945:     if ((*s_etat_processus).nombre_instructions_externes != 0)
  946:     {
  947:         free((*s_etat_processus).s_instructions_externes);
  948:     }
  949: 
  950:     if ((*s_etat_processus).debug == d_vrai)
  951:         if (((*s_etat_processus).type_debug & d_debug_processus) != 0)
  952:     {
  953:         if ((*s_etat_processus).langue == 'F')
  954:         {
  955:             printf("[%d] Fin du thread %llu\n", (int) getpid(),
  956:                     (unsigned long long) pthread_self());
  957:         }
  958:         else
  959:         {
  960:             printf("[%d] End of thread %llu\n", (int) getpid(),
  961:                     (unsigned long long) pthread_self());
  962:         }
  963: 
  964:         fflush(stdout);
  965:     }
  966: 
  967:     liberation(s_etat_processus, (*s_argument_thread).argument);
  968:     liberation(s_etat_processus, (*s_etat_processus).at_exit);
  969:     liberation(s_etat_processus, (*s_etat_processus).at_poke);
  970: 
  971:     for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++)
  972:     {
  973:         liberation(s_etat_processus,
  974:                 (*s_etat_processus).corps_interruptions[i]);
  975: 
  976:         l_element_courant = (*s_etat_processus)
  977:                 .pile_origine_interruptions[i];
  978: 
  979:         while(l_element_courant != NULL)
  980:         {
  981:             l_element_suivant = (*l_element_courant).suivant;
  982: 
  983:             liberation(s_etat_processus, (*l_element_courant).donnee);
  984:             free(l_element_courant);
  985: 
  986:             l_element_courant = l_element_suivant;
  987:         }
  988:     }
  989: 
  990:     l_element_courant = (struct_liste_chainee *) (*s_etat_processus).s_marques;
  991: 
  992:     while(l_element_courant != NULL)
  993:     {
  994:         free((*((struct_marque *) l_element_courant)).label);
  995:         free((*((struct_marque *) l_element_courant)).position);
  996:         l_element_suivant = (struct_liste_chainee *)
  997:                 (*((struct_marque *) l_element_courant)).suivant;
  998:         free((struct_marque *) l_element_courant);
  999:         l_element_courant = l_element_suivant;
 1000:     }
 1001: 
 1002:     if ((*s_etat_processus).generateur_aleatoire != NULL)
 1003:     {
 1004:         liberation_generateur_aleatoire(s_etat_processus);
 1005:     }
 1006: 
 1007:     if ((*s_etat_processus).profilage == d_vrai)
 1008:     {
 1009:         ecriture_profil(s_etat_processus);
 1010:         liberation_profil(s_etat_processus);
 1011:     }
 1012: 
 1013:     retrait_thread(s_etat_processus);
 1014:     pthread_mutex_destroy(&((*s_etat_processus).mutex_pile_processus));
 1015:     pthread_mutex_destroy(&((*s_etat_processus).mutex_allocation));
 1016:     pthread_mutex_destroy(&((*s_etat_processus).mutex_interruptions));
 1017:     pthread_mutex_destroy(&((*s_etat_processus).mutex_signaux));
 1018: 
 1019: #   ifndef SEMAPHORES_NOMMES
 1020:         sem_post(&((*s_etat_processus).semaphore_fork));
 1021:         sem_destroy(&((*s_etat_processus).semaphore_fork));
 1022: #   else
 1023:         sem_post((*s_etat_processus).semaphore_fork);
 1024:         sem_destroy3((*s_etat_processus).semaphore_fork, getpid(),
 1025:                 pthread_self(), SEM_FORK);
 1026: #   endif
 1027: 
 1028:     close((*s_argument_thread).pipe_erreurs[1]);
 1029:     close((*s_argument_thread).pipe_interruptions[1]);
 1030:     close((*s_argument_thread).pipe_nombre_elements_attente[1]);
 1031:     close((*s_argument_thread).pipe_objets[1]);
 1032:     close((*s_argument_thread).pipe_injections[0]);
 1033:     close((*s_argument_thread).pipe_nombre_injections[0]);
 1034:     close((*s_argument_thread).pipe_acquittement[0]);
 1035: 
 1036:     liberation_contexte_cas(s_etat_processus);
 1037:     free((*s_etat_processus).localisation);
 1038:     liberation_allocateur(s_etat_processus);
 1039:     liberation_allocateur_buffer(s_etat_processus);
 1040:     pthread_mutex_destroy(&((*s_etat_processus).mutex_allocation_buffer));
 1041:     sys_free(s_etat_processus);
 1042: 
 1043:     pthread_mutex_lock(&((*s_argument_thread).mutex));
 1044:     (*s_argument_thread).thread_actif = d_faux;
 1045:     pthread_mutex_unlock(&((*s_argument_thread).mutex));
 1046: 
 1047:     pthread_exit(NULL);
 1048:     return(NULL);
 1049: }
 1050: 
 1051: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>