Annotation of rpl/src/semaphores.c, revision 1.8
1.1 bertrand 1: /*
2: ================================================================================
1.5 bertrand 3: RPL/2 (R) version 4.0.18
1.1 bertrand 4: Copyright (C) 1989-2010 Dr. BERTRAND Joël
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.1 bertrand 25: #ifdef SEMAPHORES_NOMMES
26:
27: /*
28: ================================================================================
29: Fonctions d'émulation de sémaphores anonymes
30: ================================================================================
31: Entrées :
32: --------------------------------------------------------------------------------
33: Sorties :
34: --------------------------------------------------------------------------------
35: Effets de bord : néant
36: ================================================================================
37: */
38:
39: sem_t *
40: sem_init2(unsigned int valeur, enum t_semaphore semaphore)
41: {
42: snprintf(noms_semaphores[semaphore], LONGUEUR_NOM_SEMAPHORE,
43: "/RPLSEM-%d-%llu-%d", (int) getpid(),
44: (unsigned long long) pthread_self(),
45: (int) semaphore);
46: return(sem_open(noms_semaphores[semaphore], O_CREAT,
47: (S_IRUSR | S_IWUSR), valeur));
48: }
49:
50: int
51: sem_destroy2(sem_t *semaphore_p, enum t_semaphore semaphore)
52: {
53: sem_close(semaphore_p);
54: return(sem_unlink(noms_semaphores[semaphore]));
55: }
56:
57: #undef sem_post
58: #undef sem_wait
59: #undef sem_trywait
60:
61: int
62: sem_getvalue2(sem_t *semaphore, int *valeur)
63: {
64: int i;
65:
66: logical1 drapeau_fin;
67:
68: pthread_mutex_lock(&mutex_sem);
69:
70: (*valeur) = 0;
71: drapeau_fin = d_faux;
72:
73: do
74: {
75: if (sem_trywait(semaphore) == -1)
76: {
77: if (errno == EAGAIN)
78: {
79: // Le sémaphore avait une valeur nulle
80: drapeau_fin = d_vrai;
81: }
82: else
83: {
84: // Autre erreur
85: pthread_mutex_unlock(&mutex_sem);
86: return(-1);
87: }
88: }
89: else
90: {
91: (*valeur)++;
92: }
93: } while(drapeau_fin == d_faux);
94:
95: for(i = 0; i < (*valeur); i++)
96: {
97: if (sem_post(semaphore) != 0)
98: {
99: pthread_mutex_unlock(&mutex_sem);
100: return(-1);
101: }
102: }
103:
104: pthread_mutex_unlock(&mutex_sem);
105: return(0);
106: }
107:
108: #endif
109:
1.8 ! bertrand 110: #ifdef SEMAPHORES_SYSV
1.6 bertrand 111:
112: /*
113: ================================================================================
114: Fonctions d'émulation de sémaphores POSIX en fonction des sémaphores SysV
115: ================================================================================
116: Entrées :
117: --------------------------------------------------------------------------------
118: Sorties :
119: --------------------------------------------------------------------------------
120: Effets de bord : néant
121: ================================================================================
122: */
123:
124: extern unsigned char *chemin_semaphores_SysV;
125:
1.8 ! bertrand 126: #ifndef UNION_SEMUN
! 127: union semun
! 128: {
! 129: int val;
! 130: struct semid_ds *buf;
! 131: unsigned short *array;
! 132: struct seminfo *__buf;
! 133: };
! 134: #endif
! 135:
1.6 bertrand 136: int
1.8 ! bertrand 137: sem_init_SysV(sem_t *semaphore, int shared, unsigned int valeur)
1.6 bertrand 138: {
1.8 ! bertrand 139: int ios;
! 140:
1.6 bertrand 141: union semun argument;
142:
143: if (shared != 0)
144: {
145: return(ENOSYS);
146: }
147:
148: (*semaphore) = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | SEM_R | SEM_A);
149:
150: if ((*semaphore) == -1)
151: {
152: return(EINVAL);
153: }
154:
155: argument.val = valeur;
1.8 ! bertrand 156: ios = semctl((*semaphore), 0, SETVAL, argument);
1.6 bertrand 157:
1.8 ! bertrand 158: return(ios);
1.6 bertrand 159: }
160:
161: int
1.8 ! bertrand 162: sem_destroy_SysV(sem_t *semaphore)
1.6 bertrand 163: {
164: if (semctl((*semaphore), IPC_RMID, 0) == -1)
165: {
166: return(EINVAL);
167: }
168:
169: return(0);
170: }
171:
172: int
1.8 ! bertrand 173: sem_wait_SysV(sem_t *semaphore)
1.6 bertrand 174: {
175: struct sembuf commande;
176:
177: commande.sem_num = 0;
178: commande.sem_op = -1;
179: commande.sem_flg = 0;
180:
181: if (semop((*semaphore), &commande, 1) == -1)
182: {
183: return(EINVAL);
184: }
185:
186: return(0);
187: }
188:
189: int
1.8 ! bertrand 190: sem_trywait_SysV(sem_t *semaphore)
1.6 bertrand 191: {
192: struct sembuf commande;
193:
194: commande.sem_num = 0;
195: commande.sem_op = -1;
196: commande.sem_flg = IPC_NOWAIT;
197:
198: if (semop((*semaphore), &commande, 1) == -1)
199: {
200: if (errno == EAGAIN)
201: {
202: return(EAGAIN);
203: }
204:
205: return(EINVAL);
206: }
207:
208: return(0);
209: }
210:
211: int
1.8 ! bertrand 212: sem_post_SysV(sem_t *semaphore)
1.6 bertrand 213: {
214: struct sembuf commande;
215:
216: commande.sem_num = 0;
217: commande.sem_op = 1;
218: commande.sem_flg = 0;
219:
220: if (semop((*semaphore), &commande, 1) == -1)
221: {
222: return(EINVAL);
223: }
224:
225: return(0);
226: }
227:
228: int
1.8 ! bertrand 229: sem_getvalue_SysV(sem_t *semaphore, int *valeur)
1.6 bertrand 230: {
231: (*valeur) = semctl((*semaphore), 0, GETVAL);
232:
233: if ((*valeur) < 0)
234: {
235: return(EINVAL);
236: }
237:
238: return(0);
239: }
240:
241: sem_t
1.8 ! bertrand 242: *sem_open_SysV(const char *nom, int oflag, ...)
1.6 bertrand 243: //*sem_open(const char *nom, int oflag)
244: //*sem_open(const char *nom, int oflag, mode_t mode, unsigned int value)
245: {
246: mode_t mode;
247:
248: sem_t *semaphore;
249:
250: union semun argument;
251:
252: unsigned char *nom_absolu;
253:
254: unsigned int valeur;
255:
256: va_list liste;
257:
258: if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom)
259: + 1) * sizeof(unsigned char))) == NULL)
260: {
261: return(SEM_FAILED);
262: }
263:
264: sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom);
265:
266: if ((semaphore = malloc(sizeof(sem_t))) == NULL)
267: {
268: return(SEM_FAILED);
269: }
270:
271: if ((oflag & O_CREAT) == 0)
272: {
273: // 2 arguments
274: (*semaphore) = semget(ftok(nom_absolu, 1), 0, 0);
275:
276: if ((*semaphore) == -1)
277: {
278: free(semaphore);
279: free(nom_absolu);
280:
281: return(SEM_FAILED);
282: }
283: }
284: else
285: {
286: // 4 arguments
287:
288: // O_CREAT O_EXCL
289: // S_IRUSR S_IWUSR
290:
291: va_start(liste, oflag);
292: mode = va_arg(liste, mode_t);
293: valeur = va_arg(liste, unsigned int);
294: va_end(liste);
295:
296: (*semaphore) = semget(ftok(nom_absolu, 1), 1,
297: ((oflag & O_CREAT) == 0) ? 0 : IPC_CREAT |
298: ((oflag & O_EXCL) == 0) ? 0 : IPC_EXCL |
299: ((oflag & S_IRUSR) == 0) ? 0 : SEM_R |
300: ((oflag & S_IWUSR) == 0) ? 0 : SEM_A);
301:
302: if ((*semaphore) == -1)
303: {
304: free(semaphore);
305: free(nom_absolu);
306:
307: return(SEM_FAILED);
308: }
309:
310: argument.val = valeur;
311: semctl((*semaphore), 0, SETVAL, argument);
312: }
313:
314: free(nom_absolu);
315:
1.8 ! bertrand 316: return(semaphore);
1.6 bertrand 317: }
318:
319: int
1.8 ! bertrand 320: sem_close_SysV(sem_t *semaphore)
1.6 bertrand 321: {
322: free(semaphore);
323: return(0);
324: }
325:
326: int
1.8 ! bertrand 327: sem_unlink_SysV(const char *nom)
1.6 bertrand 328: {
329: sem_t semaphore;
330:
331: struct sembuf commande;
332:
333: unsigned char *nom_absolu;
334:
335: if ((nom_absolu = malloc((strlen(chemin_semaphores_SysV) + strlen(nom)
336: + 1) * sizeof(unsigned char))) == NULL)
337: {
338: return(ENOMEM);
339: }
340:
341: sprintf(nom_absolu, "%s%s", chemin_semaphores_SysV, nom);
342:
343: if ((semaphore = semget(ftok(nom_absolu, 1), 0, 0)) == -1)
344: {
345: free(nom_absolu);
346: return(EINVAL);
347: }
348:
349: commande.sem_num = 0;
350: commande.sem_op = 0;
351: commande.sem_flg = 0;
352:
353: if (semop(semaphore, &commande, 1) == -1)
354: {
355: free(nom_absolu);
356: return(EINVAL);
357: }
358:
359: if (semctl(semaphore, IPC_RMID, 0) == -1)
360: {
361: free(nom_absolu);
362: return(EINVAL);
363: }
364:
365: if (unlink(nom_absolu) == -1)
366: {
367: free(nom_absolu);
368: return(EACCES);
369: }
370:
371: free(nom_absolu);
372:
373: return(0);
374: }
375:
376: #endif
377:
1.1 bertrand 378: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>