Annotation of rpl/src/siginfo.c, revision 1.1

1.1     ! bertrand    1: /*
        !             2: ================================================================================
        !             3:   RPL/2 (R) version 4.0.18
        !             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: static 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:    else
        !           711:    {
        !           712:        // Plusieurs interruptions à distribuer.
        !           713:        drapeau = d_vrai;
        !           714: 
        !           715:        do
        !           716:        {
        !           717:            delta = abs(horodatage() -
        !           718:                     buffer[base[0] + (nombre_queues * base[2])]);
        !           719:            pid = buffer[base[0]++];
        !           720:            base[0] %= base[2];
        !           721:            base[3]++;
        !           722: 
        !           723:            if ((delta > (2 * markov)) && (base[3] < base[2]))
        !           724:            {
        !           725:                drapeau = d_vrai;
        !           726:            }
        !           727:            else
        !           728:            {
        !           729:                drapeau = d_faux;
        !           730:            }
        !           731:        } while(drapeau == d_vrai);
        !           732: 
        !           733:        markov = chaine_markov(markov, delta);
        !           734:    }
        !           735: 
        !           736:    if (sem_post(semaphores[queue]) != 0)
        !           737:    {
        !           738:        return(-1);
        !           739:    }
        !           740: 
        !           741:    return((pid_t) pid);
        !           742: }
        !           743: 
        !           744: int
        !           745: kill_broken_siginfo(pid_t pid, int signal)
        !           746: {
        !           747:    int                 ios;
        !           748: 
        !           749:    sem_t               *semaphore;
        !           750: 
        !           751:    unsigned char       *nom;
        !           752: 
        !           753:    /*
        !           754:     * Lorsqu'on veut interrompre le processus pid, on ouvre le segment
        !           755:     * correspondant au processus en question et ou ajoute le pid dans la
        !           756:     * queue.
        !           757:     *
        !           758:     * Le sémaphore global à tous les threads d'un même processus sert
        !           759:     * à garantir que les signaux seront traités dans l'ordre de ce qui est
        !           760:     * effectivement mis dans la queue.
        !           761:     */
        !           762: 
        !           763:    // Sémaphore acquis
        !           764: 
        !           765:    if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
        !           766:    {
        !           767:        return(-1);
        !           768:    }
        !           769: 
        !           770:    while((semaphore = sem_open(nom, 0)) == SEM_FAILED);
        !           771:    free(nom);
        !           772: 
        !           773:    while(sem_wait(semaphore) != 0)
        !           774:    {
        !           775:        if (errno != EINTR)
        !           776:        {
        !           777:            return(-1);
        !           778:        }
        !           779:    }
        !           780: 
        !           781:    if ((signal != 0) && (signal != SIGINT))
        !           782:    {
        !           783:        if (queue_in(pid, signal) != 0)
        !           784:        {
        !           785:            sem_post(semaphore);
        !           786:            sem_close(semaphore);
        !           787:            return(-1);
        !           788:        }
        !           789:    }
        !           790: 
        !           791:    ios = kill(pid, signal);
        !           792: 
        !           793:    // Sémaphore relâché
        !           794: 
        !           795:    sem_post(semaphore);
        !           796:    sem_close(semaphore);
        !           797: 
        !           798:    return(ios);
        !           799: }
        !           800: 
        !           801: int
        !           802: pthread_kill_broken_siginfo(pthread_t tid, int signal)
        !           803: {
        !           804:    int                 ios;
        !           805: 
        !           806:    sem_t               *semaphore;
        !           807: 
        !           808:    unsigned char       *nom;
        !           809: 
        !           810:    if ((nom = nom_semaphore(getpid(), nombre_queues)) == NULL)
        !           811:    {
        !           812:        return(-1);
        !           813:    }
        !           814: 
        !           815:    while((semaphore = sem_open(nom, 0)) == SEM_FAILED);
        !           816:    free(nom);
        !           817: 
        !           818:    while(sem_wait(semaphore) != 0)
        !           819:    {
        !           820:        if (errno != EINTR)
        !           821:        {
        !           822:            return(-1);
        !           823:        }
        !           824:    }
        !           825: 
        !           826:    if ((signal != 0) && (signal != SIGINT))
        !           827:    {
        !           828:        if (queue_in(getpid(), signal) != 0)
        !           829:        {
        !           830:            sem_post(semaphore);
        !           831:            sem_close(semaphore);
        !           832:            return(-1);
        !           833:        }
        !           834:    }
        !           835: 
        !           836:    ios = pthread_kill(tid, signal);
        !           837: 
        !           838:    sem_post(semaphore);
        !           839:    sem_close(semaphore);
        !           840: 
        !           841:    return(ios);
        !           842: }
        !           843: 
        !           844: #endif
        !           845: 
        !           846: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>