Annotation of rpl/src/semaphores.c, revision 1.75
1.1 bertrand 1: /*
2: ================================================================================
1.73 bertrand 3: RPL/2 (R) version 4.1.25
4: Copyright (C) 1989-2016 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.29 bertrand 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 *
1.35 bertrand 31: nom_segment_semaphore(pid_t pid, int ordre)
1.29 bertrand 32: {
33: unsigned char *fichier;
34:
1.68 bertrand 35: if ((fichier = sys_malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL)
1.29 bertrand 36: {
37: return(NULL);
38: }
39:
1.56 bertrand 40: sprintf(fichier, "/RPL-%llu-%d", (unsigned long long) pid, ordre);
1.34 bertrand 41: return(fichier);
42: }
43:
44:
45: static unsigned char *
1.35 bertrand 46: nom_segment_semaphore_thread(pid_t pid, pthread_t tid, int ordre)
1.34 bertrand 47: {
48: unsigned char *fichier;
49:
1.68 bertrand 50: if ((fichier = sys_malloc((1 + 256 + 1) * sizeof(unsigned char))) == NULL)
1.34 bertrand 51: {
52: return(NULL);
53: }
54:
1.56 bertrand 55: sprintf(fichier, "/RPL-%llu-%llu-%d", (unsigned long long) pid,
1.35 bertrand 56: (unsigned long long) tid, ordre);
1.29 bertrand 57: return(fichier);
58: }
59:
60:
1.1 bertrand 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 *
1.35 bertrand 74: sem_init2(unsigned int valeur, pid_t pid, int ordre)
1.1 bertrand 75: {
1.29 bertrand 76: sem_t *semaphore;
77:
78: unsigned char *chemin;
79:
1.35 bertrand 80: if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL)
1.29 bertrand 81: {
82: return(SEM_FAILED);
83: }
84:
1.75 ! bertrand 85: semaphore = sem_open(chemin, O_RDWR | O_CREAT /*| O_EXCL*/,
! 86: S_IRUSR | S_IWUSR, valeur);
1.68 bertrand 87: sys_free(chemin);
1.29 bertrand 88:
1.34 bertrand 89: return(semaphore);
90: }
91:
92:
93: sem_t *
1.35 bertrand 94: sem_init3(unsigned int valeur, pid_t pid, pthread_t tid, int ordre)
1.34 bertrand 95: {
96: sem_t *semaphore;
97:
98: unsigned char *chemin;
99:
1.35 bertrand 100: if ((chemin = nom_segment_semaphore_thread(pid, tid, ordre)) == NULL)
1.30 bertrand 101: {
1.34 bertrand 102: return(SEM_FAILED);
1.30 bertrand 103: }
104:
1.75 ! bertrand 105: semaphore = sem_open(chemin, O_CREAT | /*O_EXCL | */ O_RDWR,
! 106: S_IRUSR | S_IWUSR, valeur);
1.68 bertrand 107: sys_free(chemin);
1.34 bertrand 108:
1.29 bertrand 109: return(semaphore);
1.1 bertrand 110: }
111:
1.29 bertrand 112:
113: sem_t *
1.35 bertrand 114: sem_open2(pid_t pid, int ordre)
1.29 bertrand 115: {
116: unsigned char *chemin;
117:
118: sem_t *semaphore;
119:
1.35 bertrand 120: if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL)
1.29 bertrand 121: {
1.34 bertrand 122: return(SEM_FAILED);
1.29 bertrand 123: }
124:
125: semaphore = sem_open(chemin, O_RDWR);
1.68 bertrand 126: sys_free(chemin);
1.29 bertrand 127:
128: return(semaphore);
129: }
130:
131:
1.1 bertrand 132: int
1.35 bertrand 133: sem_destroy2(sem_t *semaphore, pid_t pid, int ordre)
1.1 bertrand 134: {
1.29 bertrand 135: int erreur;
136:
137: unsigned char *chemin;
138:
139: sem_close(semaphore);
140:
1.35 bertrand 141: if ((chemin = nom_segment_semaphore(pid, ordre)) == NULL)
1.29 bertrand 142: {
143: return(1);
144: }
145:
1.38 bertrand 146: erreur = sem_unlink(chemin);
1.68 bertrand 147: sys_free(chemin);
1.29 bertrand 148:
149: return(erreur);
1.1 bertrand 150: }
151:
1.34 bertrand 152:
153: int
1.35 bertrand 154: sem_destroy3(sem_t *semaphore, pid_t pid, pthread_t tid, int ordre)
1.34 bertrand 155: {
156: int erreur;
157:
158: unsigned char *chemin;
159:
160: sem_close(semaphore);
161:
1.35 bertrand 162: if ((chemin = nom_segment_semaphore_thread(pid, tid, ordre)) == NULL)
1.34 bertrand 163: {
164: return(1);
165: }
166:
167: erreur = sem_unlink(chemin);
1.68 bertrand 168: sys_free(chemin);
1.34 bertrand 169:
170: return(erreur);
171: }
172:
173:
1.1 bertrand 174: int
175: sem_getvalue2(sem_t *semaphore, int *valeur)
176: {
177: int i;
1.31 bertrand 178: int j;
1.1 bertrand 179:
180: logical1 drapeau_fin;
181:
1.31 bertrand 182: struct timespec attente;
1.1 bertrand 183:
1.31 bertrand 184: attente.tv_sec = 0;
185: attente.tv_nsec = GRANULARITE_us * 1000;
1.1 bertrand 186:
1.31 bertrand 187: for(j = 0; j < 100; j++)
1.1 bertrand 188: {
1.31 bertrand 189: if (pthread_mutex_trylock(&mutex_sem) == 0)
1.1 bertrand 190: {
1.31 bertrand 191: (*valeur) = 0;
192: drapeau_fin = d_faux;
193:
194: do
1.1 bertrand 195: {
1.31 bertrand 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++)
1.1 bertrand 217: {
1.31 bertrand 218: if (sem_post(semaphore) != 0)
219: {
220: pthread_mutex_unlock(&mutex_sem);
221: return(-1);
222: }
1.1 bertrand 223: }
224:
225: pthread_mutex_unlock(&mutex_sem);
1.31 bertrand 226: return(0);
1.1 bertrand 227: }
1.31 bertrand 228:
229: INCR_GRANULARITE(attente.tv_nsec);
1.1 bertrand 230: }
231:
1.31 bertrand 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;
1.1 bertrand 236: return(0);
237: }
238:
1.63 bertrand 239:
240: #undef sem_post
241: #undef sem_wait
242: #undef sem_trywait
243:
1.1 bertrand 244:
1.14 bertrand 245: #ifdef IPCS_SYSV
1.6 bertrand 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:
1.32 bertrand 259: #ifndef OS2 // IPCS_SYSV
260: extern unsigned char *racine_segment;
261: #else // OS/2
1.9 bertrand 262: unsigned char racine_semaphores_OS2[] = "\\SEM32\\";
1.14 bertrand 263: unsigned char racine_memoire_OS2[] = "\\SHAREMEM\\";
1.9 bertrand 264: #endif
1.6 bertrand 265:
266: int
1.8 bertrand 267: sem_init_SysV(sem_t *semaphore, int shared, unsigned int valeur)
1.6 bertrand 268: {
1.11 bertrand 269: // Création d'un sémaphore anonyme qui devra être supprimé par
270: // sem_destroy_SysV
1.9 bertrand 271:
1.32 bertrand 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();
1.34 bertrand 287: (*semaphore).tid = pthread_self();
1.32 bertrand 288: (*semaphore).alloue = 0;
289: }
290: else
291: {
292: // Sémaphore partagé entre plusieurs processus
1.68 bertrand 293: if (((*semaphore).path = sys_malloc((strlen(racine_segment)
1.34 bertrand 294: + 2 + 256 + 1) * sizeof(unsigned char))) == NULL)
1.32 bertrand 295: {
296: return(-1);
297: }
298:
1.48 bertrand 299: sprintf((*semaphore).path, "%s/RPL-SEMAPHORE-%d-%llX-%llX",
1.47 bertrand 300: racine_segment, (int) getpid(),
1.48 bertrand 301: (long long unsigned) pthread_self(),
302: (long long unsigned) semaphore);
1.32 bertrand 303:
1.75 ! bertrand 304: if ((desc = open((*semaphore).path, O_RDWR | O_CREAT /*| O_EXCL*/,
1.32 bertrand 305: S_IRUSR | S_IWUSR)) == -1)
306: {
1.68 bertrand 307: sys_free((*semaphore).path);
1.32 bertrand 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: {
1.68 bertrand 318: sys_free((*semaphore).path);
1.32 bertrand 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.57 bertrand 333: argument.val = (int) valeur;
1.32 bertrand 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.68 bertrand 342: if (((*psem).cnt = sys_malloc(sizeof(ULONG))) == NULL)
1.39 bertrand 343: {
1.68 bertrand 344: sys_free(psem);
1.39 bertrand 345: errno = ENOMEM;
346: return(-1);
347: }
1.9 bertrand 348:
1.68 bertrand 349: if (((*psem).nopened = sys_malloc(sizeof(ULONG))) == NULL)
1.39 bertrand 350: {
1.68 bertrand 351: sys_free((*psem).cnt);
352: sys_free(psem);
1.39 bertrand 353: errno = ENOMEM;
354: return(-1);
355: }
1.9 bertrand 356:
1.39 bertrand 357: if (DosCreateMutexSem(NULL, &((*psem).hmtx), 0, 0) != 0)
358: {
1.68 bertrand 359: sys_free((*psem).cnt);
360: sys_free((*psem).nopened);
361: sys_free(psem);
1.39 bertrand 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);
1.68 bertrand 369: sys_free((*psem).cnt);
370: sys_free((*psem).nopened);
371: sys_free(psem);
1.39 bertrand 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.68 bertrand 430: sys_free((*psem).cnt);
431: sys_free((*psem).nopened);
1.39 bertrand 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: {
1.68 bertrand 443: sys_free(psem);
1.39 bertrand 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.53 bertrand 456: // semop() ne renvoie pas EINTR sur un signal !
457:
1.32 bertrand 458: commande.sem_num = 0;
459: commande.sem_op = -1;
460: commande.sem_flg = 0;
461:
1.53 bertrand 462: if (semop((*semaphore).sem, &commande, 1) == -1)
1.32 bertrand 463: {
1.53 bertrand 464: if (errno != EAGAIN)
1.32 bertrand 465: {
466: errno = EINVAL;
467: return(-1);
468: }
1.53 bertrand 469: else
470: {
471: return(-1);
472: }
1.11 bertrand 473: }
1.9 bertrand 474:
1.32 bertrand 475: return(0);
476: # else // OS/2
1.39 bertrand 477: sem_t *psem;
1.9 bertrand 478:
1.39 bertrand 479: ULONG cnt;
1.9 bertrand 480:
1.39 bertrand 481: psem = semaphore;
1.9 bertrand 482:
1.39 bertrand 483: if (DosWaitEventSem((*psem).hev, SEM_INDEFINITE_WAIT) != 0)
484: {
485: errno = EINVAL;
486: return(-1);
487: }
1.9 bertrand 488:
1.39 bertrand 489: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
490: {
491: errno = EINVAL;
492: return(-1);
493: }
1.9 bertrand 494:
1.39 bertrand 495: if ((*(*psem).cnt) > 0)
496: {
497: (*(*psem).cnt)--;
498: }
1.9 bertrand 499:
1.39 bertrand 500: if ((*(*psem).cnt) == 0)
501: {
502: DosResetEventSem((*psem).hev, &cnt);
503: }
1.9 bertrand 504:
1.39 bertrand 505: DosReleaseMutexSem((*psem).hmtx);
506: return(0);
1.9 bertrand 507: # endif
1.6 bertrand 508: }
509:
510: int
1.8 bertrand 511: sem_trywait_SysV(sem_t *semaphore)
1.6 bertrand 512: {
1.32 bertrand 513: # ifndef OS2 // IPCS_SYSV
514: struct sembuf commande;
1.6 bertrand 515:
1.32 bertrand 516: commande.sem_num = 0;
517: commande.sem_op = -1;
518: commande.sem_flg = IPC_NOWAIT;
519:
1.53 bertrand 520: if (semop((*semaphore).sem, &commande, 1) == -1)
1.32 bertrand 521: {
1.53 bertrand 522: return(-1);
1.11 bertrand 523: }
1.9 bertrand 524:
1.32 bertrand 525: return(0);
526: # else // OS/2
1.39 bertrand 527: int ios;
1.9 bertrand 528:
1.39 bertrand 529: sem_t *psem;
1.9 bertrand 530:
1.39 bertrand 531: ULONG cnt;
1.9 bertrand 532:
1.39 bertrand 533: psem = semaphore;
1.9 bertrand 534:
1.39 bertrand 535: if ((ios = DosWaitEventSem((*psem).hev, SEM_IMMEDIATE_RETURN)) != 0)
536: {
537: errno = (ios == ERROR_TIMEOUT) ? EAGAIN : EINVAL;
538: return(-1);
539: }
1.9 bertrand 540:
1.39 bertrand 541: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
542: {
543: errno = EINVAL;
544: return(-1);
545: }
1.9 bertrand 546:
1.39 bertrand 547: if ((*(*psem).cnt) > 0)
548: {
549: (*(*psem).cnt)--;
550: }
1.9 bertrand 551:
1.39 bertrand 552: if ((*(*psem).cnt) == 0)
553: {
554: DosResetEventSem((*psem).hev, &cnt);
555: }
1.9 bertrand 556:
1.39 bertrand 557: DosReleaseMutexSem((*psem).hmtx);
558: return(0);
1.9 bertrand 559: # endif
1.6 bertrand 560: }
561:
1.47 bertrand 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:
1.6 bertrand 620: int
1.8 bertrand 621: sem_post_SysV(sem_t *semaphore)
1.6 bertrand 622: {
1.32 bertrand 623: # ifndef OS2 // IPCS_SYSV
624: struct sembuf commande;
1.9 bertrand 625:
1.32 bertrand 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: }
1.11 bertrand 637: }
1.9 bertrand 638:
1.32 bertrand 639: return(0);
640: # else // OS/2
1.39 bertrand 641: sem_t *psem;
1.9 bertrand 642:
1.39 bertrand 643: psem = semaphore;
1.9 bertrand 644:
1.39 bertrand 645: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
646: {
647: errno = EINVAL;
648: return(-1);
649: }
1.9 bertrand 650:
1.39 bertrand 651: (*(*psem).cnt)++;
652: DosPostEventSem((*psem).hev);
653: DosReleaseMutexSem((*psem).hmtx);
1.9 bertrand 654:
1.39 bertrand 655: return(0);
1.9 bertrand 656: # endif
1.6 bertrand 657: }
658:
659: int
1.8 bertrand 660: sem_getvalue_SysV(sem_t *semaphore, int *valeur)
1.6 bertrand 661: {
1.32 bertrand 662: # ifndef OS2 // IPCS_SYSV
663: (*valeur) = semctl((*semaphore).sem, 0, GETVAL);
1.9 bertrand 664:
1.32 bertrand 665: if ((*valeur) < 0)
666: {
667: return(EINVAL);
668: }
1.9 bertrand 669:
1.32 bertrand 670: return(0);
1.9 bertrand 671: # else
1.39 bertrand 672: sem_t *psem;
1.9 bertrand 673:
1.39 bertrand 674: psem = semaphore;
1.9 bertrand 675:
1.39 bertrand 676: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
677: {
678: errno = EINVAL;
679: return(-1);
680: }
1.9 bertrand 681:
1.39 bertrand 682: (*valeur) = (*(*psem).cnt);
683: DosReleaseMutexSem((*psem).hmtx);
1.9 bertrand 684:
1.39 bertrand 685: return(0);
1.9 bertrand 686: # endif
1.6 bertrand 687: }
688:
689: sem_t
1.8 bertrand 690: *sem_open_SysV(const char *nom, int oflag, ...)
1.6 bertrand 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:
1.9 bertrand 698: # ifndef OS2
1.32 bertrand 699: int desc;
1.10 bertrand 700:
1.32 bertrand 701: key_t clef;
1.10 bertrand 702:
1.32 bertrand 703: union semun argument;
1.9 bertrand 704: # endif
1.6 bertrand 705:
706: unsigned char *nom_absolu;
707:
708: unsigned int valeur;
709:
710: va_list liste;
711:
1.9 bertrand 712: # ifdef OS2
1.32 bertrand 713: sem_t *psem;
1.9 bertrand 714:
1.32 bertrand 715: PVOID base;
1.9 bertrand 716:
1.32 bertrand 717: unsigned char *ptr;
718: unsigned char *nom_segment;
1.9 bertrand 719: # endif
720:
1.32 bertrand 721: # ifndef OS2 // IPCS_SYSV
1.68 bertrand 722: if ((nom_absolu = sys_malloc((strlen(racine_segment) + strlen(nom)
1.32 bertrand 723: + 2) * sizeof(unsigned char))) == NULL)
724: {
725: return(SEM_FAILED);
726: }
1.6 bertrand 727:
1.32 bertrand 728: sprintf(nom_absolu, "%s/%s", racine_segment, nom);
1.6 bertrand 729:
1.68 bertrand 730: if ((semaphore = sys_malloc(sizeof(sem_t))) == NULL)
1.32 bertrand 731: {
732: return(SEM_FAILED);
733: }
1.6 bertrand 734:
1.32 bertrand 735: (*semaphore).alloue = -1;
1.34 bertrand 736: (*semaphore).pid = getpid();
737: (*semaphore).tid = pthread_self();
1.9 bertrand 738: # else
1.68 bertrand 739: if ((nom_segment = sys_malloc((strlen(racine_memoire_OS2) + strlen(nom)
740: + 1) * sizeof(unsigned char))) == NULL)
1.39 bertrand 741: {
742: return(SEM_FAILED);
743: }
744:
745: sprintf(nom_segment, "%s%s", racine_memoire_OS2, nom);
746: ptr = nom_segment;
1.9 bertrand 747:
1.39 bertrand 748: while((*ptr) != d_code_fin_chaine)
749: {
750: if ((*ptr) == '/')
751: {
752: (*ptr) = '\\';
753: }
1.9 bertrand 754:
1.39 bertrand 755: ptr++;
756: }
1.9 bertrand 757:
1.68 bertrand 758: if ((nom_absolu = sys_malloc((strlen(racine_semaphores_OS2) +
759: strlen(nom) + 2) * sizeof(unsigned char))) == NULL)
1.9 bertrand 760: {
1.39 bertrand 761: return(SEM_FAILED);
1.9 bertrand 762: }
763:
1.39 bertrand 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: }
1.9 bertrand 773:
1.39 bertrand 774: ptr++;
775: }
1.9 bertrand 776:
1.39 bertrand 777: (*(ptr + 1)) = d_code_fin_chaine;
1.9 bertrand 778:
1.68 bertrand 779: if ((psem = sys_malloc(sizeof(sem_t))) == NULL)
1.9 bertrand 780: {
1.39 bertrand 781: return(SEM_FAILED);
1.9 bertrand 782: }
783:
1.39 bertrand 784: (*psem).allocated = 1;
1.9 bertrand 785: # endif
786:
1.6 bertrand 787: if ((oflag & O_CREAT) == 0)
788: {
789: // 2 arguments
1.9 bertrand 790:
1.32 bertrand 791: # ifndef OS2 // IPCS_SYSV
792: clef = ftok(nom_absolu, 1);
1.9 bertrand 793:
1.32 bertrand 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: {
1.68 bertrand 805: sys_free(semaphore);
806: sys_free(nom_absolu);
1.32 bertrand 807:
808: return(SEM_FAILED);
809: }
810: # else // OS/2
1.68 bertrand 811: if ((psem = sys_malloc(sizeof(sem_t))) == NULL)
1.39 bertrand 812: {
1.68 bertrand 813: sys_free(nom_absolu);
814: sys_free(nom_segment);
1.39 bertrand 815: return(SEM_FAILED);
816: }
1.9 bertrand 817:
1.39 bertrand 818: (*ptr) = 'M';
1.9 bertrand 819:
1.39 bertrand 820: if (DosOpenMutexSem(nom_absolu, &((*psem).hmtx)) != 0)
821: {
1.68 bertrand 822: sys_free(psem);
823: sys_free(nom_absolu);
824: sys_free(nom_segment);
1.9 bertrand 825:
1.39 bertrand 826: return(SEM_FAILED);
827: }
1.9 bertrand 828:
1.39 bertrand 829: (*ptr) = 'S';
1.9 bertrand 830:
1.39 bertrand 831: if (DosOpenEventSem(nom_absolu, &((*psem).hev)) != 0)
832: {
833: DosCloseMutexSem((*psem).hmtx);
1.9 bertrand 834:
1.68 bertrand 835: sys_free(psem);
836: sys_free(nom_absolu);
837: sys_free(nom_segment);
1.9 bertrand 838:
1.39 bertrand 839: return(SEM_FAILED);
840: }
1.9 bertrand 841:
1.39 bertrand 842: if (DosGetNamedSharedMem(&base, nom_segment, PAG_WRITE | PAG_READ)
843: != 0)
844: {
845: DosCloseMutexSem((*psem).hmtx);
1.9 bertrand 846:
1.68 bertrand 847: sys_free(nom_absolu);
848: sys_free(nom_segment);
849: sys_free(psem);
1.9 bertrand 850:
1.39 bertrand 851: return(SEM_FAILED);
852: }
1.9 bertrand 853:
1.68 bertrand 854: sys_free(nom_segment);
1.9 bertrand 855:
1.39 bertrand 856: (*psem).cnt = (ULONG *) base;
857: (*psem).nopened = ((ULONG *) base) + 1;
858: (*psem).shared = 1;
1.9 bertrand 859:
1.39 bertrand 860: if (DosRequestMutexSem((*psem).hmtx, SEM_INDEFINITE_WAIT) != 0)
861: {
862: DosCloseMutexSem((*psem).hmtx);
1.9 bertrand 863:
1.68 bertrand 864: sys_free(nom_absolu);
865: sys_free(nom_segment);
866: sys_free(psem);
1.9 bertrand 867:
1.39 bertrand 868: return(SEM_FAILED);
869: }
1.9 bertrand 870:
1.39 bertrand 871: (*((*psem).nopened))++;
1.9 bertrand 872:
1.39 bertrand 873: DosReleaseMutexSem((*psem).hmtx);
1.9 bertrand 874:
1.39 bertrand 875: semaphore = psem;
1.9 bertrand 876: # endif
1.6 bertrand 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:
1.32 bertrand 890: # ifndef OS2 // IPCS_SYSV
1.75 ! bertrand 891: if ((desc = open(nom_absolu, O_CREAT | /*O_EXCL |*/ O_RDWR,
1.33 bertrand 892: S_IRUSR | S_IWUSR)) == -1)
1.32 bertrand 893: {
1.68 bertrand 894: sys_free(semaphore);
895: sys_free(nom_absolu);
1.32 bertrand 896:
897: return(SEM_FAILED);
898: }
899:
900: if ((clef = ftok(nom_absolu, 1)) == -1)
901: {
902: close(desc);
1.68 bertrand 903: sys_free(semaphore);
904: sys_free(nom_absolu);
1.32 bertrand 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: {
1.68 bertrand 920: sys_free(semaphore);
921: sys_free(nom_absolu);
1.32 bertrand 922:
923: return(SEM_FAILED);
924: }
925:
1.57 bertrand 926: argument.val = (int) valeur;
1.32 bertrand 927: semctl((*semaphore).sem, 0, SETVAL, argument);
928: # else // OS/2
1.68 bertrand 929: if ((psem = sys_malloc(sizeof(sem_t))) == NULL)
1.39 bertrand 930: {
1.68 bertrand 931: sys_free(nom_absolu);
932: sys_free(nom_segment);
1.9 bertrand 933:
1.39 bertrand 934: return(SEM_FAILED);
935: }
1.9 bertrand 936:
1.39 bertrand 937: (*ptr) = 'M';
1.9 bertrand 938:
1.39 bertrand 939: if (DosCreateMutexSem(nom_absolu, &((*psem).hmtx), 0, 0) != 0)
940: {
1.68 bertrand 941: sys_free(psem);
942: sys_free(nom_absolu);
943: sys_free(nom_segment);
1.9 bertrand 944:
1.39 bertrand 945: return(SEM_FAILED);
946: }
1.9 bertrand 947:
1.39 bertrand 948: (*ptr) = 'S';
1.9 bertrand 949:
1.39 bertrand 950: if (DosCreateEventSem(nom_absolu, &((*psem).hev), 0,
951: (valeur != 0) ? 1 : 0) != 0)
952: {
953: DosCloseMutexSem((*psem).hmtx);
1.9 bertrand 954:
1.68 bertrand 955: sys_free(nom_absolu);
956: sys_free(nom_segment);
957: sys_free(psem);
1.39 bertrand 958:
959: return(SEM_FAILED);
960: }
1.9 bertrand 961:
1.39 bertrand 962: if (DosAllocSharedMem(&base, nom_segment, 2 * sizeof(ULONG),
963: PAG_WRITE | PAG_READ | PAG_COMMIT) != 0)
964: {
965: DosCloseMutexSem((*psem).hmtx);
1.9 bertrand 966:
1.68 bertrand 967: sys_free(nom_absolu);
968: sys_free(nom_segment);
969: sys_free(psem);
1.9 bertrand 970:
1.39 bertrand 971: return(SEM_FAILED);
972: }
1.9 bertrand 973:
1.68 bertrand 974: sys_free(nom_segment);
1.9 bertrand 975:
1.39 bertrand 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;
1.9 bertrand 982: # endif
1.6 bertrand 983: }
984:
1.8 bertrand 985: return(semaphore);
1.6 bertrand 986: }
987:
988: int
1.8 bertrand 989: sem_close_SysV(sem_t *semaphore)
1.6 bertrand 990: {
1.11 bertrand 991: // Ferme un sémaphore nommé créé par sem_open_SysV()
1.32 bertrand 992: # ifndef OS2 // IPCS_SYSV
993: if ((*semaphore).path != NULL)
994: {
1.68 bertrand 995: sys_free((*semaphore).path);
1.32 bertrand 996: }
1.9 bertrand 997:
1.32 bertrand 998: if ((*semaphore).alloue == -1)
999: {
1.68 bertrand 1000: sys_free(semaphore);
1.32 bertrand 1001: }
1.9 bertrand 1002:
1.32 bertrand 1003: return(0);
1.9 bertrand 1004: # else
1.39 bertrand 1005: sem_t *psem;
1.9 bertrand 1006:
1.39 bertrand 1007: psem = semaphore;
1.9 bertrand 1008:
1.39 bertrand 1009: if (DosCloseMutexSem((*psem).hmtx) != 0)
1010: {
1011: return(EINVAL);
1012: }
1.9 bertrand 1013:
1.39 bertrand 1014: while(DosCloseEventSem((*psem).hev) == ERROR_SEM_BUSY)
1015: {
1016: DosPostEventSem((*psem).hev);
1017: }
1.9 bertrand 1018:
1.39 bertrand 1019: (*(*psem).nopened)--;
1.9 bertrand 1020:
1.39 bertrand 1021: if ((*psem).shared == 0)
1022: {
1.68 bertrand 1023: sys_free((*psem).cnt);
1024: sys_free((*psem).nopened);
1.39 bertrand 1025: }
1026: else
1027: {
1028: if ((*(*psem).nopened) == 0)
1029: {
1030: DosFreeMem((*psem).cnt);
1031: }
1032: }
1.9 bertrand 1033:
1.39 bertrand 1034: if ((*psem).allocated != 0)
1.9 bertrand 1035: {
1.68 bertrand 1036: sys_free(psem);
1.9 bertrand 1037: }
1038:
1.39 bertrand 1039: return(0);
1.9 bertrand 1040: # endif
1.6 bertrand 1041: }
1042:
1043: int
1.47 bertrand 1044: sem_unlink_SysV(char *nom)
1.6 bertrand 1045: {
1.11 bertrand 1046: // Détruit un sémaphore nommé créé par sem_open_SysV()
1.32 bertrand 1047: # ifndef OS2 // IPCS_SYSV
1.37 bertrand 1048: semctl(semget(ftok(nom, 1), 0, 0), 0, IPC_RMID);
1.6 bertrand 1049:
1.37 bertrand 1050: if (unlink(nom) == -1)
1.32 bertrand 1051: {
1052: return(EACCES);
1053: }
1.6 bertrand 1054:
1.68 bertrand 1055: sys_free(nom);
1.32 bertrand 1056: return(0);
1.9 bertrand 1057: # else
1.39 bertrand 1058: return(0);
1.9 bertrand 1059: # endif
1.6 bertrand 1060: }
1061:
1062: #endif
1063:
1.1 bertrand 1064: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>