I'm modifying a piece of CORBA software to use shared memory as a transport. I created a shared memory class that houses all the necessary calls to implement shared memory. The issue is that when I call this class in another class the shared memory is not created, but all of my methods return true as if they function correctly. Shm_open
returns a non negative int (3), which indicates it didn't fail. When I replaced my class calls with hard coded shm_open
inside the orb.cc
class though it creates the shared memory segment.
Is this a permission issue, or is my class not just being called correctly even though all my debugging says it correctly created the segment even though it doesn't appear in /dev/shm
?
Apologies on the formatting first time posting code.
Thanks in advance.
sharedMemory.cc
#include "sharedMemory.h"
#include <sys/mman.h>
#include <errno.h>
#include <cstdio>
#include <cstdlib>
#include <CORBA-SMALL.h>
#include <mico/os-net.h>
#include <semaphore.h>
#include <pthread.h>
using namespace std;
MICO::CSharedMemory::CSharedMemory( const string& sName) :m_sName(sName),m_Ptr(NULL),m_iD(-1),
m_nSize(0)
{
m_SemiD = NULL;
}
std::string MICO::CSharedMemory::sLockSemaphoreName;
bool
MICO::CSharedMemory::openSem(std::string sem)
{
sLockSemaphoreName = sem;
m_SemiD = sem_open(sLockSemaphoreName.c_str(), O_CREAT, S_IRUSR | S_IWUSR, 1);
return true;
}
bool
MICO::CSharedMemory::Create( size_t nSize, int mode /*= READ_WRITE*/ )
{
m_nSize = nSize;
m_iD = shm_open(m_sName.c_str(), O_CREAT | O_RDWR, 0777);
if(m_iD < 0)
{
switch(errno)
{
case EACCES:
throw CSharedMemoryException("Permission Exception ");
cout << "\nEACCES";
break;
case EEXIST:
cout << "\nEEXIST";
throw CSharedMemoryException("Shared memory object specified by name already exists.");
break;
case EINVAL:
cout << "\nEINVAL";
throw CSharedMemoryException("Invalid shared memory name passed.");
break;
case EMFILE:
throw CSharedMemoryException("The process already has the maximum number of files open.");
break;
case ENAMETOOLONG:
throw CSharedMemoryException("The length of name exceeds PATH_MAX.");
break;
case ENFILE:
throw CSharedMemoryException("The limit on the total number of files open on the system has been reached");
break;
default:
cout << "\ndefault";
throw CSharedMemoryException("Invalid exception occurred in shared memory creation");
break;
}
}
/* adjusting mapped file size (make room for the whole segment to map) -- ftruncate() */
ftruncate(m_iD, m_nSize);
return true;
}
sharedMemory.h
#include <string>
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <sys/mman.h>
#include <fcntl.h> /* For O_* constants */
#include <semaphore.h>
#include <pthread.h>
namespace MICO {
/**
* Signals a problem with the execution of a SharedMemory call.
*/
class CSharedMemoryException: public std::exception
{
public:
/**
* Construct a SharedMemoryException with a explanatory message.
* @param message explanatory message
* @param bSysMsg true if system message (from strerror(errno))
* should be postfixed to the user provided message
*/
CSharedMemoryException(const std::string &message, bool bSysMsg = false) throw();
/** Destructor.
* Virtual to allow for subclassing.
*/
virtual ~CSharedMemoryException() throw ();
/** Returns a pointer to the (constant) error description.
* @return A pointer to a \c const \c char*. The underlying memory
* is in posession of the \c Exception object. Callers \a must
* not attempt to free the memory.
*/
virtual const char* what() const throw (){ return m_sMsg.c_str(); }
protected:
/** Error message.
*/
std::string m_sMsg;
};
class CSharedMemory
{
public:
enum
{
C_READ_ONLY = O_RDONLY,
C_READ_WRITE = O_RDWR,
} CREATE_MODE;
enum
{
A_READ = PROT_READ,
A_WRITE = PROT_WRITE,
} ATTACH_MODE;
static std::string sLockSemaphoreName;
public:
CSharedMemory(const std::string& sName );
~CSharedMemory();
bool openSem(std::string sem);
bool Create(size_t nSize, int mode = C_READ_WRITE);
bool Attach(int mode = A_READ | A_WRITE);
bool Detach();
bool Lock();
bool UnLock();
int GetID() { return m_iD; }
void* GetData() { return m_Ptr; };
const void* GetData() const { return m_Ptr; }
private:
void Clear();
private:
std::string m_sName;
int m_iD;
sem_t* m_SemiD;
size_t m_nSize;
void* m_Ptr;
};
}
#endif // __mico_transport_sharedMemory_h_
Orb.cc class
void sharedMemory(string address, string sem, int length){
try{
MICO::CSharedMemory shmMemory(address);
shmMemory.Create(length);
shmMemory.Attach();
} catch(std::exception& e){
cout << "Exception:" <<e.what();
}
}
Source for Attach Method
bool
MICO::CSharedMemory::Attach( int mode /*= A_READ | A_WRITE*/ )
{
/* requesting the shared segment -- mmap() */
m_Ptr = mmap(NULL, m_nSize, PROT_READ | PROT_WRITE, MAP_SHARED, m_iD, 0);
if (m_Ptr == NULL)
{
cout << "Error in attach";
throw CSharedMemoryException("Exception in attaching the shared memory region");
}
return true;
}