File:  [local] / rpl / src / Attic / siginfo.c
Revision 1.4: download - view: text, annotated - select for diffs - revision graph
Thu Sep 2 07:51:48 2010 UTC (13 years, 9 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Correction du mécanisme de gestion des interruptions logicielles et
correction des cas où siginfo_t peut être nul.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.0.19
    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: #define __BROKEN_SIGINFO_ROUTINES__
   24: #include "rpl-conv.h"
   25: 
   26: #ifdef _BROKEN_SIGINFO
   27: 
   28: #define longueur_queue  256
   29: #define nombre_queues   13
   30: 
   31: static int              *fifos;
   32: static int              markov;
   33: static int              segment;
   34: static sem_t            *semaphores[nombre_queues];
   35: static sem_t            *semaphore_global;
   36: 
   37: #ifdef IPCS_SYSV
   38: static unsigned char    *chemin = NULL;
   39: #endif
   40: 
   41: static unsigned char *
   42: nom_segment(unsigned char *chemin, pid_t pid)
   43: {
   44:     unsigned char               *fichier;
   45: 
   46: #   ifdef IPCS_SYSV
   47:     if ((fichier = malloc((strlen(chemin) + 1 + 256 + 1) *
   48:             sizeof(unsigned char))) == NULL)
   49:     {
   50:         return(NULL);
   51:     }
   52: 
   53:     sprintf(fichier, "%s/RPL-SIGQUEUES-%d", chemin, (int) pid);
   54: #   else
   55:     if ((fichier = malloc((1 + 256 + 1) *
   56:             sizeof(unsigned char))) == NULL)
   57:     {
   58:         return(NULL);
   59:     }
   60: 
   61:     sprintf(fichier, "/RPL-SIGQUEUES-%d", (int) pid);
   62: #   endif
   63: 
   64:     return(fichier);
   65: }
   66: 
   67: static unsigned char *
   68: nom_semaphore(pid_t pid, int queue)
   69: {
   70:     unsigned char               *fichier;
   71: 
   72:     if ((fichier = malloc((256 + 1) * sizeof(unsigned char))) == NULL)
   73:     {
   74:         return(NULL);
   75:     }
   76: 
   77:     sprintf(fichier, "/RPL-SIGESMAPHORES-%d-%d", (int) pid, queue);
   78: 
   79:     return(fichier);
   80: }
   81: 
   82: static inline int
   83: queue_de_signal(int signal)
   84: {
   85:     switch(signal)
   86:     {
   87:         case SIGINT:
   88:             return(0);
   89:         case SIGTSTP:
   90:             return(1);
   91:         case SIGCONT:
   92:             return(2);
   93:         case SIGURG:
   94:             return(3);
   95:         case SIGPIPE:
   96:             return(4);
   97:         case SIGALRM:
   98:             return(5);
   99:         case SIGFSTOP:
  100:             return(6);
  101:         case SIGSTART:
  102:             return(7);
  103:         case SIGINJECT:
  104:             return(8);
  105:         case SIGABORT:
  106:             return(9);
  107:         case SIGFABORT:
  108:             return(10);
  109:         case SIGSEGV:
  110:             return(11);
  111:         case SIGBUS:
  112:             return(12);
  113:     }
  114: 
  115:     return(-1);
  116: }
  117: 
  118: void
  119: creation_fifos_signaux(struct_processus *s_etat_processus)
  120: {
  121:     /*
  122:      * Signaux utilisés
  123:      * SIGINT, SIGTSTP, SIGCONT, SIGURG, SIGPIPE, SIGALRM, SIGFSTOP,
  124:      * SIGSTART, SIGINJECT, SIGABORT, SIGFABORT
  125:      */
  126: 
  127:     int                             i;
  128: 
  129:     unsigned char                   *nom;
  130: 
  131: #   ifndef IPCS_SYSV // POSIX
  132: 
  133:     if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
  134:             getpid())) == NULL)
  135:     {
  136:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  137:         return;
  138:     }
  139: 
  140:     if ((segment = shm_open(nom, O_RDWR | O_CREAT | O_EXCL,
  141:             S_IRUSR | S_IWUSR)) == -1)
  142:     {
  143:         free(nom);
  144:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  145:         return;
  146:     }
  147: 
  148:     if (ftruncate(segment, nombre_queues * ((2 * longueur_queue) + 4) *
  149:             sizeof(int)) == -1)
  150:     {
  151:         free(nom);
  152:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  153:         return;
  154:     }
  155: 
  156:     fifos = mmap(NULL, nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
  157:             PROT_READ | PROT_WRITE, MAP_SHARED, segment, 0);
  158:     close(segment);
  159: 
  160:     if (((void *) fifos) == ((void *) -1))
  161:     {
  162:         if (shm_unlink(nom) == -1)
  163:         {
  164:             free(nom);
  165:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  166:             return;
  167:         }
  168: 
  169:         free(nom);
  170:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  171:         return;
  172:     }
  173: 
  174:     free(nom);
  175: 
  176: #   else // SystemV
  177: 
  178:     file                            *desc;
  179: 
  180:     key_t                           clef;
  181: 
  182:     // Création d'un segment de données associé au PID du processus courant
  183: 
  184:     chemin = (*s_etat_processus).chemin_fichiers_temporaires;
  185: 
  186:     if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
  187:             getpid())) == NULL)
  188:     {
  189:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  190:         return;
  191:     }
  192: 
  193:     if ((desc = fopen(nom, "w")) == NULL)
  194:     {
  195:         (*s_etat_processus).erreur_systeme = d_es_erreur_fichier;
  196:         return;
  197:     }
  198: 
  199:     fclose(desc);
  200: 
  201:     if ((clef = ftok(nom, 1)) == -1)
  202:     {
  203:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  204:         return;
  205:     }
  206: 
  207:     free(nom);
  208: 
  209:     if ((segment = shmget(clef,
  210:             nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
  211:             IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1)
  212:     {
  213:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  214:         return;
  215:     }
  216: 
  217:     fifos = shmat(segment, NULL, 0);
  218: 
  219:     if (((void *) fifos) == ((void *) -1))
  220:     {
  221:         if (shmctl(segment, IPC_RMID, 0) == -1)
  222:         {
  223:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  224:             return;
  225:         }
  226: 
  227:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  228:         return;
  229:     }
  230: 
  231: #   endif
  232: 
  233:     /*
  234:      * Structure d'une queue
  235:      * 0 : pointeur en lecture sur le premier emplacement libre (int)
  236:      * 1 : pointeur en écriture sur le premier emplacement à lire (int)
  237:      * 2 : longueur de la queue (int)
  238:      * 3 : éléments restants (int)
  239:      * 4 à 4 + (2) : queue (int)
  240:      * 4 + (2) + 1 ) 4 + 2 * (2) : horodatage en centième de secondes.
  241:      */
  242: 
  243:     for(i = 0; i < nombre_queues; i++)
  244:     {
  245:         fifos[(i * (longueur_queue + 4))] = 0;
  246:         fifos[(i * (longueur_queue + 4)) + 1] = 0;
  247:         fifos[(i * (longueur_queue + 4)) + 2] = longueur_queue;
  248:         fifos[(i * (longueur_queue + 4)) + 3] = longueur_queue;
  249:     }
  250: 
  251:     // Création des sémaphores : un sémaphore par signal et par queue
  252:     // plus un sémaphore global pour tous les threads.
  253: 
  254:     for(i = 0; i < nombre_queues; i++)
  255:     {
  256:         if ((nom = nom_semaphore(getpid(), i)) == NULL)
  257:         {
  258:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  259:             return;
  260:         }
  261: 
  262:         // Le sémaphore est créé en écrasant si nécessaire un sémaphore
  263:         // préexistant. Comme le nom du sémaphore contient l'identifiant du
  264:         // processus, il est anormal d'avoir un sémaphore de même nom
  265:         // préexistant.
  266: 
  267:         if ((semaphores[i] = sem_open(nom, O_CREAT, S_IRUSR | S_IWUSR,
  268:                 1)) == SEM_FAILED)
  269:         {
  270:             (*s_etat_processus).erreur_systeme = d_es_semaphore;
  271:             return;
  272:         }
  273: 
  274:         free(nom);
  275:     }
  276: 
  277: 
  278:     if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
  279:     {
  280:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  281:         return;
  282:     }
  283: 
  284:     if ((semaphore_global = sem_open(nom, O_CREAT, S_IRUSR | S_IWUSR,
  285:             1)) == SEM_FAILED)
  286:     {
  287:         (*s_etat_processus).erreur_systeme = d_es_semaphore;
  288:         return;
  289:     }
  290: 
  291:     free(nom);
  292: 
  293:     markov = 0;
  294: 
  295:     return;
  296: }
  297: 
  298: void
  299: liberation_fifos_signaux(struct_processus *s_etat_processus)
  300: {
  301:     int                 i;
  302: 
  303: #   ifdef IPCS_SYSV // SystemV
  304: 
  305:     if (shmdt(fifos) == -1)
  306:     {
  307:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  308:         return;
  309:     }
  310: 
  311: #   else // POSIX
  312: 
  313:     if (munmap(fifos, nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int))
  314:             != 0)
  315:     {
  316:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  317:         return;
  318:     }
  319: 
  320: #   endif
  321: 
  322:     for(i = 0; i < nombre_queues; i++)
  323:     {
  324:         if (sem_close(semaphores[i]) != 0)
  325:         {
  326:             (*s_etat_processus).erreur_systeme = d_es_semaphore;
  327:             return;
  328:         }
  329:     }
  330: 
  331:     if (sem_close(semaphore_global) != 0)
  332:     {
  333:         (*s_etat_processus).erreur_systeme = d_es_semaphore;
  334:         return;
  335:     }
  336: 
  337:     return;
  338: }
  339: 
  340: void
  341: destruction_fifos_signaux(struct_processus *s_etat_processus)
  342: {
  343:     int                 i;
  344: 
  345:     unsigned char       *nom;
  346: 
  347: #   ifdef IPCS_SYSV // SystemV
  348: 
  349:     if (shmdt(fifos) == -1)
  350:     {
  351:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  352:         return;
  353:     }
  354: 
  355:     if (shmctl(segment, IPC_RMID, 0) == -1)
  356:     {
  357:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  358:         return;
  359:     }
  360: 
  361:     if ((nom = nom_segment((*s_etat_processus).chemin_fichiers_temporaires,
  362:             getpid())) == NULL)
  363:     {
  364:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  365:         return;
  366:     }
  367: 
  368:     unlink(nom);
  369:     free(nom);
  370: 
  371: #   else // POSIX
  372: 
  373:     if (munmap(fifos, nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int))
  374:             != 0)
  375:     {
  376:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  377:         return;
  378:     }
  379: 
  380:     if ((nom = nom_segment(NULL, getpid())) == NULL)
  381:     {
  382:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  383:         return;
  384:     }
  385: 
  386:     if (shm_unlink(nom) != 0)
  387:     {
  388:         free(nom);
  389:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  390:         return;
  391:     }
  392: 
  393:     free(nom);
  394: 
  395: #   endif
  396: 
  397:     for(i = 0; i < nombre_queues; i++)
  398:     {
  399:         if ((nom = nom_semaphore(getpid(), i)) == NULL)
  400:         {
  401:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  402:             return;
  403:         }
  404: 
  405:         if (sem_unlink(nom) != 0)
  406:         {
  407:             (*s_etat_processus).erreur_systeme = d_es_semaphore;
  408:             return;
  409:         }
  410: 
  411:         free(nom);
  412:     }
  413: 
  414:     if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
  415:     {
  416:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  417:         return;
  418:     }
  419: 
  420:     if (sem_unlink(nom) != 0)
  421:     {
  422:         (*s_etat_processus).erreur_systeme = d_es_semaphore;
  423:         return;
  424:     }
  425: 
  426:     free(nom);
  427: 
  428:     return;
  429: }
  430: 
  431: static inline int
  432: horodatage()
  433: {
  434:     int             ts;
  435: 
  436:     struct timeval  tv;
  437: 
  438:     gettimeofday(&tv, NULL);
  439:     ts = (int) ((tv.tv_sec * 100) + (tv.tv_usec / 10000));
  440: 
  441:     return(ts);
  442: }
  443: 
  444: int
  445: queue_in(pid_t pid, int signal)
  446: {
  447:     int             queue;
  448:     int             *base;
  449:     int             *buffer;
  450:     int             horodatage_initial;
  451:     int             identifiant;
  452:     int             *projection_fifos;
  453: 
  454:     sem_t           *semaphore;
  455: 
  456:     queue = queue_de_signal(signal);
  457: 
  458:     unsigned char   *nom;
  459: 
  460: #   ifndef IPCS_SYSV
  461: 
  462:     // Ouverture des projections
  463: 
  464:     if ((nom = nom_segment(NULL, pid)) == NULL)
  465:     {
  466:         return(-1);
  467:     }
  468: 
  469:     // Dans le cas de SIGSTART, premier signal envoyé à un processus fils,
  470:     // il convient d'attendre que le fichier support soit effectivement
  471:     // accessible. Dans tous les autres cas, ce fichier doit exister. S'il
  472:     // n'existe plus, le processus associé n'existe plus.
  473: 
  474:     if (signal == SIGSTART)
  475:     {
  476:         horodatage_initial = horodatage();
  477: 
  478:         while((identifiant = shm_open(nom, O_RDWR, S_IRUSR | S_IWUSR)) == -1)
  479:         {
  480:             if (abs(horodatage_initial - horodatage()) > 500)
  481:             {
  482:                 return(-1);
  483:             }
  484:         }
  485:     }
  486:     else
  487:     {
  488:         if ((identifiant = shm_open(nom, O_RDWR, S_IRUSR | S_IWUSR)) == -1)
  489:         {
  490:             return(-1);
  491:         }
  492:     }
  493: 
  494:     projection_fifos = mmap(NULL, nombre_queues * ((2 * longueur_queue) + 4)
  495:             * sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, identifiant, 0);
  496:     close(identifiant);
  497: 
  498:     if (((void *) projection_fifos) == ((void *) -1))
  499:     {
  500:         return(-1);
  501:     }
  502: 
  503: #   else // Traitement à l'aide d'IPCS SystemV
  504: 
  505:     key_t           clef;
  506: 
  507:     struct stat     s_stat;
  508: 
  509:     // Ouverture des projections
  510: 
  511:     if ((nom = nom_segment(chemin, pid)) == NULL)
  512:     {
  513:         return(-1);
  514:     }
  515: 
  516:     // Dans le cas de SIGSTART, premier signal envoyé à un processus fils,
  517:     // il convient d'attendre que le fichier support soit effectivement
  518:     // accessible. Dans tous les autres cas, ce fichier doit exister. S'il
  519:     // n'existe plus, le processus associé n'existe plus.
  520: 
  521:     if (signal == SIGSTART)
  522:     {
  523:         // On attend que le fichier sois présent
  524: 
  525:         horodatage_initial = horodatage();
  526: 
  527:         while(stat(nom, &s_stat) != 0)
  528:         {
  529:             if (abs(horodatage_initial - horodatage()) > 500)
  530:             {
  531:                 return(-1);
  532:             }
  533:         }
  534:     }
  535: 
  536:     if ((clef = ftok(nom, 1)) == -1)
  537:     {
  538:         return(-1);
  539:     }
  540: 
  541:     free(nom);
  542: 
  543:     if (signal == SIGSTART)
  544:     {
  545:         while((identifiant = shmget(clef,
  546:                 nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
  547:                 S_IRUSR | S_IWUSR)) == -1);
  548:     }
  549:     else
  550:     {
  551:         if ((identifiant = shmget(clef,
  552:                 nombre_queues * ((2 * longueur_queue) + 4) * sizeof(int),
  553:                 S_IRUSR | S_IWUSR)) == -1)
  554:         {
  555:             return(-1);
  556:         }
  557:     }
  558: 
  559:     projection_fifos = shmat(identifiant, NULL, 0);
  560: 
  561:     if (((void *) projection_fifos) == ((void *) -1))
  562:     {
  563:         return(-1);
  564:     }
  565: 
  566: #   endif
  567: 
  568:     if ((nom = nom_semaphore(pid, queue)) == NULL)
  569:     {
  570: #       ifdef IPCS_SYSV
  571:         shmdt(projection_fifos);
  572: #       else
  573:         munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
  574:                 * sizeof(int));
  575: #       endif
  576:         return(-1);
  577:     }
  578: 
  579:     while((semaphore = sem_open(nom, 0)) == SEM_FAILED);
  580:     free(nom);
  581: 
  582:     while(sem_wait(semaphore) != 0)
  583:     {
  584:         if (errno != EINTR)
  585:         {
  586: #           ifdef IPCS_SYSV
  587:             shmdt(projection_fifos);
  588: #           else
  589:             munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
  590:                     * sizeof(int));
  591: #           endif
  592:             return(-1);
  593:         }
  594:     }
  595: 
  596:     base = &(projection_fifos[(longueur_queue + 4) * queue]);
  597:     buffer = &(base[4]);
  598: 
  599:     // base[3] contient le nombre d'éléments restants
  600: 
  601:     if (base[3] <= 0)
  602:     {
  603:         sem_post(semaphore);
  604:         sem_close(semaphore);
  605: #       ifdef IPCS_SYSV
  606:         shmdt(projection_fifos);
  607: #       else
  608:         munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
  609:                 * sizeof(int));
  610: #       endif
  611:         return(-1);
  612:     }
  613: 
  614:     base[3]--;
  615: 
  616:     // base[1] contient le prochain élément à écrire
  617: 
  618:     buffer[base[1] + (nombre_queues * base[2])] = horodatage();
  619:     buffer[base[1]++] = (int) pid;
  620:     base[1] %= base[2];
  621: 
  622:     if (sem_post(semaphore) != 0)
  623:     {
  624: #       ifdef IPCS_SYSV
  625:         shmdt(projection_fifos);
  626: #       else
  627:         munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
  628:                 * sizeof(int));
  629: #       endif
  630:         sem_close(semaphore);
  631:         return(-1);
  632:     }
  633: 
  634:     sem_close(semaphore);
  635: 
  636:     // Fermeture des projections
  637: #   ifdef IPCS_SYSV
  638:     shmdt(projection_fifos);
  639: #   else
  640:     munmap(projection_fifos, nombre_queues * ((2 * longueur_queue) + 4)
  641:             * sizeof(int));
  642: #   endif
  643: 
  644:     return(0);
  645: }
  646: 
  647: static inline int
  648: chaine_markov(int markov, int delta)
  649: {
  650:     double      memoire = 0.9;
  651:     int         valeur;
  652: 
  653:     valeur = (int) ((memoire * markov) + ((1 - memoire) * delta));
  654:     valeur = (valeur < 10) ? 10 : valeur;
  655: 
  656:     return(valeur);
  657: }
  658: 
  659: pid_t
  660: origine_signal(int signal)
  661: {
  662:     logical1        drapeau;
  663: 
  664:     int             *base;
  665:     int             *buffer;
  666:     int             delta;
  667:     int             pid;
  668:     int             queue;
  669: 
  670:     queue = queue_de_signal(signal);
  671: 
  672:     BUG(queue == -1, uprintf("[%d] Unknown signal %d in this context\n",
  673:             (int) getpid(), signal));
  674: 
  675:     while(sem_wait(semaphores[queue]) != 0)
  676:     {
  677:         if (errno != EINTR)
  678:         {
  679:             return(-1);
  680:         }
  681:     }
  682: 
  683:     // On retire les interruptions anciennes qui ont été ratées sauf s'il
  684:     // s'agit de la dernière dans la queue.
  685: 
  686:     base = &(fifos[(longueur_queue + 4) * queue]);
  687:     buffer = &(base[4]);
  688: 
  689:     if (base[3] == (base[2] - 1))
  690:     {
  691:         delta = abs(horodatage() -
  692:                  buffer[base[0] + (nombre_queues * base[2])]);
  693:         // Une seule interruption dans la queue.
  694:         pid = buffer[base[0]++];
  695:         base[0] %= base[2];
  696:         base[3]++;
  697: 
  698:         markov = chaine_markov(markov, delta);
  699:     }
  700:     else if (base[3] >= base[2])
  701:     {
  702:         // Aucune interruption n'est dans la queue.
  703:         // On a retiré trop d'interruptions de la queue.
  704: 
  705:         // (base[3] - base[2]) + 1 : nombre d'interruptions manquantes
  706:         // base[0] - 1             : dernière interruption lue
  707:         pid = buffer[((((base[0] + base[2] - 1) % base[2])
  708:                 - ((base[3] - base[2]) + 1)) + base[2]) % base[2]];
  709: 
  710:         if (kill(pid, 0) != 0)
  711:         {
  712:             pid = getpid();
  713:         }
  714:     }
  715:     else
  716:     {
  717:         // Plusieurs interruptions à distribuer.
  718:         drapeau = d_vrai;
  719: 
  720:         do
  721:         {
  722:             delta = abs(horodatage() -
  723:                      buffer[base[0] + (nombre_queues * base[2])]);
  724:             pid = buffer[base[0]++];
  725:             base[0] %= base[2];
  726:             base[3]++;
  727: 
  728:             if ((delta > (2 * markov)) && (base[3] < base[2]))
  729:             {
  730:                 drapeau = d_vrai;
  731:             }
  732:             else
  733:             {
  734:                 drapeau = d_faux;
  735:             }
  736:         } while(drapeau == d_vrai);
  737: 
  738:         markov = chaine_markov(markov, delta);
  739:     }
  740: 
  741:     if (sem_post(semaphores[queue]) != 0)
  742:     {
  743:         return(-1);
  744:     }
  745: 
  746:     return((pid_t) pid);
  747: }
  748: 
  749: int
  750: kill_broken_siginfo(pid_t pid, int signal)
  751: {
  752:     int                 ios;
  753: 
  754:     sem_t               *semaphore;
  755: 
  756:     unsigned char       *nom;
  757: 
  758:     /*
  759:      * Lorsqu'on veut interrompre le processus pid, on ouvre le segment
  760:      * correspondant au processus en question et ou ajoute le pid dans la
  761:      * queue.
  762:      *
  763:      * Le sémaphore global à tous les threads d'un même processus sert
  764:      * à garantir que les signaux seront traités dans l'ordre de ce qui est
  765:      * effectivement mis dans la queue.
  766:      */
  767: 
  768:     // Sémaphore acquis
  769: 
  770:     if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
  771:     {
  772:         return(-1);
  773:     }
  774: 
  775:     while((semaphore = sem_open(nom, 0)) == SEM_FAILED);
  776:     free(nom);
  777: 
  778:     while(sem_wait(semaphore) != 0)
  779:     {
  780:         if (errno != EINTR)
  781:         {
  782:             return(-1);
  783:         }
  784:     }
  785: 
  786:     if ((signal != 0) && (signal != SIGINT))
  787:     {
  788:         if (queue_in(pid, signal) != 0)
  789:         {
  790:             sem_post(semaphore);
  791:             sem_close(semaphore);
  792:             return(-1);
  793:         }
  794:     }
  795: 
  796:     ios = kill(pid, signal);
  797: 
  798:     // Sémaphore relâché
  799: 
  800:     sem_post(semaphore);
  801:     sem_close(semaphore);
  802: 
  803:     return(ios);
  804: }
  805: 
  806: int
  807: pthread_kill_broken_siginfo(pthread_t tid, int signal)
  808: {
  809:     int                 ios;
  810: 
  811:     sem_t               *semaphore;
  812: 
  813:     unsigned char       *nom;
  814: 
  815:     if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
  816:     {
  817:         return(-1);
  818:     }
  819: 
  820:     while((semaphore = sem_open(nom, 0)) == SEM_FAILED);
  821:     free(nom);
  822: 
  823:     while(sem_wait(semaphore) != 0)
  824:     {
  825:         if (errno != EINTR)
  826:         {
  827:             return(-1);
  828:         }
  829:     }
  830: 
  831:     if ((signal != 0) && (signal != SIGINT))
  832:     {
  833:         if (queue_in(getpid(), signal) != 0)
  834:         {
  835:             sem_post(semaphore);
  836:             sem_close(semaphore);
  837:             return(-1);
  838:         }
  839:     }
  840: 
  841:     ios = pthread_kill(tid, signal);
  842: 
  843:     sem_post(semaphore);
  844:     sem_close(semaphore);
  845: 
  846:     return(ios);
  847: }
  848: 
  849: #endif
  850: 
  851: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>