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

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.6       bertrand  110: #ifdef OS2
                    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: 
                    126: int
                    127: sem_init(sem_t *semaphore, int shared, unsigned int valeur)
                    128: {
                    129:    union semun     argument;
                    130: 
                    131:    if (shared != 0)
                    132:    {
                    133:        return(ENOSYS);
                    134:    }
                    135: 
                    136:    (*semaphore) = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | SEM_R | SEM_A);
                    137: 
                    138:    if ((*semaphore) == -1)
                    139:    {
                    140:        return(EINVAL);
                    141:    }
                    142: 
                    143:    argument.val = valeur;
                    144:    semctl((*semaphore), 0, SETVAL, argument);
                    145: 
                    146:    return(0);
                    147: }
                    148: 
                    149: int
                    150: sem_destroy(sem_t *semaphore)
                    151: {
                    152:    if (semctl((*semaphore), IPC_RMID, 0) == -1)
                    153:    {
                    154:        return(EINVAL);
                    155:    }
                    156: 
                    157:    return(0);
                    158: }
                    159: 
                    160: int
                    161: sem_wait(sem_t *semaphore)
                    162: {
                    163:    struct sembuf       commande;
                    164: 
                    165:    commande.sem_num = 0;
                    166:    commande.sem_op = -1;
                    167:    commande.sem_flg = 0;
                    168: 
                    169:    if (semop((*semaphore), &commande, 1) == -1)
                    170:    {
                    171:        return(EINVAL);
                    172:    }
                    173: 
                    174:    return(0);
                    175: }
                    176: 
                    177: int
                    178: sem_trywait(sem_t *semaphore)
                    179: {
                    180:    struct sembuf       commande;
                    181: 
                    182:    commande.sem_num = 0;
                    183:    commande.sem_op = -1;
                    184:    commande.sem_flg = IPC_NOWAIT;
                    185: 
                    186:    if (semop((*semaphore), &commande, 1) == -1)
                    187:    {
                    188:        if (errno == EAGAIN)
                    189:        {
                    190:            return(EAGAIN);
                    191:        }
                    192: 
                    193:        return(EINVAL);
                    194:    }
                    195: 
                    196:    return(0);
                    197: }
                    198: 
                    199: int
                    200: sem_post(sem_t *semaphore)
                    201: {
                    202:    struct sembuf       commande;
                    203: 
                    204:    commande.sem_num = 0;
                    205:    commande.sem_op = 1;
                    206:    commande.sem_flg = 0;
                    207: 
                    208:    if (semop((*semaphore), &commande, 1) == -1)
                    209:    {
                    210:        return(EINVAL);
                    211:    }
                    212: 
                    213:    return(0);
                    214: }
                    215: 
                    216: int
                    217: sem_getvalue(sem_t *semaphore, int *valeur)
                    218: {
                    219:    (*valeur) = semctl((*semaphore), 0, GETVAL);
                    220: 
                    221:    if ((*valeur) < 0)
                    222:    {
                    223:        return(EINVAL);
                    224:    }
                    225: 
                    226:    return(0);
                    227: }
                    228: 
                    229: sem_t
                    230: *sem_open(const char *nom, int oflag, ...)
                    231: //*sem_open(const char *nom, int oflag)
                    232: //*sem_open(const char *nom, int oflag, mode_t mode, unsigned int value)
                    233: {
                    234:    mode_t              mode;
                    235: 
                    236:    sem_t               *semaphore;
                    237: 
                    238:    union semun         argument;
                    239: 
                    240:    unsigned char       *nom_absolu;
                    241: 
                    242:    unsigned int        valeur;
                    243: 
                    244:    va_list             liste;
                    245: 
                    246:    if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom)
                    247:            + 1) * sizeof(unsigned char))) == NULL)
                    248:    {
                    249:        return(SEM_FAILED);
                    250:    }
                    251: 
                    252:    sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom);
                    253: 
                    254:    if ((semaphore = malloc(sizeof(sem_t))) == NULL)
                    255:    {
                    256:        return(SEM_FAILED);
                    257:    }
                    258: 
                    259:    if ((oflag & O_CREAT) == 0)
                    260:    {
                    261:        // 2 arguments
                    262:        (*semaphore) = semget(ftok(nom_absolu, 1), 0, 0);
                    263: 
                    264:        if ((*semaphore) == -1)
                    265:        {   
                    266:            free(semaphore);
                    267:            free(nom_absolu);
                    268: 
                    269:            return(SEM_FAILED);
                    270:        }
                    271:    }
                    272:    else
                    273:    {
                    274:        // 4 arguments
                    275: 
                    276:        // O_CREAT O_EXCL
                    277:        // S_IRUSR S_IWUSR
                    278: 
                    279:        va_start(liste, oflag);
                    280:        mode = va_arg(liste, mode_t);
                    281:        valeur = va_arg(liste, unsigned int);
                    282:        va_end(liste);
                    283: 
                    284:        (*semaphore) = semget(ftok(nom_absolu, 1), 1,
                    285:                ((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT |
                    286:                ((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL |
                    287:                ((oflag & S_IRUSR) == 0) ? 0 : SEM_R |
                    288:                ((oflag & S_IWUSR) == 0) ? 0 : SEM_A);
                    289: 
                    290:        if ((*semaphore) == -1)
                    291:        {   
                    292:            free(semaphore);
                    293:            free(nom_absolu);
                    294: 
                    295:            return(SEM_FAILED);
                    296:        }
                    297: 
                    298:        argument.val = valeur;
                    299:        semctl((*semaphore), 0, SETVAL, argument);
                    300:    }
                    301: 
                    302:    free(nom_absolu);
                    303: 
                    304:    return(SEM_FAILED);
                    305: }
                    306: 
                    307: int
                    308: sem_close(sem_t *semaphore)
                    309: {
                    310:    free(semaphore);
                    311:    return(0);
                    312: }
                    313: 
                    314: int
                    315: sem_unlink(const char *nom)
                    316: {
                    317:    sem_t               semaphore;
                    318: 
                    319:    struct sembuf       commande;
                    320: 
                    321:    unsigned char       *nom_absolu;
                    322: 
                    323:    if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom)
                    324:            + 1) * sizeof(unsigned char))) == NULL)
                    325:    {
                    326:        return(ENOMEM);
                    327:    }
                    328: 
                    329:    sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom);
                    330: 
                    331:    if ((semaphore = semget(ftok(nom_absolu, 1), 0, 0)) == -1)
                    332:    {   
                    333:        free(nom_absolu);
                    334:        return(EINVAL);
                    335:    }
                    336: 
                    337:    commande.sem_num = 0;
                    338:    commande.sem_op = 0;
                    339:    commande.sem_flg = 0;
                    340: 
                    341:    if (semop(semaphore, &commande, 1) == -1)
                    342:    {
                    343:        free(nom_absolu);
                    344:        return(EINVAL);
                    345:    }
                    346: 
                    347:    if (semctl(semaphore, IPC_RMID, 0) == -1)
                    348:    {
                    349:        free(nom_absolu);
                    350:        return(EINVAL);
                    351:    }
                    352: 
                    353:    if (unlink(nom_absolu) == -1)
                    354:    {
                    355:        free(nom_absolu);
                    356:        return(EACCES);
                    357:    }
                    358: 
                    359:    free(nom_absolu);
                    360: 
                    361:    return(0);
                    362: }
                    363: 
                    364: #endif
                    365: 
1.1       bertrand  366: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>