Add basic shared memory support for Windows OS

This commit is contained in:
alex85k 2014-04-07 17:07:27 +06:00
parent 75303c95f8
commit 3282d410c4

View File

@ -34,7 +34,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/interprocess/mapped_region.hpp>
#ifndef WIN32
#include <boost/interprocess/xsi_shared_memory.hpp>
#else
#include <boost/interprocess/shared_memory_object.hpp>
#endif
#ifdef __linux__
#include <sys/ipc.h>
@ -57,6 +61,7 @@ struct OSRMLockFile
}
};
#ifndef WIN32
class SharedMemory
{
@ -189,6 +194,144 @@ class SharedMemory
boost::interprocess::mapped_region region;
shm_remove remover;
};
#else
// Windows - specific code
class SharedMemory : boost::noncopyable
{
//Remove shared memory on destruction
class shm_remove : boost::noncopyable
{
private:
char* m_shmid;
bool m_initialized;
public:
void SetID(char* shmid)
{
m_shmid = shmid;
m_initialized = true;
}
shm_remove() : m_shmid("undefined"), m_initialized(false) {}
~shm_remove()
{
if(m_initialized)
{
SimpleLogger().Write(logDEBUG) <<
"automatic memory deallocation";
if(!boost::interprocess::shared_memory_object::remove(m_shmid))
{
SimpleLogger().Write(logDEBUG) << "could not deallocate id " << m_shmid;
}
}
}
};
public:
void * Ptr() const
{
return region.get_address();
}
SharedMemory(
const boost::filesystem::path & lock_file,
const int id,
const uint64_t size = 0,
bool read_write = false,
bool remove_prev = true)
{
sprintf(key,"%s.%d","osrm.lock", id);
if( 0 == size )
{ //read_only
shm = boost::interprocess::shared_memory_object(
boost::interprocess::open_only,
key,
read_write ? boost::interprocess::read_write : boost::interprocess::read_only);
region = boost::interprocess::mapped_region (
shm, read_write ? boost::interprocess::read_write : boost::interprocess::read_only);
} else
{ //writeable pointer
//remove previously allocated mem
if( remove_prev )
{
Remove(key);
}
shm = boost::interprocess::shared_memory_object (
boost::interprocess::open_or_create, key, boost::interprocess::read_write);
shm.truncate(size);
region = boost::interprocess::mapped_region( shm, boost::interprocess::read_write);
remover.SetID( key );
SimpleLogger().Write(logDEBUG) <<
"writeable memory allocated " << size << " bytes";
}
}
static bool RegionExists(const int id)
{
bool result = true;
try
{
char k[500];
build_key(id, k);
result = RegionExists(k);
} catch(...)
{
result = false;
}
return result;
}
static bool Remove(const int id)
{
char k[500];
build_key(id, k);
return Remove(k);
}
private:
static void build_key(int id, char* key)
{
OSRMLockFile lock_file;
sprintf(key,"%s.%d","osrm.lock", id);
}
static bool RegionExists(const char* key)
{
bool result = true;
try
{
boost::interprocess::shared_memory_object shm(
boost::interprocess::open_only, key, boost::interprocess::read_write);
} catch(...)
{
result = false;
}
return result;
}
static bool Remove(char* key)
{
bool ret = false;
try
{
SimpleLogger().Write(logDEBUG) << "deallocating prev memory";
ret = boost::interprocess::shared_memory_object::remove(key);
} catch(const boost::interprocess::interprocess_exception &e)
{
if(e.get_error_code() != boost::interprocess::not_found_error)
{
throw;
}
}
return ret;
}
char key[500];
boost::interprocess::shared_memory_object shm;
boost::interprocess::mapped_region region;
shm_remove remover;
};
#endif
template <class LockFileT = OSRMLockFile> class SharedMemoryFactory_tmpl
{