rllib  1
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
Public Types | Public Member Functions | Public Attributes | Private Attributes | List of all members
rlSharedMemory Class Reference

#include <rlsharedmemory.h>

Inheritance diagram for rlSharedMemory:
Inheritance graph
[legend]

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_tmutex
 
HANDLE hSharedFile
 
OVERLAPPED overlapped
 

Detailed Description

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.

Member Enumeration Documentation

Enumerator:
OK 
ERROR_FILE 
ERROR_SHMGET 
ERROR_SHMAT 
ERROR_SHMCTL 

Definition at line 33 of file rlsharedmemory.h.

Constructor & Destructor Documentation

rlSharedMemory::rlSharedMemory ( const char *  name,
unsigned long  size,
int  rwmode = 0600 
)

rwmode := access rights under unix. default 0600 user=read,write

Definition at line 90 of file rlsharedmemory.cpp.

{
#ifdef RLUNIX
struct shmid_ds buf;
name = new char[strlen(shmname)+1];
strcpy(name,shmname);
size = Size + sizeof(*mutex);
// create file
fdlock = open(name, O_RDWR | O_CREAT, rwmode );
if(fdlock < 0)
{
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);
}
// 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; };
user_adr = base_adr + sizeof(*mutex);
flock(fdlock,LOCK_UN);
#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);
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
&section_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 hShmem;
int file_existed;
status = OK;
name = new char[strlen(shmname)+1];
strcpy(name,shmname);
size = Size + sizeof(HANDLE); // sizeof(*mutex);
file_existed = 1;
hSharedFile = CreateFile(name,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if(hSharedFile == INVALID_HANDLE_VALUE)
{
file_existed = 0;
hSharedFile = CreateFile(name,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL
);
}
if(hSharedFile == INVALID_HANDLE_VALUE) { status=ERROR_FILE; return; }
//char *global_name = new char[strlen(name)+40];
//strcpy(global_name,"Global\\"); strcat(global_name, name);
//for(int i=7; i<strlen(global_name); i++)
//{
// if (global_name[i] == ':') global_name[i] = '_';
// else if(global_name[i] == '\\') global_name[i] = '_';
// else if(global_name[i] == '.') global_name[i] = '_';
// else if(global_name[i] == ' ') global_name[i] = '_';
//}
hShmem = CreateFileMapping(
NULL, // no security attributes
PAGE_READWRITE, // read/write access
0, // size: high 32-bits
size, // size: low 32-bits
0); // name of map object // changed by FMakkinga 25-03-2013 global_name);
// global_name); // name of map object
//delete [] global_name;
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;
user_adr = base_adr + sizeof(*mutex);
memset(&overlapped, 0, sizeof(overlapped)); // Changed by FMakkinga 22-03-2013
UnlockFileEx(hSharedFile,0,size,0,&overlapped);
#endif
if(rwmode == 0) return; // no warning of unused parameter
}
rlSharedMemory::~rlSharedMemory ( )
virtual

Definition at line 310 of file rlsharedmemory.cpp.

{
delete [] name;
printf("We are within the destructor\n");
#ifdef RLWIN32
if(status != OK) return;
CloseHandle((HANDLE) id);
CloseHandle((HANDLE) shmkey);
#elif defined(RLUNIX)
if(fdlock >= 0) close(fdlock);
#endif
}

Member Function Documentation

int rlSharedMemory::deleteSharedMemory ( )

Definition at line 323 of file rlsharedmemory.cpp.

{
#ifdef RLUNIX
struct shmid_ds buf;
if(status != OK) return -1;
//rlwthread_mutex_destroy(mutex);
flock(fdlock,LOCK_UN);
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;
// 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,&section_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);
UnlockFile(hSharedFile,0,0,size,0); // Changed by FMakkinga 18-03-2013
CloseHandle(hSharedFile); // Changed by FMakkinga 18-03-2013
status = ~OK;
return 0;
#endif
}
void * rlSharedMemory::getUserAdr ( )

Definition at line 491 of file rlsharedmemory.cpp.

{
return (void *) user_adr;
}
int rlSharedMemory::read ( unsigned long  offset,
void *  buf,
int  len 
)

Definition at line 399 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
LockFileEx(hSharedFile,LOCKFILE_EXCLUSIVE_LOCK,0,size,0,&overlapped); // Changed by FMakkinga 18-03-2013
#elif defined(RLUNIX)
flock(fdlock,LOCK_EX);
#else
mylock(mutex,1);
#endif
memcpy(buf,ptr,len);
#ifdef RLWIN32
UnlockFileEx(hSharedFile,0,size,0,&overlapped); // Changed by FMakkinga 18-03-2013
#elif defined(RLUNIX)
flock(fdlock,LOCK_UN);
#else
myunlock(mutex);
#endif
return len;
}
int rlSharedMemory::readByte ( unsigned long  offset,
int  index 
)

Definition at line 440 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 448 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 424 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 432 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 501 of file rlsharedmemory.cpp.

{
return id;
}
int rlSharedMemory::shmKey ( )

Definition at line 496 of file rlsharedmemory.cpp.

{
return shmkey;
}
int rlSharedMemory::write ( unsigned long  offset,
const void *  buf,
int  len 
)

Definition at line 374 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
LockFileEx(hSharedFile,LOCKFILE_EXCLUSIVE_LOCK,0,size,0,&overlapped); // Changed by FMakkinga 18-03-2013
#elif defined(RLUNIX)
flock(fdlock,LOCK_EX);
#else
mylock(mutex,1);
#endif
memcpy(ptr,buf,len);
#ifdef RLWIN32
UnlockFileEx(hSharedFile,0,size,0,&overlapped); // Changed by FMakkinga 18-03-2013
#elif defined(RLUNIX)
flock(fdlock,LOCK_UN);
#else
myunlock(mutex);
#endif
return len;
}
int rlSharedMemory::writeByte ( unsigned long  offset,
int  index,
unsigned char  val 
)

Definition at line 475 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 483 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 456 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 464 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;
}

Member Data Documentation

char* rlSharedMemory::base_adr
private

Definition at line 64 of file rlsharedmemory.h.

HANDLE rlSharedMemory::hSharedFile
private

Definition at line 69 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.

OVERLAPPED rlSharedMemory::overlapped
private

Definition at line 70 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.

int rlSharedMemory::status

Definition at line 59 of file rlsharedmemory.h.

char* rlSharedMemory::user_adr
private

Definition at line 65 of file rlsharedmemory.h.


The documentation for this class was generated from the following files: