Annotation of rpl/src/semaphores.c, revision 1.56
1.1 bertrand 1: /*
2: ================================================================================
1.55 bertrand 3: RPL/2 (R) version 4.1.13
1.54 bertrand 4: Copyright (C) 1989-2013 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.56 ! bertrand 42: sprintf(fichier, "/RPL-%llu-%d", (unsigned long long) 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.56 ! bertrand 57: sprintf(fichier, "/RPL-%llu-%llu-%d", (unsigned long long) pid,
1.35 bertrand 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.48 bertrand 301: sprintf((*semaphore).path, "%s/RPL-SEMAPHORE-%d-%llX-%llX",
1.47 bertrand 302: racine_segment, (int) getpid(),
1.48 bertrand 303: (long long unsigned) pthread_self(),
304: (long long unsigned) semaphore);
1.32 bertrand 305:
1.33 bertrand 306: if ((desc = open((*semaphore).path, O_RDWR | O_CREAT | O_EXCL,
1.32 bertrand 307: S_IRUSR | S_IWUSR)) == -1)
308: {
309: free((*semaphore).path);
310: return(-1);
311: }
312:
313: (*semaphore).pid = getpid();
1.37 bertrand 314: (*semaphore).tid = pthread_self();
1.32 bertrand 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: }
1.8 bertrand 328:
1.32 bertrand 329: if ((*semaphore).sem == -1)
330: {
331: errno = EINVAL;
332: return(-1);
333: }
1.6 bertrand 334:
1.32 bertrand 335: argument.val = valeur;
336: ios = semctl((*semaphore).sem, 0, SETVAL, argument);
1.6 bertrand 337:
1.32 bertrand 338: return(ios);
339: # else // OS/2
1.39 bertrand 340: sem_t *psem;
1.9 bertrand 341:
1.39 bertrand 342: psem = semaphore;
1.9 bertrand 343:
1.39 bertrand 344: if (((*psem).cnt = malloc(sizeof(ULONG))) == NULL)
345: {
346: free(psem);
347: errno = ENOMEM;
348: return(-1);
349: }
1.9 bertrand 350:
1.39 bertrand 351: if (((*psem).nopened = malloc(sizeof(ULONG))) == NULL)
352: {
353: free((*psem).cnt);
354: free(psem);
355: errno = ENOMEM;
356: return(-1);
357: }
1.9 bertrand 358:
1.39 bertrand 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: }
1.9 bertrand 366:
1.39 bertrand 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: }
1.9 bertrand 376:
1.39 bertrand 377: (*(*psem).cnt) = valeur;
378: (*(*psem).nopened) = 1;
379: (*psem).shared = shared;
380: (*psem).allocated = 0;
1.9 bertrand 381:
1.39 bertrand 382: return(0);
1.9 bertrand 383: # endif
1.6 bertrand 384: }
385:
386: int
1.8 bertrand 387: sem_destroy_SysV(sem_t *semaphore)
1.6 bertrand 388: {
1.11 bertrand 389: // Détruit un sémaphore anonmyme
1.9 bertrand 390:
1.32 bertrand 391: # ifndef OS2 // IPCS_SYSV
392: if ((*semaphore).path != NULL)
393: {
394: return(EINVAL);
395: }
1.11 bertrand 396:
1.32 bertrand 397: if ((*semaphore).pid != getpid())
398: {
399: return(0);
400: }
1.11 bertrand 401:
1.32 bertrand 402: if (semctl((*semaphore).sem, 0, IPC_RMID) == -1)
403: {
404: return(EINVAL);
405: }
1.6 bertrand 406:
1.32 bertrand 407: return(0);
408: # else // OS/2
1.39 bertrand 409: sem_t *psem;
1.9 bertrand 410:
1.39 bertrand 411: psem = semaphore;
1.9 bertrand 412:
1.39 bertrand 413: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
414: {
415: return(EINVAL);
416: }
1.9 bertrand 417:
1.39 bertrand 418: if (DosCloseMutexSem((*psem).hmtx) != 0)
419: {
420: return(EINVAL);
421: }
1.9 bertrand 422:
1.39 bertrand 423: while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
424: {
425: DosPostEventSem((*psem).hev);
426: }
1.9 bertrand 427:
1.39 bertrand 428: (*(*psem).nopened)--;
1.9 bertrand 429:
1.39 bertrand 430: if ((*psem).shared == 0)
1.9 bertrand 431: {
1.39 bertrand 432: free((*psem).cnt);
433: free((*psem).nopened);
434: }
435: else
436: {
437: if ((*(*psem).nopened) == 0)
438: {
439: DosFreeMem((*psem).cnt);
440: }
1.9 bertrand 441: }
442:
1.39 bertrand 443: if ((*psem).allocated != 0)
444: {
445: free(psem);
446: }
1.9 bertrand 447:
1.39 bertrand 448: return(0);
1.9 bertrand 449: # endif
1.6 bertrand 450: }
451:
452: int
1.8 bertrand 453: sem_wait_SysV(sem_t *semaphore)
1.6 bertrand 454: {
1.32 bertrand 455: # ifndef OS2 // IPCS_SYSV
456: struct sembuf commande;
1.9 bertrand 457:
1.53 bertrand 458: // semop() ne renvoie pas EINTR sur un signal !
459:
1.32 bertrand 460: commande.sem_num = 0;
461: commande.sem_op = -1;
462: commande.sem_flg = 0;
463:
1.53 bertrand 464: if (semop((*semaphore).sem, &commande, 1) == -1)
1.32 bertrand 465: {
1.53 bertrand 466: if (errno != EAGAIN)
1.32 bertrand 467: {
468: errno = EINVAL;
469: return(-1);
470: }
1.53 bertrand 471: else
472: {
473: return(-1);
474: }
1.11 bertrand 475: }
1.9 bertrand 476:
1.32 bertrand 477: return(0);
478: # else // OS/2
1.39 bertrand 479: sem_t *psem;
1.9 bertrand 480:
1.39 bertrand 481: ULONG cnt;
1.9 bertrand 482:
1.39 bertrand 483: psem = semaphore;
1.9 bertrand 484:
1.39 bertrand 485: if (DosWaitEventSem((*psem).hev, SEM_INDEFINITE_WAIT) != 0)
486: {
487: errno = EINVAL;
488: return(-1);
489: }
1.9 bertrand 490:
1.39 bertrand 491: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
492: {
493: errno = EINVAL;
494: return(-1);
495: }
1.9 bertrand 496:
1.39 bertrand 497: if ((*(*psem).cnt) > 0)
498: {
499: (*(*psem).cnt)--;
500: }
1.9 bertrand 501:
1.39 bertrand 502: if ((*(*psem).cnt) == 0)
503: {
504: DosResetEventSem((*psem).hev, &cnt);
505: }
1.9 bertrand 506:
1.39 bertrand 507: DosReleaseMutexSem((*psem).hmtx);
508: return(0);
1.9 bertrand 509: # endif
1.6 bertrand 510: }
511:
512: int
1.8 bertrand 513: sem_trywait_SysV(sem_t *semaphore)
1.6 bertrand 514: {
1.32 bertrand 515: # ifndef OS2 // IPCS_SYSV
516: struct sembuf commande;
1.6 bertrand 517:
1.32 bertrand 518: commande.sem_num = 0;
519: commande.sem_op = -1;
520: commande.sem_flg = IPC_NOWAIT;
521:
1.53 bertrand 522: if (semop((*semaphore).sem, &commande, 1) == -1)
1.32 bertrand 523: {
1.53 bertrand 524: return(-1);
1.11 bertrand 525: }
1.9 bertrand 526:
1.32 bertrand 527: return(0);
528: # else // OS/2
1.39 bertrand 529: int ios;
1.9 bertrand 530:
1.39 bertrand 531: sem_t *psem;
1.9 bertrand 532:
1.39 bertrand 533: ULONG cnt;
1.9 bertrand 534:
1.39 bertrand 535: psem = semaphore;
1.9 bertrand 536:
1.39 bertrand 537: if ((ios = DosWaitEventSem((*psem).hev, SEM_IMMEDIATE_RETURN)) != 0)
538: {
539: errno = (ios == ERROR_TIMEOUT) ? EAGAIN : EINVAL;
540: return(-1);
541: }
1.9 bertrand 542:
1.39 bertrand 543: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
544: {
545: errno = EINVAL;
546: return(-1);
547: }
1.9 bertrand 548:
1.39 bertrand 549: if ((*(*psem).cnt) > 0)
550: {
551: (*(*psem).cnt)--;
552: }
1.9 bertrand 553:
1.39 bertrand 554: if ((*(*psem).cnt) == 0)
555: {
556: DosResetEventSem((*psem).hev, &cnt);
557: }
1.9 bertrand 558:
1.39 bertrand 559: DosReleaseMutexSem((*psem).hmtx);
560: return(0);
1.9 bertrand 561: # endif
1.6 bertrand 562: }
563:
1.47 bertrand 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:
1.6 bertrand 622: int
1.8 bertrand 623: sem_post_SysV(sem_t *semaphore)
1.6 bertrand 624: {
1.32 bertrand 625: # ifndef OS2 // IPCS_SYSV
626: struct sembuf commande;
1.9 bertrand 627:
1.32 bertrand 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: }
1.11 bertrand 639: }
1.9 bertrand 640:
1.32 bertrand 641: return(0);
642: # else // OS/2
1.39 bertrand 643: sem_t *psem;
1.9 bertrand 644:
1.39 bertrand 645: psem = semaphore;
1.9 bertrand 646:
1.39 bertrand 647: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
648: {
649: errno = EINVAL;
650: return(-1);
651: }
1.9 bertrand 652:
1.39 bertrand 653: (*(*psem).cnt)++;
654: DosPostEventSem((*psem).hev);
655: DosReleaseMutexSem((*psem).hmtx);
1.9 bertrand 656:
1.39 bertrand 657: return(0);
1.9 bertrand 658: # endif
1.6 bertrand 659: }
660:
661: int
1.8 bertrand 662: sem_getvalue_SysV(sem_t *semaphore, int *valeur)
1.6 bertrand 663: {
1.32 bertrand 664: # ifndef OS2 // IPCS_SYSV
665: (*valeur) = semctl((*semaphore).sem, 0, GETVAL);
1.9 bertrand 666:
1.32 bertrand 667: if ((*valeur) < 0)
668: {
669: return(EINVAL);
670: }
1.9 bertrand 671:
1.32 bertrand 672: return(0);
1.9 bertrand 673: # else
1.39 bertrand 674: sem_t *psem;
1.9 bertrand 675:
1.39 bertrand 676: psem = semaphore;
1.9 bertrand 677:
1.39 bertrand 678: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
679: {
680: errno = EINVAL;
681: return(-1);
682: }
1.9 bertrand 683:
1.39 bertrand 684: (*valeur) = (*(*psem).cnt);
685: DosReleaseMutexSem((*psem).hmtx);
1.9 bertrand 686:
1.39 bertrand 687: return(0);
1.9 bertrand 688: # endif
1.6 bertrand 689: }
690:
691: sem_t
1.8 bertrand 692: *sem_open_SysV(const char *nom, int oflag, ...)
1.6 bertrand 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:
1.9 bertrand 700: # ifndef OS2
1.32 bertrand 701: int desc;
1.10 bertrand 702:
1.32 bertrand 703: key_t clef;
1.10 bertrand 704:
1.32 bertrand 705: union semun argument;
1.9 bertrand 706: # endif
1.6 bertrand 707:
708: unsigned char *nom_absolu;
709:
710: unsigned int valeur;
711:
712: va_list liste;
713:
1.9 bertrand 714: # ifdef OS2
1.32 bertrand 715: sem_t *psem;
1.9 bertrand 716:
1.32 bertrand 717: PVOID base;
1.9 bertrand 718:
1.32 bertrand 719: unsigned char *ptr;
720: unsigned char *nom_segment;
1.9 bertrand 721: # endif
722:
1.32 bertrand 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: }
1.6 bertrand 729:
1.32 bertrand 730: sprintf(nom_absolu, "%s/%s", racine_segment, nom);
1.6 bertrand 731:
1.32 bertrand 732: if ((semaphore = malloc(sizeof(sem_t))) == NULL)
733: {
734: return(SEM_FAILED);
735: }
1.6 bertrand 736:
1.32 bertrand 737: (*semaphore).alloue = -1;
1.34 bertrand 738: (*semaphore).pid = getpid();
739: (*semaphore).tid = pthread_self();
1.9 bertrand 740: # else
1.39 bertrand 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;
1.9 bertrand 749:
1.39 bertrand 750: while((*ptr) != d_code_fin_chaine)
751: {
752: if ((*ptr) == '/')
753: {
754: (*ptr) = '\\';
755: }
1.9 bertrand 756:
1.39 bertrand 757: ptr++;
758: }
1.9 bertrand 759:
1.39 bertrand 760: if ((nom_absolu = malloc((strlen(racine_semaphores_OS2) + strlen(nom)
761: + 2) * sizeof(unsigned char))) == NULL)
1.9 bertrand 762: {
1.39 bertrand 763: return(SEM_FAILED);
1.9 bertrand 764: }
765:
1.39 bertrand 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: }
1.9 bertrand 775:
1.39 bertrand 776: ptr++;
777: }
1.9 bertrand 778:
1.39 bertrand 779: (*(ptr + 1)) = d_code_fin_chaine;
1.9 bertrand 780:
1.39 bertrand 781: if ((psem = malloc(sizeof(sem_t))) == NULL)
1.9 bertrand 782: {
1.39 bertrand 783: return(SEM_FAILED);
1.9 bertrand 784: }
785:
1.39 bertrand 786: (*psem).allocated = 1;
1.9 bertrand 787: # endif
788:
1.6 bertrand 789: if ((oflag & O_CREAT) == 0)
790: {
791: // 2 arguments
1.9 bertrand 792:
1.32 bertrand 793: # ifndef OS2 // IPCS_SYSV
794: clef = ftok(nom_absolu, 1);
1.9 bertrand 795:
1.32 bertrand 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
1.39 bertrand 813: if ((psem = malloc(sizeof(sem_t))) == NULL)
814: {
815: free(nom_absolu);
816: free(nom_segment);
817: return(SEM_FAILED);
818: }
1.9 bertrand 819:
1.39 bertrand 820: (*ptr) = 'M';
1.9 bertrand 821:
1.39 bertrand 822: if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0)
823: {
824: free(psem);
825: free(nom_absolu);
826: free(nom_segment);
1.9 bertrand 827:
1.39 bertrand 828: return(SEM_FAILED);
829: }
1.9 bertrand 830:
1.39 bertrand 831: (*ptr) = 'S';
1.9 bertrand 832:
1.39 bertrand 833: if (DosOpenEventSem(nom_absolu, &((*psem).hev)) != 0)
834: {
835: DosCloseMutexSem((*psem).hmtx);
1.9 bertrand 836:
1.39 bertrand 837: free(psem);
838: free(nom_absolu);
839: free(nom_segment);
1.9 bertrand 840:
1.39 bertrand 841: return(SEM_FAILED);
842: }
1.9 bertrand 843:
1.39 bertrand 844: if (DosGetNamedSharedMem(&base, nom_segment, PAG_WRITE | PAG_READ)
845: != 0)
846: {
847: DosCloseMutexSem((*psem).hmtx);
1.9 bertrand 848:
1.39 bertrand 849: free(nom_absolu);
850: free(nom_segment);
851: free(psem);
1.9 bertrand 852:
1.39 bertrand 853: return(SEM_FAILED);
854: }
1.9 bertrand 855:
1.39 bertrand 856: free(nom_segment);
1.9 bertrand 857:
1.39 bertrand 858: (*psem).cnt = (ULONG *) base;
859: (*psem).nopened = ((ULONG *) base) + 1;
860: (*psem).shared = 1;
1.9 bertrand 861:
1.39 bertrand 862: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
863: {
864: DosCloseMutexSem((*psem).hmtx);
1.9 bertrand 865:
1.39 bertrand 866: free(nom_absolu);
867: free(nom_segment);
868: free(psem);
1.9 bertrand 869:
1.39 bertrand 870: return(SEM_FAILED);
871: }
1.9 bertrand 872:
1.39 bertrand 873: (*((*psem).nopened))++;
1.9 bertrand 874:
1.39 bertrand 875: DosReleaseMutexSem((*psem).hmtx);
1.9 bertrand 876:
1.39 bertrand 877: semaphore = psem;
1.9 bertrand 878: # endif
1.6 bertrand 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:
1.32 bertrand 892: # ifndef OS2 // IPCS_SYSV
1.33 bertrand 893: if ((desc = open(nom_absolu, O_CREAT | O_EXCL | O_RDWR,
894: S_IRUSR | S_IWUSR)) == -1)
1.32 bertrand 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
1.39 bertrand 931: if ((psem = malloc(sizeof(sem_t))) == NULL)
932: {
933: free(nom_absolu);
934: free(nom_segment);
1.9 bertrand 935:
1.39 bertrand 936: return(SEM_FAILED);
937: }
1.9 bertrand 938:
1.39 bertrand 939: (*ptr) = 'M';
1.9 bertrand 940:
1.39 bertrand 941: if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0)
942: {
943: free(psem);
944: free(nom_absolu);
945: free(nom_segment);
1.9 bertrand 946:
1.39 bertrand 947: return(SEM_FAILED);
948: }
1.9 bertrand 949:
1.39 bertrand 950: (*ptr) = 'S';
1.9 bertrand 951:
1.39 bertrand 952: if (DosCreateEventSem(nom_absolu, &((*psem).hev), 0,
953: (valeur != 0) ? 1 : 0) != 0)
954: {
955: DosCloseMutexSem((*psem).hmtx);
1.9 bertrand 956:
1.39 bertrand 957: free(nom_absolu);
958: free(nom_segment);
959: free(psem);
960:
961: return(SEM_FAILED);
962: }
1.9 bertrand 963:
1.39 bertrand 964: if (DosAllocSharedMem(&base, nom_segment, 2 * sizeof(ULONG),
965: PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
966: {
967: DosCloseMutexSem((*psem).hmtx);
1.9 bertrand 968:
1.39 bertrand 969: free(nom_absolu);
970: free(nom_segment);
971: free(psem);
1.9 bertrand 972:
1.39 bertrand 973: return(SEM_FAILED);
974: }
1.9 bertrand 975:
976: free(nom_segment);
977:
1.39 bertrand 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;
1.9 bertrand 984: # endif
1.6 bertrand 985: }
986:
1.8 bertrand 987: return(semaphore);
1.6 bertrand 988: }
989:
990: int
1.8 bertrand 991: sem_close_SysV(sem_t *semaphore)
1.6 bertrand 992: {
1.11 bertrand 993: // Ferme un sémaphore nommé créé par sem_open_SysV()
1.32 bertrand 994: # ifndef OS2 // IPCS_SYSV
995: if ((*semaphore).path != NULL)
996: {
997: free((*semaphore).path);
998: }
1.9 bertrand 999:
1.32 bertrand 1000: if ((*semaphore).alloue == -1)
1001: {
1002: free(semaphore);
1003: }
1.9 bertrand 1004:
1.32 bertrand 1005: return(0);
1.9 bertrand 1006: # else
1.39 bertrand 1007: sem_t *psem;
1.9 bertrand 1008:
1.39 bertrand 1009: psem = semaphore;
1.9 bertrand 1010:
1.39 bertrand 1011: if (DosCloseMutexSem((*psem).hmtx) != 0)
1012: {
1013: return(EINVAL);
1014: }
1.9 bertrand 1015:
1.39 bertrand 1016: while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
1017: {
1018: DosPostEventSem((*psem).hev);
1019: }
1.9 bertrand 1020:
1.39 bertrand 1021: (*(*psem).nopened)--;
1.9 bertrand 1022:
1.39 bertrand 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: }
1.9 bertrand 1035:
1.39 bertrand 1036: if ((*psem).allocated != 0)
1.9 bertrand 1037: {
1.39 bertrand 1038: free(psem);
1.9 bertrand 1039: }
1040:
1.39 bertrand 1041: return(0);
1.9 bertrand 1042: # endif
1.6 bertrand 1043: }
1044:
1045: int
1.47 bertrand 1046: sem_unlink_SysV(char *nom)
1.6 bertrand 1047: {
1.11 bertrand 1048: // Détruit un sémaphore nommé créé par sem_open_SysV()
1.32 bertrand 1049: # ifndef OS2 // IPCS_SYSV
1.37 bertrand 1050: semctl(semget(ftok(nom, 1), 0, 0), 0, IPC_RMID);
1.6 bertrand 1051:
1.37 bertrand 1052: if (unlink(nom) == -1)
1.32 bertrand 1053: {
1054: return(EACCES);
1055: }
1.6 bertrand 1056:
1.38 bertrand 1057: free(nom);
1.32 bertrand 1058: return(0);
1.9 bertrand 1059: # else
1.39 bertrand 1060: return(0);
1.9 bertrand 1061: # endif
1.6 bertrand 1062: }
1063:
1064: #endif
1065:
1.1 bertrand 1066: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>