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