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