File:  [local] / rpl / src / gestion_threads.c
Revision 1.76: download - view: text, annotated - select for diffs - revision graph
Tue Mar 26 09:04:32 2013 UTC (11 years, 1 month ago) by bertrand
Branches: MAIN
CVS tags: HEAD
La procédure ATEXIT est exécutée même si le programme est arrêté par
SIGINT.

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

CVSweb interface <joel.bertrand@systella.fr>