Merge branch 'develop'

This commit is contained in:
Ion Gaztañaga
2017-02-17 11:58:09 +01:00
12 changed files with 527 additions and 131 deletions

View File

@@ -6754,6 +6754,21 @@ thank them:
[section:release_notes Release Notes]
[section:release_notes_boost_1_64_00 Boost 1.64 Release]
* Fixed bugs:
* [@https://svn.boost.org/trac/boost/ticket/12617 Trac #12617 (['"clock_gettime not available on OS X 10.11"])].
* [@https://svn.boost.org/trac/boost/ticket/12744 Trac #12744 (['"winapi::set_timer_resolution inadvertently changes timer resolution (Windows)"])].
* [@https://github.com/boostorg/interprocess/pull/32 GitHub Pull #32 (['"Conform to std::pointer_traits requirements"])].
* [@https://github.com/boostorg/interprocess/pull/33 GitHub Pull #33 (['"explicit cast to derived class" and "64/32 bit processes sharing"])].
* [@https://github.com/boostorg/interprocess/pull/34 GitHub Pull #34 (['"Update example to use multi_index::member instead of BOOST_MULTI_INDEX_MEMBER"])].
* [@https://github.com/boostorg/interprocess/pull/35 GitHub Pull #35 (['"Fixed options for cross-compilation"])].
* New experimental option `BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED` from Windows systems.
This option derives the unique booststamp used to name the folder where shared memory is placed from registry values associated
with the session manager. This option only works on Vista and later systems and might be more stable than the default version.
[endsect]
[section:release_notes_boost_1_63_00 Boost 1.63 Release]
* Fixed bugs:
* [@https://svn.boost.org/trac/boost/ticket/12499 Trac #12499 (['"Memory allocation fails"])].
@@ -6770,7 +6785,7 @@ thank them:
[section:release_notes_boost_1_61_00 Boost 1.61 Release]
* Fixed bugs:
* [@https://github.com/boostorg/interprocess/pull/23 GitHub Pull #23 (['"Fixed case sensetive for linux mingw"])].
* [@https://github.com/boostorg/interprocess/pull/23 GitHub Pull #23 (['"Fixed case sensitive for linux mingw"])].
[endsect]

View File

@@ -26,9 +26,9 @@ rule test_all
<toolset>acc:<linkflags>-lrt
<toolset>acc-pa_risc:<linkflags>-lrt
<toolset>gcc,<target-os>windows:<linkflags>"-lole32 -loleaut32 -lpsapi -ladvapi32"
<host-os>hpux,<toolset>gcc:<linkflags>"-Wl,+as,mpas"
<host-os>windows,<toolset>clang:<linkflags>"-lole32 -loleaut32 -lpsapi -ladvapi32"
<host-os>linux:<linkflags>"-lrt"
<target-os>hpux,<toolset>gcc:<linkflags>"-Wl,+as,mpas"
<target-os>windows,<toolset>clang:<linkflags>"-lole32 -loleaut32 -lpsapi -ladvapi32"
<target-os>linux:<linkflags>"-lrt"
: # test-files
: # requirements
] ;
@@ -43,9 +43,9 @@ rule test_all
<toolset>acc:<linkflags>-lrt
<toolset>acc-pa_risc:<linkflags>-lrt
<toolset>gcc-mingw:<linkflags>"-lole32 -loleaut32 -lpsapi -ladvapi32"
<host-os>hpux,<toolset>gcc:<linkflags>"-Wl,+as,mpas"
<host-os>windows,<toolset>clang:<linkflags>"-lole32 -loleaut32 -lpsapi -ladvapi32"
<host-os>linux:<linkflags>"-lrt"
<target-os>hpux,<toolset>gcc:<linkflags>"-Wl,+as,mpas"
<target-os>windows,<toolset>clang:<linkflags>"-lole32 -loleaut32 -lpsapi -ladvapi32"
<target-os>linux:<linkflags>"-lrt"
] ;
}

View File

@@ -61,11 +61,11 @@ typedef bmi::multi_index_container<
employee,
bmi::indexed_by<
bmi::ordered_unique
<bmi::tag<id>, BOOST_MULTI_INDEX_MEMBER(employee,int,id)>,
<bmi::tag<id>, bmi::member<employee,int,&employee::id> >,
bmi::ordered_non_unique<
bmi::tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,shm_string,name)>,
bmi::tag<name>, bmi::member<employee,shm_string,&employee::name> >,
bmi::ordered_non_unique
<bmi::tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >,
<bmi::tag<age>, bmi::member<employee,int,&employee::age> > >,
managed_shared_memory::allocator<employee>::type
> employee_set;

View File

@@ -102,6 +102,9 @@ inline file_handle_t file_handle_from_mapping_handle(mapping_handle_t hnd)
inline bool create_directory(const char *path)
{ return winapi::create_directory(path); }
inline bool remove_directory(const char *path)
{ return winapi::remove_directory(path); }
inline bool get_temporary_path(char *buffer, std::size_t buf_len, std::size_t &required_len)
{
required_len = 0;
@@ -422,6 +425,9 @@ inline file_handle_t file_handle_from_mapping_handle(mapping_handle_t hnd)
inline bool create_directory(const char *path)
{ return ::mkdir(path, 0777) == 0 && ::chmod(path, 0777) == 0; }
inline bool remove_directory(const char *path)
{ return ::rmdir(path) == 0; }
inline bool get_temporary_path(char *buffer, std::size_t buf_len, std::size_t &required_len)
{
required_len = 5u;

View File

@@ -53,7 +53,12 @@
# include <sys/sysctl.h>
# endif
//According to the article "C/C++ tip: How to measure elapsed real time for benchmarking"
# if defined(CLOCK_MONOTONIC_PRECISE) //BSD
//Check MacOs first as macOS 10.12 SDK defines both CLOCK_MONOTONIC and
//CLOCK_MONOTONIC_RAW and no clock_gettime.
# if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
# include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t
# define BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME
# elif defined(CLOCK_MONOTONIC_PRECISE) //BSD
# define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_MONOTONIC_PRECISE
# elif defined(CLOCK_MONOTONIC_RAW) //Linux
# define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_MONOTONIC_RAW
@@ -61,9 +66,6 @@
# define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_HIGHRES
# elif defined(CLOCK_MONOTONIC) //POSIX (AIX, BSD, Linux, Solaris)
# define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_MONOTONIC
# elif !defined(CLOCK_MONOTONIC) && (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
# include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t
# define BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME
# else
# error "No high resolution steady clock in your system, please provide a patch"
# endif
@@ -112,8 +114,8 @@ inline bool equal_thread_id(OS_thread_id_t id1, OS_thread_id_t id2)
//return the system tick in ns
inline unsigned long get_system_tick_ns()
{
unsigned long curres;
winapi::set_timer_resolution(10000, 0, &curres);
unsigned long curres, ignore1, ignore2;
winapi::query_timer_resolution(&ignore1, &ignore2, &curres);
//Windows API returns the value in hundreds of ns
return (curres - 1ul)*100ul;
}
@@ -121,8 +123,8 @@ inline unsigned long get_system_tick_ns()
//return the system tick in us
inline unsigned long get_system_tick_us()
{
unsigned long curres;
winapi::set_timer_resolution(10000, 0, &curres);
unsigned long curres, ignore1, ignore2;
winapi::query_timer_resolution(&ignore1, &ignore2, &curres);
//Windows API returns the value in hundreds of ns
return (curres - 1ul)/10ul + 1ul;
}
@@ -132,8 +134,8 @@ typedef unsigned __int64 OS_highres_count_t;
inline unsigned long get_system_tick_in_highres_counts()
{
__int64 freq;
unsigned long curres;
winapi::set_timer_resolution(10000, 0, &curres);
unsigned long curres, ignore1, ignore2;
winapi::query_timer_resolution(&ignore1, &ignore2, &curres);
//Frequency in counts per second
if(!winapi::query_performance_frequency(&freq)){
//Tick resolution in ms

View File

@@ -156,29 +156,29 @@ BOOST_INTERPROCESS_FORCEINLINE bool size_overflows(SizeType count)
return multiplication_overflows(SizeType(SztSizeOfType), count);
}
template<class RawPointer>
class pointer_uintptr_caster;
template<class RawPointer, class OffsetType>
class pointer_offset_caster;
template<class T>
class pointer_uintptr_caster<T*>
template<class T, class OffsetType>
class pointer_offset_caster<T*, OffsetType>
{
public:
BOOST_INTERPROCESS_FORCEINLINE explicit pointer_uintptr_caster(uintptr_t sz)
: m_uintptr(sz)
BOOST_INTERPROCESS_FORCEINLINE explicit pointer_offset_caster(OffsetType offset)
: m_offset(offset)
{}
BOOST_INTERPROCESS_FORCEINLINE explicit pointer_uintptr_caster(const volatile T *p)
: m_uintptr(reinterpret_cast<uintptr_t>(p))
BOOST_INTERPROCESS_FORCEINLINE explicit pointer_offset_caster(const volatile T *p)
: m_offset(reinterpret_cast<OffsetType>(p))
{}
BOOST_INTERPROCESS_FORCEINLINE uintptr_t uintptr() const
{ return m_uintptr; }
BOOST_INTERPROCESS_FORCEINLINE OffsetType offset() const
{ return m_offset; }
BOOST_INTERPROCESS_FORCEINLINE T* pointer() const
{ return reinterpret_cast<T*>(m_uintptr); }
{ return reinterpret_cast<T*>(m_offset); }
private:
uintptr_t m_uintptr;
OffsetType m_offset;
};

View File

@@ -31,9 +31,45 @@
#include <string>
#include <vector>
//#define BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME
//#define BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED
//#define BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED
#ifdef BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME
# define BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME_VALUE 1
#else
# define BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME_VALUE 0
#endif
#ifdef BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED
# define BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED_VALUE 1
#else
# define BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED_VALUE 0
#endif
#ifdef BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED
# define BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED_VALUE 1
#else
# define BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED_VALUE 0
#endif
#define BOOST_INTERPROCESS_BOOTSTAMP_VALUE_SUM \
(BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED_VALUE + \
BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED_VALUE + \
BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME_VALUE)
#if 1 < BOOST_INTERPROCESS_BOOTSTAMP_VALUE_SUM
# error "Only one of BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME, \
BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED and \
BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED can be defined"
#endif
#if 0 == BOOST_INTERPROCESS_BOOTSTAMP_VALUE_SUM
# define BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED
#endif
#ifdef BOOST_USE_WINDOWS_H
#include <windows.h>
# if defined(BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME)
# include <wbemidl.h>
# include <objbase.h>
@@ -1162,6 +1198,23 @@ const unsigned long COINIT_MULTITHREADED_BIPC = 0x0;
const unsigned long COINIT_DISABLE_OLE1DDE_BIPC = 0x4;
const unsigned long COINIT_SPEED_OVER_MEMORY_BIPC = 0x4;
// Registry types
#define reg_none ( 0 ) // No value type
#define reg_sz ( 1 ) // Unicode nul terminated string
#define reg_expand_sz ( 2 ) // Unicode nul terminated string
// (with environment variable references)
#define reg_binary ( 3 ) // Free form binary
#define reg_dword ( 4 ) // 32-bit number
#define reg_dword_little_endian ( 4 ) // 32-bit number (same as REG_DWORD)
#define reg_dword_big_endian ( 5 ) // 32-bit number
#define reg_link ( 6 ) // Symbolic Link (unicode)
#define reg_multi_sz ( 7 ) // Multiple Unicode strings
#define reg_resource_list ( 8 ) // Resource list in the resource map
#define reg_full_resource_descriptor ( 9 ) // Resource list in the hardware description
#define reg_resource_requirements_list ( 10 )
#define reg_qword ( 11 ) // 64-bit number
#define reg_qword_little_endian ( 11 ) // 64-bit number (same as reg_qword)
//If the user needs to change default COM initialization model,
//it can define BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL to one of these:
@@ -1654,28 +1707,6 @@ inline bool get_boot_and_system_time(unsigned char (&bootsystemstamp) [BootAndSy
return true;
}
inline bool get_boot_time_str(char *bootstamp_str, std::size_t &s)
//will write BootstampLength chars
{
if(s < (BootstampLength*2))
return false;
system_timeofday_information info;
bool ret = get_system_time_of_day_information(info);
if(!ret){
return false;
}
const char Characters [] =
{ '0', '1', '2', '3', '4', '5', '6', '7'
, '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
std::size_t char_counter = 0;
for(std::size_t i = 0; i != static_cast<std::size_t>(BootstampLength); ++i){
bootstamp_str[char_counter++] = Characters[(info.Reserved1[i]&0xF0)>>4];
bootstamp_str[char_counter++] = Characters[(info.Reserved1[i]&0x0F)];
}
s = BootstampLength*2;
return true;
}
//Writes the hexadecimal value of the buffer, in the wide character string.
//str must be twice length
inline void buffer_to_wide_str(const void *buf, std::size_t length, wchar_t *str)
@@ -1691,6 +1722,37 @@ inline void buffer_to_wide_str(const void *buf, std::size_t length, wchar_t *str
}
}
//Writes the hexadecimal value of the buffer, in the narrow character string.
//str must be twice length
inline void buffer_to_narrow_str(const void *buf, std::size_t length, char *str)
{
const char Characters [] =
{ '0', '1', '2', '3', '4', '5', '6', '7'
, '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
std::size_t char_counter = 0;
const char *chbuf = static_cast<const char *>(buf);
for(std::size_t i = 0; i != length; ++i){
str[char_counter++] = Characters[(chbuf[i]&0xF0)>>4];
str[char_counter++] = Characters[(chbuf[i]&0x0F)];
}
}
inline bool get_boot_time_str(char *bootstamp_str, std::size_t &s)
//will write BootstampLength chars
{
if(s < (BootstampLength*2))
return false;
system_timeofday_information info;
bool ret = get_system_time_of_day_information(info);
if(!ret){
return false;
}
buffer_to_narrow_str(info.Reserved1, BootstampLength, bootstamp_str);
s = BootstampLength*2;
return true;
}
inline bool get_boot_and_system_time_wstr(wchar_t *bootsystemstamp, std::size_t &s)
//will write BootAndSystemstampLength chars
{
@@ -1748,7 +1810,7 @@ class nt_query_mem_deleter
(SystemTimeOfDayInfoLength + sizeof(unsigned long) + sizeof(boost::uint32_t))*2;
public:
nt_query_mem_deleter(std::size_t object_name_information_size)
explicit nt_query_mem_deleter(std::size_t object_name_information_size)
: m_size(object_name_information_size + rename_offset + rename_suffix)
, m_buf(new char [m_size])
{}
@@ -1786,7 +1848,7 @@ class nt_query_mem_deleter
class c_heap_deleter
{
public:
c_heap_deleter(std::size_t size)
explicit c_heap_deleter(std::size_t size)
: m_buf(::malloc(size))
{}
@@ -1935,13 +1997,35 @@ struct reg_closer
~reg_closer(){ reg_close_key(key_); }
};
inline void get_shared_documents_folder(std::string &s)
inline bool get_registry_value_buffer(hkey key_type, const char *subkey_name, const char *value_name, void *buf, std::size_t &buflen)
{
#if 1 //Original registry search code
bool bret = false;
hkey key;
if (reg_open_key_ex( key_type
, subkey_name
, 0
, key_query_value
, &key) == 0){
reg_closer key_closer(key);
//Obtain the value
unsigned long size = buflen;
unsigned long type;
buflen = 0;
bret = 0 == reg_query_value_ex( key, value_name, 0, &type, (unsigned char*)buf, &size);
if(bret)
buflen = (std::size_t)size;
}
return bret;
}
inline bool get_registry_value_string(hkey key_type, const char *subkey_name, const char *value_name, std::string &s)
{
bool bret = false;
s.clear();
hkey key;
if (reg_open_key_ex( hkey_local_machine
, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
if (reg_open_key_ex( key_type
, subkey_name
, 0
, key_query_value
, &key) == 0){
@@ -1950,19 +2034,28 @@ inline void get_shared_documents_folder(std::string &s)
//Obtain the value
unsigned long size;
unsigned long type;
const char *const reg_value = "Common AppData";
//long err = (*pRegQueryValue)( key, reg_value, 0, &type, 0, &size);
long err = reg_query_value_ex( key, reg_value, 0, &type, 0, &size);
if(!err){
long err = reg_query_value_ex( key, value_name, 0, &type, 0, &size);
if((reg_sz == type || reg_expand_sz != type) && !err){
//Size includes terminating NULL
s.resize(size);
//err = (*pRegQueryValue)( key, reg_value, 0, &type, (unsigned char*)(&s[0]), &size);
err = reg_query_value_ex( key, reg_value, 0, &type, (unsigned char*)(&s[0]), &size);
if(!err)
err = reg_query_value_ex( key, value_name, 0, &type, (unsigned char*)(&s[0]), &size);
if(!err){
s.erase(s.end()-1);
bret = true;
}
(void)err;
}
}
return bret;
}
inline void get_shared_documents_folder(std::string &s)
{
#if 1 //Original registry search code
get_registry_value_string( hkey_local_machine
, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
, "Common AppData"
, s);
#else //registry alternative: SHGetFolderPath
const int BIPC_CSIDL_COMMON_APPDATA = 0x0023; // All Users\Application Data
const int BIPC_CSIDL_FLAG_CREATE = 0x8000; // new for Win2K, or this in to force creation of folder
@@ -2175,7 +2268,9 @@ inline bool get_last_bootup_time( std::string& str )
return ret;
}
#else
#endif //BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME
#if defined(BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED)
// Loop through the buffer and obtain the contents of the
// requested record in the buffer.
@@ -2271,7 +2366,41 @@ inline bool get_last_bootup_time(std::string &stamp)
return true;
}
#endif
#endif //BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED
#if defined(BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED)
inline bool get_last_bootup_time(std::string &stamp)
{
unsigned dword_val = 0;
std::size_t dword_size = sizeof(dword_val);
bool b_ret = get_registry_value_buffer( hkey_local_machine
, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management\\PrefetchParameters"
, "BootId", &dword_val, dword_size);
if (b_ret)
{
char dword_str[sizeof(dword_val)*2u+1];
buffer_to_narrow_str(&dword_val, dword_size, dword_str);
dword_str[sizeof(dword_val)*2] = '\0';
stamp = dword_str;
b_ret = get_registry_value_buffer( hkey_local_machine
, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Power"
, "HybridBootAnimationTime", &dword_val, dword_size);
//Old Windows versions have no HybridBootAnimationTime
if(b_ret)
{
buffer_to_narrow_str(&dword_val, dword_size, dword_str);
dword_str[sizeof(dword_val)*2] = '\0';
stamp += "_";
stamp += dword_str;
}
b_ret = true;
}
return b_ret;
}
#endif //BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED
inline bool is_directory(const char *path)
{

View File

@@ -23,6 +23,9 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_constructible.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_unsigned.hpp>
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/detail/utilities.hpp>
@@ -55,6 +58,7 @@ namespace ipcdetail {
union offset_ptr_internal
{
BOOST_STATIC_ASSERT(sizeof(OffsetType) >= sizeof(uintptr_t));
BOOST_STATIC_ASSERT(boost::is_integral<OffsetType>::value && boost::is_unsigned<OffsetType>::value);
explicit offset_ptr_internal(OffsetType off)
: m_offset(off)
@@ -81,20 +85,21 @@ namespace ipcdetail {
//
////////////////////////////////////////////////////////////////////////
#define BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_PTR
BOOST_INTERPROCESS_FORCEINLINE void * offset_ptr_to_raw_pointer(const volatile void *this_ptr, uintptr_t offset)
template <class OffsetType>
BOOST_INTERPROCESS_FORCEINLINE void * offset_ptr_to_raw_pointer(const volatile void *this_ptr, OffsetType offset)
{
typedef pointer_uintptr_caster<void*> caster_t;
typedef pointer_offset_caster<void*, OffsetType> caster_t;
#ifndef BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_PTR
if(offset == 1){
return 0;
}
else{
return caster_t(caster_t(this_ptr).uintptr() + offset).pointer();
return caster_t(caster_t(this_ptr).offset() + offset).pointer();
}
#else
uintptr_t mask = offset == 1;
OffsetType mask = offset == 1;
--mask;
uintptr_t target_offset = caster_t(this_ptr).uintptr() + offset;
OffsetType target_offset = caster_t(this_ptr).offset() + offset;
target_offset &= mask;
return caster_t(target_offset).pointer();
#endif
@@ -106,27 +111,28 @@ namespace ipcdetail {
//
////////////////////////////////////////////////////////////////////////
#define BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_OFF
BOOST_INTERPROCESS_FORCEINLINE uintptr_t offset_ptr_to_offset(const volatile void *ptr, const volatile void *this_ptr)
template<class OffsetType>
BOOST_INTERPROCESS_FORCEINLINE OffsetType offset_ptr_to_offset(const volatile void *ptr, const volatile void *this_ptr)
{
typedef pointer_uintptr_caster<void*> caster_t;
typedef pointer_offset_caster<void*, OffsetType> caster_t;
#ifndef BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_OFF
//offset == 1 && ptr != 0 is not legal for this pointer
if(!ptr){
return 1;
}
else{
uintptr_t offset = caster_t(ptr).uintptr() - caster_t(this_ptr).uintptr();
OffsetType offset = caster_t(ptr).offset()- caster_t(this_ptr).offset();
BOOST_ASSERT(offset != 1);
return offset;
}
#else
//const uintptr_t other = -uintptr_t(ptr != 0);
//const uintptr_t offset = (caster_t(ptr).uintptr() - caster_t(this_ptr).uintptr()) & other;
//return offset + uintptr_t(!other);
//const OffsetType other = -OffsetType(ptr != 0);
//const OffsetType offset = (caster_t(ptr).offset() - caster_t(this_ptr).offset()) & other;
//return offset + OffsetType(!other);
//
uintptr_t offset = caster_t(ptr).uintptr() - caster_t(this_ptr).uintptr();
OffsetType offset = caster_t(ptr).offset() - caster_t(this_ptr).offset();
--offset;
uintptr_t mask = uintptr_t(ptr == 0);
OffsetType mask = ptr == 0;
--mask;
offset &= mask;
return ++offset;
@@ -139,28 +145,29 @@ namespace ipcdetail {
//
////////////////////////////////////////////////////////////////////////
#define BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_OFF_FROM_OTHER
BOOST_INTERPROCESS_FORCEINLINE uintptr_t offset_ptr_to_offset_from_other
(const volatile void *this_ptr, const volatile void *other_ptr, uintptr_t other_offset)
template<class OffsetType>
BOOST_INTERPROCESS_FORCEINLINE OffsetType offset_ptr_to_offset_from_other
(const volatile void *this_ptr, const volatile void *other_ptr, OffsetType other_offset)
{
typedef pointer_uintptr_caster<void*> caster_t;
typedef pointer_offset_caster<void*, OffsetType> caster_t;
#ifndef BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_OFF_FROM_OTHER
if(other_offset == 1){
return 1;
}
else{
uintptr_t offset = caster_t(other_ptr).uintptr() - caster_t(this_ptr).uintptr() + other_offset;
OffsetType offset = caster_t(other_ptr).offset() - caster_t(this_ptr).offset() + other_offset;
BOOST_ASSERT(offset != 1);
return offset;
}
#else
uintptr_t mask = other_offset == 1;
OffsetType mask = other_offset == 1;
--mask;
uintptr_t offset = caster_t(other_ptr).uintptr() - caster_t(this_ptr).uintptr();
OffsetType offset = caster_t(other_ptr).offset() - caster_t(this_ptr).offset();
offset &= mask;
return offset + other_offset;
//uintptr_t mask = -uintptr_t(other_offset != 1);
//uintptr_t offset = caster_t(other_ptr).uintptr() - caster_t(this_ptr).uintptr();
//OffsetType mask = -OffsetType(other_offset != 1);
//OffsetType offset = caster_t(other_ptr).offset() - caster_t(this_ptr).offset();
//offset &= mask;
//return offset + other_offset;
#endif
@@ -215,9 +222,9 @@ namespace ipcdetail {
//!
//!<b>Note</b>: offset_ptr uses implementation defined properties, present in most platforms, for
//!performance reasons:
//! - Assumes that uintptr_t representation of nullptr is (uintptr_t)zero.
//! - Assumes that incrementing a uintptr_t obtained from a pointer is equivalent
//! to incrementing the pointer and then converting it back to uintptr_t.
//! - Assumes that OffsetType representation of nullptr is (OffsetType)zero.
//! - Assumes that incrementing a OffsetType obtained from a pointer is equivalent
//! to incrementing the pointer and then converting it back to OffsetType.
template <class PointedType, class DifferenceType, class OffsetType, std::size_t OffsetAlignment>
class offset_ptr
{
@@ -251,7 +258,7 @@ class offset_ptr
//!Constructor from raw pointer (allows "0" pointer conversion).
//!Never throws.
BOOST_INTERPROCESS_FORCEINLINE offset_ptr(pointer ptr) BOOST_NOEXCEPT
: internal(static_cast<OffsetType>(ipcdetail::offset_ptr_to_offset(ptr, this)))
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(ptr, this))
{}
//!Constructor from other pointer.
@@ -259,78 +266,81 @@ class offset_ptr
template <class T>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr( T *ptr
, typename ipcdetail::enable_if< ::boost::is_convertible<T*, PointedType*> >::type * = 0) BOOST_NOEXCEPT
: internal(static_cast<OffsetType>
(ipcdetail::offset_ptr_to_offset(static_cast<PointedType*>(ptr), this)))
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr), this))
{}
//!Constructor from other offset_ptr
//!Never throws.
BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr& ptr) BOOST_NOEXCEPT
: internal(static_cast<OffsetType>
(ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.internal.m_offset)))
: internal(ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.internal.m_offset))
{}
//!Constructor from other offset_ptr. If pointers of pointee types are
//!convertible, offset_ptrs will be convertibles. Never throws.
//!Constructor from other offset_ptr. Only takes part in overload resolution
//!if T2* is convertible to PointedType*. Never throws.
template<class T2>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr( const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
, typename ipcdetail::enable_if_convertible_equal_address<T2, PointedType>::type* = 0
#endif
) BOOST_NOEXCEPT
: internal(static_cast<OffsetType>
(ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.get_offset())))
: internal(ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.get_offset()))
{}
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
//!Constructor from other offset_ptr. If pointers of pointee types are
//!convertible, offset_ptrs will be convertibles. Never throws.
template<class T2>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr( const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr
, typename ipcdetail::enable_if_convertible_unequal_address<T2, PointedType>::type* = 0) BOOST_NOEXCEPT
: internal(static_cast<OffsetType>
(ipcdetail::offset_ptr_to_offset(static_cast<PointedType*>(ptr.get()), this)))
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr.get()), this))
{}
#endif
//!Constructor from other offset_ptr. Only takes part in overload resolution
//!if PointedType* is constructible from T2* other than via a conversion (e.g. cast to a derived class). Never throws.
template<class T2>
BOOST_INTERPROCESS_FORCEINLINE explicit offset_ptr(const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
, typename ipcdetail::enable_if_c<
!::boost::is_convertible<T2*, PointedType*>::value && ::boost::is_constructible<T2*, PointedType*>::value
>::type * = 0
#endif
) BOOST_NOEXCEPT
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr.get()), this))
{}
//!Emulates static_cast operator.
//!Never throws.
template<class T2, class P2, class O2, std::size_t A2>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::static_cast_tag) BOOST_NOEXCEPT
: internal(static_cast<OffsetType>
(ipcdetail::offset_ptr_to_offset(static_cast<PointedType*>(r.get()), this)))
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(r.get()), this))
{}
//!Emulates const_cast operator.
//!Never throws.
template<class T2, class P2, class O2, std::size_t A2>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::const_cast_tag) BOOST_NOEXCEPT
: internal(static_cast<OffsetType>
(ipcdetail::offset_ptr_to_offset(const_cast<PointedType*>(r.get()), this)))
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(const_cast<PointedType*>(r.get()), this))
{}
//!Emulates dynamic_cast operator.
//!Never throws.
template<class T2, class P2, class O2, std::size_t A2>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::dynamic_cast_tag) BOOST_NOEXCEPT
: internal(static_cast<OffsetType>
(ipcdetail::offset_ptr_to_offset(dynamic_cast<PointedType*>(r.get()), this)))
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(dynamic_cast<PointedType*>(r.get()), this))
{}
//!Emulates reinterpret_cast operator.
//!Never throws.
template<class T2, class P2, class O2, std::size_t A2>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::reinterpret_cast_tag) BOOST_NOEXCEPT
: internal(static_cast<OffsetType>
(ipcdetail::offset_ptr_to_offset(reinterpret_cast<PointedType*>(r.get()), this)))
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(reinterpret_cast<PointedType*>(r.get()), this))
{}
//!Obtains raw pointer from offset.
//!Never throws.
BOOST_INTERPROCESS_FORCEINLINE pointer get() const BOOST_NOEXCEPT
{ return (pointer)ipcdetail::offset_ptr_to_raw_pointer(this, this->internal.m_offset); }
{ return static_cast<pointer>(ipcdetail::offset_ptr_to_raw_pointer(this, this->internal.m_offset)); }
BOOST_INTERPROCESS_FORCEINLINE offset_type get_offset() const BOOST_NOEXCEPT
{ return this->internal.m_offset; }
@@ -358,8 +368,7 @@ class offset_ptr
//!Never throws.
BOOST_INTERPROCESS_FORCEINLINE offset_ptr& operator= (pointer from) BOOST_NOEXCEPT
{
this->internal.m_offset =
static_cast<OffsetType>(ipcdetail::offset_ptr_to_offset(from, this));
this->internal.m_offset = ipcdetail::offset_ptr_to_offset<OffsetType>(from, this);
return *this;
}
@@ -367,8 +376,7 @@ class offset_ptr
//!Never throws.
BOOST_INTERPROCESS_FORCEINLINE offset_ptr& operator= (const offset_ptr & ptr) BOOST_NOEXCEPT
{
this->internal.m_offset =
static_cast<OffsetType>(ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.internal.m_offset));
this->internal.m_offset = ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.internal.m_offset);
return *this;
}
@@ -444,9 +452,17 @@ class offset_ptr
//!Compatibility with pointer_traits
//!
#if defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class U>
struct rebind
{ typedef offset_ptr<U, DifferenceType, OffsetType, OffsetAlignment> other; };
#else
template <class U>
using rebind = offset_ptr<U, DifferenceType, OffsetType, OffsetAlignment>;
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
typedef offset_ptr<PointedType, DifferenceType, OffsetType, OffsetAlignment> other;
#endif //BOOST_INTERPROCESS_DOXYGEN_INVOKED
#endif
//!Compatibility with pointer_traits
//!
@@ -546,15 +562,13 @@ class offset_ptr
template<class T2>
BOOST_INTERPROCESS_FORCEINLINE void assign(const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr, ipcdetail::bool_<true>) BOOST_NOEXCEPT
{ //no need to pointer adjustment
this->internal.m_offset =
static_cast<OffsetType>(ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.get_offset()));
this->internal.m_offset = ipcdetail::offset_ptr_to_offset_from_other<OffsetType>(this, &ptr, ptr.get_offset());
}
template<class T2>
BOOST_INTERPROCESS_FORCEINLINE void assign(const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr, ipcdetail::bool_<false>) BOOST_NOEXCEPT
{ //we must convert to raw before calculating the offset
this->internal.m_offset =
static_cast<OffsetType>(ipcdetail::offset_ptr_to_offset(static_cast<PointedType*>(ptr.get()), this));
this->internal.m_offset = ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr.get()), this);
}
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
@@ -692,7 +706,7 @@ struct pointer_plus_bits<boost::interprocess::offset_ptr<T, P, O, A>, NumBits>
typedef boost::interprocess::offset_ptr<T, P, O, A> pointer;
//Bits are stored in the lower bits of the pointer except the LSB,
//because this bit is used to represent the null pointer.
static const uintptr_t Mask = ((uintptr_t(1) << uintptr_t(NumBits)) - uintptr_t(1)) << uintptr_t(1);
static const O Mask = ((static_cast<O>(1) << NumBits) - static_cast<O>(1)) << 1;
BOOST_STATIC_ASSERT(0 ==(Mask&1));
//We must ALWAYS take argument "n" by reference as a copy of a null pointer
@@ -701,7 +715,7 @@ struct pointer_plus_bits<boost::interprocess::offset_ptr<T, P, O, A>, NumBits>
BOOST_INTERPROCESS_FORCEINLINE static pointer get_pointer(const pointer &n) BOOST_NOEXCEPT
{
pointer p;
O const tmp_off = n.priv_offset() & O(~Mask);
O const tmp_off = n.priv_offset() & ~Mask;
p.priv_offset() = boost::interprocess::ipcdetail::offset_ptr_to_offset_from_other(&p, &n, tmp_off);
return p;
}
@@ -709,7 +723,7 @@ struct pointer_plus_bits<boost::interprocess::offset_ptr<T, P, O, A>, NumBits>
BOOST_INTERPROCESS_FORCEINLINE static void set_pointer(pointer &n, const pointer &p) BOOST_NOEXCEPT
{
BOOST_ASSERT(0 == (get_bits)(p));
O const stored_bits = O(n.priv_offset() & Mask);
O const stored_bits = n.priv_offset() & Mask;
n = p;
n.priv_offset() |= stored_bits;
}
@@ -723,7 +737,7 @@ struct pointer_plus_bits<boost::interprocess::offset_ptr<T, P, O, A>, NumBits>
{
BOOST_ASSERT(b < (std::size_t(1) << NumBits));
O tmp = n.priv_offset();
tmp &= O(~Mask);
tmp &= ~Mask;
tmp |= O(b << 1u);
n.priv_offset() = tmp;
}

View File

@@ -479,6 +479,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "segment_manager_test", "seg
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "windows_shared_dir_func", "windows_shared_dir_func.vcproj", "{E5C2683A-48EF-FA47-9164-5BA3C1006380}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
@@ -967,6 +971,10 @@ Global
{56CE18C9-0000-0000-0000-000000000000}.Debug.Build.0 = Debug|Win32
{56CE18C9-0000-0000-0000-000000000000}.Release.ActiveCfg = Release|Win32
{56CE18C9-0000-0000-0000-000000000000}.Release.Build.0 = Release|Win32
{E5C2683A-48EF-FA47-9164-5BA3C1006380}.Debug.ActiveCfg = Debug|Win32
{E5C2683A-48EF-FA47-9164-5BA3C1006380}.Debug.Build.0 = Debug|Win32
{E5C2683A-48EF-FA47-9164-5BA3C1006380}.Release.ActiveCfg = Release|Win32
{E5C2683A-48EF-FA47-9164-5BA3C1006380}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection

View File

@@ -0,0 +1,138 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="windows_shared_dir_func"
ProjectGUID="{E5C2683A-48EF-FA47-9164-5BA3C1006380}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/windows_shared_dir_func"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/windows_shared_memory_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/windows_shared_dir_func.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/windows_shared_dir_func"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/windows_shared_dir_func.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{753CF174-6A5D-F4C6-A760-F25A2D087732}">
<File
RelativePath="..\..\test\windows_shared_dir_func.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{37BBE905-7A5C-B89D-74F6-F39952E625FB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -28,9 +28,9 @@ rule test_all
<toolset>acc:<linkflags>-lrt
<toolset>acc-pa_risc:<linkflags>-lrt
<toolset>gcc,<target-os>windows:<linkflags>"-lole32 -loleaut32 -lpsapi -ladvapi32"
<host-os>hpux,<toolset>gcc:<linkflags>"-Wl,+as,mpas"
<host-os>windows,<toolset>clang:<linkflags>"-lole32 -loleaut32 -lpsapi -ladvapi32"
<host-os>linux:<linkflags>"-lrt"
<target-os>hpux,<toolset>gcc:<linkflags>"-Wl,+as,mpas"
<target-os>windows,<toolset>clang:<linkflags>"-lole32 -loleaut32 -lpsapi -ladvapi32"
<target-os>linux:<linkflags>"-lrt"
] ;
}

View File

@@ -0,0 +1,84 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#ifdef BOOST_INTERPROCESS_WINDOWS
#define BOOST_INTERPROCESS_WINDOWS
//Force user-defined get_shared_dir
#define BOOST_INTERPROCESS_SHARED_DIR_FUNC
#include <boost/interprocess/detail/shared_dir_helpers.hpp>
#include <string>
#include "get_process_id_name.hpp"
namespace boost {
namespace interprocess {
namespace ipcdetail {
static bool dir_created = false;
inline void get_shared_dir(std::string &shared_dir)
{
shared_dir = boost::interprocess::ipcdetail::get_temporary_path();
shared_dir += "/boostipctest_";
shared_dir += boost::interprocess::test::get_process_id_name();
if(!dir_created)
ipcdetail::create_directory(shared_dir.c_str());
dir_created = true;
}
}}} //namespace boost::interprocess::ipcdetail
#include <boost/interprocess/shared_memory_object.hpp>
#include <iostream>
int main ()
{
using namespace boost::interprocess;
const char *const shm_name = "test_shm";
std::string shared_dir;
ipcdetail::get_shared_dir(shared_dir);
std::string shm_path(shared_dir);
shm_path += shm_name;
int ret = 0;
shared_memory_object::remove(shm_name);
{
shared_memory_object shm(create_only, shm_name, read_write);
shm_path += shm_name;
int ret = ipcdetail::invalid_file() == ipcdetail::open_existing_file(shm_path.c_str(), read_only) ?
1 : 0;
if(ret)
{
std::cerr << "Error opening user get_shared_dir()/shm file" << std::endl;
}
}
shared_memory_object::remove(shm_name);
ipcdetail::remove_directory(shared_dir.c_str());
return ret;
}
#else
int main()
{
return 0;
}
#endif //#ifdef BOOST_INTERPROCESS_WINDOWS
#include <boost/interprocess/detail/config_end.hpp>