From 469f38d55310de6462d5ff228f3b0a73dad0e4d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Thu, 12 Jan 2017 15:00:10 +0100 Subject: [PATCH 01/14] Added test case for BOOST_INTERPROCESS_SHARED_DIR_FUNC --- .../interprocess/detail/os_file_functions.hpp | 6 + proj/vc7ide/Interprocess.sln | 8 + proj/vc7ide/windows_shared_dir_func.vcproj | 138 ++++++++++++++++++ test/windows_shared_dir_func.cpp | 84 +++++++++++ 4 files changed, 236 insertions(+) create mode 100644 proj/vc7ide/windows_shared_dir_func.vcproj create mode 100644 test/windows_shared_dir_func.cpp diff --git a/include/boost/interprocess/detail/os_file_functions.hpp b/include/boost/interprocess/detail/os_file_functions.hpp index bcb9576..7a41868 100644 --- a/include/boost/interprocess/detail/os_file_functions.hpp +++ b/include/boost/interprocess/detail/os_file_functions.hpp @@ -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; diff --git a/proj/vc7ide/Interprocess.sln b/proj/vc7ide/Interprocess.sln index be463eb..8c71e00 100644 --- a/proj/vc7ide/Interprocess.sln +++ b/proj/vc7ide/Interprocess.sln @@ -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 diff --git a/proj/vc7ide/windows_shared_dir_func.vcproj b/proj/vc7ide/windows_shared_dir_func.vcproj new file mode 100644 index 0000000..1c0032d --- /dev/null +++ b/proj/vc7ide/windows_shared_dir_func.vcproj @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/windows_shared_dir_func.cpp b/test/windows_shared_dir_func.cpp new file mode 100644 index 0000000..135f246 --- /dev/null +++ b/test/windows_shared_dir_func.cpp @@ -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 +#include + +#ifdef BOOST_INTERPROCESS_WINDOWS + +#define BOOST_INTERPROCESS_WINDOWS + +//Force user-defined get_shared_dir +#define BOOST_INTERPROCESS_SHARED_DIR_FUNC +#include +#include + +#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 +#include + +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 From 46a136479d3b48268a8cd4faab0647f0a4fc9c1b Mon Sep 17 00:00:00 2001 From: Tobias Reh Date: Thu, 5 Jan 2017 14:50:17 +0100 Subject: [PATCH 02/14] Conform to std::pointer_traits requirements offset_ptr::rebind must be offset_ptr directly to avoid breaking older pointer_traits implementations (like in Visual Studio 2015), 'other' is added as typedef so offset_ptr::rebind::other still works --- include/boost/interprocess/offset_ptr.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/boost/interprocess/offset_ptr.hpp b/include/boost/interprocess/offset_ptr.hpp index fca444e..1b57bb4 100644 --- a/include/boost/interprocess/offset_ptr.hpp +++ b/include/boost/interprocess/offset_ptr.hpp @@ -444,9 +444,17 @@ class offset_ptr //!Compatibility with pointer_traits //! + #if defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) template struct rebind { typedef offset_ptr other; }; + #else + template + using rebind = offset_ptr; + #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED + typedef offset_ptr other; + #endif //BOOST_INTERPROCESS_DOXYGEN_INVOKED + #endif //!Compatibility with pointer_traits //! From 892e541c177d5a87bfa8e8765f967cd70e9f545a Mon Sep 17 00:00:00 2001 From: Tobias Reh Date: Wed, 4 Jan 2017 14:38:34 +0100 Subject: [PATCH 03/14] Enable explicit construction of offset_ptr from offset_ptr With 'enable_if' and 'explicit', care is taken to behave just as 'normal' pointers. --- include/boost/interprocess/offset_ptr.hpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/include/boost/interprocess/offset_ptr.hpp b/include/boost/interprocess/offset_ptr.hpp index fca444e..e40be46 100644 --- a/include/boost/interprocess/offset_ptr.hpp +++ b/include/boost/interprocess/offset_ptr.hpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -270,8 +271,8 @@ class offset_ptr (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 BOOST_INTERPROCESS_FORCEINLINE offset_ptr( const offset_ptr &ptr #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED @@ -284,8 +285,6 @@ class offset_ptr #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 BOOST_INTERPROCESS_FORCEINLINE offset_ptr( const offset_ptr &ptr , typename ipcdetail::enable_if_convertible_unequal_address::type* = 0) BOOST_NOEXCEPT @@ -295,6 +294,20 @@ class offset_ptr #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 + BOOST_INTERPROCESS_FORCEINLINE explicit offset_ptr(const offset_ptr &ptr + #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED + , typename ipcdetail::enable_if_c< + !::boost::is_convertible::value && ::boost::is_constructible::value + >::type * = 0 + #endif + ) BOOST_NOEXCEPT + : internal(static_cast + (ipcdetail::offset_ptr_to_offset(static_cast(ptr.get()), this))) + {} + //!Emulates static_cast operator. //!Never throws. template From f78a2e2ffd1ff12d2da520d1a908b728750e3694 Mon Sep 17 00:00:00 2001 From: Tobias Reh Date: Wed, 11 Jan 2017 13:46:52 +0100 Subject: [PATCH 04/14] Restore possibility to communicate between 32 and 64 bit processes using 64 bit offsets If the pointed adress is 128 bytes lower than 'this', we have (a) 32bit uintptr_t, 32bit OffsetType: offset = 0x ffffff80 (b) 64bit uintptr_t, 64bit OffsetType: offset = 0xffffffffffffff80 (c) 32bit uintptr_t, 64bit OffsetType: offset = 0x00000000ffffff80 If we read (c) from an 64bit process, it gets interpreted as 4294967232 bytes forward rather than 128 bytes backward. This commit solves the problem by ajusting the offset representation of (c) to match (b). For the 32bit process itself (c) this makes no difference, as the most significant 4 bytes get truncated anyway when convertig to a pointer. Note: For the default OffsetType=uintptr_t this change is only syntactical. --- .../boost/interprocess/detail/utilities.hpp | 24 ++-- include/boost/interprocess/offset_ptr.hpp | 105 ++++++++---------- 2 files changed, 61 insertions(+), 68 deletions(-) diff --git a/include/boost/interprocess/detail/utilities.hpp b/include/boost/interprocess/detail/utilities.hpp index e1be2f1..c1b2342 100644 --- a/include/boost/interprocess/detail/utilities.hpp +++ b/include/boost/interprocess/detail/utilities.hpp @@ -156,29 +156,29 @@ BOOST_INTERPROCESS_FORCEINLINE bool size_overflows(SizeType count) return multiplication_overflows(SizeType(SztSizeOfType), count); } -template -class pointer_uintptr_caster; +template +class pointer_offset_caster; -template -class pointer_uintptr_caster +template +class pointer_offset_caster { 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(p)) + BOOST_INTERPROCESS_FORCEINLINE explicit pointer_offset_caster(const volatile T *p) + : m_offset(reinterpret_cast(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(m_uintptr); } + { return reinterpret_cast(m_offset); } private: - uintptr_t m_uintptr; + OffsetType m_offset; }; diff --git a/include/boost/interprocess/offset_ptr.hpp b/include/boost/interprocess/offset_ptr.hpp index e40be46..8ee8d5a 100644 --- a/include/boost/interprocess/offset_ptr.hpp +++ b/include/boost/interprocess/offset_ptr.hpp @@ -24,6 +24,8 @@ #include #include +#include +#include #include #include @@ -56,6 +58,7 @@ namespace ipcdetail { union offset_ptr_internal { BOOST_STATIC_ASSERT(sizeof(OffsetType) >= sizeof(uintptr_t)); + BOOST_STATIC_ASSERT(boost::is_integral::value && boost::is_unsigned::value); explicit offset_ptr_internal(OffsetType off) : m_offset(off) @@ -82,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 + BOOST_INTERPROCESS_FORCEINLINE void * offset_ptr_to_raw_pointer(const volatile void *this_ptr, OffsetType offset) { - typedef pointer_uintptr_caster caster_t; + typedef pointer_offset_caster 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 @@ -107,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 + BOOST_INTERPROCESS_FORCEINLINE OffsetType offset_ptr_to_offset(const volatile void *ptr, const volatile void *this_ptr) { - typedef pointer_uintptr_caster caster_t; + typedef pointer_offset_caster 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; @@ -140,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 + 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 caster_t; + typedef pointer_offset_caster 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 @@ -216,9 +222,9 @@ namespace ipcdetail { //! //!Note: 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 offset_ptr { @@ -252,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(ipcdetail::offset_ptr_to_offset(ptr, this))) + : internal(ipcdetail::offset_ptr_to_offset(ptr, this)) {} //!Constructor from other pointer. @@ -260,15 +266,13 @@ class offset_ptr template BOOST_INTERPROCESS_FORCEINLINE offset_ptr( T *ptr , typename ipcdetail::enable_if< ::boost::is_convertible >::type * = 0) BOOST_NOEXCEPT - : internal(static_cast - (ipcdetail::offset_ptr_to_offset(static_cast(ptr), this))) + : internal(ipcdetail::offset_ptr_to_offset(static_cast(ptr), this)) {} //!Constructor from other offset_ptr //!Never throws. BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr& ptr) BOOST_NOEXCEPT - : internal(static_cast - (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. Only takes part in overload resolution @@ -279,8 +283,7 @@ class offset_ptr , typename ipcdetail::enable_if_convertible_equal_address::type* = 0 #endif ) BOOST_NOEXCEPT - : internal(static_cast - (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 @@ -288,8 +291,7 @@ class offset_ptr template BOOST_INTERPROCESS_FORCEINLINE offset_ptr( const offset_ptr &ptr , typename ipcdetail::enable_if_convertible_unequal_address::type* = 0) BOOST_NOEXCEPT - : internal(static_cast - (ipcdetail::offset_ptr_to_offset(static_cast(ptr.get()), this))) + : internal(ipcdetail::offset_ptr_to_offset(static_cast(ptr.get()), this)) {} #endif @@ -304,46 +306,41 @@ class offset_ptr >::type * = 0 #endif ) BOOST_NOEXCEPT - : internal(static_cast - (ipcdetail::offset_ptr_to_offset(static_cast(ptr.get()), this))) + : internal(ipcdetail::offset_ptr_to_offset(static_cast(ptr.get()), this)) {} //!Emulates static_cast operator. //!Never throws. template BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr & r, ipcdetail::static_cast_tag) BOOST_NOEXCEPT - : internal(static_cast - (ipcdetail::offset_ptr_to_offset(static_cast(r.get()), this))) + : internal(ipcdetail::offset_ptr_to_offset(static_cast(r.get()), this)) {} //!Emulates const_cast operator. //!Never throws. template BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr & r, ipcdetail::const_cast_tag) BOOST_NOEXCEPT - : internal(static_cast - (ipcdetail::offset_ptr_to_offset(const_cast(r.get()), this))) + : internal(ipcdetail::offset_ptr_to_offset(const_cast(r.get()), this)) {} //!Emulates dynamic_cast operator. //!Never throws. template BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr & r, ipcdetail::dynamic_cast_tag) BOOST_NOEXCEPT - : internal(static_cast - (ipcdetail::offset_ptr_to_offset(dynamic_cast(r.get()), this))) + : internal(ipcdetail::offset_ptr_to_offset(dynamic_cast(r.get()), this)) {} //!Emulates reinterpret_cast operator. //!Never throws. template BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr & r, ipcdetail::reinterpret_cast_tag) BOOST_NOEXCEPT - : internal(static_cast - (ipcdetail::offset_ptr_to_offset(reinterpret_cast(r.get()), this))) + : internal(ipcdetail::offset_ptr_to_offset(reinterpret_cast(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(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; } @@ -371,8 +368,7 @@ class offset_ptr //!Never throws. BOOST_INTERPROCESS_FORCEINLINE offset_ptr& operator= (pointer from) BOOST_NOEXCEPT { - this->internal.m_offset = - static_cast(ipcdetail::offset_ptr_to_offset(from, this)); + this->internal.m_offset = ipcdetail::offset_ptr_to_offset(from, this); return *this; } @@ -380,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(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; } @@ -559,15 +554,13 @@ class offset_ptr template BOOST_INTERPROCESS_FORCEINLINE void assign(const offset_ptr &ptr, ipcdetail::bool_) BOOST_NOEXCEPT { //no need to pointer adjustment - this->internal.m_offset = - static_cast(ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.get_offset())); + this->internal.m_offset = ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.get_offset()); } template BOOST_INTERPROCESS_FORCEINLINE void assign(const offset_ptr &ptr, ipcdetail::bool_) BOOST_NOEXCEPT { //we must convert to raw before calculating the offset - this->internal.m_offset = - static_cast(ipcdetail::offset_ptr_to_offset(static_cast(ptr.get()), this)); + this->internal.m_offset = ipcdetail::offset_ptr_to_offset(static_cast(ptr.get()), this); } #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) @@ -705,7 +698,7 @@ struct pointer_plus_bits, NumBits> typedef boost::interprocess::offset_ptr 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(1) << NumBits) - static_cast(1)) << 1; BOOST_STATIC_ASSERT(0 ==(Mask&1)); //We must ALWAYS take argument "n" by reference as a copy of a null pointer @@ -714,7 +707,7 @@ struct pointer_plus_bits, 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; } @@ -722,7 +715,7 @@ struct pointer_plus_bits, 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; } @@ -736,7 +729,7 @@ struct pointer_plus_bits, 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; } From b3dd777e5ce41d40bbcc3920323ff4d85fc68c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Fri, 20 Jan 2017 00:49:48 +0100 Subject: [PATCH 05/14] Fixes ticket #12744 ("winapi::set_timer_resolution inadvertently changes timer resolution (Windows)") --- .../interprocess/detail/os_thread_functions.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/boost/interprocess/detail/os_thread_functions.hpp b/include/boost/interprocess/detail/os_thread_functions.hpp index 3ff0a40..291f426 100644 --- a/include/boost/interprocess/detail/os_thread_functions.hpp +++ b/include/boost/interprocess/detail/os_thread_functions.hpp @@ -112,8 +112,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 +121,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 +132,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 From 0cd4548b45a9b9fdac2c58f2acb793095754f821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Fri, 20 Jan 2017 00:50:02 +0100 Subject: [PATCH 06/14] Update changelog for 1.64 --- doc/interprocess.qbk | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/interprocess.qbk b/doc/interprocess.qbk index 8da5f63..849c033 100644 --- a/doc/interprocess.qbk +++ b/doc/interprocess.qbk @@ -6754,6 +6754,14 @@ 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/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"])]. + +[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"])]. From e9251cd22a3371299dea33bb0a8a9ba0d73e0c06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 6 Feb 2017 14:11:45 +0100 Subject: [PATCH 07/14] Check MacOs first, as macOS 10.12 SDK defines both CLOCK_MONOTONIC and CLOCK_MONOTONIC_RAW and no clock_gettime --- .../boost/interprocess/detail/os_thread_functions.hpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/boost/interprocess/detail/os_thread_functions.hpp b/include/boost/interprocess/detail/os_thread_functions.hpp index 291f426..8a0a47c 100644 --- a/include/boost/interprocess/detail/os_thread_functions.hpp +++ b/include/boost/interprocess/detail/os_thread_functions.hpp @@ -53,7 +53,12 @@ # include # 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_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_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 From 936afb13f0c106728bcf36c1ce128f09abb0b6fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 6 Feb 2017 14:17:32 +0100 Subject: [PATCH 08/14] Update changelog with Trac #12617 --- doc/interprocess.qbk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/interprocess.qbk b/doc/interprocess.qbk index 849c033..a1685b3 100644 --- a/doc/interprocess.qbk +++ b/doc/interprocess.qbk @@ -6756,12 +6756,15 @@ thank them: [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"])]. [endsect] +[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"])]. From 91cfe4bcd26a9f3c392f0731b2c0f8b3310f93e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Tue, 7 Feb 2017 09:21:45 +0100 Subject: [PATCH 09/14] Fix documentation build error: extra [endsect]. --- doc/interprocess.qbk | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/interprocess.qbk b/doc/interprocess.qbk index a1685b3..6b73264 100644 --- a/doc/interprocess.qbk +++ b/doc/interprocess.qbk @@ -6763,8 +6763,6 @@ thank them: [endsect] -[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"])]. From 6963d26e67569064b043ac8758226d9ffd825642 Mon Sep 17 00:00:00 2001 From: David Strauss Date: Wed, 8 Feb 2017 16:29:25 -0800 Subject: [PATCH 10/14] Update example to use multi_index::member instead of BOOST_MULTI_INDEX_MEMBER --- example/doc_multi_index.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/example/doc_multi_index.cpp b/example/doc_multi_index.cpp index e1ef258..df4fd72 100644 --- a/example/doc_multi_index.cpp +++ b/example/doc_multi_index.cpp @@ -61,11 +61,11 @@ typedef bmi::multi_index_container< employee, bmi::indexed_by< bmi::ordered_unique - , BOOST_MULTI_INDEX_MEMBER(employee,int,id)>, + , bmi::member >, bmi::ordered_non_unique< - bmi::tag,BOOST_MULTI_INDEX_MEMBER(employee,shm_string,name)>, + bmi::tag, bmi::member >, bmi::ordered_non_unique - , BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >, + , bmi::member > >, managed_shared_memory::allocator::type > employee_set; From 0bf3e3fc037021c9a345d23ef286adc2d47d408b Mon Sep 17 00:00:00 2001 From: Niklas Angare Date: Sun, 12 Feb 2017 13:04:09 +0100 Subject: [PATCH 11/14] Fixed options for cross-compilation. Replaced with so that the correct options for the target are selected when cross-compiling. When not cross-compiling, it makes no difference as target-os by default mirrors host-os. --- example/Jamfile.v2 | 12 ++++++------ test/Jamfile.v2 | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 index ac4f4ab..22da3e0 100644 --- a/example/Jamfile.v2 +++ b/example/Jamfile.v2 @@ -26,9 +26,9 @@ rule test_all acc:-lrt acc-pa_risc:-lrt gcc,windows:"-lole32 -loleaut32 -lpsapi -ladvapi32" - hpux,gcc:"-Wl,+as,mpas" - windows,clang:"-lole32 -loleaut32 -lpsapi -ladvapi32" - linux:"-lrt" + hpux,gcc:"-Wl,+as,mpas" + windows,clang:"-lole32 -loleaut32 -lpsapi -ladvapi32" + linux:"-lrt" : # test-files : # requirements ] ; @@ -43,9 +43,9 @@ rule test_all acc:-lrt acc-pa_risc:-lrt gcc-mingw:"-lole32 -loleaut32 -lpsapi -ladvapi32" - hpux,gcc:"-Wl,+as,mpas" - windows,clang:"-lole32 -loleaut32 -lpsapi -ladvapi32" - linux:"-lrt" + hpux,gcc:"-Wl,+as,mpas" + windows,clang:"-lole32 -loleaut32 -lpsapi -ladvapi32" + linux:"-lrt" ] ; } diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 58b81dd..a09bf8f 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -28,9 +28,9 @@ rule test_all acc:-lrt acc-pa_risc:-lrt gcc,windows:"-lole32 -loleaut32 -lpsapi -ladvapi32" - hpux,gcc:"-Wl,+as,mpas" - windows,clang:"-lole32 -loleaut32 -lpsapi -ladvapi32" - linux:"-lrt" + hpux,gcc:"-Wl,+as,mpas" + windows,clang:"-lole32 -loleaut32 -lpsapi -ladvapi32" + linux:"-lrt" ] ; } From eedc9b0a4efd428104c5c9ebb61c83704166448e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 12 Feb 2017 21:33:16 +0100 Subject: [PATCH 12/14] New experimental option `BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED` for windows systems. --- doc/interprocess.qbk | 4 + .../boost/interprocess/detail/win32_api.hpp | 205 ++++++++++++++---- 2 files changed, 171 insertions(+), 38 deletions(-) diff --git a/doc/interprocess.qbk b/doc/interprocess.qbk index 6b73264..c161998 100644 --- a/doc/interprocess.qbk +++ b/doc/interprocess.qbk @@ -6761,6 +6761,10 @@ thank them: * [@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"])]. +* 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] diff --git a/include/boost/interprocess/detail/win32_api.hpp b/include/boost/interprocess/detail/win32_api.hpp index 02c7b42..1ea8cec 100644 --- a/include/boost/interprocess/detail/win32_api.hpp +++ b/include/boost/interprocess/detail/win32_api.hpp @@ -31,9 +31,45 @@ #include #include +//#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 - # if defined(BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME) # include # include @@ -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(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(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) { From 3881f04e4689e844e977f1d978efe1eab926bda0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 12 Feb 2017 21:56:11 +0100 Subject: [PATCH 13/14] Added GitHub Pull #35 ("Fixed options for cross-compilation") to changelog. --- doc/interprocess.qbk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/interprocess.qbk b/doc/interprocess.qbk index c161998..80ecf69 100644 --- a/doc/interprocess.qbk +++ b/doc/interprocess.qbk @@ -6760,6 +6760,7 @@ thank them: * [@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/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 @@ -6783,7 +6784,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] From 4178baf8341ca76df1d5b4e17c6c10701165f202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 13 Feb 2017 00:19:05 +0100 Subject: [PATCH 14/14] Update changelog with pull request #34 --- doc/interprocess.qbk | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/interprocess.qbk b/doc/interprocess.qbk index 80ecf69..0139b61 100644 --- a/doc/interprocess.qbk +++ b/doc/interprocess.qbk @@ -6760,6 +6760,7 @@ thank them: * [@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.