|
rllib
1
|
#include <rlsharedmemory.h>

Public Types | |
| enum | SharedMemoryEnum { OK = 0, ERROR_FILE, ERROR_SHMGET, ERROR_SHMAT, ERROR_SHMCTL } |
Public Member Functions | |
| rlSharedMemory (const char *name, unsigned long size, int rwmode=0600) | |
| virtual | ~rlSharedMemory () |
| int | deleteSharedMemory () |
| int | write (unsigned long offset, const void *buf, int len) |
| int | read (unsigned long offset, void *buf, int len) |
| int | readInt (unsigned long offset, int index) |
| int | readShort (unsigned long offset, int index) |
| int | readByte (unsigned long offset, int index) |
| float | readFloat (unsigned long offset, int index) |
| int | writeInt (unsigned long offset, int index, int val) |
| int | writeShort (unsigned long offset, int index, int val) |
| int | writeByte (unsigned long offset, int index, unsigned char val) |
| int | writeFloat (unsigned long offset, int index, float val) |
| void * | getUserAdr () |
| int | shmKey () |
| int | shmId () |
Public Attributes | |
| int | status |
| char * | name |
Private Attributes | |
| int | id |
| int | shmkey |
| char * | base_adr |
| char * | user_adr |
| unsigned long | size |
| pthread_mutex_t * | mutex |
class for a shared memory.
A shared memory is a piece of RAM that is shared between processes. If many processes have access to the same RAM, it is necessary to lock the shared memory. The read/write methods will do this and copy the data to local data. If you want direct access, you may use getUserAdr().
Definition at line 30 of file rlsharedmemory.h.
Definition at line 33 of file rlsharedmemory.h.
{
OK = 0,
ERROR_FILE,
ERROR_SHMGET,
ERROR_SHMAT,
ERROR_SHMCTL
};
| rlSharedMemory::rlSharedMemory | ( | const char * | name, |
| unsigned long | size, | ||
| int | rwmode = 0600 |
||
| ) |
rwmode := access rights under unix. default 0600 user=read,write
Definition at line 84 of file rlsharedmemory.cpp.
{
#ifdef RLUNIX
struct shmid_ds buf;
FILE *fp;
int file_existed;
status = OK;
name = new char[strlen(shmname)+1];
strcpy(name,shmname);
size = Size + sizeof(*mutex);
// create file
file_existed = 1;
fp = fopen(name,"r");
if(fp == NULL)
{
file_existed = 0;
fp = fopen(name,"w");
if(fp == NULL)
{
int ret;
char buf[1024];
sprintf(buf,"could not write shm=%s\n",shmname);
ret = ::write(1,buf,strlen(buf));
if(ret < 0) exit(-1);
sprintf(buf,"you have to run this program as root !!!\n");
ret = ::write(1,buf,strlen(buf));
if(ret < 0) exit(-1);
status=ERROR_FILE;
exit(-1);
}
}
fclose(fp);
// old stuff, without suggestions from Stefan Lievens
//shmkey = ftok(name,0);
//
//id = shmget(shmkey, size, IPC_CREAT);
//shmkey = ftok(name, 'R');
shmkey = ftok(name, 'b');
//id = shmget(shmkey, size, 0600 | IPC_CREAT);
id = shmget(shmkey, size, rwmode | IPC_CREAT);
if(id < 0) { status=ERROR_SHMGET; return; }
base_adr = (char *) shmat(id,NULL,0);
if(base_adr == NULL) { status=ERROR_SHMAT; return; }
if(shmctl(id, IPC_STAT, &buf) != 0) { status=ERROR_SHMCTL; return; };
mutex = (pthread_mutex_t *) base_adr;
user_adr = base_adr + sizeof(*mutex);
//if(file_existed == 0) rlwthread_mutex_init(mutex,NULL);
if(file_existed == 0) myinit(mutex);
#endif
#ifdef __VMS
int file_existed = 0;
long ret,fd,page_size,pagelets,pagelet_size,file_block_size,flags,item,ident[2];
FILE *fp;
ADD add_in,add_ret;
struct dsc$descriptor_s section_name;
struct FAB fab;
status = OK;
name = new char[strlen(shmname)+1];
strcpy(name,shmname);
size = Size + sizeof(*mutex);
// The file block size is fixed
file_block_size = 512; // Bytes
// Get the page size
item = SYI$_PAGE_SIZE;
ret = lib$getsyi( &item ,
&page_size ,
0 ,
0 ,
0 ,
0
);
if(ret != SS$_NORMAL) { status=ERROR_FILE; return; }
// Fill descriptor for section name
section_name.dsc$w_length = strlen(name);
section_name.dsc$a_pointer = name;
section_name.dsc$b_dtype = DSC$K_DTYPE_T;
section_name.dsc$b_class = DSC$K_CLASS_S;
// The pagelet size is fixed
pagelet_size = 512; // Bytes
// Get memory
if(size % page_size == 0) pagelets = size / pagelet_size;
else pagelets = (size / page_size + 1) * (page_size / pagelet_size);
ret = sys$expreg(pagelets,&add_ret,0,0);
if(ret != SS$_NORMAL) { status=ERROR_FILE; return; }
// Set the addresses
base_adr = (char *) add_ret.start;
user_adr = base_adr + sizeof(*mutex);
mutex = (pthread_mutex_t *) base_adr;
if(base_adr == NULL) { status=ERROR_SHMAT; return; }
// Fill the fab
fab = cc$rms_fab; // Initialize fab
fab.fab$b_fac = fab.fab$b_fac | FAB$M_PUT | FAB$M_DEL | FAB$M_GET | FAB$M_UPD;
fab.fab$l_fna = name;
fab.fab$b_fns = strlen(name);
fab.fab$l_fop = fab.fab$l_fop
| FAB$M_CIF // create file if not existent
| FAB$M_CTG // contiguous
| FAB$M_UFO; // user open
fab.fab$b_shr = fab.fab$b_shr // shareble access
| FAB$M_SHRPUT
| FAB$M_UPI;
fab.fab$l_alq = pagelets * pagelet_size / file_block_size;
// Open the section file
ret = sys$create (&fab);
if(ret != RMS$_NORMAL && ret != RMS$_CREATED)
{
sys$close (&fab);
status=ERROR_FILE;
return;
}
// Set the channel
fd = fab.fab$l_stv;
// Fill the input address
add_in.start = add_ret.start;
add_in.end = add_ret.end;
// Clear ident
ident[0] = 0;
ident[1] = 0;
// Set flags
flags = 0;
flags = SEC$M_GBL | SEC$M_WRT | SEC$M_PERM;
// Create and map the section
ret = sys$crmpsc(&add_in ,&add_ret,
(long)0 , // acmode
flags , // flags
§ion_name , // gsdnam
&ident , // ident
(long)0 , // relpag
(short)fd , // chan
pagelets , // pagcnt
(long)0 , // vbn
(long)0 , // prot
(long)0 // pfc
);
if(ret != SS$_NORMAL && ret != SS$_CREATED)
{
sys$close(&fab);
status=ERROR_FILE;
return;
}
// Test the section addresses
if(add_in.start != add_ret.start || add_in.end != add_ret.end)
{
sys$close(&fab);
status=ERROR_FILE;
return;
}
// Close the section file
ret = sys$close(&fab);
// rlwthread_mutex_init(mutex,NULL);
if(file_existed == 0) myinit(mutex);
#endif
#ifdef RLWIN32
HANDLE hFile, hShmem;
int file_existed;
status = OK;
name = new char[strlen(shmname)+1];
strcpy(name,shmname);
size = Size + sizeof(*mutex);
file_existed = 1;
hFile = CreateFile(name,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if(hFile == INVALID_HANDLE_VALUE)
{
file_existed = 0;
hFile = CreateFile(name,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL
);
}
if(hFile == INVALID_HANDLE_VALUE) { status=ERROR_FILE; return; }
hShmem = CreateFileMapping(
hFile,
NULL, // no security attributes
PAGE_READWRITE, // read/write access
0, // size: high 32-bits
size, // size: low 32-bits
NULL); // name of map object
if(hShmem == NULL) { status=ERROR_FILE; return; }
base_adr = (char *) MapViewOfFile(
hShmem, // object to map view of
FILE_MAP_WRITE, // read/write access
0, // high offset: map from
0, // low offset: beginning
0); // default: map entire file
if(base_adr == NULL) { status=ERROR_FILE; return; }
id = (int) hShmem;
shmkey = (int) hFile;
mutex = (pthread_mutex_t *) base_adr;
user_adr = base_adr + sizeof(*mutex);
if(file_existed == 0) rlwthread_mutex_init(mutex,NULL);
#endif
if(rwmode == 0) return; // no warning of unused parameter
}
| rlSharedMemory::~rlSharedMemory | ( | ) | [virtual] |
| int rlSharedMemory::deleteSharedMemory | ( | ) |
Definition at line 312 of file rlsharedmemory.cpp.
{
#ifdef RLUNIX
struct shmid_ds buf;
if(status != OK) return -1;
rlwthread_mutex_destroy(mutex);
shmctl(id, IPC_RMID, &buf);
size = 0;
return 0;
#endif
#ifdef __VMS
int ret;
ADD add_in,add_ret;
struct dsc$descriptor_s section_name;
if(status != OK) return -1;
rlwthread_mutex_destroy(mutex);
// Fill descriptor for section name
section_name.dsc$w_length = strlen(name);
section_name.dsc$a_pointer = name;
section_name.dsc$b_dtype = DSC$K_DTYPE_T;
section_name.dsc$b_class = DSC$K_CLASS_S;
// Delete the section
ret = sys$dgblsc(0,§ion_name,0);
if(ret != SS$_NORMAL) return -1;
// Fill the input address
add_in.start = (long) base_adr;
add_in.end = (long) base_adr + size;
// Free the memory
ret = sys$deltva(&add_in,&add_ret,0);
if(ret != SS$_NORMAL) return -1;
// Test the section addresses
if(add_in.start != add_ret.start || add_in.end != add_ret.end) return -1;
return 0;
#endif
#ifdef RLWIN32
if(status != OK) return -1;
rlwthread_mutex_destroy(mutex);
UnmapViewOfFile(base_adr);
CloseHandle((HANDLE) id);
CloseHandle((HANDLE) shmkey);
status = ~OK;
return 0;
#endif
}
| void * rlSharedMemory::getUserAdr | ( | ) |
Definition at line 469 of file rlsharedmemory.cpp.
{
return (void *) user_adr;
}
| int rlSharedMemory::read | ( | unsigned long | offset, |
| void * | buf, | ||
| int | len | ||
| ) |
Definition at line 381 of file rlsharedmemory.cpp.
{
void *ptr;
if(status != OK) return -1;
if(len <= 0) return -1;
if(offset+len > size) return -1;
ptr = user_adr + offset;
#ifdef RLWIN32
rlwthread_mutex_lock(mutex); // Linux and OpenVMS don't support PTHREAD_PROCESS_SHARED (windows does not support pthread at all)
#else
mylock(mutex,1);
#endif
memcpy(buf,ptr,len);
#ifdef RLWIN32
rlwthread_mutex_unlock(mutex); // Linux and OpenVMS don't support PTHREAD_PROCESS_SHARED (windows does not support pthread at all)
#else
myunlock(mutex);
#endif
return len;
}
| int rlSharedMemory::readByte | ( | unsigned long | offset, |
| int | index | ||
| ) |
Definition at line 418 of file rlsharedmemory.cpp.
{
char val;
if(index < 0) return -1;
read(offset+index*sizeof(val),&val,sizeof(val));
return val;
}
| float rlSharedMemory::readFloat | ( | unsigned long | offset, |
| int | index | ||
| ) |
Definition at line 426 of file rlsharedmemory.cpp.
{
float val;
if(index < 0) return -1;
read(offset+index*sizeof(val),&val,sizeof(val));
return val;
}
| int rlSharedMemory::readInt | ( | unsigned long | offset, |
| int | index | ||
| ) |
Definition at line 402 of file rlsharedmemory.cpp.
{
int val;
if(index < 0) return -1;
read(offset+index*sizeof(val),&val,sizeof(val));
return val;
}
| int rlSharedMemory::readShort | ( | unsigned long | offset, |
| int | index | ||
| ) |
Definition at line 410 of file rlsharedmemory.cpp.
{
short int val;
if(index < 0) return -1;
read(offset+index*sizeof(val),&val,sizeof(val));
return val;
}
| int rlSharedMemory::shmId | ( | ) |
Definition at line 479 of file rlsharedmemory.cpp.
{
return id;
}
| int rlSharedMemory::shmKey | ( | ) |
Definition at line 474 of file rlsharedmemory.cpp.
{
return shmkey;
}
| int rlSharedMemory::write | ( | unsigned long | offset, |
| const void * | buf, | ||
| int | len | ||
| ) |
Definition at line 360 of file rlsharedmemory.cpp.
{
void *ptr;
if(status != OK) return -1;
if(len <= 0) return -1;
if(offset+len > size) return -1;
ptr = user_adr + offset;
#ifdef RLWIN32
rlwthread_mutex_lock(mutex); // Linux and OpenVMS don't support PTHREAD_PROCESS_SHARED (windows does not support pthread at all)
#else
mylock(mutex,1);
#endif
memcpy(ptr,buf,len);
#ifdef RLWIN32
rlwthread_mutex_unlock(mutex); // Linux and OpenVMS don't support PTHREAD_PROCESS_SHARED (windows does not support pthread at all)
#else
myunlock(mutex);
#endif
return len;
}
| int rlSharedMemory::writeByte | ( | unsigned long | offset, |
| int | index, | ||
| unsigned char | val | ||
| ) |
Definition at line 453 of file rlsharedmemory.cpp.
{
int ret;
if(index < 0) return -1;
ret = write(offset+index*sizeof(val),&val,sizeof(val));
return ret;
}
| int rlSharedMemory::writeFloat | ( | unsigned long | offset, |
| int | index, | ||
| float | val | ||
| ) |
Definition at line 461 of file rlsharedmemory.cpp.
{
int ret;
if(index < 0) return -1;
ret = write(offset+index*sizeof(val),&val,sizeof(val));
return ret;
}
| int rlSharedMemory::writeInt | ( | unsigned long | offset, |
| int | index, | ||
| int | val | ||
| ) |
Definition at line 434 of file rlsharedmemory.cpp.
{
int ret;
if(index < 0) return -1;
ret = write(offset+index*sizeof(val),&val,sizeof(val));
return ret;
}
| int rlSharedMemory::writeShort | ( | unsigned long | offset, |
| int | index, | ||
| int | val | ||
| ) |
Definition at line 442 of file rlsharedmemory.cpp.
{
int ret;
short int val2;
if(index < 0) return -1;
val2 = (short int) val;
ret = write(offset+index*sizeof(val2),&val2,sizeof(val2));
return ret;
}
char* rlSharedMemory::base_adr [private] |
Definition at line 64 of file rlsharedmemory.h.
int rlSharedMemory::id [private] |
Definition at line 62 of file rlsharedmemory.h.
pthread_mutex_t* rlSharedMemory::mutex [private] |
Definition at line 67 of file rlsharedmemory.h.
| char* rlSharedMemory::name |
Definition at line 60 of file rlsharedmemory.h.
int rlSharedMemory::shmkey [private] |
Definition at line 63 of file rlsharedmemory.h.
unsigned long rlSharedMemory::size [private] |
Definition at line 66 of file rlsharedmemory.h.
Definition at line 59 of file rlsharedmemory.h.
char* rlSharedMemory::user_adr [private] |
Definition at line 65 of file rlsharedmemory.h.
1.7.5.1