Annotation of rpl/src/semaphores.c, revision 1.39

1.1       bertrand    1: /*
                      2: ================================================================================
1.38      bertrand    3:   RPL/2 (R) version 4.1.4
1.16      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: 
1.6       bertrand   23: #include "rpl-conv.h"
                     24: 
1.39    ! bertrand   25: 
1.1       bertrand   26: #ifdef SEMAPHORES_NOMMES
                     27: 
1.29      bertrand   28: // Les fonctions suivantes ne sont utilisées que dans le cas d'un
                     29: // système POSIX qui ne possède pas de sémaphores anonymes. MacOS X
                     30: // est dans ce cas.
                     31: 
                     32: static unsigned char *
1.35      bertrand   33: nom_segment_semaphore(pid_t pid, int ordre)
1.29      bertrand   34: {
                     35:    unsigned char               *fichier;
                     36: 
                     37:    if ((fichier = malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL)
                     38:    {
                     39:        return(NULL);
                     40:    }
                     41: 
1.35      bertrand   42:    sprintf(fichier, "/RPL-%d-%d", (int) pid, ordre);
1.34      bertrand   43:    return(fichier);
                     44: }
                     45: 
                     46: 
                     47: static unsigned char *
1.35      bertrand   48: nom_segment_semaphore_thread(pid_t pid, pthread_t tid, int ordre)
1.34      bertrand   49: {
                     50:    unsigned char               *fichier;
                     51: 
                     52:    if ((fichier = malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL)
                     53:    {
                     54:        return(NULL);
                     55:    }
                     56: 
1.35      bertrand   57:    sprintf(fichier, "/RPL-%d-%llX-%d", (int) pid,
                     58:            (unsigned long long) tid, ordre);
1.29      bertrand   59:    return(fichier);
                     60: }
                     61: 
                     62: 
1.1       bertrand   63: /*
                     64: ================================================================================
                     65:   Fonctions d'émulation de sémaphores anonymes
                     66: ================================================================================
                     67:   Entrées :
                     68: --------------------------------------------------------------------------------
                     69:   Sorties :
                     70: --------------------------------------------------------------------------------
                     71:   Effets de bord : néant
                     72: ================================================================================
                     73: */
                     74: 
                     75: sem_t *
1.35      bertrand   76: sem_init2(unsigned int valeur, pid_t pid, int ordre)
1.1       bertrand   77: {
1.29      bertrand   78:    sem_t                       *semaphore;
                     79: 
                     80:    unsigned char               *chemin;
                     81: 
1.35      bertrand   82:    if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL)
1.29      bertrand   83:    {
                     84:        return(SEM_FAILED);
                     85:    }
                     86: 
1.34      bertrand   87:    semaphore = sem_open(chemin, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR,
                     88:            valeur);
1.29      bertrand   89:    free(chemin);
                     90: 
1.34      bertrand   91:    return(semaphore);
                     92: }
                     93: 
                     94: 
                     95: sem_t *
1.35      bertrand   96: sem_init3(unsigned int valeur, pid_t pid, pthread_t tid, int ordre)
1.34      bertrand   97: {
                     98:    sem_t                       *semaphore;
                     99: 
                    100:    unsigned char               *chemin;
                    101: 
1.35      bertrand  102:    if ((chemin = nom_segment_semaphore_thread(pid, tid, ordre)) == NULL)
1.30      bertrand  103:    {
1.34      bertrand  104:        return(SEM_FAILED);
1.30      bertrand  105:    }
                    106: 
1.34      bertrand  107:    semaphore = sem_open(chemin, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR,
                    108:            valeur);
                    109:    free(chemin);
                    110: 
1.29      bertrand  111:    return(semaphore);
1.1       bertrand  112: }
                    113: 
1.29      bertrand  114: 
                    115: sem_t *
1.35      bertrand  116: sem_open2(pid_t pid, int ordre)
1.29      bertrand  117: {
                    118:    unsigned char               *chemin;
                    119: 
                    120:    sem_t                       *semaphore;
                    121: 
1.35      bertrand  122:    if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL)
1.29      bertrand  123:    {
1.34      bertrand  124:        return(SEM_FAILED);
1.29      bertrand  125:    }
                    126: 
                    127:    semaphore = sem_open(chemin, O_RDWR);
                    128:    free(chemin);
                    129: 
                    130:    return(semaphore);
                    131: }
                    132: 
                    133: 
1.1       bertrand  134: int
1.35      bertrand  135: sem_destroy2(sem_t *semaphore, pid_t pid, int ordre)
1.1       bertrand  136: {
1.29      bertrand  137:    int                         erreur;
                    138: 
                    139:    unsigned char               *chemin;
                    140: 
                    141:    sem_close(semaphore);
                    142: 
1.35      bertrand  143:    if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL)
1.29      bertrand  144:    {
                    145:        return(1);
                    146:    }
                    147: 
1.38      bertrand  148:    erreur = sem_unlink(chemin);
1.29      bertrand  149:    free(chemin);
                    150: 
                    151:    return(erreur);
1.1       bertrand  152: }
                    153: 
1.34      bertrand  154: 
                    155: int
1.35      bertrand  156: sem_destroy3(sem_t *semaphore, pid_t pid, pthread_t tid, int ordre)
1.34      bertrand  157: {
                    158:    int                         erreur;
                    159: 
                    160:    unsigned char               *chemin;
                    161: 
                    162:    sem_close(semaphore);
                    163: 
1.35      bertrand  164:    if ((chemin = nom_segment_semaphore_thread(pid, tid, ordre)) == NULL)
1.34      bertrand  165:    {
                    166:        return(1);
                    167:    }
                    168: 
                    169:    erreur = sem_unlink(chemin);
                    170:    free(chemin);
                    171: 
                    172:    return(erreur);
                    173: }
                    174: 
                    175: 
1.1       bertrand  176: #undef sem_post
                    177: #undef sem_wait
                    178: #undef sem_trywait
                    179: 
                    180: int
                    181: sem_getvalue2(sem_t *semaphore, int *valeur)
                    182: {
                    183:    int                     i;
1.31      bertrand  184:    int                     j;
1.1       bertrand  185: 
                    186:    logical1                drapeau_fin;
                    187: 
1.31      bertrand  188:    struct timespec         attente;
1.1       bertrand  189: 
1.31      bertrand  190:    attente.tv_sec = 0;
                    191:    attente.tv_nsec = GRANULARITE_us * 1000;
1.1       bertrand  192: 
1.31      bertrand  193:    for(j = 0; j < 100; j++)
1.1       bertrand  194:    {
1.31      bertrand  195:        if (pthread_mutex_trylock(&mutex_sem) == 0)
1.1       bertrand  196:        {
1.31      bertrand  197:            (*valeur) = 0;
                    198:            drapeau_fin = d_faux;
                    199: 
                    200:            do
1.1       bertrand  201:            {
1.31      bertrand  202:                if (sem_trywait(semaphore) == -1)
                    203:                {
                    204:                    if (errno == EAGAIN)
                    205:                    {
                    206:                        // Le sémaphore avait une valeur nulle
                    207:                        drapeau_fin = d_vrai;
                    208:                    }
                    209:                    else
                    210:                    {
                    211:                        // Autre erreur
                    212:                        pthread_mutex_unlock(&mutex_sem);
                    213:                        return(-1);
                    214:                    }
                    215:                }
                    216:                else
                    217:                {
                    218:                    (*valeur)++;
                    219:                }
                    220:            } while(drapeau_fin == d_faux);
                    221: 
                    222:            for(i = 0; i < (*valeur); i++)
1.1       bertrand  223:            {
1.31      bertrand  224:                if (sem_post(semaphore) != 0)
                    225:                {
                    226:                    pthread_mutex_unlock(&mutex_sem);
                    227:                    return(-1);
                    228:                }
1.1       bertrand  229:            }
                    230: 
                    231:            pthread_mutex_unlock(&mutex_sem);
1.31      bertrand  232:            return(0);
1.1       bertrand  233:        }
1.31      bertrand  234: 
                    235:        INCR_GRANULARITE(attente.tv_nsec);
1.1       bertrand  236:    }
                    237: 
1.31      bertrand  238:    // Le mutex n'a pas pu être verrouillé. On peut raisonnablement penser
                    239:    // que le sémaphore est bloqué dans un sem_wait() protégé par ce mutex.
                    240: 
                    241:    (*valeur) = 0;
1.1       bertrand  242:    return(0);
                    243: }
                    244: 
                    245: #endif
                    246: 
1.14      bertrand  247: #ifdef IPCS_SYSV
1.6       bertrand  248: 
                    249: /*
                    250: ================================================================================
                    251:   Fonctions d'émulation de sémaphores POSIX en fonction des sémaphores SysV
                    252: ================================================================================
                    253:   Entrées :
                    254: --------------------------------------------------------------------------------
                    255:   Sorties :
                    256: --------------------------------------------------------------------------------
                    257:   Effets de bord : néant
                    258: ================================================================================
                    259: */
                    260: 
1.32      bertrand  261: #ifndef OS2 // IPCS_SYSV
                    262:    extern unsigned char *racine_segment;
                    263: #else // OS/2
1.9       bertrand  264:    unsigned char racine_semaphores_OS2[] = "\\SEM32\\";
1.14      bertrand  265:    unsigned char racine_memoire_OS2[] = "\\SHAREMEM\\";
1.9       bertrand  266: #endif
1.6       bertrand  267: 
                    268: int
1.8       bertrand  269: sem_init_SysV(sem_t *semaphore, int shared, unsigned int valeur)
1.6       bertrand  270: {
1.11      bertrand  271:    // Création d'un sémaphore anonyme qui devra être supprimé par
                    272:    // sem_destroy_SysV
1.9       bertrand  273: 
1.32      bertrand  274: #  ifndef OS2 // IPCS_SYSV
                    275:        int             desc;
                    276:        int             ios;
                    277: 
                    278:        key_t           clef;
                    279: 
                    280:        union semun     argument;
                    281: 
                    282:        if (shared == 0)
                    283:        {
                    284:            // Sémaphore privé
                    285:            (*semaphore).sem = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL |
                    286:                    S_IRUSR | S_IWUSR);
                    287:            (*semaphore).path = NULL;
                    288:            (*semaphore).pid = getpid();
1.34      bertrand  289:            (*semaphore).tid = pthread_self();
1.32      bertrand  290:            (*semaphore).alloue = 0;
                    291:        }
                    292:        else
                    293:        {
                    294:            // Sémaphore partagé entre plusieurs processus
                    295:            if (((*semaphore).path = malloc((strlen(racine_segment)
1.34      bertrand  296:                    + 2 + 256 + 1) * sizeof(unsigned char))) == NULL)
1.32      bertrand  297:            {
                    298:                return(-1);
                    299:            }
                    300: 
1.36      bertrand  301:            sprintf((*semaphore).path, "%s/RPL-SEMAPHORE-%d-%llX-%d",
                    302:                    racine_segment, (int) getpid(), pthread_self(), shared);
1.32      bertrand  303: 
1.33      bertrand  304:            if ((desc = open((*semaphore).path, O_RDWR | O_CREAT | O_EXCL,
1.32      bertrand  305:                    S_IRUSR | S_IWUSR)) == -1)
                    306:            {
                    307:                free((*semaphore).path);
                    308:                return(-1);
                    309:            }
                    310: 
                    311:            (*semaphore).pid = getpid();
1.37      bertrand  312:            (*semaphore).tid = pthread_self();
1.32      bertrand  313:            clef = ftok((*semaphore).path, 1);
                    314:            close(desc);
                    315: 
                    316:            if (clef == -1)
                    317:            {
                    318:                free((*semaphore).path);
                    319:                return(-1);
                    320:            }
                    321: 
                    322:            (*semaphore).alloue = 0;
                    323:            (*semaphore).sem = semget(clef, 1, IPC_CREAT | IPC_EXCL |
                    324:                    S_IRUSR | S_IWUSR);
                    325:        }
1.8       bertrand  326: 
1.32      bertrand  327:        if ((*semaphore).sem == -1)
                    328:        {
                    329:            errno = EINVAL;
                    330:            return(-1);
                    331:        }
1.6       bertrand  332: 
1.32      bertrand  333:        argument.val = valeur;
                    334:        ios = semctl((*semaphore).sem, 0, SETVAL, argument);
1.6       bertrand  335: 
1.32      bertrand  336:        return(ios);
                    337: #  else // OS/2
1.39    ! bertrand  338:        sem_t           *psem;
1.9       bertrand  339: 
1.39    ! bertrand  340:        psem = semaphore;
1.9       bertrand  341: 
1.39    ! bertrand  342:        if (((*psem).cnt = malloc(sizeof(ULONG))) == NULL)
        !           343:        {
        !           344:            free(psem);
        !           345:            errno = ENOMEM;
        !           346:            return(-1);
        !           347:        }
1.9       bertrand  348: 
1.39    ! bertrand  349:        if (((*psem).nopened = malloc(sizeof(ULONG))) == NULL)
        !           350:        {
        !           351:            free((*psem).cnt);
        !           352:            free(psem);
        !           353:            errno = ENOMEM;
        !           354:            return(-1);
        !           355:        }
1.9       bertrand  356: 
1.39    ! bertrand  357:        if (DosCreateMutexSem(NULL, &((*psem).hmtx), 0, 0) != 0)
        !           358:        {
        !           359:            free((*psem).cnt);
        !           360:            free((*psem).nopened);
        !           361:            free(psem);
        !           362:            return(-1);
        !           363:        }
1.9       bertrand  364: 
1.39    ! bertrand  365:        if (DosCreateEventSem(NULL, &((*psem).hev), 0, (valeur != 0) ? 1 : 0)
        !           366:                != 0)
        !           367:        {
        !           368:            DosCloseMutexSem((*psem).hmtx);
        !           369:            free((*psem).cnt);
        !           370:            free((*psem).nopened);
        !           371:            free(psem);
        !           372:            return(-1);
        !           373:        }
1.9       bertrand  374: 
1.39    ! bertrand  375:        (*(*psem).cnt) = valeur;
        !           376:        (*(*psem).nopened) = 1;
        !           377:        (*psem).shared = shared;
        !           378:        (*psem).allocated = 0;
1.9       bertrand  379: 
1.39    ! bertrand  380:        return(0);
1.9       bertrand  381: #  endif
1.6       bertrand  382: }
                    383: 
                    384: int
1.8       bertrand  385: sem_destroy_SysV(sem_t *semaphore)
1.6       bertrand  386: {
1.11      bertrand  387:    // Détruit un sémaphore anonmyme
1.9       bertrand  388: 
1.32      bertrand  389: #  ifndef OS2 // IPCS_SYSV
                    390:        if ((*semaphore).path != NULL)
                    391:        {
                    392:            return(EINVAL);
                    393:        }
1.11      bertrand  394: 
1.32      bertrand  395:        if ((*semaphore).pid != getpid())
                    396:        {
                    397:            return(0);
                    398:        }
1.11      bertrand  399: 
1.32      bertrand  400:        if (semctl((*semaphore).sem, 0, IPC_RMID) == -1)
                    401:        {
                    402:            return(EINVAL);
                    403:        }
1.6       bertrand  404: 
1.32      bertrand  405:        return(0);
                    406: #  else // OS/2
1.39    ! bertrand  407:        sem_t       *psem;
1.9       bertrand  408: 
1.39    ! bertrand  409:        psem = semaphore;
1.9       bertrand  410: 
1.39    ! bertrand  411:        if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
        !           412:        {
        !           413:            return(EINVAL);
        !           414:        }
1.9       bertrand  415: 
1.39    ! bertrand  416:        if (DosCloseMutexSem((*psem).hmtx) != 0)
        !           417:        {
        !           418:            return(EINVAL);
        !           419:        }
1.9       bertrand  420: 
1.39    ! bertrand  421:        while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
        !           422:        {
        !           423:            DosPostEventSem((*psem).hev);
        !           424:        }
1.9       bertrand  425: 
1.39    ! bertrand  426:        (*(*psem).nopened)--;
1.9       bertrand  427: 
1.39    ! bertrand  428:        if ((*psem).shared == 0)
1.9       bertrand  429:        {
1.39    ! bertrand  430:            free((*psem).cnt);
        !           431:            free((*psem).nopened);
        !           432:        }
        !           433:        else
        !           434:        {
        !           435:            if ((*(*psem).nopened) == 0)
        !           436:            {
        !           437:                DosFreeMem((*psem).cnt);
        !           438:            }
1.9       bertrand  439:        }
                    440: 
1.39    ! bertrand  441:        if ((*psem).allocated != 0)
        !           442:        {   
        !           443:            free(psem);
        !           444:        }
1.9       bertrand  445: 
1.39    ! bertrand  446:        return(0);
1.9       bertrand  447: #  endif
1.6       bertrand  448: }
                    449: 
                    450: int
1.8       bertrand  451: sem_wait_SysV(sem_t *semaphore)
1.6       bertrand  452: {
1.32      bertrand  453: #  ifndef OS2 // IPCS_SYSV
                    454:        struct sembuf       commande;
1.9       bertrand  455: 
1.32      bertrand  456:        commande.sem_num = 0;
                    457:        commande.sem_op = -1;
                    458:        commande.sem_flg = 0;
                    459: 
                    460:        while(semop((*semaphore).sem, &commande, 1) == -1)
                    461:        {
                    462:            if (errno != EINTR)
                    463:            {
                    464:                errno = EINVAL;
                    465:                return(-1);
                    466:            }
1.11      bertrand  467:        }
1.9       bertrand  468: 
1.32      bertrand  469:        return(0);
                    470: #  else // OS/2
1.39    ! bertrand  471:        sem_t       *psem;
1.9       bertrand  472: 
1.39    ! bertrand  473:        ULONG       cnt;
1.9       bertrand  474: 
1.39    ! bertrand  475:        psem = semaphore;
1.9       bertrand  476: 
1.39    ! bertrand  477:        if (DosWaitEventSem((*psem).hev, SEM_INDEFINITE_WAIT) != 0)
        !           478:        {
        !           479:            errno = EINVAL;
        !           480:            return(-1);
        !           481:        }
1.9       bertrand  482: 
1.39    ! bertrand  483:        if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
        !           484:        {
        !           485:            errno = EINVAL;
        !           486:            return(-1);
        !           487:        }
1.9       bertrand  488: 
1.39    ! bertrand  489:        if ((*(*psem).cnt) > 0)
        !           490:        {
        !           491:            (*(*psem).cnt)--;
        !           492:        }
1.9       bertrand  493: 
1.39    ! bertrand  494:        if ((*(*psem).cnt) == 0)
        !           495:        {
        !           496:            DosResetEventSem((*psem).hev, &cnt);
        !           497:        }
1.9       bertrand  498: 
1.39    ! bertrand  499:        DosReleaseMutexSem((*psem).hmtx);
        !           500:        return(0);
1.9       bertrand  501: #  endif
1.6       bertrand  502: }
                    503: 
                    504: int
1.8       bertrand  505: sem_trywait_SysV(sem_t *semaphore)
1.6       bertrand  506: {
1.32      bertrand  507: #  ifndef OS2 // IPCS_SYSV
                    508:        struct sembuf       commande;
1.6       bertrand  509: 
1.32      bertrand  510:        commande.sem_num = 0;
                    511:        commande.sem_op = -1;
                    512:        commande.sem_flg = IPC_NOWAIT;
                    513: 
                    514:        while(semop((*semaphore).sem, &commande, 1) == -1)
                    515:        {
                    516:            if (errno != EINTR)
                    517:            {
                    518:                errno = EINVAL;
                    519:                return(-1);
                    520:            }
1.11      bertrand  521:        }
1.9       bertrand  522: 
1.32      bertrand  523:        return(0);
                    524: #  else // OS/2
1.39    ! bertrand  525:        int         ios;
1.9       bertrand  526: 
1.39    ! bertrand  527:        sem_t       *psem;
1.9       bertrand  528: 
1.39    ! bertrand  529:        ULONG       cnt;
1.9       bertrand  530: 
1.39    ! bertrand  531:        psem = semaphore;
1.9       bertrand  532: 
1.39    ! bertrand  533:        if ((ios = DosWaitEventSem((*psem).hev, SEM_IMMEDIATE_RETURN)) != 0)
        !           534:        {
        !           535:            errno = (ios == ERROR_TIMEOUT) ? EAGAIN : EINVAL;
        !           536:            return(-1);
        !           537:        }
1.9       bertrand  538: 
1.39    ! bertrand  539:        if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
        !           540:        {
        !           541:            errno = EINVAL;
        !           542:            return(-1);
        !           543:        }
1.9       bertrand  544: 
1.39    ! bertrand  545:        if ((*(*psem).cnt) > 0)
        !           546:        {
        !           547:            (*(*psem).cnt)--;
        !           548:        }
1.9       bertrand  549: 
1.39    ! bertrand  550:        if ((*(*psem).cnt) == 0)
        !           551:        {
        !           552:            DosResetEventSem((*psem).hev, &cnt);
        !           553:        }
1.9       bertrand  554: 
1.39    ! bertrand  555:        DosReleaseMutexSem((*psem).hmtx);
        !           556:        return(0);
1.9       bertrand  557: #  endif
1.6       bertrand  558: }
                    559: 
                    560: int
1.8       bertrand  561: sem_post_SysV(sem_t *semaphore)
1.6       bertrand  562: {
1.32      bertrand  563: #  ifndef OS2 // IPCS_SYSV
                    564:        struct sembuf       commande;
1.9       bertrand  565: 
1.32      bertrand  566:        commande.sem_num = 0;
                    567:        commande.sem_op = 1;
                    568:        commande.sem_flg = 0;
                    569: 
                    570:        while(semop((*semaphore).sem, &commande, 1) == -1)
                    571:        {
                    572:            if (errno != EINTR)
                    573:            {
                    574:                errno = EINVAL;
                    575:                return(-1);
                    576:            }
1.11      bertrand  577:        }
1.9       bertrand  578: 
1.32      bertrand  579:        return(0);
                    580: #  else // OS/2
1.39    ! bertrand  581:        sem_t               *psem;
1.9       bertrand  582: 
1.39    ! bertrand  583:        psem = semaphore;
1.9       bertrand  584: 
1.39    ! bertrand  585:        if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
        !           586:        {
        !           587:            errno = EINVAL;
        !           588:            return(-1);
        !           589:        }
1.9       bertrand  590: 
1.39    ! bertrand  591:        (*(*psem).cnt)++;
        !           592:        DosPostEventSem((*psem).hev);
        !           593:        DosReleaseMutexSem((*psem).hmtx);
1.9       bertrand  594: 
1.39    ! bertrand  595:        return(0);
1.9       bertrand  596: #  endif
1.6       bertrand  597: }
                    598: 
                    599: int
1.8       bertrand  600: sem_getvalue_SysV(sem_t *semaphore, int *valeur)
1.6       bertrand  601: {
1.32      bertrand  602: #  ifndef OS2 // IPCS_SYSV
                    603:        (*valeur) = semctl((*semaphore).sem, 0, GETVAL);
1.9       bertrand  604: 
1.32      bertrand  605:        if ((*valeur) < 0)
                    606:        {
                    607:            return(EINVAL);
                    608:        }
1.9       bertrand  609: 
1.32      bertrand  610:        return(0);
1.9       bertrand  611: #  else
1.39    ! bertrand  612:        sem_t               *psem;
1.9       bertrand  613: 
1.39    ! bertrand  614:        psem = semaphore;
1.9       bertrand  615: 
1.39    ! bertrand  616:        if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
        !           617:        {
        !           618:            errno = EINVAL;
        !           619:            return(-1);
        !           620:        }
1.9       bertrand  621: 
1.39    ! bertrand  622:        (*valeur) = (*(*psem).cnt);
        !           623:        DosReleaseMutexSem((*psem).hmtx);
1.9       bertrand  624: 
1.39    ! bertrand  625:        return(0);
1.9       bertrand  626: #  endif
1.6       bertrand  627: }
                    628: 
                    629: sem_t
1.8       bertrand  630: *sem_open_SysV(const char *nom, int oflag, ...)
1.6       bertrand  631: //*sem_open(const char *nom, int oflag)
                    632: //*sem_open(const char *nom, int oflag, mode_t mode, unsigned int value)
                    633: {
                    634:    mode_t              mode;
                    635: 
                    636:    sem_t               *semaphore;
                    637: 
1.9       bertrand  638: #  ifndef OS2
1.32      bertrand  639:        int             desc;
1.10      bertrand  640: 
1.32      bertrand  641:        key_t           clef;
1.10      bertrand  642: 
1.32      bertrand  643:        union semun     argument;
1.9       bertrand  644: #  endif
1.6       bertrand  645: 
                    646:    unsigned char       *nom_absolu;
                    647: 
                    648:    unsigned int        valeur;
                    649: 
                    650:    va_list             liste;
                    651: 
1.9       bertrand  652: #  ifdef OS2
1.32      bertrand  653:        sem_t           *psem;
1.9       bertrand  654: 
1.32      bertrand  655:        PVOID           base;
1.9       bertrand  656: 
1.32      bertrand  657:        unsigned char   *ptr;
                    658:        unsigned char   *nom_segment;
1.9       bertrand  659: #  endif
                    660: 
1.32      bertrand  661: #  ifndef OS2 // IPCS_SYSV
                    662:        if ((nom_absolu = malloc((strlen(racine_segment) + strlen(nom)
                    663:                + 2) * sizeof(unsigned char))) == NULL)
                    664:        {
                    665:            return(SEM_FAILED);
                    666:        }
1.6       bertrand  667: 
1.32      bertrand  668:        sprintf(nom_absolu, "%s/%s", racine_segment, nom);
1.6       bertrand  669: 
1.32      bertrand  670:        if ((semaphore = malloc(sizeof(sem_t))) == NULL)
                    671:        {
                    672:            return(SEM_FAILED);
                    673:        }
1.6       bertrand  674: 
1.32      bertrand  675:        (*semaphore).alloue = -1;
1.34      bertrand  676:        (*semaphore).pid = getpid();
                    677:        (*semaphore).tid = pthread_self();
1.9       bertrand  678: #  else
1.39    ! bertrand  679:        if ((nom_segment = malloc((strlen(racine_memoire_OS2) + strlen(nom) + 1)
        !           680:                * sizeof(unsigned char))) == NULL)
        !           681:        {
        !           682:            return(SEM_FAILED);
        !           683:        }   
        !           684: 
        !           685:        sprintf(nom_segment, "%s%s", racine_memoire_OS2, nom);
        !           686:        ptr = nom_segment;
1.9       bertrand  687: 
1.39    ! bertrand  688:        while((*ptr) != d_code_fin_chaine)
        !           689:        {
        !           690:            if ((*ptr) == '/')
        !           691:            {
        !           692:                (*ptr) = '\\';
        !           693:            }
1.9       bertrand  694: 
1.39    ! bertrand  695:            ptr++;
        !           696:        }
1.9       bertrand  697: 
1.39    ! bertrand  698:        if ((nom_absolu = malloc((strlen(racine_semaphores_OS2) + strlen(nom)
        !           699:                + 2) * sizeof(unsigned char))) == NULL)
1.9       bertrand  700:        {
1.39    ! bertrand  701:            return(SEM_FAILED);
1.9       bertrand  702:        }
                    703: 
1.39    ! bertrand  704:        sprintf(nom_absolu, "%s%s", racine_semaphores_OS2, nom);
        !           705:        ptr = nom_absolu;
        !           706: 
        !           707:        while((*ptr) != d_code_fin_chaine)
        !           708:        {
        !           709:            if ((*ptr) == '/')
        !           710:            {
        !           711:                (*ptr) = '\\';
        !           712:            }
1.9       bertrand  713: 
1.39    ! bertrand  714:            ptr++;
        !           715:        }
1.9       bertrand  716: 
1.39    ! bertrand  717:        (*(ptr + 1)) = d_code_fin_chaine;
1.9       bertrand  718: 
1.39    ! bertrand  719:        if ((psem = malloc(sizeof(sem_t))) == NULL)
1.9       bertrand  720:        {
1.39    ! bertrand  721:            return(SEM_FAILED);
1.9       bertrand  722:        }
                    723: 
1.39    ! bertrand  724:        (*psem).allocated = 1;
1.9       bertrand  725: #  endif
                    726: 
1.6       bertrand  727:    if ((oflag & O_CREAT) == 0)
                    728:    {
                    729:        // 2 arguments
1.9       bertrand  730: 
1.32      bertrand  731: #      ifndef OS2 // IPCS_SYSV
                    732:            clef = ftok(nom_absolu, 1);
1.9       bertrand  733: 
1.32      bertrand  734:            if (clef == -1)
                    735:            {
                    736:                return(SEM_FAILED);
                    737:            }
                    738: 
                    739:            (*semaphore).sem = semget(clef, 0, 0);
                    740:            (*semaphore).path = nom_absolu;
                    741:            (*semaphore).pid = getpid();
                    742: 
                    743:            if ((*semaphore).sem == -1)
                    744:            {   
                    745:                free(semaphore);
                    746:                free(nom_absolu);
                    747: 
                    748:                return(SEM_FAILED);
                    749:            }
                    750: #      else // OS/2
1.39    ! bertrand  751:            if ((psem = malloc(sizeof(sem_t))) == NULL)
        !           752:            {
        !           753:                free(nom_absolu);
        !           754:                free(nom_segment);
        !           755:                return(SEM_FAILED);
        !           756:            }
1.9       bertrand  757: 
1.39    ! bertrand  758:            (*ptr) = 'M';
1.9       bertrand  759: 
1.39    ! bertrand  760:            if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0)
        !           761:            {
        !           762:                free(psem);
        !           763:                free(nom_absolu);
        !           764:                free(nom_segment);
1.9       bertrand  765: 
1.39    ! bertrand  766:                return(SEM_FAILED);
        !           767:            }
1.9       bertrand  768: 
1.39    ! bertrand  769:            (*ptr) = 'S';
1.9       bertrand  770: 
1.39    ! bertrand  771:            if (DosOpenEventSem(nom_absolu, &((*psem).hev)) != 0)
        !           772:            {
        !           773:                DosCloseMutexSem((*psem).hmtx);
1.9       bertrand  774: 
1.39    ! bertrand  775:                free(psem);
        !           776:                free(nom_absolu);
        !           777:                free(nom_segment);
1.9       bertrand  778: 
1.39    ! bertrand  779:                return(SEM_FAILED);
        !           780:            }
1.9       bertrand  781: 
1.39    ! bertrand  782:            if (DosGetNamedSharedMem(&base, nom_segment, PAG_WRITE | PAG_READ)
        !           783:                    != 0)
        !           784:            {
        !           785:                DosCloseMutexSem((*psem).hmtx);
1.9       bertrand  786: 
1.39    ! bertrand  787:                free(nom_absolu);
        !           788:                free(nom_segment);
        !           789:                free(psem);
1.9       bertrand  790: 
1.39    ! bertrand  791:                return(SEM_FAILED);
        !           792:            }
1.9       bertrand  793: 
1.39    ! bertrand  794:            free(nom_segment);
1.9       bertrand  795: 
1.39    ! bertrand  796:            (*psem).cnt = (ULONG *) base;
        !           797:            (*psem).nopened = ((ULONG *) base) + 1;
        !           798:            (*psem).shared = 1;
1.9       bertrand  799: 
1.39    ! bertrand  800:            if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
        !           801:            {
        !           802:                DosCloseMutexSem((*psem).hmtx);
1.9       bertrand  803: 
1.39    ! bertrand  804:                free(nom_absolu);
        !           805:                free(nom_segment);
        !           806:                free(psem);
1.9       bertrand  807: 
1.39    ! bertrand  808:                return(SEM_FAILED);
        !           809:            }
1.9       bertrand  810: 
1.39    ! bertrand  811:            (*((*psem).nopened))++;
1.9       bertrand  812: 
1.39    ! bertrand  813:            DosReleaseMutexSem((*psem).hmtx);
1.9       bertrand  814: 
1.39    ! bertrand  815:            semaphore = psem;
1.9       bertrand  816: #      endif
1.6       bertrand  817:    }
                    818:    else
                    819:    {
                    820:        // 4 arguments
                    821: 
                    822:        // O_CREAT O_EXCL
                    823:        // S_IRUSR S_IWUSR
                    824: 
                    825:        va_start(liste, oflag);
                    826:        mode = va_arg(liste, mode_t);
                    827:        valeur = va_arg(liste, unsigned int);
                    828:        va_end(liste);
                    829: 
1.32      bertrand  830: #      ifndef OS2 // IPCS_SYSV
1.33      bertrand  831:            if ((desc = open(nom_absolu, O_CREAT | O_EXCL | O_RDWR,
                    832:                    S_IRUSR | S_IWUSR)) == -1)
1.32      bertrand  833:            {
                    834:                free(semaphore);
                    835:                free(nom_absolu);
                    836: 
                    837:                return(SEM_FAILED);
                    838:            }
                    839: 
                    840:            if ((clef = ftok(nom_absolu, 1)) == -1)
                    841:            {
                    842:                close(desc);
                    843:                free(semaphore);
                    844:                free(nom_absolu);
                    845: 
                    846:                return(SEM_FAILED);
                    847:            }
                    848: 
                    849:            close(desc);
                    850: 
                    851:            (*semaphore).sem = semget(clef, 1,
                    852:                    (((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT) |
                    853:                    (((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL) |
                    854:                    (int) mode);
                    855:            (*semaphore).path = nom_absolu;
                    856:            (*semaphore).pid = getpid();
                    857: 
                    858:            if ((*semaphore).sem == -1)
                    859:            {   
                    860:                free(semaphore);
                    861:                free(nom_absolu);
                    862: 
                    863:                return(SEM_FAILED);
                    864:            }
                    865: 
                    866:            argument.val = valeur;
                    867:            semctl((*semaphore).sem, 0, SETVAL, argument);
                    868: #      else // OS/2
1.39    ! bertrand  869:            if ((psem = malloc(sizeof(sem_t))) == NULL)
        !           870:            {
        !           871:                free(nom_absolu);
        !           872:                free(nom_segment);
1.9       bertrand  873: 
1.39    ! bertrand  874:                return(SEM_FAILED);
        !           875:            }
1.9       bertrand  876: 
1.39    ! bertrand  877:            (*ptr) = 'M';
1.9       bertrand  878: 
1.39    ! bertrand  879:            if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0)
        !           880:            {
        !           881:                free(psem);
        !           882:                free(nom_absolu);
        !           883:                free(nom_segment);
1.9       bertrand  884: 
1.39    ! bertrand  885:                return(SEM_FAILED);
        !           886:            }
1.9       bertrand  887: 
1.39    ! bertrand  888:            (*ptr) = 'S';
1.9       bertrand  889: 
1.39    ! bertrand  890:            if (DosCreateEventSem(nom_absolu, &((*psem).hev), 0,
        !           891:                    (valeur != 0) ? 1 : 0) != 0)
        !           892:            {
        !           893:                DosCloseMutexSem((*psem).hmtx);
1.9       bertrand  894: 
1.39    ! bertrand  895:                free(nom_absolu);
        !           896:                free(nom_segment);
        !           897:                free(psem);
        !           898: 
        !           899:                return(SEM_FAILED);
        !           900:            }
1.9       bertrand  901: 
1.39    ! bertrand  902:            if (DosAllocSharedMem(&base, nom_segment, 2 * sizeof(ULONG),
        !           903:                    PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
        !           904:            {
        !           905:                DosCloseMutexSem((*psem).hmtx);
1.9       bertrand  906: 
1.39    ! bertrand  907:                free(nom_absolu);
        !           908:                free(nom_segment);
        !           909:                free(psem);
1.9       bertrand  910: 
1.39    ! bertrand  911:                return(SEM_FAILED);
        !           912:            }
1.9       bertrand  913: 
                    914:            free(nom_segment);
                    915: 
1.39    ! bertrand  916:            (*psem).cnt = (ULONG *) base;
        !           917:            (*psem).nopened = ((ULONG *) base) + 1;
        !           918:            (*(*psem).cnt) = valeur;
        !           919:            (*(*psem).nopened) = 1;
        !           920:            (*psem).shared = 1;
        !           921:            semaphore = psem;
1.9       bertrand  922: #      endif
1.6       bertrand  923:    }
                    924: 
1.8       bertrand  925:    return(semaphore);
1.6       bertrand  926: }
                    927: 
                    928: int
1.8       bertrand  929: sem_close_SysV(sem_t *semaphore)
1.6       bertrand  930: {
1.11      bertrand  931:    // Ferme un sémaphore nommé créé par sem_open_SysV()
1.32      bertrand  932: #  ifndef OS2 // IPCS_SYSV
                    933:        if ((*semaphore).path != NULL)
                    934:        {
                    935:            free((*semaphore).path);
                    936:        }
1.9       bertrand  937: 
1.32      bertrand  938:        if ((*semaphore).alloue == -1)
                    939:        {
                    940:            free(semaphore);
                    941:        }
1.9       bertrand  942: 
1.32      bertrand  943:        return(0);
1.9       bertrand  944: #  else
1.39    ! bertrand  945:        sem_t       *psem;
1.9       bertrand  946: 
1.39    ! bertrand  947:        psem = semaphore;
1.9       bertrand  948: 
1.39    ! bertrand  949:        if (DosCloseMutexSem((*psem).hmtx) != 0)
        !           950:        {
        !           951:            return(EINVAL);
        !           952:        }
1.9       bertrand  953: 
1.39    ! bertrand  954:        while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
        !           955:        {
        !           956:            DosPostEventSem((*psem).hev);
        !           957:        }
1.9       bertrand  958: 
1.39    ! bertrand  959:        (*(*psem).nopened)--;
1.9       bertrand  960: 
1.39    ! bertrand  961:        if ((*psem).shared == 0)
        !           962:        {
        !           963:            free((*psem).cnt);
        !           964:            free((*psem).nopened);
        !           965:        }
        !           966:        else
        !           967:        {
        !           968:            if ((*(*psem).nopened) == 0)
        !           969:            {
        !           970:                DosFreeMem((*psem).cnt);
        !           971:            }
        !           972:        }
1.9       bertrand  973: 
1.39    ! bertrand  974:        if ((*psem).allocated != 0)
1.9       bertrand  975:        {
1.39    ! bertrand  976:            free(psem);
1.9       bertrand  977:        }
                    978: 
1.39    ! bertrand  979:        return(0);
1.9       bertrand  980: #  endif
1.6       bertrand  981: }
                    982: 
                    983: int
1.8       bertrand  984: sem_unlink_SysV(const char *nom)
1.6       bertrand  985: {
1.11      bertrand  986:    // Détruit un sémaphore nommé créé par sem_open_SysV()
1.32      bertrand  987: #  ifndef OS2 // IPCS_SYSV
1.37      bertrand  988:        semctl(semget(ftok(nom, 1), 0, 0), 0, IPC_RMID);
1.6       bertrand  989: 
1.37      bertrand  990:        if (unlink(nom) == -1)
1.32      bertrand  991:        {
1.38      bertrand  992:            free(nom_absolu);
1.32      bertrand  993:            return(EACCES);
                    994:        }
1.6       bertrand  995: 
1.38      bertrand  996:        free(nom);
1.32      bertrand  997:        return(0);
1.9       bertrand  998: #  else
1.39    ! bertrand  999:        return(0);
1.9       bertrand 1000: #  endif
1.6       bertrand 1001: }
                   1002: 
                   1003: #endif
                   1004: 
1.1       bertrand 1005: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>