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

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

CVSweb interface <joel.bertrand@systella.fr>