File:  [local] / rpl / src / semaphores.c
Revision 1.56: download - view: text, annotated - select for diffs - revision graph
Thu Mar 21 12:07:39 2013 UTC (11 years, 1 month ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Toutes les grandeurs connexes aux objets sont maintenant en 64 bits.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.13
    4:   Copyright (C) 1989-2013 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: 
   26: #ifdef SEMAPHORES_NOMMES
   27: 
   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 *
   33: nom_segment_semaphore(pid_t pid, int ordre)
   34: {
   35:     unsigned char               *fichier;
   36: 
   37:     if ((fichier = malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL)
   38:     {
   39:         return(NULL);
   40:     }
   41: 
   42:     sprintf(fichier, "/RPL-%llu-%d", (unsigned long long) pid, ordre);
   43:     return(fichier);
   44: }
   45: 
   46: 
   47: static unsigned char *
   48: nom_segment_semaphore_thread(pid_t pid, pthread_t tid, int ordre)
   49: {
   50:     unsigned char               *fichier;
   51: 
   52:     if ((fichier = malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL)
   53:     {
   54:         return(NULL);
   55:     }
   56: 
   57:     sprintf(fichier, "/RPL-%llu-%llu-%d", (unsigned long long) pid,
   58:             (unsigned long long) tid, ordre);
   59:     return(fichier);
   60: }
   61: 
   62: 
   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 *
   76: sem_init2(unsigned int valeur, pid_t pid, int ordre)
   77: {
   78:     sem_t                       *semaphore;
   79: 
   80:     unsigned char               *chemin;
   81: 
   82:     if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL)
   83:     {
   84:         return(SEM_FAILED);
   85:     }
   86: 
   87:     semaphore = sem_open(chemin, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR,
   88:             valeur);
   89:     free(chemin);
   90: 
   91:     return(semaphore);
   92: }
   93: 
   94: 
   95: sem_t *
   96: sem_init3(unsigned int valeur, pid_t pid, pthread_t tid, int ordre)
   97: {
   98:     sem_t                       *semaphore;
   99: 
  100:     unsigned char               *chemin;
  101: 
  102:     if ((chemin = nom_segment_semaphore_thread(pid, tid, ordre)) == NULL)
  103:     {
  104:         return(SEM_FAILED);
  105:     }
  106: 
  107:     semaphore = sem_open(chemin, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR,
  108:             valeur);
  109:     free(chemin);
  110: 
  111:     return(semaphore);
  112: }
  113: 
  114: 
  115: sem_t *
  116: sem_open2(pid_t pid, int ordre)
  117: {
  118:     unsigned char               *chemin;
  119: 
  120:     sem_t                       *semaphore;
  121: 
  122:     if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL)
  123:     {
  124:         return(SEM_FAILED);
  125:     }
  126: 
  127:     semaphore = sem_open(chemin, O_RDWR);
  128:     free(chemin);
  129: 
  130:     return(semaphore);
  131: }
  132: 
  133: 
  134: int
  135: sem_destroy2(sem_t *semaphore, pid_t pid, int ordre)
  136: {
  137:     int                         erreur;
  138: 
  139:     unsigned char               *chemin;
  140: 
  141:     sem_close(semaphore);
  142: 
  143:     if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL)
  144:     {
  145:         return(1);
  146:     }
  147: 
  148:     erreur = sem_unlink(chemin);
  149:     free(chemin);
  150: 
  151:     return(erreur);
  152: }
  153: 
  154: 
  155: int
  156: sem_destroy3(sem_t *semaphore, pid_t pid, pthread_t tid, int ordre)
  157: {
  158:     int                         erreur;
  159: 
  160:     unsigned char               *chemin;
  161: 
  162:     sem_close(semaphore);
  163: 
  164:     if ((chemin = nom_segment_semaphore_thread(pid, tid, ordre)) == NULL)
  165:     {
  166:         return(1);
  167:     }
  168: 
  169:     erreur = sem_unlink(chemin);
  170:     free(chemin);
  171: 
  172:     return(erreur);
  173: }
  174: 
  175: 
  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;
  184:     int                     j;
  185: 
  186:     logical1                drapeau_fin;
  187: 
  188:     struct timespec         attente;
  189: 
  190:     attente.tv_sec = 0;
  191:     attente.tv_nsec = GRANULARITE_us * 1000;
  192: 
  193:     for(j = 0; j < 100; j++)
  194:     {
  195:         if (pthread_mutex_trylock(&mutex_sem) == 0)
  196:         {
  197:             (*valeur) = 0;
  198:             drapeau_fin = d_faux;
  199: 
  200:             do
  201:             {
  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++)
  223:             {
  224:                 if (sem_post(semaphore) != 0)
  225:                 {
  226:                     pthread_mutex_unlock(&mutex_sem);
  227:                     return(-1);
  228:                 }
  229:             }
  230: 
  231:             pthread_mutex_unlock(&mutex_sem);
  232:             return(0);
  233:         }
  234: 
  235:         INCR_GRANULARITE(attente.tv_nsec);
  236:     }
  237: 
  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;
  242:     return(0);
  243: }
  244: 
  245: #endif
  246: 
  247: #ifdef IPCS_SYSV
  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: 
  261: #ifndef OS2 // IPCS_SYSV
  262:     extern unsigned char *racine_segment;
  263: #else // OS/2
  264:     unsigned char racine_semaphores_OS2[] = "\\SEM32\\";
  265:     unsigned char racine_memoire_OS2[] = "\\SHAREMEM\\";
  266: #endif
  267: 
  268: int
  269: sem_init_SysV(sem_t *semaphore, int shared, unsigned int valeur)
  270: {
  271:     // Création d'un sémaphore anonyme qui devra être supprimé par
  272:     // sem_destroy_SysV
  273: 
  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();
  289:             (*semaphore).tid = pthread_self();
  290:             (*semaphore).alloue = 0;
  291:         }
  292:         else
  293:         {
  294:             // Sémaphore partagé entre plusieurs processus
  295:             if (((*semaphore).path = malloc((strlen(racine_segment)
  296:                     + 2 + 256 + 1) * sizeof(unsigned char))) == NULL)
  297:             {
  298:                 return(-1);
  299:             }
  300: 
  301:             sprintf((*semaphore).path, "%s/RPL-SEMAPHORE-%d-%llX-%llX",
  302:                     racine_segment, (int) getpid(),
  303:                     (long long unsigned) pthread_self(),
  304:                     (long long unsigned) semaphore);
  305: 
  306:             if ((desc = open((*semaphore).path, O_RDWR | O_CREAT | O_EXCL,
  307:                     S_IRUSR | S_IWUSR)) == -1)
  308:             {
  309:                 free((*semaphore).path);
  310:                 return(-1);
  311:             }
  312: 
  313:             (*semaphore).pid = getpid();
  314:             (*semaphore).tid = pthread_self();
  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:         }
  328: 
  329:         if ((*semaphore).sem == -1)
  330:         {
  331:             errno = EINVAL;
  332:             return(-1);
  333:         }
  334: 
  335:         argument.val = valeur;
  336:         ios = semctl((*semaphore).sem, 0, SETVAL, argument);
  337: 
  338:         return(ios);
  339: #   else // OS/2
  340:         sem_t           *psem;
  341: 
  342:         psem = semaphore;
  343: 
  344:         if (((*psem).cnt = malloc(sizeof(ULONG))) == NULL)
  345:         {
  346:             free(psem);
  347:             errno = ENOMEM;
  348:             return(-1);
  349:         }
  350: 
  351:         if (((*psem).nopened = malloc(sizeof(ULONG))) == NULL)
  352:         {
  353:             free((*psem).cnt);
  354:             free(psem);
  355:             errno = ENOMEM;
  356:             return(-1);
  357:         }
  358: 
  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:         }
  366: 
  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:         }
  376: 
  377:         (*(*psem).cnt) = valeur;
  378:         (*(*psem).nopened) = 1;
  379:         (*psem).shared = shared;
  380:         (*psem).allocated = 0;
  381: 
  382:         return(0);
  383: #   endif
  384: }
  385: 
  386: int
  387: sem_destroy_SysV(sem_t *semaphore)
  388: {
  389:     // Détruit un sémaphore anonmyme
  390: 
  391: #   ifndef OS2 // IPCS_SYSV
  392:         if ((*semaphore).path != NULL)
  393:         {
  394:             return(EINVAL);
  395:         }
  396: 
  397:         if ((*semaphore).pid != getpid())
  398:         {
  399:             return(0);
  400:         }
  401: 
  402:         if (semctl((*semaphore).sem, 0, IPC_RMID) == -1)
  403:         {
  404:             return(EINVAL);
  405:         }
  406: 
  407:         return(0);
  408: #   else // OS/2
  409:         sem_t       *psem;
  410: 
  411:         psem = semaphore;
  412: 
  413:         if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
  414:         {
  415:             return(EINVAL);
  416:         }
  417: 
  418:         if (DosCloseMutexSem((*psem).hmtx) != 0)
  419:         {
  420:             return(EINVAL);
  421:         }
  422: 
  423:         while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
  424:         {
  425:             DosPostEventSem((*psem).hev);
  426:         }
  427: 
  428:         (*(*psem).nopened)--;
  429: 
  430:         if ((*psem).shared == 0)
  431:         {
  432:             free((*psem).cnt);
  433:             free((*psem).nopened);
  434:         }
  435:         else
  436:         {
  437:             if ((*(*psem).nopened) == 0)
  438:             {
  439:                 DosFreeMem((*psem).cnt);
  440:             }
  441:         }
  442: 
  443:         if ((*psem).allocated != 0)
  444:         {   
  445:             free(psem);
  446:         }
  447: 
  448:         return(0);
  449: #   endif
  450: }
  451: 
  452: int
  453: sem_wait_SysV(sem_t *semaphore)
  454: {
  455: #   ifndef OS2 // IPCS_SYSV
  456:         struct sembuf       commande;
  457: 
  458:         // semop() ne renvoie pas EINTR sur un signal !
  459: 
  460:         commande.sem_num = 0;
  461:         commande.sem_op = -1;
  462:         commande.sem_flg = 0;
  463: 
  464:         if (semop((*semaphore).sem, &commande, 1) == -1)
  465:         {
  466:             if (errno != EAGAIN)
  467:             {
  468:                 errno = EINVAL;
  469:                 return(-1);
  470:             }
  471:             else
  472:             {
  473:                 return(-1);
  474:             }
  475:         }
  476: 
  477:         return(0);
  478: #   else // OS/2
  479:         sem_t       *psem;
  480: 
  481:         ULONG       cnt;
  482: 
  483:         psem = semaphore;
  484: 
  485:         if (DosWaitEventSem((*psem).hev, SEM_INDEFINITE_WAIT) != 0)
  486:         {
  487:             errno = EINVAL;
  488:             return(-1);
  489:         }
  490: 
  491:         if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
  492:         {
  493:             errno = EINVAL;
  494:             return(-1);
  495:         }
  496: 
  497:         if ((*(*psem).cnt) > 0)
  498:         {
  499:             (*(*psem).cnt)--;
  500:         }
  501: 
  502:         if ((*(*psem).cnt) == 0)
  503:         {
  504:             DosResetEventSem((*psem).hev, &cnt);
  505:         }
  506: 
  507:         DosReleaseMutexSem((*psem).hmtx);
  508:         return(0);
  509: #   endif
  510: }
  511: 
  512: int
  513: sem_trywait_SysV(sem_t *semaphore)
  514: {
  515: #   ifndef OS2 // IPCS_SYSV
  516:         struct sembuf       commande;
  517: 
  518:         commande.sem_num = 0;
  519:         commande.sem_op = -1;
  520:         commande.sem_flg = IPC_NOWAIT;
  521: 
  522:         if (semop((*semaphore).sem, &commande, 1) == -1)
  523:         {
  524:             return(-1);
  525:         }
  526: 
  527:         return(0);
  528: #   else // OS/2
  529:         int         ios;
  530: 
  531:         sem_t       *psem;
  532: 
  533:         ULONG       cnt;
  534: 
  535:         psem = semaphore;
  536: 
  537:         if ((ios = DosWaitEventSem((*psem).hev, SEM_IMMEDIATE_RETURN)) != 0)
  538:         {
  539:             errno = (ios == ERROR_TIMEOUT) ? EAGAIN : EINVAL;
  540:             return(-1);
  541:         }
  542: 
  543:         if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
  544:         {
  545:             errno = EINVAL;
  546:             return(-1);
  547:         }
  548: 
  549:         if ((*(*psem).cnt) > 0)
  550:         {
  551:             (*(*psem).cnt)--;
  552:         }
  553: 
  554:         if ((*(*psem).cnt) == 0)
  555:         {
  556:             DosResetEventSem((*psem).hev, &cnt);
  557:         }
  558: 
  559:         DosReleaseMutexSem((*psem).hmtx);
  560:         return(0);
  561: #   endif
  562: }
  563: 
  564: #ifndef timespeccmp
  565: #   define timespeccmp(tsp, usp, cmp) \
  566:             (((tsp)->tv_sec == (usp)->tv_sec) ? \
  567:             ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
  568:             ((tsp)->tv_sec cmp (usp)->tv_sec))
  569: #   define timespecadd(tsp, usp, vsp) \
  570:             do { \
  571:                 (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \
  572:                 (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \
  573:                 if ((vsp)->tv_nsec >= 1000000000L) { \
  574:                     (vsp)->tv_sec++; \
  575:                     (vsp)->tv_nsec -= 1000000000L; \
  576:                 } \
  577:             } while(0)
  578: #   define timespecsub(tsp, usp, vsp) \
  579:             do { \
  580:                 (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \
  581:                 (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \
  582:                 if ((vsp)->tv_nsec < 0) { \
  583:                     (vsp)->tv_sec--; \
  584:                     (vsp)->tv_nsec += 1000000000L; \
  585:                 } \
  586:             } while(0)
  587: #endif
  588: 
  589: int
  590: sem_timedwait_SysV(sem_t *sem, struct timespec *ts)
  591: {
  592:     struct timespec onems = { 0, 1000000 };
  593:     struct timespec total = { 0, 0 };
  594:     struct timespec unslept;
  595:     struct timespec elapsed;
  596:     struct timespec tmp;
  597: 
  598:     while(timespeccmp(ts, &total, >))
  599:     {
  600:         if (sem_trywait_SysV(sem) == 0)
  601:         {
  602:             return(0);
  603:         }
  604: 
  605:         if (errno != EAGAIN)
  606:         {
  607:             return(-1);
  608:         }
  609: 
  610:         nanosleep(&onems, &unslept);
  611: 
  612:         timespecsub(&onems, &unslept, &elapsed);
  613:         timespecadd(&total, &elapsed, &tmp);
  614:         total.tv_sec = tmp.tv_sec;
  615:         total.tv_nsec = tmp.tv_nsec;
  616:     }
  617: 
  618:     errno = ETIMEDOUT;
  619:     return(-1);
  620: }
  621: 
  622: int
  623: sem_post_SysV(sem_t *semaphore)
  624: {
  625: #   ifndef OS2 // IPCS_SYSV
  626:         struct sembuf       commande;
  627: 
  628:         commande.sem_num = 0;
  629:         commande.sem_op = 1;
  630:         commande.sem_flg = 0;
  631: 
  632:         while(semop((*semaphore).sem, &commande, 1) == -1)
  633:         {
  634:             if (errno != EINTR)
  635:             {
  636:                 errno = EINVAL;
  637:                 return(-1);
  638:             }
  639:         }
  640: 
  641:         return(0);
  642: #   else // OS/2
  643:         sem_t               *psem;
  644: 
  645:         psem = semaphore;
  646: 
  647:         if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
  648:         {
  649:             errno = EINVAL;
  650:             return(-1);
  651:         }
  652: 
  653:         (*(*psem).cnt)++;
  654:         DosPostEventSem((*psem).hev);
  655:         DosReleaseMutexSem((*psem).hmtx);
  656: 
  657:         return(0);
  658: #   endif
  659: }
  660: 
  661: int
  662: sem_getvalue_SysV(sem_t *semaphore, int *valeur)
  663: {
  664: #   ifndef OS2 // IPCS_SYSV
  665:         (*valeur) = semctl((*semaphore).sem, 0, GETVAL);
  666: 
  667:         if ((*valeur) < 0)
  668:         {
  669:             return(EINVAL);
  670:         }
  671: 
  672:         return(0);
  673: #   else
  674:         sem_t               *psem;
  675: 
  676:         psem = semaphore;
  677: 
  678:         if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
  679:         {
  680:             errno = EINVAL;
  681:             return(-1);
  682:         }
  683: 
  684:         (*valeur) = (*(*psem).cnt);
  685:         DosReleaseMutexSem((*psem).hmtx);
  686: 
  687:         return(0);
  688: #   endif
  689: }
  690: 
  691: sem_t
  692: *sem_open_SysV(const char *nom, int oflag, ...)
  693: //*sem_open(const char *nom, int oflag)
  694: //*sem_open(const char *nom, int oflag, mode_t mode, unsigned int value)
  695: {
  696:     mode_t              mode;
  697: 
  698:     sem_t               *semaphore;
  699: 
  700: #   ifndef OS2
  701:         int             desc;
  702: 
  703:         key_t           clef;
  704: 
  705:         union semun     argument;
  706: #   endif
  707: 
  708:     unsigned char       *nom_absolu;
  709: 
  710:     unsigned int        valeur;
  711: 
  712:     va_list             liste;
  713: 
  714: #   ifdef OS2
  715:         sem_t           *psem;
  716: 
  717:         PVOID           base;
  718: 
  719:         unsigned char   *ptr;
  720:         unsigned char   *nom_segment;
  721: #   endif
  722: 
  723: #   ifndef OS2 // IPCS_SYSV
  724:         if ((nom_absolu = malloc((strlen(racine_segment) + strlen(nom)
  725:                 + 2) * sizeof(unsigned char))) == NULL)
  726:         {
  727:             return(SEM_FAILED);
  728:         }
  729: 
  730:         sprintf(nom_absolu, "%s/%s", racine_segment, nom);
  731: 
  732:         if ((semaphore = malloc(sizeof(sem_t))) == NULL)
  733:         {
  734:             return(SEM_FAILED);
  735:         }
  736: 
  737:         (*semaphore).alloue = -1;
  738:         (*semaphore).pid = getpid();
  739:         (*semaphore).tid = pthread_self();
  740: #   else
  741:         if ((nom_segment = malloc((strlen(racine_memoire_OS2) + strlen(nom) + 1)
  742:                 * sizeof(unsigned char))) == NULL)
  743:         {
  744:             return(SEM_FAILED);
  745:         }   
  746: 
  747:         sprintf(nom_segment, "%s%s", racine_memoire_OS2, nom);
  748:         ptr = nom_segment;
  749: 
  750:         while((*ptr) != d_code_fin_chaine)
  751:         {
  752:             if ((*ptr) == '/')
  753:             {
  754:                 (*ptr) = '\\';
  755:             }
  756: 
  757:             ptr++;
  758:         }
  759: 
  760:         if ((nom_absolu = malloc((strlen(racine_semaphores_OS2) + strlen(nom)
  761:                 + 2) * sizeof(unsigned char))) == NULL)
  762:         {
  763:             return(SEM_FAILED);
  764:         }
  765: 
  766:         sprintf(nom_absolu, "%s%s", racine_semaphores_OS2, nom);
  767:         ptr = nom_absolu;
  768: 
  769:         while((*ptr) != d_code_fin_chaine)
  770:         {
  771:             if ((*ptr) == '/')
  772:             {
  773:                 (*ptr) = '\\';
  774:             }
  775: 
  776:             ptr++;
  777:         }
  778: 
  779:         (*(ptr + 1)) = d_code_fin_chaine;
  780: 
  781:         if ((psem = malloc(sizeof(sem_t))) == NULL)
  782:         {
  783:             return(SEM_FAILED);
  784:         }
  785: 
  786:         (*psem).allocated = 1;
  787: #   endif
  788: 
  789:     if ((oflag & O_CREAT) == 0)
  790:     {
  791:         // 2 arguments
  792: 
  793: #       ifndef OS2 // IPCS_SYSV
  794:             clef = ftok(nom_absolu, 1);
  795: 
  796:             if (clef == -1)
  797:             {
  798:                 return(SEM_FAILED);
  799:             }
  800: 
  801:             (*semaphore).sem = semget(clef, 0, 0);
  802:             (*semaphore).path = nom_absolu;
  803:             (*semaphore).pid = getpid();
  804: 
  805:             if ((*semaphore).sem == -1)
  806:             {   
  807:                 free(semaphore);
  808:                 free(nom_absolu);
  809: 
  810:                 return(SEM_FAILED);
  811:             }
  812: #       else // OS/2
  813:             if ((psem = malloc(sizeof(sem_t))) == NULL)
  814:             {
  815:                 free(nom_absolu);
  816:                 free(nom_segment);
  817:                 return(SEM_FAILED);
  818:             }
  819: 
  820:             (*ptr) = 'M';
  821: 
  822:             if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0)
  823:             {
  824:                 free(psem);
  825:                 free(nom_absolu);
  826:                 free(nom_segment);
  827: 
  828:                 return(SEM_FAILED);
  829:             }
  830: 
  831:             (*ptr) = 'S';
  832: 
  833:             if (DosOpenEventSem(nom_absolu, &((*psem).hev)) != 0)
  834:             {
  835:                 DosCloseMutexSem((*psem).hmtx);
  836: 
  837:                 free(psem);
  838:                 free(nom_absolu);
  839:                 free(nom_segment);
  840: 
  841:                 return(SEM_FAILED);
  842:             }
  843: 
  844:             if (DosGetNamedSharedMem(&base, nom_segment, PAG_WRITE | PAG_READ)
  845:                     != 0)
  846:             {
  847:                 DosCloseMutexSem((*psem).hmtx);
  848: 
  849:                 free(nom_absolu);
  850:                 free(nom_segment);
  851:                 free(psem);
  852: 
  853:                 return(SEM_FAILED);
  854:             }
  855: 
  856:             free(nom_segment);
  857: 
  858:             (*psem).cnt = (ULONG *) base;
  859:             (*psem).nopened = ((ULONG *) base) + 1;
  860:             (*psem).shared = 1;
  861: 
  862:             if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
  863:             {
  864:                 DosCloseMutexSem((*psem).hmtx);
  865: 
  866:                 free(nom_absolu);
  867:                 free(nom_segment);
  868:                 free(psem);
  869: 
  870:                 return(SEM_FAILED);
  871:             }
  872: 
  873:             (*((*psem).nopened))++;
  874: 
  875:             DosReleaseMutexSem((*psem).hmtx);
  876: 
  877:             semaphore = psem;
  878: #       endif
  879:     }
  880:     else
  881:     {
  882:         // 4 arguments
  883: 
  884:         // O_CREAT O_EXCL
  885:         // S_IRUSR S_IWUSR
  886: 
  887:         va_start(liste, oflag);
  888:         mode = va_arg(liste, mode_t);
  889:         valeur = va_arg(liste, unsigned int);
  890:         va_end(liste);
  891: 
  892: #       ifndef OS2 // IPCS_SYSV
  893:             if ((desc = open(nom_absolu, O_CREAT | O_EXCL | O_RDWR,
  894:                     S_IRUSR | S_IWUSR)) == -1)
  895:             {
  896:                 free(semaphore);
  897:                 free(nom_absolu);
  898: 
  899:                 return(SEM_FAILED);
  900:             }
  901: 
  902:             if ((clef = ftok(nom_absolu, 1)) == -1)
  903:             {
  904:                 close(desc);
  905:                 free(semaphore);
  906:                 free(nom_absolu);
  907: 
  908:                 return(SEM_FAILED);
  909:             }
  910: 
  911:             close(desc);
  912: 
  913:             (*semaphore).sem = semget(clef, 1,
  914:                     (((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT) |
  915:                     (((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL) |
  916:                     (int) mode);
  917:             (*semaphore).path = nom_absolu;
  918:             (*semaphore).pid = getpid();
  919: 
  920:             if ((*semaphore).sem == -1)
  921:             {   
  922:                 free(semaphore);
  923:                 free(nom_absolu);
  924: 
  925:                 return(SEM_FAILED);
  926:             }
  927: 
  928:             argument.val = valeur;
  929:             semctl((*semaphore).sem, 0, SETVAL, argument);
  930: #       else // OS/2
  931:             if ((psem = malloc(sizeof(sem_t))) == NULL)
  932:             {
  933:                 free(nom_absolu);
  934:                 free(nom_segment);
  935: 
  936:                 return(SEM_FAILED);
  937:             }
  938: 
  939:             (*ptr) = 'M';
  940: 
  941:             if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0)
  942:             {
  943:                 free(psem);
  944:                 free(nom_absolu);
  945:                 free(nom_segment);
  946: 
  947:                 return(SEM_FAILED);
  948:             }
  949: 
  950:             (*ptr) = 'S';
  951: 
  952:             if (DosCreateEventSem(nom_absolu, &((*psem).hev), 0,
  953:                     (valeur != 0) ? 1 : 0) != 0)
  954:             {
  955:                 DosCloseMutexSem((*psem).hmtx);
  956: 
  957:                 free(nom_absolu);
  958:                 free(nom_segment);
  959:                 free(psem);
  960: 
  961:                 return(SEM_FAILED);
  962:             }
  963: 
  964:             if (DosAllocSharedMem(&base, nom_segment, 2 * sizeof(ULONG),
  965:                     PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
  966:             {
  967:                 DosCloseMutexSem((*psem).hmtx);
  968: 
  969:                 free(nom_absolu);
  970:                 free(nom_segment);
  971:                 free(psem);
  972: 
  973:                 return(SEM_FAILED);
  974:             }
  975: 
  976:             free(nom_segment);
  977: 
  978:             (*psem).cnt = (ULONG *) base;
  979:             (*psem).nopened = ((ULONG *) base) + 1;
  980:             (*(*psem).cnt) = valeur;
  981:             (*(*psem).nopened) = 1;
  982:             (*psem).shared = 1;
  983:             semaphore = psem;
  984: #       endif
  985:     }
  986: 
  987:     return(semaphore);
  988: }
  989: 
  990: int
  991: sem_close_SysV(sem_t *semaphore)
  992: {
  993:     // Ferme un sémaphore nommé créé par sem_open_SysV()
  994: #   ifndef OS2 // IPCS_SYSV
  995:         if ((*semaphore).path != NULL)
  996:         {
  997:             free((*semaphore).path);
  998:         }
  999: 
 1000:         if ((*semaphore).alloue == -1)
 1001:         {
 1002:             free(semaphore);
 1003:         }
 1004: 
 1005:         return(0);
 1006: #   else
 1007:         sem_t       *psem;
 1008: 
 1009:         psem = semaphore;
 1010: 
 1011:         if (DosCloseMutexSem((*psem).hmtx) != 0)
 1012:         {
 1013:             return(EINVAL);
 1014:         }
 1015: 
 1016:         while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
 1017:         {
 1018:             DosPostEventSem((*psem).hev);
 1019:         }
 1020: 
 1021:         (*(*psem).nopened)--;
 1022: 
 1023:         if ((*psem).shared == 0)
 1024:         {
 1025:             free((*psem).cnt);
 1026:             free((*psem).nopened);
 1027:         }
 1028:         else
 1029:         {
 1030:             if ((*(*psem).nopened) == 0)
 1031:             {
 1032:                 DosFreeMem((*psem).cnt);
 1033:             }
 1034:         }
 1035: 
 1036:         if ((*psem).allocated != 0)
 1037:         {
 1038:             free(psem);
 1039:         }
 1040: 
 1041:         return(0);
 1042: #   endif
 1043: }
 1044: 
 1045: int
 1046: sem_unlink_SysV(char *nom)
 1047: {
 1048:     // Détruit un sémaphore nommé créé par sem_open_SysV()
 1049: #   ifndef OS2 // IPCS_SYSV
 1050:         semctl(semget(ftok(nom, 1), 0, 0), 0, IPC_RMID);
 1051: 
 1052:         if (unlink(nom) == -1)
 1053:         {
 1054:             return(EACCES);
 1055:         }
 1056: 
 1057:         free(nom);
 1058:         return(0);
 1059: #   else
 1060:         return(0);
 1061: #   endif
 1062: }
 1063: 
 1064: #endif
 1065: 
 1066: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>