File:  [local] / rpl / src / gestion_threads.c
Revision 1.13: download - view: text, annotated - select for diffs - revision graph
Wed Apr 28 09:38:27 2010 UTC (14 years ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Exécution de la procédure stockée dans ATEXIT même lorsque le processus
a été interrompu par STOP.

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

CVSweb interface <joel.bertrand@systella.fr>