File:  [local] / rpl / src / semaphores.c
Revision 1.31: download - view: text, annotated - select for diffs - revision graph
Sun Sep 18 18:45:31 2011 UTC (12 years, 7 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Correction de sem_getvalue2 pour éviter une 'race condition'.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.3
    4:   Copyright (C) 1989-2011 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: // Les fonctions suivantes ne sont utilisées que dans le cas d'un
   28: // système POSIX qui ne possède pas de sémaphores anonymes. MacOS X
   29: // est dans ce cas.
   30: 
   31: static unsigned char *
   32: nom_segment_semaphore(pid_t pid)
   33: {
   34:     unsigned char               *fichier;
   35: 
   36:     if ((fichier = malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL)
   37:     {
   38:         return(NULL);
   39:     }
   40: 
   41:     sprintf(fichier, "/RPL-SIGSEMAPHORE-%d", (int) pid);
   42:     return(fichier);
   43: }
   44: 
   45: 
   46: /*
   47: ================================================================================
   48:   Fonctions d'émulation de sémaphores anonymes
   49: ================================================================================
   50:   Entrées :
   51: --------------------------------------------------------------------------------
   52:   Sorties :
   53: --------------------------------------------------------------------------------
   54:   Effets de bord : néant
   55: ================================================================================
   56: */
   57: 
   58: sem_t *
   59: sem_init2(unsigned int valeur, pid_t pid)
   60: {
   61:     sem_t                       *semaphore;
   62: 
   63:     unsigned char               *chemin;
   64:     unsigned int                i;
   65: 
   66:     if ((chemin = nom_segment_semaphore(pid)) == NULL)
   67:     {
   68:         return(SEM_FAILED);
   69:     }
   70: 
   71:     semaphore = sem_open(chemin, O_CREAT, (S_IRUSR | S_IWUSR), valeur);
   72:     free(chemin);
   73: 
   74:     for(i = 0; i < valeur; i++)
   75:     {
   76:         if (sem_post(semaphore) != 0)
   77:         {
   78:             sem_close(semaphore);
   79:             return(SEM_FAILED);
   80:         }
   81:     }
   82: 
   83:     return(semaphore);
   84: }
   85: 
   86: 
   87: sem_t *
   88: sem_open2(pid_t pid)
   89: {
   90:     unsigned char               *chemin;
   91: 
   92:     sem_t                       *semaphore;
   93: 
   94:     if ((chemin = nom_segment_semaphore(pid)) == NULL)
   95:     {
   96:         return(1);
   97:     }
   98: 
   99:     semaphore = sem_open(chemin, O_RDWR);
  100:     free(chemin);
  101: 
  102:     return(semaphore);
  103: }
  104: 
  105: 
  106: int
  107: sem_destroy2(sem_t *semaphore, pid_t pid)
  108: {
  109:     int                         erreur;
  110: 
  111:     unsigned char               *chemin;
  112: 
  113:     sem_close(semaphore);
  114: 
  115:     if ((chemin = nom_segment_semaphore(pid)) == NULL)
  116:     {
  117:         return(1);
  118:     }
  119: 
  120:     erreur = sem_unlink(chemin);
  121:     free(chemin);
  122: 
  123:     return(erreur);
  124: }
  125: 
  126: #undef sem_post
  127: #undef sem_wait
  128: #undef sem_trywait
  129: 
  130: int
  131: sem_getvalue2(sem_t *semaphore, int *valeur)
  132: {
  133:     int                     i;
  134:     int                     j;
  135: 
  136:     logical1                drapeau_fin;
  137: 
  138:     struct timespec         attente;
  139: 
  140:     attente.tv_sec = 0;
  141:     attente.tv_nsec = GRANULARITE_us * 1000;
  142: 
  143:     for(j = 0; j < 100; j++)
  144:     {
  145:         if (pthread_mutex_trylock(&mutex_sem) == 0)
  146:         {
  147:             (*valeur) = 0;
  148:             drapeau_fin = d_faux;
  149: 
  150:             do
  151:             {
  152:                 if (sem_trywait(semaphore) == -1)
  153:                 {
  154:                     if (errno == EAGAIN)
  155:                     {
  156:                         // Le sémaphore avait une valeur nulle
  157:                         drapeau_fin = d_vrai;
  158:                     }
  159:                     else
  160:                     {
  161:                         // Autre erreur
  162:                         pthread_mutex_unlock(&mutex_sem);
  163:                         return(-1);
  164:                     }
  165:                 }
  166:                 else
  167:                 {
  168:                     (*valeur)++;
  169:                 }
  170:             } while(drapeau_fin == d_faux);
  171: 
  172:             for(i = 0; i < (*valeur); i++)
  173:             {
  174:                 if (sem_post(semaphore) != 0)
  175:                 {
  176:                     pthread_mutex_unlock(&mutex_sem);
  177:                     return(-1);
  178:                 }
  179:             }
  180: 
  181:             pthread_mutex_unlock(&mutex_sem);
  182:             return(0);
  183:         }
  184: 
  185:         INCR_GRANULARITE(attente.tv_nsec);
  186:     }
  187: 
  188:     // Le mutex n'a pas pu être verrouillé. On peut raisonnablement penser
  189:     // que le sémaphore est bloqué dans un sem_wait() protégé par ce mutex.
  190: 
  191:     (*valeur) = 0;
  192:     return(0);
  193: }
  194: 
  195: #endif
  196: 
  197: #ifdef IPCS_SYSV
  198: 
  199: /*
  200: ================================================================================
  201:   Fonctions d'émulation de sémaphores POSIX en fonction des sémaphores SysV
  202: ================================================================================
  203:   Entrées :
  204: --------------------------------------------------------------------------------
  205:   Sorties :
  206: --------------------------------------------------------------------------------
  207:   Effets de bord : néant
  208: ================================================================================
  209: */
  210: 
  211: #ifndef OS2
  212:     extern unsigned char *chemin_semaphores_SysV;
  213: #else
  214:     unsigned char racine_semaphores_OS2[] = "\\SEM32\\";
  215:     unsigned char racine_memoire_OS2[] = "\\SHAREMEM\\";
  216: #endif
  217: 
  218: int
  219: sem_init_SysV(sem_t *semaphore, int shared, unsigned int valeur)
  220: {
  221:     // Création d'un sémaphore anonyme qui devra être supprimé par
  222:     // sem_destroy_SysV
  223: #   ifndef OS2
  224: 
  225:     int             ios;
  226: 
  227:     union semun     argument;
  228: 
  229:     if (shared != 0)
  230:     {
  231:         errno = ENOSYS;
  232:         return(-1);
  233:     }
  234: 
  235:     (*semaphore).sem = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL |
  236:             S_IRUSR | S_IWUSR);
  237:     (*semaphore).path = NULL;
  238:     (*semaphore).pid = getpid();
  239: 
  240:     if ((*semaphore).sem == -1)
  241:     {
  242:         errno = EINVAL;
  243:         return(-1);
  244:     }
  245: 
  246:     argument.val = valeur;
  247:     ios = semctl((*semaphore).sem, 0, SETVAL, argument);
  248: 
  249:     return(ios);
  250: 
  251: #   else
  252: 
  253:     sem_t           *psem;
  254: 
  255:     psem = semaphore;
  256: 
  257:     if (shared != 0)
  258:     {
  259:         errno = ENOSYS;
  260:         return(-1);
  261:     }
  262: 
  263:     if (((*psem).cnt = malloc(sizeof(ULONG))) == NULL)
  264:     {
  265:         free(psem);
  266:         errno = ENOMEM;
  267:         return(-1);
  268:     }
  269: 
  270:     if (((*psem).nopened = malloc(sizeof(ULONG))) == NULL)
  271:     {
  272:         free((*psem).cnt);
  273:         free(psem);
  274:         errno = ENOMEM;
  275:         return(-1);
  276:     }
  277: 
  278:     if (DosCreateMutexSem(NULL, &((*psem).hmtx), 0, 0) != 0)
  279:     {
  280:         free((*psem).cnt);
  281:         free((*psem).nopened);
  282:         free(psem);
  283:         return(-1);
  284:     }
  285: 
  286:     if (DosCreateEventSem(NULL, &((*psem).hev), 0, (valeur != 0) ? 1 : 0) != 0)
  287:     {
  288:         DosCloseMutexSem((*psem).hmtx);
  289:         free((*psem).cnt);
  290:         free((*psem).nopened);
  291:         free(psem);
  292:         return(-1);
  293:     }
  294: 
  295:     (*(*psem).cnt) = valeur;
  296:     (*(*psem).nopened) = 1;
  297:     (*psem).shared = shared;
  298:     (*psem).allocated = 0;
  299: 
  300:     return(0);
  301: 
  302: #   endif
  303: }
  304: 
  305: int
  306: sem_destroy_SysV(sem_t *semaphore)
  307: {
  308:     // Détruit un sémaphore anonmyme
  309: #   ifndef OS2
  310: 
  311:     if ((*semaphore).path != NULL)
  312:     {
  313:         return(EINVAL);
  314:     }
  315: 
  316:     if ((*semaphore).pid != getpid())
  317:     {
  318:         return(0);
  319:     }
  320: 
  321:     if (semctl((*semaphore).sem, 0, IPC_RMID) == -1)
  322:     {
  323:         return(EINVAL);
  324:     }
  325: 
  326:     return(0);
  327: 
  328: #   else
  329: 
  330:     sem_t       *psem;
  331: 
  332:     psem = semaphore;
  333: 
  334:     if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
  335:     {
  336:         return(EINVAL);
  337:     }
  338: 
  339:     if (DosCloseMutexSem((*psem).hmtx) != 0)
  340:     {
  341:         return(EINVAL);
  342:     }
  343: 
  344:     while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
  345:     {
  346:         DosPostEventSem((*psem).hev);
  347:     }
  348: 
  349:     (*(*psem).nopened)--;
  350: 
  351:     if ((*psem).shared == 0)
  352:     {
  353:         free((*psem).cnt);
  354:         free((*psem).nopened);
  355:     }
  356:     else
  357:     {
  358:         if ((*(*psem).nopened) == 0)
  359:         {
  360:             DosFreeMem((*psem).cnt);
  361:         }
  362:     }
  363: 
  364:     if ((*psem).allocated != 0)
  365:     {   
  366:         free(psem);
  367:     }
  368: 
  369:     return(0);
  370: 
  371: #   endif
  372: }
  373: 
  374: int
  375: sem_wait_SysV(sem_t *semaphore)
  376: {
  377: #   ifndef OS2
  378: 
  379:     struct sembuf       commande;
  380: 
  381:     commande.sem_num = 0;
  382:     commande.sem_op = -1;
  383:     commande.sem_flg = 0;
  384: 
  385:     while(semop((*semaphore).sem, &commande, 1) == -1)
  386:     {
  387:         if (errno != EINTR)
  388:         {
  389:             errno = EINVAL;
  390:             return(-1);
  391:         }
  392:     }
  393: 
  394:     return(0);
  395: 
  396: #   else
  397: 
  398:     sem_t       *psem;
  399: 
  400:     ULONG       cnt;
  401: 
  402:     psem = semaphore;
  403: 
  404:     if (DosWaitEventSem((*psem).hev, SEM_INDEFINITE_WAIT) != 0)
  405:     {
  406:         errno = EINVAL;
  407:         return(-1);
  408:     }
  409: 
  410:     if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
  411:     {
  412:         errno = EINVAL;
  413:         return(-1);
  414:     }
  415: 
  416:     if ((*(*psem).cnt) > 0)
  417:     {
  418:         (*(*psem).cnt)--;
  419:     }
  420: 
  421:     if ((*(*psem).cnt) == 0)
  422:     {
  423:         DosResetEventSem((*psem).hev, &cnt);
  424:     }
  425: 
  426:     DosReleaseMutexSem((*psem).hmtx);
  427:     return(0);
  428: 
  429: #   endif
  430: }
  431: 
  432: int
  433: sem_trywait_SysV(sem_t *semaphore)
  434: {
  435: #   ifndef OS2
  436: 
  437:     struct sembuf       commande;
  438: 
  439:     commande.sem_num = 0;
  440:     commande.sem_op = -1;
  441:     commande.sem_flg = IPC_NOWAIT;
  442: 
  443:     while(semop((*semaphore).sem, &commande, 1) == -1)
  444:     {
  445:         if (errno != EINTR)
  446:         {
  447:             errno = EINVAL;
  448:             return(-1);
  449:         }
  450:     }
  451: 
  452:     return(0);
  453: 
  454: #   else
  455: 
  456:     int         ios;
  457: 
  458:     sem_t       *psem;
  459: 
  460:     ULONG       cnt;
  461: 
  462:     psem = semaphore;
  463: 
  464:     if ((ios = DosWaitEventSem((*psem).hev, SEM_IMMEDIATE_RETURN)) != 0)
  465:     {
  466:         errno = (ios == ERROR_TIMEOUT) ? EAGAIN : EINVAL;
  467:         return(-1);
  468:     }
  469: 
  470:     if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
  471:     {
  472:         errno = EINVAL;
  473:         return(-1);
  474:     }
  475: 
  476:     if ((*(*psem).cnt) > 0)
  477:     {
  478:         (*(*psem).cnt)--;
  479:     }
  480: 
  481:     if ((*(*psem).cnt) == 0)
  482:     {
  483:         DosResetEventSem((*psem).hev, &cnt);
  484:     }
  485: 
  486:     DosReleaseMutexSem((*psem).hmtx);
  487:     return(0);
  488: 
  489: #   endif
  490: }
  491: 
  492: int
  493: sem_post_SysV(sem_t *semaphore)
  494: {
  495: #   ifndef OS2
  496: 
  497:     struct sembuf       commande;
  498: 
  499:     commande.sem_num = 0;
  500:     commande.sem_op = 1;
  501:     commande.sem_flg = 0;
  502: 
  503:     while(semop((*semaphore).sem, &commande, 1) == -1)
  504:     {
  505:         if (errno != EINTR)
  506:         {
  507:             errno = EINVAL;
  508:             return(-1);
  509:         }
  510:     }
  511: 
  512:     return(0);
  513: 
  514: #   else
  515: 
  516:     sem_t               *psem;
  517: 
  518:     psem = semaphore;
  519: 
  520:     if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
  521:     {
  522:         errno = EINVAL;
  523:         return(-1);
  524:     }
  525: 
  526:     (*(*psem).cnt)++;
  527:     DosPostEventSem((*psem).hev);
  528:     DosReleaseMutexSem((*psem).hmtx);
  529: 
  530:     return(0);
  531: 
  532: #   endif
  533: }
  534: 
  535: int
  536: sem_getvalue_SysV(sem_t *semaphore, int *valeur)
  537: {
  538: #   ifndef OS2
  539: 
  540:     (*valeur) = semctl((*semaphore).sem, 0, GETVAL);
  541: 
  542:     if ((*valeur) < 0)
  543:     {
  544:         return(EINVAL);
  545:     }
  546: 
  547:     return(0);
  548: 
  549: #   else
  550: 
  551:     sem_t               *psem;
  552: 
  553:     psem = semaphore;
  554: 
  555:     if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
  556:     {
  557:         errno = EINVAL;
  558:         return(-1);
  559:     }
  560: 
  561:     (*valeur) = (*(*psem).cnt);
  562:     DosReleaseMutexSem((*psem).hmtx);
  563: 
  564:     return(0);
  565: 
  566: #   endif
  567: }
  568: 
  569: sem_t
  570: *sem_open_SysV(const char *nom, int oflag, ...)
  571: //*sem_open(const char *nom, int oflag)
  572: //*sem_open(const char *nom, int oflag, mode_t mode, unsigned int value)
  573: {
  574:     mode_t              mode;
  575: 
  576:     sem_t               *semaphore;
  577: 
  578: #   ifndef OS2
  579:     file                *desc;
  580: 
  581:     key_t               clef;
  582: 
  583:     union semun         argument;
  584: #   endif
  585: 
  586:     unsigned char       *nom_absolu;
  587: 
  588:     unsigned int        valeur;
  589: 
  590:     va_list             liste;
  591: 
  592: #   ifdef OS2
  593:     sem_t               *psem;
  594: 
  595:     PVOID               base;
  596: 
  597:     unsigned char       *ptr;
  598:     unsigned char       *nom_segment;
  599: #   endif
  600: 
  601: #   ifndef OS2
  602: 
  603:     if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom)
  604:             + 1) * sizeof(unsigned char))) == NULL)
  605:     {
  606:         return(SEM_FAILED);
  607:     }
  608: 
  609:     sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom);
  610: 
  611:     if ((semaphore = malloc(sizeof(sem_t))) == NULL)
  612:     {
  613:         return(SEM_FAILED);
  614:     }
  615: 
  616: #   else
  617: 
  618:     if ((nom_segment = malloc((strlen(racine_memoire_OS2) + strlen(nom) + 1)
  619:             * sizeof(unsigned char))) == NULL)
  620:     {
  621:         return(SEM_FAILED);
  622:     }   
  623: 
  624:     sprintf(nom_segment, "%s%s", racine_memoire_OS2, nom);
  625:     ptr = nom_segment;
  626: 
  627:     while((*ptr) != d_code_fin_chaine)
  628:     {
  629:         if ((*ptr) == '/')
  630:         {
  631:             (*ptr) = '\\';
  632:         }
  633: 
  634:         ptr++;
  635:     }
  636: 
  637:     if ((nom_absolu = malloc((strlen(racine_semaphores_OS2) + strlen(nom)
  638:             + 2) * sizeof(unsigned char))) == NULL)
  639:     {
  640:         return(SEM_FAILED);
  641:     }
  642: 
  643:     sprintf(nom_absolu, "%s%s", racine_semaphores_OS2, nom);
  644:     ptr = nom_absolu;
  645: 
  646:     while((*ptr) != d_code_fin_chaine)
  647:     {
  648:         if ((*ptr) == '/')
  649:         {
  650:             (*ptr) = '\\';
  651:         }
  652: 
  653:         ptr++;
  654:     }
  655: 
  656:     (*(ptr + 1)) = d_code_fin_chaine;
  657: 
  658:     if ((psem = malloc(sizeof(sem_t))) == NULL)
  659:     {
  660:         return(SEM_FAILED);
  661:     }
  662: 
  663:     (*psem).allocated = 1;
  664: 
  665: #   endif
  666: 
  667:     if ((oflag & O_CREAT) == 0)
  668:     {
  669:         // 2 arguments
  670: 
  671: #       ifndef OS2
  672: 
  673:         clef = ftok(nom_absolu, 1);
  674: 
  675:         if (clef == -1)
  676:         {
  677:             return(SEM_FAILED);
  678:         }
  679: 
  680:         (*semaphore).sem = semget(clef, 0, 0);
  681:         (*semaphore).path = nom_absolu;
  682:         (*semaphore).pid = getpid();
  683: 
  684:         if ((*semaphore).sem == -1)
  685:         {   
  686:             free(semaphore);
  687:             free(nom_absolu);
  688: 
  689:             return(SEM_FAILED);
  690:         }
  691: 
  692: #       else
  693: 
  694:         if ((psem = malloc(sizeof(sem_t))) == NULL)
  695:         {
  696:             free(nom_absolu);
  697:             free(nom_segment);
  698:             return(SEM_FAILED);
  699:         }
  700: 
  701:         (*ptr) = 'M';
  702: 
  703:         if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0)
  704:         {
  705:             free(psem);
  706:             free(nom_absolu);
  707:             free(nom_segment);
  708: 
  709:             return(SEM_FAILED);
  710:         }
  711: 
  712:         (*ptr) = 'S';
  713: 
  714:         if (DosOpenEventSem(nom_absolu, &((*psem).hev)) != 0)
  715:         {
  716:             DosCloseMutexSem((*psem).hmtx);
  717: 
  718:             free(psem);
  719:             free(nom_absolu);
  720:             free(nom_segment);
  721: 
  722:             return(SEM_FAILED);
  723:         }
  724: 
  725:         if (DosGetNamedSharedMem(&base, nom_segment, PAG_WRITE | PAG_READ) != 0)
  726:         {
  727:             DosCloseMutexSem((*psem).hmtx);
  728: 
  729:             free(nom_absolu);
  730:             free(nom_segment);
  731:             free(psem);
  732: 
  733:             return(SEM_FAILED);
  734:         }
  735: 
  736:         free(nom_segment);
  737: 
  738:         (*psem).cnt = (ULONG *) base;
  739:         (*psem).nopened = ((ULONG *) base) + 1;
  740:         (*psem).shared = 1;
  741: 
  742:         if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
  743:         {
  744:             DosCloseMutexSem((*psem).hmtx);
  745: 
  746:             free(nom_absolu);
  747:             free(nom_segment);
  748:             free(psem);
  749: 
  750:             return(SEM_FAILED);
  751:         }
  752: 
  753:         (*((*psem).nopened))++;
  754: 
  755:         DosReleaseMutexSem((*psem).hmtx);
  756: 
  757:         semaphore = psem;
  758: 
  759: #       endif
  760:     }
  761:     else
  762:     {
  763:         // 4 arguments
  764: 
  765:         // O_CREAT O_EXCL
  766:         // S_IRUSR S_IWUSR
  767: 
  768:         va_start(liste, oflag);
  769:         mode = va_arg(liste, mode_t);
  770:         valeur = va_arg(liste, unsigned int);
  771:         va_end(liste);
  772: 
  773: #       ifndef OS2
  774: 
  775:         if ((desc = fopen(nom_absolu, "w")) == NULL)
  776:         {
  777:             free(semaphore);
  778:             free(nom_absolu);
  779: 
  780:             return(SEM_FAILED);
  781:         }
  782: 
  783:         fclose(desc);
  784: 
  785:         if ((clef = ftok(nom_absolu, 1)) == -1)
  786:         {
  787:             free(semaphore);
  788:             free(nom_absolu);
  789: 
  790:             return(SEM_FAILED);
  791:         }
  792: 
  793:         (*semaphore).sem = semget(clef, 1,
  794:                 (((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT) |
  795:                 (((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL) |
  796:                 (int) mode);
  797:         (*semaphore).path = nom_absolu;
  798:         (*semaphore).pid = getpid();
  799: 
  800:         if ((*semaphore).sem == -1)
  801:         {   
  802:             free(semaphore);
  803:             free(nom_absolu);
  804: 
  805:             return(SEM_FAILED);
  806:         }
  807: 
  808:         argument.val = valeur;
  809:         semctl((*semaphore).sem, 0, SETVAL, argument);
  810: 
  811: #       else
  812: 
  813:         if ((psem = malloc(sizeof(sem_t))) == NULL)
  814:         {
  815:             free(nom_absolu);
  816:             free(nom_segment);
  817: 
  818:             return(SEM_FAILED);
  819:         }
  820: 
  821:         (*ptr) = 'M';
  822: 
  823:         if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0)
  824:         {
  825:             free(psem);
  826:             free(nom_absolu);
  827:             free(nom_segment);
  828: 
  829:             return(SEM_FAILED);
  830:         }
  831: 
  832:         (*ptr) = 'S';
  833: 
  834:         if (DosCreateEventSem(nom_absolu, &((*psem).hev), 0,
  835:                 (valeur != 0) ? 1 : 0) != 0)
  836:         {
  837:             DosCloseMutexSem((*psem).hmtx);
  838: 
  839:             free(nom_absolu);
  840:             free(nom_segment);
  841:             free(psem);
  842: 
  843:             return(SEM_FAILED);
  844:         }
  845: 
  846:         if (DosAllocSharedMem(&base, nom_segment, 2 * sizeof(ULONG),
  847:                 PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
  848:         {
  849:             DosCloseMutexSem((*psem).hmtx);
  850: 
  851:             free(nom_absolu);
  852:             free(nom_segment);
  853:             free(psem);
  854: 
  855:             return(SEM_FAILED);
  856:         }
  857: 
  858:         free(nom_segment);
  859: 
  860:         (*psem).cnt = (ULONG *) base;
  861:         (*psem).nopened = ((ULONG *) base) + 1;
  862:         (*(*psem).cnt) = valeur;
  863:         (*(*psem).nopened) = 1;
  864:         (*psem).shared = 1;
  865:         semaphore = psem;
  866: 
  867: #       endif
  868:     }
  869: 
  870:     return(semaphore);
  871: }
  872: 
  873: int
  874: sem_close_SysV(sem_t *semaphore)
  875: {
  876:     // Ferme un sémaphore nommé créé par sem_open_SysV()
  877: #   ifndef OS2
  878: 
  879:     if ((*semaphore).path != NULL)
  880:     {
  881:         free((*semaphore).path);
  882:     }
  883: 
  884:     free(semaphore);
  885:     return(0);
  886: 
  887: #   else
  888: 
  889:     sem_t       *psem;
  890: 
  891:     psem = semaphore;
  892: 
  893:     if (DosCloseMutexSem((*psem).hmtx) != 0)
  894:     {
  895:         return(EINVAL);
  896:     }
  897: 
  898:     while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
  899:     {
  900:         DosPostEventSem((*psem).hev);
  901:     }
  902: 
  903:     (*(*psem).nopened)--;
  904: 
  905:     if ((*psem).shared == 0)
  906:     {
  907:         free((*psem).cnt);
  908:         free((*psem).nopened);
  909:     }
  910:     else
  911:     {
  912:         if ((*(*psem).nopened) == 0)
  913:         {
  914:             DosFreeMem((*psem).cnt);
  915:         }
  916:     }
  917: 
  918:     if ((*psem).allocated != 0)
  919:     {
  920:         free(psem);
  921:     }
  922: 
  923:     return(0);
  924: 
  925: #   endif
  926: }
  927: 
  928: int
  929: sem_unlink_SysV(const char *nom)
  930: {
  931:     // Détruit un sémaphore nommé créé par sem_open_SysV()
  932: #   ifndef OS2
  933: 
  934:     unsigned char       *nom_absolu;
  935: 
  936:     if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom)
  937:             + 1) * sizeof(unsigned char))) == NULL)
  938:     {
  939:         return(ENOMEM);
  940:     }
  941: 
  942:     sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom);
  943:     semctl(semget(ftok(nom_absolu, 1), 0, 0), 0, IPC_RMID);
  944: 
  945:     if (unlink(nom_absolu) == -1)
  946:     {
  947:         free(nom_absolu);
  948:         return(EACCES);
  949:     }
  950: 
  951:     free(nom_absolu);
  952: 
  953:     return(0);
  954: 
  955: #   else
  956: 
  957:     return(0);
  958: 
  959: #   endif
  960: }
  961: 
  962: #endif
  963: 
  964: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>