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

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: 
1.2     ! bertrand  444: int
1.1       bertrand  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>