rllib  1
Public Types | Public Member Functions | Public Attributes | Private Attributes
rlSharedMemory Class Reference

#include <rlsharedmemory.h>

Inheritance diagram for rlSharedMemory:
Inheritance graph
[legend]

List of all members.

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

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 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
                     &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 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]

Definition at line 302 of file rlsharedmemory.cpp.

{
  delete [] name;
#ifdef RLWIN32
  if(status != OK) return;
  CloseHandle((HANDLE) id);
  CloseHandle((HANDLE) shmkey);
#endif
}

Member Function Documentation

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,&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);
  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;
}

Member Data Documentation

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.

Definition at line 67 of file rlsharedmemory.h.

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.


The documentation for this class was generated from the following files:
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines