mirror of
https://github.com/boostorg/interprocess.git
synced 2026-01-19 04:12:13 +00:00
Merge branch 'develop'
This commit is contained in:
@@ -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]
|
||||
|
||||
|
||||
@@ -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"
|
||||
] ;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
138
proj/vc7ide/windows_shared_dir_func.vcproj
Normal file
138
proj/vc7ide/windows_shared_dir_func.vcproj
Normal 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>
|
||||
@@ -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"
|
||||
] ;
|
||||
}
|
||||
|
||||
|
||||
84
test/windows_shared_dir_func.cpp
Normal file
84
test/windows_shared_dir_func.cpp
Normal 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>
|
||||
Reference in New Issue
Block a user