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