00001
00002
00003 #ifndef SIMPLE_SHMEM_H
00004 #define SIMPLE_SHMEM_H
00005
00006 #include <sys/ipc.h>
00007 #include <sys/shm.h>
00008 #include <sys/user.h>
00009
00010 #include <errno.h>
00011
00012 class SimpleSHMEM
00013 {
00014 protected:
00015 int _key;
00016
00017 int _valid;
00018 int _id;
00019 int _size;
00020 int _last_num_attached;
00021
00022 char *_local_addr;
00023
00024 struct shmid_ds _shmem_description;
00025
00026 public:
00027 SimpleSHMEM( int key ) : _key(key), _last_num_attached(0), _local_addr(NULL) {}
00028
00029 virtual ~SimpleSHMEM() {
00030 if (_local_addr && _valid)
00031 shmdt(_local_addr);
00032 }
00033
00034 int create( int size, int perms = 0644) {
00035 _size = size;
00036 _id = shmget(_key, size, IPC_CREAT | IPC_EXCL | perms);
00037
00038 _valid = _id != -1;
00039 if ( _valid )
00040 _local_addr = (char *)shmat(_id, NULL, 0);
00041
00042
00043
00044
00045
00046 return _valid;
00047
00048
00049
00050
00051
00052
00053
00054 }
00055
00056 int num_attached() {
00057 if ( shmctl(_id, IPC_STAT, &_shmem_description) != -1 )
00058 return _shmem_description.shm_nattch;
00059 else
00060 cerr << "ERROR: Couldn't get shmem description for SHMEM ID #" << _id << endl;
00061 return -1;
00062 }
00063
00064
00065 bool lost_attached() {
00066 int curr_num_attached = num_attached();
00067 bool ret = curr_num_attached < _last_num_attached;
00068 _last_num_attached = curr_num_attached;
00069 return ret;
00070 }
00071
00072
00073 int attach() {
00074 _id = shmget(_key, 0, 0);
00075 if (_id == -1)
00076 _valid = 0;
00077 else {
00078 _valid = 1;
00079
00080
00081 struct shmid_ds buf;
00082 int s = shmctl(_id, IPC_STAT, &buf);
00083 _size = int(buf.shm_segsz);
00084
00085
00086 _local_addr = (char *)shmat(_id, NULL, 0);
00087
00088 }
00089
00090 return _valid;
00091 }
00092
00093 void detach() {
00094 if ( shmdt( _local_addr ) )
00095 cerr << "ERROR: Couldn't detach from shared memory id " << _key << endl;
00096 }
00097
00098 int valid() const { return _valid; }
00099 int size () const { return _size; }
00100
00101 int remove() {
00102 if (_local_addr && _valid)
00103 shmdt(_local_addr);
00104
00105 if (shmctl(_id, IPC_RMID, NULL) == -1) {
00106 return 0;
00107 } else {
00108 _valid = 0;
00109 return 1;
00110 }
00111 }
00112
00113
00114
00115 int removed() {
00116 if (shmget(_key, 0, 0) == -1) {
00117
00118
00119 return 1;
00120 }
00121
00122 return 0;
00123 }
00124
00125 char *local_addr() {
00126 if (!_local_addr)
00127 _local_addr = (char *)shmat(_id, NULL, 0);
00128
00129 return _local_addr;
00130 }
00131 };
00132
00133 #endif