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

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

CVSweb interface <joel.bertrand@systella.fr>