00001
00002 #ifndef IPC_SIMPLE_SEMAPHORE_H
00003 #define IPC_SIMPLE_SEMAPHORE_H
00004
00005
00006
00007
00008
00009 #include "simple.sem.H"
00010
00011 #ifdef linux
00012
00013 #include <sys/types.h>
00014 #include <sys/ipc.h>
00015 #include <sys/sem.h>
00016
00017 #include <iostream.h>
00018 #include <stdio.h>
00019 #include <stdlib.h>
00020
00021
00022 union semun {
00023 int val;
00024 struct semid_ds *buf;
00025 unsigned short *array;
00026 struct seminfo *__buf;
00027 };
00028
00029 class IPC_SimpleSemaphore : public SimpleSemaphore
00030 {
00031 protected:
00032 int _id;
00033
00034 int v_op()
00035 {
00036 struct sembuf sops[1];
00037 sops[0].sem_num = 0;
00038 sops[0].sem_op = 1;
00039 sops[0].sem_flg = 0;
00040 if (semop(_id, sops, 1) == -1)
00041 return 0;
00042 else
00043 return 1;
00044 }
00045
00046 int p_op()
00047 {
00048 struct sembuf sops[1];
00049 sops[0].sem_num = 0;
00050 sops[0].sem_op = -1;
00051 sops[0].sem_flg = 0;
00052
00053 if (semop(_id, sops, 1) == -1)
00054 return 0;
00055 else
00056 return 1;
00057 }
00058
00059
00060
00061 int wait_op()
00062 {
00063 struct sembuf sops[1];
00064 sops[0].sem_num = 0;
00065 sops[0].sem_op = 0;
00066 sops[0].sem_flg = 0;
00067
00068 if (semop(_id, sops, 1) == -1)
00069 return 0;
00070 else
00071 return 1;
00072 }
00073
00074 public:
00075 IPC_SimpleSemaphore(int key) : SimpleSemaphore(key), _id(0) {}
00076
00077
00078 inline int up() { return v_op(); }
00079 inline int down() { return p_op(); }
00080
00081
00082 inline int wait() { return wait_op(); }
00083
00084
00085 virtual int create() {
00086 int nsems = 1;
00087 _id = semget((key_t)_key, nsems, IPC_CREAT | IPC_EXCL | 0666);
00088 if (_id == -1) {
00089 return 0;
00090 } else {
00091
00092 union semun argument;
00093 argument.val = 0;
00094 if (semctl(_id, 0, SETVAL, argument) < 0) {
00095 cerr << "IPC_SimpleSemaphore: constructor cannot set semaphore value." << endl;
00096 return 0;
00097 }
00098
00099
00100 if (!v_op()) {
00101 cerr << "IPC_SimpleSemaphore: constructor couldn't do initial v-operation" << endl;
00102 return 0;
00103 }
00104
00105 _valid = 1;
00106 return 1;
00107 }
00108 }
00109
00110 virtual int attach() {
00111 _id = semget((key_t)_key, 0, 0);
00112
00113 if (_id == -1)
00114 return 0;
00115
00116 _valid = 1;
00117 return 1;
00118 }
00119
00120 virtual int remove() {
00121 if (semctl(_id, 0, IPC_RMID) == -1)
00122 return 0;
00123 else
00124 return 1;
00125 }
00126
00127
00128 virtual int lock() {
00129 return p_op();
00130 }
00131
00132 virtual int unlock() {
00133 return v_op();
00134 }
00135
00136 virtual void print( int do_wait=1 )
00137 {
00138
00139 struct semid_ds buf;
00140 union semun arg;
00141 arg.buf = &buf;
00142
00143 int s = semctl(_id, 0, IPC_STAT, &arg);
00144 if (s==0) {
00145 cerr << " value: " << semctl(_id, 0, GETVAL) << endl;
00146 cerr << " permissions:" << endl;
00147 cerr << " uid: " << int(buf.sem_perm.uid) << endl;
00148 cerr << " mode: " << int(buf.sem_perm.mode) << endl;
00149 cerr << " nsems: " << int(buf.sem_nsems) << endl;
00150 } else {
00151 cerr << "unable to get IPC_STAT info..." << endl;
00152 }
00153
00154 system ("ipcs -s");
00155
00156 if (do_wait) {
00157 cerr << "Type a number and <return> to continue..." << endl;
00158 int tmp;
00159 cin >> tmp;
00160 }
00161 }
00162 };
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 class SemaphorePair
00179 {
00180 protected:
00181 int _semid;
00182 int _creator;
00183 int _key;
00184
00185 public:
00186 enum {EMPTY=0, FULL=1};
00187 enum {ALL_DONE =0, DONE=1};
00188
00189 SemaphorePair( int key ) : _semid(-1), _creator(0), _key(key) {}
00190
00191 virtual ~SemaphorePair() {
00192 if (_creator)
00193 semctl(_semid, 2, IPC_RMID, 0);
00194 }
00195
00196 int semid() const { return _semid; }
00197
00198 int create() {
00199 if ((_semid = semget(_key, 2, 0777 | IPC_CREAT)) == -1)
00200 perror("SemaphorePair: semget");
00201
00202 ushort init_values[2] = {1, 0};
00203 if(semctl(_semid, 2, SETALL, init_values) == -1)
00204 perror("SemaphorePair: semctl");
00205
00206 _creator = 1;
00207
00208 return _semid;
00209 }
00210
00211 int attach() {
00212 _semid = semget(_key, 0, 0);
00213 return (_semid!=-1);
00214 }
00215
00216
00217 int wait(int index) {
00218 struct sembuf operation;
00219
00220 operation.sem_num = index;
00221 operation.sem_op = -1;
00222 operation.sem_flg = 0;
00223
00224 return semop(_semid, & operation, 1);
00225 }
00226
00227
00228 int signal(int index) {
00229 struct sembuf operation;
00230
00231 operation.sem_num = index;
00232 operation.sem_op = 1;
00233 operation.sem_flg = 0;
00234
00235 return semop(_semid, & operation, 1);
00236 }
00237 };
00238
00239
00240 #endif
00241
00242 #endif
00243