©2004 by Marc J. Rochkind. All rights reserved. Portions marked "Open Source" may be copied under license.

 

Main Page   Modules   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

c7/SimpleSemSysV.c

Go to the documentation of this file.
00001 /*
00002     Simple Semaphore Interface - System V implementation
00003     AUP2, Sec. 7.09.2
00004 
00005     Copyright 2003 by Marc J. Rochkind. All rights reserved.
00006     May be copied only for purposes and under conditions described
00007     on the Web page www.basepath.com/aup/copyright.htm.
00008 
00009     The Example Files are provided "as is," without any warranty;
00010     without even the implied warranty of merchantability or fitness
00011     for a particular purpose. The author and his publisher are not
00012     responsible for any damages, direct or incidental, resulting
00013     from the use or non-use of these Example Files.
00014 
00015     The Example Files may contain defects, and some contain deliberate
00016     coding mistakes that were included for educational reasons.
00017     You are responsible for determining if and how the Example Files
00018     are to be used.
00019 
00020 */
00021 #include "defs.h"
00022 #include "SimpleSem.h"
00023 #include <sys/sem.h>
00024 /*[SimpleSemOpen]*/
00025 struct SimpleSem *SimpleSemOpen(const char *name)
00026 {
00027     struct SimpleSem *sem = NULL;
00028     key_t key;
00029     union semun {
00030         int val;
00031         struct semid_ds *buf;
00032         unsigned short *array;
00033     } arg;
00034     struct sembuf sop;
00035 
00036     (void)close(open(name, O_WRONLY | O_CREAT, 0));
00037     ec_neg1( key = ftok(name, 1) )
00038     ec_null( sem = malloc(sizeof(struct SimpleSem)) )
00039     if ((sem->sm.sm_semid = semget(key, 1,
00040       PERM_FILE | IPC_CREAT | IPC_EXCL)) != -1) {
00041         arg.val = 0;
00042         ec_neg1( semctl(sem->sm.sm_semid, 0, SETVAL, arg) )
00043         sop.sem_num = 0;
00044         sop.sem_op = 0;
00045         sop.sem_flg = 0;
00046         ec_neg1( semop(sem->sm.sm_semid, &sop, 1) )
00047     }
00048     else {
00049         if (errno == EEXIST) {
00050             while (true)
00051                 if ((sem->sm.sm_semid = semget(key, 1, PERM_FILE)) == -1) {
00052                     if (errno == ENOENT) {
00053                         sleep(1);
00054                         continue;
00055                     }
00056                     else
00057                         EC_FAIL
00058                 }
00059                 else
00060                     break;
00061 #ifndef FREEBSD // bug -- otime not set
00062             while (true) {
00063                 struct semid_ds buf;
00064 
00065                 arg.buf = &buf;
00066                 ec_neg1( semctl(sem->sm.sm_semid, 0, IPC_STAT, arg) )
00067                 if (buf.sem_otime == 0 && false) {
00068                     sleep(1);
00069                     continue;
00070                 }
00071                 else
00072                     break;
00073             }
00074 #endif
00075         }
00076         else
00077             EC_FAIL
00078     }
00079     return sem;
00080 
00081 EC_CLEANUP_BGN
00082     free(sem);
00083     return NULL;
00084 EC_CLEANUP_END
00085 }
00086 /*[SimpleSemPost]*/
00087 bool SimpleSemPost(struct SimpleSem *sem)
00088 {
00089     struct sembuf sop;
00090 
00091     sop.sem_num = 0;
00092     sop.sem_op = 1;
00093     sop.sem_flg = 0;
00094     ec_neg1( semop(sem->sm.sm_semid, &sop, 1) )
00095     return true;
00096 
00097 EC_CLEANUP_BGN
00098     return false;
00099 EC_CLEANUP_END
00100 }
00101 /*[SimpleSemWait]*/
00102 bool SimpleSemWait(struct SimpleSem *sem)
00103 {
00104     struct sembuf sop;
00105 
00106     sop.sem_num = 0;
00107     sop.sem_op = -1;
00108     sop.sem_flg = 0;
00109     ec_neg1( semop(sem->sm.sm_semid, &sop, 1) )
00110     return true;
00111 
00112 EC_CLEANUP_BGN
00113     return false;
00114 EC_CLEANUP_END
00115 }
00116 /*[SimpleSemClose]*/
00117 bool SimpleSemClose(struct SimpleSem *sem)
00118 {
00119     free(sem);
00120     return true;
00121 }
00122 /*[SimpleSemRemove]*/
00123 bool SimpleSemRemove(const char *name)
00124 {
00125     key_t key;
00126     int semid;
00127 
00128     if ((key = ftok(name, 1)) == -1) {
00129         if (errno != ENOENT)
00130             EC_FAIL
00131     }
00132     else {
00133         if ((semid = semget(key, 1, PERM_FILE)) == -1) {
00134             if (errno != ENOENT)
00135                 EC_FAIL
00136         }
00137         else
00138             ec_neg1( semctl(semid, 0, IPC_RMID) )
00139     }
00140     return true;
00141 
00142 EC_CLEANUP_BGN
00143     return false;
00144 EC_CLEANUP_END
00145 }
00146 /*[]*/

Generated on Fri Apr 23 10:56:59 2004 for AUP2 Example Source by doxygen 1.3.1