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