00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "defs.h"
00022 #include "SimpleSem.h"
00023 #include <sys/sem.h>
00024
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
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
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
00117 bool SimpleSemClose(struct SimpleSem *sem)
00118 {
00119 free(sem);
00120 return true;
00121 }
00122
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