File:  [local] / rpl / src / semaphores.c
Revision 1.68: download - view: text, annotated - select for diffs - revision graph
Tue Jan 27 14:18:09 2015 UTC (9 years, 3 months ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_20, HEAD
Ajout d'un allocateur utilisant une mémoire cache.

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

CVSweb interface <joel.bertrand@systella.fr>