File:  [local] / rpl / src / Attic / siginfo.c
Revision 1.13: download - view: text, annotated - select for diffs - revision graph
Tue Jun 21 15:26:35 2011 UTC (12 years, 11 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Correction d'une réinitialisation sauvage de la pile des variables par niveau
dans la copie de la structure de description du processus. Cela corrige
la fonction SPAWN qui échouait sur un segmentation fault car la pile des
variables par niveau était vide alors même que l'arbre des variables contenait
bien les variables. Passage à la prerelease 2.

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

CVSweb interface <joel.bertrand@systella.fr>