File:  [local] / rpl / src / semaphores.c
Revision 1.7: download - view: text, annotated - select for diffs - revision graph
Fri Aug 6 15:33:04 2010 UTC (13 years, 8 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Cohérence

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.0.18
    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: 
   23: #include "rpl-conv.h"
   24: 
   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: 
  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: 
  366: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>