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

1.1       bertrand    1: /*
                      2: ================================================================================
1.5       bertrand    3:   RPL/2 (R) version 4.0.18
1.1       bertrand    4:   Copyright (C) 1989-2010 Dr. BERTRAND Joël
                      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.1       bertrand   25: #ifdef SEMAPHORES_NOMMES
                     26: 
                     27: /*
                     28: ================================================================================
                     29:   Fonctions d'émulation de sémaphores anonymes
                     30: ================================================================================
                     31:   Entrées :
                     32: --------------------------------------------------------------------------------
                     33:   Sorties :
                     34: --------------------------------------------------------------------------------
                     35:   Effets de bord : néant
                     36: ================================================================================
                     37: */
                     38: 
                     39: sem_t *
                     40: sem_init2(unsigned int valeur, enum t_semaphore semaphore)
                     41: {
                     42:    snprintf(noms_semaphores[semaphore], LONGUEUR_NOM_SEMAPHORE,
                     43:            "/RPLSEM-%d-%llu-%d", (int) getpid(),
                     44:            (unsigned long long) pthread_self(),
                     45:            (int) semaphore);
                     46:    return(sem_open(noms_semaphores[semaphore], O_CREAT,
                     47:            (S_IRUSR | S_IWUSR), valeur));
                     48: }
                     49: 
                     50: int
                     51: sem_destroy2(sem_t *semaphore_p, enum t_semaphore semaphore)
                     52: {
                     53:    sem_close(semaphore_p);
                     54:    return(sem_unlink(noms_semaphores[semaphore]));
                     55: }
                     56: 
                     57: #undef sem_post
                     58: #undef sem_wait
                     59: #undef sem_trywait
                     60: 
                     61: int
                     62: sem_getvalue2(sem_t *semaphore, int *valeur)
                     63: {
                     64:    int                     i;
                     65: 
                     66:    logical1                drapeau_fin;
                     67: 
                     68:    pthread_mutex_lock(&mutex_sem);
                     69: 
                     70:    (*valeur) = 0;
                     71:    drapeau_fin = d_faux;
                     72: 
                     73:    do
                     74:    {
                     75:        if (sem_trywait(semaphore) == -1)
                     76:        {
                     77:            if (errno == EAGAIN)
                     78:            {
                     79:                // Le sémaphore avait une valeur nulle
                     80:                drapeau_fin = d_vrai;
                     81:            }
                     82:            else
                     83:            {
                     84:                // Autre erreur
                     85:                pthread_mutex_unlock(&mutex_sem);
                     86:                return(-1);
                     87:            }
                     88:        }
                     89:        else
                     90:        {
                     91:            (*valeur)++;
                     92:        }
                     93:    } while(drapeau_fin == d_faux);
                     94: 
                     95:    for(i = 0; i < (*valeur); i++)
                     96:    {
                     97:        if (sem_post(semaphore) != 0)
                     98:        {
                     99:            pthread_mutex_unlock(&mutex_sem);
                    100:            return(-1);
                    101:        }
                    102:    }
                    103: 
                    104:    pthread_mutex_unlock(&mutex_sem);
                    105:    return(0);
                    106: }
                    107: 
                    108: #endif
                    109: 
1.8     ! bertrand  110: #ifdef SEMAPHORES_SYSV
1.6       bertrand  111: 
                    112: /*
                    113: ================================================================================
                    114:   Fonctions d'émulation de sémaphores POSIX en fonction des sémaphores SysV
                    115: ================================================================================
                    116:   Entrées :
                    117: --------------------------------------------------------------------------------
                    118:   Sorties :
                    119: --------------------------------------------------------------------------------
                    120:   Effets de bord : néant
                    121: ================================================================================
                    122: */
                    123: 
                    124: extern unsigned char *chemin_semaphores_SysV;
                    125: 
1.8     ! bertrand  126: #ifndef UNION_SEMUN
        !           127: union semun
        !           128: {
        !           129:    int                 val;
        !           130:    struct semid_ds     *buf;
        !           131:    unsigned short      *array;
        !           132:    struct seminfo      *__buf;
        !           133: };
        !           134: #endif
        !           135: 
1.6       bertrand  136: int
1.8     ! bertrand  137: sem_init_SysV(sem_t *semaphore, int shared, unsigned int valeur)
1.6       bertrand  138: {
1.8     ! bertrand  139:    int             ios;
        !           140: 
1.6       bertrand  141:    union semun     argument;
                    142: 
                    143:    if (shared != 0)
                    144:    {
                    145:        return(ENOSYS);
                    146:    }
                    147: 
                    148:    (*semaphore) = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | SEM_R | SEM_A);
                    149: 
                    150:    if ((*semaphore) == -1)
                    151:    {
                    152:        return(EINVAL);
                    153:    }
                    154: 
                    155:    argument.val = valeur;
1.8     ! bertrand  156:    ios = semctl((*semaphore), 0, SETVAL, argument);
1.6       bertrand  157: 
1.8     ! bertrand  158:    return(ios);
1.6       bertrand  159: }
                    160: 
                    161: int
1.8     ! bertrand  162: sem_destroy_SysV(sem_t *semaphore)
1.6       bertrand  163: {
                    164:    if (semctl((*semaphore), IPC_RMID, 0) == -1)
                    165:    {
                    166:        return(EINVAL);
                    167:    }
                    168: 
                    169:    return(0);
                    170: }
                    171: 
                    172: int
1.8     ! bertrand  173: sem_wait_SysV(sem_t *semaphore)
1.6       bertrand  174: {
                    175:    struct sembuf       commande;
                    176: 
                    177:    commande.sem_num = 0;
                    178:    commande.sem_op = -1;
                    179:    commande.sem_flg = 0;
                    180: 
                    181:    if (semop((*semaphore), &commande, 1) == -1)
                    182:    {
                    183:        return(EINVAL);
                    184:    }
                    185: 
                    186:    return(0);
                    187: }
                    188: 
                    189: int
1.8     ! bertrand  190: sem_trywait_SysV(sem_t *semaphore)
1.6       bertrand  191: {
                    192:    struct sembuf       commande;
                    193: 
                    194:    commande.sem_num = 0;
                    195:    commande.sem_op = -1;
                    196:    commande.sem_flg = IPC_NOWAIT;
                    197: 
                    198:    if (semop((*semaphore), &commande, 1) == -1)
                    199:    {
                    200:        if (errno == EAGAIN)
                    201:        {
                    202:            return(EAGAIN);
                    203:        }
                    204: 
                    205:        return(EINVAL);
                    206:    }
                    207: 
                    208:    return(0);
                    209: }
                    210: 
                    211: int
1.8     ! bertrand  212: sem_post_SysV(sem_t *semaphore)
1.6       bertrand  213: {
                    214:    struct sembuf       commande;
                    215: 
                    216:    commande.sem_num = 0;
                    217:    commande.sem_op = 1;
                    218:    commande.sem_flg = 0;
                    219: 
                    220:    if (semop((*semaphore), &commande, 1) == -1)
                    221:    {
                    222:        return(EINVAL);
                    223:    }
                    224: 
                    225:    return(0);
                    226: }
                    227: 
                    228: int
1.8     ! bertrand  229: sem_getvalue_SysV(sem_t *semaphore, int *valeur)
1.6       bertrand  230: {
                    231:    (*valeur) = semctl((*semaphore), 0, GETVAL);
                    232: 
                    233:    if ((*valeur) < 0)
                    234:    {
                    235:        return(EINVAL);
                    236:    }
                    237: 
                    238:    return(0);
                    239: }
                    240: 
                    241: sem_t
1.8     ! bertrand  242: *sem_open_SysV(const char *nom, int oflag, ...)
1.6       bertrand  243: //*sem_open(const char *nom, int oflag)
                    244: //*sem_open(const char *nom, int oflag, mode_t mode, unsigned int value)
                    245: {
                    246:    mode_t              mode;
                    247: 
                    248:    sem_t               *semaphore;
                    249: 
                    250:    union semun         argument;
                    251: 
                    252:    unsigned char       *nom_absolu;
                    253: 
                    254:    unsigned int        valeur;
                    255: 
                    256:    va_list             liste;
                    257: 
                    258:    if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom)
                    259:            + 1) * sizeof(unsigned char))) == NULL)
                    260:    {
                    261:        return(SEM_FAILED);
                    262:    }
                    263: 
                    264:    sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom);
                    265: 
                    266:    if ((semaphore = malloc(sizeof(sem_t))) == NULL)
                    267:    {
                    268:        return(SEM_FAILED);
                    269:    }
                    270: 
                    271:    if ((oflag & O_CREAT) == 0)
                    272:    {
                    273:        // 2 arguments
                    274:        (*semaphore) = semget(ftok(nom_absolu, 1), 0, 0);
                    275: 
                    276:        if ((*semaphore) == -1)
                    277:        {   
                    278:            free(semaphore);
                    279:            free(nom_absolu);
                    280: 
                    281:            return(SEM_FAILED);
                    282:        }
                    283:    }
                    284:    else
                    285:    {
                    286:        // 4 arguments
                    287: 
                    288:        // O_CREAT O_EXCL
                    289:        // S_IRUSR S_IWUSR
                    290: 
                    291:        va_start(liste, oflag);
                    292:        mode = va_arg(liste, mode_t);
                    293:        valeur = va_arg(liste, unsigned int);
                    294:        va_end(liste);
                    295: 
                    296:        (*semaphore) = semget(ftok(nom_absolu, 1), 1,
                    297:                ((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT |
                    298:                ((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL |
                    299:                ((oflag & S_IRUSR) == 0) ? 0 : SEM_R |
                    300:                ((oflag & S_IWUSR) == 0) ? 0 : SEM_A);
                    301: 
                    302:        if ((*semaphore) == -1)
                    303:        {   
                    304:            free(semaphore);
                    305:            free(nom_absolu);
                    306: 
                    307:            return(SEM_FAILED);
                    308:        }
                    309: 
                    310:        argument.val = valeur;
                    311:        semctl((*semaphore), 0, SETVAL, argument);
                    312:    }
                    313: 
                    314:    free(nom_absolu);
                    315: 
1.8     ! bertrand  316:    return(semaphore);
1.6       bertrand  317: }
                    318: 
                    319: int
1.8     ! bertrand  320: sem_close_SysV(sem_t *semaphore)
1.6       bertrand  321: {
                    322:    free(semaphore);
                    323:    return(0);
                    324: }
                    325: 
                    326: int
1.8     ! bertrand  327: sem_unlink_SysV(const char *nom)
1.6       bertrand  328: {
                    329:    sem_t               semaphore;
                    330: 
                    331:    struct sembuf       commande;
                    332: 
                    333:    unsigned char       *nom_absolu;
                    334: 
                    335:    if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom)
                    336:            + 1) * sizeof(unsigned char))) == NULL)
                    337:    {
                    338:        return(ENOMEM);
                    339:    }
                    340: 
                    341:    sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom);
                    342: 
                    343:    if ((semaphore = semget(ftok(nom_absolu, 1), 0, 0)) == -1)
                    344:    {   
                    345:        free(nom_absolu);
                    346:        return(EINVAL);
                    347:    }
                    348: 
                    349:    commande.sem_num = 0;
                    350:    commande.sem_op = 0;
                    351:    commande.sem_flg = 0;
                    352: 
                    353:    if (semop(semaphore, &commande, 1) == -1)
                    354:    {
                    355:        free(nom_absolu);
                    356:        return(EINVAL);
                    357:    }
                    358: 
                    359:    if (semctl(semaphore, IPC_RMID, 0) == -1)
                    360:    {
                    361:        free(nom_absolu);
                    362:        return(EINVAL);
                    363:    }
                    364: 
                    365:    if (unlink(nom_absolu) == -1)
                    366:    {
                    367:        free(nom_absolu);
                    368:        return(EACCES);
                    369:    }
                    370: 
                    371:    free(nom_absolu);
                    372: 
                    373:    return(0);
                    374: }
                    375: 
                    376: #endif
                    377: 
1.1       bertrand  378: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>