Share Library (C++)
File detail
Source code
/**
* @file SharedSegment.cpp
* @brief Platform-indepent shared segment representation
* @author Kamil Dudka, xdudka00@gmail.com
* @date 2007-05-15
* @ingroup backend
*/
#include "SharedSegment.h"
#ifdef _LINUX
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/shm.h>
#endif // _LINUX
using namespace Share;
void SharedSegment::setName (const char *name)
{
szName_ = new char[strlen (name) + 1];
strcpy (szName_, name);
}
#ifdef _LINUX
namespace
{
/**
* This function was copy-pasted from MDSTk
* and will be documented later.
*/
//! Creates a unique system identifier from a given string
unsigned CreateKey(const std::string& sId)
{
// String conversion/hash function parameters
static const unsigned uShift = 6;
static const unsigned uMask = ~0U << (16U - uShift);
// String to UInt conversion
unsigned uHash = 0;
for (int i = 0; i < (int)sId.length(); i++)
{
uHash = (uHash & uMask) ^ (uHash << uShift) ^ sId[i];
}
// Return the hash
return (uHash & 0xffff);
}
}
SharedSegment::SharedSegment (const char *name, size_t size) throw (ShareException)
{
setName (name);
// Create the shared memory key (MDSTk)
key_t key = static_cast<key_t> (CreateKey(name));
id_= shmget (key, size, IPC_CREAT | IPC_EXCL | 0600);
if (0 >= id_)
throw ShareException ("Segment: Unable to create new shared segment - shmget() failed");
attach ();
}
SharedSegment::SharedSegment (const char *name) throw (ShareException)
{
setName (name);
// Create the shared memory key (MDSTk)
key_t key = static_cast<key_t> (CreateKey(name));
id_= shmget (key, 0, 0600);
if (0 >= id_)
throw ShareException ("Segment: Unable to attach to existing shared segment - shmget() failed");
attach ();
}
SharedSegment::~SharedSegment () throw ()
{
//std::cout<<"=== Detaching segment with id "<<id_<<" attached at address "<<atAddr_<<"\n";
if (atAddr_)
shmdt (atAddr_);
delete[] szName_;
}
void SharedSegment::destroy ()
{
//std::cout<<"Segment::destroy()\n";
if (id_);
shmctl (id_, IPC_RMID, 0);
}
void SharedSegment::attach ()
{
atAddr_= shmat (id_, 0, 0);
if (!atAddr_)
throw ShareException ("Segment: Unable to attach shared segment - shmat() failded");
//std::cout<<"=== Attached segment with id "<<id_<<" at address "<<atAddr_<<"\n";
}
#endif // _LINUX
#ifdef _WIN32
SharedSegment::SharedSegment (const char *name, size_t size) throw (ShareException)
{
setName (name);
id_ = CreateFileMappingA (
INVALID_HANDLE_VALUE,
0,
PAGE_READWRITE,
0,
static_cast<DWORD>(size),
name
);
if (NULL== id_ || INVALID_HANDLE_VALUE== id_)
throw ShareException ("Segment: Unable to create new shared segment - CreateFileMappingA() failed");
if (GetLastError() == ERROR_ALREADY_EXISTS) {
CloseHandle (id_);
throw ShareException ("Segment: Unable to create new shared segment - given name already exist");
}
this-> attach();
}
SharedSegment::SharedSegment (const char *name) throw (ShareException)
{
setName (name);
id_ = OpenFileMappingA (
FILE_MAP_WRITE,
false,
name
);
if (NULL== id_ || INVALID_HANDLE_VALUE== id_)
throw ShareException ("Segment: Unable to attach to existing shared segment - OpenFileMappingA() failed");
this-> attach();
}
SharedSegment::~SharedSegment ()
{
if (atAddr_)
UnmapViewOfFile (atAddr_);
if (id_)
CloseHandle (id_);
delete[] szName_;
}
void SharedSegment::attach ()
{
atAddr_= MapViewOfFile (
id_,
FILE_MAP_WRITE,
0,
0,
0
);
if (!atAddr_) {
CloseHandle (id_);
throw ShareException ("Segment: Unable to attach to shared segment - MapViewOfFile() failed");
}
}
void SharedSegment::destroy ()
{
//std::cout << "Segment::destroy()\n";
}
#endif // _WIN32