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