Annotation of rpl/src/semaphores.c, revision 1.47
1.1 bertrand 1: /*
2: ================================================================================
1.45 bertrand 3: RPL/2 (R) version 4.1.9
1.41 bertrand 4: Copyright (C) 1989-2012 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",
1.47 ! bertrand 302: racine_segment, (int) getpid(),
! 303: (long long unsigned) pthread_self(), shared);
1.32 bertrand 304:
1.33 bertrand 305: if ((desc = open((*semaphore).path, O_RDWR | O_CREAT | O_EXCL,
1.32 bertrand 306: S_IRUSR | S_IWUSR)) == -1)
307: {
308: free((*semaphore).path);
309: return(-1);
310: }
311:
312: (*semaphore).pid = getpid();
1.37 bertrand 313: (*semaphore).tid = pthread_self();
1.32 bertrand 314: clef = ftok((*semaphore).path, 1);
315: close(desc);
316:
317: if (clef == -1)
318: {
319: free((*semaphore).path);
320: return(-1);
321: }
322:
323: (*semaphore).alloue = 0;
324: (*semaphore).sem = semget(clef, 1, IPC_CREAT | IPC_EXCL |
325: S_IRUSR | S_IWUSR);
326: }
1.8 bertrand 327:
1.32 bertrand 328: if ((*semaphore).sem == -1)
329: {
330: errno = EINVAL;
331: return(-1);
332: }
1.6 bertrand 333:
1.32 bertrand 334: argument.val = valeur;
335: ios = semctl((*semaphore).sem, 0, SETVAL, argument);
1.6 bertrand 336:
1.32 bertrand 337: return(ios);
338: # else // OS/2
1.39 bertrand 339: sem_t *psem;
1.9 bertrand 340:
1.39 bertrand 341: psem = semaphore;
1.9 bertrand 342:
1.39 bertrand 343: if (((*psem).cnt = malloc(sizeof(ULONG))) == NULL)
344: {
345: free(psem);
346: errno = ENOMEM;
347: return(-1);
348: }
1.9 bertrand 349:
1.39 bertrand 350: if (((*psem).nopened = malloc(sizeof(ULONG))) == NULL)
351: {
352: free((*psem).cnt);
353: free(psem);
354: errno = ENOMEM;
355: return(-1);
356: }
1.9 bertrand 357:
1.39 bertrand 358: if (DosCreateMutexSem(NULL, &((*psem).hmtx), 0, 0) != 0)
359: {
360: free((*psem).cnt);
361: free((*psem).nopened);
362: free(psem);
363: return(-1);
364: }
1.9 bertrand 365:
1.39 bertrand 366: if (DosCreateEventSem(NULL, &((*psem).hev), 0, (valeur != 0) ? 1 : 0)
367: != 0)
368: {
369: DosCloseMutexSem((*psem).hmtx);
370: free((*psem).cnt);
371: free((*psem).nopened);
372: free(psem);
373: return(-1);
374: }
1.9 bertrand 375:
1.39 bertrand 376: (*(*psem).cnt) = valeur;
377: (*(*psem).nopened) = 1;
378: (*psem).shared = shared;
379: (*psem).allocated = 0;
1.9 bertrand 380:
1.39 bertrand 381: return(0);
1.9 bertrand 382: # endif
1.6 bertrand 383: }
384:
385: int
1.8 bertrand 386: sem_destroy_SysV(sem_t *semaphore)
1.6 bertrand 387: {
1.11 bertrand 388: // Détruit un sémaphore anonmyme
1.9 bertrand 389:
1.32 bertrand 390: # ifndef OS2 // IPCS_SYSV
391: if ((*semaphore).path != NULL)
392: {
393: return(EINVAL);
394: }
1.11 bertrand 395:
1.32 bertrand 396: if ((*semaphore).pid != getpid())
397: {
398: return(0);
399: }
1.11 bertrand 400:
1.32 bertrand 401: if (semctl((*semaphore).sem, 0, IPC_RMID) == -1)
402: {
403: return(EINVAL);
404: }
1.6 bertrand 405:
1.32 bertrand 406: return(0);
407: # else // OS/2
1.39 bertrand 408: sem_t *psem;
1.9 bertrand 409:
1.39 bertrand 410: psem = semaphore;
1.9 bertrand 411:
1.39 bertrand 412: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
413: {
414: return(EINVAL);
415: }
1.9 bertrand 416:
1.39 bertrand 417: if (DosCloseMutexSem((*psem).hmtx) != 0)
418: {
419: return(EINVAL);
420: }
1.9 bertrand 421:
1.39 bertrand 422: while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
423: {
424: DosPostEventSem((*psem).hev);
425: }
1.9 bertrand 426:
1.39 bertrand 427: (*(*psem).nopened)--;
1.9 bertrand 428:
1.39 bertrand 429: if ((*psem).shared == 0)
1.9 bertrand 430: {
1.39 bertrand 431: free((*psem).cnt);
432: free((*psem).nopened);
433: }
434: else
435: {
436: if ((*(*psem).nopened) == 0)
437: {
438: DosFreeMem((*psem).cnt);
439: }
1.9 bertrand 440: }
441:
1.39 bertrand 442: if ((*psem).allocated != 0)
443: {
444: free(psem);
445: }
1.9 bertrand 446:
1.39 bertrand 447: return(0);
1.9 bertrand 448: # endif
1.6 bertrand 449: }
450:
451: int
1.8 bertrand 452: sem_wait_SysV(sem_t *semaphore)
1.6 bertrand 453: {
1.32 bertrand 454: # ifndef OS2 // IPCS_SYSV
455: struct sembuf commande;
1.9 bertrand 456:
1.32 bertrand 457: commande.sem_num = 0;
458: commande.sem_op = -1;
459: commande.sem_flg = 0;
460:
461: while(semop((*semaphore).sem, &commande, 1) == -1)
462: {
463: if (errno != EINTR)
464: {
465: errno = EINVAL;
466: return(-1);
467: }
1.11 bertrand 468: }
1.9 bertrand 469:
1.32 bertrand 470: return(0);
471: # else // OS/2
1.39 bertrand 472: sem_t *psem;
1.9 bertrand 473:
1.39 bertrand 474: ULONG cnt;
1.9 bertrand 475:
1.39 bertrand 476: psem = semaphore;
1.9 bertrand 477:
1.39 bertrand 478: if (DosWaitEventSem((*psem).hev, SEM_INDEFINITE_WAIT) != 0)
479: {
480: errno = EINVAL;
481: return(-1);
482: }
1.9 bertrand 483:
1.39 bertrand 484: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
485: {
486: errno = EINVAL;
487: return(-1);
488: }
1.9 bertrand 489:
1.39 bertrand 490: if ((*(*psem).cnt) > 0)
491: {
492: (*(*psem).cnt)--;
493: }
1.9 bertrand 494:
1.39 bertrand 495: if ((*(*psem).cnt) == 0)
496: {
497: DosResetEventSem((*psem).hev, &cnt);
498: }
1.9 bertrand 499:
1.39 bertrand 500: DosReleaseMutexSem((*psem).hmtx);
501: return(0);
1.9 bertrand 502: # endif
1.6 bertrand 503: }
504:
505: int
1.8 bertrand 506: sem_trywait_SysV(sem_t *semaphore)
1.6 bertrand 507: {
1.32 bertrand 508: # ifndef OS2 // IPCS_SYSV
509: struct sembuf commande;
1.6 bertrand 510:
1.32 bertrand 511: commande.sem_num = 0;
512: commande.sem_op = -1;
513: commande.sem_flg = IPC_NOWAIT;
514:
515: while(semop((*semaphore).sem, &commande, 1) == -1)
516: {
517: if (errno != EINTR)
518: {
519: errno = EINVAL;
520: return(-1);
521: }
1.11 bertrand 522: }
1.9 bertrand 523:
1.32 bertrand 524: return(0);
525: # else // OS/2
1.39 bertrand 526: int ios;
1.9 bertrand 527:
1.39 bertrand 528: sem_t *psem;
1.9 bertrand 529:
1.39 bertrand 530: ULONG cnt;
1.9 bertrand 531:
1.39 bertrand 532: psem = semaphore;
1.9 bertrand 533:
1.39 bertrand 534: if ((ios = DosWaitEventSem((*psem).hev, SEM_IMMEDIATE_RETURN)) != 0)
535: {
536: errno = (ios == ERROR_TIMEOUT) ? EAGAIN : EINVAL;
537: return(-1);
538: }
1.9 bertrand 539:
1.39 bertrand 540: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
541: {
542: errno = EINVAL;
543: return(-1);
544: }
1.9 bertrand 545:
1.39 bertrand 546: if ((*(*psem).cnt) > 0)
547: {
548: (*(*psem).cnt)--;
549: }
1.9 bertrand 550:
1.39 bertrand 551: if ((*(*psem).cnt) == 0)
552: {
553: DosResetEventSem((*psem).hev, &cnt);
554: }
1.9 bertrand 555:
1.39 bertrand 556: DosReleaseMutexSem((*psem).hmtx);
557: return(0);
1.9 bertrand 558: # endif
1.6 bertrand 559: }
560:
1.47 ! bertrand 561: #ifndef timespeccmp
! 562: # define timespeccmp(tsp, usp, cmp) \
! 563: (((tsp)->tv_sec == (usp)->tv_sec) ? \
! 564: ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
! 565: ((tsp)->tv_sec cmp (usp)->tv_sec))
! 566: # define timespecadd(tsp, usp, vsp) \
! 567: do { \
! 568: (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \
! 569: (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \
! 570: if ((vsp)->tv_nsec >= 1000000000L) { \
! 571: (vsp)->tv_sec++; \
! 572: (vsp)->tv_nsec -= 1000000000L; \
! 573: } \
! 574: } while(0)
! 575: # define timespecsub(tsp, usp, vsp) \
! 576: do { \
! 577: (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \
! 578: (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \
! 579: if ((vsp)->tv_nsec < 0) { \
! 580: (vsp)->tv_sec--; \
! 581: (vsp)->tv_nsec += 1000000000L; \
! 582: } \
! 583: } while(0)
! 584: #endif
! 585:
! 586: int
! 587: sem_timedwait_SysV(sem_t *sem, struct timespec *ts)
! 588: {
! 589: struct timespec onems = { 0, 1000000 };
! 590: struct timespec total = { 0, 0 };
! 591: struct timespec unslept;
! 592: struct timespec elapsed;
! 593: struct timespec tmp;
! 594:
! 595: while(timespeccmp(ts, &total, >))
! 596: {
! 597: if (sem_trywait_SysV(sem) == 0)
! 598: {
! 599: return(0);
! 600: }
! 601:
! 602: if (errno != EAGAIN)
! 603: {
! 604: return(-1);
! 605: }
! 606:
! 607: nanosleep(&onems, &unslept);
! 608:
! 609: timespecsub(&onems, &unslept, &elapsed);
! 610: timespecadd(&total, &elapsed, &tmp);
! 611: total.tv_sec = tmp.tv_sec;
! 612: total.tv_nsec = tmp.tv_nsec;
! 613: }
! 614:
! 615: errno = ETIMEDOUT;
! 616: return(-1);
! 617: }
! 618:
1.6 bertrand 619: int
1.8 bertrand 620: sem_post_SysV(sem_t *semaphore)
1.6 bertrand 621: {
1.32 bertrand 622: # ifndef OS2 // IPCS_SYSV
623: struct sembuf commande;
1.9 bertrand 624:
1.32 bertrand 625: commande.sem_num = 0;
626: commande.sem_op = 1;
627: commande.sem_flg = 0;
628:
629: while(semop((*semaphore).sem, &commande, 1) == -1)
630: {
631: if (errno != EINTR)
632: {
633: errno = EINVAL;
634: return(-1);
635: }
1.11 bertrand 636: }
1.9 bertrand 637:
1.32 bertrand 638: return(0);
639: # else // OS/2
1.39 bertrand 640: sem_t *psem;
1.9 bertrand 641:
1.39 bertrand 642: psem = semaphore;
1.9 bertrand 643:
1.39 bertrand 644: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
645: {
646: errno = EINVAL;
647: return(-1);
648: }
1.9 bertrand 649:
1.39 bertrand 650: (*(*psem).cnt)++;
651: DosPostEventSem((*psem).hev);
652: DosReleaseMutexSem((*psem).hmtx);
1.9 bertrand 653:
1.39 bertrand 654: return(0);
1.9 bertrand 655: # endif
1.6 bertrand 656: }
657:
658: int
1.8 bertrand 659: sem_getvalue_SysV(sem_t *semaphore, int *valeur)
1.6 bertrand 660: {
1.32 bertrand 661: # ifndef OS2 // IPCS_SYSV
662: (*valeur) = semctl((*semaphore).sem, 0, GETVAL);
1.9 bertrand 663:
1.32 bertrand 664: if ((*valeur) < 0)
665: {
666: return(EINVAL);
667: }
1.9 bertrand 668:
1.32 bertrand 669: return(0);
1.9 bertrand 670: # else
1.39 bertrand 671: sem_t *psem;
1.9 bertrand 672:
1.39 bertrand 673: psem = semaphore;
1.9 bertrand 674:
1.39 bertrand 675: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
676: {
677: errno = EINVAL;
678: return(-1);
679: }
1.9 bertrand 680:
1.39 bertrand 681: (*valeur) = (*(*psem).cnt);
682: DosReleaseMutexSem((*psem).hmtx);
1.9 bertrand 683:
1.39 bertrand 684: return(0);
1.9 bertrand 685: # endif
1.6 bertrand 686: }
687:
688: sem_t
1.8 bertrand 689: *sem_open_SysV(const char *nom, int oflag, ...)
1.6 bertrand 690: //*sem_open(const char *nom, int oflag)
691: //*sem_open(const char *nom, int oflag, mode_t mode, unsigned int value)
692: {
693: mode_t mode;
694:
695: sem_t *semaphore;
696:
1.9 bertrand 697: # ifndef OS2
1.32 bertrand 698: int desc;
1.10 bertrand 699:
1.32 bertrand 700: key_t clef;
1.10 bertrand 701:
1.32 bertrand 702: union semun argument;
1.9 bertrand 703: # endif
1.6 bertrand 704:
705: unsigned char *nom_absolu;
706:
707: unsigned int valeur;
708:
709: va_list liste;
710:
1.9 bertrand 711: # ifdef OS2
1.32 bertrand 712: sem_t *psem;
1.9 bertrand 713:
1.32 bertrand 714: PVOID base;
1.9 bertrand 715:
1.32 bertrand 716: unsigned char *ptr;
717: unsigned char *nom_segment;
1.9 bertrand 718: # endif
719:
1.32 bertrand 720: # ifndef OS2 // IPCS_SYSV
721: if ((nom_absolu = malloc((strlen(racine_segment) + strlen(nom)
722: + 2) * sizeof(unsigned char))) == NULL)
723: {
724: return(SEM_FAILED);
725: }
1.6 bertrand 726:
1.32 bertrand 727: sprintf(nom_absolu, "%s/%s", racine_segment, nom);
1.6 bertrand 728:
1.32 bertrand 729: if ((semaphore = malloc(sizeof(sem_t))) == NULL)
730: {
731: return(SEM_FAILED);
732: }
1.6 bertrand 733:
1.32 bertrand 734: (*semaphore).alloue = -1;
1.34 bertrand 735: (*semaphore).pid = getpid();
736: (*semaphore).tid = pthread_self();
1.9 bertrand 737: # else
1.39 bertrand 738: if ((nom_segment = malloc((strlen(racine_memoire_OS2) + strlen(nom) + 1)
739: * sizeof(unsigned char))) == NULL)
740: {
741: return(SEM_FAILED);
742: }
743:
744: sprintf(nom_segment, "%s%s", racine_memoire_OS2, nom);
745: ptr = nom_segment;
1.9 bertrand 746:
1.39 bertrand 747: while((*ptr) != d_code_fin_chaine)
748: {
749: if ((*ptr) == '/')
750: {
751: (*ptr) = '\\';
752: }
1.9 bertrand 753:
1.39 bertrand 754: ptr++;
755: }
1.9 bertrand 756:
1.39 bertrand 757: if ((nom_absolu = malloc((strlen(racine_semaphores_OS2) + strlen(nom)
758: + 2) * sizeof(unsigned char))) == NULL)
1.9 bertrand 759: {
1.39 bertrand 760: return(SEM_FAILED);
1.9 bertrand 761: }
762:
1.39 bertrand 763: sprintf(nom_absolu, "%s%s", racine_semaphores_OS2, nom);
764: ptr = nom_absolu;
765:
766: while((*ptr) != d_code_fin_chaine)
767: {
768: if ((*ptr) == '/')
769: {
770: (*ptr) = '\\';
771: }
1.9 bertrand 772:
1.39 bertrand 773: ptr++;
774: }
1.9 bertrand 775:
1.39 bertrand 776: (*(ptr + 1)) = d_code_fin_chaine;
1.9 bertrand 777:
1.39 bertrand 778: if ((psem = malloc(sizeof(sem_t))) == NULL)
1.9 bertrand 779: {
1.39 bertrand 780: return(SEM_FAILED);
1.9 bertrand 781: }
782:
1.39 bertrand 783: (*psem).allocated = 1;
1.9 bertrand 784: # endif
785:
1.6 bertrand 786: if ((oflag & O_CREAT) == 0)
787: {
788: // 2 arguments
1.9 bertrand 789:
1.32 bertrand 790: # ifndef OS2 // IPCS_SYSV
791: clef = ftok(nom_absolu, 1);
1.9 bertrand 792:
1.32 bertrand 793: if (clef == -1)
794: {
795: return(SEM_FAILED);
796: }
797:
798: (*semaphore).sem = semget(clef, 0, 0);
799: (*semaphore).path = nom_absolu;
800: (*semaphore).pid = getpid();
801:
802: if ((*semaphore).sem == -1)
803: {
804: free(semaphore);
805: free(nom_absolu);
806:
807: return(SEM_FAILED);
808: }
809: # else // OS/2
1.39 bertrand 810: if ((psem = malloc(sizeof(sem_t))) == NULL)
811: {
812: free(nom_absolu);
813: free(nom_segment);
814: return(SEM_FAILED);
815: }
1.9 bertrand 816:
1.39 bertrand 817: (*ptr) = 'M';
1.9 bertrand 818:
1.39 bertrand 819: if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0)
820: {
821: free(psem);
822: free(nom_absolu);
823: free(nom_segment);
1.9 bertrand 824:
1.39 bertrand 825: return(SEM_FAILED);
826: }
1.9 bertrand 827:
1.39 bertrand 828: (*ptr) = 'S';
1.9 bertrand 829:
1.39 bertrand 830: if (DosOpenEventSem(nom_absolu, &((*psem).hev)) != 0)
831: {
832: DosCloseMutexSem((*psem).hmtx);
1.9 bertrand 833:
1.39 bertrand 834: free(psem);
835: free(nom_absolu);
836: free(nom_segment);
1.9 bertrand 837:
1.39 bertrand 838: return(SEM_FAILED);
839: }
1.9 bertrand 840:
1.39 bertrand 841: if (DosGetNamedSharedMem(&base, nom_segment, PAG_WRITE | PAG_READ)
842: != 0)
843: {
844: DosCloseMutexSem((*psem).hmtx);
1.9 bertrand 845:
1.39 bertrand 846: free(nom_absolu);
847: free(nom_segment);
848: free(psem);
1.9 bertrand 849:
1.39 bertrand 850: return(SEM_FAILED);
851: }
1.9 bertrand 852:
1.39 bertrand 853: free(nom_segment);
1.9 bertrand 854:
1.39 bertrand 855: (*psem).cnt = (ULONG *) base;
856: (*psem).nopened = ((ULONG *) base) + 1;
857: (*psem).shared = 1;
1.9 bertrand 858:
1.39 bertrand 859: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
860: {
861: DosCloseMutexSem((*psem).hmtx);
1.9 bertrand 862:
1.39 bertrand 863: free(nom_absolu);
864: free(nom_segment);
865: free(psem);
1.9 bertrand 866:
1.39 bertrand 867: return(SEM_FAILED);
868: }
1.9 bertrand 869:
1.39 bertrand 870: (*((*psem).nopened))++;
1.9 bertrand 871:
1.39 bertrand 872: DosReleaseMutexSem((*psem).hmtx);
1.9 bertrand 873:
1.39 bertrand 874: semaphore = psem;
1.9 bertrand 875: # endif
1.6 bertrand 876: }
877: else
878: {
879: // 4 arguments
880:
881: // O_CREAT O_EXCL
882: // S_IRUSR S_IWUSR
883:
884: va_start(liste, oflag);
885: mode = va_arg(liste, mode_t);
886: valeur = va_arg(liste, unsigned int);
887: va_end(liste);
888:
1.32 bertrand 889: # ifndef OS2 // IPCS_SYSV
1.33 bertrand 890: if ((desc = open(nom_absolu, O_CREAT | O_EXCL | O_RDWR,
891: S_IRUSR | S_IWUSR)) == -1)
1.32 bertrand 892: {
893: free(semaphore);
894: free(nom_absolu);
895:
896: return(SEM_FAILED);
897: }
898:
899: if ((clef = ftok(nom_absolu, 1)) == -1)
900: {
901: close(desc);
902: free(semaphore);
903: free(nom_absolu);
904:
905: return(SEM_FAILED);
906: }
907:
908: close(desc);
909:
910: (*semaphore).sem = semget(clef, 1,
911: (((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT) |
912: (((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL) |
913: (int) mode);
914: (*semaphore).path = nom_absolu;
915: (*semaphore).pid = getpid();
916:
917: if ((*semaphore).sem == -1)
918: {
919: free(semaphore);
920: free(nom_absolu);
921:
922: return(SEM_FAILED);
923: }
924:
925: argument.val = valeur;
926: semctl((*semaphore).sem, 0, SETVAL, argument);
927: # else // OS/2
1.39 bertrand 928: if ((psem = malloc(sizeof(sem_t))) == NULL)
929: {
930: free(nom_absolu);
931: free(nom_segment);
1.9 bertrand 932:
1.39 bertrand 933: return(SEM_FAILED);
934: }
1.9 bertrand 935:
1.39 bertrand 936: (*ptr) = 'M';
1.9 bertrand 937:
1.39 bertrand 938: if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0)
939: {
940: free(psem);
941: free(nom_absolu);
942: free(nom_segment);
1.9 bertrand 943:
1.39 bertrand 944: return(SEM_FAILED);
945: }
1.9 bertrand 946:
1.39 bertrand 947: (*ptr) = 'S';
1.9 bertrand 948:
1.39 bertrand 949: if (DosCreateEventSem(nom_absolu, &((*psem).hev), 0,
950: (valeur != 0) ? 1 : 0) != 0)
951: {
952: DosCloseMutexSem((*psem).hmtx);
1.9 bertrand 953:
1.39 bertrand 954: free(nom_absolu);
955: free(nom_segment);
956: free(psem);
957:
958: return(SEM_FAILED);
959: }
1.9 bertrand 960:
1.39 bertrand 961: if (DosAllocSharedMem(&base, nom_segment, 2 * sizeof(ULONG),
962: PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
963: {
964: DosCloseMutexSem((*psem).hmtx);
1.9 bertrand 965:
1.39 bertrand 966: free(nom_absolu);
967: free(nom_segment);
968: free(psem);
1.9 bertrand 969:
1.39 bertrand 970: return(SEM_FAILED);
971: }
1.9 bertrand 972:
973: free(nom_segment);
974:
1.39 bertrand 975: (*psem).cnt = (ULONG *) base;
976: (*psem).nopened = ((ULONG *) base) + 1;
977: (*(*psem).cnt) = valeur;
978: (*(*psem).nopened) = 1;
979: (*psem).shared = 1;
980: semaphore = psem;
1.9 bertrand 981: # endif
1.6 bertrand 982: }
983:
1.8 bertrand 984: return(semaphore);
1.6 bertrand 985: }
986:
987: int
1.8 bertrand 988: sem_close_SysV(sem_t *semaphore)
1.6 bertrand 989: {
1.11 bertrand 990: // Ferme un sémaphore nommé créé par sem_open_SysV()
1.32 bertrand 991: # ifndef OS2 // IPCS_SYSV
992: if ((*semaphore).path != NULL)
993: {
994: free((*semaphore).path);
995: }
1.9 bertrand 996:
1.32 bertrand 997: if ((*semaphore).alloue == -1)
998: {
999: free(semaphore);
1000: }
1.9 bertrand 1001:
1.32 bertrand 1002: return(0);
1.9 bertrand 1003: # else
1.39 bertrand 1004: sem_t *psem;
1.9 bertrand 1005:
1.39 bertrand 1006: psem = semaphore;
1.9 bertrand 1007:
1.39 bertrand 1008: if (DosCloseMutexSem((*psem).hmtx) != 0)
1009: {
1010: return(EINVAL);
1011: }
1.9 bertrand 1012:
1.39 bertrand 1013: while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
1014: {
1015: DosPostEventSem((*psem).hev);
1016: }
1.9 bertrand 1017:
1.39 bertrand 1018: (*(*psem).nopened)--;
1.9 bertrand 1019:
1.39 bertrand 1020: if ((*psem).shared == 0)
1021: {
1022: free((*psem).cnt);
1023: free((*psem).nopened);
1024: }
1025: else
1026: {
1027: if ((*(*psem).nopened) == 0)
1028: {
1029: DosFreeMem((*psem).cnt);
1030: }
1031: }
1.9 bertrand 1032:
1.39 bertrand 1033: if ((*psem).allocated != 0)
1.9 bertrand 1034: {
1.39 bertrand 1035: free(psem);
1.9 bertrand 1036: }
1037:
1.39 bertrand 1038: return(0);
1.9 bertrand 1039: # endif
1.6 bertrand 1040: }
1041:
1042: int
1.47 ! bertrand 1043: sem_unlink_SysV(char *nom)
1.6 bertrand 1044: {
1.11 bertrand 1045: // Détruit un sémaphore nommé créé par sem_open_SysV()
1.32 bertrand 1046: # ifndef OS2 // IPCS_SYSV
1.37 bertrand 1047: semctl(semget(ftok(nom, 1), 0, 0), 0, IPC_RMID);
1.6 bertrand 1048:
1.37 bertrand 1049: if (unlink(nom) == -1)
1.32 bertrand 1050: {
1051: return(EACCES);
1052: }
1.6 bertrand 1053:
1.38 bertrand 1054: free(nom);
1.32 bertrand 1055: return(0);
1.9 bertrand 1056: # else
1.39 bertrand 1057: return(0);
1.9 bertrand 1058: # endif
1.6 bertrand 1059: }
1060:
1061: #endif
1062:
1.1 bertrand 1063: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>