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

1.1       bertrand    1: /*
                      2: ================================================================================
1.45      bertrand    3:   RPL/2 (R) version 4.1.9
1.41      bertrand    4:   Copyright (C) 1989-2012 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",
1.47    ! bertrand  302:                    racine_segment, (int) getpid(),
        !           303:                    (long long unsigned) pthread_self(), shared);
1.32      bertrand  304: 
1.33      bertrand  305:            if ((desc = open((*semaphore).path, O_RDWR | O_CREAT | O_EXCL,
1.32      bertrand  306:                    S_IRUSR | S_IWUSR)) == -1)
                    307:            {
                    308:                free((*semaphore).path);
                    309:                return(-1);
                    310:            }
                    311: 
                    312:            (*semaphore).pid = getpid();
1.37      bertrand  313:            (*semaphore).tid = pthread_self();
1.32      bertrand  314:            clef = ftok((*semaphore).path, 1);
                    315:            close(desc);
                    316: 
                    317:            if (clef == -1)
                    318:            {
                    319:                free((*semaphore).path);
                    320:                return(-1);
                    321:            }
                    322: 
                    323:            (*semaphore).alloue = 0;
                    324:            (*semaphore).sem = semget(clef, 1, IPC_CREAT | IPC_EXCL |
                    325:                    S_IRUSR | S_IWUSR);
                    326:        }
1.8       bertrand  327: 
1.32      bertrand  328:        if ((*semaphore).sem == -1)
                    329:        {
                    330:            errno = EINVAL;
                    331:            return(-1);
                    332:        }
1.6       bertrand  333: 
1.32      bertrand  334:        argument.val = valeur;
                    335:        ios = semctl((*semaphore).sem, 0, SETVAL, argument);
1.6       bertrand  336: 
1.32      bertrand  337:        return(ios);
                    338: #  else // OS/2
1.39      bertrand  339:        sem_t           *psem;
1.9       bertrand  340: 
1.39      bertrand  341:        psem = semaphore;
1.9       bertrand  342: 
1.39      bertrand  343:        if (((*psem).cnt = malloc(sizeof(ULONG))) == NULL)
                    344:        {
                    345:            free(psem);
                    346:            errno = ENOMEM;
                    347:            return(-1);
                    348:        }
1.9       bertrand  349: 
1.39      bertrand  350:        if (((*psem).nopened = malloc(sizeof(ULONG))) == NULL)
                    351:        {
                    352:            free((*psem).cnt);
                    353:            free(psem);
                    354:            errno = ENOMEM;
                    355:            return(-1);
                    356:        }
1.9       bertrand  357: 
1.39      bertrand  358:        if (DosCreateMutexSem(NULL, &((*psem).hmtx), 0, 0) != 0)
                    359:        {
                    360:            free((*psem).cnt);
                    361:            free((*psem).nopened);
                    362:            free(psem);
                    363:            return(-1);
                    364:        }
1.9       bertrand  365: 
1.39      bertrand  366:        if (DosCreateEventSem(NULL, &((*psem).hev), 0, (valeur != 0) ? 1 : 0)
                    367:                != 0)
                    368:        {
                    369:            DosCloseMutexSem((*psem).hmtx);
                    370:            free((*psem).cnt);
                    371:            free((*psem).nopened);
                    372:            free(psem);
                    373:            return(-1);
                    374:        }
1.9       bertrand  375: 
1.39      bertrand  376:        (*(*psem).cnt) = valeur;
                    377:        (*(*psem).nopened) = 1;
                    378:        (*psem).shared = shared;
                    379:        (*psem).allocated = 0;
1.9       bertrand  380: 
1.39      bertrand  381:        return(0);
1.9       bertrand  382: #  endif
1.6       bertrand  383: }
                    384: 
                    385: int
1.8       bertrand  386: sem_destroy_SysV(sem_t *semaphore)
1.6       bertrand  387: {
1.11      bertrand  388:    // Détruit un sémaphore anonmyme
1.9       bertrand  389: 
1.32      bertrand  390: #  ifndef OS2 // IPCS_SYSV
                    391:        if ((*semaphore).path != NULL)
                    392:        {
                    393:            return(EINVAL);
                    394:        }
1.11      bertrand  395: 
1.32      bertrand  396:        if ((*semaphore).pid != getpid())
                    397:        {
                    398:            return(0);
                    399:        }
1.11      bertrand  400: 
1.32      bertrand  401:        if (semctl((*semaphore).sem, 0, IPC_RMID) == -1)
                    402:        {
                    403:            return(EINVAL);
                    404:        }
1.6       bertrand  405: 
1.32      bertrand  406:        return(0);
                    407: #  else // OS/2
1.39      bertrand  408:        sem_t       *psem;
1.9       bertrand  409: 
1.39      bertrand  410:        psem = semaphore;
1.9       bertrand  411: 
1.39      bertrand  412:        if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
                    413:        {
                    414:            return(EINVAL);
                    415:        }
1.9       bertrand  416: 
1.39      bertrand  417:        if (DosCloseMutexSem((*psem).hmtx) != 0)
                    418:        {
                    419:            return(EINVAL);
                    420:        }
1.9       bertrand  421: 
1.39      bertrand  422:        while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
                    423:        {
                    424:            DosPostEventSem((*psem).hev);
                    425:        }
1.9       bertrand  426: 
1.39      bertrand  427:        (*(*psem).nopened)--;
1.9       bertrand  428: 
1.39      bertrand  429:        if ((*psem).shared == 0)
1.9       bertrand  430:        {
1.39      bertrand  431:            free((*psem).cnt);
                    432:            free((*psem).nopened);
                    433:        }
                    434:        else
                    435:        {
                    436:            if ((*(*psem).nopened) == 0)
                    437:            {
                    438:                DosFreeMem((*psem).cnt);
                    439:            }
1.9       bertrand  440:        }
                    441: 
1.39      bertrand  442:        if ((*psem).allocated != 0)
                    443:        {   
                    444:            free(psem);
                    445:        }
1.9       bertrand  446: 
1.39      bertrand  447:        return(0);
1.9       bertrand  448: #  endif
1.6       bertrand  449: }
                    450: 
                    451: int
1.8       bertrand  452: sem_wait_SysV(sem_t *semaphore)
1.6       bertrand  453: {
1.32      bertrand  454: #  ifndef OS2 // IPCS_SYSV
                    455:        struct sembuf       commande;
1.9       bertrand  456: 
1.32      bertrand  457:        commande.sem_num = 0;
                    458:        commande.sem_op = -1;
                    459:        commande.sem_flg = 0;
                    460: 
                    461:        while(semop((*semaphore).sem, &commande, 1) == -1)
                    462:        {
                    463:            if (errno != EINTR)
                    464:            {
                    465:                errno = EINVAL;
                    466:                return(-1);
                    467:            }
1.11      bertrand  468:        }
1.9       bertrand  469: 
1.32      bertrand  470:        return(0);
                    471: #  else // OS/2
1.39      bertrand  472:        sem_t       *psem;
1.9       bertrand  473: 
1.39      bertrand  474:        ULONG       cnt;
1.9       bertrand  475: 
1.39      bertrand  476:        psem = semaphore;
1.9       bertrand  477: 
1.39      bertrand  478:        if (DosWaitEventSem((*psem).hev, SEM_INDEFINITE_WAIT) != 0)
                    479:        {
                    480:            errno = EINVAL;
                    481:            return(-1);
                    482:        }
1.9       bertrand  483: 
1.39      bertrand  484:        if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
                    485:        {
                    486:            errno = EINVAL;
                    487:            return(-1);
                    488:        }
1.9       bertrand  489: 
1.39      bertrand  490:        if ((*(*psem).cnt) > 0)
                    491:        {
                    492:            (*(*psem).cnt)--;
                    493:        }
1.9       bertrand  494: 
1.39      bertrand  495:        if ((*(*psem).cnt) == 0)
                    496:        {
                    497:            DosResetEventSem((*psem).hev, &cnt);
                    498:        }
1.9       bertrand  499: 
1.39      bertrand  500:        DosReleaseMutexSem((*psem).hmtx);
                    501:        return(0);
1.9       bertrand  502: #  endif
1.6       bertrand  503: }
                    504: 
                    505: int
1.8       bertrand  506: sem_trywait_SysV(sem_t *semaphore)
1.6       bertrand  507: {
1.32      bertrand  508: #  ifndef OS2 // IPCS_SYSV
                    509:        struct sembuf       commande;
1.6       bertrand  510: 
1.32      bertrand  511:        commande.sem_num = 0;
                    512:        commande.sem_op = -1;
                    513:        commande.sem_flg = IPC_NOWAIT;
                    514: 
                    515:        while(semop((*semaphore).sem, &commande, 1) == -1)
                    516:        {
                    517:            if (errno != EINTR)
                    518:            {
                    519:                errno = EINVAL;
                    520:                return(-1);
                    521:            }
1.11      bertrand  522:        }
1.9       bertrand  523: 
1.32      bertrand  524:        return(0);
                    525: #  else // OS/2
1.39      bertrand  526:        int         ios;
1.9       bertrand  527: 
1.39      bertrand  528:        sem_t       *psem;
1.9       bertrand  529: 
1.39      bertrand  530:        ULONG       cnt;
1.9       bertrand  531: 
1.39      bertrand  532:        psem = semaphore;
1.9       bertrand  533: 
1.39      bertrand  534:        if ((ios = DosWaitEventSem((*psem).hev, SEM_IMMEDIATE_RETURN)) != 0)
                    535:        {
                    536:            errno = (ios == ERROR_TIMEOUT) ? EAGAIN : EINVAL;
                    537:            return(-1);
                    538:        }
1.9       bertrand  539: 
1.39      bertrand  540:        if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
                    541:        {
                    542:            errno = EINVAL;
                    543:            return(-1);
                    544:        }
1.9       bertrand  545: 
1.39      bertrand  546:        if ((*(*psem).cnt) > 0)
                    547:        {
                    548:            (*(*psem).cnt)--;
                    549:        }
1.9       bertrand  550: 
1.39      bertrand  551:        if ((*(*psem).cnt) == 0)
                    552:        {
                    553:            DosResetEventSem((*psem).hev, &cnt);
                    554:        }
1.9       bertrand  555: 
1.39      bertrand  556:        DosReleaseMutexSem((*psem).hmtx);
                    557:        return(0);
1.9       bertrand  558: #  endif
1.6       bertrand  559: }
                    560: 
1.47    ! bertrand  561: #ifndef timespeccmp
        !           562: #  define timespeccmp(tsp, usp, cmp) \
        !           563:            (((tsp)->tv_sec == (usp)->tv_sec) ? \
        !           564:            ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
        !           565:            ((tsp)->tv_sec cmp (usp)->tv_sec))
        !           566: #  define timespecadd(tsp, usp, vsp) \
        !           567:            do { \
        !           568:                (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \
        !           569:                (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \
        !           570:                if ((vsp)->tv_nsec >= 1000000000L) { \
        !           571:                    (vsp)->tv_sec++; \
        !           572:                    (vsp)->tv_nsec -= 1000000000L; \
        !           573:                } \
        !           574:            } while(0)
        !           575: #  define timespecsub(tsp, usp, vsp) \
        !           576:            do { \
        !           577:                (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \
        !           578:                (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \
        !           579:                if ((vsp)->tv_nsec < 0) { \
        !           580:                    (vsp)->tv_sec--; \
        !           581:                    (vsp)->tv_nsec += 1000000000L; \
        !           582:                } \
        !           583:            } while(0)
        !           584: #endif
        !           585: 
        !           586: int
        !           587: sem_timedwait_SysV(sem_t *sem, struct timespec *ts)
        !           588: {
        !           589:    struct timespec onems = { 0, 1000000 };
        !           590:    struct timespec total = { 0, 0 };
        !           591:    struct timespec unslept;
        !           592:    struct timespec elapsed;
        !           593:    struct timespec tmp;
        !           594: 
        !           595:    while(timespeccmp(ts, &total, >))
        !           596:    {
        !           597:        if (sem_trywait_SysV(sem) == 0)
        !           598:        {
        !           599:            return(0);
        !           600:        }
        !           601: 
        !           602:        if (errno != EAGAIN)
        !           603:        {
        !           604:            return(-1);
        !           605:        }
        !           606: 
        !           607:        nanosleep(&onems, &unslept);
        !           608: 
        !           609:        timespecsub(&onems, &unslept, &elapsed);
        !           610:        timespecadd(&total, &elapsed, &tmp);
        !           611:        total.tv_sec = tmp.tv_sec;
        !           612:        total.tv_nsec = tmp.tv_nsec;
        !           613:    }
        !           614: 
        !           615:    errno = ETIMEDOUT;
        !           616:    return(-1);
        !           617: }
        !           618: 
1.6       bertrand  619: int
1.8       bertrand  620: sem_post_SysV(sem_t *semaphore)
1.6       bertrand  621: {
1.32      bertrand  622: #  ifndef OS2 // IPCS_SYSV
                    623:        struct sembuf       commande;
1.9       bertrand  624: 
1.32      bertrand  625:        commande.sem_num = 0;
                    626:        commande.sem_op = 1;
                    627:        commande.sem_flg = 0;
                    628: 
                    629:        while(semop((*semaphore).sem, &commande, 1) == -1)
                    630:        {
                    631:            if (errno != EINTR)
                    632:            {
                    633:                errno = EINVAL;
                    634:                return(-1);
                    635:            }
1.11      bertrand  636:        }
1.9       bertrand  637: 
1.32      bertrand  638:        return(0);
                    639: #  else // OS/2
1.39      bertrand  640:        sem_t               *psem;
1.9       bertrand  641: 
1.39      bertrand  642:        psem = semaphore;
1.9       bertrand  643: 
1.39      bertrand  644:        if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
                    645:        {
                    646:            errno = EINVAL;
                    647:            return(-1);
                    648:        }
1.9       bertrand  649: 
1.39      bertrand  650:        (*(*psem).cnt)++;
                    651:        DosPostEventSem((*psem).hev);
                    652:        DosReleaseMutexSem((*psem).hmtx);
1.9       bertrand  653: 
1.39      bertrand  654:        return(0);
1.9       bertrand  655: #  endif
1.6       bertrand  656: }
                    657: 
                    658: int
1.8       bertrand  659: sem_getvalue_SysV(sem_t *semaphore, int *valeur)
1.6       bertrand  660: {
1.32      bertrand  661: #  ifndef OS2 // IPCS_SYSV
                    662:        (*valeur) = semctl((*semaphore).sem, 0, GETVAL);
1.9       bertrand  663: 
1.32      bertrand  664:        if ((*valeur) < 0)
                    665:        {
                    666:            return(EINVAL);
                    667:        }
1.9       bertrand  668: 
1.32      bertrand  669:        return(0);
1.9       bertrand  670: #  else
1.39      bertrand  671:        sem_t               *psem;
1.9       bertrand  672: 
1.39      bertrand  673:        psem = semaphore;
1.9       bertrand  674: 
1.39      bertrand  675:        if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
                    676:        {
                    677:            errno = EINVAL;
                    678:            return(-1);
                    679:        }
1.9       bertrand  680: 
1.39      bertrand  681:        (*valeur) = (*(*psem).cnt);
                    682:        DosReleaseMutexSem((*psem).hmtx);
1.9       bertrand  683: 
1.39      bertrand  684:        return(0);
1.9       bertrand  685: #  endif
1.6       bertrand  686: }
                    687: 
                    688: sem_t
1.8       bertrand  689: *sem_open_SysV(const char *nom, int oflag, ...)
1.6       bertrand  690: //*sem_open(const char *nom, int oflag)
                    691: //*sem_open(const char *nom, int oflag, mode_t mode, unsigned int value)
                    692: {
                    693:    mode_t              mode;
                    694: 
                    695:    sem_t               *semaphore;
                    696: 
1.9       bertrand  697: #  ifndef OS2
1.32      bertrand  698:        int             desc;
1.10      bertrand  699: 
1.32      bertrand  700:        key_t           clef;
1.10      bertrand  701: 
1.32      bertrand  702:        union semun     argument;
1.9       bertrand  703: #  endif
1.6       bertrand  704: 
                    705:    unsigned char       *nom_absolu;
                    706: 
                    707:    unsigned int        valeur;
                    708: 
                    709:    va_list             liste;
                    710: 
1.9       bertrand  711: #  ifdef OS2
1.32      bertrand  712:        sem_t           *psem;
1.9       bertrand  713: 
1.32      bertrand  714:        PVOID           base;
1.9       bertrand  715: 
1.32      bertrand  716:        unsigned char   *ptr;
                    717:        unsigned char   *nom_segment;
1.9       bertrand  718: #  endif
                    719: 
1.32      bertrand  720: #  ifndef OS2 // IPCS_SYSV
                    721:        if ((nom_absolu = malloc((strlen(racine_segment) + strlen(nom)
                    722:                + 2) * sizeof(unsigned char))) == NULL)
                    723:        {
                    724:            return(SEM_FAILED);
                    725:        }
1.6       bertrand  726: 
1.32      bertrand  727:        sprintf(nom_absolu, "%s/%s", racine_segment, nom);
1.6       bertrand  728: 
1.32      bertrand  729:        if ((semaphore = malloc(sizeof(sem_t))) == NULL)
                    730:        {
                    731:            return(SEM_FAILED);
                    732:        }
1.6       bertrand  733: 
1.32      bertrand  734:        (*semaphore).alloue = -1;
1.34      bertrand  735:        (*semaphore).pid = getpid();
                    736:        (*semaphore).tid = pthread_self();
1.9       bertrand  737: #  else
1.39      bertrand  738:        if ((nom_segment = malloc((strlen(racine_memoire_OS2) + strlen(nom) + 1)
                    739:                * sizeof(unsigned char))) == NULL)
                    740:        {
                    741:            return(SEM_FAILED);
                    742:        }   
                    743: 
                    744:        sprintf(nom_segment, "%s%s", racine_memoire_OS2, nom);
                    745:        ptr = nom_segment;
1.9       bertrand  746: 
1.39      bertrand  747:        while((*ptr) != d_code_fin_chaine)
                    748:        {
                    749:            if ((*ptr) == '/')
                    750:            {
                    751:                (*ptr) = '\\';
                    752:            }
1.9       bertrand  753: 
1.39      bertrand  754:            ptr++;
                    755:        }
1.9       bertrand  756: 
1.39      bertrand  757:        if ((nom_absolu = malloc((strlen(racine_semaphores_OS2) + strlen(nom)
                    758:                + 2) * sizeof(unsigned char))) == NULL)
1.9       bertrand  759:        {
1.39      bertrand  760:            return(SEM_FAILED);
1.9       bertrand  761:        }
                    762: 
1.39      bertrand  763:        sprintf(nom_absolu, "%s%s", racine_semaphores_OS2, nom);
                    764:        ptr = nom_absolu;
                    765: 
                    766:        while((*ptr) != d_code_fin_chaine)
                    767:        {
                    768:            if ((*ptr) == '/')
                    769:            {
                    770:                (*ptr) = '\\';
                    771:            }
1.9       bertrand  772: 
1.39      bertrand  773:            ptr++;
                    774:        }
1.9       bertrand  775: 
1.39      bertrand  776:        (*(ptr + 1)) = d_code_fin_chaine;
1.9       bertrand  777: 
1.39      bertrand  778:        if ((psem = malloc(sizeof(sem_t))) == NULL)
1.9       bertrand  779:        {
1.39      bertrand  780:            return(SEM_FAILED);
1.9       bertrand  781:        }
                    782: 
1.39      bertrand  783:        (*psem).allocated = 1;
1.9       bertrand  784: #  endif
                    785: 
1.6       bertrand  786:    if ((oflag & O_CREAT) == 0)
                    787:    {
                    788:        // 2 arguments
1.9       bertrand  789: 
1.32      bertrand  790: #      ifndef OS2 // IPCS_SYSV
                    791:            clef = ftok(nom_absolu, 1);
1.9       bertrand  792: 
1.32      bertrand  793:            if (clef == -1)
                    794:            {
                    795:                return(SEM_FAILED);
                    796:            }
                    797: 
                    798:            (*semaphore).sem = semget(clef, 0, 0);
                    799:            (*semaphore).path = nom_absolu;
                    800:            (*semaphore).pid = getpid();
                    801: 
                    802:            if ((*semaphore).sem == -1)
                    803:            {   
                    804:                free(semaphore);
                    805:                free(nom_absolu);
                    806: 
                    807:                return(SEM_FAILED);
                    808:            }
                    809: #      else // OS/2
1.39      bertrand  810:            if ((psem = malloc(sizeof(sem_t))) == NULL)
                    811:            {
                    812:                free(nom_absolu);
                    813:                free(nom_segment);
                    814:                return(SEM_FAILED);
                    815:            }
1.9       bertrand  816: 
1.39      bertrand  817:            (*ptr) = 'M';
1.9       bertrand  818: 
1.39      bertrand  819:            if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0)
                    820:            {
                    821:                free(psem);
                    822:                free(nom_absolu);
                    823:                free(nom_segment);
1.9       bertrand  824: 
1.39      bertrand  825:                return(SEM_FAILED);
                    826:            }
1.9       bertrand  827: 
1.39      bertrand  828:            (*ptr) = 'S';
1.9       bertrand  829: 
1.39      bertrand  830:            if (DosOpenEventSem(nom_absolu, &((*psem).hev)) != 0)
                    831:            {
                    832:                DosCloseMutexSem((*psem).hmtx);
1.9       bertrand  833: 
1.39      bertrand  834:                free(psem);
                    835:                free(nom_absolu);
                    836:                free(nom_segment);
1.9       bertrand  837: 
1.39      bertrand  838:                return(SEM_FAILED);
                    839:            }
1.9       bertrand  840: 
1.39      bertrand  841:            if (DosGetNamedSharedMem(&base, nom_segment, PAG_WRITE | PAG_READ)
                    842:                    != 0)
                    843:            {
                    844:                DosCloseMutexSem((*psem).hmtx);
1.9       bertrand  845: 
1.39      bertrand  846:                free(nom_absolu);
                    847:                free(nom_segment);
                    848:                free(psem);
1.9       bertrand  849: 
1.39      bertrand  850:                return(SEM_FAILED);
                    851:            }
1.9       bertrand  852: 
1.39      bertrand  853:            free(nom_segment);
1.9       bertrand  854: 
1.39      bertrand  855:            (*psem).cnt = (ULONG *) base;
                    856:            (*psem).nopened = ((ULONG *) base) + 1;
                    857:            (*psem).shared = 1;
1.9       bertrand  858: 
1.39      bertrand  859:            if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
                    860:            {
                    861:                DosCloseMutexSem((*psem).hmtx);
1.9       bertrand  862: 
1.39      bertrand  863:                free(nom_absolu);
                    864:                free(nom_segment);
                    865:                free(psem);
1.9       bertrand  866: 
1.39      bertrand  867:                return(SEM_FAILED);
                    868:            }
1.9       bertrand  869: 
1.39      bertrand  870:            (*((*psem).nopened))++;
1.9       bertrand  871: 
1.39      bertrand  872:            DosReleaseMutexSem((*psem).hmtx);
1.9       bertrand  873: 
1.39      bertrand  874:            semaphore = psem;
1.9       bertrand  875: #      endif
1.6       bertrand  876:    }
                    877:    else
                    878:    {
                    879:        // 4 arguments
                    880: 
                    881:        // O_CREAT O_EXCL
                    882:        // S_IRUSR S_IWUSR
                    883: 
                    884:        va_start(liste, oflag);
                    885:        mode = va_arg(liste, mode_t);
                    886:        valeur = va_arg(liste, unsigned int);
                    887:        va_end(liste);
                    888: 
1.32      bertrand  889: #      ifndef OS2 // IPCS_SYSV
1.33      bertrand  890:            if ((desc = open(nom_absolu, O_CREAT | O_EXCL | O_RDWR,
                    891:                    S_IRUSR | S_IWUSR)) == -1)
1.32      bertrand  892:            {
                    893:                free(semaphore);
                    894:                free(nom_absolu);
                    895: 
                    896:                return(SEM_FAILED);
                    897:            }
                    898: 
                    899:            if ((clef = ftok(nom_absolu, 1)) == -1)
                    900:            {
                    901:                close(desc);
                    902:                free(semaphore);
                    903:                free(nom_absolu);
                    904: 
                    905:                return(SEM_FAILED);
                    906:            }
                    907: 
                    908:            close(desc);
                    909: 
                    910:            (*semaphore).sem = semget(clef, 1,
                    911:                    (((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT) |
                    912:                    (((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL) |
                    913:                    (int) mode);
                    914:            (*semaphore).path = nom_absolu;
                    915:            (*semaphore).pid = getpid();
                    916: 
                    917:            if ((*semaphore).sem == -1)
                    918:            {   
                    919:                free(semaphore);
                    920:                free(nom_absolu);
                    921: 
                    922:                return(SEM_FAILED);
                    923:            }
                    924: 
                    925:            argument.val = valeur;
                    926:            semctl((*semaphore).sem, 0, SETVAL, argument);
                    927: #      else // OS/2
1.39      bertrand  928:            if ((psem = malloc(sizeof(sem_t))) == NULL)
                    929:            {
                    930:                free(nom_absolu);
                    931:                free(nom_segment);
1.9       bertrand  932: 
1.39      bertrand  933:                return(SEM_FAILED);
                    934:            }
1.9       bertrand  935: 
1.39      bertrand  936:            (*ptr) = 'M';
1.9       bertrand  937: 
1.39      bertrand  938:            if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0)
                    939:            {
                    940:                free(psem);
                    941:                free(nom_absolu);
                    942:                free(nom_segment);
1.9       bertrand  943: 
1.39      bertrand  944:                return(SEM_FAILED);
                    945:            }
1.9       bertrand  946: 
1.39      bertrand  947:            (*ptr) = 'S';
1.9       bertrand  948: 
1.39      bertrand  949:            if (DosCreateEventSem(nom_absolu, &((*psem).hev), 0,
                    950:                    (valeur != 0) ? 1 : 0) != 0)
                    951:            {
                    952:                DosCloseMutexSem((*psem).hmtx);
1.9       bertrand  953: 
1.39      bertrand  954:                free(nom_absolu);
                    955:                free(nom_segment);
                    956:                free(psem);
                    957: 
                    958:                return(SEM_FAILED);
                    959:            }
1.9       bertrand  960: 
1.39      bertrand  961:            if (DosAllocSharedMem(&base, nom_segment, 2 * sizeof(ULONG),
                    962:                    PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
                    963:            {
                    964:                DosCloseMutexSem((*psem).hmtx);
1.9       bertrand  965: 
1.39      bertrand  966:                free(nom_absolu);
                    967:                free(nom_segment);
                    968:                free(psem);
1.9       bertrand  969: 
1.39      bertrand  970:                return(SEM_FAILED);
                    971:            }
1.9       bertrand  972: 
                    973:            free(nom_segment);
                    974: 
1.39      bertrand  975:            (*psem).cnt = (ULONG *) base;
                    976:            (*psem).nopened = ((ULONG *) base) + 1;
                    977:            (*(*psem).cnt) = valeur;
                    978:            (*(*psem).nopened) = 1;
                    979:            (*psem).shared = 1;
                    980:            semaphore = psem;
1.9       bertrand  981: #      endif
1.6       bertrand  982:    }
                    983: 
1.8       bertrand  984:    return(semaphore);
1.6       bertrand  985: }
                    986: 
                    987: int
1.8       bertrand  988: sem_close_SysV(sem_t *semaphore)
1.6       bertrand  989: {
1.11      bertrand  990:    // Ferme un sémaphore nommé créé par sem_open_SysV()
1.32      bertrand  991: #  ifndef OS2 // IPCS_SYSV
                    992:        if ((*semaphore).path != NULL)
                    993:        {
                    994:            free((*semaphore).path);
                    995:        }
1.9       bertrand  996: 
1.32      bertrand  997:        if ((*semaphore).alloue == -1)
                    998:        {
                    999:            free(semaphore);
                   1000:        }
1.9       bertrand 1001: 
1.32      bertrand 1002:        return(0);
1.9       bertrand 1003: #  else
1.39      bertrand 1004:        sem_t       *psem;
1.9       bertrand 1005: 
1.39      bertrand 1006:        psem = semaphore;
1.9       bertrand 1007: 
1.39      bertrand 1008:        if (DosCloseMutexSem((*psem).hmtx) != 0)
                   1009:        {
                   1010:            return(EINVAL);
                   1011:        }
1.9       bertrand 1012: 
1.39      bertrand 1013:        while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
                   1014:        {
                   1015:            DosPostEventSem((*psem).hev);
                   1016:        }
1.9       bertrand 1017: 
1.39      bertrand 1018:        (*(*psem).nopened)--;
1.9       bertrand 1019: 
1.39      bertrand 1020:        if ((*psem).shared == 0)
                   1021:        {
                   1022:            free((*psem).cnt);
                   1023:            free((*psem).nopened);
                   1024:        }
                   1025:        else
                   1026:        {
                   1027:            if ((*(*psem).nopened) == 0)
                   1028:            {
                   1029:                DosFreeMem((*psem).cnt);
                   1030:            }
                   1031:        }
1.9       bertrand 1032: 
1.39      bertrand 1033:        if ((*psem).allocated != 0)
1.9       bertrand 1034:        {
1.39      bertrand 1035:            free(psem);
1.9       bertrand 1036:        }
                   1037: 
1.39      bertrand 1038:        return(0);
1.9       bertrand 1039: #  endif
1.6       bertrand 1040: }
                   1041: 
                   1042: int
1.47    ! bertrand 1043: sem_unlink_SysV(char *nom)
1.6       bertrand 1044: {
1.11      bertrand 1045:    // Détruit un sémaphore nommé créé par sem_open_SysV()
1.32      bertrand 1046: #  ifndef OS2 // IPCS_SYSV
1.37      bertrand 1047:        semctl(semget(ftok(nom, 1), 0, 0), 0, IPC_RMID);
1.6       bertrand 1048: 
1.37      bertrand 1049:        if (unlink(nom) == -1)
1.32      bertrand 1050:        {
                   1051:            return(EACCES);
                   1052:        }
1.6       bertrand 1053: 
1.38      bertrand 1054:        free(nom);
1.32      bertrand 1055:        return(0);
1.9       bertrand 1056: #  else
1.39      bertrand 1057:        return(0);
1.9       bertrand 1058: #  endif
1.6       bertrand 1059: }
                   1060: 
                   1061: #endif
                   1062: 
1.1       bertrand 1063: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>