File:  [local] / rpl / src / gestion_threads.c
Revision 1.75: download - view: text, annotated - select for diffs - revision graph
Sun Mar 24 22:06:10 2013 UTC (11 years, 1 month ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Correction d'un certain nombre de bugs touchant à l'initialisation des threads
par SPAWN (possibilité de récupérer un segfault ou une erreur système de type
d_es_processus). Correction de petits problèmes sur les variables partagées.
Attention, la fonction VARS peut encore bloquer.

    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).var_volatile_alarme == 0)
  192:                         && ((*s_etat_processus).arret_depuis_abort == 0)
  193:                         && ((*s_etat_processus).at_exit != NULL))
  194:                 {
  195:                     (*s_etat_processus).var_volatile_requete_arret = 0;
  196:                     (*s_etat_processus).var_volatile_traitement_retarde_stop =
  197:                             -1;
  198: 
  199:                     if (evaluation(s_etat_processus,
  200:                             (*s_etat_processus).at_exit, 'E') == d_erreur)
  201:                     {
  202:                         if (((*s_etat_processus).erreur_execution == d_ex) &&
  203:                                 ((*s_etat_processus).erreur_systeme == d_es))
  204:                         {
  205:                             (*s_etat_processus).erreur_execution =
  206:                                     d_ex_erreur_evaluation;
  207:                         }
  208:                     }
  209:                 }
  210:             }
  211:         }
  212: 
  213:         if ((*s_argument_thread).destruction_objet == d_vrai)
  214:         {
  215:             liberation(s_etat_processus, (*s_argument_thread).argument);
  216:         }
  217:     }
  218: 
  219:     if ((*s_etat_processus).presence_fusible == d_vrai)
  220:     {
  221:         pthread_cancel((*s_etat_processus).thread_fusible);
  222:     }
  223: 
  224:     tid_final = (pthread_t) -2;
  225: 
  226:     while((longueur_ecriture = write_atomic(s_etat_processus,
  227:             (*s_argument_thread).pipe_nombre_interruptions_attente[1],
  228:             &tid_final, sizeof(tid_final))) != sizeof(tid_final))
  229:     {
  230:         if (longueur_ecriture == -1)
  231:         {
  232:             break;
  233:         }
  234:     }
  235: 
  236:     while((longueur_ecriture = write_atomic(s_etat_processus,
  237:             (*s_argument_thread).pipe_nombre_objets_attente[1],
  238:             &tid_final, sizeof(tid_final))) != sizeof(tid_final))
  239:     {
  240:         if (longueur_ecriture == -1)
  241:         {
  242:             break;
  243:         }
  244:     }
  245: 
  246:     if ((*s_etat_processus).var_volatile_processus_pere != 0)
  247:     {
  248:         // Racine des processus atteinte
  249: 
  250:         erreur = d_ex;
  251: 
  252:         while((longueur_ecriture = write_atomic(s_etat_processus,
  253:                 (*s_argument_thread).pipe_erreurs[1], &erreur,
  254:                 sizeof((*s_etat_processus).erreur_execution))) !=
  255:                 sizeof((*s_etat_processus).erreur_execution))
  256:         {
  257:             if (longueur_ecriture == -1)
  258:             {
  259:                 break;
  260:             }
  261:         }
  262:     }
  263:     else
  264:     {
  265:         while((longueur_ecriture = write_atomic(s_etat_processus,
  266:                 (*s_argument_thread).pipe_erreurs[1],
  267:                 &((*s_etat_processus).erreur_execution),
  268:                 sizeof((*s_etat_processus).erreur_execution))) !=
  269:                 sizeof((*s_etat_processus).erreur_execution))
  270:         {
  271:             if (longueur_ecriture == -1)
  272:             {
  273:                 break;
  274:             }
  275:         }
  276:     }
  277: 
  278:     if ((*s_etat_processus).var_volatile_processus_pere != 0)
  279:     {
  280:         // Racine des processus atteinte
  281: 
  282:         erreur = d_es;
  283: 
  284:         while((longueur_ecriture = write_atomic(s_etat_processus,
  285:                 (*s_argument_thread).pipe_erreurs[1], &erreur,
  286:                 sizeof((*s_etat_processus).erreur_systeme))) !=
  287:                 sizeof((*s_etat_processus).erreur_systeme))
  288:         {
  289:             if (longueur_ecriture == -1)
  290:             {
  291:                 break;
  292:             }
  293:         }
  294:     }
  295:     else
  296:     {
  297:         while((longueur_ecriture = write_atomic(s_etat_processus,
  298:                 (*s_argument_thread).pipe_erreurs[1],
  299:                 &((*s_etat_processus).erreur_systeme),
  300:                 sizeof((*s_etat_processus).erreur_systeme))) !=
  301:                 sizeof((*s_etat_processus).erreur_systeme))
  302:         {
  303:             if (longueur_ecriture == -1)
  304:             {
  305:                 break;
  306:             }
  307:         }
  308:     }
  309: 
  310:     if ((*s_etat_processus).pid_erreur_processus_fils == 0)
  311:     {
  312:         ppid = getpid();
  313: 
  314:         while((longueur_ecriture = write_atomic(s_etat_processus,
  315:                 (*s_argument_thread).pipe_erreurs[1],
  316:                 &ppid, sizeof(ppid))) != sizeof(ppid))
  317:         {
  318:             if (longueur_ecriture == -1)
  319:             {
  320:                 break;
  321:             }
  322:         }
  323:     }
  324:     else
  325:     {
  326:         while((longueur_ecriture = write_atomic(s_etat_processus,
  327:                 (*s_argument_thread).pipe_erreurs[1],
  328:                 &((*s_etat_processus).pid_erreur_processus_fils),
  329:                 sizeof((*s_etat_processus).pid_erreur_processus_fils))) !=
  330:                 sizeof((*s_etat_processus).pid_erreur_processus_fils))
  331:         {
  332:             if (longueur_ecriture == -1)
  333:             {
  334:                 break;
  335:             }
  336:         }
  337:     }
  338: 
  339:     close((*s_argument_thread).pipe_erreurs[1]);
  340:     close((*s_argument_thread).pipe_interruptions[1]);
  341:     close((*s_argument_thread).pipe_nombre_interruptions_attente[1]);
  342:     close((*s_argument_thread).pipe_objets[1]);
  343:     close((*s_argument_thread).pipe_nombre_objets_attente[1]);
  344:     close((*s_argument_thread).pipe_injections[0]);
  345:     close((*s_argument_thread).pipe_nombre_injections[0]);
  346:     close((*s_argument_thread).pipe_acquittement[0]);
  347: 
  348:     l_element_courant = (*s_etat_processus).s_fichiers;
  349: 
  350:     while(l_element_courant != NULL)
  351:     {
  352:         l_element_suivant = (*l_element_courant).suivant;
  353: 
  354:         if ((*((struct_descripteur_fichier *) (*l_element_courant)
  355:                 .donnee)).pid == getpid())
  356:         {
  357:             fclose((*((struct_descripteur_fichier *)
  358:                     (*l_element_courant).donnee)).descripteur_c);
  359: 
  360:             if ((*((struct_descripteur_fichier *)
  361:                     (*l_element_courant).donnee)).type != 'C')
  362:             {
  363:                 sqlite3_close((*((struct_descripteur_fichier *)
  364:                         (*l_element_courant).donnee)).descripteur_sqlite);
  365:             }
  366: 
  367:             if ((*((struct_descripteur_fichier *) (*l_element_courant)
  368:                     .donnee)).effacement == 'Y')
  369:             {
  370:                 unlink((*((struct_descripteur_fichier *)
  371:                         (*l_element_courant).donnee)).nom);
  372:             }
  373:         }
  374: 
  375:         free((*((struct_descripteur_fichier *) (*l_element_courant)
  376:                 .donnee)).nom);
  377:         free((struct_descripteur_fichier *) (*l_element_courant).donnee);
  378:         free(l_element_courant);
  379: 
  380:         l_element_courant = l_element_suivant;
  381:     }
  382: 
  383:     pthread_mutex_lock(&((*s_etat_processus).mutex));
  384: 
  385:     l_element_courant = (struct_liste_chainee *)
  386:             (*s_etat_processus).l_base_pile_processus;
  387: 
  388:     while(l_element_courant != NULL)
  389:     {
  390:         if ((*(*((struct_processus_fils *) (*(*l_element_courant).donnee)
  391:                 .objet)).thread).processus_detache == d_vrai)
  392:         {
  393:             if ((*s_etat_processus).debug == d_vrai)
  394:             {
  395:                 if (((*s_etat_processus).type_debug & d_debug_processus) != 0)
  396:                 {
  397:                     if ((*s_etat_processus).langue == 'F')
  398:                     {
  399:                         printf("[%d] Signalement pour arrêt du processus %d\n",
  400:                                 (int) getpid(),
  401:                                 (int) (*(*((struct_processus_fils *)
  402:                                 (*(*l_element_courant).donnee).objet)).thread)
  403:                                 .pid);
  404:                     }
  405:                     else
  406:                     {
  407:                         printf("[%d] Send stop signal to process %d\n",
  408:                                 (int) getpid(),
  409:                                 (int) (*(*((struct_processus_fils *)
  410:                                 (*(*l_element_courant).donnee).objet)).thread)
  411:                                 .pid);
  412:                     }
  413:                 }
  414:             }
  415: 
  416:             if ((*s_etat_processus).var_volatile_alarme != 0)
  417:             {
  418:                 envoi_signal_processus((*(*((struct_processus_fils *)
  419:                         (*(*l_element_courant)
  420:                         .donnee).objet)).thread).pid, rpl_sigurg);
  421:             }
  422:             else
  423:             {
  424:                 if ((*s_etat_processus).arret_depuis_abort == -1)
  425:                 {
  426:                     envoi_signal_processus((*(*((struct_processus_fils *)
  427:                             (*(*l_element_courant)
  428:                             .donnee).objet)).thread).pid, rpl_sigabort);
  429:                 }
  430:                 else
  431:                 {
  432:                     envoi_signal_processus((*(*((struct_processus_fils *)
  433:                             (*(*l_element_courant)
  434:                             .donnee).objet)).thread).pid, rpl_sigstop);
  435:                 }
  436:             }
  437:         }
  438:         else
  439:         {
  440:             if ((*s_etat_processus).debug == d_vrai)
  441:             {
  442:                 if (((*s_etat_processus).type_debug & d_debug_processus) != 0)
  443:                 {
  444:                     if ((*s_etat_processus).langue == 'F')
  445:                     {
  446:                         printf("[%d] Signalement pour arrêt du thread %llu\n",
  447:                                 (int) getpid(), (unsigned long long)
  448:                                 (*(*((struct_processus_fils *)
  449:                                 (*(*l_element_courant).donnee).objet)).thread)
  450:                                 .tid);
  451:                     }
  452:                     else
  453:                     {
  454:                         printf("[%d] Send stop signal to thread %llu\n",
  455:                                 (int) getpid(), (unsigned long long)
  456:                                 (*(*((struct_processus_fils *)
  457:                                 (*(*l_element_courant).donnee).objet)).thread)
  458:                                 .tid);
  459:                     }
  460:                 }
  461:             }
  462: 
  463:             if ((*s_etat_processus).var_volatile_alarme != 0)
  464:             {
  465:                 if (pthread_mutex_lock(&((*(*((struct_processus_fils *)
  466:                         (*(*l_element_courant).donnee).objet)).thread).mutex))
  467:                         != 0)
  468:                 {
  469:                     pthread_mutex_unlock(&((*s_etat_processus).mutex));
  470:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  471: 
  472:                     pthread_mutex_lock(&((*s_argument_thread).mutex));
  473:                     pthread_mutex_unlock(&((*s_argument_thread).mutex));
  474: 
  475:                     (*s_argument_thread).thread_actif = d_faux;
  476: 
  477:                     pthread_exit(NULL);
  478:                 }
  479: 
  480:                 if ((*(*((struct_processus_fils *)
  481:                         (*(*l_element_courant).donnee).objet)).thread)
  482:                         .thread_actif == d_vrai)
  483:                 {
  484:                     envoi_signal_thread((*(*((struct_processus_fils *)
  485:                             (*(*l_element_courant).donnee).objet)).thread).tid,
  486:                             rpl_sigurg);
  487:                 }
  488: 
  489:                 if (pthread_mutex_unlock(&((*(*((struct_processus_fils *)
  490:                         (*(*l_element_courant).donnee).objet)).thread)
  491:                         .mutex)) != 0)
  492:                 {
  493:                     pthread_mutex_unlock(&((*s_etat_processus).mutex));
  494:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  495: 
  496:                     pthread_mutex_lock(&((*s_argument_thread).mutex));
  497:                     pthread_mutex_unlock(&((*s_argument_thread).mutex));
  498: 
  499:                     (*s_argument_thread).thread_actif = d_faux;
  500: 
  501:                     pthread_exit(NULL);
  502:                 }
  503:             }
  504:             else
  505:             {
  506:                 if (pthread_mutex_lock(&((*(*((struct_processus_fils *)
  507:                         (*(*l_element_courant).donnee).objet)).thread).mutex))
  508:                         != 0)
  509:                 {
  510:                     pthread_mutex_unlock(&((*s_etat_processus).mutex));
  511:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  512: 
  513:                     pthread_mutex_lock(&((*s_argument_thread).mutex));
  514:                     pthread_mutex_unlock(&((*s_argument_thread).mutex));
  515: 
  516:                     (*s_argument_thread).thread_actif = d_faux;
  517: 
  518:                     pthread_exit(NULL);
  519:                 }
  520: 
  521:                 if ((*(*((struct_processus_fils *)
  522:                         (*(*l_element_courant).donnee).objet)).thread)
  523:                         .thread_actif == d_vrai)
  524:                 {
  525:                     if ((*s_etat_processus).arret_depuis_abort == -1)
  526:                     {
  527:                         envoi_signal_thread((*(*((struct_processus_fils *)
  528:                                 (*(*l_element_courant).donnee).objet)).thread)
  529:                                 .tid, rpl_sigabort);
  530:                     }
  531:                     else
  532:                     {
  533:                         envoi_signal_thread((*(*((struct_processus_fils *)
  534:                                 (*(*l_element_courant).donnee).objet)).thread)
  535:                                 .tid, rpl_sigstop);
  536:                     }
  537:                 }
  538: 
  539:                 if (pthread_mutex_unlock(&((*(*((struct_processus_fils *)
  540:                         (*(*l_element_courant).donnee).objet)).thread).mutex))
  541:                         != 0)
  542:                 {
  543:                     pthread_mutex_unlock(&((*s_etat_processus).mutex));
  544:                     (*s_etat_processus).erreur_systeme = d_es_processus;
  545: 
  546:                     pthread_mutex_lock(&((*s_argument_thread).mutex));
  547:                     pthread_mutex_unlock(&((*s_argument_thread).mutex));
  548: 
  549:                     (*s_argument_thread).thread_actif = d_faux;
  550: 
  551:                     pthread_exit(NULL);
  552:                 }
  553:             }
  554:         }
  555: 
  556:         l_element_courant = (*l_element_courant).suivant;
  557:     }
  558: 
  559:     /*
  560:      * Attente de la fin de tous les processus fils
  561:      */
  562: 
  563:     for(i = 0; i < d_NOMBRE_INTERRUPTIONS;
  564:             (*s_etat_processus).masque_interruptions[i++] = 'I');
  565: 
  566:     attente.tv_sec = 0;
  567:     attente.tv_nsec = GRANULARITE_us * 1000;
  568: 
  569:     while((*s_etat_processus).l_base_pile_processus != NULL)
  570:     {
  571:         status = 0;
  572: 
  573:         l_element_courant = (struct_liste_chainee *)
  574:                 (*s_etat_processus).l_base_pile_processus;
  575: 
  576:         registre_stop = (*s_etat_processus)
  577:                 .var_volatile_traitement_retarde_stop;
  578:         (*s_etat_processus).var_volatile_traitement_retarde_stop = 1;
  579: 
  580:         for(i = 0; i < (*(*((struct_processus_fils *)
  581:                 (*(*l_element_courant).donnee).objet)).thread)
  582:                 .nombre_objets_dans_pipe; i++)
  583:         {
  584:             if ((s_objet_temporaire = lecture_pipe(s_etat_processus,
  585:                     (*(*((struct_processus_fils *) (*(*l_element_courant)
  586:                     .donnee).objet)).thread).pipe_objets[0])) != NULL)
  587:             {
  588:                 liberation(s_etat_processus, s_objet_temporaire);
  589: 
  590:                 (*(*((struct_processus_fils *) (*(*l_element_courant)
  591:                         .donnee).objet)).thread).nombre_objets_dans_pipe--;
  592: 
  593:                 action.sa_handler = SIG_IGN;
  594:                 action.sa_flags = SA_ONSTACK;
  595: 
  596:                 if (sigaction(SIGPIPE, &action, &registre) != 0)
  597:                 {
  598:                     pthread_mutex_unlock(&((*s_etat_processus).mutex));
  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).mutex));
  650: 
  651:                     (*s_etat_processus).erreur_systeme = d_es_signal;
  652:                     exit(EXIT_FAILURE);
  653:                 }
  654:             }
  655:         }
  656: 
  657:         if ((*(*((struct_processus_fils *) (*(*l_element_courant)
  658:                 .donnee).objet)).thread).processus_detache == d_vrai)
  659:         {
  660:             if (waitpid((*(*((struct_processus_fils *)
  661:                     (*(*l_element_courant).donnee).objet)).thread).pid,
  662:                     &status, WNOHANG) < 0)
  663:             {
  664:             }
  665:         }
  666: 
  667:         pthread_mutex_unlock(&((*s_etat_processus).mutex));
  668: 
  669:         if ((*s_etat_processus).nombre_interruptions_non_affectees != 0)
  670:         {
  671:             affectation_interruptions_logicielles(s_etat_processus);
  672:         }
  673: 
  674:         nanosleep(&attente, NULL);
  675:         pthread_mutex_lock(&((*s_etat_processus).mutex));
  676:     }
  677: 
  678:     pthread_mutex_unlock(&((*s_etat_processus).mutex));
  679: 
  680:     l_element_courant = (*s_etat_processus).s_sockets;
  681: 
  682:     while(l_element_courant != NULL)
  683:     {
  684:         l_element_suivant = (*l_element_courant).suivant;
  685: 
  686:         /*
  687:          * Fermeture des sockets créées dans le processus courant.
  688:          */
  689: 
  690:         if (((*((struct_socket *) (*(*l_element_courant).donnee).objet))
  691:                 .pid == getpid()) && (pthread_equal((*((struct_socket *)
  692:                 (*(*l_element_courant).donnee).objet)).tid, pthread_self())
  693:                 != 0))
  694:         {
  695:             if ((*((struct_socket *) (*(*l_element_courant).donnee).objet))
  696:                     .socket_connectee == d_vrai)
  697:             {
  698:                 shutdown((*((struct_socket *) (*(*l_element_courant).donnee)
  699:                         .objet)).socket, SHUT_RDWR);
  700:             }
  701: 
  702:             close((*((struct_socket *) (*(*l_element_courant).donnee).objet))
  703:                     .socket);
  704: 
  705:             if ((*((struct_socket *) (*(*l_element_courant).donnee).objet))
  706:                     .effacement == 'Y')
  707:             {
  708:                 unlink((*((struct_socket *) (*(*l_element_courant).donnee)
  709:                         .objet)).adresse);
  710:             }
  711:         }
  712: 
  713:         liberation(s_etat_processus, (*((struct_liste_chainee *)
  714:                 l_element_courant)).donnee);
  715:         free(l_element_courant);
  716: 
  717:         l_element_courant = l_element_suivant;
  718:     }
  719: 
  720:     l_element_courant = (*s_etat_processus).s_connecteurs_sql;
  721: 
  722:     while(l_element_courant != NULL)
  723:     {
  724:         l_element_suivant = (*l_element_courant).suivant;
  725: 
  726:         /*
  727:          * Fermeture des connecteurs créés dans le processus courant.
  728:          */
  729: 
  730:         if (((*((struct_socket *) (*(*l_element_courant).donnee).objet))
  731:                 .pid == getpid()) && (pthread_equal((*((struct_socket *)
  732:                 (*(*l_element_courant).donnee).objet)).tid, pthread_self())
  733:                 != 0))
  734:         {
  735:             sqlclose((*l_element_courant).donnee);
  736:         }
  737: 
  738:         liberation(s_etat_processus, (*((struct_liste_chainee *)
  739:                 l_element_courant)).donnee);
  740:         free(l_element_courant);
  741: 
  742:         l_element_courant = l_element_suivant;
  743:     }
  744: 
  745:     if ((((*s_etat_processus).erreur_execution != d_ex) ||
  746:             ((*s_etat_processus).exception != d_ep) ||
  747:             ((*s_etat_processus).erreur_systeme != d_es)) &&
  748:             ((*s_etat_processus).var_volatile_traitement_sigint == 0))
  749:     {
  750:         printf("%s [%d]\n", message =
  751:                 messages(s_etat_processus), (int) getpid());
  752:         free(message);
  753: 
  754:         if ((*s_etat_processus).core == d_vrai)
  755:         {
  756:             printf("\n");
  757: 
  758:             if ((*s_etat_processus).langue == 'F')
  759:             {
  760:                  printf("+++Information : Génération du fichier rpl-core "
  761:                         "[%d]\n", (int) getpid());
  762:             }
  763:             else
  764:             {
  765:                 printf("+++Information : Writing rpl-core file [%d]\n",
  766:                         (int) getpid());
  767:             }
  768: 
  769:             rplcore(s_etat_processus);
  770: 
  771:             if ((*s_etat_processus).langue == 'F')
  772:             {
  773:                 printf("+++Information : Processus tracé [%d]\n",
  774:                         (int) getpid());
  775:             }
  776:             else
  777:             {
  778:                 printf("+++Information : Done [%d]\n", (int) getpid());
  779:             }
  780: 
  781:             printf("\n");
  782:             fflush(stdout);
  783:         }
  784:     }
  785: 
  786:     if ((*s_etat_processus).entree_standard != NULL)
  787:     {
  788:         pclose((*s_etat_processus).entree_standard);
  789:         (*s_etat_processus).entree_standard = NULL;
  790:     }
  791: 
  792:     if ((*s_etat_processus).fichiers_graphiques != NULL)
  793:     {
  794:         instruction_cllcd(s_etat_processus);
  795:     }
  796: 
  797:     liberation(s_etat_processus, (*s_etat_processus).indep);
  798:     liberation(s_etat_processus, (*s_etat_processus).depend);
  799: 
  800:     free((*s_etat_processus).label_x);
  801:     free((*s_etat_processus).label_y);
  802:     free((*s_etat_processus).label_z);
  803:     free((*s_etat_processus).titre);
  804:     free((*s_etat_processus).legende);
  805: 
  806:     liberation(s_etat_processus,
  807:             (*s_etat_processus).parametres_courbes_de_niveau);
  808: 
  809:     if ((*s_etat_processus).instruction_derniere_erreur != NULL)
  810:     {
  811:         free((*s_etat_processus).instruction_derniere_erreur);
  812:         (*s_etat_processus).instruction_derniere_erreur = NULL;
  813:     }
  814: 
  815:     liberation_arbre_variables(s_etat_processus,
  816:             (*s_etat_processus).s_arbre_variables, d_faux);
  817: 
  818:     l_element_statique_courant = (*s_etat_processus)
  819:             .l_liste_variables_statiques;
  820: 
  821:     while(l_element_statique_courant != NULL)
  822:     {
  823:         l_element_statique_suivant = (*l_element_statique_courant).suivant;
  824:         free(l_element_statique_courant);
  825:         l_element_statique_courant = l_element_statique_suivant;
  826:     }
  827: 
  828:     l_element_courant = (*s_etat_processus).l_base_pile;
  829:     while(l_element_courant != NULL)
  830:     {
  831:         l_element_suivant = (*l_element_courant).suivant;
  832: 
  833:         liberation(s_etat_processus, (*l_element_courant).donnee);
  834:         free(l_element_courant);
  835: 
  836:         l_element_courant = l_element_suivant;
  837:     }
  838: 
  839:     l_element_courant = (*s_etat_processus).l_base_pile_last;
  840:     while(l_element_courant != NULL)
  841:     {
  842:         l_element_suivant = (*l_element_courant).suivant;
  843: 
  844:         liberation(s_etat_processus, (*l_element_courant).donnee);
  845:         free(l_element_courant);
  846: 
  847:         l_element_courant = l_element_suivant;
  848:     }
  849: 
  850:     l_element_courant = (*s_etat_processus).l_base_pile_contextes;
  851:     while(l_element_courant != NULL)
  852:     {
  853:         l_element_suivant = (*l_element_courant).suivant;
  854: 
  855:         liberation(s_etat_processus, (*l_element_courant).donnee);
  856:         free(l_element_courant);
  857: 
  858:         l_element_courant = l_element_suivant;
  859:     }
  860: 
  861:     l_element_courant = (*s_etat_processus).l_base_pile_taille_contextes;
  862:     while(l_element_courant != NULL)
  863:     {
  864:         l_element_suivant = (*l_element_courant).suivant;
  865: 
  866:         liberation(s_etat_processus, (*l_element_courant).donnee);
  867:         free(l_element_courant);
  868: 
  869:         l_element_courant = l_element_suivant;
  870:     }
  871: 
  872:     l_element_courant = (struct_liste_chainee *)
  873:             (*s_etat_processus).l_base_pile_systeme;
  874:     while(l_element_courant != NULL)
  875:     {
  876:         l_element_suivant = (struct_liste_chainee *)
  877:                 (*((struct_liste_pile_systeme *)
  878:                 l_element_courant)).suivant;
  879: 
  880:         liberation(s_etat_processus, (*((struct_liste_pile_systeme *)
  881:                 l_element_courant)).indice_boucle);
  882:         liberation(s_etat_processus, (*((struct_liste_pile_systeme *)
  883:                 l_element_courant)).limite_indice_boucle);
  884:         liberation(s_etat_processus, (*((struct_liste_pile_systeme *)
  885:                 l_element_courant)).objet_de_test);
  886: 
  887:         if ((*((struct_liste_pile_systeme *)
  888:                 l_element_courant)).nom_variable != NULL)
  889:         {
  890:             free((*((struct_liste_pile_systeme *)
  891:                     l_element_courant)).nom_variable);
  892:         }
  893: 
  894:         free((struct_liste_pile_systeme *) l_element_courant);
  895: 
  896:         l_element_courant = l_element_suivant;
  897:     }
  898: 
  899:     l_element_courant = (*s_etat_processus).s_bibliotheques;
  900: 
  901:     while(l_element_courant != NULL)
  902:     {
  903:         l_element_suivant = (*l_element_courant).suivant;
  904: 
  905:         free((*((struct_bibliotheque *) (*l_element_courant).donnee)).nom);
  906: 
  907:         if (((*((struct_bibliotheque *) (*l_element_courant).donnee)).pid
  908:                 == getpid()) && (pthread_equal((*((struct_bibliotheque *)
  909:                 (*l_element_courant).donnee)).tid, pthread_self()) != 0))
  910:         {
  911:             dlclose((*((struct_bibliotheque *) (*l_element_courant).donnee))
  912:                     .descripteur);
  913:         }
  914: 
  915:         free((*l_element_courant).donnee);
  916:         free(l_element_courant);
  917: 
  918:         l_element_courant = l_element_suivant;
  919:     }
  920: 
  921:     for(i = 0; i < (*s_etat_processus).nombre_instructions_externes; i++)
  922:     {
  923:         free((*s_etat_processus).s_instructions_externes[i].nom);
  924:         free((*s_etat_processus).s_instructions_externes[i]
  925:                 .nom_bibliotheque);
  926:     }
  927: 
  928:     if ((*s_etat_processus).nombre_instructions_externes != 0)
  929:     {
  930:         free((*s_etat_processus).s_instructions_externes);
  931:     }
  932: 
  933:     if ((*s_etat_processus).debug == d_vrai)
  934:         if (((*s_etat_processus).type_debug & d_debug_processus) != 0)
  935:     {
  936:         if ((*s_etat_processus).langue == 'F')
  937:         {
  938:             printf("[%d] Fin du thread %llu\n", (int) getpid(),
  939:                     (unsigned long long) pthread_self());
  940:         }
  941:         else
  942:         {
  943:             printf("[%d] End of thread %llu\n", (int) getpid(),
  944:                     (unsigned long long) pthread_self());
  945:         }
  946: 
  947:         fflush(stdout);
  948:     }
  949: 
  950:     liberation(s_etat_processus, (*s_argument_thread).argument);
  951:     liberation(s_etat_processus, (*s_etat_processus).at_exit);
  952:     liberation(s_etat_processus, (*s_etat_processus).at_poke);
  953: 
  954:     for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++)
  955:     {
  956:         liberation(s_etat_processus,
  957:                 (*s_etat_processus).corps_interruptions[i]);
  958: 
  959:         l_element_courant = (*s_etat_processus)
  960:                 .pile_origine_interruptions[i];
  961: 
  962:         while(l_element_courant != NULL)
  963:         {
  964:             l_element_suivant = (*l_element_courant).suivant;
  965: 
  966:             liberation(s_etat_processus, (*l_element_courant).donnee);
  967:             free(l_element_courant);
  968: 
  969:             l_element_courant = l_element_suivant;
  970:         }
  971:     }
  972: 
  973:     l_element_courant = (struct_liste_chainee *) (*s_etat_processus).s_marques;
  974: 
  975:     while(l_element_courant != NULL)
  976:     {
  977:         free((*((struct_marque *) l_element_courant)).label);
  978:         free((*((struct_marque *) l_element_courant)).position);
  979:         l_element_suivant = (struct_liste_chainee *)
  980:                 (*((struct_marque *) l_element_courant)).suivant;
  981:         free((struct_marque *) l_element_courant);
  982:         l_element_courant = l_element_suivant;
  983:     }
  984: 
  985:     if ((*s_etat_processus).generateur_aleatoire != NULL)
  986:     {
  987:         liberation_generateur_aleatoire(s_etat_processus);
  988:     }
  989: 
  990:     if ((*s_etat_processus).profilage == d_vrai)
  991:     {
  992:         ecriture_profil(s_etat_processus);
  993:         liberation_profil(s_etat_processus);
  994:     }
  995: 
  996:     liberation_allocateur(s_etat_processus);
  997: 
  998:     retrait_thread(s_etat_processus);
  999:     pthread_mutex_destroy(&((*s_etat_processus).mutex));
 1000:     pthread_mutex_destroy(&((*s_etat_processus).mutex_allocation));
 1001: 
 1002: #   ifndef SEMAPHORES_NOMMES
 1003:         sem_destroy(&((*s_etat_processus).semaphore_fork));
 1004: #   else
 1005:         sem_destroy3((*s_etat_processus).semaphore_fork, getpid(),
 1006:                 pthread_self(), SEM_FORK);
 1007: #   endif
 1008: 
 1009:     liberation_contexte_cas(s_etat_processus);
 1010:     free((*s_etat_processus).localisation);
 1011:     free(s_etat_processus);
 1012: 
 1013:     pthread_mutex_lock(&((*s_argument_thread).mutex));
 1014:     pthread_mutex_unlock(&((*s_argument_thread).mutex));
 1015: 
 1016:     (*s_argument_thread).thread_actif = d_faux;
 1017:     pthread_exit(NULL);
 1018:     return(NULL);
 1019: }
 1020: 
 1021: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>