diff --git a/DataStructures/SharedMemoryFactory.h b/DataStructures/SharedMemoryFactory.h index 818ad7baa..3223c083c 100644 --- a/DataStructures/SharedMemoryFactory.h +++ b/DataStructures/SharedMemoryFactory.h @@ -34,7 +34,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#ifndef WIN32 #include +#else +#include +#endif #ifdef __linux__ #include @@ -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 SharedMemoryFactory_tmpl {