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

1.1       bertrand    1: /*
                      2: ================================================================================
1.8.2.2 ! bertrand    3:   RPL/2 (R) version 4.0.23
1.7       bertrand    4:   Copyright (C) 1989-2011 Dr. BERTRAND Joël
1.1       bertrand    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
1.5       bertrand   37: #ifndef OS2
1.1       bertrand   38: static unsigned char   *chemin = NULL;
                     39: #endif
1.5       bertrand   40: #endif
                     41: 
                     42: #ifdef OS2
                     43: PVOID                  ptr_os2;
                     44: #else
                     45: static int             segment;
                     46: #endif
1.1       bertrand   47: 
                     48: static unsigned char *
                     49: nom_segment(unsigned char *chemin, pid_t pid)
                     50: {
                     51:    unsigned char               *fichier;
                     52: 
                     53: #  ifdef IPCS_SYSV
1.5       bertrand   54: 
                     55: #  ifndef OS2
                     56: 
1.1       bertrand   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);
1.5       bertrand   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
1.1       bertrand   75: #  else
1.5       bertrand   76: 
1.1       bertrand   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);
1.5       bertrand   84: 
1.1       bertrand   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: 
1.5       bertrand  100:    sprintf(fichier, "/RPL-SIGSEMAPHORES-%d-%d", (int) pid, queue);
1.1       bertrand  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
1.5       bertrand  200: #  ifndef OS2
1.1       bertrand  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: 
1.5       bertrand  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
1.1       bertrand  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
1.5       bertrand  349: #  ifndef OS2
1.1       bertrand  350: 
                    351:    if (shmdt(fifos) == -1)
                    352:    {
                    353:        (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    354:        return;
                    355:    }
                    356: 
1.5       bertrand  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
1.1       bertrand  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
1.5       bertrand  403: #  ifndef OS2
1.1       bertrand  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: 
1.5       bertrand  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
1.1       bertrand  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: 
1.2       bertrand  509: int
1.1       bertrand  510: queue_in(pid_t pid, int signal)
                    511: {
                    512:    int             queue;
                    513:    int             *base;
                    514:    int             *buffer;
                    515:    int             horodatage_initial;
1.5       bertrand  516: #  ifndef OS2
1.1       bertrand  517:    int             identifiant;
1.5       bertrand  518: #  endif
1.1       bertrand  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: 
1.5       bertrand  572: #  ifndef OS2
1.1       bertrand  573:    key_t           clef;
                    574: 
                    575:    struct stat     s_stat;
1.5       bertrand  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
1.1       bertrand  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: 
1.5       bertrand  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
1.1       bertrand  671: #  endif
                    672: 
                    673:    if ((nom = nom_semaphore(pid, queue)) == NULL)
                    674:    {
                    675: #      ifdef IPCS_SYSV
1.5       bertrand  676: #      ifndef OS2
1.1       bertrand  677:        shmdt(projection_fifos);
                    678: #      else
1.5       bertrand  679:        DosFreeMem(projection_fifos);
                    680: #      endif
                    681: #      else
1.1       bertrand  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
1.5       bertrand  696: #          ifndef OS2
1.1       bertrand  697:            shmdt(projection_fifos);
                    698: #          else
1.5       bertrand  699:            DosFreeMem(projection_fifos);
                    700: #          endif
                    701: #          else
1.1       bertrand  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
1.5       bertrand  719: #      ifndef OS2
1.1       bertrand  720:        shmdt(projection_fifos);
                    721: #      else
1.5       bertrand  722:        DosFreeMem(projection_fifos);
                    723: #      endif
                    724: #      else
1.1       bertrand  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
1.5       bertrand  742: #      ifndef OS2
1.1       bertrand  743:        shmdt(projection_fifos);
                    744: #      else
1.5       bertrand  745:        DosFreeMem(projection_fifos);
                    746: #      endif
                    747: #      else
1.1       bertrand  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
1.5       bertrand  759: #  ifndef OS2
1.1       bertrand  760:    shmdt(projection_fifos);
                    761: #  else
1.5       bertrand  762:    DosFreeMem(projection_fifos);
                    763: #  endif
                    764: #  else
1.1       bertrand  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]];
1.4       bertrand  834: 
                    835:        if (kill(pid, 0) != 0)
                    836:        {
                    837:            pid = getpid();
                    838:        }
1.1       bertrand  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>