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 else {
00042 char errStr[512];
00043 sprintf( errStr, "SimpleSHMEM::create() failed on %s because ", getenv("HOST") );
00044 perror( errStr );
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
00079
00080
00081
00082 }
00083 else {
00084 _valid = 1;
00085
00086
00087 struct shmid_ds buf;
00088 int s = shmctl(_id, IPC_STAT, &buf);
00089 _size = int(buf.shm_segsz);
00090
00091
00092 _local_addr = (char *)shmat(_id, NULL, 0);
00093
00094 }
00095
00096 return _valid;
00097 }
00098
00099 void detach() {
00100 if ( shmdt( _local_addr ) )
00101 cerr << "ERROR: Couldn't detach from shared memory id " << _key << endl;
00102 }
00103
00104 int valid() const { return _valid; }
00105 int size () const { return _size; }
00106
00107 int remove() {
00108 if (_local_addr && _valid)
00109 shmdt(_local_addr);
00110
00111 if (shmctl(_id, IPC_RMID, NULL) == -1) {
00112 return 0;
00113 } else {
00114 _valid = 0;
00115 return 1;
00116 }
00117 }
00118
00119
00120
00121 int removed() {
00122 if (shmget(_key, 0, 0) == -1) {
00123
00124
00125 return 1;
00126 }
00127
00128 return 0;
00129 }
00130
00131 char *local_addr() {
00132 if (!_local_addr)
00133 _local_addr = (char *)shmat(_id, NULL, 0);
00134
00135 return _local_addr;
00136 }
00137 };
00138
00139 #endif