summaryrefslogtreecommitdiff
path: root/boost/interprocess
diff options
context:
space:
mode:
Diffstat (limited to 'boost/interprocess')
-rw-r--r--boost/interprocess/allocators/adaptive_pool.hpp56
-rw-r--r--boost/interprocess/allocators/allocator.hpp22
-rw-r--r--boost/interprocess/allocators/cached_adaptive_pool.hpp32
-rw-r--r--boost/interprocess/allocators/cached_node_allocator.hpp28
-rw-r--r--boost/interprocess/allocators/detail/adaptive_node_pool.hpp4
-rw-r--r--boost/interprocess/allocators/detail/allocator_common.hpp54
-rw-r--r--boost/interprocess/allocators/detail/node_pool.hpp8
-rw-r--r--boost/interprocess/allocators/node_allocator.hpp56
-rw-r--r--boost/interprocess/allocators/private_adaptive_pool.hpp38
-rw-r--r--boost/interprocess/allocators/private_node_allocator.hpp40
-rw-r--r--boost/interprocess/anonymous_shared_memory.hpp12
-rw-r--r--boost/interprocess/detail/atomic.hpp355
-rw-r--r--boost/interprocess/detail/config_begin.hpp1
-rw-r--r--boost/interprocess/detail/file_locking_helpers.hpp298
-rw-r--r--boost/interprocess/detail/file_wrapper.hpp22
-rw-r--r--boost/interprocess/detail/in_place_interface.hpp2
-rw-r--r--boost/interprocess/detail/intermodule_singleton.hpp1148
-rw-r--r--boost/interprocess/detail/intermodule_singleton_common.hpp495
-rw-r--r--boost/interprocess/detail/intersegment_ptr.hpp120
-rw-r--r--boost/interprocess/detail/managed_global_memory.hpp115
-rw-r--r--boost/interprocess/detail/managed_memory_impl.hpp166
-rw-r--r--boost/interprocess/detail/managed_multi_shared_memory.hpp52
-rw-r--r--boost/interprocess/detail/managed_open_or_create_impl.hpp39
-rw-r--r--boost/interprocess/detail/math_functions.hpp4
-rw-r--r--boost/interprocess/detail/min_max.hpp4
-rw-r--r--boost/interprocess/detail/mpl.hpp20
-rw-r--r--boost/interprocess/detail/multi_segment_services.hpp2
-rw-r--r--boost/interprocess/detail/named_proxy.hpp24
-rw-r--r--boost/interprocess/detail/os_file_functions.hpp66
-rw-r--r--boost/interprocess/detail/os_thread_functions.hpp4
-rw-r--r--boost/interprocess/detail/pointer_type.hpp4
-rw-r--r--boost/interprocess/detail/portable_intermodule_singleton.hpp356
-rw-r--r--boost/interprocess/detail/posix_time_types_wrk.hpp2
-rw-r--r--boost/interprocess/detail/preprocessor.hpp32
-rw-r--r--boost/interprocess/detail/ptime_wrk.hpp2
-rw-r--r--boost/interprocess/detail/robust_emulation.hpp10
-rw-r--r--boost/interprocess/detail/segment_manager_helper.hpp48
-rw-r--r--boost/interprocess/detail/tmp_dir_helpers.hpp163
-rw-r--r--boost/interprocess/detail/transform_iterator.hpp8
-rw-r--r--boost/interprocess/detail/type_traits.hpp4
-rw-r--r--boost/interprocess/detail/utilities.hpp8
-rw-r--r--boost/interprocess/detail/variadic_templates_tools.hpp4
-rw-r--r--boost/interprocess/detail/win32_api.hpp766
-rw-r--r--boost/interprocess/detail/windows_intermodule_singleton.hpp306
-rw-r--r--boost/interprocess/detail/workaround.hpp133
-rw-r--r--boost/interprocess/detail/xsi_shared_memory_device.hpp10
-rw-r--r--boost/interprocess/detail/xsi_shared_memory_file_wrapper.hpp6
-rw-r--r--boost/interprocess/errors.hpp16
-rw-r--r--boost/interprocess/file_mapping.hpp20
-rw-r--r--boost/interprocess/indexes/iset_index.hpp22
-rw-r--r--boost/interprocess/indexes/iunordered_set_index.hpp28
-rw-r--r--boost/interprocess/indexes/map_index.hpp2
-rw-r--r--boost/interprocess/indexes/null_index.hpp2
-rw-r--r--boost/interprocess/indexes/unordered_map_index.hpp2
-rw-r--r--boost/interprocess/interprocess_fwd.hpp6
-rw-r--r--boost/interprocess/ipc/message_queue.hpp152
-rw-r--r--boost/interprocess/managed_external_buffer.hpp18
-rw-r--r--boost/interprocess/managed_heap_memory.hpp26
-rw-r--r--boost/interprocess/managed_mapped_file.hpp46
-rw-r--r--boost/interprocess/managed_shared_memory.hpp50
-rw-r--r--boost/interprocess/managed_windows_shared_memory.hpp32
-rw-r--r--boost/interprocess/managed_xsi_shared_memory.hpp36
-rw-r--r--boost/interprocess/mapped_region.hpp458
-rw-r--r--boost/interprocess/mem_algo/detail/mem_algo_common.hpp30
-rw-r--r--boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp68
-rw-r--r--boost/interprocess/mem_algo/rbtree_best_fit.hpp98
-rw-r--r--boost/interprocess/mem_algo/simple_seq_fit.hpp4
-rw-r--r--boost/interprocess/offset_ptr.hpp70
-rw-r--r--boost/interprocess/segment_manager.hpp138
-rw-r--r--boost/interprocess/shared_memory_object.hpp26
-rw-r--r--boost/interprocess/smart_ptr/deleter.hpp6
-rw-r--r--boost/interprocess/smart_ptr/detail/shared_count.hpp6
-rw-r--r--boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp6
-rw-r--r--boost/interprocess/smart_ptr/intrusive_ptr.hpp24
-rw-r--r--boost/interprocess/smart_ptr/scoped_ptr.hpp12
-rw-r--r--boost/interprocess/smart_ptr/shared_ptr.hpp63
-rw-r--r--boost/interprocess/smart_ptr/unique_ptr.hpp10
-rw-r--r--boost/interprocess/smart_ptr/weak_ptr.hpp16
-rw-r--r--boost/interprocess/streams/bufferstream.hpp38
-rw-r--r--boost/interprocess/streams/vectorstream.hpp50
-rw-r--r--boost/interprocess/sync/detail/condition_algorithm_8a.hpp316
-rw-r--r--boost/interprocess/sync/file_lock.hpp32
-rw-r--r--boost/interprocess/sync/interprocess_condition.hpp22
-rw-r--r--boost/interprocess/sync/interprocess_mutex.hpp12
-rw-r--r--boost/interprocess/sync/interprocess_recursive_mutex.hpp12
-rw-r--r--boost/interprocess/sync/interprocess_semaphore.hpp14
-rw-r--r--boost/interprocess/sync/interprocess_upgradable_mutex.hpp100
-rw-r--r--boost/interprocess/sync/mutex_family.hpp4
-rw-r--r--boost/interprocess/sync/named_condition.hpp34
-rw-r--r--boost/interprocess/sync/named_mutex.hpp33
-rw-r--r--boost/interprocess/sync/named_recursive_mutex.hpp20
-rw-r--r--boost/interprocess/sync/named_semaphore.hpp21
-rw-r--r--boost/interprocess/sync/named_upgradable_mutex.hpp64
-rw-r--r--boost/interprocess/sync/posix/condition.hpp18
-rw-r--r--boost/interprocess/sync/posix/mutex.hpp6
-rw-r--r--boost/interprocess/sync/posix/pthread_helpers.hpp22
-rw-r--r--boost/interprocess/sync/posix/recursive_mutex.hpp4
-rw-r--r--boost/interprocess/sync/posix/semaphore_wrapper.hpp8
-rw-r--r--boost/interprocess/sync/scoped_lock.hpp38
-rw-r--r--boost/interprocess/sync/sharable_lock.hpp20
-rw-r--r--boost/interprocess/sync/shm/named_condition.hpp47
-rw-r--r--boost/interprocess/sync/shm/named_creation_functor.hpp2
-rw-r--r--boost/interprocess/sync/shm/named_mutex.hpp6
-rw-r--r--boost/interprocess/sync/shm/named_recursive_mutex.hpp4
-rw-r--r--boost/interprocess/sync/shm/named_upgradable_mutex.hpp64
-rw-r--r--boost/interprocess/sync/spin/condition.hpp32
-rw-r--r--boost/interprocess/sync/spin/mutex.hpp8
-rw-r--r--boost/interprocess/sync/spin/recursive_mutex.hpp8
-rw-r--r--boost/interprocess/sync/upgradable_lock.hpp20
-rw-r--r--boost/interprocess/sync/windows/condition.hpp315
-rw-r--r--boost/interprocess/sync/windows/mutex.hpp63
-rw-r--r--boost/interprocess/sync/windows/named_condition.hpp334
-rw-r--r--boost/interprocess/sync/windows/named_mutex.hpp175
-rw-r--r--boost/interprocess/sync/windows/named_recursive_mutex.hpp58
-rw-r--r--boost/interprocess/sync/windows/named_semaphore.hpp178
-rw-r--r--boost/interprocess/sync/windows/named_sync.hpp215
-rw-r--r--boost/interprocess/sync/windows/semaphore.hpp63
-rw-r--r--boost/interprocess/sync/windows/sync_utils.hpp117
-rw-r--r--boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp163
-rw-r--r--boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp198
-rw-r--r--boost/interprocess/sync/xsi/xsi_named_mutex.hpp16
-rw-r--r--boost/interprocess/windows_shared_memory.hpp45
-rw-r--r--boost/interprocess/xsi_shared_memory.hpp14
123 files changed, 5839 insertions, 3836 deletions
diff --git a/boost/interprocess/allocators/adaptive_pool.hpp b/boost/interprocess/allocators/adaptive_pool.hpp
index 846df5d413..a85202b4ee 100644
--- a/boost/interprocess/allocators/adaptive_pool.hpp
+++ b/boost/interprocess/allocators/adaptive_pool.hpp
@@ -35,7 +35,7 @@
#include <cstddef>
//!\file
-//!Describes adaptive_pool pooled shared memory STL compatible allocator
+//!Describes adaptive_pool pooled shared memory STL compatible allocator
namespace boost {
namespace interprocess {
@@ -101,11 +101,11 @@ class adaptive_pool_base
typedef boost::container::container_detail::transform_multiallocation_chain
<typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
- //!Obtains adaptive_pool_base from
+ //!Obtains adaptive_pool_base from
//!adaptive_pool_base
template<class T2>
struct rebind
- {
+ {
typedef adaptive_pool_base<Version, T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
};
@@ -122,15 +122,15 @@ class adaptive_pool_base
//!Constructor from a segment manager. If not present, constructs a node
//!pool. Increments the reference count of the associated node pool.
//!Can throw boost::interprocess::bad_alloc
- adaptive_pool_base(segment_manager *segment_mngr)
+ adaptive_pool_base(segment_manager *segment_mngr)
: mp_node_pool(ipcdetail::get_or_create_node_pool<typename node_pool<0>::type>(segment_mngr)) { }
- //!Copy constructor from other adaptive_pool_base. Increments the reference
+ //!Copy constructor from other adaptive_pool_base. Increments the reference
//!count of the associated node pool. Never throws
- adaptive_pool_base(const adaptive_pool_base &other)
- : mp_node_pool(other.get_node_pool())
- {
- node_pool<0>::get(ipcdetail::to_raw_pointer(mp_node_pool))->inc_ref_count();
+ adaptive_pool_base(const adaptive_pool_base &other)
+ : mp_node_pool(other.get_node_pool())
+ {
+ node_pool<0>::get(ipcdetail::to_raw_pointer(mp_node_pool))->inc_ref_count();
}
//!Assignment from other adaptive_pool_base
@@ -151,7 +151,7 @@ class adaptive_pool_base
//!Destructor, removes node_pool_t from memory
//!if its reference count reaches to zero. Never throws
- ~adaptive_pool_base()
+ ~adaptive_pool_base()
{ ipcdetail::destroy_node_pool_if_last_link(node_pool<0>::get(ipcdetail::to_raw_pointer(mp_node_pool))); }
//!Returns a pointer to the node pool.
@@ -178,14 +178,14 @@ class adaptive_pool_base
//!Equality test for same type
//!of adaptive_pool_base
template<unsigned int V, class T, class S, std::size_t NPC, std::size_t F, unsigned char OP> inline
-bool operator==(const adaptive_pool_base<V, T, S, NPC, F, OP> &alloc1,
+bool operator==(const adaptive_pool_base<V, T, S, NPC, F, OP> &alloc1,
const adaptive_pool_base<V, T, S, NPC, F, OP> &alloc2)
{ return alloc1.get_node_pool() == alloc2.get_node_pool(); }
//!Inequality test for same type
//!of adaptive_pool_base
template<unsigned int V, class T, class S, std::size_t NPC, std::size_t F, unsigned char OP> inline
-bool operator!=(const adaptive_pool_base<V, T, S, NPC, F, OP> &alloc1,
+bool operator!=(const adaptive_pool_base<V, T, S, NPC, F, OP> &alloc1,
const adaptive_pool_base<V, T, S, NPC, F, OP> &alloc2)
{ return alloc1.get_node_pool() != alloc2.get_node_pool(); }
@@ -211,11 +211,11 @@ class adaptive_pool_v1
template<class T2>
struct rebind
- {
+ {
typedef adaptive_pool_v1<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
};
- adaptive_pool_v1(SegmentManager *segment_mngr)
+ adaptive_pool_v1(SegmentManager *segment_mngr)
: base_t(segment_mngr)
{}
@@ -230,13 +230,13 @@ class adaptive_pool_v1
/// @endcond
-//!An STL node allocator that uses a segment manager as memory
+//!An STL node allocator that uses a segment manager as memory
//!source. The internal pointer type will of the same type (raw, smart) as
//!"typename SegmentManager::void_pointer" type. This allows
//!placing the allocator in shared memory, memory mapped-files, etc...
//!
-//!This node allocator shares a segregated storage between all instances
-//!of adaptive_pool with equal sizeof(T) placed in the same segment
+//!This node allocator shares a segregated storage between all instances
+//!of adaptive_pool with equal sizeof(T) placed in the same segment
//!group. NodesPerBlock is the number of nodes allocated at once when the allocator
//!needs runs out of nodes. MaxFreeBlocks is the maximum number of totally free blocks
//!that the adaptive node pool will hold. The rest of the totally free blocks will be
@@ -271,11 +271,11 @@ class adaptive_pool
template<class T2>
struct rebind
- {
+ {
typedef adaptive_pool<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
};
- adaptive_pool(SegmentManager *segment_mngr)
+ adaptive_pool(SegmentManager *segment_mngr)
: base_t(segment_mngr)
{}
@@ -299,11 +299,11 @@ class adaptive_pool
typedef typename segment_manager::size_type size_type;
typedef typename segment_manager::difference_type difference_type;
- //!Obtains adaptive_pool from
+ //!Obtains adaptive_pool from
//!adaptive_pool
template<class T2>
struct rebind
- {
+ {
typedef adaptive_pool<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
};
@@ -314,7 +314,7 @@ class adaptive_pool
adaptive_pool& operator=
(const adaptive_pool<T2, SegmentManager2, N2, F2, OP2>&);
- //!Not assignable from
+ //!Not assignable from
//!other adaptive_pool
//adaptive_pool& operator=(const adaptive_pool&);
@@ -324,7 +324,7 @@ class adaptive_pool
//!Can throw boost::interprocess::bad_alloc
adaptive_pool(segment_manager *segment_mngr);
- //!Copy constructor from other adaptive_pool. Increments the reference
+ //!Copy constructor from other adaptive_pool. Increments the reference
//!count of the associated node pool. Never throws
adaptive_pool(const adaptive_pool &other);
@@ -351,7 +351,7 @@ class adaptive_pool
//!Never throws
size_type max_size() const;
- //!Allocate memory for an array of count elements.
+ //!Allocate memory for an array of count elements.
//!Throws boost::interprocess::bad_alloc if there is no enough memory
pointer allocate(size_type count, cvoid_pointer hint = 0);
@@ -375,7 +375,7 @@ class adaptive_pool
//!Never throws
const_pointer address(const_reference value) const;
/*
- //!Copy construct an object.
+ //!Copy construct an object.
//!Throws if T's copy constructor throws
void construct(const pointer &ptr, const_reference v);
@@ -390,7 +390,7 @@ class adaptive_pool
std::pair<pointer, bool>
allocation_command(boost::interprocess::allocation_type command,
- size_type limit_size,
+ size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0);
@@ -448,13 +448,13 @@ class adaptive_pool
//!Equality test for same type
//!of adaptive_pool
template<class T, class S, std::size_t NodesPerBlock, std::size_t F, unsigned char OP> inline
-bool operator==(const adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1,
+bool operator==(const adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1,
const adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc2);
//!Inequality test for same type
//!of adaptive_pool
template<class T, class S, std::size_t NodesPerBlock, std::size_t F, unsigned char OP> inline
-bool operator!=(const adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1,
+bool operator!=(const adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1,
const adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc2);
#endif
diff --git a/boost/interprocess/allocators/allocator.hpp b/boost/interprocess/allocators/allocator.hpp
index aa4b22dcc9..38e8c6901a 100644
--- a/boost/interprocess/allocators/allocator.hpp
+++ b/boost/interprocess/allocators/allocator.hpp
@@ -45,12 +45,12 @@ namespace boost {
namespace interprocess {
-//!An STL compatible allocator that uses a segment manager as
+//!An STL compatible allocator that uses a segment manager as
//!memory source. The internal pointer type will of the same type (raw, smart) as
//!"typename SegmentManager::void_pointer" type. This allows
//!placing the allocator in shared memory, memory mapped-files, etc...
template<class T, class SegmentManager>
-class allocator
+class allocator
{
public:
//Segment manager
@@ -115,7 +115,7 @@ class allocator
//!objects of type T2
template<class T2>
struct rebind
- {
+ {
typedef allocator<T2, SegmentManager> other;
};
@@ -126,21 +126,21 @@ class allocator
//!Constructor from the segment manager.
//!Never throws
- allocator(segment_manager *segment_mngr)
+ allocator(segment_manager *segment_mngr)
: mp_mngr(segment_mngr) { }
//!Constructor from other allocator.
//!Never throws
- allocator(const allocator &other)
+ allocator(const allocator &other)
: mp_mngr(other.get_segment_manager()){ }
//!Constructor from related allocator.
//!Never throws
template<class T2>
- allocator(const allocator<T2, SegmentManager> &other)
+ allocator(const allocator<T2, SegmentManager> &other)
: mp_mngr(other.get_segment_manager()){}
- //!Allocates memory for an array of count elements.
+ //!Allocates memory for an array of count elements.
//!Throws boost::interprocess::bad_alloc if there is no enough memory
pointer allocate(size_type count, cvoid_ptr hint = 0)
{
@@ -169,13 +169,13 @@ class allocator
//!pointed by p can hold. This size only works for memory allocated with
//!allocate, allocation_command and allocate_many.
size_type size(const pointer &p) const
- {
+ {
return (size_type)mp_mngr->size(ipcdetail::to_raw_pointer(p))/sizeof(T);
}
std::pair<pointer, bool>
allocation_command(boost::interprocess::allocation_type command,
- size_type limit_size,
+ size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0)
{
@@ -273,14 +273,14 @@ class allocator
//!Equality test for same type
//!of allocator
template<class T, class SegmentManager> inline
-bool operator==(const allocator<T , SegmentManager> &alloc1,
+bool operator==(const allocator<T , SegmentManager> &alloc1,
const allocator<T, SegmentManager> &alloc2)
{ return alloc1.get_segment_manager() == alloc2.get_segment_manager(); }
//!Inequality test for same type
//!of allocator
template<class T, class SegmentManager> inline
-bool operator!=(const allocator<T, SegmentManager> &alloc1,
+bool operator!=(const allocator<T, SegmentManager> &alloc1,
const allocator<T, SegmentManager> &alloc2)
{ return alloc1.get_segment_manager() != alloc2.get_segment_manager(); }
diff --git a/boost/interprocess/allocators/cached_adaptive_pool.hpp b/boost/interprocess/allocators/cached_adaptive_pool.hpp
index bec1050de5..98af033fe6 100644
--- a/boost/interprocess/allocators/cached_adaptive_pool.hpp
+++ b/boost/interprocess/allocators/cached_adaptive_pool.hpp
@@ -28,7 +28,7 @@
#include <cstddef>
//!\file
-//!Describes cached_adaptive_pool pooled shared memory STL compatible allocator
+//!Describes cached_adaptive_pool pooled shared memory STL compatible allocator
namespace boost {
namespace interprocess {
@@ -69,7 +69,7 @@ class cached_adaptive_pool_v1
template<class T2>
struct rebind
- {
+ {
typedef cached_adaptive_pool_v1
<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
};
@@ -77,7 +77,7 @@ class cached_adaptive_pool_v1
typedef typename base_t::size_type size_type;
cached_adaptive_pool_v1(SegmentManager *segment_mngr,
- size_type max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
+ size_type max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
: base_t(segment_mngr, max_cached_nodes)
{}
@@ -93,12 +93,12 @@ class cached_adaptive_pool_v1
/// @endcond
-//!An STL node allocator that uses a segment manager as memory
+//!An STL node allocator that uses a segment manager as memory
//!source. The internal pointer type will of the same type (raw, smart) as
//!"typename SegmentManager::void_pointer" type. This allows
//!placing the allocator in shared memory, memory mapped-files, etc...
//!
-//!This node allocator shares a segregated storage between all instances of
+//!This node allocator shares a segregated storage between all instances of
//!cached_adaptive_pool with equal sizeof(T) placed in the same
//!memory segment. But also caches some nodes privately to
//!avoid some synchronization overhead.
@@ -149,13 +149,13 @@ class cached_adaptive_pool
template<class T2>
struct rebind
- {
+ {
typedef cached_adaptive_pool
<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
};
cached_adaptive_pool(SegmentManager *segment_mngr,
- std::size_t max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
+ std::size_t max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
: base_t(segment_mngr, max_cached_nodes)
{}
@@ -179,11 +179,11 @@ class cached_adaptive_pool
typedef typename segment_manager::size_type size_type;
typedef typename segment_manager::difference_type difference_type;
- //!Obtains cached_adaptive_pool from
+ //!Obtains cached_adaptive_pool from
//!cached_adaptive_pool
template<class T2>
struct rebind
- {
+ {
typedef cached_adaptive_pool<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
};
@@ -194,7 +194,7 @@ class cached_adaptive_pool
cached_adaptive_pool& operator=
(const cached_adaptive_pool<T2, SegmentManager2, N2, F2, OP2>&);
- //!Not assignable from
+ //!Not assignable from
//!other cached_adaptive_pool
cached_adaptive_pool& operator=(const cached_adaptive_pool&);
@@ -204,7 +204,7 @@ class cached_adaptive_pool
//!Can throw boost::interprocess::bad_alloc
cached_adaptive_pool(segment_manager *segment_mngr);
- //!Copy constructor from other cached_adaptive_pool. Increments the reference
+ //!Copy constructor from other cached_adaptive_pool. Increments the reference
//!count of the associated node pool. Never throws
cached_adaptive_pool(const cached_adaptive_pool &other);
@@ -231,7 +231,7 @@ class cached_adaptive_pool
//!Never throws
size_type max_size() const;
- //!Allocate memory for an array of count elements.
+ //!Allocate memory for an array of count elements.
//!Throws boost::interprocess::bad_alloc if there is no enough memory
pointer allocate(size_type count, cvoid_pointer hint = 0);
@@ -255,7 +255,7 @@ class cached_adaptive_pool
//!Never throws
const_pointer address(const_reference value) const;
- //!Copy construct an object.
+ //!Copy construct an object.
//!Throws if T's copy constructor throws
void construct(const pointer &ptr, const_reference v);
@@ -270,7 +270,7 @@ class cached_adaptive_pool
std::pair<pointer, bool>
allocation_command(boost::interprocess::allocation_type command,
- size_type limit_size,
+ size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0);
@@ -335,13 +335,13 @@ class cached_adaptive_pool
//!Equality test for same type
//!of cached_adaptive_pool
template<class T, class S, std::size_t NodesPerBlock, std::size_t F, std::size_t OP> inline
-bool operator==(const cached_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1,
+bool operator==(const cached_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1,
const cached_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc2);
//!Inequality test for same type
//!of cached_adaptive_pool
template<class T, class S, std::size_t NodesPerBlock, std::size_t F, std::size_t OP> inline
-bool operator!=(const cached_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1,
+bool operator!=(const cached_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1,
const cached_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc2);
#endif
diff --git a/boost/interprocess/allocators/cached_node_allocator.hpp b/boost/interprocess/allocators/cached_node_allocator.hpp
index 03398156db..b0ad0e4ebc 100644
--- a/boost/interprocess/allocators/cached_node_allocator.hpp
+++ b/boost/interprocess/allocators/cached_node_allocator.hpp
@@ -28,7 +28,7 @@
#include <cstddef>
//!\file
-//!Describes cached_cached_node_allocator pooled shared memory STL compatible allocator
+//!Describes cached_cached_node_allocator pooled shared memory STL compatible allocator
namespace boost {
namespace interprocess {
@@ -64,7 +64,7 @@ class cached_node_allocator_v1
template<class T2>
struct rebind
- {
+ {
typedef cached_node_allocator_v1
<T2, SegmentManager, NodesPerBlock> other;
};
@@ -72,7 +72,7 @@ class cached_node_allocator_v1
typedef typename base_t::size_type size_type;
cached_node_allocator_v1(SegmentManager *segment_mngr,
- size_type max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
+ size_type max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
: base_t(segment_mngr, max_cached_nodes)
{}
@@ -122,12 +122,12 @@ class cached_node_allocator
template<class T2>
struct rebind
- {
+ {
typedef cached_node_allocator<T2, SegmentManager, NodesPerBlock> other;
};
cached_node_allocator(SegmentManager *segment_mngr,
- size_type max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
+ size_type max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
: base_t(segment_mngr, max_cached_nodes)
{}
@@ -151,11 +151,11 @@ class cached_node_allocator
typedef typename SegmentManager::size_type size_type;
typedef typename SegmentManager::difference_type difference_type;
- //!Obtains cached_node_allocator from
+ //!Obtains cached_node_allocator from
//!cached_node_allocator
template<class T2>
struct rebind
- {
+ {
typedef cached_node_allocator<T2, SegmentManager> other;
};
@@ -166,7 +166,7 @@ class cached_node_allocator
cached_node_allocator& operator=
(const cached_node_allocator<T2, SegmentManager2, N2>&);
- //!Not assignable from
+ //!Not assignable from
//!other cached_node_allocator
cached_node_allocator& operator=(const cached_node_allocator&);
@@ -176,7 +176,7 @@ class cached_node_allocator
//!Can throw boost::interprocess::bad_alloc
cached_node_allocator(segment_manager *segment_mngr);
- //!Copy constructor from other cached_node_allocator. Increments the reference
+ //!Copy constructor from other cached_node_allocator. Increments the reference
//!count of the associated node pool. Never throws
cached_node_allocator(const cached_node_allocator &other);
@@ -203,7 +203,7 @@ class cached_node_allocator
//!Never throws
size_type max_size() const;
- //!Allocate memory for an array of count elements.
+ //!Allocate memory for an array of count elements.
//!Throws boost::interprocess::bad_alloc if there is no enough memory
pointer allocate(size_type count, cvoid_pointer hint = 0);
@@ -227,7 +227,7 @@ class cached_node_allocator
//!Never throws
const_pointer address(const_reference value) const;
- //!Default construct an object.
+ //!Default construct an object.
//!Throws if T's default constructor throws
void construct(const pointer &ptr, const_reference v);
@@ -242,7 +242,7 @@ class cached_node_allocator
std::pair<pointer, bool>
allocation_command(boost::interprocess::allocation_type command,
- size_type limit_size,
+ size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0);
@@ -307,13 +307,13 @@ class cached_node_allocator
//!Equality test for same type
//!of cached_node_allocator
template<class T, class S, std::size_t NPC> inline
-bool operator==(const cached_node_allocator<T, S, NPC> &alloc1,
+bool operator==(const cached_node_allocator<T, S, NPC> &alloc1,
const cached_node_allocator<T, S, NPC> &alloc2);
//!Inequality test for same type
//!of cached_node_allocator
template<class T, class S, std::size_t NPC> inline
-bool operator!=(const cached_node_allocator<T, S, NPC> &alloc1,
+bool operator!=(const cached_node_allocator<T, S, NPC> &alloc1,
const cached_node_allocator<T, S, NPC> &alloc2);
#endif
diff --git a/boost/interprocess/allocators/detail/adaptive_node_pool.hpp b/boost/interprocess/allocators/detail/adaptive_node_pool.hpp
index 4ccc920663..abe183146f 100644
--- a/boost/interprocess/allocators/detail/adaptive_node_pool.hpp
+++ b/boost/interprocess/allocators/detail/adaptive_node_pool.hpp
@@ -74,7 +74,7 @@ class private_adaptive_node_pool
};
//!Pooled shared memory allocator using adaptive pool. Includes
-//!a reference count but the class does not delete itself, this is
+//!a reference count but the class does not delete itself, this is
//!responsibility of user classes. Node size (NodeSize) and the number of
//!nodes allocated per block (NodesPerBlock) are known at compile time
template< class SegmentManager
@@ -83,7 +83,7 @@ template< class SegmentManager
, std::size_t MaxFreeBlocks
, unsigned char OverheadPercent
>
-class shared_adaptive_node_pool
+class shared_adaptive_node_pool
: public ipcdetail::shared_pool_impl
< private_adaptive_node_pool
<SegmentManager, NodeSize, NodesPerBlock, MaxFreeBlocks, OverheadPercent>
diff --git a/boost/interprocess/allocators/detail/allocator_common.hpp b/boost/interprocess/allocators/detail/allocator_common.hpp
index ea660b1a90..ba14d3f64d 100644
--- a/boost/interprocess/allocators/detail/allocator_common.hpp
+++ b/boost/interprocess/allocators/detail/allocator_common.hpp
@@ -73,7 +73,7 @@ namespace ipcdetail {
template<class NodePool>
struct get_or_create_node_pool_func
{
-
+
//!This connects or constructs the unique instance of node_pool_t
//!Can throw boost::interprocess::bad_alloc
void operator()()
@@ -90,7 +90,7 @@ struct get_or_create_node_pool_func
//!object parameters
get_or_create_node_pool_func(typename NodePool::segment_manager *mngr)
: mp_segment_manager(mngr){}
-
+
NodePool *mp_node_pool;
typename NodePool::segment_manager *mp_segment_manager;
};
@@ -103,13 +103,13 @@ inline NodePool *get_or_create_node_pool(typename NodePool::segment_manager *mgn
return func.mp_node_pool;
}
-//!Object function that decrements the reference count. If the count
-//!reaches to zero destroys the node allocator from memory.
+//!Object function that decrements the reference count. If the count
+//!reaches to zero destroys the node allocator from memory.
//!Never throws
template<class NodePool>
struct destroy_if_last_link_func
{
- //!Decrements reference count and destroys the object if there is no
+ //!Decrements reference count and destroys the object if there is no
//!more attached allocators. Never throws
void operator()()
{
@@ -117,19 +117,19 @@ struct destroy_if_last_link_func
if(mp_node_pool->dec_ref_count() != 0) return;
//Last link, let's destroy the segment_manager
- mp_node_pool->get_segment_manager()->template destroy<NodePool>(boost::interprocess::unique_instance);
- }
+ mp_node_pool->get_segment_manager()->template destroy<NodePool>(boost::interprocess::unique_instance);
+ }
//!Constructor. Initializes function
//!object parameters
- destroy_if_last_link_func(NodePool *pool)
+ destroy_if_last_link_func(NodePool *pool)
: mp_node_pool(pool)
{}
NodePool *mp_node_pool;
};
-//!Destruction function, initializes and executes destruction function
+//!Destruction function, initializes and executes destruction function
//!object. Never throws
template<class NodePool>
inline void destroy_node_pool_if_last_link(NodePool *pool)
@@ -173,7 +173,7 @@ class cache_impl
~cache_impl()
{
this->deallocate_all_cached_nodes();
- ipcdetail::destroy_node_pool_if_last_link(ipcdetail::to_raw_pointer(mp_node_pool));
+ ipcdetail::destroy_node_pool_if_last_link(ipcdetail::to_raw_pointer(mp_node_pool));
}
NodePool *get_node_pool() const
@@ -227,7 +227,7 @@ class cache_impl
//Check if cache is full
if(m_cached_nodes.size() >= m_max_cached_nodes){
//This only occurs if this allocator deallocate memory allocated
- //with other equal allocator. Since the cache is full, and more
+ //with other equal allocator. Since the cache is full, and more
//deallocations are probably coming, we'll make some room in cache
//in a single, efficient multi node deallocation.
this->priv_deallocate_n_nodes(m_cached_nodes.size() - m_max_cached_nodes/2);
@@ -242,7 +242,7 @@ class cache_impl
//Check if cache is full
if(m_cached_nodes.size() >= m_max_cached_nodes){
//This only occurs if this allocator deallocate memory allocated
- //with other equal allocator. Since the cache is full, and more
+ //with other equal allocator. Since the cache is full, and more
//deallocations are probably coming, we'll make some room in cache
//in a single, efficient multi node deallocation.
this->priv_deallocate_n_nodes(m_cached_nodes.size() - m_max_cached_nodes/2);
@@ -279,7 +279,7 @@ class cache_impl
void priv_deallocate_n_nodes(size_type n)
{
//This only occurs if this allocator deallocate memory allocated
- //with other equal allocator. Since the cache is full, and more
+ //with other equal allocator. Since the cache is full, and more
//deallocations are probably coming, we'll make some room in cache
//in a single, efficient multi node deallocation.
size_type count(n);
@@ -296,10 +296,10 @@ class cache_impl
public:
void swap(cache_impl &other)
{
- ipcdetail::do_swap(mp_node_pool, other.mp_node_pool);
- m_cached_nodes.swap(other.m_cached_nodes);
- ipcdetail::do_swap(m_max_cached_nodes, other.m_max_cached_nodes);
- }
+ ipcdetail::do_swap(mp_node_pool, other.mp_node_pool);
+ m_cached_nodes.swap(other.m_cached_nodes);
+ ipcdetail::do_swap(m_max_cached_nodes, other.m_max_cached_nodes);
+ }
};
template<class Derived, class T, class SegmentManager>
@@ -335,13 +335,13 @@ class array_allocation_impl
//!pointed by p can hold. This size only works for memory allocated with
//!allocate, allocation_command and allocate_many.
size_type size(const pointer &p) const
- {
+ {
return (size_type)this->derived()->get_segment_manager()->size(ipcdetail::to_raw_pointer(p))/sizeof(T);
}
std::pair<pointer, bool>
allocation_command(boost::interprocess::allocation_type command,
- size_type limit_size,
+ size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0)
{
@@ -450,7 +450,7 @@ class node_pool_allocation_impl
};
public:
- //!Allocate memory for an array of count elements.
+ //!Allocate memory for an array of count elements.
//!Throws boost::interprocess::bad_alloc if there is no enough memory
pointer allocate(size_type count, cvoid_pointer hint = 0)
{
@@ -599,7 +599,7 @@ class cached_allocator_impl
size_type get_max_cached_nodes() const
{ return m_cache.get_max_cached_nodes(); }
- //!Allocate memory for an array of count elements.
+ //!Allocate memory for an array of count elements.
//!Throws boost::interprocess::bad_alloc if there is no enough memory
pointer allocate(size_type count, cvoid_pointer hint = 0)
{
@@ -612,7 +612,7 @@ class cached_allocator_impl
}
else{
ret = this->get_segment_manager()->allocate(sizeof(T)*count);
- }
+ }
return pointer(static_cast<T*>(ret));
}
@@ -686,20 +686,20 @@ class cached_allocator_impl
//!Equality test for same type of
//!cached_allocator_impl
template<class T, class N, unsigned int V> inline
-bool operator==(const cached_allocator_impl<T, N, V> &alloc1,
+bool operator==(const cached_allocator_impl<T, N, V> &alloc1,
const cached_allocator_impl<T, N, V> &alloc2)
{ return alloc1.get_node_pool() == alloc2.get_node_pool(); }
//!Inequality test for same type of
//!cached_allocator_impl
template<class T, class N, unsigned int V> inline
-bool operator!=(const cached_allocator_impl<T, N, V> &alloc1,
+bool operator!=(const cached_allocator_impl<T, N, V> &alloc1,
const cached_allocator_impl<T, N, V> &alloc2)
{ return alloc1.get_node_pool() != alloc2.get_node_pool(); }
//!Pooled shared memory allocator using adaptive pool. Includes
-//!a reference count but the class does not delete itself, this is
+//!a reference count but the class does not delete itself, this is
//!responsibility of user classes. Node size (NodeSize) and the number of
//!nodes allocated per block (NodesPerBlock) are known at compile time
template<class private_node_allocator_t>
@@ -736,7 +736,7 @@ class shared_pool_impl
//-----------------------
return private_node_allocator_t::allocate_node();
}
-
+
//!Deallocates an array pointed by ptr. Never throws
void deallocate_node(void *ptr)
{
@@ -756,7 +756,7 @@ class shared_pool_impl
return private_node_allocator_t::allocate_nodes(nodes, n);
}
*/
- //!Allocates n nodes.
+ //!Allocates n nodes.
//!Can throw boost::interprocess::bad_alloc
multiallocation_chain allocate_nodes(const size_type n)
{
diff --git a/boost/interprocess/allocators/detail/node_pool.hpp b/boost/interprocess/allocators/detail/node_pool.hpp
index 7327ff92d5..562b64863b 100644
--- a/boost/interprocess/allocators/detail/node_pool.hpp
+++ b/boost/interprocess/allocators/detail/node_pool.hpp
@@ -37,7 +37,7 @@ namespace ipcdetail {
//!Pooled shared memory allocator using single segregated storage. Includes
-//!a reference count but the class does not delete itself, this is
+//!a reference count but the class does not delete itself, this is
//!responsibility of user classes. Node size (NodeSize) and the number of
//!nodes allocated per block (NodesPerBlock) are known at compile time
template< class SegmentManager, std::size_t NodeSize, std::size_t NodesPerBlock >
@@ -73,18 +73,18 @@ class private_node_pool
//!Pooled shared memory allocator using single segregated storage. Includes
-//!a reference count but the class does not delete itself, this is
+//!a reference count but the class does not delete itself, this is
//!responsibility of user classes. Node size (NodeSize) and the number of
//!nodes allocated per block (NodesPerBlock) are known at compile time
//!Pooled shared memory allocator using adaptive pool. Includes
-//!a reference count but the class does not delete itself, this is
+//!a reference count but the class does not delete itself, this is
//!responsibility of user classes. Node size (NodeSize) and the number of
//!nodes allocated per block (NodesPerBlock) are known at compile time
template< class SegmentManager
, std::size_t NodeSize
, std::size_t NodesPerBlock
>
-class shared_node_pool
+class shared_node_pool
: public ipcdetail::shared_pool_impl
< private_node_pool
<SegmentManager, NodeSize, NodesPerBlock>
diff --git a/boost/interprocess/allocators/node_allocator.hpp b/boost/interprocess/allocators/node_allocator.hpp
index f1c3259d73..2c1fe566a3 100644
--- a/boost/interprocess/allocators/node_allocator.hpp
+++ b/boost/interprocess/allocators/node_allocator.hpp
@@ -34,7 +34,7 @@
#include <cstddef>
//!\file
-//!Describes node_allocator pooled shared memory STL compatible allocator
+//!Describes node_allocator pooled shared memory STL compatible allocator
namespace boost {
namespace interprocess {
@@ -98,11 +98,11 @@ class node_allocator_base
typedef boost::container::container_detail::transform_multiallocation_chain
<typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
- //!Obtains node_allocator_base from
+ //!Obtains node_allocator_base from
//!node_allocator_base
template<class T2>
struct rebind
- {
+ {
typedef node_allocator_base<Version, T2, SegmentManager, NodesPerBlock> other;
};
@@ -121,15 +121,15 @@ class node_allocator_base
//!Constructor from a segment manager. If not present, constructs a node
//!pool. Increments the reference count of the associated node pool.
//!Can throw boost::interprocess::bad_alloc
- node_allocator_base(segment_manager *segment_mngr)
+ node_allocator_base(segment_manager *segment_mngr)
: mp_node_pool(ipcdetail::get_or_create_node_pool<typename node_pool<0>::type>(segment_mngr)) { }
- //!Copy constructor from other node_allocator_base. Increments the reference
+ //!Copy constructor from other node_allocator_base. Increments the reference
//!count of the associated node pool. Never throws
- node_allocator_base(const node_allocator_base &other)
- : mp_node_pool(other.get_node_pool())
- {
- node_pool<0>::get(ipcdetail::to_raw_pointer(mp_node_pool))->inc_ref_count();
+ node_allocator_base(const node_allocator_base &other)
+ : mp_node_pool(other.get_node_pool())
+ {
+ node_pool<0>::get(ipcdetail::to_raw_pointer(mp_node_pool))->inc_ref_count();
}
//!Copy constructor from related node_allocator_base. If not present, constructs
@@ -150,7 +150,7 @@ class node_allocator_base
//!Destructor, removes node_pool_t from memory
//!if its reference count reaches to zero. Never throws
- ~node_allocator_base()
+ ~node_allocator_base()
{ ipcdetail::destroy_node_pool_if_last_link(node_pool<0>::get(ipcdetail::to_raw_pointer(mp_node_pool))); }
//!Returns a pointer to the node pool.
@@ -177,14 +177,14 @@ class node_allocator_base
//!Equality test for same type
//!of node_allocator_base
template<unsigned int V, class T, class S, std::size_t NPC> inline
-bool operator==(const node_allocator_base<V, T, S, NPC> &alloc1,
+bool operator==(const node_allocator_base<V, T, S, NPC> &alloc1,
const node_allocator_base<V, T, S, NPC> &alloc2)
{ return alloc1.get_node_pool() == alloc2.get_node_pool(); }
//!Inequality test for same type
//!of node_allocator_base
template<unsigned int V, class T, class S, std::size_t NPC> inline
-bool operator!=(const node_allocator_base<V, T, S, NPC> &alloc1,
+bool operator!=(const node_allocator_base<V, T, S, NPC> &alloc1,
const node_allocator_base<V, T, S, NPC> &alloc2)
{ return alloc1.get_node_pool() != alloc2.get_node_pool(); }
@@ -206,11 +206,11 @@ class node_allocator_v1
template<class T2>
struct rebind
- {
+ {
typedef node_allocator_v1<T2, SegmentManager, NodesPerBlock> other;
};
- node_allocator_v1(SegmentManager *segment_mngr)
+ node_allocator_v1(SegmentManager *segment_mngr)
: base_t(segment_mngr)
{}
@@ -225,12 +225,12 @@ class node_allocator_v1
/// @endcond
-//!An STL node allocator that uses a segment manager as memory
+//!An STL node allocator that uses a segment manager as memory
//!source. The internal pointer type will of the same type (raw, smart) as
//!"typename SegmentManager::void_pointer" type. This allows
//!placing the allocator in shared memory, memory mapped-files, etc...
-//!This node allocator shares a segregated storage between all instances
-//!of node_allocator with equal sizeof(T) placed in the same segment
+//!This node allocator shares a segregated storage between all instances
+//!of node_allocator with equal sizeof(T) placed in the same segment
//!group. NodesPerBlock is the number of nodes allocated at once when the allocator
//!needs runs out of nodes
template < class T
@@ -256,11 +256,11 @@ class node_allocator
template<class T2>
struct rebind
- {
+ {
typedef node_allocator<T2, SegmentManager, NodesPerBlock> other;
};
- node_allocator(SegmentManager *segment_mngr)
+ node_allocator(SegmentManager *segment_mngr)
: base_t(segment_mngr)
{}
@@ -284,11 +284,11 @@ class node_allocator
typedef typename segment_manager::size_type size_type;
typedef typename segment_manager::difference_type difference_type;
- //!Obtains node_allocator from
+ //!Obtains node_allocator from
//!node_allocator
template<class T2>
struct rebind
- {
+ {
typedef node_allocator<T2, SegmentManager, NodesPerBlock> other;
};
@@ -299,7 +299,7 @@ class node_allocator
node_allocator& operator=
(const node_allocator<T2, SegmentManager2, N2>&);
- //!Not assignable from
+ //!Not assignable from
//!other node_allocator
//node_allocator& operator=(const node_allocator&);
@@ -309,7 +309,7 @@ class node_allocator
//!Can throw boost::interprocess::bad_alloc
node_allocator(segment_manager *segment_mngr);
- //!Copy constructor from other node_allocator. Increments the reference
+ //!Copy constructor from other node_allocator. Increments the reference
//!count of the associated node pool. Never throws
node_allocator(const node_allocator &other);
@@ -336,7 +336,7 @@ class node_allocator
//!Never throws
size_type max_size() const;
- //!Allocate memory for an array of count elements.
+ //!Allocate memory for an array of count elements.
//!Throws boost::interprocess::bad_alloc if there is no enough memory
pointer allocate(size_type count, cvoid_pointer hint = 0);
@@ -360,7 +360,7 @@ class node_allocator
//!Never throws
const_pointer address(const_reference value) const;
- //!Copy construct an object.
+ //!Copy construct an object.
//!Throws if T's copy constructor throws
void construct(const pointer &ptr, const_reference v);
@@ -375,7 +375,7 @@ class node_allocator
std::pair<pointer, bool>
allocation_command(boost::interprocess::allocation_type command,
- size_type limit_size,
+ size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0);
@@ -433,13 +433,13 @@ class node_allocator
//!Equality test for same type
//!of node_allocator
template<class T, class S, std::size_t NPC> inline
-bool operator==(const node_allocator<T, S, NPC> &alloc1,
+bool operator==(const node_allocator<T, S, NPC> &alloc1,
const node_allocator<T, S, NPC> &alloc2);
//!Inequality test for same type
//!of node_allocator
template<class T, class S, std::size_t NPC> inline
-bool operator!=(const node_allocator<T, S, NPC> &alloc1,
+bool operator!=(const node_allocator<T, S, NPC> &alloc1,
const node_allocator<T, S, NPC> &alloc2);
#endif
diff --git a/boost/interprocess/allocators/private_adaptive_pool.hpp b/boost/interprocess/allocators/private_adaptive_pool.hpp
index 301fb92daa..febe85c69d 100644
--- a/boost/interprocess/allocators/private_adaptive_pool.hpp
+++ b/boost/interprocess/allocators/private_adaptive_pool.hpp
@@ -33,7 +33,7 @@
#include <cstddef>
//!\file
-//!Describes private_adaptive_pool_base pooled shared memory STL compatible allocator
+//!Describes private_adaptive_pool_base pooled shared memory STL compatible allocator
namespace boost {
namespace interprocess {
@@ -102,7 +102,7 @@ class private_adaptive_pool_base
//!Obtains node_allocator from other node_allocator
template<class T2>
struct rebind
- {
+ {
typedef private_adaptive_pool_base
<Version, T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
};
@@ -154,7 +154,7 @@ class private_adaptive_pool_base
{}
//!Destructor, frees all used memory. Never throws
- ~private_adaptive_pool_base()
+ ~private_adaptive_pool_base()
{}
//!Returns the segment manager. Never throws
@@ -178,13 +178,13 @@ class private_adaptive_pool_base
//!Equality test for same type of private_adaptive_pool_base
template<unsigned int V, class T, class S, std::size_t NodesPerBlock, std::size_t F, unsigned char OP> inline
-bool operator==(const private_adaptive_pool_base<V, T, S, NodesPerBlock, F, OP> &alloc1,
+bool operator==(const private_adaptive_pool_base<V, T, S, NodesPerBlock, F, OP> &alloc1,
const private_adaptive_pool_base<V, T, S, NodesPerBlock, F, OP> &alloc2)
{ return &alloc1 == &alloc2; }
//!Inequality test for same type of private_adaptive_pool_base
template<unsigned int V, class T, class S, std::size_t NodesPerBlock, std::size_t F, unsigned char OP> inline
-bool operator!=(const private_adaptive_pool_base<V, T, S, NodesPerBlock, F, OP> &alloc1,
+bool operator!=(const private_adaptive_pool_base<V, T, S, NodesPerBlock, F, OP> &alloc1,
const private_adaptive_pool_base<V, T, S, NodesPerBlock, F, OP> &alloc2)
{ return &alloc1 != &alloc2; }
@@ -210,11 +210,11 @@ class private_adaptive_pool_v1
template<class T2>
struct rebind
- {
+ {
typedef private_adaptive_pool_v1<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
};
- private_adaptive_pool_v1(SegmentManager *segment_mngr)
+ private_adaptive_pool_v1(SegmentManager *segment_mngr)
: base_t(segment_mngr)
{}
@@ -229,7 +229,7 @@ class private_adaptive_pool_v1
/// @endcond
-//!An STL node allocator that uses a segment manager as memory
+//!An STL node allocator that uses a segment manager as memory
//!source. The internal pointer type will of the same type (raw, smart) as
//!"typename SegmentManager::void_pointer" type. This allows
//!placing the allocator in shared memory, memory mapped-files, etc...
@@ -269,12 +269,12 @@ class private_adaptive_pool
template<class T2>
struct rebind
- {
+ {
typedef private_adaptive_pool
<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
};
- private_adaptive_pool(SegmentManager *segment_mngr)
+ private_adaptive_pool(SegmentManager *segment_mngr)
: base_t(segment_mngr)
{}
@@ -298,11 +298,11 @@ class private_adaptive_pool
typedef typename segment_manager::size_type size_type;
typedef typename segment_manager::difference_type difference_type;
- //!Obtains private_adaptive_pool from
+ //!Obtains private_adaptive_pool from
//!private_adaptive_pool
template<class T2>
struct rebind
- {
+ {
typedef private_adaptive_pool
<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
};
@@ -314,7 +314,7 @@ class private_adaptive_pool
private_adaptive_pool& operator=
(const private_adaptive_pool<T2, SegmentManager2, N2, F2>&);
- //!Not assignable from
+ //!Not assignable from
//!other private_adaptive_pool
private_adaptive_pool& operator=(const private_adaptive_pool&);
@@ -324,7 +324,7 @@ class private_adaptive_pool
//!Can throw boost::interprocess::bad_alloc
private_adaptive_pool(segment_manager *segment_mngr);
- //!Copy constructor from other private_adaptive_pool. Increments the reference
+ //!Copy constructor from other private_adaptive_pool. Increments the reference
//!count of the associated node pool. Never throws
private_adaptive_pool(const private_adaptive_pool &other);
@@ -351,7 +351,7 @@ class private_adaptive_pool
//!Never throws
size_type max_size() const;
- //!Allocate memory for an array of count elements.
+ //!Allocate memory for an array of count elements.
//!Throws boost::interprocess::bad_alloc if there is no enough memory
pointer allocate(size_type count, cvoid_pointer hint = 0);
@@ -375,7 +375,7 @@ class private_adaptive_pool
//!Never throws
const_pointer address(const_reference value) const;
- //!Copy construct an object.
+ //!Copy construct an object.
//!Throws if T's copy constructor throws
void construct(const pointer &ptr, const_reference v);
@@ -390,7 +390,7 @@ class private_adaptive_pool
std::pair<pointer, bool>
allocation_command(boost::interprocess::allocation_type command,
- size_type limit_size,
+ size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0);
@@ -448,13 +448,13 @@ class private_adaptive_pool
//!Equality test for same type
//!of private_adaptive_pool
template<class T, class S, std::size_t NodesPerBlock, std::size_t F, unsigned char OP> inline
-bool operator==(const private_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1,
+bool operator==(const private_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1,
const private_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc2);
//!Inequality test for same type
//!of private_adaptive_pool
template<class T, class S, std::size_t NodesPerBlock, std::size_t F, unsigned char OP> inline
-bool operator!=(const private_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1,
+bool operator!=(const private_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1,
const private_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc2);
#endif
diff --git a/boost/interprocess/allocators/private_node_allocator.hpp b/boost/interprocess/allocators/private_node_allocator.hpp
index f202e316fa..46b7dd6097 100644
--- a/boost/interprocess/allocators/private_node_allocator.hpp
+++ b/boost/interprocess/allocators/private_node_allocator.hpp
@@ -33,7 +33,7 @@
#include <cstddef>
//!\file
-//!Describes private_node_allocator_base pooled shared memory STL compatible allocator
+//!Describes private_node_allocator_base pooled shared memory STL compatible allocator
namespace boost {
namespace interprocess {
@@ -97,7 +97,7 @@ class private_node_allocator_base
//!Obtains node_allocator from other node_allocator
template<class T2>
struct rebind
- {
+ {
typedef private_node_allocator_base
<Version, T2, SegmentManager, NodesPerBlock> other;
};
@@ -146,7 +146,7 @@ class private_node_allocator_base
{}
//!Destructor, frees all used memory. Never throws
- ~private_node_allocator_base()
+ ~private_node_allocator_base()
{}
//!Returns the segment manager. Never throws
@@ -170,13 +170,13 @@ class private_node_allocator_base
//!Equality test for same type of private_node_allocator_base
template<unsigned int V, class T, class S, std::size_t NPC> inline
-bool operator==(const private_node_allocator_base<V, T, S, NPC> &alloc1,
+bool operator==(const private_node_allocator_base<V, T, S, NPC> &alloc1,
const private_node_allocator_base<V, T, S, NPC> &alloc2)
{ return &alloc1 == &alloc2; }
//!Inequality test for same type of private_node_allocator_base
template<unsigned int V, class T, class S, std::size_t NPC> inline
-bool operator!=(const private_node_allocator_base<V, T, S, NPC> &alloc1,
+bool operator!=(const private_node_allocator_base<V, T, S, NPC> &alloc1,
const private_node_allocator_base<V, T, S, NPC> &alloc2)
{ return &alloc1 != &alloc2; }
@@ -198,11 +198,11 @@ class private_node_allocator_v1
template<class T2>
struct rebind
- {
+ {
typedef private_node_allocator_v1<T2, SegmentManager, NodesPerBlock> other;
};
- private_node_allocator_v1(SegmentManager *segment_mngr)
+ private_node_allocator_v1(SegmentManager *segment_mngr)
: base_t(segment_mngr)
{}
@@ -217,11 +217,11 @@ class private_node_allocator_v1
/// @endcond
-//!An STL node allocator that uses a segment manager as memory
+//!An STL node allocator that uses a segment manager as memory
//!source. The internal pointer type will of the same type (raw, smart) as
//!"typename SegmentManager::void_pointer" type. This allows
//!placing the allocator in shared memory, memory mapped-files, etc...
-//!This allocator has its own node pool. NodesPerBlock is the number of nodes allocated
+//!This allocator has its own node pool. NodesPerBlock is the number of nodes allocated
//!at once when the allocator needs runs out of nodes
template < class T
, class SegmentManager
@@ -246,12 +246,12 @@ class private_node_allocator
template<class T2>
struct rebind
- {
+ {
typedef private_node_allocator
<T2, SegmentManager, NodesPerBlock> other;
};
- private_node_allocator(SegmentManager *segment_mngr)
+ private_node_allocator(SegmentManager *segment_mngr)
: base_t(segment_mngr)
{}
@@ -275,11 +275,11 @@ class private_node_allocator
typedef typename segment_manager::size_type size_type;
typedef typename segment_manage::difference_type difference_type;
- //!Obtains private_node_allocator from
+ //!Obtains private_node_allocator from
//!private_node_allocator
template<class T2>
struct rebind
- {
+ {
typedef private_node_allocator
<T2, SegmentManager, NodesPerBlock> other;
};
@@ -291,7 +291,7 @@ class private_node_allocator
private_node_allocator& operator=
(const private_node_allocator<T2, SegmentManager2, N2>&);
- //!Not assignable from
+ //!Not assignable from
//!other private_node_allocator
private_node_allocator& operator=(const private_node_allocator&);
@@ -301,7 +301,7 @@ class private_node_allocator
//!Can throw boost::interprocess::bad_alloc
private_node_allocator(segment_manager *segment_mngr);
- //!Copy constructor from other private_node_allocator. Increments the reference
+ //!Copy constructor from other private_node_allocator. Increments the reference
//!count of the associated node pool. Never throws
private_node_allocator(const private_node_allocator &other);
@@ -328,7 +328,7 @@ class private_node_allocator
//!Never throws
size_type max_size() const;
- //!Allocate memory for an array of count elements.
+ //!Allocate memory for an array of count elements.
//!Throws boost::interprocess::bad_alloc if there is no enough memory
pointer allocate(size_type count, cvoid_pointer hint = 0);
@@ -352,7 +352,7 @@ class private_node_allocator
//!Never throws
const_pointer address(const_reference value) const;
- //!Copy construct an object.
+ //!Copy construct an object.
//!Throws if T's copy constructor throws
void construct(const pointer &ptr, const_reference v);
@@ -367,7 +367,7 @@ class private_node_allocator
std::pair<pointer, bool>
allocation_command(boost::interprocess::allocation_type command,
- size_type limit_size,
+ size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0);
@@ -425,13 +425,13 @@ class private_node_allocator
//!Equality test for same type
//!of private_node_allocator
template<class T, class S, std::size_t NodesPerBlock, std::size_t F, unsigned char OP> inline
-bool operator==(const private_node_allocator<T, S, NodesPerBlock, F, OP> &alloc1,
+bool operator==(const private_node_allocator<T, S, NodesPerBlock, F, OP> &alloc1,
const private_node_allocator<T, S, NodesPerBlock, F, OP> &alloc2);
//!Inequality test for same type
//!of private_node_allocator
template<class T, class S, std::size_t NodesPerBlock, std::size_t F, unsigned char OP> inline
-bool operator!=(const private_node_allocator<T, S, NodesPerBlock, F, OP> &alloc1,
+bool operator!=(const private_node_allocator<T, S, NodesPerBlock, F, OP> &alloc1,
const private_node_allocator<T, S, NodesPerBlock, F, OP> &alloc2);
#endif
diff --git a/boost/interprocess/anonymous_shared_memory.hpp b/boost/interprocess/anonymous_shared_memory.hpp
index 7184306a6d..624f57f9c3 100644
--- a/boost/interprocess/anonymous_shared_memory.hpp
+++ b/boost/interprocess/anonymous_shared_memory.hpp
@@ -20,7 +20,7 @@
#include <cstddef>
#if (!defined(BOOST_INTERPROCESS_WINDOWS))
-# include <fcntl.h> //open, O_CREAT, O_*...
+# include <fcntl.h> //open, O_CREAT, O_*...
# include <sys/mman.h> //mmap
# include <sys/stat.h> //mode_t, S_IRWXG, S_IRWXO, S_IRWXU,
#else
@@ -43,12 +43,10 @@ namespace ipcdetail{
{
public:
static mapped_region
- create_posix_mapped_region(void *address, offset_t offset, std::size_t size)
+ create_posix_mapped_region(void *address, std::size_t size)
{
mapped_region region;
region.m_base = address;
- region.m_offset = offset;
- region.m_extra_offset = 0;
region.m_size = size;
return region;
}
@@ -92,16 +90,16 @@ anonymous_shared_memory(std::size_t size, void *address = 0)
, 0);
if(address == MAP_FAILED){
- if(fd != -1)
+ if(fd != -1)
close(fd);
error_info err = system_error_code();
throw interprocess_exception(err);
}
- if(fd != -1)
+ if(fd != -1)
close(fd);
- return ipcdetail::raw_mapped_region_creator::create_posix_mapped_region(address, 0, size);
+ return ipcdetail::raw_mapped_region_creator::create_posix_mapped_region(address, size);
}
#else
{
diff --git a/boost/interprocess/detail/atomic.hpp b/boost/interprocess/detail/atomic.hpp
index f7551f3dda..aab1533985 100644
--- a/boost/interprocess/detail/atomic.hpp
+++ b/boost/interprocess/detail/atomic.hpp
@@ -117,23 +117,6 @@ inline boost::uint32_t atomic_cas32
: "cc");
return prev;
-/*
- asm volatile( "lock\n\t"
- "cmpxchg %3,%1"
- : "=a" (prev), "=m" (*(mem))
- : "0" (prev), "r" (with)
- : "memory", "cc");
-*/
-/*
- boost::uint32_t prev;
-
- asm volatile ("lock; cmpxchgl %1, %2"
- : "=a" (prev)
- : "r" (with), "m" (*(mem)), "0"(cmp));
- asm volatile("" : : : "memory");
-
- return prev;
-*/
}
//! Atomically add 'val' to an boost::uint32_t
@@ -158,14 +141,6 @@ inline boost::uint32_t atomic_add32
);
return r;
-/*
- asm volatile( "lock\n\t; xaddl %0,%1"
- : "=r"(val), "=m"(*mem)
- : "0"(val), "m"(*mem));
- asm volatile("" : : : "memory");
-
- return val;
-*/
}
//! Atomically increment an apr_uint32_t by 1
@@ -208,17 +183,14 @@ inline boost::uint32_t atomic_add32(volatile boost::uint32_t *mem, boost::uint32
{
boost::uint32_t prev, temp;
- asm volatile ("0:\n\t" // retry local label
- "lwarx %0,0,%2\n\t" // load prev and reserve
- "add %1,%0,%3\n\t" // temp = prev + val
- "stwcx. %1,0,%2\n\t" // conditionally store
- "bne- 0b" // start over if we lost
- // the reservation
- //XXX find a cleaner way to define the temp
- //it's not an output
- : "=&r" (prev), "=&r" (temp) // output, temp
- : "b" (mem), "r" (val) // inputs
- : "memory", "cc"); // clobbered
+ asm volatile ("1:\n\t"
+ "lwarx %0,0,%2\n\t"
+ "add %1,%0,%3\n\t"
+ "stwcx. %1,0,%2\n\t"
+ "bne- 1b"
+ : "=&r" (prev), "=&r" (temp)
+ : "b" (mem), "r" (val)
+ : "cc", "memory");
return prev;
}
@@ -233,19 +205,16 @@ inline boost::uint32_t atomic_cas32
{
boost::uint32_t prev;
- asm volatile ("0:\n\t" // retry local label
- "lwarx %0,0,%1\n\t" // load prev and reserve
- "cmpw %0,%3\n\t" // does it match cmp?
- "bne- 1f\n\t" // ...no, bail out
- "stwcx. %2,0,%1\n\t" // ...yes, conditionally
- // store with
- "bne- 0b\n\t" // start over if we lost
- // the reservation
- "1:" // exit local label
-
- : "=&r"(prev) // output
- : "b" (mem), "r" (with), "r"(cmp) // inputs
- : "memory", "cc"); // clobbered
+ asm volatile ("1:\n\t"
+ "lwarx %0,0,%1\n\t"
+ "cmpw %0,%3\n\t"
+ "bne- 2f\n\t"
+ "stwcx. %2,0,%1\n\t"
+ "bne- 1b\n\t"
+ "2:"
+ : "=&r"(prev)
+ : "b" (mem), "r"(cmp), "r" (with)
+ : "cc", "memory");
return prev;
}
@@ -275,56 +244,6 @@ inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
} //namespace interprocess{
} //namespace boost{
-#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
-
-namespace boost {
-namespace interprocess {
-namespace ipcdetail{
-
-//! Atomically add 'val' to an boost::uint32_t
-//! "mem": pointer to the object
-//! "val": amount to add
-//! Returns the old value pointed to by mem
-inline boost::uint32_t atomic_add32
- (volatile boost::uint32_t *mem, boost::uint32_t val)
-{ return __sync_fetch_and_add(const_cast<boost::uint32_t *>(mem), val); }
-
-//! Atomically increment an apr_uint32_t by 1
-//! "mem": pointer to the object
-//! Returns the old value pointed to by mem
-inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem)
-{ return atomic_add32(mem, 1); }
-
-//! Atomically decrement an boost::uint32_t by 1
-//! "mem": pointer to the atomic value
-//! Returns the old value pointed to by mem
-inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem)
-{ return atomic_add32(mem, (boost::uint32_t)-1); }
-
-//! Atomically read an boost::uint32_t from memory
-inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
-{ return *mem; }
-
-//! Compare an boost::uint32_t's value with "cmp".
-//! If they are the same swap the value with "with"
-//! "mem": pointer to the value
-//! "with" what to swap it with
-//! "cmp": the value to compare it to
-//! Returns the old value of *mem
-inline boost::uint32_t atomic_cas32
- (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
-{ return __sync_val_compare_and_swap(const_cast<boost::uint32_t *>(mem), cmp, with); }
-
-//! Atomically set an boost::uint32_t in memory
-//! "mem": pointer to the object
-//! "param": val value that the object will assume
-inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{ *mem = val; }
-
-} //namespace ipcdetail{
-} //namespace interprocess{
-} //namespace boost{
-
#elif (defined(sun) || defined(__sun))
#include <atomic.h>
@@ -471,97 +390,147 @@ inline boost::uint32_t atomic_cas32(
} //namespace interprocess{
} //namespace boost{
-#elif defined(__IBMCPP__) && (__IBMCPP__ >= 800) && defined(_AIX)
-
-#include <builtins.h>
-
-namespace boost {
-namespace interprocess {
-namespace ipcdetail{
-
-//first define boost::uint32_t versions of __lwarx and __stwcx to avoid poluting
-//all the functions with casts
-
-//! From XLC documenation :
-//! This function can be used with a subsequent stwcxu call to implement a
-//! read-modify-write on a specified memory location. The two functions work
-//! together to ensure that if the store is successfully performed, no other
-//! processor or mechanism can modify the target doubleword between the time
-//! lwarxu function is executed and the time the stwcxu functio ncompletes.
-//! "mem" : pointer to the object
-//! Returns the value at pointed to by mem
-inline boost::uint32_t lwarxu(volatile boost::uint32_t *mem)
-{
- return static_cast<boost::uint32_t>(__lwarx(reinterpret_cast<volatile int*>(mem)));
-}
-
-//! "mem" : pointer to the object
-//! "val" : the value to store
-//! Returns true if the update of mem is successful and false if it is
-//!unsuccessful
-inline bool stwcxu(volatile boost::uint32_t* mem, boost::uint32_t val)
-{
- return (__stwcx(reinterpret_cast<volatile int*>(mem), static_cast<int>(val)) != 0);
-}
-
-//! "mem": pointer to the object
-//! "val": amount to add
-//! Returns the old value pointed to by mem
-inline boost::uint32_t atomic_add32
- (volatile boost::uint32_t *mem, boost::uint32_t val)
-{
- boost::uint32_t oldValue;
- do
- {
- oldValue = lwarxu(mem);
- }while (!stwcxu(mem, oldValue+val));
- return oldValue;
-}
-
-//! Atomically increment an apr_uint32_t by 1
-//! "mem": pointer to the object
-//! Returns the old value pointed to by mem
-inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem)
-{ return atomic_add32(mem, 1); }
-
-//! Atomically decrement an boost::uint32_t by 1
-//! "mem": pointer to the atomic value
-//! Returns the old value pointed to by mem
-inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem)
-{ return atomic_add32(mem, (boost::uint32_t)-1); }
-
-//! Atomically read an boost::uint32_t from memory
-inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
-{ return *mem; }
-
-//! Compare an boost::uint32_t's value with "cmp".
-//! If they are the same swap the value with "with"
-//! "mem": pointer to the value
-//! "with" what to swap it with
-//! "cmp": the value to compare it to
-//! Returns the old value of *mem
-inline boost::uint32_t atomic_cas32
- (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
-{
- boost::uint32_t oldValue;
- boost::uint32_t valueToStore;
- do
- {
- oldValue = lwarxu(mem);
- } while (!stwcxu(mem, (oldValue == with) ? cmp : oldValue));
-
- return oldValue;
-}
-
-//! Atomically set an boost::uint32_t in memory
-//! "mem": pointer to the object
-//! "param": val value that the object will assume
-inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{ *mem = val; }
-
-} //namespace ipcdetail
-} //namespace interprocess
-} //namespace boost
+#elif defined(__IBMCPP__) && (__IBMCPP__ >= 800) && defined(_AIX)
+
+#include <builtins.h>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail{
+
+//first define boost::uint32_t versions of __lwarx and __stwcx to avoid poluting
+//all the functions with casts
+
+//! From XLC documenation :
+//! This function can be used with a subsequent stwcxu call to implement a
+//! read-modify-write on a specified memory location. The two functions work
+//! together to ensure that if the store is successfully performed, no other
+//! processor or mechanism can modify the target doubleword between the time
+//! lwarxu function is executed and the time the stwcxu functio ncompletes.
+//! "mem" : pointer to the object
+//! Returns the value at pointed to by mem
+inline boost::uint32_t lwarxu(volatile boost::uint32_t *mem)
+{
+ return static_cast<boost::uint32_t>(__lwarx(reinterpret_cast<volatile int*>(mem)));
+}
+
+//! "mem" : pointer to the object
+//! "val" : the value to store
+//! Returns true if the update of mem is successful and false if it is
+//!unsuccessful
+inline bool stwcxu(volatile boost::uint32_t* mem, boost::uint32_t val)
+{
+ return (__stwcx(reinterpret_cast<volatile int*>(mem), static_cast<int>(val)) != 0);
+}
+
+//! "mem": pointer to the object
+//! "val": amount to add
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_add32
+ (volatile boost::uint32_t *mem, boost::uint32_t val)
+{
+ boost::uint32_t oldValue;
+ do
+ {
+ oldValue = lwarxu(mem);
+ }while (!stwcxu(mem, oldValue+val));
+ return oldValue;
+}
+
+//! Atomically increment an apr_uint32_t by 1
+//! "mem": pointer to the object
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem)
+{ return atomic_add32(mem, 1); }
+
+//! Atomically decrement an boost::uint32_t by 1
+//! "mem": pointer to the atomic value
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem)
+{ return atomic_add32(mem, (boost::uint32_t)-1); }
+
+//! Atomically read an boost::uint32_t from memory
+inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
+{ return *mem; }
+
+//! Compare an boost::uint32_t's value with "cmp".
+//! If they are the same swap the value with "with"
+//! "mem": pointer to the value
+//! "with" what to swap it with
+//! "cmp": the value to compare it to
+//! Returns the old value of *mem
+inline boost::uint32_t atomic_cas32
+ (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
+{
+ boost::uint32_t oldValue;
+ boost::uint32_t valueToStore;
+ do
+ {
+ oldValue = lwarxu(mem);
+ } while (!stwcxu(mem, (oldValue == with) ? cmp : oldValue));
+
+ return oldValue;
+}
+
+//! Atomically set an boost::uint32_t in memory
+//! "mem": pointer to the object
+//! "param": val value that the object will assume
+inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
+{ *mem = val; }
+
+} //namespace ipcdetail
+} //namespace interprocess
+} //namespace boost
+
+#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail{
+
+//! Atomically add 'val' to an boost::uint32_t
+//! "mem": pointer to the object
+//! "val": amount to add
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_add32
+ (volatile boost::uint32_t *mem, boost::uint32_t val)
+{ return __sync_fetch_and_add(const_cast<boost::uint32_t *>(mem), val); }
+
+//! Atomically increment an apr_uint32_t by 1
+//! "mem": pointer to the object
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem)
+{ return atomic_add32(mem, 1); }
+
+//! Atomically decrement an boost::uint32_t by 1
+//! "mem": pointer to the atomic value
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem)
+{ return atomic_add32(mem, (boost::uint32_t)-1); }
+
+//! Atomically read an boost::uint32_t from memory
+inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
+{ return *mem; }
+
+//! Compare an boost::uint32_t's value with "cmp".
+//! If they are the same swap the value with "with"
+//! "mem": pointer to the value
+//! "with" what to swap it with
+//! "cmp": the value to compare it to
+//! Returns the old value of *mem
+inline boost::uint32_t atomic_cas32
+ (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
+{ return __sync_val_compare_and_swap(const_cast<boost::uint32_t *>(mem), cmp, with); }
+
+//! Atomically set an boost::uint32_t in memory
+//! "mem": pointer to the object
+//! "param": val value that the object will assume
+inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
+{ *mem = val; }
+
+} //namespace ipcdetail{
+} //namespace interprocess{
+} //namespace boost{
#else
@@ -583,9 +552,9 @@ inline bool atomic_add_unless32
return c != unless_this;
}
-} //namespace ipcdetail
-} //namespace interprocess
-} //namespace boost
+} //namespace ipcdetail
+} //namespace interprocess
+} //namespace boost
#include <boost/interprocess/detail/config_end.hpp>
diff --git a/boost/interprocess/detail/config_begin.hpp b/boost/interprocess/detail/config_begin.hpp
index 559331ab32..a72f6df1fe 100644
--- a/boost/interprocess/detail/config_begin.hpp
+++ b/boost/interprocess/detail/config_begin.hpp
@@ -44,4 +44,5 @@
// with /GR-; unpredictable behavior may result
#pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
#pragma warning (disable : 4671) // the copy constructor is inaccessible
+ #pragma warning (disable : 4250) // inherits 'x' via dominance
#endif
diff --git a/boost/interprocess/detail/file_locking_helpers.hpp b/boost/interprocess/detail/file_locking_helpers.hpp
new file mode 100644
index 0000000000..2b96e2b6d5
--- /dev/null
+++ b/boost/interprocess/detail/file_locking_helpers.hpp
@@ -0,0 +1,298 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009-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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_FILE_LOCKING_HELPERS_HPP
+#define BOOST_INTERPROCESS_FILE_LOCKING_HELPERS_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#include <sstream>
+#include <string>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <cstddef>
+#include <boost/interprocess/detail/os_file_functions.hpp>
+
+#include <boost/interprocess/detail/tmp_dir_helpers.hpp>
+
+#if defined(BOOST_INTERPROCESS_WINDOWS)
+
+#include <fcntl.h>
+#include <io.h>
+#include <sys/locking.h>
+
+#else //defined(BOOST_INTERPROCESS_WINDOWS)
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#endif //defined(BOOST_INTERPROCESS_WINDOWS)
+
+namespace boost{
+namespace interprocess{
+namespace ipcdetail{
+
+#if defined(BOOST_INTERPROCESS_WINDOWS)
+
+struct locking_file_serial_id
+{
+ int fd;
+ unsigned long dwVolumeSerialNumber;
+ unsigned long nFileIndexHigh;
+ unsigned long nFileIndexLow;
+ //This reference count counts the number of modules attached
+ //to the shared memory and lock file. This serves to unlink
+ //the locking file and shared memory when all modules are
+ //done with the global memory (shared memory)
+ volatile boost::uint32_t modules_attached_to_gmem_count;
+};
+
+inline bool lock_locking_file(int fd)
+{
+ int ret = 0;
+ while(ret != 0 && errno == EDEADLK){
+ ret = _locking(fd, _LK_LOCK, 1/*lock_file_contents_length()*/);
+ }
+ return 0 == ret;
+}
+
+inline bool try_lock_locking_file(int fd)
+{
+ return 0 == _locking(fd, _LK_NBLCK , 1);
+}
+
+inline int open_or_create_and_lock_file(const char *name)
+{
+ permissions p;
+ p.set_unrestricted();
+ while(1){
+ file_handle_t handle = create_or_open_file(name, read_write, p);
+ int fd = _open_osfhandle((intptr_t)handle, _O_TEXT);
+ if(fd < 0){
+ close_file(handle);
+ return fd;
+ }
+ if(!try_lock_locking_file(fd)){
+ _close(fd);
+ return -1;
+ }
+ struct _stat s;
+ if(0 == _stat(name, &s)){
+ return fd;
+ }
+ else{
+ _close(fd);
+ }
+ }
+}
+
+inline int try_open_and_lock_file(const char *name)
+{
+ file_handle_t handle = open_existing_file(name, read_write);
+ int fd = _open_osfhandle((intptr_t)handle, _O_TEXT);
+ if(fd < 0){
+ close_file(handle);
+ return fd;
+ }
+ if(!try_lock_locking_file(fd)){
+ _close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+inline void close_lock_file(int fd)
+{ _close(fd); }
+
+inline bool is_valid_fd(int fd)
+{
+ struct _stat s;
+ return EBADF != _fstat(fd, &s);
+}
+
+inline bool is_normal_file(int fd)
+{
+ if(_isatty(fd))
+ return false;
+ struct _stat s;
+ if(0 != _fstat(fd, &s))
+ return false;
+ return 0 != (s.st_mode & _S_IFREG);
+}
+
+inline std::size_t get_size(int fd)
+{
+ struct _stat s;
+ if(0 != _fstat(fd, &s))
+ return 0u;
+ return (std::size_t)s.st_size;
+}
+
+inline bool fill_file_serial_id(int fd, locking_file_serial_id &id)
+{
+ winapi::interprocess_by_handle_file_information info;
+ if(!winapi::get_file_information_by_handle((void*)_get_osfhandle(fd), &info))
+ return false;
+ id.fd = fd;
+ id.dwVolumeSerialNumber = info.dwVolumeSerialNumber;
+ id.nFileIndexHigh = info.nFileIndexHigh;
+ id.nFileIndexLow = info.nFileIndexLow;
+ id.modules_attached_to_gmem_count = 1; //Initialize attached count
+ return true;
+}
+
+inline bool compare_file_serial(int fd, const locking_file_serial_id &id)
+{
+ winapi::interprocess_by_handle_file_information info;
+ if(!winapi::get_file_information_by_handle((void*)_get_osfhandle(fd), &info))
+ return false;
+
+ return id.dwVolumeSerialNumber == info.dwVolumeSerialNumber &&
+ id.nFileIndexHigh == info.nFileIndexHigh &&
+ id.nFileIndexLow == info.nFileIndexLow;
+}
+
+#else //UNIX
+
+struct locking_file_serial_id
+{
+ int fd;
+ dev_t st_dev;
+ ino_t st_ino;
+ //This reference count counts the number of modules attached
+ //to the shared memory and lock file. This serves to unlink
+ //the locking file and shared memory when all modules are
+ //done with the global memory (shared memory)
+ volatile boost::uint32_t modules_attached_to_gmem_count;
+};
+
+inline bool lock_locking_file(int fd)
+{
+ int ret = 0;
+ while(ret != 0 && errno != EINTR){
+ struct flock lock;
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0;
+ lock.l_len = 1;
+ ret = fcntl (fd, F_SETLKW, &lock);
+ }
+ return 0 == ret;
+}
+
+inline bool try_lock_locking_file(int fd)
+{
+ struct flock lock;
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0;
+ lock.l_len = 1;
+ return 0 == fcntl (fd, F_SETLK, &lock);
+}
+
+inline int open_or_create_and_lock_file(const char *name)
+{
+ permissions p;
+ p.set_unrestricted();
+ while(1){
+ int fd = create_or_open_file(name, read_write, p);
+ if(fd < 0){
+ return fd;
+ }
+ if(!try_lock_locking_file(fd)){
+ close(fd);
+ return -1;
+ }
+ struct stat s;
+ if(0 == stat(name, &s)){
+ return fd;
+ }
+ else{
+ close(fd);
+ }
+ }
+}
+
+inline int try_open_and_lock_file(const char *name)
+{
+ int fd = open_existing_file(name, read_write);
+ if(fd < 0){
+ return fd;
+ }
+ if(!try_lock_locking_file(fd)){
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+inline void close_lock_file(int fd)
+{ close(fd); }
+
+inline bool is_valid_fd(int fd)
+{
+ struct stat s;
+ return EBADF != fstat(fd, &s);
+}
+
+inline bool is_normal_file(int fd)
+{
+ struct stat s;
+ if(0 != fstat(fd, &s))
+ return false;
+ return 0 != (s.st_mode & S_IFREG);
+}
+
+inline std::size_t get_size(int fd)
+{
+ struct stat s;
+ if(0 != fstat(fd, &s))
+ return 0u;
+ return (std::size_t)s.st_size;
+}
+
+inline bool fill_file_serial_id(int fd, locking_file_serial_id &id)
+{
+ struct stat s;
+ if(0 != fstat(fd, &s))
+ return false;
+ id.fd = fd;
+ id.st_dev = s.st_dev;
+ id.st_ino = s.st_ino;
+ id.modules_attached_to_gmem_count = 1; //Initialize attached count
+ return true;
+}
+
+inline bool compare_file_serial(int fd, const locking_file_serial_id &id)
+{
+ struct stat info;
+ if(0 != fstat(fd, &info))
+ return false;
+
+ return id.st_dev == info.st_dev &&
+ id.st_ino == info.st_ino;
+}
+
+#endif
+
+} //namespace ipcdetail{
+} //namespace interprocess{
+} //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_FILE_LOCKING_HELPERS_HPP
diff --git a/boost/interprocess/detail/file_wrapper.hpp b/boost/interprocess/detail/file_wrapper.hpp
index 7b53f36ac8..586e20db4d 100644
--- a/boost/interprocess/detail/file_wrapper.hpp
+++ b/boost/interprocess/detail/file_wrapper.hpp
@@ -44,13 +44,13 @@ class file_wrapper
file_wrapper(open_or_create_t, const char *name, mode_t mode, const permissions &perm = permissions())
{ this->priv_open_or_create(ipcdetail::DoOpenOrCreate, name, mode, perm); }
- //!Tries to open a file with name "name", with the access mode "mode".
+ //!Tries to open a file with name "name", with the access mode "mode".
//!If the file does not previously exist, it throws an error.
file_wrapper(open_only_t, const char *name, mode_t mode)
{ this->priv_open_or_create(ipcdetail::DoOpen, name, mode, permissions()); }
- //!Moves the ownership of "moved"'s file to *this.
- //!After the call, "moved" does not represent any file.
+ //!Moves the ownership of "moved"'s file to *this.
+ //!After the call, "moved" does not represent any file.
//!Does not throw
file_wrapper(BOOST_RV_REF(file_wrapper) moved)
: m_handle(file_handle_t(ipcdetail::invalid_file()))
@@ -60,10 +60,10 @@ class file_wrapper
//!After the call, "moved" does not represent any file.
//!Does not throw
file_wrapper &operator=(BOOST_RV_REF(file_wrapper) moved)
- {
+ {
file_wrapper tmp(boost::move(moved));
this->swap(tmp);
- return *this;
+ return *this;
}
//!Swaps to file_wrappers.
@@ -73,7 +73,7 @@ class file_wrapper
//!Erases a file from the system.
//!Returns false on error. Never throws
static bool remove(const char *name);
-
+
//!Sets the size of the file
void truncate(offset_t length);
@@ -108,11 +108,11 @@ class file_wrapper
std::string m_filename;
};
-inline file_wrapper::file_wrapper()
+inline file_wrapper::file_wrapper()
: m_handle(file_handle_t(ipcdetail::invalid_file()))
{}
-inline file_wrapper::~file_wrapper()
+inline file_wrapper::~file_wrapper()
{ this->priv_close(); }
inline const char *file_wrapper::get_name() const
@@ -122,10 +122,10 @@ inline bool file_wrapper::get_size(offset_t &size) const
{ return get_file_size((file_handle_t)m_handle, size); }
inline void file_wrapper::swap(file_wrapper &other)
-{
+{
std::swap(m_handle, other.m_handle);
std::swap(m_mode, other.m_mode);
- m_filename.swap(other.m_filename);
+ m_filename.swap(other.m_filename);
}
inline mapping_handle_t file_wrapper::get_mapping_handle() const
@@ -135,7 +135,7 @@ inline mode_t file_wrapper::get_mode() const
{ return m_mode; }
inline bool file_wrapper::priv_open_or_create
- (ipcdetail::create_enum_t type,
+ (ipcdetail::create_enum_t type,
const char *filename,
mode_t mode,
const permissions &perm = permissions())
diff --git a/boost/interprocess/detail/in_place_interface.hpp b/boost/interprocess/detail/in_place_interface.hpp
index 0e69452a40..b43b2ce165 100644
--- a/boost/interprocess/detail/in_place_interface.hpp
+++ b/boost/interprocess/detail/in_place_interface.hpp
@@ -25,7 +25,7 @@
//!Describes an abstract interface for placement construction and destruction.
namespace boost {
-namespace interprocess {
+namespace interprocess {
namespace ipcdetail {
struct in_place_interface
diff --git a/boost/interprocess/detail/intermodule_singleton.hpp b/boost/interprocess/detail/intermodule_singleton.hpp
index 4bffbe9d4e..054322699d 100644
--- a/boost/interprocess/detail/intermodule_singleton.hpp
+++ b/boost/interprocess/detail/intermodule_singleton.hpp
@@ -18,1163 +18,27 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-#include <boost/interprocess/windows_shared_memory.hpp>
-#endif
-
-#include <boost/interprocess/shared_memory_object.hpp>
-
-#include <boost/interprocess/offset_ptr.hpp>
-#include <boost/interprocess/sync/spin/mutex.hpp>
-#include <boost/interprocess/sync/spin/recursive_mutex.hpp>
-#include <boost/interprocess/detail/managed_memory_impl.hpp>
-#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
-#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
-#include <boost/interprocess/indexes/iset_index.hpp>
-#include <boost/interprocess/creation_tags.hpp>
-#include <boost/interprocess/permissions.hpp>
-
-
-#include <boost/interprocess/detail/atomic.hpp>
-#include <boost/interprocess/detail/os_thread_functions.hpp>
-#include <boost/interprocess/detail/tmp_dir_helpers.hpp>
-#include <boost/interprocess/detail/os_file_functions.hpp>
-#include <boost/interprocess/detail/mpl.hpp>
-#include <boost/type_traits/type_with_alignment.hpp>
-#include <boost/assert.hpp>
-#include <cstddef>
-#include <cstdio>
-#include <cstring>
-#include <string>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-#include <fcntl.h>
-#include <io.h>
-
-#include <sys/locking.h>
-#else
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <unistd.h>
+#ifdef BOOST_INTERPROCESS_WINDOWS
+ #include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
#endif
+#include <boost/interprocess/detail/portable_intermodule_singleton.hpp>
namespace boost{
namespace interprocess{
namespace ipcdetail{
-struct intermodule_singleton_mutex_family
-{
- typedef boost::interprocess::ipcdetail::spin_mutex mutex_type;
- typedef boost::interprocess::ipcdetail::spin_recursive_mutex recursive_mutex_type;
-};
-
-struct intermodule_types
-{
- //We must use offset_ptr since a loaded DLL can map the singleton holder shared memory
- //at a different address than other DLLs/main executables
- typedef rbtree_best_fit<intermodule_singleton_mutex_family, offset_ptr<void> > mem_algo;
- template<class Device, bool FileBased>
- struct open_or_create
- {
- typedef managed_open_or_create_impl
- <Device, mem_algo::Alignment, FileBased> type;
- };
-};
-
-template<class Device, bool FileBased>
-class basic_managed_global_memory
- : public basic_managed_memory_impl
- < char
- , intermodule_types::mem_algo
- , iset_index
- , intermodule_types::open_or_create<Device, FileBased>::type::ManagedOpenOrCreateUserOffset
- >
- , private intermodule_types::open_or_create<Device, FileBased>::type
-{
- /// @cond
- typedef typename intermodule_types::template open_or_create<Device, FileBased>::type base2_t;
-
- typedef basic_managed_memory_impl
- < char
- , intermodule_types::mem_algo
- , iset_index
- , base2_t::ManagedOpenOrCreateUserOffset
- > base_t;
-
- typedef create_open_func<base_t> create_open_func_t;
-
- basic_managed_global_memory *get_this_pointer()
- { return this; }
-
- public:
- typedef typename base_t::size_type size_type;
-
- private:
- typedef typename base_t::char_ptr_holder_t char_ptr_holder_t;
- BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_managed_global_memory)
- /// @endcond
-
- public: //functions
-/*
- basic_managed_global_memory()
- {}
-
- basic_managed_global_memory(create_only_t create_only, const char *name,
- size_type size, const void *addr = 0, const permissions& perm = permissions())
- : base_t()
- , base2_t(create_only, name, size, read_write, addr,
- create_open_func_t(get_this_pointer(), DoCreate), perm)
- {}
-*/
- basic_managed_global_memory (open_or_create_t open_or_create,
- const char *name, size_type size,
- const void *addr = 0, const permissions& perm = permissions())
- : base_t()
- , base2_t(open_or_create, name, size, read_write, addr,
- create_open_func_t(get_this_pointer(),
- DoOpenOrCreate), perm)
- {}
-
- basic_managed_global_memory (open_only_t open_only, const char* name,
- const void *addr = 0)
- : base_t()
- , base2_t(open_only, name, read_write, addr,
- create_open_func_t(get_this_pointer(),
- DoOpen))
- {}
-
-/*
- basic_managed_global_memory (open_copy_on_write_t, const char* name,
- const void *addr = 0)
- : base_t()
- , base2_t(open_only, name, copy_on_write, addr,
- create_open_func_t(get_this_pointer(),
- DoOpen))
- {}
-
- //!Connects to a created shared memory and its segment manager.
- //!in read-only mode.
- //!This can throw.
- basic_managed_global_memory (open_read_only_t, const char* name,
- const void *addr = 0)
- : base_t()
- , base2_t(open_only, name, read_only, addr,
- create_open_func_t(get_this_pointer(),
- DoOpen))
- {}
-
- //!Moves the ownership of "moved"'s managed memory to *this.
- //!Does not throw
- basic_managed_global_memory(BOOST_RV_REF(basic_managed_global_memory) moved)
- {
- basic_managed_global_memory tmp;
- this->swap(moved);
- tmp.swap(moved);
- }
-
- //!Moves the ownership of "moved"'s managed memory to *this.
- //!Does not throw
- basic_managed_global_memory &operator=(BOOST_RV_REF(basic_managed_global_memory) moved)
- {
- basic_managed_global_memory tmp(boost::move(moved));
- this->swap(tmp);
- return *this;
- }*/
-};
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-typedef basic_managed_global_memory<windows_shared_memory, false> windows_managed_global_memory;
-#endif
-
-typedef basic_managed_global_memory<shared_memory_object, true> managed_global_memory;
-
-namespace file_locking_helpers {
-
-inline void get_pid_creation_time_str(std::string &s)
-{
- std::stringstream stream;
- stream << get_current_process_id() << '_';
- stream.precision(6);
- stream << std::fixed << get_current_process_creation_time();
- s = stream.str();
-}
-
-inline void create_tmp_subdir_and_get_pid_based_filepath(const char *subdir_name, const char *file_prefix, OS_process_id_t pid, std::string &s, bool creation_time = false)
-{
- //Let's create a lock file for each process gmem that will mark if
- //the process is alive or not
- create_tmp_and_clean_old(s);
- s += "/";
- s += subdir_name;
- if(!open_or_create_directory(s.c_str())){
- throw interprocess_exception(error_info(system_error_code()));
- }
- s += "/";
- s += file_prefix;
- if(creation_time){
- std::string sstamp;
- get_pid_creation_time_str(sstamp);
- s += sstamp;
- }
- else{
- pid_str_t pid_str;
- get_pid_str(pid_str, pid);
- s += pid_str;
- }
-}
-
-inline bool check_if_filename_complies_with_pid
- (const char *filename, const char *prefix, OS_process_id_t pid, std::string &file_suffix, bool creation_time = false)
-{
- //Check if filename complies with lock file name pattern
- std::string fname(filename);
- std::string fprefix(prefix);
- if(fname.size() <= fprefix.size()){
- return false;
- }
- fname.resize(fprefix.size());
- if(fname != fprefix){
- return false;
- }
-
- //If not our lock file, delete it if we can lock it
- fname = filename;
- fname.erase(0, fprefix.size());
- pid_str_t pid_str;
- get_pid_str(pid_str, pid);
- file_suffix = pid_str;
- if(creation_time){
- std::size_t p = fname.find('_');
- if (p == std::string::npos){
- return false;
- }
- std::string save_suffix(fname);
- fname.erase(p);
- fname.swap(file_suffix);
- bool ret = (file_suffix == fname);
- file_suffix.swap(save_suffix);
- return ret;
- }
- else{
- fname.swap(file_suffix);
- return (file_suffix == fname);
- }
-}
-
-} //file_locking_helpers
-
-namespace intermodule_singleton_helpers {
-
-const int GMemMarkToBeRemoved = -1;
-const int GMemNotPresent = -2;
-
-inline const char *get_lock_file_subdir_name()
-{ return "gmem"; }
-
-inline const char *get_lock_file_base_name()
-{ return "lck"; }
-
-inline void create_and_get_singleton_lock_file_path(std::string &s)
-{
- file_locking_helpers::create_tmp_subdir_and_get_pid_based_filepath
- (get_lock_file_subdir_name(), get_lock_file_base_name(), get_current_process_id(), s, true);
-}
-
-inline const char *get_shm_base_name()
-{ return "bip.gmem.shm."; }
-
-inline void get_shm_name(std::string &shm_name)
-{
- file_locking_helpers::get_pid_creation_time_str(shm_name);
- shm_name.insert(0, get_shm_base_name());
-}
-
-inline std::size_t get_shm_size()
-{ return 65536; }
-
-template<class ManagedShMem>
-struct managed_sh_dependant
-{
- static void apply_gmem_erase_logic(const char *filepath, const char *filename);
-
- static bool remove_old_gmem()
- {
- std::string refcstrRootDirectory;
- tmp_folder(refcstrRootDirectory);
- refcstrRootDirectory += "/";
- refcstrRootDirectory += get_lock_file_subdir_name();
- return for_each_file_in_dir(refcstrRootDirectory.c_str(), apply_gmem_erase_logic);
- }
-};
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-
-template<>
-struct managed_sh_dependant<windows_managed_global_memory>
-{
- static void apply_gmem_erase_logic(const char *, const char *){}
-
- static bool remove_old_gmem()
- { return true; }
-};
-
-
-struct locking_file_serial_id
-{
- int fd;
- unsigned long dwVolumeSerialNumber;
- unsigned long nFileIndexHigh;
- unsigned long nFileIndexLow;
- //This reference count counts the number of modules attached
- //to the shared memory and lock file. This serves to unlink
- //the locking file and shared memory when all modules are
- //done with the global memory (shared memory)
- volatile boost::uint32_t modules_attached_to_gmem_count;
-};
-
-inline bool lock_locking_file(int fd)
-{
- int ret = 0;
- while(ret != 0 && errno == EDEADLK){
- ret = _locking(fd, _LK_LOCK, 1/*lock_file_contents_length()*/);
- }
- return 0 == ret;
-}
-
-inline bool try_lock_locking_file(int fd)
-{
- return 0 == _locking(fd, _LK_NBLCK , 1);
-}
-
-inline int open_or_create_and_lock_file(const char *name)
-{
- permissions p;
- p.set_unrestricted();
- while(1){
- file_handle_t handle = create_or_open_file(name, read_write, p);
- int fd = _open_osfhandle((intptr_t)handle, _O_TEXT);
- if(fd < 0){
- close_file(handle);
- return fd;
- }
- if(!try_lock_locking_file(fd)){
- _close(fd);
- return -1;
- }
- struct _stat s;
- if(0 == _stat(name, &s)){
- return fd;
- }
- else{
- _close(fd);
- }
- }
-}
-
-inline int try_open_and_lock_file(const char *name)
-{
- file_handle_t handle = open_existing_file(name, read_write);
- int fd = _open_osfhandle((intptr_t)handle, _O_TEXT);
- if(fd < 0){
- close_file(handle);
- return fd;
- }
- if(!try_lock_locking_file(fd)){
- _close(fd);
- return -1;
- }
- return fd;
-}
-
-inline void close_lock_file(int fd)
-{ _close(fd); }
-
-inline bool is_valid_fd(int fd)
-{
- struct _stat s;
- return EBADF != _fstat(fd, &s);
-}
-
-inline bool is_normal_file(int fd)
-{
- if(_isatty(fd))
- return false;
- struct _stat s;
- if(0 != _fstat(fd, &s))
- return false;
- return 0 != (s.st_mode & _S_IFREG);
-}
-
-inline std::size_t get_size(int fd)
-{
- struct _stat s;
- if(0 != _fstat(fd, &s))
- return 0u;
- return (std::size_t)s.st_size;
-}
-
-inline bool fill_file_serial_id(int fd, locking_file_serial_id &id)
-{
- winapi::interprocess_by_handle_file_information info;
- if(!winapi::get_file_information_by_handle((void*)_get_osfhandle(fd), &info))
- return false;
- id.fd = fd;
- id.dwVolumeSerialNumber = info.dwVolumeSerialNumber;
- id.nFileIndexHigh = info.nFileIndexHigh;
- id.nFileIndexLow = info.nFileIndexLow;
- id.modules_attached_to_gmem_count = 1; //Initialize attached count
- return true;
-}
-
-inline bool compare_file_serial(int fd, const locking_file_serial_id &id)
-{
- winapi::interprocess_by_handle_file_information info;
- if(!winapi::get_file_information_by_handle((void*)_get_osfhandle(fd), &info))
- return false;
-
- return id.dwVolumeSerialNumber == info.dwVolumeSerialNumber &&
- id.nFileIndexHigh == info.nFileIndexHigh &&
- id.nFileIndexLow == info.nFileIndexLow;
-}
-
-#else //UNIX
-
-struct locking_file_serial_id
-{
- int fd;
- dev_t st_dev;
- ino_t st_ino;
- //This reference count counts the number of modules attached
- //to the shared memory and lock file. This serves to unlink
- //the locking file and shared memory when all modules are
- //done with the global memory (shared memory)
- volatile boost::uint32_t modules_attached_to_gmem_count;
-};
-
-inline bool lock_locking_file(int fd)
-{
- int ret = 0;
- while(ret != 0 && errno != EINTR){
- struct flock lock;
- lock.l_type = F_WRLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = 0;
- lock.l_len = 1;
- ret = fcntl (fd, F_SETLKW, &lock);
- }
- return 0 == ret;
-}
-
-inline bool try_lock_locking_file(int fd)
-{
- struct flock lock;
- lock.l_type = F_WRLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = 0;
- lock.l_len = 1;
- return 0 == fcntl (fd, F_SETLK, &lock);
-}
-
-inline int open_or_create_and_lock_file(const char *name)
-{
- permissions p;
- p.set_unrestricted();
- while(1){
- int fd = create_or_open_file(name, read_write, p);
- if(fd < 0){
- return fd;
- }
- if(!try_lock_locking_file(fd)){
- close(fd);
- return -1;
- }
- struct stat s;
- if(0 == stat(name, &s)){
- return fd;
- }
- else{
- close(fd);
- }
- }
-}
-
-inline int try_open_and_lock_file(const char *name)
-{
- int fd = open_existing_file(name, read_write);
- if(fd < 0){
- return fd;
- }
- if(!try_lock_locking_file(fd)){
- close(fd);
- return -1;
- }
- return fd;
-}
-
-inline void close_lock_file(int fd)
-{ close(fd); }
-
-inline bool is_valid_fd(int fd)
-{
- struct stat s;
- return EBADF != fstat(fd, &s);
-}
-
-inline bool is_normal_file(int fd)
-{
- struct stat s;
- if(0 != fstat(fd, &s))
- return false;
- return 0 != (s.st_mode & S_IFREG);
-}
-
-inline std::size_t get_size(int fd)
-{
- struct stat s;
- if(0 != fstat(fd, &s))
- return 0u;
- return (std::size_t)s.st_size;
-}
-
-inline bool fill_file_serial_id(int fd, locking_file_serial_id &id)
-{
- struct stat s;
- if(0 != fstat(fd, &s))
- return false;
- id.fd = fd;
- id.st_dev = s.st_dev;
- id.st_ino = s.st_ino;
- id.modules_attached_to_gmem_count = 1; //Initialize attached count
- return true;
-}
-
-inline bool compare_file_serial(int fd, const locking_file_serial_id &id)
-{
- struct stat info;
- if(0 != fstat(fd, &info))
- return false;
-
- return id.st_dev == info.st_dev &&
- id.st_ino == info.st_ino;
-}
-
-#endif
-
-template<class ManagedShMem>
-struct gmem_erase_func
-{
- gmem_erase_func(const char *shm_name, const char *singleton_lock_file_path, ManagedShMem & shm)
- :shm_name_(shm_name), singleton_lock_file_path_(singleton_lock_file_path), shm_(shm)
- {}
-
- void operator()()
- {
- locking_file_serial_id *pserial_id = shm_.template find<locking_file_serial_id>("lock_file_fd").first;
- if(pserial_id){
- pserial_id->fd = GMemMarkToBeRemoved;
- }
- delete_file(singleton_lock_file_path_);
- shared_memory_object::remove(shm_name_);
- }
-
- const char * const shm_name_;
- const char * const singleton_lock_file_path_;
- ManagedShMem & shm_;
-};
-
-//This function applies shared memory erasure logic based on the passed lock file.
-template<class ManagedShMem>
-void managed_sh_dependant<ManagedShMem>::
- apply_gmem_erase_logic(const char *filepath, const char *filename)
-{
- int fd = GMemMarkToBeRemoved;
- try{
- std::string str;
- //If the filename is current process lock file, then avoid it
- if(file_locking_helpers::check_if_filename_complies_with_pid
- (filename, get_lock_file_base_name(), get_current_process_id(), str, true)){
- return;
- }
- //Open and lock the other process' lock file
- fd = try_open_and_lock_file(filepath);
- if(fd < 0){
- return;
- }
- //If done, then the process is dead so take global shared memory name
- //(the name is based on the lock file name) and try to apply erasure logic
- str.insert(0, get_shm_base_name());
- try{
- ManagedShMem shm(open_only, str.c_str());
- gmem_erase_func<ManagedShMem> func(str.c_str(), filepath, shm);
- shm.try_atomic_func(func);
- }
- catch(interprocess_exception &e){
- //If shared memory is not found erase the lock file
- if(e.get_error_code() == not_found_error){
- delete_file(filepath);
- }
- }
- }
- catch(...){
-
- }
- if(fd >= 0){
- close_lock_file(fd);
- }
-}
-
-} //namespace intermodule_singleton_helpers {
-
-
-
-namespace intermodule_singleton_helpers {
-
-//The lock file logic creates uses a unique instance to a file
-template <class ManagedShMem>
-struct lock_file_logic
-{
- lock_file_logic(ManagedShMem &shm)
- : mshm(shm)
- { shm.atomic_func(*this); }
-
- void operator()(void)
- {
- retry_with_new_shm = false;
-
- //First find the file locking descriptor id
- locking_file_serial_id *pserial_id =
- mshm.template find<locking_file_serial_id>("lock_file_fd").first;
-
- int fd;
- //If not found schedule a creation
- if(!pserial_id){
- fd = GMemNotPresent;
- }
- //Else get it
- else{
- fd = pserial_id->fd;
- }
- //If we need to create a new one, do it
- if(fd == GMemNotPresent){
- std::string lck_str;
- //Create a unique current pid based lock file path
- create_and_get_singleton_lock_file_path(lck_str);
- //Open or create and lock file
- int fd = intermodule_singleton_helpers::open_or_create_and_lock_file(lck_str.c_str());
- //If failed, write a bad file descriptor to notify other modules that
- //something was wrong and unlink shared memory. Mark the function object
- //to tell caller to retry with another shared memory
- if(fd < 0){
- this->register_lock_file(GMemMarkToBeRemoved);
- std::string s;
- get_shm_name(s);
- shared_memory_object::remove(s.c_str());
- retry_with_new_shm = true;
- }
- //If successful, register the file descriptor
- else{
- this->register_lock_file(fd);
- }
- }
- //If the fd was invalid (maybe a previous try failed) notify caller that
- //should retry creation logic, since this shm might have been already
- //unlinked since the shm was removed
- else if (fd == GMemMarkToBeRemoved){
- retry_with_new_shm = true;
- }
- //If the stored fd is not valid (a open fd, a normal file with the
- //expected size, or does not have the same file id number,
- //then it's an old shm from an old process with the same pid.
- //If that's the case, mark it as invalid
- else if(!is_valid_fd(fd) ||
- !is_normal_file(fd) ||
- 0 != get_size(fd) ||
- !compare_file_serial(fd, *pserial_id)){
- pserial_id->fd = GMemMarkToBeRemoved;
- std::string s;
- get_shm_name(s);
- shared_memory_object::remove(s.c_str());
- retry_with_new_shm = true;
- }
- else{
- //If the lock file is ok, increment reference count of
- //attached modules to shared memory
- atomic_inc32(&pserial_id->modules_attached_to_gmem_count);
- }
- }
-
- private:
- locking_file_serial_id * register_lock_file(int fd)
- {
- locking_file_serial_id *pinfo = mshm.template construct<locking_file_serial_id>("lock_file_fd")();
- fill_file_serial_id(fd, *pinfo);
- return pinfo;
- }
-
- public:
- ManagedShMem &mshm;
- bool retry_with_new_shm;
-};
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-
-template<>
-struct lock_file_logic<windows_managed_global_memory>
-{
- lock_file_logic(windows_managed_global_memory &)
- : retry_with_new_shm(false)
- {}
-
- void operator()(void){}
- const bool retry_with_new_shm;
-};
-
-#endif
-
-} //namespace intermodule_singleton_helpers {
-
-//This class contains common code for all singleton types, so that we instantiate this
-//code just once per module. This class also holds a reference counted shared memory
-//to be used by all instances
-
-template<class ManagedShMem>
-class intermodule_singleton_common
-{
- public:
- typedef void*(singleton_constructor_t)(ManagedShMem &);
- typedef void (singleton_destructor_t)(void *, ManagedShMem &);
-
- static const ::boost::uint32_t Uninitialized = 0u;
- static const ::boost::uint32_t Initializing = 1u;
- static const ::boost::uint32_t Initialized = 2u;
- static const ::boost::uint32_t Broken = 3u;
-
- static void finalize_singleton_logic(void *ptr, singleton_destructor_t destructor)
- {
- if(ptr)
- destructor(ptr, get_shm());
- //If this is the last singleton of this module
- //apply shm destruction.
- //Note: singletons are destroyed when the module is unloaded
- //so no threads should be executing or holding references
- //to this module
- if(1 == atomic_dec32(&this_module_singleton_count)){
- destroy_shm();
- }
- }
-
- static void initialize_singleton_logic
- (void *&ptr, volatile boost::uint32_t &this_module_singleton_initialized, singleton_constructor_t ini_func);
-
- private:
- static ManagedShMem &get_shm()
- {
- return *static_cast<ManagedShMem *>(static_cast<void *>(&mem_holder.shm_mem));
- }
-
- static void initialize_shm();
- static void destroy_shm();
- //Static data, zero-initalized without any dependencies
- //this_module_singleton_count is the number of singletons used by this module
- static volatile boost::uint32_t this_module_singleton_count;
- //this_module_shm_initialized is the state of this module's shm class object
- static volatile boost::uint32_t this_module_shm_initialized;
- static struct mem_holder_t
- {
- ::boost::detail::max_align aligner;
- char shm_mem [sizeof(ManagedShMem)];
- } mem_holder;
-};
-
-template<class ManagedShMem>
-volatile boost::uint32_t intermodule_singleton_common<ManagedShMem>::this_module_singleton_count;
-
-template<class ManagedShMem>
-volatile boost::uint32_t intermodule_singleton_common<ManagedShMem>::this_module_shm_initialized;
-
-template<class ManagedShMem>
-typename intermodule_singleton_common<ManagedShMem>::mem_holder_t
- intermodule_singleton_common<ManagedShMem>::mem_holder;
-
-template<class ManagedShMem>
-void intermodule_singleton_common<ManagedShMem>::initialize_shm()
-{
- //Obtain unique shm name and size
- std::string s;
- while(1){
- //Try to pass shm state to initializing
- ::boost::uint32_t tmp = atomic_cas32(&this_module_shm_initialized, Initializing, Uninitialized);
- if(tmp >= Initialized){
- break;
- }
- //If some other thread is doing the work wait
- else if(tmp == Initializing){
- thread_yield();
- }
- else{ //(tmp == Uninitialized)
- //If not initialized try it again?
- try{
- //Remove old shared memory from the system
- intermodule_singleton_helpers::managed_sh_dependant<ManagedShMem>::remove_old_gmem();
- //
- if(s.empty()){
- intermodule_singleton_helpers::get_shm_name(s);
- }
- const char *ShmName = s.c_str();
- const std::size_t ShmSize = intermodule_singleton_helpers::get_shm_size();;
-
- //in-place construction of the shared memory class
- ::new (&get_shm())ManagedShMem(open_or_create, ShmName, ShmSize);
- //Use shared memory internal lock to initialize the lock file
- //that will mark this gmem as "in use".
- intermodule_singleton_helpers::lock_file_logic<ManagedShMem> f(get_shm());
- //If function failed (maybe a competing process has erased the shared
- //memory between creation and file locking), retry with a new instance.
- if(f.retry_with_new_shm){
- get_shm().~ManagedShMem();
- atomic_write32(&this_module_shm_initialized, Uninitialized);
- }
- else{
- //Locking succeeded, so this shared memory module-instance is ready
- atomic_write32(&this_module_shm_initialized, Initialized);
- break;
- }
- }
- catch(...){
- //
- throw;
- }
- }
- }
-}
-
-template<class ManagedShMem>
-struct unlink_shmlogic
-{
- unlink_shmlogic(ManagedShMem &mshm)
- : mshm_(mshm)
- { mshm.atomic_func(*this); }
- void operator()()
- {
- intermodule_singleton_helpers::locking_file_serial_id *pserial_id =
- mshm_.template find<intermodule_singleton_helpers::locking_file_serial_id>
- ("lock_file_fd").first;
- BOOST_ASSERT(0 != pserial_id);
- if(1 == atomic_dec32(&pserial_id->modules_attached_to_gmem_count)){
- int fd = pserial_id->fd;
- if(fd > 0){
- pserial_id->fd = intermodule_singleton_helpers::GMemMarkToBeRemoved;
- std::string s;
- intermodule_singleton_helpers::create_and_get_singleton_lock_file_path(s);
- delete_file(s.c_str());
- intermodule_singleton_helpers::close_lock_file(fd);
- intermodule_singleton_helpers::get_shm_name(s);
- shared_memory_object::remove(s.c_str());
- }
- }
- }
- ManagedShMem &mshm_;
-};
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-
-template<>
-struct unlink_shmlogic<windows_managed_global_memory>
-{
- unlink_shmlogic(windows_managed_global_memory &)
- {}
- void operator()(){}
-};
-
-#endif
-
-
-template<class ManagedShMem>
-void intermodule_singleton_common<ManagedShMem>::destroy_shm()
-{
- if(!atomic_read32(&this_module_singleton_count)){
- //This module is being unloaded, so destroy
- //the shared memory object of this module
- //and unlink the shared memory if it's the last
- unlink_shmlogic<ManagedShMem> f(get_shm());
- (get_shm()).~ManagedShMem();
- atomic_write32(&this_module_shm_initialized, Uninitialized);
- //Do some cleanup for other processes old gmem instances
- intermodule_singleton_helpers::managed_sh_dependant<ManagedShMem>::remove_old_gmem();
- }
-}
-
-//Initialize this_module_singleton_ptr, creates the shared memory if needed and also creates an unique
-//opaque type in shared memory through a singleton_constructor_t function call,
-//initializing the passed pointer to that unique instance.
-//
-//We have two concurrency types here. a)the shared memory/singleton creation must
-//be safe between threads of this process but in different modules/dlls. b)
-//the pointer to the singleton is per-module, so we have to protect this
-//initization between threads of the same module.
-//
-//All static variables declared here are shared between inside a module
-//so atomic operations will synchronize only threads of the same module.
-template<class ManagedShMem>
-void intermodule_singleton_common<ManagedShMem>::initialize_singleton_logic
- (void *&ptr, volatile boost::uint32_t &this_module_singleton_initialized, singleton_constructor_t constructor)
-{
- //If current module is not initialized enter to lock free logic
- if(atomic_read32(&this_module_singleton_initialized) != Initialized){
- //Now a single thread of the module will succeed in this CAS.
- //trying to pass from Uninitialized to Initializing
- ::boost::uint32_t previous_module_singleton_initialized = atomic_cas32
- (&this_module_singleton_initialized, Initializing, Uninitialized);
- //If the thread succeeded the CAS (winner) it will compete with other
- //winner threads from other modules to create the shared memory
- if(previous_module_singleton_initialized == Uninitialized){
- try{
- //Now initialize shm, this function solves concurrency issues
- //between threads of several modules
- initialize_shm();
- //Increment the module reference count that reflects how many
- //singletons this module holds, so that we can safely destroy
- //module shared memory object when no singleton is left
- atomic_inc32(&this_module_singleton_count);
- //Now try to create the singleton in shared memory.
- //This function solves concurrency issues
- //between threads of several modules
- void *tmp = constructor(get_shm());
- //Insert a barrier before assigning the pointer to
- //make sure this assignment comes after the initialization
- atomic_write32(&this_module_singleton_initialized, Initializing);
- //Assign the singleton address to the module-local pointer
- ptr = tmp;
- //Memory barrier inserted, all previous operations should complete
- //before this one. Now marked as initialized
- atomic_inc32(&this_module_singleton_initialized);
- }
- catch(...){
- //Mark singleton failed to initialize
- atomic_write32(&this_module_singleton_initialized, Broken);
- throw;
- }
- }
- //If previous state was initializing, this means that another winner thread is
- //trying to initialize the singleton. Just wait until completes its work.
- else if(previous_module_singleton_initialized == Initializing){
- while(1){
- previous_module_singleton_initialized = atomic_read32(&this_module_singleton_initialized);
- if(previous_module_singleton_initialized >= Initialized){
- //Already initialized, or exception thrown by initializer thread
- break;
- }
- else if(previous_module_singleton_initialized == Initializing){
- thread_yield();
- }
- else{
- //This can't be happening!
- BOOST_ASSERT(0);
- }
- }
- }
- else if(previous_module_singleton_initialized == Initialized){
- //Nothing to do here, the singleton is ready
- }
- //If previous state was greater than initialized, then memory is broken
- //trying to initialize the singleton.
- else{//(previous_module_singleton_initialized > Initialized)
- throw interprocess_exception("boost::interprocess::intermodule_singleton initialization failed");
- }
- }
- BOOST_ASSERT(ptr != 0);
-}
-
-//Now this class is a singleton, initializing the singleton in
-//the first get() function call if LazyInit is false. If true
-//then the singleton will be initialized when loading the module.
-template<typename C, bool LazyInit, class ManagedShMem>
-class intermodule_singleton_impl
-{
- public:
- static C& get() //Let's make inlining easy
- {
- if(!this_module_singleton_ptr){
- if(lifetime.dummy_function()) //This forces lifetime instantiation, for reference counted destruction
- intermodule_singleton_common<ManagedShMem>::initialize_singleton_logic
- (this_module_singleton_ptr, this_module_singleton_initialized, singleton_constructor);
- }
- return *static_cast<C*>(this_module_singleton_ptr);
- }
-
- private:
-
- struct ref_count_ptr
- {
- ref_count_ptr(C *p, boost::uint32_t count)
- : ptr(p), singleton_ref_count(count)
- {}
- C *ptr;
- //This reference count serves to count the number of attached
- //modules to this singleton
- volatile boost::uint32_t singleton_ref_count;
- };
-
- //These statics will be zero-initialized without any constructor call dependency
- //this_module_singleton_ptr will be a module-local pointer to the singleton
- static void* this_module_singleton_ptr;
- //this_module_singleton_count will be used to synchronize threads of the same module
- //for access to a singleton instance, and to flag the state of the
- //singleton.
- static volatile boost::uint32_t this_module_singleton_initialized;
-
- //This class destructor will trigger singleton destruction
- struct lifetime_type_lazy
- {
- bool dummy_function()
- { return m_dummy == 0; }
-
- ~lifetime_type_lazy()
- {
- intermodule_singleton_common<ManagedShMem>::finalize_singleton_logic
- (this_module_singleton_ptr, singleton_destructor);
- }
- //Dummy volatile so that the compiler can't resolve its value at compile-time
- //and can't avoid lifetime_type instantiation if dummy_function() is called.
- static volatile int m_dummy;
- };
-
- struct lifetime_type_static
- : public lifetime_type_lazy
- {
- lifetime_type_static()
- {
- intermodule_singleton_common<ManagedShMem>::initialize_singleton_logic
- (this_module_singleton_ptr, this_module_singleton_initialized, singleton_constructor);
- }
- };
-
- typedef typename if_c
- <LazyInit, lifetime_type_lazy, lifetime_type_static>::type lifetime_type;
-
- static lifetime_type lifetime;
-
- //A functor to be executed inside shared memory lock that just
- //searches for the singleton in shm and if not present creates a new one.
- //If singleton constructor throws, the exception is propagated
- struct init_atomic_func
- {
- init_atomic_func(ManagedShMem &m)
- : mshm(m)
- {}
-
- void operator()()
- {
- ref_count_ptr *rcount = mshm.template find<ref_count_ptr>(unique_instance).first;
- if(!rcount){
- C *p = new C();
- try{
- rcount = mshm.template construct<ref_count_ptr>(unique_instance)(p, 0u);
- }
- catch(...){
- delete p;
- throw;
- }
- }
- atomic_inc32(&rcount->singleton_ref_count);
- ret_ptr = rcount->ptr;
- }
- ManagedShMem &mshm;
- void *ret_ptr;
- };
-
- //A functor to be executed inside shared memory lock that just
- //deletes the singleton in shm if the attached count reaches to zero
- struct fini_atomic_func
- {
- fini_atomic_func(ManagedShMem &m)
- : mshm(m)
- {}
-
- void operator()()
- {
- ref_count_ptr *rcount = mshm.template find<ref_count_ptr>(unique_instance).first;
- //The object must exist
- BOOST_ASSERT(rcount);
- //Check if last reference
- if(atomic_dec32(&rcount->singleton_ref_count) == 1){
- //If last, destroy the object
- BOOST_ASSERT(rcount->ptr != 0);
- delete rcount->ptr;
- //Now destroy shm entry
- bool destroyed = mshm.template destroy<ref_count_ptr>(unique_instance);
- (void)destroyed; BOOST_ASSERT(destroyed == true);
- }
- }
- ManagedShMem &mshm;
- void *ret_ptr;
- };
-
- //A wrapper to execute init_atomic_func
- static void *singleton_constructor(ManagedShMem &mshm)
- {
- init_atomic_func f(mshm);
- mshm.atomic_func(f);
- return f.ret_ptr;
- }
-
- //A wrapper to execute fini_atomic_func
- static void singleton_destructor(void *p, ManagedShMem &mshm)
- { (void)p;
- fini_atomic_func f(mshm);
- mshm.atomic_func(f);
- }
-};
-
-template <typename C, bool L, class ManagedShMem>
-volatile int intermodule_singleton_impl<C, L, ManagedShMem>::lifetime_type_lazy::m_dummy = 0;
-
-//These will be zero-initialized by the loader
-template <typename C, bool L, class ManagedShMem>
-void *intermodule_singleton_impl<C, L, ManagedShMem>::this_module_singleton_ptr = 0;
-
-template <typename C, bool L, class ManagedShMem>
-volatile boost::uint32_t intermodule_singleton_impl<C, L, ManagedShMem>::this_module_singleton_initialized = 0;
-
-template <typename C, bool L, class ManagedShMem>
-typename intermodule_singleton_impl<C, L, ManagedShMem>::lifetime_type
- intermodule_singleton_impl<C, L, ManagedShMem>::lifetime;
-
-template<typename C, bool LazyInit = false>
-class portable_intermodule_singleton
- : public intermodule_singleton_impl<C, LazyInit, managed_global_memory>
-{};
-
-#if defined(BOOST_INTERPROCESS_WINDOWS)
-
-template<typename C, bool LazyInit = false>
-class windows_intermodule_singleton
- : public intermodule_singleton_impl
- < C
- , LazyInit
- , windows_managed_global_memory
- >
-{};
-
-#endif
-
//Now this class is a singleton, initializing the singleton in
//the first get() function call if LazyInit is false. If true
//then the singleton will be initialized when loading the module.
-template<typename C, bool LazyInit = false>
+template<typename C, bool LazyInit = true, bool Phoenix = true>
class intermodule_singleton
#ifdef BOOST_INTERPROCESS_WINDOWS
- : public windows_intermodule_singleton<C, LazyInit>
+ : public windows_intermodule_singleton<C, LazyInit, Phoenix>
#else
- : public portable_intermodule_singleton<C, LazyInit>
+ : public portable_intermodule_singleton<C, LazyInit, Phoenix>
#endif
{};
-
} //namespace ipcdetail{
} //namespace interprocess{
} //namespace boost{
diff --git a/boost/interprocess/detail/intermodule_singleton_common.hpp b/boost/interprocess/detail/intermodule_singleton_common.hpp
new file mode 100644
index 0000000000..0710c0bbc1
--- /dev/null
+++ b/boost/interprocess/detail/intermodule_singleton_common.hpp
@@ -0,0 +1,495 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009-2011. 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_INTERMODULE_SINGLETON_COMMON_HPP
+#define BOOST_INTERPROCESS_INTERMODULE_SINGLETON_COMMON_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#include <boost/interprocess/detail/atomic.hpp>
+#include <boost/interprocess/detail/os_thread_functions.hpp>
+#include <boost/type_traits/type_with_alignment.hpp>
+#include <boost/interprocess/detail/mpl.hpp>
+#include <boost/assert.hpp>
+#include <cstddef>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <string>
+#include <sstream>
+
+namespace boost{
+namespace interprocess{
+namespace ipcdetail{
+
+namespace intermodule_singleton_helpers {
+
+inline void get_pid_creation_time_str(std::string &s)
+{
+ std::stringstream stream;
+ stream << get_current_process_id() << '_';
+ stream.precision(6);
+ stream << std::fixed << get_current_process_creation_time();
+ s = stream.str();
+}
+
+inline const char *get_map_base_name()
+{ return "bip.gmem.map."; }
+
+inline void get_map_name(std::string &map_name)
+{
+ get_pid_creation_time_str(map_name);
+ map_name.insert(0, get_map_base_name());
+}
+
+inline std::size_t get_map_size()
+{ return 65536; }
+
+template<class ThreadSafeGlobalMap>
+struct thread_safe_global_map_dependant;
+
+} //namespace intermodule_singleton_helpers {
+
+//This class contains common code for all singleton types, so that we instantiate this
+//code just once per module. This class also holds a thread soafe global map
+//to be used by all instances protected with a reference count
+template<class ThreadSafeGlobalMap>
+class intermodule_singleton_common
+{
+ public:
+ typedef void*(singleton_constructor_t)(ThreadSafeGlobalMap &);
+ typedef void (singleton_destructor_t)(void *, ThreadSafeGlobalMap &);
+
+ static const ::boost::uint32_t Uninitialized = 0u;
+ static const ::boost::uint32_t Initializing = 1u;
+ static const ::boost::uint32_t Initialized = 2u;
+ static const ::boost::uint32_t Broken = 3u;
+ static const ::boost::uint32_t Destroyed = 4u;
+
+ //Initialize this_module_singleton_ptr, creates the global map if needed and also creates an unique
+ //opaque type in global map through a singleton_constructor_t function call,
+ //initializing the passed pointer to that unique instance.
+ //
+ //We have two concurrency types here. a)the global map/singleton creation must
+ //be safe between threads of this process but in different modules/dlls. b)
+ //the pointer to the singleton is per-module, so we have to protect this
+ //initization between threads of the same module.
+ //
+ //All static variables declared here are shared between inside a module
+ //so atomic operations will synchronize only threads of the same module.
+ static void initialize_singleton_logic
+ (void *&ptr, volatile boost::uint32_t &this_module_singleton_initialized, singleton_constructor_t constructor, bool phoenix)
+ {
+ //If current module is not initialized enter to lock free logic
+ if(atomic_read32(&this_module_singleton_initialized) != Initialized){
+ //Now a single thread of the module will succeed in this CAS.
+ //trying to pass from Uninitialized to Initializing
+ ::boost::uint32_t previous_module_singleton_initialized = atomic_cas32
+ (&this_module_singleton_initialized, Initializing, Uninitialized);
+ //If the thread succeeded the CAS (winner) it will compete with other
+ //winner threads from other modules to create the global map
+ if(previous_module_singleton_initialized == Destroyed){
+ //Trying to resurrect a dead Phoenix singleton. Just try to
+ //mark it as uninitialized and start again
+ if(phoenix){
+ atomic_cas32(&this_module_singleton_initialized, Uninitialized, Destroyed);
+ previous_module_singleton_initialized = atomic_cas32
+ (&this_module_singleton_initialized, Initializing, Uninitialized);
+ }
+ //Trying to resurrect a non-Phoenix dead singleton is an error
+ else{
+ throw interprocess_exception("Boost.Interprocess: Dead reference on non-Phoenix singleton of type");
+ }
+ }
+ if(previous_module_singleton_initialized == Uninitialized){
+ try{
+ //Now initialize the global map, this function must solve concurrency
+ //issues between threads of several modules
+ initialize_global_map_handle();
+ //Now try to create the singleton in global map.
+ //This function solves concurrency issues
+ //between threads of several modules
+ void *tmp = constructor(get_map());
+ //Increment the module reference count that reflects how many
+ //singletons this module holds, so that we can safely destroy
+ //module global map object when no singleton is left
+ atomic_inc32(&this_module_singleton_count);
+ //Insert a barrier before assigning the pointer to
+ //make sure this assignment comes after the initialization
+ atomic_write32(&this_module_singleton_initialized, Initializing);
+ //Assign the singleton address to the module-local pointer
+ ptr = tmp;
+ //Memory barrier inserted, all previous operations should complete
+ //before this one. Now marked as initialized
+ atomic_write32(&this_module_singleton_initialized, Initialized);
+ }
+ catch(...){
+ //Mark singleton failed to initialize
+ atomic_write32(&this_module_singleton_initialized, Broken);
+ throw;
+ }
+ }
+ //If previous state was initializing, this means that another winner thread is
+ //trying to initialize the singleton. Just wait until completes its work.
+ else if(previous_module_singleton_initialized == Initializing){
+ while(1){
+ previous_module_singleton_initialized = atomic_read32(&this_module_singleton_initialized);
+ if(previous_module_singleton_initialized >= Initialized){
+ //Already initialized, or exception thrown by initializer thread
+ break;
+ }
+ else if(previous_module_singleton_initialized == Initializing){
+ thread_yield();
+ }
+ else{
+ //This can't be happening!
+ BOOST_ASSERT(0);
+ }
+ }
+ }
+ else if(previous_module_singleton_initialized == Initialized){
+ //Nothing to do here, the singleton is ready
+ }
+ //If previous state was greater than initialized, then memory is broken
+ //trying to initialize the singleton.
+ else{//(previous_module_singleton_initialized > Initialized)
+ throw interprocess_exception("boost::interprocess::intermodule_singleton initialization failed");
+ }
+ }
+ BOOST_ASSERT(ptr != 0);
+ }
+
+ static void finalize_singleton_logic(void *&ptr, volatile boost::uint32_t &this_module_singleton_initialized, singleton_destructor_t destructor)
+ {
+ //Protect destruction against lazy singletons not initialized in this execution
+ if(ptr){
+ //Note: this destructor might provoke a Phoenix singleton
+ //resurrection. This means that this_module_singleton_count
+ //might change after this call.
+ destructor(ptr, get_map());
+ ptr = 0;
+
+ //Memory barrier to make sure pointer is nulled.
+ //Mark this singleton as destroyed.
+ atomic_write32(&this_module_singleton_initialized, Destroyed);
+
+ //If this is the last singleton of this module
+ //apply map destruction.
+ //Note: singletons are destroyed when the module is unloaded
+ //so no threads should be executing or holding references
+ //to this module
+ if(1 == atomic_dec32(&this_module_singleton_count)){
+ destroy_global_map_handle();
+ }
+ }
+ }
+
+ private:
+ static ThreadSafeGlobalMap &get_map()
+ {
+ return *static_cast<ThreadSafeGlobalMap *>(static_cast<void *>(&mem_holder.map_mem));
+ }
+
+ static void initialize_global_map_handle()
+ {
+ //Obtain unique map name and size
+ while(1){
+ //Try to pass map state to initializing
+ ::boost::uint32_t tmp = atomic_cas32(&this_module_map_initialized, Initializing, Uninitialized);
+ if(tmp == Initialized || tmp == Broken){
+ break;
+ }
+ else if(tmp == Destroyed){
+ tmp = atomic_cas32(&this_module_map_initialized, Uninitialized, Destroyed);
+ continue;
+ }
+ //If some other thread is doing the work wait
+ else if(tmp == Initializing){
+ thread_yield();
+ }
+ else{ //(tmp == Uninitialized)
+ //If not initialized try it again?
+ try{
+ //Remove old global map from the system
+ intermodule_singleton_helpers::thread_safe_global_map_dependant<ThreadSafeGlobalMap>::remove_old_gmem();
+ //in-place construction of the global map class
+ intermodule_singleton_helpers::thread_safe_global_map_dependant
+ <ThreadSafeGlobalMap>::construct_map(static_cast<void*>(&get_map()));
+ //Use global map's internal lock to initialize the lock file
+ //that will mark this gmem as "in use".
+ typename intermodule_singleton_helpers::thread_safe_global_map_dependant<ThreadSafeGlobalMap>::
+ lock_file_logic f(get_map());
+ //If function failed (maybe a competing process has erased the shared
+ //memory between creation and file locking), retry with a new instance.
+ if(f.retry()){
+ get_map().~ThreadSafeGlobalMap();
+ atomic_write32(&this_module_map_initialized, Destroyed);
+ }
+ else{
+ //Locking succeeded, so this global map module-instance is ready
+ atomic_write32(&this_module_map_initialized, Initialized);
+ break;
+ }
+ }
+ catch(...){
+ //
+ throw;
+ }
+ }
+ }
+ }
+
+ static void destroy_global_map_handle()
+ {
+ if(!atomic_read32(&this_module_singleton_count)){
+ //This module is being unloaded, so destroy
+ //the global map object of this module
+ //and unlink the global map if it's the last
+ typename intermodule_singleton_helpers::thread_safe_global_map_dependant<ThreadSafeGlobalMap>::
+ unlink_map_logic f(get_map());
+ (get_map()).~ThreadSafeGlobalMap();
+ atomic_write32(&this_module_map_initialized, Destroyed);
+ //Do some cleanup for other processes old gmem instances
+ intermodule_singleton_helpers::thread_safe_global_map_dependant<ThreadSafeGlobalMap>::remove_old_gmem();
+ }
+ }
+
+ //Static data, zero-initalized without any dependencies
+ //this_module_singleton_count is the number of singletons used by this module
+ static volatile boost::uint32_t this_module_singleton_count;
+
+ //this_module_map_initialized is the state of this module's map class object.
+ //Values: Uninitialized, Initializing, Initialized, Broken
+ static volatile boost::uint32_t this_module_map_initialized;
+
+ //Raw memory to construct the global map manager
+ static struct mem_holder_t
+ {
+ ::boost::detail::max_align aligner;
+ char map_mem [sizeof(ThreadSafeGlobalMap)];
+ } mem_holder;
+};
+
+template<class ThreadSafeGlobalMap>
+volatile boost::uint32_t intermodule_singleton_common<ThreadSafeGlobalMap>::this_module_singleton_count;
+
+template<class ThreadSafeGlobalMap>
+volatile boost::uint32_t intermodule_singleton_common<ThreadSafeGlobalMap>::this_module_map_initialized;
+
+template<class ThreadSafeGlobalMap>
+typename intermodule_singleton_common<ThreadSafeGlobalMap>::mem_holder_t
+ intermodule_singleton_common<ThreadSafeGlobalMap>::mem_holder;
+
+//A reference count to be stored in global map holding the number
+//of singletons (one per module) attached to the instance pointed by
+//the internal ptr.
+struct ref_count_ptr
+{
+ ref_count_ptr(void *p, boost::uint32_t count)
+ : ptr(p), singleton_ref_count(count)
+ {}
+ void *ptr;
+ //This reference count serves to count the number of attached
+ //modules to this singleton
+ volatile boost::uint32_t singleton_ref_count;
+};
+
+
+//Now this class is a singleton, initializing the singleton in
+//the first get() function call if LazyInit is false. If true
+//then the singleton will be initialized when loading the module.
+template<typename C, bool LazyInit, bool Phoenix, class ThreadSafeGlobalMap>
+class intermodule_singleton_impl
+{
+ public:
+
+ static C& get() //Let's make inlining easy
+ {
+ if(!this_module_singleton_ptr){
+ if(lifetime.dummy_function()){ //This forces lifetime instantiation, for reference counted destruction
+ atentry_work();
+ }
+ }
+ return *static_cast<C*>(this_module_singleton_ptr);
+ }
+
+ private:
+
+ static void atentry_work()
+ {
+ intermodule_singleton_common<ThreadSafeGlobalMap>::initialize_singleton_logic
+ (this_module_singleton_ptr, this_module_singleton_initialized, singleton_constructor, Phoenix);
+ }
+
+ static void atexit_work()
+ {
+ intermodule_singleton_common<ThreadSafeGlobalMap>::finalize_singleton_logic
+ (this_module_singleton_ptr, this_module_singleton_initialized, singleton_destructor);
+ }
+
+ //These statics will be zero-initialized without any constructor call dependency
+ //this_module_singleton_ptr will be a module-local pointer to the singleton
+ static void* this_module_singleton_ptr;
+
+ //this_module_singleton_count will be used to synchronize threads of the same module
+ //for access to a singleton instance, and to flag the state of the
+ //singleton.
+ static volatile boost::uint32_t this_module_singleton_initialized;
+
+ //This class destructor will trigger singleton destruction
+ struct lifetime_type_lazy
+ {
+ bool dummy_function()
+ { return m_dummy == 0; }
+
+ ~lifetime_type_lazy()
+ {
+ if(!Phoenix){
+ atexit_work();
+ }
+ }
+
+ //Dummy volatile so that the compiler can't resolve its value at compile-time
+ //and can't avoid lifetime_type instantiation if dummy_function() is called.
+ static volatile int m_dummy;
+ };
+
+ struct lifetime_type_static
+ : public lifetime_type_lazy
+ {
+ lifetime_type_static()
+ { atentry_work(); }
+ };
+
+ typedef typename if_c
+ <LazyInit, lifetime_type_lazy, lifetime_type_static>::type lifetime_type;
+
+ static lifetime_type lifetime;
+
+ //A functor to be executed inside global map lock that just
+ //searches for the singleton in map and if not present creates a new one.
+ //If singleton constructor throws, the exception is propagated
+ struct init_atomic_func
+ {
+ init_atomic_func(ThreadSafeGlobalMap &m)
+ : m_map(m)
+ {}
+
+ void operator()()
+ {
+ ref_count_ptr *rcount = intermodule_singleton_helpers::thread_safe_global_map_dependant
+ <ThreadSafeGlobalMap>::find(m_map, typeid(C).name());
+ if(!rcount){
+ C *p = new C;
+ try{
+ ref_count_ptr val(p, 0u);
+ rcount = intermodule_singleton_helpers::thread_safe_global_map_dependant
+ <ThreadSafeGlobalMap>::insert(m_map, typeid(C).name(), val);
+ }
+ catch(...){
+ intermodule_singleton_helpers::thread_safe_global_map_dependant
+ <ThreadSafeGlobalMap>::erase(m_map, typeid(C).name());
+ delete p;
+ throw;
+ }
+ }
+ if(Phoenix){
+ std::atexit(&atexit_work);
+ }
+ atomic_inc32(&rcount->singleton_ref_count);
+ ret_ptr = rcount->ptr;
+ }
+ void *data() const
+ { return ret_ptr; }
+
+ private:
+ ThreadSafeGlobalMap &m_map;
+ void *ret_ptr;
+ };
+
+ //A functor to be executed inside global map lock that just
+ //deletes the singleton in map if the attached count reaches to zero
+ struct fini_atomic_func
+ {
+ fini_atomic_func(ThreadSafeGlobalMap &m)
+ : m_map(m)
+ {}
+
+ void operator()()
+ {
+ ref_count_ptr *rcount = intermodule_singleton_helpers::thread_safe_global_map_dependant
+ <ThreadSafeGlobalMap>::find(m_map, typeid(C).name());
+ //The object must exist
+ BOOST_ASSERT(rcount);
+ BOOST_ASSERT(rcount->singleton_ref_count > 0);
+ //Check if last reference
+ if(atomic_dec32(&rcount->singleton_ref_count) == 1){
+ //If last, destroy the object
+ BOOST_ASSERT(rcount->ptr != 0);
+ C *pc = static_cast<C*>(rcount->ptr);
+ //Now destroy map entry
+ bool destroyed = intermodule_singleton_helpers::thread_safe_global_map_dependant
+ <ThreadSafeGlobalMap>::erase(m_map, typeid(C).name());
+ (void)destroyed; BOOST_ASSERT(destroyed == true);
+ delete pc;
+ }
+ }
+ void *data() const
+ { return ret_ptr; }
+
+ private:
+ ThreadSafeGlobalMap &m_map;
+ void *ret_ptr;
+ };
+
+ //A wrapper to execute init_atomic_func
+ static void *singleton_constructor(ThreadSafeGlobalMap &map)
+ {
+ init_atomic_func f(map);
+ intermodule_singleton_helpers::thread_safe_global_map_dependant
+ <ThreadSafeGlobalMap>::atomic_func(map, f);
+ return f.data();
+ }
+
+ //A wrapper to execute fini_atomic_func
+ static void singleton_destructor(void *p, ThreadSafeGlobalMap &map)
+ { (void)p;
+ fini_atomic_func f(map);
+ intermodule_singleton_helpers::thread_safe_global_map_dependant
+ <ThreadSafeGlobalMap>::atomic_func(map, f);
+ }
+};
+
+template <typename C, bool L, bool P, class ThreadSafeGlobalMap>
+volatile int intermodule_singleton_impl<C, L, P, ThreadSafeGlobalMap>::lifetime_type_lazy::m_dummy = 0;
+
+//These will be zero-initialized by the loader
+template <typename C, bool L, bool P, class ThreadSafeGlobalMap>
+void *intermodule_singleton_impl<C, L, P, ThreadSafeGlobalMap>::this_module_singleton_ptr = 0;
+
+template <typename C, bool L, bool P, class ThreadSafeGlobalMap>
+volatile boost::uint32_t intermodule_singleton_impl<C, L, P, ThreadSafeGlobalMap>::this_module_singleton_initialized = 0;
+
+template <typename C, bool L, bool P, class ThreadSafeGlobalMap>
+typename intermodule_singleton_impl<C, L, P, ThreadSafeGlobalMap>::lifetime_type
+ intermodule_singleton_impl<C, L, P, ThreadSafeGlobalMap>::lifetime;
+
+} //namespace ipcdetail{
+} //namespace interprocess{
+} //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_INTERPROCESS_INTERMODULE_SINGLETON_COMMON_HPP
diff --git a/boost/interprocess/detail/intersegment_ptr.hpp b/boost/interprocess/detail/intersegment_ptr.hpp
index 92970923d0..16d3505883 100644
--- a/boost/interprocess/detail/intersegment_ptr.hpp
+++ b/boost/interprocess/detail/intersegment_ptr.hpp
@@ -68,8 +68,8 @@ struct intersegment_base
static const std::size_t begin_bits = max_segment_size_bits - align_bits;
static const std::size_t pow_size_bits_helper = static_log2<max_segment_size_bits>::value;
- static const std::size_t pow_size_bits =
- (max_segment_size_bits == (std::size_t(1) << pow_size_bits_helper)) ?
+ static const std::size_t pow_size_bits =
+ (max_segment_size_bits == (std::size_t(1) << pow_size_bits_helper)) ?
pow_size_bits_helper : pow_size_bits_helper + 1;
static const std::size_t frc_size_bits =
size_t_bits - ctrl_bits - begin_bits - pow_size_bits;
@@ -177,7 +177,7 @@ struct intersegment_base
void set_mode(std::size_t mode)
{
- BOOST_ASSERT(mode < is_max_mode);
+ BOOST_ASSERT(mode < is_max_mode);
members.direct.ctrl = mode;
}
@@ -185,7 +185,7 @@ struct intersegment_base
//!null pointer
bool is_null() const
{
- return (this->get_mode() < is_relative) &&
+ return (this->get_mode() < is_relative) &&
!members.direct.dummy &&
!members.direct.addr;
}
@@ -309,13 +309,13 @@ struct flat_map_intersegment
void *ptr_base;
void *this_base;
get_segment_info_and_offset(this, this_info, this_offset, this_base);
-
+
if(!this_info.group){
this->set_mode(is_in_stack);
this->members.direct.addr = const_cast<void*>(ptr);
}
else{
- get_segment_info_and_offset(ptr, ptr_info, ptr_offset, ptr_base);
+ get_segment_info_and_offset(ptr, ptr_info, ptr_offset, ptr_base);
if(ptr_info.group != this_info.group){
this->set_mode(is_pointee_outside);
@@ -340,7 +340,7 @@ struct flat_map_intersegment
}
}
- //!Sets the object internals to represent the address pointed
+ //!Sets the object internals to represent the address pointed
//!by another flat_map_intersegment
void set_from_other(const self_t &other)
{
@@ -383,7 +383,7 @@ struct flat_map_intersegment
};
vector<segment_data> m_segments;
multi_segment_services &m_ms_services;
-
+
public:
segment_group_t(multi_segment_services &ms_services)
: m_ms_services(ms_services)
@@ -434,7 +434,7 @@ struct flat_map_intersegment
typedef set<segment_group_t> segment_groups_t;
typedef boost::interprocess::flat_map
- <const void *
+ <const void *
,segment_info_t
,std::less<const void *> > ptr_to_segment_info_t;
@@ -443,9 +443,9 @@ struct flat_map_intersegment
//!Mutex to preserve integrity in multi-threaded
//!enviroments
typedef Mutex mutex_type;
- //!Maps base addresses and segment information
+ //!Maps base addresses and segment information
//!(size and segment group and id)*
-
+
ptr_to_segment_info_t m_ptr_to_segment_info;
~mappings_t()
@@ -476,7 +476,7 @@ struct flat_map_intersegment
return;
}
//Find the first base address greater than ptr
- typename ptr_to_segment_info_t::iterator it
+ typename ptr_to_segment_info_t::iterator it
= s_map.m_ptr_to_segment_info.upper_bound(ptr);
if(it == s_map.m_ptr_to_segment_info.begin()){
segment = segment_info_t();
@@ -486,7 +486,7 @@ struct flat_map_intersegment
--it;
char * segment_base = const_cast<char*>(reinterpret_cast<const char*>(it->first));
std::size_t segment_size = it->second.size;
-
+
if(segment_base <= reinterpret_cast<const char*>(ptr) &&
(segment_base + segment_size) >= reinterpret_cast<const char*>(ptr)){
segment = it->second;
@@ -552,7 +552,7 @@ struct flat_map_intersegment
s_groups.insert(segment_group_t(*services));
BOOST_ASSERT(ret.second);
return &*ret.first;
- }
+ }
}
static bool delete_group(segment_group_id id)
@@ -574,23 +574,23 @@ struct flat_map_intersegment
}
}
return success;
- }
+ }
}
};
//!Static map-segment_info associated with
//!flat_map_intersegment<>
template <class Mutex>
-typename flat_map_intersegment<Mutex>::mappings_t
+typename flat_map_intersegment<Mutex>::mappings_t
flat_map_intersegment<Mutex>::s_map;
//!Static segment group container associated with
//!flat_map_intersegment<>
template <class Mutex>
-typename flat_map_intersegment<Mutex>::segment_groups_t
+typename flat_map_intersegment<Mutex>::segment_groups_t
flat_map_intersegment<Mutex>::s_groups;
-//!A smart pointer that can point to a pointee that resides in another memory
+//!A smart pointer that can point to a pointee that resides in another memory
//!memory mapped or shared memory segment.
template <class T>
class intersegment_ptr : public flat_map_intersegment<interprocess_mutex>
@@ -623,13 +623,13 @@ class intersegment_ptr : public flat_map_intersegment<interprocess_mutex>
//!Constructor from other intersegment_ptr
//!Never throws
- intersegment_ptr(const intersegment_ptr& ptr)
+ intersegment_ptr(const intersegment_ptr& ptr)
{ base_t::set_from_other(ptr); }
- //!Constructor from other intersegment_ptr. If pointers of pointee types are
+ //!Constructor from other intersegment_ptr. If pointers of pointee types are
//!convertible, intersegment_ptrs will be convertibles. Never throws.
template<class T2>
- intersegment_ptr(const intersegment_ptr<T2> &ptr)
+ intersegment_ptr(const intersegment_ptr<T2> &ptr)
{ pointer p(ptr.get()); (void)p; base_t::set_from_other(ptr); }
//!Emulates static_cast operator.
@@ -663,17 +663,17 @@ class intersegment_ptr : public flat_map_intersegment<interprocess_mutex>
//!Pointer-like -> operator. It can return 0 pointer.
//!Never throws.
- pointer operator->() const
+ pointer operator->() const
{ return self_t::get(); }
- //!Dereferencing operator, if it is a null intersegment_ptr behavior
+ //!Dereferencing operator, if it is a null intersegment_ptr behavior
//!is undefined. Never throws.
- reference operator* () const
+ reference operator* () const
{ return *(self_t::get()); }
//!Indexing operator.
//!Never throws.
- reference operator[](std::ptrdiff_t idx) const
+ reference operator[](std::ptrdiff_t idx) const
{ return self_t::get()[idx]; }
//!Assignment from pointer (saves extra conversion).
@@ -686,19 +686,19 @@ class intersegment_ptr : public flat_map_intersegment<interprocess_mutex>
intersegment_ptr& operator= (const intersegment_ptr &ptr)
{ base_t::set_from_other(ptr); return *this; }
- //!Assignment from related intersegment_ptr. If pointers of pointee types
+ //!Assignment from related intersegment_ptr. If pointers of pointee types
//!are assignable, intersegment_ptrs will be assignable. Never throws.
template <class T2>
intersegment_ptr& operator= (const intersegment_ptr<T2> & ptr)
- {
- pointer p(ptr.get()); (void)p;
- base_t::set_from_other(ptr); return *this;
+ {
+ pointer p(ptr.get()); (void)p;
+ base_t::set_from_other(ptr); return *this;
}
-
+
//!intersegment_ptr + std::ptrdiff_t.
//!Never throws.
- intersegment_ptr operator+ (std::ptrdiff_t idx) const
- {
+ intersegment_ptr operator+ (std::ptrdiff_t idx) const
+ {
intersegment_ptr result (*this);
result.inc_offset(idx*sizeof(T));
return result;
@@ -706,8 +706,8 @@ class intersegment_ptr : public flat_map_intersegment<interprocess_mutex>
//!intersegment_ptr - std::ptrdiff_t.
//!Never throws.
- intersegment_ptr operator- (std::ptrdiff_t idx) const
- {
+ intersegment_ptr operator- (std::ptrdiff_t idx) const
+ {
intersegment_ptr result (*this);
result.dec_offset(idx*sizeof(T));
return result;
@@ -727,7 +727,7 @@ class intersegment_ptr : public flat_map_intersegment<interprocess_mutex>
//!Never throws.
intersegment_ptr& operator++ (void)
{ base_t::inc_offset(sizeof(T)); return *this; }
-
+
//!intersegment_ptr++.
//!Never throws.
intersegment_ptr operator++ (int)
@@ -745,10 +745,10 @@ class intersegment_ptr : public flat_map_intersegment<interprocess_mutex>
//!Safe bool conversion operator.
//!Never throws.
- operator unspecified_bool_type() const
+ operator unspecified_bool_type() const
{ return base_t::is_null()? 0 : &self_t::unspecified_bool_type_func; }
- //!Not operator. Not needed in theory, but improves portability.
+ //!Not operator. Not needed in theory, but improves portability.
//!Never throws.
bool operator! () const
{ return base_t::is_null(); }
@@ -784,12 +784,12 @@ class intersegment_ptr : public flat_map_intersegment<interprocess_mutex>
template <class T1, class T2> inline
bool operator ==(const intersegment_ptr<T1> &left,
const intersegment_ptr<T2> &right)
-{
+{
//Make sure both pointers can be compared
bool e = typename intersegment_ptr<T1>::pointer(0) ==
typename intersegment_ptr<T2>::pointer(0);
(void)e;
- return left._equal(right);
+ return left._equal(right);
}
//!Returns true if *this is less than other.
@@ -798,74 +798,74 @@ bool operator ==(const intersegment_ptr<T1> &left,
template <class T1, class T2> inline
bool operator <(const intersegment_ptr<T1> &left,
const intersegment_ptr<T2> &right)
-{
+{
//Make sure both pointers can be compared
bool e = typename intersegment_ptr<T1>::pointer(0) <
typename intersegment_ptr<T2>::pointer(0);
(void)e;
- return left._less(right);
+ return left._less(right);
}
template<class T1, class T2> inline
-bool operator!= (const intersegment_ptr<T1> &pt1,
+bool operator!= (const intersegment_ptr<T1> &pt1,
const intersegment_ptr<T2> &pt2)
{ return !(pt1 ==pt2); }
//!intersegment_ptr<T1> <= intersegment_ptr<T2>.
//!Never throws.
template<class T1, class T2> inline
-bool operator<= (const intersegment_ptr<T1> &pt1,
+bool operator<= (const intersegment_ptr<T1> &pt1,
const intersegment_ptr<T2> &pt2)
{ return !(pt1 > pt2); }
//!intersegment_ptr<T1> > intersegment_ptr<T2>.
//!Never throws.
template<class T1, class T2> inline
-bool operator> (const intersegment_ptr<T1> &pt1,
+bool operator> (const intersegment_ptr<T1> &pt1,
const intersegment_ptr<T2> &pt2)
{ return (pt2 < pt1); }
//!intersegment_ptr<T1> >= intersegment_ptr<T2>.
//!Never throws.
template<class T1, class T2> inline
-bool operator>= (const intersegment_ptr<T1> &pt1,
+bool operator>= (const intersegment_ptr<T1> &pt1,
const intersegment_ptr<T2> &pt2)
{ return !(pt1 < pt2); }
//!operator<<
template<class E, class T, class U> inline
-std::basic_ostream<E, T> & operator<<
+std::basic_ostream<E, T> & operator<<
(std::basic_ostream<E, T> & os, const intersegment_ptr<U> & p)
{ return os << p.get(); }
//!operator>>
template<class E, class T, class U> inline
-std::basic_istream<E, T> & operator>>
+std::basic_istream<E, T> & operator>>
(std::basic_istream<E, T> & os, intersegment_ptr<U> & p)
{ U * tmp; return os >> tmp; p = tmp; }
-//!std::ptrdiff_t + intersegment_ptr.
+//!std::ptrdiff_t + intersegment_ptr.
//!The result is another pointer of the same segment
template<class T> inline
intersegment_ptr<T> operator+
(std::ptrdiff_t diff, const intersegment_ptr<T>& right)
{ return right + diff; }
-//!intersegment_ptr - intersegment_ptr.
+//!intersegment_ptr - intersegment_ptr.
//!This only works with two intersegment_ptr-s that point to the
//!same segment
template <class T, class T2> inline
-std::ptrdiff_t operator- (const intersegment_ptr<T> &pt,
+std::ptrdiff_t operator- (const intersegment_ptr<T> &pt,
const intersegment_ptr<T2> &pt2)
{ return pt._diff(pt2)/sizeof(T); }
//! swap specialization
template<class T> inline
-void swap (boost::interprocess::intersegment_ptr<T> &pt,
+void swap (boost::interprocess::intersegment_ptr<T> &pt,
boost::interprocess::intersegment_ptr<T> &pt2)
{ pt.swap(pt2); }
-//!to_raw_pointer() enables boost::mem_fn to recognize intersegment_ptr.
+//!to_raw_pointer() enables boost::mem_fn to recognize intersegment_ptr.
//!Never throws.
template<class T> inline
T * to_raw_pointer(boost::interprocess::intersegment_ptr<T> const & p)
@@ -873,19 +873,19 @@ T * to_raw_pointer(boost::interprocess::intersegment_ptr<T> const & p)
//!Simulation of static_cast between pointers.
//!Never throws.
-template<class T, class U> inline
+template<class T, class U> inline
boost::interprocess::intersegment_ptr<T> static_pointer_cast(const boost::interprocess::intersegment_ptr<U> &r)
{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::ipcdetail::static_cast_tag()); }
//!Simulation of const_cast between pointers.
//!Never throws.
-template<class T, class U> inline
+template<class T, class U> inline
boost::interprocess::intersegment_ptr<T> const_pointer_cast(const boost::interprocess::intersegment_ptr<U> &r)
{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::ipcdetail::const_cast_tag()); }
//!Simulation of dynamic_cast between pointers.
//!Never throws.
-template<class T, class U> inline
+template<class T, class U> inline
boost::interprocess::intersegment_ptr<T> dynamic_pointer_cast(const boost::interprocess::intersegment_ptr<U> &r)
{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::ipcdetail::dynamic_cast_tag()); }
@@ -895,7 +895,7 @@ template<class T, class U> inline
boost::interprocess::intersegment_ptr<T> reinterpret_pointer_cast(const boost::interprocess::intersegment_ptr<U> &r)
{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::ipcdetail::reinterpret_cast_tag()); }
-//!Trait class to detect if an smart pointer has
+//!Trait class to detect if an smart pointer has
//!multi-segment addressing capabilities.
template <class T>
struct is_multisegment_ptr
@@ -907,7 +907,7 @@ struct is_multisegment_ptr
} //namespace interprocess {
#if defined(_MSC_VER) && (_MSC_VER < 1400)
-//!to_raw_pointer() enables boost::mem_fn to recognize intersegment_ptr.
+//!to_raw_pointer() enables boost::mem_fn to recognize intersegment_ptr.
//!Never throws.
template<class T> inline
T * to_raw_pointer(boost::interprocess::intersegment_ptr<T> const & p)
@@ -918,14 +918,14 @@ T * to_raw_pointer(boost::interprocess::intersegment_ptr<T> const & p)
//!for optimizations
template <class T>
struct has_trivial_constructor
- < boost::interprocess::intersegment_ptr<T> >
+ < boost::interprocess::intersegment_ptr<T> >
: public true_type{};
//!has_trivial_destructor<> == true_type specialization
//!for optimizations
template <class T>
struct has_trivial_destructor
- < boost::interprocess::intersegment_ptr<T> >
+ < boost::interprocess::intersegment_ptr<T> >
: public true_type{};
} //namespace boost {
@@ -950,7 +950,7 @@ struct has_trivial_destructor
// std::size_t offset;
//RELATIVE_SIZE_BITS = SIZE_T_BITS -
-// MAX_SEGMENT_BITS -
+// MAX_SEGMENT_BITS -
// CTRL_BITS 10 10
//MAX_SEGMENT_SIZE = SIZE_T_BITS - ALIGN_BITS 20 52
diff --git a/boost/interprocess/detail/managed_global_memory.hpp b/boost/interprocess/detail/managed_global_memory.hpp
new file mode 100644
index 0000000000..39dd0b1e6d
--- /dev/null
+++ b/boost/interprocess/detail/managed_global_memory.hpp
@@ -0,0 +1,115 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009-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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_BASIC_GLOBAL_MEMORY_HPP
+#define BOOST_INTERPROCESS_BASIC_GLOBAL_MEMORY_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#include <boost/interprocess/offset_ptr.hpp>
+#include <boost/interprocess/sync/spin/mutex.hpp>
+#include <boost/interprocess/sync/spin/recursive_mutex.hpp>
+#include <boost/interprocess/detail/managed_memory_impl.hpp>
+#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
+#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
+#include <boost/interprocess/indexes/iset_index.hpp>
+#include <boost/interprocess/creation_tags.hpp>
+#include <boost/interprocess/permissions.hpp>
+
+namespace boost{
+namespace interprocess{
+namespace ipcdetail{
+
+struct intermodule_singleton_mutex_family
+{
+ typedef boost::interprocess::ipcdetail::spin_mutex mutex_type;
+ typedef boost::interprocess::ipcdetail::spin_recursive_mutex recursive_mutex_type;
+};
+
+struct intermodule_types
+{
+ //We must use offset_ptr since a loaded DLL can map the singleton holder shared memory
+ //at a different address than other DLLs or the main executable
+ typedef rbtree_best_fit<intermodule_singleton_mutex_family, offset_ptr<void> > mem_algo;
+ template<class Device, bool FileBased>
+ struct open_or_create
+ {
+ typedef managed_open_or_create_impl
+ <Device, mem_algo::Alignment, FileBased> type;
+ };
+};
+
+//we must implement our own managed shared memory to avoid circular dependencies
+template<class Device, bool FileBased>
+class basic_managed_global_memory
+ : public basic_managed_memory_impl
+ < char
+ , intermodule_types::mem_algo
+ , iset_index
+ , intermodule_types::open_or_create<Device, FileBased>::type::ManagedOpenOrCreateUserOffset
+ >
+ , private intermodule_types::open_or_create<Device, FileBased>::type
+{
+ /// @cond
+ typedef typename intermodule_types::template open_or_create<Device, FileBased>::type base2_t;
+
+ typedef basic_managed_memory_impl
+ < char
+ , intermodule_types::mem_algo
+ , iset_index
+ , base2_t::ManagedOpenOrCreateUserOffset
+ > base_t;
+
+ typedef create_open_func<base_t> create_open_func_t;
+
+ basic_managed_global_memory *get_this_pointer()
+ { return this; }
+
+ public:
+ typedef typename base_t::size_type size_type;
+
+ private:
+ typedef typename base_t::char_ptr_holder_t char_ptr_holder_t;
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_managed_global_memory)
+ /// @endcond
+
+ public: //functions
+
+ basic_managed_global_memory (open_or_create_t open_or_create,
+ const char *name, size_type size,
+ const void *addr = 0, const permissions& perm = permissions())
+ : base_t()
+ , base2_t(open_or_create, name, size, read_write, addr,
+ create_open_func_t(get_this_pointer(),
+ DoOpenOrCreate), perm)
+ {}
+
+ basic_managed_global_memory (open_only_t open_only, const char* name,
+ const void *addr = 0)
+ : base_t()
+ , base2_t(open_only, name, read_write, addr,
+ create_open_func_t(get_this_pointer(),
+ DoOpen))
+ {}
+};
+
+
+} //namespace ipcdetail{
+} //namespace interprocess{
+} //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_INTERPROCESS_BASIC_GLOBAL_MEMORY_HPP
diff --git a/boost/interprocess/detail/managed_memory_impl.hpp b/boost/interprocess/detail/managed_memory_impl.hpp
index 31c3804439..f9ecb8a860 100644
--- a/boost/interprocess/detail/managed_memory_impl.hpp
+++ b/boost/interprocess/detail/managed_memory_impl.hpp
@@ -34,7 +34,7 @@
#include <boost/assert.hpp>
//!\file
-//!Describes a named shared memory allocation user class.
+//!Describes a named shared memory allocation user class.
//!
namespace boost {
@@ -45,7 +45,7 @@ template<class BasicManagedMemoryImpl>
class create_open_func;
template<
- class CharType,
+ class CharType,
class MemoryAlgorithm,
template<class IndexConfig> class IndexType
>
@@ -54,14 +54,14 @@ struct segment_manager_type
typedef segment_manager<CharType, MemoryAlgorithm, IndexType> type;
};
-//!This class is designed to be a base class to classes that manage
-//!creation of objects in a fixed size memory buffer. Apart
-//!from allocating raw memory, the user can construct named objects. To
+//!This class is designed to be a base class to classes that manage
+//!creation of objects in a fixed size memory buffer. Apart
+//!from allocating raw memory, the user can construct named objects. To
//!achieve this, this class uses the reserved space provided by the allocation
//!algorithm to place a named_allocator_algo, who takes care of name mappings.
//!The class can be customized with the char type used for object names
//!and the memory allocation algorithm to be used.*/
-template < class CharType
+template < class CharType
, class MemoryAlgorithm
, template<class IndexConfig> class IndexType
, std::size_t Offset = 0
@@ -92,7 +92,7 @@ class basic_managed_memory_impl
/// @cond
- typedef typename
+ typedef typename
segment_manager::char_ptr_holder_t char_ptr_holder_t;
//Experimental. Don't use.
@@ -153,7 +153,7 @@ class basic_managed_memory_impl
}
//!Constructor. Allocates basic resources. Never throws.
- basic_managed_memory_impl()
+ basic_managed_memory_impl()
: mp_header(0){}
//!Destructor. Calls close. Never throws.
@@ -169,19 +169,19 @@ class basic_managed_memory_impl
if(size < segment_manager::get_min_size())
return false;
- //This function should not throw. The index construction can
+ //This function should not throw. The index construction can
//throw if constructor allocates memory. So we must catch it.
BOOST_TRY{
- //Let's construct the allocator in memory
+ //Let's construct the allocator in memory
mp_header = new(addr) segment_manager(size);
}
BOOST_CATCH(...){
return false;
}
BOOST_CATCH_END
- return true;
+ return true;
}
-
+
//!Connects to a segment manager in the reserved buffer. Never throws.
bool open_impl (void *addr, size_type)
{
@@ -192,7 +192,7 @@ class basic_managed_memory_impl
//!Frees resources. Never throws.
bool close_impl()
- {
+ {
bool ret = mp_header != 0;
mp_header = 0;
return ret;
@@ -249,40 +249,40 @@ class basic_managed_memory_impl
void zero_free_memory()
{ mp_header->zero_free_memory(); }
- //!Transforms an absolute address into an offset from base address.
+ //!Transforms an absolute address into an offset from base address.
//!The address must belong to the memory segment. Never throws.
handle_t get_handle_from_address (const void *ptr) const
{
- return (handle_t)(reinterpret_cast<const char*>(ptr) -
- reinterpret_cast<const char*>(this->get_address()));
+ return (handle_t)(reinterpret_cast<const char*>(ptr) -
+ reinterpret_cast<const char*>(this->get_address()));
}
//!Returns true if the address belongs to the managed memory segment
bool belongs_to_segment (const void *ptr) const
- {
- return ptr >= this->get_address() &&
+ {
+ return ptr >= this->get_address() &&
ptr < (reinterpret_cast<const char*>(this->get_address()) + this->get_size());
}
- //!Transforms previously obtained offset into an absolute address in the
+ //!Transforms previously obtained offset into an absolute address in the
//!process space of the current process. Never throws.*/
void * get_address_from_handle (handle_t offset) const
{ return reinterpret_cast<char*>(this->get_address()) + offset; }
//!Searches for nbytes of free memory in the segment, marks the
- //!memory as used and return the pointer to the memory. If no
+ //!memory as used and return the pointer to the memory. If no
//!memory is available throws a boost::interprocess::bad_alloc exception
void* allocate (size_type nbytes)
{ return mp_header->allocate(nbytes); }
- //!Searches for nbytes of free memory in the segment, marks the
- //!memory as used and return the pointer to the memory. If no memory
+ //!Searches for nbytes of free memory in the segment, marks the
+ //!memory as used and return the pointer to the memory. If no memory
//!is available returns 0. Never throws.
void* allocate (size_type nbytes, std::nothrow_t nothrow)
{ return mp_header->allocate(nbytes, nothrow); }
//!Allocates nbytes bytes aligned to "alignment" bytes. "alignment"
- //!must be power of two. If no memory
+ //!must be power of two. If no memory
//!is available returns 0. Never throws.
void * allocate_aligned (size_type nbytes, size_type alignment, std::nothrow_t nothrow)
{ return mp_header->allocate_aligned(nbytes, alignment, nothrow); }
@@ -292,13 +292,13 @@ class basic_managed_memory_impl
allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
size_type preferred_size,size_type &received_size,
T *reuse_ptr = 0)
- {
+ {
return mp_header->allocation_command
(command, limit_size, preferred_size, received_size, reuse_ptr);
}
//!Allocates nbytes bytes aligned to "alignment" bytes. "alignment"
- //!must be power of two. If no
+ //!must be power of two. If no
//!memory is available throws a boost::interprocess::bad_alloc exception
void * allocate_aligned(size_type nbytes, size_type alignment)
{ return mp_header->allocate_aligned(nbytes, alignment); }
@@ -342,18 +342,18 @@ class basic_managed_memory_impl
//!Creates a named object or array in memory
//!
- //!Allocates and constructs a T object or an array of T in memory,
- //!associates this with the given name and returns a pointer to the
+ //!Allocates and constructs a T object or an array of T in memory,
+ //!associates this with the given name and returns a pointer to the
//!created object. If an array is being constructed all objects are
//!created using the same parameters given to this function.
//!
//!-> If the name was previously used, returns 0.
//!
- //!-> Throws boost::interprocess::bad_alloc if there is no available memory
+ //!-> Throws boost::interprocess::bad_alloc if there is no available memory
//!
//!-> If T's constructor throws, the function throws that exception.
//!
- //!Memory is freed automatically if T's constructor throws and if an
+ //!Memory is freed automatically if T's constructor throws and if an
//!array was being constructed, destructors of created objects are called
//!before freeing the memory.
template <class T>
@@ -363,18 +363,18 @@ class basic_managed_memory_impl
//!Finds or creates a named object or array in memory
//!
- //!Tries to find an object with the given name in memory. If
- //!found, returns the pointer to this pointer. If the object is not found,
- //!allocates and constructs a T object or an array of T in memory,
- //!associates this with the given name and returns a pointer to the
+ //!Tries to find an object with the given name in memory. If
+ //!found, returns the pointer to this pointer. If the object is not found,
+ //!allocates and constructs a T object or an array of T in memory,
+ //!associates this with the given name and returns a pointer to the
//!created object. If an array is being constructed all objects are
//!created using the same parameters given to this function.
//!
- //!-> Throws boost::interprocess::bad_alloc if there is no available memory
+ //!-> Throws boost::interprocess::bad_alloc if there is no available memory
//!
//!-> If T's constructor throws, the function throws that exception.
//!
- //!Memory is freed automatically if T's constructor throws and if an
+ //!Memory is freed automatically if T's constructor throws and if an
//!array was being constructed, destructors of created objects are called
//!before freeing the memory.
template <class T>
@@ -384,18 +384,18 @@ class basic_managed_memory_impl
//!Creates a named object or array in memory
//!
- //!Allocates and constructs a T object or an array of T in memory,
- //!associates this with the given name and returns a pointer to the
+ //!Allocates and constructs a T object or an array of T in memory,
+ //!associates this with the given name and returns a pointer to the
//!created object. If an array is being constructed all objects are
//!created using the same parameters given to this function.
//!
//!-> If the name was previously used, returns 0.
//!
- //!-> Returns 0 if there is no available memory
+ //!-> Returns 0 if there is no available memory
//!
//!-> If T's constructor throws, the function throws that exception.
//!
- //!Memory is freed automatically if T's constructor throws and if an
+ //!Memory is freed automatically if T's constructor throws and if an
//!array was being constructed, destructors of created objects are called
//!before freeing the memory.
template <class T>
@@ -405,18 +405,18 @@ class basic_managed_memory_impl
//!Finds or creates a named object or array in memory
//!
- //!Tries to find an object with the given name in memory. If
- //!found, returns the pointer to this pointer. If the object is not found,
- //!allocates and constructs a T object or an array of T in memory,
- //!associates this with the given name and returns a pointer to the
+ //!Tries to find an object with the given name in memory. If
+ //!found, returns the pointer to this pointer. If the object is not found,
+ //!allocates and constructs a T object or an array of T in memory,
+ //!associates this with the given name and returns a pointer to the
//!created object. If an array is being constructed all objects are
//!created using the same parameters given to this function.
//!
- //!-> Returns 0 if there is no available memory
+ //!-> Returns 0 if there is no available memory
//!
//!-> If T's constructor throws, the function throws that exception.
//!
- //!Memory is freed automatically if T's constructor throws and if an
+ //!Memory is freed automatically if T's constructor throws and if an
//!array was being constructed, destructors of created objects are called
//!before freeing the memory.
template <class T>
@@ -424,54 +424,54 @@ class basic_managed_memory_impl
find_or_construct(char_ptr_holder_t name, std::nothrow_t nothrow)
{ return mp_header->template find_or_construct<T>(name, nothrow); }
- //!Creates a named array from iterators in memory
+ //!Creates a named array from iterators in memory
//!
- //!Allocates and constructs an array of T in memory,
- //!associates this with the given name and returns a pointer to the
+ //!Allocates and constructs an array of T in memory,
+ //!associates this with the given name and returns a pointer to the
//!created object. Each element in the array is created using the
//!objects returned when dereferencing iterators as parameters
//!and incrementing all iterators for each element.
//!
//!-> If the name was previously used, returns 0.
//!
- //!-> Throws boost::interprocess::bad_alloc if there is no available memory
+ //!-> Throws boost::interprocess::bad_alloc if there is no available memory
//!
//!-> If T's constructor throws, the function throws that exception.
//!
- //!Memory is freed automatically if T's constructor throws and
+ //!Memory is freed automatically if T's constructor throws and
//!destructors of created objects are called before freeing the memory.
template <class T>
typename segment_manager::template construct_iter_proxy<T>::type
construct_it(char_ptr_holder_t name)
{ return mp_header->template construct_it<T>(name); }
- //!Finds or creates a named array from iterators in memory
+ //!Finds or creates a named array from iterators in memory
//!
- //!Tries to find an object with the given name in memory. If
- //!found, returns the pointer to this pointer. If the object is not found,
- //!allocates and constructs an array of T in memory,
- //!associates this with the given name and returns a pointer to the
+ //!Tries to find an object with the given name in memory. If
+ //!found, returns the pointer to this pointer. If the object is not found,
+ //!allocates and constructs an array of T in memory,
+ //!associates this with the given name and returns a pointer to the
//!created object. Each element in the array is created using the
//!objects returned when dereferencing iterators as parameters
//!and incrementing all iterators for each element.
//!
//!-> If the name was previously used, returns 0.
//!
- //!-> Throws boost::interprocess::bad_alloc if there is no available memory
+ //!-> Throws boost::interprocess::bad_alloc if there is no available memory
//!
//!-> If T's constructor throws, the function throws that exception.
//!
- //!Memory is freed automatically if T's constructor throws and
+ //!Memory is freed automatically if T's constructor throws and
//!destructors of created objects are called before freeing the memory.
template <class T>
typename segment_manager::template construct_iter_proxy<T>::type
find_or_construct_it(char_ptr_holder_t name)
{ return mp_header->template find_or_construct_it<T>(name); }
- //!Creates a named array from iterators in memory
+ //!Creates a named array from iterators in memory
//!
- //!Allocates and constructs an array of T in memory,
- //!associates this with the given name and returns a pointer to the
+ //!Allocates and constructs an array of T in memory,
+ //!associates this with the given name and returns a pointer to the
//!created object. Each element in the array is created using the
//!objects returned when dereferencing iterators as parameters
//!and incrementing all iterators for each element.
@@ -482,19 +482,19 @@ class basic_managed_memory_impl
//!
//!-> If T's constructor throws, the function throws that exception.
//!
- //!Memory is freed automatically if T's constructor throws and
+ //!Memory is freed automatically if T's constructor throws and
//!destructors of created objects are called before freeing the memory.*/
template <class T>
typename segment_manager::template construct_iter_proxy<T>::type
construct_it(char_ptr_holder_t name, std::nothrow_t nothrow)
{ return mp_header->template construct_it<T>(name, nothrow); }
- //!Finds or creates a named array from iterators in memory
+ //!Finds or creates a named array from iterators in memory
//!
- //!Tries to find an object with the given name in memory. If
- //!found, returns the pointer to this pointer. If the object is not found,
- //!allocates and constructs an array of T in memory,
- //!associates this with the given name and returns a pointer to the
+ //!Tries to find an object with the given name in memory. If
+ //!found, returns the pointer to this pointer. If the object is not found,
+ //!allocates and constructs an array of T in memory,
+ //!associates this with the given name and returns a pointer to the
//!created object. Each element in the array is created using the
//!objects returned when dereferencing iterators as parameters
//!and incrementing all iterators for each element.
@@ -505,7 +505,7 @@ class basic_managed_memory_impl
//!
//!-> If T's constructor throws, the function throws that exception.
//!
- //!Memory is freed automatically if T's constructor throws and
+ //!Memory is freed automatically if T's constructor throws and
//!destructors of created objects are called before freeing the memory.*/
template <class T>
typename segment_manager::template construct_iter_proxy<T>::type
@@ -537,11 +537,11 @@ class basic_managed_memory_impl
//!
//!Exception Handling:
//!
- //!When deleting a dynamically object or array, the Standard
+ //!When deleting a dynamically object or array, the Standard
//!does not guarantee that dynamically allocated memory, will be released.
- //!Also, when deleting arrays, the Standard doesn't require calling
- //!destructors for the rest of the objects if for one of them the destructor
- //!terminated with an exception.
+ //!Also, when deleting arrays, the Standard doesn't require calling
+ //!destructors for the rest of the objects if for one of them the destructor
+ //!terminated with an exception.
//!
//!Destroying an object:
//!
@@ -550,13 +550,13 @@ class basic_managed_memory_impl
//!
//!Destroying an array:
//!
- //!When destroying an array, if a destructor throws, the rest of
+ //!When destroying an array, if a destructor throws, the rest of
//!destructors are called. If any of these throws, the exceptions are
//!ignored. The name association will be erased, memory will be freed and
//!the first exception will be thrown. This guarantees the unlocking of
//!mutexes and other resources.
//!
- //!For all theses reasons, classes with throwing destructors are not
+ //!For all theses reasons, classes with throwing destructors are not
//!recommended.
template <class T>
bool destroy(const CharType *name)
@@ -568,7 +568,7 @@ class basic_managed_memory_impl
//!
//!Exception Handling:
//!
- //!When deleting a dynamically object, the Standard does not
+ //!When deleting a dynamically object, the Standard does not
//!guarantee that dynamically allocated memory will be released.
//!
//!Destroying an object:
@@ -576,7 +576,7 @@ class basic_managed_memory_impl
//!If the destructor throws, the memory will be freed and that exception
//!will be thrown.
//!
- //!For all theses reasons, classes with throwing destructors are not
+ //!For all theses reasons, classes with throwing destructors are not
//!recommended for memory.
template <class T>
bool destroy(const unique_instance_t *const )
@@ -588,7 +588,7 @@ class basic_managed_memory_impl
//!
//!Exception Handling:
//!
- //!When deleting a dynamically object, the Standard does not
+ //!When deleting a dynamically object, the Standard does not
//!guarantee that dynamically allocated memory will be released.
//!
//!Destroying an object:
@@ -596,7 +596,7 @@ class basic_managed_memory_impl
//!If the destructor throws, the memory will be freed and that exception
//!will be thrown.
//!
- //!For all theses reasons, classes with throwing destructors are not
+ //!For all theses reasons, classes with throwing destructors are not
//!recommended for memory.
template <class T>
void destroy_ptr(const T *ptr)
@@ -620,13 +620,13 @@ class basic_managed_memory_impl
static size_type get_instance_length(const T *ptr)
{ return segment_manager::get_instance_length(ptr); }
- //!Preallocates needed index resources to optimize the
+ //!Preallocates needed index resources to optimize the
//!creation of "num" named objects in the memory segment.
//!Can throw boost::interprocess::bad_alloc if there is no enough memory.
void reserve_named_objects(size_type num)
{ mp_header->reserve_named_objects(num); }
- //!Preallocates needed index resources to optimize the
+ //!Preallocates needed index resources to optimize the
//!creation of "num" unique objects in the memory segment.
//!Can throw boost::interprocess::bad_alloc if there is no enough memory.
void reserve_unique_objects(size_type num)
@@ -652,7 +652,7 @@ class basic_managed_memory_impl
const_named_iterator named_begin() const
{ return mp_header->named_begin(); }
- //!Returns a constant iterator to the end of the index
+ //!Returns a constant iterator to the end of the index
//!storing the named allocations. NOT thread-safe. Never throws.
const_named_iterator named_end() const
{ return mp_header->named_end(); }
@@ -662,7 +662,7 @@ class basic_managed_memory_impl
const_unique_iterator unique_begin() const
{ return mp_header->unique_begin(); }
- //!Returns a constant iterator to the end of the index
+ //!Returns a constant iterator to the end of the index
//!storing the unique allocations. NOT thread-safe. Never throws.
const_unique_iterator unique_end() const
{ return mp_header->unique_end(); }
@@ -724,8 +724,8 @@ class create_open_func
: m_frontend(frontend), m_type(type){}
bool operator()(void *addr, typename BasicManagedMemoryImpl::size_type size, bool created) const
- {
- if(((m_type == DoOpen) && created) ||
+ {
+ if(((m_type == DoOpen) && created) ||
((m_type == DoCreate) && !created))
return false;
diff --git a/boost/interprocess/detail/managed_multi_shared_memory.hpp b/boost/interprocess/detail/managed_multi_shared_memory.hpp
index 579d1ad6ff..654c8bb9f3 100644
--- a/boost/interprocess/detail/managed_multi_shared_memory.hpp
+++ b/boost/interprocess/detail/managed_multi_shared_memory.hpp
@@ -36,7 +36,7 @@
#include <boost/assert.hpp>
//These includes needed to fulfill default template parameters of
//predeclarations in interprocess_fwd.hpp
-#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
+#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
#include <boost/interprocess/sync/mutex_family.hpp>
//!\file
@@ -51,25 +51,25 @@ namespace interprocess {
//-Use GetSecurityInfo?
//-Change everything to use only a shared memory object expanded via truncate()?
-//!A basic shared memory named object creation class. Initializes the
-//!shared memory segment. Inherits all basic functionality from
+//!A basic shared memory named object creation class. Initializes the
+//!shared memory segment. Inherits all basic functionality from
//!basic_managed_memory_impl<CharType, MemoryAlgorithm, IndexType>
template
<
- class CharType,
- class MemoryAlgorithm,
+ class CharType,
+ class MemoryAlgorithm,
template<class IndexConfig> class IndexType
>
-class basic_managed_multi_shared_memory
+class basic_managed_multi_shared_memory
: public ipcdetail::basic_managed_memory_impl
<CharType, MemoryAlgorithm, IndexType>
{
typedef basic_managed_multi_shared_memory
<CharType, MemoryAlgorithm, IndexType> self_t;
- typedef ipcdetail::basic_managed_memory_impl
+ typedef ipcdetail::basic_managed_memory_impl
<CharType, MemoryAlgorithm, IndexType> base_t;
-
+
typedef typename MemoryAlgorithm::void_pointer void_pointer;
typedef typename ipcdetail::
managed_open_or_create_impl<shared_memory_object, MemoryAlgorithm::Alignment> managed_impl;
@@ -91,7 +91,7 @@ class basic_managed_multi_shared_memory
// {
// public:
// segment_creator(shared_memory &shmem,
-// const char *mem_name,
+// const char *mem_name,
// const void *addr)
// : m_shmem(shmem), m_mem_name(mem_name), m_addr(addr){}
//
@@ -99,8 +99,8 @@ class basic_managed_multi_shared_memory
// {
// if(!m_shmem.create(m_mem_name, size, m_addr))
// return 0;
-// return m_shmem.get_address();
-// }
+// return m_shmem.get_address();
+// }
// private:
// shared_memory &m_shmem;
// const char *m_mem_name;
@@ -113,7 +113,7 @@ class basic_managed_multi_shared_memory
public:
typedef std::pair<void *, size_type> result_type;
typedef basic_managed_multi_shared_memory frontend_t;
- typedef typename
+ typedef typename
basic_managed_multi_shared_memory::void_pointer void_pointer;
typedef typename void_pointer::segment_group_id segment_group_id;
group_services(frontend_t *const frontend)
@@ -127,14 +127,14 @@ class basic_managed_multi_shared_memory
alloc_size += 1;
//If requested size is less than minimum, update that
- alloc_size = (m_min_segment_size > alloc_size) ?
+ alloc_size = (m_min_segment_size > alloc_size) ?
m_min_segment_size : alloc_size;
if(mp_frontend->priv_new_segment(create_open_func::DoCreate,
alloc_size, 0, permissions())){
typename shmem_list_t::value_type &m_impl = *mp_frontend->m_shmem_list.rbegin();
return result_type(m_impl.get_real_address(), m_impl.get_real_size()-1);
}*/
- return result_type(static_cast<void *>(0), 0);
+ return result_type(static_cast<void *>(0), 0);
}
virtual bool update_segments ()
@@ -166,7 +166,7 @@ class basic_managed_multi_shared_memory
struct create_open_func
{
enum type_t { DoCreate, DoOpen, DoOpenOrCreate };
- typedef typename
+ typedef typename
basic_managed_multi_shared_memory::void_pointer void_pointer;
create_open_func(self_t * const frontend,
@@ -174,8 +174,8 @@ class basic_managed_multi_shared_memory
: mp_frontend(frontend), m_type(type), m_segment_number(segment_number){}
bool operator()(void *addr, size_type size, bool created) const
- {
- if(((m_type == DoOpen) && created) ||
+ {
+ if(((m_type == DoOpen) && created) ||
((m_type == DoCreate) && !created))
return false;
segment_group_id group = mp_frontend->m_group_services.get_group();
@@ -191,7 +191,7 @@ class basic_managed_multi_shared_memory
//Check if this is the master segment
if(!m_segment_number){
//Create or open the Interprocess machinery
- if((impl_done = created ?
+ if((impl_done = created ?
mp_frontend->create_impl(addr, size) : mp_frontend->open_impl(addr, size))){
return true;
}
@@ -219,14 +219,14 @@ class basic_managed_multi_shared_memory
//!Functor to execute atomically when closing a shared memory segment.
struct close_func
{
- typedef typename
+ typedef typename
basic_managed_multi_shared_memory::void_pointer void_pointer;
close_func(self_t * const frontend)
: mp_frontend(frontend){}
void operator()(const mapped_region &region, bool last) const
- {
+ {
if(last) mp_frontend->destroy_impl();
else mp_frontend->close_impl();
}
@@ -251,7 +251,7 @@ class basic_managed_multi_shared_memory
const permissions &perm = permissions())
: m_group_services(get_this_pointer())
{
- priv_open_or_create(create_open_func::DoCreate,name, size, perm);
+ priv_open_or_create(create_open_func::DoCreate,name, size, perm);
}
basic_managed_multi_shared_memory(open_or_create_t,
@@ -273,7 +273,7 @@ class basic_managed_multi_shared_memory
{ this->priv_close(); }
private:
- bool priv_open_or_create(typename create_open_func::type_t type,
+ bool priv_open_or_create(typename create_open_func::type_t type,
const char *name,
size_type size,
const permissions &perm)
@@ -301,7 +301,7 @@ class basic_managed_multi_shared_memory
if(group){
void_pointer::delete_group(group);
}
- return false;
+ return false;
}
bool priv_new_segment(typename create_open_func::type_t type,
@@ -312,7 +312,7 @@ class basic_managed_multi_shared_memory
BOOST_TRY{
//Get the number of groups of this multi_segment group
size_type segment_id = m_shmem_list.size();
- //Format the name of the shared memory: append segment number.
+ //Format the name of the shared memory: append segment number.
boost::interprocess::basic_ovectorstream<boost::interprocess::string> formatter;
//Pre-reserve string size
size_type str_size = m_root_name.length()+10;
@@ -368,7 +368,7 @@ class basic_managed_multi_shared_memory
//!Frees resources. Never throws.
void priv_close()
- {
+ {
if(!m_shmem_list.empty()){
bool ret;
//Obtain group identifier
@@ -385,7 +385,7 @@ class basic_managed_multi_shared_memory
m_shmem_list.clear();
}
}
-
+
private:
shmem_list_t m_shmem_list;
group_services m_group_services;
diff --git a/boost/interprocess/detail/managed_open_or_create_impl.hpp b/boost/interprocess/detail/managed_open_or_create_impl.hpp
index 4d6997f330..a4f1f15817 100644
--- a/boost/interprocess/detail/managed_open_or_create_impl.hpp
+++ b/boost/interprocess/detail/managed_open_or_create_impl.hpp
@@ -48,12 +48,12 @@ class xsi_key;
template<>
struct managed_open_or_create_impl_device_id_t<xsi_shared_memory_file_wrapper>
-{
+{
typedef xsi_key type;
};
#endif //BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
-
+
/// @endcond
namespace ipcdetail {
@@ -79,7 +79,7 @@ class managed_open_or_create_impl_device_holder<true, DeviceAbstraction>
const DeviceAbstraction &get_device() const
{ return dev; }
-
+
private:
DeviceAbstraction dev;
};
@@ -94,16 +94,16 @@ class managed_open_or_create_impl
typedef typename managed_open_or_create_impl_device_id_t<DeviceAbstraction>::type device_id_t;
typedef managed_open_or_create_impl_device_holder<StoreDevice, DeviceAbstraction> DevHolder;
enum
- {
- UninitializedSegment,
- InitializingSegment,
+ {
+ UninitializedSegment,
+ InitializingSegment,
InitializedSegment,
CorruptedSegment
};
public:
static const std::size_t
- ManagedOpenOrCreateUserOffset =
+ ManagedOpenOrCreateUserOffset =
ct_rounded_size
< sizeof(boost::uint32_t)
, MemAlignment ? (MemAlignment) :
@@ -113,7 +113,7 @@ class managed_open_or_create_impl
managed_open_or_create_impl()
{}
- managed_open_or_create_impl(create_only_t,
+ managed_open_or_create_impl(create_only_t,
const device_id_t & id,
std::size_t size,
mode_t mode,
@@ -130,7 +130,7 @@ class managed_open_or_create_impl
, null_mapped_region_function());
}
- managed_open_or_create_impl(open_only_t,
+ managed_open_or_create_impl(open_only_t,
const device_id_t & id,
mode_t mode,
const void *addr)
@@ -146,7 +146,7 @@ class managed_open_or_create_impl
}
- managed_open_or_create_impl(open_or_create_t,
+ managed_open_or_create_impl(open_or_create_t,
const device_id_t & id,
std::size_t size,
mode_t mode,
@@ -164,7 +164,7 @@ class managed_open_or_create_impl
}
template <class ConstructFunc>
- managed_open_or_create_impl(create_only_t,
+ managed_open_or_create_impl(create_only_t,
const device_id_t & id,
std::size_t size,
mode_t mode,
@@ -183,7 +183,7 @@ class managed_open_or_create_impl
}
template <class ConstructFunc>
- managed_open_or_create_impl(open_only_t,
+ managed_open_or_create_impl(open_only_t,
const device_id_t & id,
mode_t mode,
const void *addr,
@@ -200,7 +200,7 @@ class managed_open_or_create_impl
}
template <class ConstructFunc>
- managed_open_or_create_impl(open_or_create_t,
+ managed_open_or_create_impl(open_or_create_t,
const device_id_t & id,
std::size_t size,
mode_t mode,
@@ -222,10 +222,10 @@ class managed_open_or_create_impl
{ this->swap(moved); }
managed_open_or_create_impl &operator=(BOOST_RV_REF(managed_open_or_create_impl) moved)
- {
+ {
managed_open_or_create_impl tmp(boost::move(moved));
this->swap(tmp);
- return *this;
+ return *this;
}
~managed_open_or_create_impl()
@@ -298,10 +298,10 @@ class managed_open_or_create_impl
tmp.swap(dev);
}
- template <class ConstructFunc> inline
+ template <class ConstructFunc> inline
void priv_open_or_create
- (create_enum_t type,
- const device_id_t & id,
+ (create_enum_t type,
+ const device_id_t & id,
std::size_t size,
mode_t mode, const void *addr,
const permissions &perm,
@@ -396,7 +396,8 @@ class managed_open_or_create_impl
if(previous == UninitializedSegment){
try{
- construct_func(static_cast<char*>(region.get_address()) + ManagedOpenOrCreateUserOffset, size - ManagedOpenOrCreateUserOffset, true);
+ construct_func( static_cast<char*>(region.get_address()) + ManagedOpenOrCreateUserOffset
+ , size - ManagedOpenOrCreateUserOffset, true);
//All ok, just move resources to the external mapped region
m_mapped_region.swap(region);
}
diff --git a/boost/interprocess/detail/math_functions.hpp b/boost/interprocess/detail/math_functions.hpp
index 08274160db..2fc457c683 100644
--- a/boost/interprocess/detail/math_functions.hpp
+++ b/boost/interprocess/detail/math_functions.hpp
@@ -4,7 +4,7 @@
// (C) Copyright Ion Gaztanaga 2007-2011.
//
// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// (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.
@@ -93,7 +93,7 @@ inline std::size_t floor_log2 (std::size_t x)
std::size_t n = x;
std::size_t log2 = 0;
-
+
for(std::size_t shift = Bits >> 1; shift; shift >>= 1){
std::size_t tmp = n >> shift;
if (tmp)
diff --git a/boost/interprocess/detail/min_max.hpp b/boost/interprocess/detail/min_max.hpp
index 75aa00f87b..1f4ebdfc33 100644
--- a/boost/interprocess/detail/min_max.hpp
+++ b/boost/interprocess/detail/min_max.hpp
@@ -21,7 +21,7 @@
#include <boost/interprocess/detail/workaround.hpp>
namespace boost {
-namespace interprocess {
+namespace interprocess {
template<class T>
const T &max_value(const T &a, const T &b)
@@ -31,7 +31,7 @@ template<class T>
const T &min_value(const T &a, const T &b)
{ return a < b ? a : b; }
-} //namespace interprocess {
+} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
diff --git a/boost/interprocess/detail/mpl.hpp b/boost/interprocess/detail/mpl.hpp
index c5b6f90ef1..e2c7f52d24 100644
--- a/boost/interprocess/detail/mpl.hpp
+++ b/boost/interprocess/detail/mpl.hpp
@@ -20,7 +20,7 @@
#include <cstddef>
namespace boost {
-namespace interprocess {
+namespace interprocess {
namespace ipcdetail {
template <class T, T val>
@@ -105,24 +105,24 @@ struct if_
template <class Pair>
-struct select1st
-// : public std::unary_function<Pair, typename Pair::first_type>
+struct select1st
+// : public std::unary_function<Pair, typename Pair::first_type>
{
template<class OtherPair>
- const typename Pair::first_type& operator()(const OtherPair& x) const
+ const typename Pair::first_type& operator()(const OtherPair& x) const
{ return x.first; }
- const typename Pair::first_type& operator()(const typename Pair::first_type& x) const
+ const typename Pair::first_type& operator()(const typename Pair::first_type& x) const
{ return x; }
};
// identity is an extension: it is not part of the standard.
template <class T>
-struct identity
-// : public std::unary_function<T,T>
+struct identity
+// : public std::unary_function<T,T>
{
typedef T type;
- const T& operator()(const T& x) const
+ const T& operator()(const T& x) const
{ return x; }
};
@@ -144,8 +144,8 @@ struct ls_zeros<1>
static const std::size_t value = 0;
};
-} //namespace ipcdetail {
-} //namespace interprocess {
+} //namespace ipcdetail {
+} //namespace interprocess {
} //namespace boost {
#endif //#ifndef BOOST_INTERPROCESS_DETAIL_MPL_HPP
diff --git a/boost/interprocess/detail/multi_segment_services.hpp b/boost/interprocess/detail/multi_segment_services.hpp
index 4b6cafc742..d1451d3379 100644
--- a/boost/interprocess/detail/multi_segment_services.hpp
+++ b/boost/interprocess/detail/multi_segment_services.hpp
@@ -20,7 +20,7 @@
/*!\file
- Describes a named shared memory allocation user class.
+ Describes a named shared memory allocation user class.
*/
namespace boost {
diff --git a/boost/interprocess/detail/named_proxy.hpp b/boost/interprocess/detail/named_proxy.hpp
index 604d7881ea..c2aafed9ac 100644
--- a/boost/interprocess/detail/named_proxy.hpp
+++ b/boost/interprocess/detail/named_proxy.hpp
@@ -24,7 +24,7 @@
#include <boost/interprocess/detail/mpl.hpp>
#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
-#include <boost/interprocess/detail/preprocessor.hpp>
+#include <boost/interprocess/detail/preprocessor.hpp>
#else
#include <boost/move/move.hpp>
#include <boost/interprocess/detail/variadic_templates_tools.hpp>
@@ -34,7 +34,7 @@
//!Describes a proxy class that implements named allocation syntax.
namespace boost {
-namespace interprocess {
+namespace interprocess {
namespace ipcdetail {
#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
@@ -83,7 +83,7 @@ struct CtorNArg : public placement_destroy<T>
{
this->expansion_helper(++get<IdxPack>(args_)...);
}
-
+
template<class ...ExpansionArgs>
void expansion_helper(ExpansionArgs &&...)
{}
@@ -93,11 +93,11 @@ struct CtorNArg : public placement_destroy<T>
{}
tuple<Args&...> args_;
-};
+};
//!Describes a proxy class that implements named
//!allocation syntax.
-template
+template
< class SegmentManager //segment manager to construct the object
, class T //type of object to build
, bool is_iterator //passing parameters are normal object or iterators?
@@ -119,10 +119,10 @@ class named_proxy
template<class ...Args>
T *operator()(Args &&...args) const
- {
+ {
CtorNArg<T, is_iterator, Args...> &&ctor_obj = CtorNArg<T, is_iterator, Args...>
(boost::forward<Args>(args)...);
- return mp_mngr->template
+ return mp_mngr->template
generic_construct<T>(mp_name, m_num, m_find, m_dothrow, ctor_obj);
}
@@ -199,7 +199,7 @@ struct Ctor0Arg : public placement_destroy<T>
// private:
// void construct(void *mem, true_)
// { new((void*)mem)T(*m_p1, *m_p2); }
-//
+//
// void construct(void *mem, false_)
// { new((void*)mem)T(m_p1, m_p2); }
//
@@ -270,7 +270,7 @@ struct Ctor0Arg : public placement_destroy<T>
//!Describes a proxy class that implements named
//!allocation syntax.
-template
+template
< class SegmentManager //segment manager to construct the object
, class T //type of object to build
, bool is_iterator //passing parameters are normal object or iterators?
@@ -293,9 +293,9 @@ class named_proxy
//!makes a named allocation and calls the
//!default constructor
T *operator()() const
- {
+ {
Ctor0Arg<T> ctor_obj;
- return mp_mngr->template
+ return mp_mngr->template
generic_construct<T>(mp_name, m_num, m_find, m_dothrow, ctor_obj);
}
//!
@@ -322,7 +322,7 @@ class named_proxy
////////////////////////////////////////////////////////////////////////
//
// template <class P1, class P2>
- // T *operator()(P1 &p1, P2 &p2) const
+ // T *operator()(P1 &p1, P2 &p2) const
// {
// typedef Ctor2Arg
// <T, is_iterator, P1, P2>
diff --git a/boost/interprocess/detail/os_file_functions.hpp b/boost/interprocess/detail/os_file_functions.hpp
index b680c57132..08decd9bc4 100644
--- a/boost/interprocess/detail/os_file_functions.hpp
+++ b/boost/interprocess/detail/os_file_functions.hpp
@@ -32,7 +32,7 @@
# include <cstdio>
# include <dirent.h>
# if 0
-# include <sys/file.h>
+# include <sys/file.h>
# endif
# else
# error Unknown platform
@@ -58,7 +58,7 @@ typedef enum { read_only = winapi::generic_read
, read_write = winapi::generic_read | winapi::generic_write
, copy_on_write
, read_private
- , invalid_mode = 0xffff
+ , invalid_mode = 0xffff
} mode_t;
typedef enum { file_begin = winapi::file_begin
@@ -96,28 +96,28 @@ inline const char *get_temporary_path()
inline file_handle_t create_new_file
(const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
-{
+{
unsigned long attr = temporary ? winapi::file_attribute_temporary : 0;
return winapi::create_file
( name, (unsigned int)mode, winapi::create_new, attr
- , (winapi::interprocess_security_attributes*)perm.get_permissions());
+ , (winapi::interprocess_security_attributes*)perm.get_permissions());
}
inline file_handle_t create_or_open_file
(const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
-{
+{
unsigned long attr = temporary ? winapi::file_attribute_temporary : 0;
return winapi::create_file
( name, (unsigned int)mode, winapi::open_always, attr
- , (winapi::interprocess_security_attributes*)perm.get_permissions());
+ , (winapi::interprocess_security_attributes*)perm.get_permissions());
}
inline file_handle_t open_existing_file
(const char *name, mode_t mode, bool temporary = false)
-{
+{
unsigned long attr = temporary ? winapi::file_attribute_temporary : 0;
return winapi::create_file
- (name, (unsigned int)mode, winapi::open_existing, attr, 0);
+ (name, (unsigned int)mode, winapi::open_existing, attr, 0);
}
inline bool delete_file(const char *name)
@@ -140,7 +140,7 @@ inline bool truncate_file (file_handle_t hnd, std::size_t size)
if(offset_t(size) > filesize){
if(!winapi::set_file_pointer_ex(hnd, filesize, 0, winapi::file_begin)){
return false;
- }
+ }
//We will write zeros in the end of the file
//since set_end_of_file does not guarantee this
for(std::size_t remaining = size - filesize, write_size = 0
@@ -177,7 +177,7 @@ inline bool get_file_pointer(file_handle_t hnd, offset_t &off)
{ return winapi::set_file_pointer_ex(hnd, 0, &off, winapi::file_current); }
inline bool write_file(file_handle_t hnd, const void *data, std::size_t numdata)
-{
+{
unsigned long written;
return 0 != winapi::write_file(hnd, data, (unsigned long)numdata, &written, 0);
}
@@ -189,9 +189,9 @@ inline bool close_file(file_handle_t hnd)
{ return 0 != winapi::close_handle(hnd); }
inline bool acquire_file_lock(file_handle_t hnd)
-{
+{
static winapi::interprocess_overlapped overlapped;
- const unsigned long len = 0xffffffff;
+ const unsigned long len = ~((unsigned long)(0u));
// winapi::interprocess_overlapped overlapped;
// std::memset(&overlapped, 0, sizeof(overlapped));
return winapi::lock_file_ex
@@ -199,44 +199,44 @@ inline bool acquire_file_lock(file_handle_t hnd)
}
inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
-{
- const unsigned long len = 0xffffffff;
+{
+ const unsigned long len = ~((unsigned long)(0u));
winapi::interprocess_overlapped overlapped;
std::memset(&overlapped, 0, sizeof(overlapped));
if(!winapi::lock_file_ex
- (hnd, winapi::lockfile_exclusive_lock | winapi::lockfile_fail_immediately,
+ (hnd, winapi::lockfile_exclusive_lock | winapi::lockfile_fail_immediately,
0, len, len, &overlapped)){
- return winapi::get_last_error() == winapi::error_lock_violation ?
+ return winapi::get_last_error() == winapi::error_lock_violation ?
acquired = false, true : false;
-
+
}
return (acquired = true);
}
inline bool release_file_lock(file_handle_t hnd)
-{
- const unsigned long len = 0xffffffff;
+{
+ const unsigned long len = ~((unsigned long)(0u));
winapi::interprocess_overlapped overlapped;
std::memset(&overlapped, 0, sizeof(overlapped));
return winapi::unlock_file_ex(hnd, 0, len, len, &overlapped);
}
inline bool acquire_file_lock_sharable(file_handle_t hnd)
-{
- const unsigned long len = 0xffffffff;
+{
+ const unsigned long len = ~((unsigned long)(0u));
winapi::interprocess_overlapped overlapped;
std::memset(&overlapped, 0, sizeof(overlapped));
return winapi::lock_file_ex(hnd, 0, 0, len, len, &overlapped);
}
inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired)
-{
- const unsigned long len = 0xffffffff;
+{
+ const unsigned long len = ~((unsigned long)(0u));
winapi::interprocess_overlapped overlapped;
std::memset(&overlapped, 0, sizeof(overlapped));
if(!winapi::lock_file_ex
(hnd, winapi::lockfile_fail_immediately, 0, len, len, &overlapped)){
- return winapi::get_last_error() == winapi::error_lock_violation ?
+ return winapi::get_last_error() == winapi::error_lock_violation ?
acquired = false, true : false;
}
return (acquired = true);
@@ -367,7 +367,7 @@ typedef enum { read_only = O_RDONLY
, read_write = O_RDWR
, copy_on_write
, read_private
- , invalid_mode = 0xffff
+ , invalid_mode = 0xffff
} mode_t;
typedef enum { file_begin = SEEK_SET
@@ -406,7 +406,7 @@ inline const char *get_temporary_path()
inline file_handle_t create_new_file
(const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
-{
+{
(void)temporary;
int ret = ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions());
if(ret >= 0){
@@ -439,7 +439,7 @@ inline file_handle_t create_or_open_file
inline file_handle_t open_existing_file
(const char *name, mode_t mode, bool temporary = false)
-{
+{
(void)temporary;
return ::open(name, (int)mode);
}
@@ -459,7 +459,7 @@ inline bool truncate_file (file_handle_t hnd, std::size_t size)
}
inline bool get_file_size(file_handle_t hnd, offset_t &size)
-{
+{
struct stat data;
bool ret = 0 == ::fstat(hnd, &data);
if(ret){
@@ -472,7 +472,7 @@ inline bool set_file_pointer(file_handle_t hnd, offset_t off, file_pos_t pos)
{ return ((off_t)(-1)) != ::lseek(hnd, off, (int)pos); }
inline bool get_file_pointer(file_handle_t hnd, offset_t &off)
-{
+{
off = ::lseek(hnd, 0, SEEK_CUR);
return off != ((off_t)-1);
}
@@ -522,7 +522,7 @@ inline bool release_file_lock(file_handle_t hnd)
}
inline bool acquire_file_lock_sharable(file_handle_t hnd)
-{
+{
struct ::flock lock;
lock.l_type = F_RDLCK;
lock.l_whence = SEEK_SET;
@@ -532,7 +532,7 @@ inline bool acquire_file_lock_sharable(file_handle_t hnd)
}
inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired)
-{
+{
struct flock lock;
lock.l_type = F_RDLCK;
lock.l_whence = SEEK_SET;
@@ -540,7 +540,7 @@ inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired)
lock.l_len = 0;
int ret = ::fcntl(hnd, F_SETLK, &lock);
if(ret == -1){
- return (errno == EAGAIN || errno == EACCES) ?
+ return (errno == EAGAIN || errno == EACCES) ?
acquired = false, true : false;
}
return (acquired = true);
@@ -601,7 +601,7 @@ inline bool delete_subdirectories_recursive
|| (de->d_name[1] == '.' && de->d_name[2] == '\0' )) ){
continue;
}
- if(dont_delete_this && std::strcmp(dont_delete_this, de->d_name) == 0){
+ if(dont_delete_this && std::strcmp(dont_delete_this, de->d_name) == 0){
continue;
}
fn = refcstrRootDirectory;
diff --git a/boost/interprocess/detail/os_thread_functions.hpp b/boost/interprocess/detail/os_thread_functions.hpp
index e49e82c8e0..8d769fc4e9 100644
--- a/boost/interprocess/detail/os_thread_functions.hpp
+++ b/boost/interprocess/detail/os_thread_functions.hpp
@@ -104,7 +104,7 @@ typedef pthread_t OS_thread_id_t;
typedef pid_t OS_process_id_t;
struct OS_systemwide_thread_id_t
-{
+{
OS_systemwide_thread_id_t()
: pid(), tid()
{}
@@ -153,7 +153,7 @@ inline OS_thread_id_t get_current_thread_id()
{ return ::pthread_self(); }
inline OS_thread_id_t get_invalid_thread_id()
-{
+{
static pthread_t invalid_id;
return invalid_id;
}
diff --git a/boost/interprocess/detail/pointer_type.hpp b/boost/interprocess/detail/pointer_type.hpp
index 7c45be085e..549b23fa6c 100644
--- a/boost/interprocess/detail/pointer_type.hpp
+++ b/boost/interprocess/detail/pointer_type.hpp
@@ -61,11 +61,11 @@ template <class T, class D>
struct pointer_type
{
typedef typename pointer_type_imp::pointer_type<T,
- typename ipcdetail::remove_reference<D>::type>::type type;
+ typename remove_reference<D>::type>::type type;
};
} //namespace ipcdetail {
-} //namespace interprocess {
+} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
diff --git a/boost/interprocess/detail/portable_intermodule_singleton.hpp b/boost/interprocess/detail/portable_intermodule_singleton.hpp
new file mode 100644
index 0000000000..eb2a13e104
--- /dev/null
+++ b/boost/interprocess/detail/portable_intermodule_singleton.hpp
@@ -0,0 +1,356 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009-2011. 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_PORTABLE_INTERMODULE_SINGLETON_HPP
+#define BOOST_INTERPROCESS_PORTABLE_INTERMODULE_SINGLETON_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#include <boost/interprocess/detail/managed_global_memory.hpp>
+#include <boost/interprocess/detail/intermodule_singleton_common.hpp>
+#include <boost/interprocess/shared_memory_object.hpp>
+#include <boost/interprocess/detail/atomic.hpp>
+#include <boost/interprocess/detail/os_thread_functions.hpp>
+#include <boost/interprocess/detail/tmp_dir_helpers.hpp>
+#include <boost/interprocess/detail/os_file_functions.hpp>
+#include <boost/interprocess/detail/file_locking_helpers.hpp>
+#include <boost/assert.hpp>
+#include <cstddef>
+#include <cstdio>
+#include <cstring>
+#include <string>
+
+namespace boost{
+namespace interprocess{
+namespace ipcdetail{
+
+typedef basic_managed_global_memory<shared_memory_object, true> managed_global_memory;
+
+namespace intermodule_singleton_helpers {
+
+static void create_tmp_subdir_and_get_pid_based_filepath
+ (const char *subdir_name, const char *file_prefix, OS_process_id_t pid, std::string &s, bool creation_time = false)
+{
+ //Let's create a lock file for each process gmem that will mark if
+ //the process is alive or not
+ create_tmp_and_clean_old(s);
+ s += "/";
+ s += subdir_name;
+ if(!open_or_create_directory(s.c_str())){
+ throw interprocess_exception(error_info(system_error_code()));
+ }
+ s += "/";
+ s += file_prefix;
+ if(creation_time){
+ std::string sstamp;
+ get_pid_creation_time_str(sstamp);
+ s += sstamp;
+ }
+ else{
+ pid_str_t pid_str;
+ get_pid_str(pid_str, pid);
+ s += pid_str;
+ }
+}
+
+static bool check_if_filename_complies_with_pid
+ (const char *filename, const char *prefix, OS_process_id_t pid, std::string &file_suffix, bool creation_time = false)
+{
+ //Check if filename complies with lock file name pattern
+ std::string fname(filename);
+ std::string fprefix(prefix);
+ if(fname.size() <= fprefix.size()){
+ return false;
+ }
+ fname.resize(fprefix.size());
+ if(fname != fprefix){
+ return false;
+ }
+
+ //If not our lock file, delete it if we can lock it
+ fname = filename;
+ fname.erase(0, fprefix.size());
+ pid_str_t pid_str;
+ get_pid_str(pid_str, pid);
+ file_suffix = pid_str;
+ if(creation_time){
+ std::size_t p = fname.find('_');
+ if (p == std::string::npos){
+ return false;
+ }
+ std::string save_suffix(fname);
+ fname.erase(p);
+ fname.swap(file_suffix);
+ bool ret = (file_suffix == fname);
+ file_suffix.swap(save_suffix);
+ return ret;
+ }
+ else{
+ fname.swap(file_suffix);
+ return (file_suffix == fname);
+ }
+}
+
+template<>
+struct thread_safe_global_map_dependant<managed_global_memory>
+{
+ private:
+ static const int GMemMarkToBeRemoved = -1;
+ static const int GMemNotPresent = -2;
+
+ static const char *get_lock_file_subdir_name()
+ { return "gmem"; }
+
+ static const char *get_lock_file_base_name()
+ { return "lck"; }
+
+ static void create_and_get_singleton_lock_file_path(std::string &s)
+ {
+ create_tmp_subdir_and_get_pid_based_filepath
+ (get_lock_file_subdir_name(), get_lock_file_base_name(), get_current_process_id(), s, true);
+ }
+
+ struct gmem_erase_func
+ {
+ gmem_erase_func(const char *shm_name, const char *singleton_lock_file_path, managed_global_memory & shm)
+ :shm_name_(shm_name), singleton_lock_file_path_(singleton_lock_file_path), shm_(shm)
+ {}
+
+ void operator()()
+ {
+ locking_file_serial_id *pserial_id = shm_.find<locking_file_serial_id>("lock_file_fd").first;
+ if(pserial_id){
+ pserial_id->fd = GMemMarkToBeRemoved;
+ }
+ delete_file(singleton_lock_file_path_);
+ shared_memory_object::remove(shm_name_);
+ }
+
+ const char * const shm_name_;
+ const char * const singleton_lock_file_path_;
+ managed_global_memory & shm_;
+ };
+
+ //This function applies shared memory erasure logic based on the passed lock file.
+ static void apply_gmem_erase_logic(const char *filepath, const char *filename)
+ {
+ int fd = GMemMarkToBeRemoved;
+ try{
+ std::string str;
+ //If the filename is current process lock file, then avoid it
+ if(check_if_filename_complies_with_pid
+ (filename, get_lock_file_base_name(), get_current_process_id(), str, true)){
+ return;
+ }
+ //Open and lock the other process' lock file
+ fd = try_open_and_lock_file(filepath);
+ if(fd < 0){
+ return;
+ }
+ //If done, then the process is dead so take global shared memory name
+ //(the name is based on the lock file name) and try to apply erasure logic
+ str.insert(0, get_map_base_name());
+ try{
+ managed_global_memory shm(open_only, str.c_str());
+ gmem_erase_func func(str.c_str(), filepath, shm);
+ shm.try_atomic_func(func);
+ }
+ catch(interprocess_exception &e){
+ //If shared memory is not found erase the lock file
+ if(e.get_error_code() == not_found_error){
+ delete_file(filepath);
+ }
+ }
+ }
+ catch(...){
+
+ }
+ if(fd >= 0){
+ close_lock_file(fd);
+ }
+ }
+
+ public:
+
+ static bool remove_old_gmem()
+ {
+ std::string refcstrRootDirectory;
+ tmp_folder(refcstrRootDirectory);
+ refcstrRootDirectory += "/";
+ refcstrRootDirectory += get_lock_file_subdir_name();
+ return for_each_file_in_dir(refcstrRootDirectory.c_str(), apply_gmem_erase_logic);
+ }
+
+ struct lock_file_logic
+ {
+ lock_file_logic(managed_global_memory &shm)
+ : mshm(shm)
+ { shm.atomic_func(*this); }
+
+ void operator()(void)
+ {
+ retry_with_new_map = false;
+
+ //First find the file locking descriptor id
+ locking_file_serial_id *pserial_id =
+ mshm.find<locking_file_serial_id>("lock_file_fd").first;
+
+ int fd;
+ //If not found schedule a creation
+ if(!pserial_id){
+ fd = GMemNotPresent;
+ }
+ //Else get it
+ else{
+ fd = pserial_id->fd;
+ }
+ //If we need to create a new one, do it
+ if(fd == GMemNotPresent){
+ std::string lck_str;
+ //Create a unique current pid based lock file path
+ create_and_get_singleton_lock_file_path(lck_str);
+ //Open or create and lock file
+ int fd = open_or_create_and_lock_file(lck_str.c_str());
+ //If failed, write a bad file descriptor to notify other modules that
+ //something was wrong and unlink shared memory. Mark the function object
+ //to tell caller to retry with another shared memory
+ if(fd < 0){
+ this->register_lock_file(GMemMarkToBeRemoved);
+ std::string s;
+ get_map_name(s);
+ shared_memory_object::remove(s.c_str());
+ retry_with_new_map = true;
+ }
+ //If successful, register the file descriptor
+ else{
+ this->register_lock_file(fd);
+ }
+ }
+ //If the fd was invalid (maybe a previous try failed) notify caller that
+ //should retry creation logic, since this shm might have been already
+ //unlinked since the shm was removed
+ else if (fd == GMemMarkToBeRemoved){
+ retry_with_new_map = true;
+ }
+ //If the stored fd is not valid (a open fd, a normal file with the
+ //expected size, or does not have the same file id number,
+ //then it's an old shm from an old process with the same pid.
+ //If that's the case, mark it as invalid
+ else if(!is_valid_fd(fd) ||
+ !is_normal_file(fd) ||
+ 0 != get_size(fd) ||
+ !compare_file_serial(fd, *pserial_id)){
+ pserial_id->fd = GMemMarkToBeRemoved;
+ std::string s;
+ get_map_name(s);
+ shared_memory_object::remove(s.c_str());
+ retry_with_new_map = true;
+ }
+ else{
+ //If the lock file is ok, increment reference count of
+ //attached modules to shared memory
+ atomic_inc32(&pserial_id->modules_attached_to_gmem_count);
+ }
+ }
+
+ bool retry() const { return retry_with_new_map; }
+
+ private:
+ locking_file_serial_id * register_lock_file(int fd)
+ {
+ locking_file_serial_id *pinfo = mshm.construct<locking_file_serial_id>("lock_file_fd")();
+ fill_file_serial_id(fd, *pinfo);
+ return pinfo;
+ }
+
+ managed_global_memory &mshm;
+ bool retry_with_new_map;
+ };
+
+ static void construct_map(void *addr)
+ {
+ std::string s;
+ intermodule_singleton_helpers::get_map_name(s);
+ const char *MapName = s.c_str();
+ const std::size_t MapSize = intermodule_singleton_helpers::get_map_size();;
+ ::new (addr)managed_global_memory(open_or_create, MapName, MapSize);
+ }
+
+ struct unlink_map_logic
+ {
+ unlink_map_logic(managed_global_memory &mshm)
+ : mshm_(mshm)
+ { mshm.atomic_func(*this); }
+
+ void operator()()
+ {
+ locking_file_serial_id *pserial_id =
+ mshm_.find<locking_file_serial_id>
+ ("lock_file_fd").first;
+ BOOST_ASSERT(0 != pserial_id);
+ if(1 == atomic_dec32(&pserial_id->modules_attached_to_gmem_count)){
+ int fd = pserial_id->fd;
+ if(fd > 0){
+ pserial_id->fd = GMemMarkToBeRemoved;
+ std::string s;
+ create_and_get_singleton_lock_file_path(s);
+ delete_file(s.c_str());
+ close_lock_file(fd);
+ intermodule_singleton_helpers::get_map_name(s);
+ shared_memory_object::remove(s.c_str());
+ }
+ }
+ }
+
+ private:
+ managed_global_memory &mshm_;
+ };
+
+ static ref_count_ptr *find(managed_global_memory &map, const char *name)
+ {
+ return map.find<ref_count_ptr>(name).first;
+ }
+
+ static ref_count_ptr *insert(managed_global_memory &map, const char *name, const ref_count_ptr &ref)
+ {
+ return map.construct<ref_count_ptr>(name)(ref);
+ }
+
+ static bool erase(managed_global_memory &map, const char *name)
+ {
+ return map.destroy<ref_count_ptr>(name);
+ }
+
+ template<class F>
+ static void atomic_func(managed_global_memory &map, F &f)
+ {
+ map.atomic_func(f);
+ }
+};
+
+} //namespace intermodule_singleton_helpers {
+
+template<typename C, bool LazyInit = true, bool Phoenix = true>
+class portable_intermodule_singleton
+ : public intermodule_singleton_impl<C, LazyInit, Phoenix, managed_global_memory>
+{};
+
+} //namespace ipcdetail{
+} //namespace interprocess{
+} //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_INTERPROCESS_PORTABLE_INTERMODULE_SINGLETON_HPP
diff --git a/boost/interprocess/detail/posix_time_types_wrk.hpp b/boost/interprocess/detail/posix_time_types_wrk.hpp
index c1276f0f26..e4df85a572 100644
--- a/boost/interprocess/detail/posix_time_types_wrk.hpp
+++ b/boost/interprocess/detail/posix_time_types_wrk.hpp
@@ -15,7 +15,7 @@
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
#define BOOST_INTERPROCESS_WIN32_LEAN_AND_MEAN
#endif //#ifndef WIN32_LEAN_AND_MEAN
#endif //#ifdef _WIN32
diff --git a/boost/interprocess/detail/preprocessor.hpp b/boost/interprocess/detail/preprocessor.hpp
index 4af2686452..47b591c901 100644
--- a/boost/interprocess/detail/preprocessor.hpp
+++ b/boost/interprocess/detail/preprocessor.hpp
@@ -21,7 +21,7 @@
#error "This file is not needed when perfect forwarding is available"
#endif
-#include <boost/preprocessor/iteration/local.hpp>
+#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
@@ -57,28 +57,30 @@
#ifndef BOOST_NO_RVALUE_REFERENCES
-#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+ #if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
-#define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
- BOOST_PP_CAT(m_p, n) (BOOST_INTERPROCESS_MOVE_NAMESPACE::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) )) \
-//!
+ #define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
+ BOOST_PP_CAT(m_p, n) (BOOST_PP_CAT(p, n)) \
+ //!
-#else
-#define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
- BOOST_PP_CAT(m_p, n) (BOOST_PP_CAT(p, n)) \
-//!
+ #else //#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
-#endif
+ #define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
+ BOOST_PP_CAT(m_p, n) (::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) )) \
+ //!
-#else
-#define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
- BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
-//!
+ #endif //#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+
+#else //#ifndef BOOST_NO_RVALUE_REFERENCES
+
+ #define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
+ BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
+ //!
#endif
#define BOOST_INTERPROCESS_PP_PARAM_INC(z, n, data) \
- BOOST_PP_CAT(++m_p, n) \
+ BOOST_PP_CAT(++m_p, n) \
//!
#ifndef BOOST_NO_RVALUE_REFERENCES
diff --git a/boost/interprocess/detail/ptime_wrk.hpp b/boost/interprocess/detail/ptime_wrk.hpp
index 4a4709e3a8..8cda3a445d 100644
--- a/boost/interprocess/detail/ptime_wrk.hpp
+++ b/boost/interprocess/detail/ptime_wrk.hpp
@@ -15,7 +15,7 @@
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
#define BOOST_INTERPROCESS_WIN32_LEAN_AND_MEAN
#endif //#ifndef WIN32_LEAN_AND_MEAN
#endif //#ifdef _WIN32
diff --git a/boost/interprocess/detail/robust_emulation.hpp b/boost/interprocess/detail/robust_emulation.hpp
index b2097d0ad7..1feb42dc35 100644
--- a/boost/interprocess/detail/robust_emulation.hpp
+++ b/boost/interprocess/detail/robust_emulation.hpp
@@ -68,7 +68,7 @@ inline void robust_lock_path(std::string &s)
inline void create_and_get_robust_lock_file_path(std::string &s, OS_process_id_t pid)
{
- file_locking_helpers::create_tmp_subdir_and_get_pid_based_filepath
+ intermodule_singleton_helpers::create_tmp_subdir_and_get_pid_based_filepath
(robust_lock_subdir_path(), robust_lock_prefix(), pid, s);
}
@@ -132,7 +132,7 @@ class robust_mutex_lock_file
throw interprocess_exception(other_error, "Robust emulation robust_mutex_lock_file constructor failed: create_file filed with unexpected error");
}
}
- }
+ }
~robust_mutex_lock_file()
{
@@ -154,7 +154,7 @@ class robust_mutex_lock_file
{
std::string pid_str;
//If the lock file is not our own lock file, then try to do the cleanup
- if(!file_locking_helpers::check_if_filename_complies_with_pid
+ if(!intermodule_singleton_helpers::check_if_filename_complies_with_pid
(filename, robust_lock_prefix(), get_current_process_id(), pid_str)){
remove_if_can_lock_file(filepath);
}
@@ -324,7 +324,7 @@ inline bool robust_spin_mutex<Mutex>::robust_check()
return false;
}
atomic_write32(&this->state, fixing_state);
- return true;
+ return true;
}
template<class Mutex>
@@ -424,7 +424,7 @@ template<class Mutex>
inline bool robust_spin_mutex<Mutex>::lock_own_unique_file()
{
//This function forces instantiation of the singleton
- robust_emulation_helpers::robust_mutex_lock_file* dummy =
+ robust_emulation_helpers::robust_mutex_lock_file* dummy =
&ipcdetail::intermodule_singleton
<robust_emulation_helpers::robust_mutex_lock_file>::get();
return dummy != 0;
diff --git a/boost/interprocess/detail/segment_manager_helper.hpp b/boost/interprocess/detail/segment_manager_helper.hpp
index ea820b3881..2b715d8f5e 100644
--- a/boost/interprocess/detail/segment_manager_helper.hpp
+++ b/boost/interprocess/detail/segment_manager_helper.hpp
@@ -91,7 +91,7 @@ struct block_header
, m_num_char((unsigned short)num_char)
, m_value_alignment((unsigned char)value_alignment)
, m_alloc_type_sizeof_char
- ( (alloc_type << 5u) |
+ ( (alloc_type << 5u) |
((unsigned char)sizeof_char & 0x1F) )
{};
@@ -130,7 +130,7 @@ struct block_header
template<class CharType>
CharType *name() const
- {
+ {
return const_cast<CharType*>(reinterpret_cast<const CharType*>
(reinterpret_cast<const char*>(this) + name_offset()));
}
@@ -139,7 +139,7 @@ struct block_header
{ return m_num_char; }
size_type name_offset() const
- {
+ {
return this->value_offset() + get_rounded_size(size_type(m_value_bytes), size_type(sizeof_char()));
}
@@ -157,7 +157,7 @@ struct block_header
bool less_comp(const block_header<size_type> &b) const
{
return m_num_char < b.m_num_char ||
- (m_num_char < b.m_num_char &&
+ (m_num_char < b.m_num_char &&
std::char_traits<CharType>::compare
(name<CharType>(), b.name<CharType>(), m_num_char) < 0);
}
@@ -175,10 +175,10 @@ struct block_header
{ return block_header_from_value(value, sizeof(T), ::boost::alignment_of<T>::value); }
static block_header<size_type> *block_header_from_value(const void *value, std::size_t sz, std::size_t algn)
- {
- block_header * hdr =
+ {
+ block_header * hdr =
const_cast<block_header*>
- (reinterpret_cast<const block_header*>(reinterpret_cast<const char*>(value) -
+ (reinterpret_cast<const block_header*>(reinterpret_cast<const char*>(value) -
get_rounded_size(sizeof(block_header), algn)));
(void)sz;
//Some sanity checks
@@ -189,9 +189,9 @@ struct block_header
template<class Header>
static block_header<size_type> *from_first_header(Header *header)
- {
- block_header<size_type> * hdr =
- reinterpret_cast<block_header<size_type>*>(reinterpret_cast<char*>(header) +
+ {
+ block_header<size_type> * hdr =
+ reinterpret_cast<block_header<size_type>*>(reinterpret_cast<char*>(header) +
get_rounded_size(size_type(sizeof(Header)), size_type(::boost::alignment_of<block_header<size_type> >::value)));
//Some sanity checks
return hdr;
@@ -199,9 +199,9 @@ struct block_header
template<class Header>
static Header *to_first_header(block_header<size_type> *bheader)
- {
- Header * hdr =
- reinterpret_cast<Header*>(reinterpret_cast<char*>(bheader) -
+ {
+ Header * hdr =
+ reinterpret_cast<Header*>(reinterpret_cast<char*>(bheader) -
get_rounded_size(size_type(sizeof(Header)), size_type(::boost::alignment_of<block_header<size_type> >::value)));
//Some sanity checks
return hdr;
@@ -311,15 +311,15 @@ template<class CharType>
class char_ptr_holder
{
public:
- char_ptr_holder(const CharType *name)
+ char_ptr_holder(const CharType *name)
: m_name(name)
{}
- char_ptr_holder(const anonymous_instance_t *)
+ char_ptr_holder(const anonymous_instance_t *)
: m_name(static_cast<CharType*>(0))
{}
- char_ptr_holder(const unique_instance_t *)
+ char_ptr_holder(const unique_instance_t *)
: m_name(reinterpret_cast<CharType*>(-1))
{}
@@ -330,7 +330,7 @@ class char_ptr_holder
const CharType *m_name;
};
-//!The key of the the named allocation information index. Stores an offset pointer
+//!The key of the the named allocation information index. Stores an offset pointer
//!to a null terminated string and the length of the string to speed up sorting
template<class CharT, class VoidPointer>
struct index_key
@@ -356,9 +356,9 @@ struct index_key
//!Less than function for index ordering
bool operator < (const index_key & right) const
{
- return (m_len < right.m_len) ||
- (m_len == right.m_len &&
- std::char_traits<char_type>::compare
+ return (m_len < right.m_len) ||
+ (m_len == right.m_len &&
+ std::char_traits<char_type>::compare
(to_raw_pointer(mp_str)
,to_raw_pointer(right.mp_str), m_len) < 0);
}
@@ -366,8 +366,8 @@ struct index_key
//!Equal to function for index ordering
bool operator == (const index_key & right) const
{
- return m_len == right.m_len &&
- std::char_traits<char_type>::compare
+ return m_len == right.m_len &&
+ std::char_traits<char_type>::compare
(to_raw_pointer(mp_str),
to_raw_pointer(right.mp_str), m_len) == 0;
}
@@ -478,14 +478,14 @@ struct segment_manager_iterator_transform
, segment_manager_iterator_value_adaptor<Iterator, intrusive> >
{
typedef segment_manager_iterator_value_adaptor<Iterator, intrusive> result_type;
-
+
result_type operator()(const typename Iterator::value_type &arg) const
{ return result_type(arg); }
};
} //namespace ipcdetail {
-//These pointers are the ones the user will use to
+//These pointers are the ones the user will use to
//indicate previous allocation types
static const ipcdetail::anonymous_instance_t * anonymous_instance = 0;
static const ipcdetail::unique_instance_t * unique_instance = 0;
diff --git a/boost/interprocess/detail/tmp_dir_helpers.hpp b/boost/interprocess/detail/tmp_dir_helpers.hpp
index 38aafb2beb..28e7341406 100644
--- a/boost/interprocess/detail/tmp_dir_helpers.hpp
+++ b/boost/interprocess/detail/tmp_dir_helpers.hpp
@@ -18,80 +18,87 @@
#include <boost/interprocess/exceptions.hpp>
#include <string>
-#if defined(BOOST_INTERPROCESS_WINDOWS)
- //#define BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME
- //#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
- //#include <boost/interprocess/detail/win32_api.hpp>
-#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
- //#include <sys/sysctl.h>
- //#if defined(CTL_KERN) && defined (KERN_BOOTTIME)
- //#define BOOST_INTERPROCESS_HAS_BSD_KERNEL_BOOTTIME
- //#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
- //#endif
+#if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME) && defined(BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
#endif
namespace boost {
namespace interprocess {
namespace ipcdetail {
-#if defined (BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME)
-inline void get_bootstamp(std::string &s, bool add = false)
-{
- std::string bootstamp;
- winapi::get_last_bootup_time(bootstamp);
- if(add){
- s += bootstamp;
- }
- else{
- s.swap(bootstamp);
- }
-}
-#elif defined(BOOST_INTERPROCESS_HAS_BSD_KERNEL_BOOTTIME)
-inline void get_bootstamp(std::string &s, bool add = false)
-{
- // FreeBSD specific: sysctl "kern.boottime"
- int request[2] = { CTL_KERN, KERN_BOOTTIME };
- struct ::timeval result;
- std::size_t result_len = sizeof result;
-
- if (::sysctl (request, 2, &result, &result_len, NULL, 0) < 0)
- return;
-
- char bootstamp_str[256];
-
- 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;
- //32 bit values to allow 32 and 64 bit process IPC
- boost::uint32_t fields[2] = { boost::uint32_t(result.tv_sec), boost::uint32_t(result.tv_usec) };
- for(std::size_t field = 0; field != 2; ++field){
- for(std::size_t i = 0; i != sizeof(fields[0]); ++i){
- const char *ptr = (const char *)&fields[field];
- bootstamp_str[char_counter++] = Characters[(ptr[i]&0xF0)>>4];
- bootstamp_str[char_counter++] = Characters[(ptr[i]&0x0F)];
+#if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME)
+ #if defined(BOOST_INTERPROCESS_WINDOWS)
+ //This type will initialize the stamp
+ struct windows_bootstamp
+ {
+ windows_bootstamp()
+ {
+ winapi::get_last_bootup_time(stamp);
+ }
+ //Use std::string. Even if this will be constructed in shared memory, all
+ //modules/dlls are from this process so internal raw pointers to heap are always valid
+ std::string stamp;
+ };
+
+ inline void get_bootstamp(std::string &s, bool add = false)
+ {
+ const windows_bootstamp &bootstamp = windows_intermodule_singleton<windows_bootstamp>::get();
+ if(add){
+ s += bootstamp.stamp;
+ }
+ else{
+ s = bootstamp.stamp;
+ }
}
- }
- bootstamp_str[char_counter] = 0;
- if(add){
- s += bootstamp_str;
- }
- else{
- s = bootstamp_str;
- }
-}
-#endif
+ #elif defined(BOOST_INTERPROCESS_HAS_BSD_KERNEL_BOOTTIME)
+ inline void get_bootstamp(std::string &s, bool add = false)
+ {
+ // FreeBSD specific: sysctl "kern.boottime"
+ int request[2] = { CTL_KERN, KERN_BOOTTIME };
+ struct ::timeval result;
+ std::size_t result_len = sizeof result;
+
+ if (::sysctl (request, 2, &result, &result_len, NULL, 0) < 0)
+ return;
+
+ char bootstamp_str[256];
+
+ 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;
+ //32 bit values to allow 32 and 64 bit process IPC
+ boost::uint32_t fields[2] = { boost::uint32_t(result.tv_sec), boost::uint32_t(result.tv_usec) };
+ for(std::size_t field = 0; field != 2; ++field){
+ for(std::size_t i = 0; i != sizeof(fields[0]); ++i){
+ const char *ptr = (const char *)&fields[field];
+ bootstamp_str[char_counter++] = Characters[(ptr[i]&0xF0)>>4];
+ bootstamp_str[char_counter++] = Characters[(ptr[i]&0x0F)];
+ }
+ }
+ bootstamp_str[char_counter] = 0;
+ if(add){
+ s += bootstamp_str;
+ }
+ else{
+ s = bootstamp_str;
+ }
+ }
+ #else
+ #error "BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME defined with no known implementation"
+ #endif
+#endif //#if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME)
inline void get_tmp_base_dir(std::string &tmp_name)
{
#if defined (BOOST_INTERPROCESS_WINDOWS)
- winapi::get_shared_documents_folder(tmp_name);
- if(tmp_name.empty() || !winapi::is_directory(tmp_name.c_str())){
- tmp_name = get_temporary_path();
- }
+ winapi::get_shared_documents_folder(tmp_name);
+ if(tmp_name.empty() || !winapi::is_directory(tmp_name.c_str())){
+ tmp_name = get_temporary_path();
+ }
#else
- tmp_name = get_temporary_path();
+ tmp_name = get_temporary_path();
#endif
if(tmp_name.empty()){
error_info err = system_error_code();
@@ -104,9 +111,9 @@ inline void get_tmp_base_dir(std::string &tmp_name)
inline void tmp_folder(std::string &tmp_name)
{
get_tmp_base_dir(tmp_name);
- #ifdef BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
- tmp_name += "/";
- get_bootstamp(tmp_name, true);
+ #if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME)
+ tmp_name += "/";
+ get_bootstamp(tmp_name, true);
#endif
}
@@ -131,22 +138,22 @@ inline void create_tmp_and_clean_old(std::string &tmp_name)
}
}
- #ifdef BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
- tmp_folder(tmp_name);
+ #if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME)
+ tmp_folder(tmp_name);
- //If fails, check that it's because already exists
- if(!create_directory(tmp_name.c_str())){
- error_info info(system_error_code());
- if(info.get_error_code() != already_exists_error){
- throw interprocess_exception(info);
+ //If fails, check that it's because already exists
+ if(!create_directory(tmp_name.c_str())){
+ error_info info(system_error_code());
+ if(info.get_error_code() != already_exists_error){
+ throw interprocess_exception(info);
+ }
}
- }
- //Now erase all old directories created in the previous boot sessions
- std::string subdir = tmp_name;
- subdir.erase(0, root_tmp_name.size()+1);
- delete_subdirectories(root_tmp_name, subdir.c_str());
+ //Now erase all old directories created in the previous boot sessions
+ std::string subdir = tmp_name;
+ subdir.erase(0, root_tmp_name.size()+1);
+ delete_subdirectories(root_tmp_name, subdir.c_str());
#else
- tmp_name = root_tmp_name;
+ tmp_name = root_tmp_name;
#endif
}
diff --git a/boost/interprocess/detail/transform_iterator.hpp b/boost/interprocess/detail/transform_iterator.hpp
index ef646fbefe..922c875d6d 100644
--- a/boost/interprocess/detail/transform_iterator.hpp
+++ b/boost/interprocess/detail/transform_iterator.hpp
@@ -27,7 +27,7 @@
#include <boost/interprocess/detail/type_traits.hpp>
namespace boost {
-namespace interprocess {
+namespace interprocess {
template <class PseudoReference>
struct operator_arrow_proxy
@@ -77,7 +77,7 @@ class transform_iterator
{}
//Constructors
- transform_iterator& operator++()
+ transform_iterator& operator++()
{ increment(); return *this; }
transform_iterator operator++(int)
@@ -87,7 +87,7 @@ class transform_iterator
return result;
}
- transform_iterator& operator--()
+ transform_iterator& operator--()
{ decrement(); return *this; }
transform_iterator operator--(int)
@@ -186,7 +186,7 @@ make_transform_iterator(Iterator it, UnaryFunc fun)
return transform_iterator<Iterator, UnaryFunc>(it, fun);
}
-} //namespace interprocess {
+} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
diff --git a/boost/interprocess/detail/type_traits.hpp b/boost/interprocess/detail/type_traits.hpp
index 2cfa0be291..7a582fee5c 100644
--- a/boost/interprocess/detail/type_traits.hpp
+++ b/boost/interprocess/detail/type_traits.hpp
@@ -20,7 +20,7 @@
#include <boost/interprocess/detail/config_begin.hpp>
namespace boost {
-namespace interprocess {
+namespace interprocess {
namespace ipcdetail {
struct nat{};
@@ -137,7 +137,7 @@ struct is_same
};
} // namespace ipcdetail
-} //namespace interprocess {
+} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
diff --git a/boost/interprocess/detail/utilities.hpp b/boost/interprocess/detail/utilities.hpp
index 625a9159d3..fcb211fb09 100644
--- a/boost/interprocess/detail/utilities.hpp
+++ b/boost/interprocess/detail/utilities.hpp
@@ -35,7 +35,7 @@
#include <algorithm>
namespace boost {
-namespace interprocess {
+namespace interprocess {
namespace ipcdetail {
template <class T>
@@ -138,9 +138,9 @@ template<class Cont>
class value_eraser
{
public:
- value_eraser(Cont & cont, typename Cont::iterator it)
+ value_eraser(Cont & cont, typename Cont::iterator it)
: m_cont(cont), m_index_it(it), m_erase(true){}
- ~value_eraser()
+ ~value_eraser()
{ if(m_erase) m_cont.erase(m_index_it); }
void release() { m_erase = false; }
@@ -151,7 +151,7 @@ class value_eraser
bool m_erase;
};
-} //namespace interprocess {
+} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
diff --git a/boost/interprocess/detail/variadic_templates_tools.hpp b/boost/interprocess/detail/variadic_templates_tools.hpp
index 1e6c4216e3..482a0056a7 100644
--- a/boost/interprocess/detail/variadic_templates_tools.hpp
+++ b/boost/interprocess/detail/variadic_templates_tools.hpp
@@ -21,7 +21,7 @@
#include <cstddef> //std::size_t
namespace boost {
-namespace interprocess {
+namespace interprocess {
namespace ipcdetail {
template<typename... Values>
@@ -136,7 +136,7 @@ struct index_tuple{};
template<std::size_t Num, typename Tuple = index_tuple<> >
struct build_number_seq;
-template<std::size_t Num, int... Indexes>
+template<std::size_t Num, int... Indexes>
struct build_number_seq<Num, index_tuple<Indexes...> >
: build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> >
{};
diff --git a/boost/interprocess/detail/win32_api.hpp b/boost/interprocess/detail/win32_api.hpp
index b420c3d67b..c53725ca3b 100644
--- a/boost/interprocess/detail/win32_api.hpp
+++ b/boost/interprocess/detail/win32_api.hpp
@@ -46,6 +46,7 @@ namespace winapi {
//Some used constants
static const unsigned long infinite_time = 0xFFFFFFFF;
static const unsigned long error_already_exists = 183L;
+static const unsigned long error_invalid_handle = 6L;
static const unsigned long error_sharing_violation = 32L;
static const unsigned long error_file_not_found = 2u;
static const unsigned long error_no_more_files = 18u;
@@ -137,7 +138,14 @@ static const unsigned long lang_neutral = (unsigned long)0x00;
static const unsigned long sublang_default = (unsigned long)0x01;
static const unsigned long invalid_file_size = (unsigned long)0xFFFFFFFF;
static const unsigned long invalid_file_attributes = ((unsigned long)-1);
-static void * const invalid_handle_value = (void*)(long)(-1);
+static void * const invalid_handle_value = ((void*)(long)(-1));
+
+static const unsigned long file_type_char = 0x0002L;
+static const unsigned long file_type_disk = 0x0001L;
+static const unsigned long file_type_pipe = 0x0003L;
+static const unsigned long file_type_remote = 0x8000L;
+static const unsigned long file_type_unknown = 0x0000L;
+
static const unsigned long create_new = 1;
static const unsigned long create_always = 2;
static const unsigned long open_existing = 3;
@@ -159,7 +167,6 @@ static const long BootAndSystemstampLength = 16;
static const long BootstampLength = 8;
static const unsigned long MaxPath = 260;
-
//Keys
static void * const hkey_local_machine = (void*)(unsigned long*)(long)(0x80000002);
static unsigned long key_query_value = 0x0001;
@@ -179,6 +186,27 @@ const signed long WBEM_INFINITE_BIPC = 0xffffffffL;
const signed long RPC_E_TOO_LATE_BIPC = 0x80010119L;
const signed long S_OK_BIPC = 0L;
const signed long S_FALSE_BIPC = 1;
+const signed long RPC_E_CHANGED_MODE_BIPC = 0x80010106L;
+const unsigned long COINIT_APARTMENTTHREADED_BIPC = 0x2;
+const unsigned long COINIT_MULTITHREADED_BIPC = 0x0;
+const unsigned long COINIT_DISABLE_OLE1DDE_BIPC = 0x4;
+const unsigned long COINIT_SPEED_OVER_MEMORY_BIPC = 0x4;
+
+//If the user needs to change default COM initialization model,
+//it can define BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL to one of these:
+//
+// COINIT_APARTMENTTHREADED_BIPC
+// COINIT_MULTITHREADED_BIPC
+// COINIT_DISABLE_OLE1DDE_BIPC
+// COINIT_SPEED_OVER_MEMORY_BIPC
+#if !defined(BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL)
+ #define BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL COINIT_APARTMENTTHREADED_BIPC
+#elif (BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL != COINIT_APARTMENTTHREADED_BIPC) &&\
+ (BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL != COINIT_MULTITHREADED_BIPC) &&\
+ (BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL != COINIT_DISABLE_OLE1DDE_BIPC) &&\
+ (BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL != COINIT_SPEED_OVER_MEMORY_BIPC)
+ #error "Wrong value for BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL macro"
+#endif
} //namespace winapi {
} //namespace interprocess {
@@ -214,158 +242,158 @@ struct wchar_variant
struct IUnknown_BIPC
{
public:
- virtual long __stdcall QueryInterface(
+ virtual long __stdcall QueryInterface(
/* [in] */ const GUID_BIPC &riid,
/* [iid_is][out] */ void **ppvObject) = 0;
-
+
virtual unsigned long __stdcall AddRef( void) = 0;
-
+
virtual unsigned long __stdcall Release( void) = 0;
};
struct IWbemClassObject_BIPC : public IUnknown_BIPC
{
public:
- virtual long __stdcall GetQualifierSet(
+ virtual long __stdcall GetQualifierSet(
/* [out] */ void **ppQualSet) = 0;
-
- virtual long __stdcall Get(
+
+ virtual long __stdcall Get(
/* [string][in] */ const wchar_t * wszName,
/* [in] */ long lFlags,
/* [unique][in][out] */ wchar_variant *pVal,
/* [unique][in][out] */ long *pType,
/* [unique][in][out] */ long *plFlavor) = 0;
-
- virtual long __stdcall Put(
+
+ virtual long __stdcall Put(
/* [string][in] */ const wchar_t * wszName,
/* [in] */ long lFlags,
/* [in] */ wchar_variant *pVal,
/* [in] */ long Type) = 0;
-
- virtual long __stdcall Delete(
+
+ virtual long __stdcall Delete(
/* [string][in] */ const wchar_t * wszName) = 0;
-
- virtual long __stdcall GetNames(
+
+ virtual long __stdcall GetNames(
/* [string][in] */ const wchar_t * wszQualifierName,
/* [in] */ long lFlags,
/* [in] */ wchar_variant *pQualifierVal,
/* [out] */ void * *pNames) = 0;
-
- virtual long __stdcall BeginEnumeration(
+
+ virtual long __stdcall BeginEnumeration(
/* [in] */ long lEnumFlags) = 0;
-
- virtual long __stdcall Next(
+
+ virtual long __stdcall Next(
/* [in] */ long lFlags,
/* [unique][in][out] */ wchar_t * *strName,
/* [unique][in][out] */ wchar_variant *pVal,
/* [unique][in][out] */ long *pType,
/* [unique][in][out] */ long *plFlavor) = 0;
-
+
virtual long __stdcall EndEnumeration( void) = 0;
-
- virtual long __stdcall GetPropertyQualifierSet(
+
+ virtual long __stdcall GetPropertyQualifierSet(
/* [string][in] */ const wchar_t * wszProperty,
/* [out] */ void **ppQualSet) = 0;
-
- virtual long __stdcall Clone(
+
+ virtual long __stdcall Clone(
/* [out] */ IWbemClassObject_BIPC **ppCopy) = 0;
-
- virtual long __stdcall GetObjectText(
+
+ virtual long __stdcall GetObjectText(
/* [in] */ long lFlags,
/* [out] */ wchar_t * *pstrObjectText) = 0;
-
- virtual long __stdcall SpawnDerivedClass(
+
+ virtual long __stdcall SpawnDerivedClass(
/* [in] */ long lFlags,
/* [out] */ IWbemClassObject_BIPC **ppNewClass) = 0;
-
- virtual long __stdcall SpawnInstance(
+
+ virtual long __stdcall SpawnInstance(
/* [in] */ long lFlags,
/* [out] */ IWbemClassObject_BIPC **ppNewInstance) = 0;
-
- virtual long __stdcall CompareTo(
+
+ virtual long __stdcall CompareTo(
/* [in] */ long lFlags,
/* [in] */ IWbemClassObject_BIPC *pCompareTo) = 0;
-
- virtual long __stdcall GetPropertyOrigin(
+
+ virtual long __stdcall GetPropertyOrigin(
/* [string][in] */ const wchar_t * wszName,
/* [out] */ wchar_t * *pstrClassName) = 0;
-
- virtual long __stdcall InheritsFrom(
+
+ virtual long __stdcall InheritsFrom(
/* [in] */ const wchar_t * strAncestor) = 0;
-
- virtual long __stdcall GetMethod(
+
+ virtual long __stdcall GetMethod(
/* [string][in] */ const wchar_t * wszName,
/* [in] */ long lFlags,
/* [out] */ IWbemClassObject_BIPC **ppInSignature,
/* [out] */ IWbemClassObject_BIPC **ppOutSignature) = 0;
-
- virtual long __stdcall PutMethod(
+
+ virtual long __stdcall PutMethod(
/* [string][in] */ const wchar_t * wszName,
/* [in] */ long lFlags,
/* [in] */ IWbemClassObject_BIPC *pInSignature,
/* [in] */ IWbemClassObject_BIPC *pOutSignature) = 0;
-
- virtual long __stdcall DeleteMethod(
+
+ virtual long __stdcall DeleteMethod(
/* [string][in] */ const wchar_t * wszName) = 0;
-
- virtual long __stdcall BeginMethodEnumeration(
+
+ virtual long __stdcall BeginMethodEnumeration(
/* [in] */ long lEnumFlags) = 0;
-
- virtual long __stdcall NextMethod(
+
+ virtual long __stdcall NextMethod(
/* [in] */ long lFlags,
/* [unique][in][out] */ wchar_t * *pstrName,
/* [unique][in][out] */ IWbemClassObject_BIPC **ppInSignature,
/* [unique][in][out] */ IWbemClassObject_BIPC **ppOutSignature) = 0;
-
+
virtual long __stdcall EndMethodEnumeration( void) = 0;
-
- virtual long __stdcall GetMethodQualifierSet(
+
+ virtual long __stdcall GetMethodQualifierSet(
/* [string][in] */ const wchar_t * wszMethod,
/* [out] */ void **ppQualSet) = 0;
-
- virtual long __stdcall GetMethodOrigin(
+
+ virtual long __stdcall GetMethodOrigin(
/* [string][in] */ const wchar_t * wszMethodName,
/* [out] */ wchar_t * *pstrClassName) = 0;
-
+
};
struct IWbemContext_BIPC : public IUnknown_BIPC
{
public:
- virtual long __stdcall Clone(
+ virtual long __stdcall Clone(
/* [out] */ IWbemContext_BIPC **ppNewCopy) = 0;
-
- virtual long __stdcall GetNames(
+
+ virtual long __stdcall GetNames(
/* [in] */ long lFlags,
/* [out] */ void * *pNames) = 0;
-
- virtual long __stdcall BeginEnumeration(
+
+ virtual long __stdcall BeginEnumeration(
/* [in] */ long lFlags) = 0;
-
- virtual long __stdcall Next(
+
+ virtual long __stdcall Next(
/* [in] */ long lFlags,
/* [out] */ wchar_t * *pstrName,
/* [out] */ wchar_variant *pValue) = 0;
-
+
virtual long __stdcall EndEnumeration( void) = 0;
-
- virtual long __stdcall SetValue(
+
+ virtual long __stdcall SetValue(
/* [string][in] */ const wchar_t * wszName,
/* [in] */ long lFlags,
/* [in] */ wchar_variant *pValue) = 0;
-
- virtual long __stdcall GetValue(
+
+ virtual long __stdcall GetValue(
/* [string][in] */ const wchar_t * wszName,
/* [in] */ long lFlags,
/* [out] */ wchar_variant *pValue) = 0;
-
- virtual long __stdcall DeleteValue(
+
+ virtual long __stdcall DeleteValue(
/* [string][in] */ const wchar_t * wszName,
/* [in] */ long lFlags) = 0;
-
+
virtual long __stdcall DeleteAll( void) = 0;
-
+
};
@@ -373,157 +401,157 @@ struct IEnumWbemClassObject_BIPC : public IUnknown_BIPC
{
public:
virtual long __stdcall Reset( void) = 0;
-
- virtual long __stdcall Next(
+
+ virtual long __stdcall Next(
/* [in] */ long lTimeout,
/* [in] */ unsigned long uCount,
/* [length_is][size_is][out] */ IWbemClassObject_BIPC **apObjects,
/* [out] */ unsigned long *puReturned) = 0;
-
- virtual long __stdcall NextAsync(
+
+ virtual long __stdcall NextAsync(
/* [in] */ unsigned long uCount,
/* [in] */ void *pSink) = 0;
-
- virtual long __stdcall Clone(
+
+ virtual long __stdcall Clone(
/* [out] */ void **ppEnum) = 0;
-
- virtual long __stdcall Skip(
+
+ virtual long __stdcall Skip(
/* [in] */ long lTimeout,
/* [in] */ unsigned long nCount) = 0;
-
+
};
struct IWbemServices_BIPC : public IUnknown_BIPC
{
public:
- virtual long __stdcall OpenNamespace(
+ virtual long __stdcall OpenNamespace(
/* [in] */ const wchar_t * strNamespace,
/* [in] */ long lFlags,
/* [in] */ void *pCtx,
/* [unique][in][out] */ void **ppWorkingNamespace,
/* [unique][in][out] */ void **ppResult) = 0;
-
- virtual long __stdcall CancelAsyncCall(
+
+ virtual long __stdcall CancelAsyncCall(
/* [in] */ void *pSink) = 0;
-
- virtual long __stdcall QueryObjectSink(
+
+ virtual long __stdcall QueryObjectSink(
/* [in] */ long lFlags,
/* [out] */ void **ppResponseHandler) = 0;
-
- virtual long __stdcall GetObject(
+
+ virtual long __stdcall GetObject(
/* [in] */ const wchar_t * strObjectPath,
/* [in] */ long lFlags,
/* [in] */ void *pCtx,
/* [unique][in][out] */ void **ppObject,
/* [unique][in][out] */ void **ppCallResult) = 0;
-
- virtual long __stdcall GetObjectAsync(
+
+ virtual long __stdcall GetObjectAsync(
/* [in] */ const wchar_t * strObjectPath,
/* [in] */ long lFlags,
/* [in] */ void *pCtx,
/* [in] */ void *pResponseHandler) = 0;
-
- virtual long __stdcall PutClass(
+
+ virtual long __stdcall PutClass(
/* [in] */ IWbemClassObject_BIPC *pObject,
/* [in] */ long lFlags,
/* [in] */ void *pCtx,
/* [unique][in][out] */ void **ppCallResult) = 0;
-
- virtual long __stdcall PutClassAsync(
+
+ virtual long __stdcall PutClassAsync(
/* [in] */ IWbemClassObject_BIPC *pObject,
/* [in] */ long lFlags,
/* [in] */ void *pCtx,
/* [in] */ void *pResponseHandler) = 0;
-
- virtual long __stdcall DeleteClass(
+
+ virtual long __stdcall DeleteClass(
/* [in] */ const wchar_t * strClass,
/* [in] */ long lFlags,
/* [in] */ void *pCtx,
/* [unique][in][out] */ void **ppCallResult) = 0;
-
- virtual long __stdcall DeleteClassAsync(
+
+ virtual long __stdcall DeleteClassAsync(
/* [in] */ const wchar_t * strClass,
/* [in] */ long lFlags,
/* [in] */ void *pCtx,
/* [in] */ void *pResponseHandler) = 0;
-
- virtual long __stdcall CreateClassEnum(
+
+ virtual long __stdcall CreateClassEnum(
/* [in] */ const wchar_t * strSuperclass,
/* [in] */ long lFlags,
/* [in] */ void *pCtx,
/* [out] */ void **ppEnum) = 0;
-
- virtual long __stdcall CreateClassEnumAsync(
+
+ virtual long __stdcall CreateClassEnumAsync(
/* [in] */ const wchar_t * strSuperclass,
/* [in] */ long lFlags,
/* [in] */ void *pCtx,
/* [in] */ void *pResponseHandler) = 0;
-
- virtual long __stdcall PutInstance(
+
+ virtual long __stdcall PutInstance(
/* [in] */ void *pInst,
/* [in] */ long lFlags,
/* [in] */ void *pCtx,
/* [unique][in][out] */ void **ppCallResult) = 0;
-
- virtual long __stdcall PutInstanceAsync(
+
+ virtual long __stdcall PutInstanceAsync(
/* [in] */ void *pInst,
/* [in] */ long lFlags,
/* [in] */ void *pCtx,
/* [in] */ void *pResponseHandler) = 0;
-
- virtual long __stdcall DeleteInstance(
+
+ virtual long __stdcall DeleteInstance(
/* [in] */ const wchar_t * strObjectPath,
/* [in] */ long lFlags,
/* [in] */ void *pCtx,
/* [unique][in][out] */ void **ppCallResult) = 0;
-
- virtual long __stdcall DeleteInstanceAsync(
+
+ virtual long __stdcall DeleteInstanceAsync(
/* [in] */ const wchar_t * strObjectPath,
/* [in] */ long lFlags,
/* [in] */ void *pCtx,
/* [in] */ void *pResponseHandler) = 0;
-
- virtual long __stdcall CreateInstanceEnum(
+
+ virtual long __stdcall CreateInstanceEnum(
/* [in] */ const wchar_t * strFilter,
/* [in] */ long lFlags,
/* [in] */ void *pCtx,
/* [out] */ void **ppEnum) = 0;
-
- virtual long __stdcall CreateInstanceEnumAsync(
+
+ virtual long __stdcall CreateInstanceEnumAsync(
/* [in] */ const wchar_t * strFilter,
/* [in] */ long lFlags,
/* [in] */ void *pCtx,
/* [in] */ void *pResponseHandler) = 0;
-
- virtual long __stdcall ExecQuery(
+
+ virtual long __stdcall ExecQuery(
/* [in] */ const wchar_t * strQueryLanguage,
/* [in] */ const wchar_t * strQuery,
/* [in] */ long lFlags,
/* [in] */ IWbemContext_BIPC *pCtx,
/* [out] */ IEnumWbemClassObject_BIPC **ppEnum) = 0;
- virtual long __stdcall ExecQueryAsync(
+ virtual long __stdcall ExecQueryAsync(
/* [in] */ const wchar_t * strQueryLanguage,
/* [in] */ const wchar_t * strQuery,
/* [in] */ long lFlags,
/* [in] */ IWbemContext_BIPC *pCtx,
/* [in] */ void *pResponseHandler) = 0;
-
- virtual long __stdcall ExecNotificationQuery(
+
+ virtual long __stdcall ExecNotificationQuery(
/* [in] */ const wchar_t * strQueryLanguage,
/* [in] */ const wchar_t * strQuery,
/* [in] */ long lFlags,
/* [in] */ IWbemContext_BIPC *pCtx,
/* [out] */ void **ppEnum) = 0;
-
- virtual long __stdcall ExecNotificationQueryAsync(
+
+ virtual long __stdcall ExecNotificationQueryAsync(
/* [in] */ const wchar_t * strQueryLanguage,
/* [in] */ const wchar_t * strQuery,
/* [in] */ long lFlags,
/* [in] */ IWbemContext_BIPC *pCtx,
/* [in] */ void *pResponseHandler) = 0;
-
- virtual long __stdcall ExecMethod(
+
+ virtual long __stdcall ExecMethod(
/* [in] */ const wchar_t * strObjectPath,
/* [in] */ const wchar_t * strMethodName,
/* [in] */ long lFlags,
@@ -531,21 +559,21 @@ public:
/* [in] */ IWbemClassObject_BIPC *pInParams,
/* [unique][in][out] */ IWbemClassObject_BIPC **ppOutParams,
/* [unique][in][out] */ void **ppCallResult) = 0;
-
- virtual long __stdcall ExecMethodAsync(
+
+ virtual long __stdcall ExecMethodAsync(
/* [in] */ const wchar_t * strObjectPath,
/* [in] */ const wchar_t * strMethodName,
/* [in] */ long lFlags,
/* [in] */ IWbemContext_BIPC *pCtx,
/* [in] */ IWbemClassObject_BIPC *pInParams,
/* [in] */ void *pResponseHandler) = 0;
-
+
};
struct IWbemLocator_BIPC : public IUnknown_BIPC
{
public:
- virtual long __stdcall ConnectServer(
+ virtual long __stdcall ConnectServer(
/* [in] */ const wchar_t * strNetworkResource,
/* [in] */ const wchar_t * strUser,
/* [in] */ const wchar_t * strPassword,
@@ -554,12 +582,12 @@ public:
/* [in] */ const wchar_t * strAuthority,
/* [in] */ void *pCtx,
/* [out] */ IWbemServices_BIPC **ppNamespace) = 0;
-
+
};
-
-struct interprocess_overlapped
+
+struct interprocess_overlapped
{
unsigned long *internal;
unsigned long *internal_high;
@@ -574,9 +602,22 @@ struct interprocess_overlapped
void *h_event;
};
+struct interprocess_semaphore_basic_information
+{
+ unsigned int count; // current semaphore count
+ unsigned int limit; // max semaphore count
+};
+
+struct interprocess_section_basic_information
+{
+ void * base_address;
+ unsigned long section_attributes;
+ __int64 section_size;
+};
+
struct interprocess_filetime
-{
- unsigned long dwLowDateTime;
+{
+ unsigned long dwLowDateTime;
unsigned long dwHighDateTime;
};
@@ -620,16 +661,16 @@ struct system_info {
unsigned short wProcessorRevision;
};
-struct interprocess_memory_basic_information
+typedef struct _interprocess_memory_basic_information
{
- void * BaseAddress;
+ void * BaseAddress;
void * AllocationBase;
unsigned long AllocationProtect;
unsigned long RegionSize;
unsigned long State;
unsigned long Protect;
unsigned long Type;
-};
+} interprocess_memory_basic_information;
typedef struct _interprocess_acl
{
@@ -695,6 +736,10 @@ enum file_information_class_t {
file_maximum_information
};
+enum semaphore_information_class {
+ semaphore_basic_information = 0
+};
+
struct file_name_information_t {
unsigned long FileNameLength;
wchar_t FileName[1];
@@ -779,6 +824,12 @@ enum object_information_class
object_data_information
};
+enum section_information_class
+{
+ section_basic_information,
+ section_image_information
+};
+
struct object_name_information_t
{
unicode_string_t Name;
@@ -803,6 +854,7 @@ extern "C" __declspec(dllimport) int __stdcall DuplicateHandle
, void *hTargetProcessHandle, void **lpTargetHandle
, unsigned long dwDesiredAccess, int bInheritHandle
, unsigned long dwOptions);
+extern "C" __declspec(dllimport) long __stdcall GetFileType(void *hFile);
extern "C" __declspec(dllimport) void *__stdcall FindFirstFileA(const char *lpFileName, win32_find_data_t *lpFindFileData);
extern "C" __declspec(dllimport) int __stdcall FindNextFileA(void *hFindFile, win32_find_data_t *lpFindFileData);
extern "C" __declspec(dllimport) int __stdcall FindClose(void *hFindFile);
@@ -827,8 +879,8 @@ extern "C" __declspec(dllimport) int __stdcall FlushViewOfFile (void *, std::siz
extern "C" __declspec(dllimport) int __stdcall FlushFileBuffers (void *);
extern "C" __declspec(dllimport) int __stdcall GetFileSizeEx (void *, __int64 *size);
extern "C" __declspec(dllimport) unsigned long __stdcall FormatMessageA
- (unsigned long dwFlags, const void *lpSource, unsigned long dwMessageId,
- unsigned long dwLanguageId, char *lpBuffer, unsigned long nSize,
+ (unsigned long dwFlags, const void *lpSource, unsigned long dwMessageId,
+ unsigned long dwLanguageId, char *lpBuffer, unsigned long nSize,
std::va_list *Arguments);
extern "C" __declspec(dllimport) void *__stdcall LocalFree (void *);
extern "C" __declspec(dllimport) unsigned long __stdcall GetFileAttributesA(const char *);
@@ -844,6 +896,7 @@ extern "C" __declspec(dllimport) int __stdcall UnlockFile(void *hnd, unsigned lo
extern "C" __declspec(dllimport) int __stdcall LockFileEx(void *hnd, unsigned long flags, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped* overlapped);
extern "C" __declspec(dllimport) int __stdcall UnlockFileEx(void *hnd, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped* overlapped);
extern "C" __declspec(dllimport) int __stdcall WriteFile(void *hnd, const void *buffer, unsigned long bytes_to_write, unsigned long *bytes_written, interprocess_overlapped* overlapped);
+extern "C" __declspec(dllimport) int __stdcall ReadFile(void *hnd, void *buffer, unsigned long bytes_to_read, unsigned long *bytes_read, interprocess_overlapped* overlapped);
extern "C" __declspec(dllimport) int __stdcall InitializeSecurityDescriptor(interprocess_security_descriptor *pSecurityDescriptor, unsigned long dwRevision);
extern "C" __declspec(dllimport) int __stdcall SetSecurityDescriptorDacl(interprocess_security_descriptor *pSecurityDescriptor, int bDaclPresent, interprocess_acl *pDacl, int bDaclDefaulted);
extern "C" __declspec(dllimport) void *__stdcall LoadLibraryA(const char *);
@@ -858,17 +911,17 @@ extern "C" __declspec(dllimport) long __stdcall RegCloseKey(void *);
extern "C" __declspec(dllimport) int __stdcall QueryPerformanceCounter(__int64 *lpPerformanceCount);
//COM API
-extern "C" __declspec(dllimport) long __stdcall CoInitialize(void *pvReserved);
+extern "C" __declspec(dllimport) long __stdcall CoInitializeEx(void *pvReserved, unsigned long dwCoInit);
extern "C" __declspec(dllimport) long __stdcall CoInitializeSecurity(
- void* pSecDesc,
- long cAuthSvc,
- void *asAuthSvc,
- void *pReserved1,
- unsigned long dwAuthnLevel,
- unsigned long dwImpLevel,
- void *pAuthList,
- unsigned long dwCapabilities,
- void *pReserved3 );
+ void* pSecDesc,
+ long cAuthSvc,
+ void * asAuthSvc,
+ void *pReserved1,
+ unsigned long dwAuthnLevel,
+ unsigned long dwImpLevel,
+ void *pAuthList,
+ unsigned long dwCapabilities,
+ void *pReserved3 );
extern "C" __declspec(dllimport) long __stdcall CoSetProxyBlanket(
IUnknown_BIPC *pProxy,
@@ -889,10 +942,12 @@ extern "C" __declspec(dllimport) void __stdcall CoUninitialize(void);
//API function typedefs
//Pointer to functions
-typedef long (__stdcall *NtDeleteFile_t)(object_attributes_t *ObjectAttributes);
-typedef long (__stdcall *NtSetInformationFile_t)(void *FileHandle, io_status_block_t *IoStatusBlock, void *FileInformation, unsigned long Length, int FileInformationClass );
-typedef long (__stdcall * NtQuerySystemInformation_t)(int, void*, unsigned long, unsigned long *);
-typedef long (__stdcall * NtQueryObject_t)(void*, object_information_class, void *, unsigned long, unsigned long *);
+typedef long (__stdcall *NtDeleteFile_t)(object_attributes_t *ObjectAttributes);
+typedef long (__stdcall *NtSetInformationFile_t)(void *FileHandle, io_status_block_t *IoStatusBlock, void *FileInformation, unsigned long Length, int FileInformationClass );
+typedef long (__stdcall *NtQuerySystemInformation_t)(int, void*, unsigned long, unsigned long *);
+typedef long (__stdcall *NtQueryObject_t)(void*, object_information_class, void *, unsigned long, unsigned long *);
+typedef long (__stdcall *NtQuerySemaphore_t)(void*, unsigned int info_class, interprocess_semaphore_basic_information *pinfo, unsigned int info_size, unsigned int *ret_len);
+typedef long (__stdcall *NtQuerySection_t)(void*, section_information_class, interprocess_section_basic_information *pinfo, unsigned long info_size, unsigned long *ret_len);
typedef long (__stdcall *NtQueryInformationFile_t)(void *,io_status_block_t *,void *, long, int);
typedef long (__stdcall *NtOpenFile_t)(void*,unsigned long ,object_attributes_t*,io_status_block_t*,unsigned long,unsigned long);
typedef long (__stdcall *NtClose_t) (void*);
@@ -977,6 +1032,12 @@ inline bool duplicate_current_process_handle
, lpTargetHandle, 0, 0
, duplicate_same_access);
}
+
+inline long get_file_type(void *hFile)
+{
+ return GetFileType(hFile);
+}
+
/*
inline void get_system_time_as_file_time(interprocess_filetime *filetime)
{ GetSystemTimeAsFileTime(filetime); }
@@ -1000,13 +1061,16 @@ inline int unmap_view_of_file(void *address)
inline void *open_or_create_semaphore(const char *name, long initial_count, long maximum_count, interprocess_security_attributes *attr)
{ return CreateSemaphoreA(attr, initial_count, maximum_count, name); }
+inline void *open_semaphore(const char *name)
+{ return OpenSemaphoreA(semaphore_all_access, 0, name); }
+
inline int release_semaphore(void *handle, long release_count, long *prev_count)
{ return ReleaseSemaphore(handle, release_count, prev_count); }
class interprocess_all_access_security
{
interprocess_security_attributes sa;
- interprocess_security_descriptor sd;
+ interprocess_security_descriptor sd;
bool initialized;
public:
@@ -1027,16 +1091,21 @@ class interprocess_all_access_security
{ return &sa; }
};
-inline void * create_file_mapping (void * handle, unsigned long access, unsigned long high_size, unsigned long low_size, const char * name, interprocess_security_attributes *psec)
+inline void * create_file_mapping (void * handle, unsigned long access, unsigned __int64 file_offset, const char * name, interprocess_security_attributes *psec)
{
- return CreateFileMappingA (handle, psec, access, high_size, low_size, name);
+ const unsigned long high_size(file_offset >> 32), low_size((boost::uint32_t)file_offset);
+ return CreateFileMappingA (handle, psec, access, high_size, low_size, name);
}
inline void * open_file_mapping (unsigned long access, const char *name)
{ return OpenFileMappingA (access, 0, name); }
-inline void *map_view_of_file_ex(void *handle, unsigned long file_access, unsigned long highoffset, unsigned long lowoffset, std::size_t numbytes, void *base_addr)
-{ return MapViewOfFileEx(handle, file_access, highoffset, lowoffset, numbytes, base_addr); }
+inline void *map_view_of_file_ex(void *handle, unsigned long file_access, unsigned __int64 offset, std::size_t numbytes, void *base_addr)
+{
+ const unsigned long offset_low = (unsigned long)(offset & ((unsigned __int64)0xFFFFFFFF));
+ const unsigned long offset_high = offset >> 32;
+ return MapViewOfFileEx(handle, file_access, offset_high, offset_low, numbytes, base_addr);
+}
inline void *create_file(const char *name, unsigned long access, unsigned long creation_flags, unsigned long attributes, interprocess_security_attributes *psec)
{
@@ -1051,7 +1120,7 @@ inline void *create_file(const char *name, unsigned long access, unsigned long c
if (error_sharing_violation != get_last_error()){
return handle;
}
- Sleep(error_sharing_violation_sleep_ms);
+ sleep(error_sharing_violation_sleep_ms);
}
return invalid_handle_value;
}
@@ -1075,9 +1144,9 @@ inline bool get_file_size(void *handle, __int64 &size)
{ return 0 != GetFileSizeEx(handle, &size); }
inline bool create_directory(const char *name)
-{
+{
interprocess_all_access_security sec;
- return 0 != CreateDirectoryA(name, sec.get_attributes());
+ return 0 != CreateDirectoryA(name, sec.get_attributes());
}
inline bool remove_directory(const char *lpPathName)
@@ -1101,6 +1170,9 @@ inline bool unlock_file_ex(void *hnd, unsigned long reserved, unsigned long size
inline bool write_file(void *hnd, const void *buffer, unsigned long bytes_to_write, unsigned long *bytes_written, interprocess_overlapped* overlapped)
{ return 0 != WriteFile(hnd, buffer, bytes_to_write, bytes_written, overlapped); }
+inline bool read_file(void *hnd, void *buffer, unsigned long bytes_to_read, unsigned long *bytes_read, interprocess_overlapped* overlapped)
+{ return 0 != ReadFile(hnd, buffer, bytes_to_read, bytes_read, overlapped); }
+
inline bool get_file_information_by_handle(void *hnd, interprocess_by_handle_file_information *info)
{ return 0 != GetFileInformationByHandle(hnd, info); }
@@ -1176,7 +1248,7 @@ inline void rtl_init_empty_unicode_string(unicode_string_t *ucStr, wchar_t *buf,
template<int Dummy>
struct function_address_holder
{
- enum { NtSetInformationFile, NtQuerySystemInformation, NtQueryObject, NumFunction };
+ enum { NtSetInformationFile, NtQuerySystemInformation, NtQueryObject, NtQuerySemaphore, NtQuerySection, NumFunction };
enum { NtDll_dll, NumModule };
private:
@@ -1213,7 +1285,7 @@ struct function_address_holder
static void *get_address_from_dll(const unsigned int id)
{
assert(id < (unsigned int)NumFunction);
- const char *function[] = { "NtSetInformationFile", "NtQuerySystemInformation", "NtQueryObject" };
+ const char *function[] = { "NtSetInformationFile", "NtQuerySystemInformation", "NtQueryObject", "NtQuerySemaphore", "NtQuerySection" };
bool compile_check[sizeof(function)/sizeof(function[0]) == NumFunction];
(void)compile_check;
return get_proc_address(get_module(NtDll_dll), function[id]);
@@ -1264,7 +1336,7 @@ struct library_unloader
//pszFilename must have room for at least MaxPath+1 characters
inline bool get_file_name_from_handle_function
- (void * hFile, wchar_t *pszFilename, std::size_t length, std::size_t &out_length)
+ (void * hFile, wchar_t *pszFilename, std::size_t length, std::size_t &out_length)
{
if(length <= MaxPath){
return false;
@@ -1285,17 +1357,17 @@ inline bool get_file_name_from_handle_function
bool bSuccess = false;
// Create a file mapping object.
- void * hFileMap = create_file_mapping(hFile, page_readonly, 0, 1, 0, 0);
+ void * hFileMap = create_file_mapping(hFile, page_readonly, 1, 0, 0);
if(hFileMap){
// Create a file mapping to get the file name.
- void* pMem = map_view_of_file_ex(hFileMap, file_map_read, 0, 0, 1, 0);
+ void* pMem = map_view_of_file_ex(hFileMap, file_map_read, 0, 1, 0);
if (pMem){
//out_length = pfGMFN(get_current_process(), pMem, pszFilename, MaxPath);
out_length = get_mapped_file_name(get_current_process(), pMem, pszFilename, MaxPath);
if(out_length){
bSuccess = true;
- }
+ }
unmap_view_of_file(pMem);
}
close_handle(hFileMap);
@@ -1307,7 +1379,6 @@ inline bool get_file_name_from_handle_function
inline bool get_system_time_of_day_information(system_timeofday_information &info)
{
NtQuerySystemInformation_t pNtQuerySystemInformation = (NtQuerySystemInformation_t)
- //get_proc_address(get_module_handle("ntdll.dll"), "NtQuerySystemInformation");
dll_func::get(dll_func::NtQuerySystemInformation);
unsigned long res;
long status = pNtQuerySystemInformation(system_time_of_day_information, &info, sizeof(info), &res);
@@ -1384,9 +1455,12 @@ inline bool get_boot_and_system_time_wstr(wchar_t *bootsystemstamp, std::size_t
class handle_closer
{
void *handle_;
+ handle_closer(const handle_closer &);
+ handle_closer& operator=(const handle_closer &);
public:
- handle_closer(void *handle) : handle_(handle){}
- ~handle_closer(){ close_handle(handle_); }
+ explicit handle_closer(void *handle) : handle_(handle){}
+ ~handle_closer()
+ { close_handle(handle_); }
};
union ntquery_mem_t
@@ -1401,81 +1475,92 @@ union ntquery_mem_t
inline bool unlink_file(const char *filename)
{
- if(!delete_file(filename)){
- try{
- NtSetInformationFile_t pNtSetInformationFile =
- //(NtSetInformationFile_t)get_proc_address(get_module_handle("ntdll.dll"), "NtSetInformationFile");
- (NtSetInformationFile_t)dll_func::get(dll_func::NtSetInformationFile);
- if(!pNtSetInformationFile){
- return false;
- }
+ //Don't try to optimize doing a DeleteFile first
+ //as there are interactions with permissions and
+ //in-use files.
+ //
+ //if(!delete_file(filename)){
+ // (...)
+ //
+
+ //This functions tries to emulate UNIX unlink semantics in windows.
+ //
+ //- Open the file and mark the handle as delete-on-close
+ //- Rename the file to an arbitrary name based on a random number
+ //- Close the handle. If there are no file users, it will be deleted.
+ // Otherwise it will be used by already connected handles but the
+ // file name can't be used to open this file again
+ try{
+ NtSetInformationFile_t pNtSetInformationFile =
+ (NtSetInformationFile_t)dll_func::get(dll_func::NtSetInformationFile);
+ if(!pNtSetInformationFile){
+ return false;
+ }
- NtQueryObject_t pNtQueryObject =
- //(NtQueryObject_t)get_proc_address(get_module_handle("ntdll.dll"), "NtQueryObject");
- (NtQueryObject_t)dll_func::get(dll_func::NtQueryObject);
+ NtQueryObject_t pNtQueryObject =
+ (NtQueryObject_t)dll_func::get(dll_func::NtQueryObject);
- //First step: Obtain a handle to the file using Win32 rules. This resolves relative paths
- void *fh = create_file(filename, generic_read | delete_access, open_existing,
- file_flag_backup_semantics | file_flag_delete_on_close, 0);
- if(fh == invalid_handle_value){
- return false;
- }
+ //First step: Obtain a handle to the file using Win32 rules. This resolves relative paths
+ void *fh = create_file(filename, generic_read | delete_access, open_existing,
+ file_flag_backup_semantics | file_flag_delete_on_close, 0);
+ if(fh == invalid_handle_value){
+ return false;
+ }
- handle_closer h_closer(fh);
+ handle_closer h_closer(fh);
- std::auto_ptr<ntquery_mem_t> pmem(new ntquery_mem_t);
- file_rename_information_t *pfri = &pmem->ren.info;
- const std::size_t RenMaxNumChars =
- ((char*)pmem.get() - (char*)&pmem->ren.info.FileName[0])/sizeof(wchar_t);
+ std::auto_ptr<ntquery_mem_t> pmem(new ntquery_mem_t);
+ file_rename_information_t *pfri = &pmem->ren.info;
+ const std::size_t RenMaxNumChars =
+ ((char*)pmem.get() - (char*)&pmem->ren.info.FileName[0])/sizeof(wchar_t);
- //Obtain file name
- unsigned long size;
- if(pNtQueryObject(fh, object_name_information, pmem.get(), sizeof(ntquery_mem_t), &size)){
- return false;
- }
+ //Obtain file name
+ unsigned long size;
+ if(pNtQueryObject(fh, object_name_information, pmem.get(), sizeof(ntquery_mem_t), &size)){
+ return false;
+ }
- //Copy filename to the rename member
- std::memmove(pmem->ren.info.FileName, pmem->name.Name.Buffer, pmem->name.Name.Length);
- std::size_t filename_string_length = pmem->name.Name.Length/sizeof(wchar_t);
+ //Copy filename to the rename member
+ std::memmove(pmem->ren.info.FileName, pmem->name.Name.Buffer, pmem->name.Name.Length);
+ std::size_t filename_string_length = pmem->name.Name.Length/sizeof(wchar_t);
- //Second step: obtain the complete native-nt filename
- //if(!get_file_name_from_handle_function(fh, pfri->FileName, RenMaxNumChars, filename_string_length)){
- //return 0;
- //}
+ //Second step: obtain the complete native-nt filename
+ //if(!get_file_name_from_handle_function(fh, pfri->FileName, RenMaxNumChars, filename_string_length)){
+ //return 0;
+ //}
- //Add trailing mark
- if((RenMaxNumChars-filename_string_length) < (SystemTimeOfDayInfoLength*2)){
- return false;
- }
+ //Add trailing mark
+ if((RenMaxNumChars-filename_string_length) < (SystemTimeOfDayInfoLength*2)){
+ return false;
+ }
- //Search '\\' character to replace it
- for(std::size_t i = filename_string_length; i != 0; --filename_string_length){
- if(pmem->ren.info.FileName[--i] == L'\\')
- break;
- }
+ //Search '\\' character to replace it
+ for(std::size_t i = filename_string_length; i != 0; --filename_string_length){
+ if(pmem->ren.info.FileName[--i] == L'\\')
+ break;
+ }
- //Add random number
- std::size_t s = RenMaxNumChars - filename_string_length;
- if(!get_boot_and_system_time_wstr(&pfri->FileName[filename_string_length], s)){
- return false;
- }
- filename_string_length += s;
+ //Add random number
+ std::size_t s = RenMaxNumChars - filename_string_length;
+ if(!get_boot_and_system_time_wstr(&pfri->FileName[filename_string_length], s)){
+ return false;
+ }
+ filename_string_length += s;
- //Fill rename information (FileNameLength is in bytes)
- pfri->FileNameLength = static_cast<unsigned long>(sizeof(wchar_t)*(filename_string_length));
- pfri->Replace = 1;
- pfri->RootDir = 0;
+ //Fill rename information (FileNameLength is in bytes)
+ pfri->FileNameLength = static_cast<unsigned long>(sizeof(wchar_t)*(filename_string_length));
+ pfri->Replace = 1;
+ pfri->RootDir = 0;
- //Final step: change the name of the in-use file:
- io_status_block_t io;
- if(0 != pNtSetInformationFile(fh, &io, pfri, sizeof(ntquery_mem_t::ren_t), file_rename_information)){
- return false;
- }
- return true;
- }
- catch(...){
+ //Final step: change the name of the in-use file:
+ io_status_block_t io;
+ if(0 != pNtSetInformationFile(fh, &io, pfri, sizeof(ntquery_mem_t::ren_t), file_rename_information)){
return false;
}
+ return true;
+ }
+ catch(...){
+ return false;
}
return true;
}
@@ -1493,116 +1578,77 @@ struct reg_closer
inline void get_shared_documents_folder(std::string &s)
{
s.clear();
- //void *hAdvapi = load_library("Advapi32.dll");
- //if (hAdvapi){
- //library_unloader unloader(hAdvapi);
- // Pointer to function RegOpenKeyA
- //RegOpenKeyEx_t pRegOpenKey =
- //(RegOpenKeyEx_t)get_proc_address(hAdvapi, "RegOpenKeyExA");
- //if (pRegOpenKey){
- // Pointer to function RegCloseKey
- //RegCloseKey_t pRegCloseKey =
- //(RegCloseKey_t)get_proc_address(hAdvapi, "RegCloseKey");
- //if (pRegCloseKey){
- // Pointer to function RegQueryValueA
- //RegQueryValueEx_t pRegQueryValue =
- //(RegQueryValueEx_t)get_proc_address(hAdvapi, "RegQueryValueExA");
- //if (pRegQueryValue){
- //Open the key
- void *key;
- //if ((*pRegOpenKey)( hkey_local_machine
- //, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
- //, 0
- //, key_query_value
- //, &key) == 0){
- //reg_closer key_closer(pRegCloseKey, key);
- if (reg_open_key_ex( hkey_local_machine
- , "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
- , 0
- , key_query_value
- , &key) == 0){
- reg_closer key_closer(key);
-
- //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){
- //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)
- s.erase(s.end()-1);
- (void)err;
- }
- }
- //}
- //}
- //}
- //}
+ void *key;
+ if (reg_open_key_ex( hkey_local_machine
+ , "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
+ , 0
+ , key_query_value
+ , &key) == 0){
+ reg_closer key_closer(key);
+
+ //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){
+ //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)
+ s.erase(s.end()-1);
+ (void)err;
+ }
+ }
}
-
inline void get_registry_value(const char *folder, const char *value_key, std::vector<unsigned char> &s)
{
s.clear();
- //void *hAdvapi = load_library("Advapi32.dll");
- //if (hAdvapi){
- //library_unloader unloader(hAdvapi);
- // Pointer to function RegOpenKeyA
- //RegOpenKeyEx_t pRegOpenKey =
- //(RegOpenKeyEx_t)get_proc_address(hAdvapi, "RegOpenKeyExA");
- //if (pRegOpenKey){
- // Pointer to function RegCloseKey
- //RegCloseKey_t pRegCloseKey =
- //(RegCloseKey_t)get_proc_address(hAdvapi, "RegCloseKey");
- //if (pRegCloseKey){
- // Pointer to function RegQueryValueA
- //RegQueryValueEx_t pRegQueryValue =
- //(RegQueryValueEx_t)get_proc_address(hAdvapi, "RegQueryValueExA");
- //if (pRegQueryValue){
- //Open the key
- void *key;
- //if ((*pRegOpenKey)( hkey_local_machine
- //, folder
- //, 0
- //, key_query_value
- //, &key) == 0){
- //reg_closer key_closer(pRegCloseKey, key);
- if (reg_open_key_ex( hkey_local_machine
- , folder
- , 0
- , key_query_value
- , &key) == 0){
- reg_closer key_closer(key);
-
- //Obtain the value
- unsigned long size;
- unsigned long type;
- const char *const reg_value = value_key;
- //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){
- //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)
- s.erase(s.end()-1);
- (void)err;
- }
- }
- //}
- //}
- //}
- //}
+ void *key;
+ if (reg_open_key_ex( hkey_local_machine
+ , folder
+ , 0
+ , key_query_value
+ , &key) == 0){
+ reg_closer key_closer(key);
+
+ //Obtain the value
+ unsigned long size;
+ unsigned long type;
+ const char *const reg_value = value_key;
+ //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){
+ //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)
+ s.erase(s.end()-1);
+ (void)err;
+ }
+ }
}
struct co_uninitializer
-{ ~co_uninitializer() { CoUninitialize(); } };
+{
+ co_uninitializer(bool b_uninitialize)
+ : m_b_uninitialize(b_uninitialize)
+ {}
+
+ ~co_uninitializer()
+ {
+ if(m_b_uninitialize){
+ CoUninitialize();
+ }
+ }
+
+ private:
+ const bool m_b_uninitialize;
+};
template<class Object>
struct com_releaser
@@ -1615,29 +1661,32 @@ struct com_releaser
inline bool get_wmi_class_attribute( std::wstring& strValue, const wchar_t *wmi_class, const wchar_t *wmi_class_var)
{
//See example http://msdn.microsoft.com/en-us/library/aa390423%28v=VS.85%29.aspx
- long co_init_ret = CoInitialize(0);
- if(co_init_ret != S_OK_BIPC && co_init_ret != S_FALSE_BIPC)
+ //
+ //See BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL definition if you need to change the
+ //default value of this macro in your application
+ long co_init_ret = CoInitializeEx(0, BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL);
+ if(co_init_ret != S_OK_BIPC && co_init_ret != S_FALSE_BIPC && co_init_ret != RPC_E_CHANGED_MODE_BIPC)
return false;
- co_uninitializer co_initialize_end;
+ co_uninitializer co_initialize_end(co_init_ret != RPC_E_CHANGED_MODE_BIPC);
(void)co_initialize_end;
bool bRet = false;
long sec_init_ret = CoInitializeSecurity
- ( 0 //pVoid
- ,-1 //cAuthSvc
- , 0 //asAuthSvc
- , 0 //pReserved1
- , RPC_C_AUTHN_LEVEL_PKT_BIPC //dwAuthnLevel
- , RPC_C_IMP_LEVEL_IMPERSONATE_BIPC //dwImpLevel
- , 0 //pAuthList
- , EOAC_NONE_BIPC //dwCapabilities
- , 0 //pReserved3
+ ( 0 //pVoid
+ ,-1 //cAuthSvc
+ , 0 //asAuthSvc
+ , 0 //pReserved1
+ , RPC_C_AUTHN_LEVEL_PKT_BIPC //dwAuthnLevel
+ , RPC_C_IMP_LEVEL_IMPERSONATE_BIPC //dwImpLevel
+ , 0 //pAuthList
+ , EOAC_NONE_BIPC //dwCapabilities
+ , 0 //pReserved3
);
if( 0 == sec_init_ret || RPC_E_TOO_LATE_BIPC == sec_init_ret)
{
IWbemLocator_BIPC * pIWbemLocator = 0;
const wchar_t * bstrNamespace = L"root\\cimv2";
-
+
if( 0 != CoCreateInstance(
CLSID_WbemAdministrativeLocator,
0,
@@ -1645,7 +1694,7 @@ inline bool get_wmi_class_attribute( std::wstring& strValue, const wchar_t *wmi_
IID_IUnknown, (void **)&pIWbemLocator)){
return false;
}
-
+
com_releaser<IWbemLocator_BIPC> IWbemLocator_releaser(pIWbemLocator);
IWbemServices_BIPC *pWbemServices = 0;
@@ -1677,7 +1726,7 @@ inline bool get_wmi_class_attribute( std::wstring& strValue, const wchar_t *wmi_
){
return false;
}
-
+
com_releaser<IWbemServices_BIPC> IWbemServices_releaser(pWbemServices);
strValue.clear();
@@ -1757,9 +1806,40 @@ inline bool is_directory(const char *path)
(attrib & file_attribute_directory));
}
-} //namespace winapi
+inline bool get_file_mapping_size(void *file_mapping_hnd, __int64 &size)
+{
+ NtQuerySection_t pNtQuerySection =
+ (NtQuerySection_t)dll_func::get(dll_func::NtQuerySection);
+ //Obtain file name
+ interprocess_section_basic_information info;
+ unsigned long ntstatus =
+ pNtQuerySection(file_mapping_hnd, section_basic_information, &info, sizeof(info), 0);
+ if(ntstatus){
+ return false;
+ }
+ size = info.section_size;
+ return true;
+}
+
+inline bool get_semaphore_info(void *handle, long &count, long &limit)
+{
+ winapi::interprocess_semaphore_basic_information info;
+ winapi::NtQuerySemaphore_t pNtQuerySemaphore =
+ (winapi::NtQuerySemaphore_t)dll_func::get(winapi::dll_func::NtQuerySemaphore);
+ unsigned int ret_len;
+ long status = pNtQuerySemaphore(handle, winapi::semaphore_basic_information, &info, sizeof(info), &ret_len);
+ if(status){
+ return false;
+ }
+ count = info.count;
+ limit = info.limit;
+ return true;
+}
+
+
+} //namespace winapi
} //namespace interprocess
-} //namespace boost
+} //namespace boost
#include <boost/interprocess/detail/config_end.hpp>
diff --git a/boost/interprocess/detail/windows_intermodule_singleton.hpp b/boost/interprocess/detail/windows_intermodule_singleton.hpp
new file mode 100644
index 0000000000..a716e270a7
--- /dev/null
+++ b/boost/interprocess/detail/windows_intermodule_singleton.hpp
@@ -0,0 +1,306 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009-2011. 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_WINDOWS_INTERMODULE_SINGLETON_HPP
+#define BOOST_INTERPROCESS_WINDOWS_INTERMODULE_SINGLETON_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#if !defined(BOOST_INTERPROCESS_WINDOWS)
+ #error "This header can't be included from non-windows operating systems"
+#endif
+
+#include <boost/assert.hpp>
+#include <boost/interprocess/detail/intermodule_singleton_common.hpp>
+#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
+#include <boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <boost/cstdint.hpp>
+#include <string>
+#include <map>
+
+namespace boost{
+namespace interprocess{
+namespace ipcdetail{
+
+namespace intermodule_singleton_helpers {
+
+//This global map will be implemented using 3 sync primitives:
+//
+//1) A named mutex that will implement global mutual exclusion between
+// threads from different modules/dlls
+//
+//2) A semaphore that will act as a global counter for modules attached to the global map
+// so that the global map can be destroyed when the last module is detached.
+//
+//3) A semaphore that will be hacked to hold the address of a heap-allocated map in the
+// max and current semaphore count.
+class windows_semaphore_based_map
+{
+ typedef std::map<std::string, ref_count_ptr> map_type;
+
+ public:
+ windows_semaphore_based_map()
+ {
+ map_type *m = new map_type;
+ boost::uint32_t initial_count = 0;
+ boost::uint32_t max_count = 0;
+
+ //Windows user address space sizes:
+ //32 bit windows: [32 bit processes] 2GB or 3GB (31/32 bits)
+ //64 bit windows: [32 bit processes] 2GB or 4GB (31/32 bits)
+ // [64 bit processes] 2GB or 8TB (31/43 bits)
+ //
+ //Windows semaphores use 'long' parameters (32 bits in LLP64 data model) and
+ //those values can't be negative, so we have 31 bits to store something
+ //in max_count and initial count parameters.
+ //Also, max count must be bigger than 0 and bigger or equal than initial count.
+ if(sizeof(void*) == sizeof(boost::uint32_t)){
+ //This means that for 32 bit processes, a semaphore count (31 usable bits) is
+ //enough to store 4 byte aligned memory (4GB -> 32 bits - 2 bits = 30 bits).
+ //The max count will hold the pointer value and current semaphore count
+ //will be zero.
+ //
+ //Relying in UB with a cast through union, but all known windows compilers
+ //accept this (C11 also accepts this).
+ union caster_union
+ {
+ void *addr;
+ boost::uint32_t addr_uint32;
+ } caster;
+ caster.addr = m;
+ //memory is at least 4 byte aligned in windows
+ BOOST_ASSERT((caster.addr_uint32 & boost::uint32_t(3)) == 0);
+ max_count = caster.addr_uint32 >> 2;
+ }
+ else if(sizeof(void*) == sizeof(boost::uint64_t)){
+ //Relying in UB with a cast through union, but all known windows compilers
+ //accept this (C11 accepts this).
+ union caster_union
+ {
+ void *addr;
+ boost::uint64_t addr_uint64;
+ } caster;
+ caster.addr = m;
+ //We'll encode the address using 30 bits in each 32 bit high and low parts.
+ //High part will be the sem max count, low part will be the sem initial count.
+ //(restrictions: max count > 0, initial count >= 0 and max count >= initial count):
+ //
+ // - Low part will be shifted two times (4 byte alignment) so that top
+ // two bits are cleared (the top one for sign, the next one to
+ // assure low part value is always less than the high part value.
+ // - The top bit of the high part will be cleared and the next bit will be 1
+ // (so high part is always bigger than low part due to the quasi-top bit).
+ //
+ // This means that the addresses we can store must be 4 byte aligned
+ // and less than 1 ExbiBytes ( 2^60 bytes, ~1 ExaByte). User-level address space in Windows 64
+ // is much less than this (8TB, 2^43 bytes): "1 EByte (or it was 640K?) ought to be enough for anybody" ;-).
+ caster.addr = m;
+ BOOST_ASSERT((caster.addr_uint64 & boost::uint64_t(3)) == 0);
+ max_count = boost::uint32_t(caster.addr_uint64 >> 32);
+ initial_count = boost::uint32_t(caster.addr_uint64);
+ initial_count = initial_count/4;
+ //Make sure top two bits are zero
+ BOOST_ASSERT((max_count & boost::uint32_t(0xC0000000)) == 0);
+ //Set quasi-top bit
+ max_count |= boost::uint32_t(0x40000000);
+ }
+ bool created = false;
+ const permissions & perm = permissions();
+ std::string pid_creation_time, name;
+ get_pid_creation_time_str(pid_creation_time);
+ name = "bipc_gmap_sem_lock_";
+ name += pid_creation_time;
+ bool success = m_mtx_lock.open_or_create(name.c_str(), perm);
+ name = "bipc_gmap_sem_count_";
+ name += pid_creation_time;
+ scoped_lock<winapi_mutex_wrapper> lck(m_mtx_lock);
+ {
+ success = success && m_sem_count.open_or_create
+ ( name.c_str(), static_cast<long>(0), winapi_semaphore_wrapper::MaxCount, perm, created);
+ name = "bipc_gmap_sem_map_";
+ name += pid_creation_time;
+ success = success && m_sem_map.open_or_create
+ (name.c_str(), initial_count, max_count, perm, created);
+ if(!success){
+ //winapi_xxx wrappers do the cleanup...
+ throw int(0);
+ }
+ if(!created){
+ delete m;
+ }
+ else{
+ BOOST_ASSERT(&get_map_unlocked() == m);
+ }
+ m_sem_count.post();
+ }
+ }
+
+ map_type &get_map_unlocked()
+ {
+ if(sizeof(void*) == sizeof(boost::uint32_t)){
+ union caster_union
+ {
+ void *addr;
+ boost::uint32_t addr_uint32;
+ } caster;
+ caster.addr = 0;
+ caster.addr_uint32 = m_sem_map.limit();
+ caster.addr_uint32 = caster.addr_uint32 << 2;
+ return *static_cast<map_type*>(caster.addr);
+ }
+ else{
+ union caster_union
+ {
+ void *addr;
+ boost::uint64_t addr_uint64;
+ } caster;
+ boost::uint32_t max_count(m_sem_map.limit()), initial_count(m_sem_map.value());
+ //Clear quasi-top bit
+ max_count &= boost::uint32_t(0xBFFFFFFF);
+ caster.addr_uint64 = max_count;
+ caster.addr_uint64 = caster.addr_uint64 << 32;
+ caster.addr_uint64 |= boost::uint64_t(initial_count) << 2;
+ return *static_cast<map_type*>(caster.addr);
+ }
+ }
+
+ ref_count_ptr *find(const char *name)
+ {
+ scoped_lock<winapi_mutex_wrapper> lck(m_mtx_lock);
+ map_type &map = this->get_map_unlocked();
+ map_type::iterator it = map.find(std::string(name));
+ if(it != map.end()){
+ return &it->second;
+ }
+ else{
+ return 0;
+ }
+ }
+
+ ref_count_ptr * insert(const char *name, const ref_count_ptr &ref)
+ {
+ scoped_lock<winapi_mutex_wrapper> lck(m_mtx_lock);
+ map_type &map = this->get_map_unlocked();
+ map_type::iterator it = map.insert(map_type::value_type(std::string(name), ref)).first;
+ return &it->second;
+ }
+
+ bool erase(const char *name)
+ {
+ scoped_lock<winapi_mutex_wrapper> lck(m_mtx_lock);
+ map_type &map = this->get_map_unlocked();
+ return map.erase(std::string(name)) != 0;
+ }
+
+ template<class F>
+ void atomic_func(F &f)
+ {
+ scoped_lock<winapi_mutex_wrapper> lck(m_mtx_lock);
+ f();
+ }
+
+ ~windows_semaphore_based_map()
+ {
+ scoped_lock<winapi_mutex_wrapper> lck(m_mtx_lock);
+ m_sem_count.wait();
+ if(0 == m_sem_count.value()){
+ delete &this->get_map_unlocked();
+ }
+ //First close sems to protect this with the external mutex
+ m_sem_map.close();
+ m_sem_count.close();
+ //Once scoped_lock unlocks the mutex, the destructor will close the handle...
+ }
+
+ private:
+ winapi_mutex_wrapper m_mtx_lock;
+ winapi_semaphore_wrapper m_sem_map;
+ winapi_semaphore_wrapper m_sem_count;
+};
+
+template<>
+struct thread_safe_global_map_dependant<windows_semaphore_based_map>
+{
+ static void apply_gmem_erase_logic(const char *, const char *){}
+
+ static bool remove_old_gmem()
+ { return true; }
+
+ struct lock_file_logic
+ {
+ lock_file_logic(windows_semaphore_based_map &)
+ : retry_with_new_map(false)
+ {}
+
+ void operator()(void){}
+ bool retry() const { return retry_with_new_map; }
+ private:
+ const bool retry_with_new_map;
+ };
+
+ static void construct_map(void *addr)
+ {
+ ::new (addr)windows_semaphore_based_map;
+ }
+
+ struct unlink_map_logic
+ {
+ unlink_map_logic(windows_semaphore_based_map &)
+ {}
+ void operator()(){}
+ };
+
+ static ref_count_ptr *find(windows_semaphore_based_map &map, const char *name)
+ {
+ return map.find(name);
+ }
+
+ static ref_count_ptr * insert(windows_semaphore_based_map &map, const char *name, const ref_count_ptr &ref)
+ {
+ return map.insert(name, ref);
+ }
+
+ static bool erase(windows_semaphore_based_map &map, const char *name)
+ {
+ return map.erase(name);
+ }
+
+ template<class F>
+ static void atomic_func(windows_semaphore_based_map &map, F &f)
+ {
+ map.atomic_func(f);
+ }
+};
+
+} //namespace intermodule_singleton_helpers {
+
+template<typename C, bool LazyInit = true, bool Phoenix = true>
+class windows_intermodule_singleton
+ : public intermodule_singleton_impl
+ < C
+ , LazyInit
+ , Phoenix
+ , intermodule_singleton_helpers::windows_semaphore_based_map
+ >
+{};
+
+} //namespace ipcdetail{
+} //namespace interprocess{
+} //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_INTERPROCESS_WINDOWS_INTERMODULE_SINGLETON_HPP
diff --git a/boost/interprocess/detail/workaround.hpp b/boost/interprocess/detail/workaround.hpp
index 896a2208a2..884b8680a6 100644
--- a/boost/interprocess/detail/workaround.hpp
+++ b/boost/interprocess/detail/workaround.hpp
@@ -13,43 +13,34 @@
#include <boost/interprocess/detail/config_begin.hpp>
-#if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32))
-
-#define BOOST_INTERPROCESS_WINDOWS
-
-/*
-#if !defined(_MSC_EXTENSIONS)
-#error "Turn on Microsoft language extensions (_MSC_EXTENSIONS) to be able to call Windows API functions"
-#endif
-*/
-
-#endif
-
-#if !defined(BOOST_INTERPROCESS_WINDOWS)
-
+#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+ #define BOOST_INTERPROCESS_WINDOWS
+ #define BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION
+ #define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
+#else
#include <unistd.h>
- #if ((_POSIX_THREAD_PROCESS_SHARED - 0) > 0)
- //Cygwin defines _POSIX_THREAD_PROCESS_SHARED but does not implement it.
- //Mac Os X >= Leopard defines _POSIX_THREAD_PROCESS_SHARED but does not seems to work.
- # if !defined(__CYGWIN__) && !defined(__APPLE__)
- # define BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
- # endif
+ #if defined(_POSIX_THREAD_PROCESS_SHARED) && ((_POSIX_THREAD_PROCESS_SHARED - 0) > 0)
+ //Cygwin defines _POSIX_THREAD_PROCESS_SHARED but does not implement it.
+ //Mac Os X >= Leopard defines _POSIX_THREAD_PROCESS_SHARED but does not seems to work.
+ #if !defined(__CYGWIN__) && !defined(__APPLE__)
+ #define BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
+ #endif
+ #endif
+
+ #if defined(_POSIX_BARRIERS) && ((_POSIX_BARRIERS - 0) > 0)
+ #define BOOST_INTERPROCESS_POSIX_BARRIERS
#endif
-
- #if ((_POSIX_BARRIERS - 0) > 0)
- # define BOOST_INTERPROCESS_POSIX_BARRIERS
- # endif
-
- #if ((_POSIX_SEMAPHORES - 0) > 0)
- # define BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
- # if defined(__CYGWIN__)
- #define BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK
- # endif
+
+ #if defined(_POSIX_SEMAPHORES) && ((_POSIX_SEMAPHORES - 0) > 0)
+ #define BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
+ #if defined(__CYGWIN__)
+ #define BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK
+ #endif
//Some platforms have a limited (name length) named semaphore support
#elif (defined(__FreeBSD__) && (__FreeBSD__ >= 4)) || defined(__APPLE__)
- # define BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
- #endif
+ #define BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
+ #endif
#if ((defined _V6_ILP32_OFFBIG) &&(_V6_ILP32_OFFBIG - 0 > 0)) ||\
((defined _V6_LP64_OFF64) &&(_V6_LP64_OFF64 - 0 > 0)) ||\
@@ -60,87 +51,83 @@
((defined _FILE_OFFSET_BITS) &&(_FILE_OFFSET_BITS - 0 >= 64))||\
((defined _FILE_OFFSET_BITS) &&(_FILE_OFFSET_BITS - 0 >= 64))
#define BOOST_INTERPROCESS_UNIX_64_BIT_OR_BIGGER_OFF_T
- #else
#endif
//Check for XSI shared memory objects. They are available in nearly all UNIX platforms
#if !defined(__QNXNTO__)
- # define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
+ #define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
#endif
- #if ((_POSIX_SHARED_MEMORY_OBJECTS - 0) > 0)
- # define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
+ #if defined(_POSIX_SHARED_MEMORY_OBJECTS) && ((_POSIX_SHARED_MEMORY_OBJECTS - 0) > 0)
+ #define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
#else
- //VMS and MACOS don't define it but the have shm_open/close interface
- # if defined(__vms)
- # if __CRTL_VER >= 70200000
- # define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
- # endif
- //Mac OS has some non-conformant features like names limited to SHM_NAME_MAX
- # elif defined (__APPLE__)
-// # define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
-// # define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS_NO_GROW
- # endif
+ //VMS and MACOS don't define it but they have shm_open/close interface
+ #if defined(__vms)
+ #if __CRTL_VER >= 70200000
+ #define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
+ #endif
+ //Mac OS has some non-conformant features like names limited to SHM_NAME_MAX
+ #elif defined (__APPLE__)
+ //#define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
+ //#define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS_NO_GROW
+ #endif
#endif
//Now check if we have only XSI shared memory
#if defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS) &&\
!defined(BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS)
- //# define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS_ONLY
+ //#define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS_ONLY
#endif
- #if ((_POSIX_TIMEOUTS - 0) > 0)
- # define BOOST_INTERPROCESS_POSIX_TIMEOUTS
- #endif
-
+ #if defined(_POSIX_TIMEOUTS) && ((_POSIX_TIMEOUTS - 0) > 0)
+ #define BOOST_INTERPROCESS_POSIX_TIMEOUTS
+ #endif
#ifdef BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
//Some systems have filesystem-based resources, so the
//portable "/shmname" format does not work due to permission issues
//For those systems we need to form a path to a temporary directory:
// hp-ux tru64 vms freebsd
- #if defined(__hpux) || defined(__osf__) || defined(__vms) || (defined(__FreeBSD__) && (__FreeBSD__ < 7))
- #define BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SHARED_MEMORY
+ #if defined(__hpux) || defined(__osf__) || defined(__vms) || (defined(__FreeBSD__) && (__FreeBSD__ < 7))
+ #define BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SHARED_MEMORY
#elif defined(__FreeBSD__)
- #define BOOST_INTERPROCESS_RUNTIME_FILESYSTEM_BASED_POSIX_SHARED_MEMORY
+ #define BOOST_INTERPROCESS_RUNTIME_FILESYSTEM_BASED_POSIX_SHARED_MEMORY
#endif
#endif
#ifdef BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
#if defined(__osf__) || defined(__vms)
- #define BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
+ #define BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
#endif
#endif
- #if ((_POSIX_VERSION + 0)>= 200112L || (_XOPEN_VERSION + 0)>= 500)
- #define BOOST_INTERPROCESS_POSIX_RECURSIVE_MUTEXES
+ #if defined(_POSIX_VERSION) && defined(_XOPEN_VERSION) && \
+ (((_POSIX_VERSION + 0)>= 200112L || (_XOPEN_VERSION + 0)>= 500))
+ #define BOOST_INTERPROCESS_POSIX_RECURSIVE_MUTEXES
#endif
-#endif
+ #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
+ #define BOOST_INTERPROCESS_BSD_DERIVATIVE
+ #include <sys/sysctl.h>
+ #if defined(CTL_KERN) && defined (KERN_BOOTTIME)
+ //#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
+ #endif
+ #endif
+#endif //!defined(BOOST_INTERPROCESS_WINDOWS)
-#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)\
- && !defined(BOOST_INTERPROCESS_DISABLE_VARIADIC_TMPL)
-#define BOOST_INTERPROCESS_PERFECT_FORWARDING
+#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
+ #define BOOST_INTERPROCESS_PERFECT_FORWARDING
#endif
//Now declare some Boost.Interprocess features depending on the implementation
-
#if defined(BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
-
-#define BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES
-
-#endif
-
-#if defined(BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
-
-#define BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES
-#define BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES
-
+ #define BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES
+ #define BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES
#endif
// Timeout duration use if BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING is set
#ifndef BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS
-#define BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS 10000
+ #define BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS 10000
#endif
#include <boost/interprocess/detail/config_end.hpp>
diff --git a/boost/interprocess/detail/xsi_shared_memory_device.hpp b/boost/interprocess/detail/xsi_shared_memory_device.hpp
index d2e2bf2ce6..ef4b009bc1 100644
--- a/boost/interprocess/detail/xsi_shared_memory_device.hpp
+++ b/boost/interprocess/detail/xsi_shared_memory_device.hpp
@@ -46,7 +46,7 @@ class xsi_shared_memory_device
{
/// @cond
BOOST_MOVABLE_BUT_NOT_COPYABLE(xsi_shared_memory_file_wrapper)
- /// @endcond
+ /// @endcond
public:
@@ -74,10 +74,10 @@ class xsi_shared_memory_device
{ this->swap(moved); }
xsi_shared_memory_device &operator=(BOOST_RV_REF(xsi_shared_memory_device) moved)
- {
+ {
xsi_shared_memory_device tmp(boost::move(moved));
this->swap(tmp);
- return *this;
+ return *this;
}
//!Swaps two xsi_shared_memory_device. Does not throw
@@ -168,7 +168,7 @@ inline xsi_shared_memory_device::xsi_shared_memory_device()
: m_shm(), m_mode(invalid_mode), m_name()
{}
-inline xsi_shared_memory_device::~xsi_shared_memory_device()
+inline xsi_shared_memory_device::~xsi_shared_memory_device()
{}
inline const char *xsi_shared_memory_device::get_name() const
@@ -178,7 +178,7 @@ inline void xsi_shared_memory_device::swap(xsi_shared_memory_device &other)
{
m_shm.swap(other.m_shm);
std::swap(m_mode, other.m_mode);
- m_name.swap(other.m_name);
+ m_name.swap(other.m_name);
}
inline mapping_handle_t xsi_shared_memory_device::get_mapping_handle() const
diff --git a/boost/interprocess/detail/xsi_shared_memory_file_wrapper.hpp b/boost/interprocess/detail/xsi_shared_memory_file_wrapper.hpp
index d74d9664a5..14811e7e62 100644
--- a/boost/interprocess/detail/xsi_shared_memory_file_wrapper.hpp
+++ b/boost/interprocess/detail/xsi_shared_memory_file_wrapper.hpp
@@ -40,7 +40,7 @@ class xsi_shared_memory_file_wrapper
{
/// @cond
BOOST_MOVABLE_BUT_NOT_COPYABLE(xsi_shared_memory_file_wrapper)
- /// @endcond
+ /// @endcond
public:
xsi_shared_memory_file_wrapper() : xsi_shared_memory() {}
@@ -61,10 +61,10 @@ class xsi_shared_memory_file_wrapper
{ this->swap(moved); }
xsi_shared_memory_file_wrapper &operator=(BOOST_RV_REF(xsi_shared_memory_file_wrapper) moved)
- {
+ {
xsi_shared_memory_file_wrapper tmp(boost::move(moved));
this->swap(tmp);
- return *this;
+ return *this;
}
//!Swaps two xsi_shared_memory_file_wrapper. Does not throw
diff --git a/boost/interprocess/errors.hpp b/boost/interprocess/errors.hpp
index e36b8e4e66..9eed55a29b 100644
--- a/boost/interprocess/errors.hpp
+++ b/boost/interprocess/errors.hpp
@@ -11,7 +11,7 @@
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 Beman Dawes
-// Copyright (C) 2001 Dietmar Kuehl
+// Copyright (C) 2001 Dietmar Kuehl
// Use, modification, and distribution is subject to 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)
@@ -64,16 +64,16 @@ inline int system_error_code() // artifact of POSIX and WINDOWS error reporting
inline void fill_system_message(int sys_err_code, std::string &str)
{
void *lpMsgBuf;
- winapi::format_message(
- winapi::format_message_allocate_buffer |
- winapi::format_message_from_system |
+ winapi::format_message(
+ winapi::format_message_allocate_buffer |
+ winapi::format_message_from_system |
winapi::format_message_ignore_inserts,
0,
sys_err_code,
winapi::make_lang_id(winapi::lang_neutral, winapi::sublang_default), // Default language
reinterpret_cast<char *>(&lpMsgBuf),
0,
- 0
+ 0
);
str += static_cast<const char*>(lpMsgBuf);
winapi::local_free( lpMsgBuf ); // free the buffer
@@ -123,7 +123,7 @@ typedef int native_error_t;
struct ec_xlate
{
native_error_t sys_ec;
- error_code_t ec;
+ error_code_t ec;
};
static const ec_xlate ec_table[] =
@@ -183,9 +183,9 @@ static const ec_xlate ec_table[] =
};
inline error_code_t lookup_error(native_error_t err)
-{
+{
const ec_xlate *cur = &ec_table[0],
- *end = cur + sizeof(ec_table)/sizeof(ec_xlate);
+ *end = cur + sizeof(ec_table)/sizeof(ec_xlate);
for (;cur != end; ++cur ){
if ( err == cur->sys_ec ) return cur->ec;
}
diff --git a/boost/interprocess/file_mapping.hpp b/boost/interprocess/file_mapping.hpp
index 3bad98fca1..2a4e4cca00 100644
--- a/boost/interprocess/file_mapping.hpp
+++ b/boost/interprocess/file_mapping.hpp
@@ -41,27 +41,27 @@ class file_mapping
//!Does not throw
file_mapping();
- //!Opens a file mapping of file "filename", starting in offset
- //!"file_offset", and the mapping's size will be "size". The mapping
+ //!Opens a file mapping of file "filename", starting in offset
+ //!"file_offset", and the mapping's size will be "size". The mapping
//!can be opened for read-only "read_only" or read-write "read_write"
//!modes. Throws interprocess_exception on error.
file_mapping(const char *filename, mode_t mode);
- //!Moves the ownership of "moved"'s file mapping object to *this.
- //!After the call, "moved" does not represent any file mapping object.
+ //!Moves the ownership of "moved"'s file mapping object to *this.
+ //!After the call, "moved" does not represent any file mapping object.
//!Does not throw
file_mapping(BOOST_RV_REF(file_mapping) moved)
: m_handle(file_handle_t(ipcdetail::invalid_file()))
{ this->swap(moved); }
//!Moves the ownership of "moved"'s file mapping to *this.
- //!After the call, "moved" does not represent any file mapping.
+ //!After the call, "moved" does not represent any file mapping.
//!Does not throw
file_mapping &operator=(BOOST_RV_REF(file_mapping) moved)
{
file_mapping tmp(boost::move(moved));
this->swap(tmp);
- return *this;
+ return *this;
}
//!Swaps to file_mappings.
@@ -100,21 +100,21 @@ class file_mapping
/// @endcond
};
-inline file_mapping::file_mapping()
+inline file_mapping::file_mapping()
: m_handle(file_handle_t(ipcdetail::invalid_file()))
{}
-inline file_mapping::~file_mapping()
+inline file_mapping::~file_mapping()
{ this->priv_close(); }
inline const char *file_mapping::get_name() const
{ return m_filename.c_str(); }
inline void file_mapping::swap(file_mapping &other)
-{
+{
std::swap(m_handle, other.m_handle);
std::swap(m_mode, other.m_mode);
- m_filename.swap(other.m_filename);
+ m_filename.swap(other.m_filename);
}
inline mapping_handle_t file_mapping::get_mapping_handle() const
diff --git a/boost/interprocess/indexes/iset_index.hpp b/boost/interprocess/indexes/iset_index.hpp
index 966239290a..8fc91466f3 100644
--- a/boost/interprocess/indexes/iset_index.hpp
+++ b/boost/interprocess/indexes/iset_index.hpp
@@ -34,17 +34,17 @@ namespace interprocess {
template <class MapConfig>
struct iset_index_aux
{
- typedef typename
+ typedef typename
MapConfig::segment_manager_base segment_manager_base;
- typedef typename
+ typedef typename
segment_manager_base::void_pointer void_pointer;
typedef typename bi::make_set_base_hook
< bi::void_pointer<void_pointer>
, bi::optimize_size<true>
>::type derivation_hook;
- typedef typename MapConfig::template
+ typedef typename MapConfig::template
intrusive_value_type<derivation_hook>::type value_type;
typedef std::less<value_type> value_compare;
typedef typename bi::make_set
@@ -82,20 +82,20 @@ class iset_index
struct intrusive_key_value_less
{
bool operator()(const intrusive_compare_key_type &i, const value_type &b) const
- {
+ {
std::size_t blen = b.name_length();
- return (i.m_len < blen) ||
- (i.m_len == blen &&
- std::char_traits<char_type>::compare
+ return (i.m_len < blen) ||
+ (i.m_len == blen &&
+ std::char_traits<char_type>::compare
(i.mp_str, b.name(), i.m_len) < 0);
}
bool operator()(const value_type &b, const intrusive_compare_key_type &i) const
- {
+ {
std::size_t blen = b.name_length();
- return (blen < i.m_len) ||
+ return (blen < i.m_len) ||
(blen == i.m_len &&
- std::char_traits<char_type>::compare
+ std::char_traits<char_type>::compare
(b.name(), i.mp_str, i.m_len) < 0);
}
};
@@ -143,7 +143,7 @@ struct is_intrusive_index
/// @endcond
} //namespace interprocess {
-} //namespace boost
+} //namespace boost
#include <boost/interprocess/detail/config_end.hpp>
diff --git a/boost/interprocess/indexes/iunordered_set_index.hpp b/boost/interprocess/indexes/iunordered_set_index.hpp
index ef1ae79d3b..3c5f85526c 100644
--- a/boost/interprocess/indexes/iunordered_set_index.hpp
+++ b/boost/interprocess/indexes/iunordered_set_index.hpp
@@ -35,17 +35,17 @@ namespace boost { namespace interprocess {
template <class MapConfig>
struct iunordered_set_index_aux
{
- typedef typename
+ typedef typename
MapConfig::segment_manager_base segment_manager_base;
- typedef typename
+ typedef typename
segment_manager_base::void_pointer void_pointer;
typedef typename bi::make_unordered_set_base_hook
< bi::void_pointer<void_pointer>
>::type derivation_hook;
- typedef typename MapConfig::template
+ typedef typename MapConfig::template
intrusive_value_type<derivation_hook>::type value_type;
typedef typename MapConfig::
@@ -58,23 +58,23 @@ struct iunordered_set_index_aux
struct equal_function
{
bool operator()(const intrusive_compare_key_type &i, const value_type &b) const
- {
+ {
return (i.m_len == b.name_length()) &&
- (std::char_traits<char_type>::compare
+ (std::char_traits<char_type>::compare
(i.mp_str, b.name(), i.m_len) == 0);
}
bool operator()(const value_type &b, const intrusive_compare_key_type &i) const
- {
+ {
return (i.m_len == b.name_length()) &&
- (std::char_traits<char_type>::compare
+ (std::char_traits<char_type>::compare
(i.mp_str, b.name(), i.m_len) == 0);
}
bool operator()(const value_type &b1, const value_type &b2) const
- {
+ {
return (b1.name_length() == b2.name_length()) &&
- (std::char_traits<char_type>::compare
+ (std::char_traits<char_type>::compare
(b1.name(), b2.name(), b1.name_length()) == 0);
}
};
@@ -119,7 +119,7 @@ struct iunordered_set_index_aux
/// @endcond
//!Index type based in boost::intrusive::set.
-//!Just derives from boost::intrusive::set
+//!Just derives from boost::intrusive::set
//!and defines the interface needed by managed memory segments
template <class MapConfig>
class iunordered_set_index
@@ -135,9 +135,9 @@ class iunordered_set_index
typedef typename index_aux::equal_function equal_function;
typedef typename index_aux::hash_function hash_function;
typedef typename MapConfig::char_type char_type;
- typedef typename
+ typedef typename
iunordered_set_index_aux<MapConfig>::allocator_type allocator_type;
- typedef typename
+ typedef typename
iunordered_set_index_aux<MapConfig>::allocator_holder allocator_holder;
/// @endcond
@@ -290,7 +290,7 @@ class iunordered_set_index
size_type cur_size = this->size();
size_type cur_count = this->bucket_count();
bucket_ptr old_p = this->bucket_pointer();
-
+
if(!this->size() && old_p != bucket_ptr(&this->init_bucket)){
this->rehash(bucket_traits(bucket_ptr(&this->init_bucket), 1));
destroy_buckets(this->alloc, old_p, cur_count);
@@ -337,7 +337,7 @@ class iunordered_set_index
//Strong guarantee: if something goes wrong
//we should remove the insertion.
//
- //We can use the iterator because the hash function
+ //We can use the iterator because the hash function
//can't throw and this means that "reserve" will
//throw only because of the memory allocation:
//the iterator has not been invalidated.
diff --git a/boost/interprocess/indexes/map_index.hpp b/boost/interprocess/indexes/map_index.hpp
index ffea73e8d9..1bfc7ce310 100644
--- a/boost/interprocess/indexes/map_index.hpp
+++ b/boost/interprocess/indexes/map_index.hpp
@@ -48,7 +48,7 @@ struct map_index_aux
} //namespace ipcdetail {
-//!Index type based in boost::interprocess::map. Just derives from boost::interprocess::map
+//!Index type based in boost::interprocess::map. Just derives from boost::interprocess::map
//!and defines the interface needed by managed memory segments
template <class MapConfig>
class map_index
diff --git a/boost/interprocess/indexes/null_index.hpp b/boost/interprocess/indexes/null_index.hpp
index 81c88be79b..a0353b101c 100644
--- a/boost/interprocess/indexes/null_index.hpp
+++ b/boost/interprocess/indexes/null_index.hpp
@@ -16,7 +16,7 @@
#include <boost/interprocess/offset_ptr.hpp>
//!\file
-//!Describes a null index adaptor, so that if we don't want to construct
+//!Describes a null index adaptor, so that if we don't want to construct
//!named objects, we can use this null index type to save resources.
namespace boost {
diff --git a/boost/interprocess/indexes/unordered_map_index.hpp b/boost/interprocess/indexes/unordered_map_index.hpp
index a14fa1d4a7..7cf4b85e65 100644
--- a/boost/interprocess/indexes/unordered_map_index.hpp
+++ b/boost/interprocess/indexes/unordered_map_index.hpp
@@ -69,7 +69,7 @@ class unordered_map_index
/// @cond
typedef unordered_map_index_aux<MapConfig> index_aux;
typedef typename index_aux::index_t base_type;
- typedef typename
+ typedef typename
MapConfig::segment_manager_base segment_manager_base;
/// @endcond
diff --git a/boost/interprocess/interprocess_fwd.hpp b/boost/interprocess/interprocess_fwd.hpp
index 2b3e3eba07..68fd89fb91 100644
--- a/boost/interprocess/interprocess_fwd.hpp
+++ b/boost/interprocess/interprocess_fwd.hpp
@@ -214,7 +214,7 @@ template <class CharType
,template<class IndexConfig> class IndexType>
class basic_managed_shared_memory;
-typedef basic_managed_shared_memory
+typedef basic_managed_shared_memory
<char
,rbtree_best_fit<mutex_family>
,iset_index>
@@ -238,7 +238,7 @@ template <class CharType
,template<class IndexConfig> class IndexType>
class basic_managed_windows_shared_memory;
-typedef basic_managed_windows_shared_memory
+typedef basic_managed_windows_shared_memory
<char
,rbtree_best_fit<mutex_family>
,iset_index>
@@ -259,7 +259,7 @@ template <class CharType
,template<class IndexConfig> class IndexType>
class basic_managed_xsi_shared_memory;
-typedef basic_managed_xsi_shared_memory
+typedef basic_managed_xsi_shared_memory
<char
,rbtree_best_fit<mutex_family>
,iset_index>
diff --git a/boost/interprocess/ipc/message_queue.hpp b/boost/interprocess/ipc/message_queue.hpp
index d3846afb7c..67dd574f61 100644
--- a/boost/interprocess/ipc/message_queue.hpp
+++ b/boost/interprocess/ipc/message_queue.hpp
@@ -66,24 +66,24 @@ class message_queue_t
//!the maximum number of messages will be "max_num_msg" and the maximum message size
//!will be "max_msg_size". Throws on error and if the queue was previously created.
message_queue_t(create_only_t create_only,
- const char *name,
- size_type max_num_msg,
+ const char *name,
+ size_type max_num_msg,
size_type max_msg_size,
const permissions &perm = permissions());
- //!Opens or creates a process shared message queue with name "name".
- //!If the queue is created, the maximum number of messages will be "max_num_msg"
- //!and the maximum message size will be "max_msg_size". If queue was previously
+ //!Opens or creates a process shared message queue with name "name".
+ //!If the queue is created, the maximum number of messages will be "max_num_msg"
+ //!and the maximum message size will be "max_msg_size". If queue was previously
//!created the queue will be opened and "max_num_msg" and "max_msg_size" parameters
//!are ignored. Throws on error.
message_queue_t(open_or_create_t open_or_create,
- const char *name,
- size_type max_num_msg,
+ const char *name,
+ size_type max_num_msg,
size_type max_msg_size,
const permissions &perm = permissions());
- //!Opens a previously created process shared message queue with name "name".
- //!If the queue was not previously created or there are no free resources,
+ //!Opens a previously created process shared message queue with name "name".
+ //!If the queue was not previously created or there are no free resources,
//!throws an error.
message_queue_t(open_only_t open_only,
const char *name);
@@ -95,65 +95,65 @@ class message_queue_t
//!this resource. The resource can still be opened again calling
//!the open constructor overload. To erase the message queue from the system
//!use remove().
- ~message_queue_t();
+ ~message_queue_t();
- //!Sends a message stored in buffer "buffer" with size "buffer_size" in the
+ //!Sends a message stored in buffer "buffer" with size "buffer_size" in the
//!message queue with priority "priority". If the message queue is full
//!the sender is blocked. Throws interprocess_error on error.*/
- void send (const void *buffer, size_type buffer_size,
+ void send (const void *buffer, size_type buffer_size,
unsigned int priority);
- //!Sends a message stored in buffer "buffer" with size "buffer_size" through the
+ //!Sends a message stored in buffer "buffer" with size "buffer_size" through the
//!message queue with priority "priority". If the message queue is full
//!the sender is not blocked and returns false, otherwise returns true.
//!Throws interprocess_error on error.
- bool try_send (const void *buffer, size_type buffer_size,
+ bool try_send (const void *buffer, size_type buffer_size,
unsigned int priority);
- //!Sends a message stored in buffer "buffer" with size "buffer_size" in the
+ //!Sends a message stored in buffer "buffer" with size "buffer_size" in the
//!message queue with priority "priority". If the message queue is full
//!the sender retries until time "abs_time" is reached. Returns true if
//!the message has been successfully sent. Returns false if timeout is reached.
//!Throws interprocess_error on error.
- bool timed_send (const void *buffer, size_type buffer_size,
+ bool timed_send (const void *buffer, size_type buffer_size,
unsigned int priority, const boost::posix_time::ptime& abs_time);
- //!Receives a message from the message queue. The message is stored in buffer
- //!"buffer", which has size "buffer_size". The received message has size
+ //!Receives a message from the message queue. The message is stored in buffer
+ //!"buffer", which has size "buffer_size". The received message has size
//!"recvd_size" and priority "priority". If the message queue is empty
//!the receiver is blocked. Throws interprocess_error on error.
- void receive (void *buffer, size_type buffer_size,
+ void receive (void *buffer, size_type buffer_size,
size_type &recvd_size,unsigned int &priority);
- //!Receives a message from the message queue. The message is stored in buffer
- //!"buffer", which has size "buffer_size". The received message has size
+ //!Receives a message from the message queue. The message is stored in buffer
+ //!"buffer", which has size "buffer_size". The received message has size
//!"recvd_size" and priority "priority". If the message queue is empty
//!the receiver is not blocked and returns false, otherwise returns true.
//!Throws interprocess_error on error.
- bool try_receive (void *buffer, size_type buffer_size,
+ bool try_receive (void *buffer, size_type buffer_size,
size_type &recvd_size,unsigned int &priority);
- //!Receives a message from the message queue. The message is stored in buffer
- //!"buffer", which has size "buffer_size". The received message has size
+ //!Receives a message from the message queue. The message is stored in buffer
+ //!"buffer", which has size "buffer_size". The received message has size
//!"recvd_size" and priority "priority". If the message queue is empty
//!the receiver retries until time "abs_time" is reached. Returns true if
//!the message has been successfully sent. Returns false if timeout is reached.
//!Throws interprocess_error on error.
- bool timed_receive (void *buffer, size_type buffer_size,
+ bool timed_receive (void *buffer, size_type buffer_size,
size_type &recvd_size,unsigned int &priority,
const boost::posix_time::ptime &abs_time);
//!Returns the maximum number of messages allowed by the queue. The message
- //!queue must be opened or created previously. Otherwise, returns 0.
+ //!queue must be opened or created previously. Otherwise, returns 0.
//!Never throws
size_type get_max_msg() const;
//!Returns the maximum size of message allowed by the queue. The message
- //!queue must be opened or created previously. Otherwise, returns 0.
+ //!queue must be opened or created previously. Otherwise, returns 0.
//!Never throws
size_type get_max_msg_size() const;
- //!Returns the number of messages currently stored.
+ //!Returns the number of messages currently stored.
//!Never throws
size_type get_num_msg();
@@ -161,16 +161,16 @@ class message_queue_t
//!Returns false on error. Never throws
static bool remove(const char *name);
- /// @cond
+ /// @cond
private:
typedef boost::posix_time::ptime ptime;
bool do_receive(block_t block,
- void *buffer, size_type buffer_size,
+ void *buffer, size_type buffer_size,
size_type &recvd_size, unsigned int &priority,
const ptime &abs_time);
bool do_send(block_t block,
- const void *buffer, size_type buffer_size,
+ const void *buffer, size_type buffer_size,
unsigned int priority, const ptime &abs_time);
//!Returns the needed memory size for the shared message queue.
@@ -187,7 +187,7 @@ namespace ipcdetail {
//!This header is the prefix of each message in the queue
template<class VoidPointer>
-class msg_hdr_t
+class msg_hdr_t
{
typedef VoidPointer void_pointer;
typedef typename boost::intrusive::
@@ -212,36 +212,36 @@ class priority_functor
rebind_pointer<msg_hdr_t<VoidPointer> >::type msg_hdr_ptr_t;
public:
- bool operator()(const msg_hdr_ptr_t &msg1,
+ bool operator()(const msg_hdr_ptr_t &msg1,
const msg_hdr_ptr_t &msg2) const
{ return msg1->priority < msg2->priority; }
};
-//!This header is placed in the beginning of the shared memory and contains
-//!the data to control the queue. This class initializes the shared memory
+//!This header is placed in the beginning of the shared memory and contains
+//!the data to control the queue. This class initializes the shared memory
//!in the following way: in ascending memory address with proper alignment
//!fillings:
//!
-//!-> mq_hdr_t:
+//!-> mq_hdr_t:
//! Main control block that controls the rest of the elements
//!
//!-> offset_ptr<msg_hdr_t> index [max_num_msg]
-//! An array of pointers with size "max_num_msg" called index. Each pointer
-//! points to a preallocated message. The elements of this array are
+//! An array of pointers with size "max_num_msg" called index. Each pointer
+//! points to a preallocated message. The elements of this array are
//! reordered in runtime in the following way:
//!
-//! When the current number of messages is "cur_num_msg", the first
+//! When the current number of messages is "cur_num_msg", the first
//! "cur_num_msg" pointers point to inserted messages and the rest
//! point to free messages. The first "cur_num_msg" pointers are
-//! ordered by the priority of the pointed message and by insertion order
-//! if two messages have the same priority. So the next message to be
+//! ordered by the priority of the pointed message and by insertion order
+//! if two messages have the same priority. So the next message to be
//! used in a "receive" is pointed by index [cur_num_msg-1] and the first free
//! message ready to be used in a "send" operation is index [cur_num_msg].
//! This transforms index in a fixed size priority queue with an embedded free
//! message queue.
//!
//!-> struct message_t
-//! {
+//! {
//! msg_hdr_t header;
//! char[max_msg_size] data;
//! } messages [max_num_msg];
@@ -252,7 +252,7 @@ class priority_functor
template<class VoidPointer>
class mq_hdr_t
: public ipcdetail::priority_functor<VoidPointer>
-{
+{
typedef VoidPointer void_pointer;
typedef msg_hdr_t<void_pointer> msg_header;
typedef typename boost::intrusive::
@@ -266,12 +266,12 @@ class mq_hdr_t
rebind_pointer<msg_hdr_ptr_t>::type msg_hdr_ptr_ptr_t;
public:
- //!Constructor. This object must be constructed in the beginning of the
+ //!Constructor. This object must be constructed in the beginning of the
//!shared memory of the size returned by the function "get_mem_size".
//!This constructor initializes the needed resources and creates
//!the internal structures like the priority index. This can throw.*/
mq_hdr_t(size_type max_num_msg, size_type max_msg_size)
- : m_max_num_msg(max_num_msg),
+ : m_max_num_msg(max_num_msg),
m_max_msg_size(max_msg_size),
m_cur_num_msg(0)
{ this->initialize_memory(); }
@@ -298,7 +298,7 @@ class mq_hdr_t
//!Inserts the first free message in the priority queue
void queue_free_msg()
- {
+ {
//Get free msg
msg_hdr_ptr_t free = mp_index[m_cur_num_msg];
//Get priority queue's range
@@ -312,19 +312,19 @@ class mq_hdr_t
++m_cur_num_msg;
}
- //!Returns the number of bytes needed to construct a message queue with
- //!"max_num_size" maximum number of messages and "max_msg_size" maximum
+ //!Returns the number of bytes needed to construct a message queue with
+ //!"max_num_size" maximum number of messages and "max_msg_size" maximum
//!message size. Never throws.
static size_type get_mem_size
(size_type max_msg_size, size_type max_num_msg)
{
- const size_type
+ const size_type
msg_hdr_align = ::boost::alignment_of<msg_header>::value,
index_align = ::boost::alignment_of<msg_hdr_ptr_t>::value,
r_hdr_size = ipcdetail::ct_rounded_size<sizeof(mq_hdr_t), index_align>::value,
r_index_size = ipcdetail::get_rounded_size(sizeof(msg_hdr_ptr_t)*max_num_msg, msg_hdr_align),
r_max_msg_size = ipcdetail::get_rounded_size(max_msg_size, msg_hdr_align) + sizeof(msg_header);
- return r_hdr_size + r_index_size + (max_num_msg*r_max_msg_size) +
+ return r_hdr_size + r_index_size + (max_num_msg*r_max_msg_size) +
ipcdetail::managed_open_or_create_impl<shared_memory_object>::ManagedOpenOrCreateUserOffset;
}
@@ -332,7 +332,7 @@ class mq_hdr_t
//!message index. Never throws.
void initialize_memory()
{
- const size_type
+ const size_type
msg_hdr_align = ::boost::alignment_of<msg_header>::value,
index_align = ::boost::alignment_of<msg_hdr_ptr_t>::value,
r_hdr_size = ipcdetail::ct_rounded_size<sizeof(mq_hdr_t), index_align>::value,
@@ -345,7 +345,7 @@ class mq_hdr_t
//Pointer to the first message header
msg_header *msg_hdr = reinterpret_cast<msg_header*>
- (reinterpret_cast<char*>(this)+r_hdr_size+r_index_size);
+ (reinterpret_cast<char*>(this)+r_hdr_size+r_index_size);
//Initialize the pointer to the index
mp_index = index;
@@ -376,7 +376,7 @@ class mq_hdr_t
};
-//!This is the atomic functor to be executed when creating or opening
+//!This is the atomic functor to be executed when creating or opening
//!shared memory. Never throws
template<class VoidPointer>
class initialization_func_t
@@ -388,7 +388,7 @@ class initialization_func_t
typedef typename boost::intrusive::pointer_traits<char_ptr>::difference_type difference_type;
typedef typename boost::make_unsigned<difference_type>::type size_type;
- initialization_func_t(size_type maxmsg = 0,
+ initialization_func_t(size_type maxmsg = 0,
size_type maxmsgsize = 0)
: m_maxmsg (maxmsg), m_maxmsgsize(maxmsgsize) {}
@@ -403,7 +403,7 @@ class initialization_func_t
new (mptr) mq_hdr_t<VoidPointer>(m_maxmsg, m_maxmsgsize);
}
BOOST_CATCH(...){
- return false;
+ return false;
}
BOOST_CATCH_END
}
@@ -426,13 +426,13 @@ inline typename message_queue_t<VoidPointer>::size_type message_queue_t<VoidPoin
template<class VoidPointer>
inline message_queue_t<VoidPointer>::message_queue_t(create_only_t create_only,
- const char *name,
- size_type max_num_msg,
+ const char *name,
+ size_type max_num_msg,
size_type max_msg_size,
const permissions &perm)
//Create shared memory and execute functor atomically
- : m_shmem(create_only,
- name,
+ : m_shmem(create_only,
+ name,
get_mem_size(max_msg_size, max_num_msg),
read_write,
static_cast<void*>(0),
@@ -443,13 +443,13 @@ inline message_queue_t<VoidPointer>::message_queue_t(create_only_t create_only,
template<class VoidPointer>
inline message_queue_t<VoidPointer>::message_queue_t(open_or_create_t open_or_create,
- const char *name,
- size_type max_num_msg,
+ const char *name,
+ size_type max_num_msg,
size_type max_msg_size,
const permissions &perm)
//Create shared memory and execute functor atomically
- : m_shmem(open_or_create,
- name,
+ : m_shmem(open_or_create,
+ name,
get_mem_size(max_msg_size, max_num_msg),
read_write,
static_cast<void*>(0),
@@ -462,7 +462,7 @@ template<class VoidPointer>
inline message_queue_t<VoidPointer>::message_queue_t(open_only_t open_only,
const char *name)
//Create shared memory and execute functor atomically
- : m_shmem(open_only,
+ : m_shmem(open_only,
name,
read_write,
static_cast<void*>(0),
@@ -494,7 +494,7 @@ inline bool message_queue_t<VoidPointer>::timed_send
template<class VoidPointer>
inline bool message_queue_t<VoidPointer>::do_send(block_t block,
- const void *buffer, size_type buffer_size,
+ const void *buffer, size_type buffer_size,
unsigned int priority, const boost::posix_time::ptime &abs_time)
{
ipcdetail::mq_hdr_t<VoidPointer> *p_hdr = static_cast<ipcdetail::mq_hdr_t<VoidPointer>*>(m_shmem.get_user_address());
@@ -536,7 +536,7 @@ inline bool message_queue_t<VoidPointer>::do_send(block_t block,
break;
}
}
-
+
//Get the first free message from free message queue
ipcdetail::msg_hdr_t<VoidPointer> *free_msg = p_hdr->free_msg();
if (free_msg == 0) {
@@ -553,7 +553,7 @@ inline bool message_queue_t<VoidPointer>::do_send(block_t block,
// bool was_empty = p_hdr->is_empty();
//Insert the first free message in the priority queue
p_hdr->queue_free_msg();
-
+
//If this message changes the queue empty state, notify it to receivers
// if (was_empty){
p_hdr->m_cond_recv.notify_one();
@@ -564,19 +564,19 @@ inline bool message_queue_t<VoidPointer>::do_send(block_t block,
}
template<class VoidPointer>
-inline void message_queue_t<VoidPointer>::receive(void *buffer, size_type buffer_size,
+inline void message_queue_t<VoidPointer>::receive(void *buffer, size_type buffer_size,
size_type &recvd_size, unsigned int &priority)
{ this->do_receive(blocking, buffer, buffer_size, recvd_size, priority, ptime()); }
template<class VoidPointer>
inline bool
- message_queue_t<VoidPointer>::try_receive(void *buffer, size_type buffer_size,
+ message_queue_t<VoidPointer>::try_receive(void *buffer, size_type buffer_size,
size_type &recvd_size, unsigned int &priority)
{ return this->do_receive(non_blocking, buffer, buffer_size, recvd_size, priority, ptime()); }
template<class VoidPointer>
inline bool
- message_queue_t<VoidPointer>::timed_receive(void *buffer, size_type buffer_size,
+ message_queue_t<VoidPointer>::timed_receive(void *buffer, size_type buffer_size,
size_type &recvd_size, unsigned int &priority,
const boost::posix_time::ptime &abs_time)
{
@@ -590,7 +590,7 @@ inline bool
template<class VoidPointer>
inline bool
message_queue_t<VoidPointer>::do_receive(block_t block,
- void *buffer, size_type buffer_size,
+ void *buffer, size_type buffer_size,
size_type &recvd_size, unsigned int &priority,
const boost::posix_time::ptime &abs_time)
{
@@ -666,20 +666,20 @@ inline bool
template<class VoidPointer>
inline typename message_queue_t<VoidPointer>::size_type message_queue_t<VoidPointer>::get_max_msg() const
-{
+{
ipcdetail::mq_hdr_t<VoidPointer> *p_hdr = static_cast<ipcdetail::mq_hdr_t<VoidPointer>*>(m_shmem.get_user_address());
return p_hdr ? p_hdr->m_max_num_msg : 0; }
template<class VoidPointer>
inline typename message_queue_t<VoidPointer>::size_type message_queue_t<VoidPointer>::get_max_msg_size() const
-{
+{
ipcdetail::mq_hdr_t<VoidPointer> *p_hdr = static_cast<ipcdetail::mq_hdr_t<VoidPointer>*>(m_shmem.get_user_address());
- return p_hdr ? p_hdr->m_max_msg_size : 0;
+ return p_hdr ? p_hdr->m_max_msg_size : 0;
}
template<class VoidPointer>
inline typename message_queue_t<VoidPointer>::size_type message_queue_t<VoidPointer>::get_num_msg()
-{
+{
ipcdetail::mq_hdr_t<VoidPointer> *p_hdr = static_cast<ipcdetail::mq_hdr_t<VoidPointer>*>(m_shmem.get_user_address());
if(p_hdr){
//---------------------------------------------
@@ -688,7 +688,7 @@ inline typename message_queue_t<VoidPointer>::size_type message_queue_t<VoidPoin
return p_hdr->m_cur_num_msg;
}
- return 0;
+ return 0;
}
template<class VoidPointer>
diff --git a/boost/interprocess/managed_external_buffer.hpp b/boost/interprocess/managed_external_buffer.hpp
index a2cf47f4e6..e268e57601 100644
--- a/boost/interprocess/managed_external_buffer.hpp
+++ b/boost/interprocess/managed_external_buffer.hpp
@@ -23,34 +23,34 @@
#include <boost/assert.hpp>
//These includes needed to fulfill default template parameters of
//predeclarations in interprocess_fwd.hpp
-#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
+#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
#include <boost/interprocess/sync/mutex_family.hpp>
#include <boost/interprocess/indexes/iset_index.hpp>
//!\file
-//!Describes a named user memory allocation user class.
+//!Describes a named user memory allocation user class.
namespace boost {
namespace interprocess {
-//!A basic user memory named object creation class. Inherits all
-//!basic functionality from
+//!A basic user memory named object creation class. Inherits all
+//!basic functionality from
//!basic_managed_memory_impl<CharType, AllocationAlgorithm, IndexType>*/
template
<
- class CharType,
- class AllocationAlgorithm,
+ class CharType,
+ class AllocationAlgorithm,
template<class IndexConfig> class IndexType
>
-class basic_managed_external_buffer
+class basic_managed_external_buffer
: public ipcdetail::basic_managed_memory_impl <CharType, AllocationAlgorithm, IndexType>
{
/// @cond
- typedef ipcdetail::basic_managed_memory_impl
+ typedef ipcdetail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType> base_t;
BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_managed_external_buffer)
/// @endcond
-
+
public:
typedef typename base_t::size_type size_type;
diff --git a/boost/interprocess/managed_heap_memory.hpp b/boost/interprocess/managed_heap_memory.hpp
index 74869bb1f5..87107855f2 100644
--- a/boost/interprocess/managed_heap_memory.hpp
+++ b/boost/interprocess/managed_heap_memory.hpp
@@ -24,32 +24,32 @@
#include <boost/detail/no_exceptions_support.hpp>
//These includes needed to fulfill default template parameters of
//predeclarations in interprocess_fwd.hpp
-#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
+#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
#include <boost/interprocess/sync/mutex_family.hpp>
#include <boost/interprocess/indexes/iset_index.hpp>
//!\file
-//!Describes a named heap memory allocation user class.
+//!Describes a named heap memory allocation user class.
namespace boost {
namespace interprocess {
-//!A basic heap memory named object creation class. Initializes the
-//!heap memory segment. Inherits all basic functionality from
+//!A basic heap memory named object creation class. Initializes the
+//!heap memory segment. Inherits all basic functionality from
//!basic_managed_memory_impl<CharType, AllocationAlgorithm, IndexType>*/
template
<
- class CharType,
- class AllocationAlgorithm,
+ class CharType,
+ class AllocationAlgorithm,
template<class IndexConfig> class IndexType
>
-class basic_managed_heap_memory
+class basic_managed_heap_memory
: public ipcdetail::basic_managed_memory_impl <CharType, AllocationAlgorithm, IndexType>
{
/// @cond
private:
- typedef ipcdetail::basic_managed_memory_impl
+ typedef ipcdetail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType> base_t;
BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_managed_heap_memory)
/// @endcond
@@ -90,16 +90,16 @@ class basic_managed_heap_memory
}
//!Tries to resize internal heap memory so that
- //!we have room for more objects.
- //!WARNING: If memory is reallocated, all the objects will
+ //!we have room for more objects.
+ //!WARNING: If memory is reallocated, all the objects will
//!be binary-copied to the new buffer. To be able to use
//!this function, all pointers constructed in this buffer
//!must be offset pointers. Otherwise, the result is undefined.
//!Returns true if the growth has been successful, so you will
- //!have some extra bytes to allocate new objects. If returns
+ //!have some extra bytes to allocate new objects. If returns
//!false, the heap allocation has failed.
bool grow(size_type extra_bytes)
- {
+ {
//If memory is reallocated, data will
//be automatically copied
BOOST_TRY{
@@ -129,7 +129,7 @@ class basic_managed_heap_memory
private:
//!Frees resources. Never throws.
void priv_close()
- {
+ {
base_t::destroy_impl();
std::vector<char>().swap(m_heapmem);
}
diff --git a/boost/interprocess/managed_mapped_file.hpp b/boost/interprocess/managed_mapped_file.hpp
index 218fa9783c..5a351adfa5 100644
--- a/boost/interprocess/managed_mapped_file.hpp
+++ b/boost/interprocess/managed_mapped_file.hpp
@@ -26,23 +26,23 @@
#include <boost/interprocess/permissions.hpp>
//These includes needed to fulfill default template parameters of
//predeclarations in interprocess_fwd.hpp
-#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
+#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
#include <boost/interprocess/sync/mutex_family.hpp>
#include <boost/interprocess/indexes/iset_index.hpp>
namespace boost {
namespace interprocess {
-//!A basic mapped file named object creation class. Initializes the
-//!mapped file. Inherits all basic functionality from
+//!A basic mapped file named object creation class. Initializes the
+//!mapped file. Inherits all basic functionality from
//!basic_managed_memory_impl<CharType, AllocationAlgorithm, IndexType>
template
<
- class CharType,
- class AllocationAlgorithm,
+ class CharType,
+ class AllocationAlgorithm,
template<class IndexConfig> class IndexType
>
-class basic_managed_mapped_file
+class basic_managed_mapped_file
: public ipcdetail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType
,ipcdetail::managed_open_or_create_impl< ipcdetail::file_wrapper
@@ -51,7 +51,7 @@ class basic_managed_mapped_file
{
/// @cond
public:
- typedef ipcdetail::basic_managed_memory_impl
+ typedef ipcdetail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType,
ipcdetail::managed_open_or_create_impl
<ipcdetail::file_wrapper, AllocationAlgorithm::Alignment>::ManagedOpenOrCreateUserOffset
@@ -61,7 +61,7 @@ class basic_managed_mapped_file
private:
- typedef ipcdetail::create_open_func<base_t> create_open_func_t;
+ typedef ipcdetail::create_open_func<base_t> create_open_func_t;
typedef ipcdetail::managed_open_or_create_impl< ipcdetail::file_wrapper
, AllocationAlgorithm::Alignment> managed_open_or_create_type;
@@ -75,16 +75,16 @@ class basic_managed_mapped_file
public: //functions
- //!Creates mapped file and creates and places the segment manager.
+ //!Creates mapped file and creates and places the segment manager.
//!This can throw.
basic_managed_mapped_file()
{}
- //!Creates mapped file and creates and places the segment manager.
+ //!Creates mapped file and creates and places the segment manager.
//!This can throw.
basic_managed_mapped_file(create_only_t create_only, const char *name,
size_type size, const void *addr = 0, const permissions &perm = permissions())
- : m_mfile(create_only, name, size, read_write, addr,
+ : m_mfile(create_only, name, size, read_write, addr,
create_open_func_t(get_this_pointer(), ipcdetail::DoCreate), perm)
{}
@@ -93,39 +93,39 @@ class basic_managed_mapped_file
//!segment.
//!This can throw.
basic_managed_mapped_file (open_or_create_t open_or_create,
- const char *name, size_type size,
+ const char *name, size_type size,
const void *addr = 0, const permissions &perm = permissions())
: m_mfile(open_or_create, name, size, read_write, addr,
- create_open_func_t(get_this_pointer(),
+ create_open_func_t(get_this_pointer(),
ipcdetail::DoOpenOrCreate), perm)
{}
//!Connects to a created mapped file and its segment manager.
//!This can throw.
- basic_managed_mapped_file (open_only_t open_only, const char* name,
+ basic_managed_mapped_file (open_only_t open_only, const char* name,
const void *addr = 0)
: m_mfile(open_only, name, read_write, addr,
- create_open_func_t(get_this_pointer(),
+ create_open_func_t(get_this_pointer(),
ipcdetail::DoOpen))
{}
//!Connects to a created mapped file and its segment manager
//!in copy_on_write mode.
//!This can throw.
- basic_managed_mapped_file (open_copy_on_write_t, const char* name,
+ basic_managed_mapped_file (open_copy_on_write_t, const char* name,
const void *addr = 0)
- : m_mfile(open_only, name, copy_on_write, addr,
- create_open_func_t(get_this_pointer(),
+ : m_mfile(open_only, name, copy_on_write, addr,
+ create_open_func_t(get_this_pointer(),
ipcdetail::DoOpen))
{}
//!Connects to a created mapped file and its segment manager
//!in read-only mode.
//!This can throw.
- basic_managed_mapped_file (open_read_only_t, const char* name,
+ basic_managed_mapped_file (open_read_only_t, const char* name,
const void *addr = 0)
- : m_mfile(open_only, name, read_only, addr,
- create_open_func_t(get_this_pointer(),
+ : m_mfile(open_only, name, read_only, addr,
+ create_open_func_t(get_this_pointer(),
ipcdetail::DoOpen))
{}
@@ -167,8 +167,8 @@ class basic_managed_mapped_file
bool flush()
{ return m_mfile.flush(); }
- //!Tries to resize mapped file so that we have room for
- //!more objects.
+ //!Tries to resize mapped file so that we have room for
+ //!more objects.
//!
//!This function is not synchronized so no other thread or process should
//!be reading or writing the file
diff --git a/boost/interprocess/managed_shared_memory.hpp b/boost/interprocess/managed_shared_memory.hpp
index cec9591be4..0f74c1a0b9 100644
--- a/boost/interprocess/managed_shared_memory.hpp
+++ b/boost/interprocess/managed_shared_memory.hpp
@@ -25,23 +25,23 @@
#include <boost/interprocess/permissions.hpp>
//These includes needed to fulfill default template parameters of
//predeclarations in interprocess_fwd.hpp
-#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
+#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
#include <boost/interprocess/sync/mutex_family.hpp>
namespace boost {
namespace interprocess {
-//!A basic shared memory named object creation class. Initializes the
-//!shared memory segment. Inherits all basic functionality from
+//!A basic shared memory named object creation class. Initializes the
+//!shared memory segment. Inherits all basic functionality from
//!basic_managed_memory_impl<CharType, AllocationAlgorithm, IndexType>*/
template
<
- class CharType,
- class AllocationAlgorithm,
+ class CharType,
+ class AllocationAlgorithm,
template<class IndexConfig> class IndexType
>
-class basic_managed_shared_memory
+class basic_managed_shared_memory
: public ipcdetail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType
,ipcdetail::managed_open_or_create_impl<shared_memory_object
@@ -50,7 +50,7 @@ class basic_managed_shared_memory
, AllocationAlgorithm::Alignment>
{
/// @cond
- typedef ipcdetail::basic_managed_memory_impl
+ typedef ipcdetail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType,
ipcdetail::managed_open_or_create_impl
< shared_memory_object, AllocationAlgorithm::Alignment>::ManagedOpenOrCreateUserOffset> base_t;
@@ -87,12 +87,12 @@ class basic_managed_shared_memory
basic_managed_shared_memory()
{}
- //!Creates shared memory and creates and places the segment manager.
+ //!Creates shared memory and creates and places the segment manager.
//!This can throw.
basic_managed_shared_memory(create_only_t create_only, const char *name,
size_type size, const void *addr = 0, const permissions& perm = permissions())
: base_t()
- , base2_t(create_only, name, size, read_write, addr,
+ , base2_t(create_only, name, size, read_write, addr,
create_open_func_t(get_this_pointer(), ipcdetail::DoCreate), perm)
{}
@@ -101,43 +101,43 @@ class basic_managed_shared_memory
//!segment.
//!This can throw.
basic_managed_shared_memory (open_or_create_t open_or_create,
- const char *name, size_type size,
+ const char *name, size_type size,
const void *addr = 0, const permissions& perm = permissions())
: base_t()
- , base2_t(open_or_create, name, size, read_write, addr,
- create_open_func_t(get_this_pointer(),
+ , base2_t(open_or_create, name, size, read_write, addr,
+ create_open_func_t(get_this_pointer(),
ipcdetail::DoOpenOrCreate), perm)
{}
//!Connects to a created shared memory and its segment manager.
//!in copy_on_write mode.
//!This can throw.
- basic_managed_shared_memory (open_copy_on_write_t, const char* name,
+ basic_managed_shared_memory (open_copy_on_write_t, const char* name,
const void *addr = 0)
: base_t()
- , base2_t(open_only, name, copy_on_write, addr,
- create_open_func_t(get_this_pointer(),
+ , base2_t(open_only, name, copy_on_write, addr,
+ create_open_func_t(get_this_pointer(),
ipcdetail::DoOpen))
{}
//!Connects to a created shared memory and its segment manager.
//!in read-only mode.
//!This can throw.
- basic_managed_shared_memory (open_read_only_t, const char* name,
+ basic_managed_shared_memory (open_read_only_t, const char* name,
const void *addr = 0)
: base_t()
- , base2_t(open_only, name, read_only, addr,
- create_open_func_t(get_this_pointer(),
+ , base2_t(open_only, name, read_only, addr,
+ create_open_func_t(get_this_pointer(),
ipcdetail::DoOpen))
{}
//!Connects to a created shared memory and its segment manager.
//!This can throw.
- basic_managed_shared_memory (open_only_t open_only, const char* name,
+ basic_managed_shared_memory (open_only_t open_only, const char* name,
const void *addr = 0)
: base_t()
- , base2_t(open_only, name, read_write, addr,
- create_open_func_t(get_this_pointer(),
+ , base2_t(open_only, name, read_write, addr,
+ create_open_func_t(get_this_pointer(),
ipcdetail::DoOpen))
{}
@@ -168,7 +168,7 @@ class basic_managed_shared_memory
}
//!Tries to resize the managed shared memory object so that we have
- //!room for more objects.
+ //!room for more objects.
//!
//!This function is not synchronized so no other thread or process should
//!be reading or writing the file
@@ -187,12 +187,6 @@ class basic_managed_shared_memory
return base_t::template shrink_to_fit
<basic_managed_shared_memory>(shmname);
}
-
- bool flush()
- {
- return this->base2_t::flush();
- }
-
/// @cond
//!Tries to find a previous named allocation address. Returns a memory
diff --git a/boost/interprocess/managed_windows_shared_memory.hpp b/boost/interprocess/managed_windows_shared_memory.hpp
index 959194cc19..414007a614 100644
--- a/boost/interprocess/managed_windows_shared_memory.hpp
+++ b/boost/interprocess/managed_windows_shared_memory.hpp
@@ -25,15 +25,15 @@
#include <boost/move/move.hpp>
//These includes needed to fulfill default template parameters of
//predeclarations in interprocess_fwd.hpp
-#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
+#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
#include <boost/interprocess/sync/mutex_family.hpp>
#include <boost/interprocess/indexes/iset_index.hpp>
namespace boost {
namespace interprocess {
-//!A basic managed windows shared memory creation class. Initializes the
-//!shared memory segment. Inherits all basic functionality from
+//!A basic managed windows shared memory creation class. Initializes the
+//!shared memory segment. Inherits all basic functionality from
//!basic_managed_memory_impl<CharType, AllocationAlgorithm, IndexType>
//!Unlike basic_managed_shared_memory, it has
//!no kernel persistence and the shared memory is destroyed
@@ -45,11 +45,11 @@ namespace interprocess {
//!basic_managed_shared_memory can't communicate between them.
template
<
- class CharType,
- class AllocationAlgorithm,
+ class CharType,
+ class AllocationAlgorithm,
template<class IndexConfig> class IndexType
>
-class basic_managed_windows_shared_memory
+class basic_managed_windows_shared_memory
: public ipcdetail::basic_managed_memory_impl
< CharType, AllocationAlgorithm, IndexType
, ipcdetail::managed_open_or_create_impl
@@ -60,7 +60,7 @@ class basic_managed_windows_shared_memory
{
/// @cond
private:
- typedef ipcdetail::basic_managed_memory_impl
+ typedef ipcdetail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType,
ipcdetail::managed_open_or_create_impl
<windows_shared_memory, AllocationAlgorithm::Alignment, false>::ManagedOpenOrCreateUserOffset> base_t;
@@ -82,12 +82,12 @@ class basic_managed_windows_shared_memory
basic_managed_windows_shared_memory()
{}
- //!Creates shared memory and creates and places the segment manager.
+ //!Creates shared memory and creates and places the segment manager.
//!This can throw.
basic_managed_windows_shared_memory
(create_only_t create_only, const char *name,
size_type size, const void *addr = 0, const permissions &perm = permissions())
- : m_wshm(create_only, name, size, read_write, addr,
+ : m_wshm(create_only, name, size, read_write, addr,
create_open_func_t(get_this_pointer(), ipcdetail::DoCreate), perm)
{}
@@ -97,11 +97,11 @@ class basic_managed_windows_shared_memory
//!This can throw.
basic_managed_windows_shared_memory
(open_or_create_t open_or_create,
- const char *name, size_type size,
+ const char *name, size_type size,
const void *addr = 0,
const permissions &perm = permissions())
- : m_wshm(open_or_create, name, size, read_write, addr,
- create_open_func_t(get_this_pointer(),
+ : m_wshm(open_or_create, name, size, read_write, addr,
+ create_open_func_t(get_this_pointer(),
ipcdetail::DoOpenOrCreate), perm)
{}
@@ -109,8 +109,8 @@ class basic_managed_windows_shared_memory
//!This can throw.
basic_managed_windows_shared_memory
(open_only_t open_only, const char* name, const void *addr = 0)
- : m_wshm(open_only, name, read_write, addr,
- create_open_func_t(get_this_pointer(),
+ : m_wshm(open_only, name, read_write, addr,
+ create_open_func_t(get_this_pointer(),
ipcdetail::DoOpen))
{}
@@ -119,7 +119,7 @@ class basic_managed_windows_shared_memory
//!This can throw.
basic_managed_windows_shared_memory
(open_copy_on_write_t, const char* name, const void *addr = 0)
- : m_wshm(open_only, name, copy_on_write, addr,
+ : m_wshm(open_only, name, copy_on_write, addr,
create_open_func_t(get_this_pointer(), ipcdetail::DoOpen))
{}
@@ -129,7 +129,7 @@ class basic_managed_windows_shared_memory
basic_managed_windows_shared_memory
(open_read_only_t, const char* name, const void *addr = 0)
: base_t()
- , m_wshm(open_only, name, read_only, addr,
+ , m_wshm(open_only, name, read_only, addr,
create_open_func_t(get_this_pointer(), ipcdetail::DoOpen))
{}
diff --git a/boost/interprocess/managed_xsi_shared_memory.hpp b/boost/interprocess/managed_xsi_shared_memory.hpp
index 9601920254..dc909f6824 100644
--- a/boost/interprocess/managed_xsi_shared_memory.hpp
+++ b/boost/interprocess/managed_xsi_shared_memory.hpp
@@ -28,7 +28,7 @@
#include <boost/interprocess/creation_tags.hpp>
//These includes needed to fulfill default template parameters of
//predeclarations in interprocess_fwd.hpp
-#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
+#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
#include <boost/interprocess/sync/mutex_family.hpp>
#include <boost/interprocess/indexes/iset_index.hpp>
@@ -36,16 +36,16 @@ namespace boost {
namespace interprocess {
-//!A basic X/Open System Interface (XSI) shared memory named object creation class. Initializes the
-//!shared memory segment. Inherits all basic functionality from
+//!A basic X/Open System Interface (XSI) shared memory named object creation class. Initializes the
+//!shared memory segment. Inherits all basic functionality from
//!basic_managed_memory_impl<CharType, AllocationAlgorithm, IndexType>*/
template
<
- class CharType,
- class AllocationAlgorithm,
+ class CharType,
+ class AllocationAlgorithm,
template<class IndexConfig> class IndexType
>
-class basic_managed_xsi_shared_memory
+class basic_managed_xsi_shared_memory
: public ipcdetail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType
,ipcdetail::managed_open_or_create_impl
@@ -61,7 +61,7 @@ class basic_managed_xsi_shared_memory
public:
typedef ipcdetail::managed_open_or_create_impl
<xsi_shared_memory_file_wrapper, AllocationAlgorithm::Alignment, false, true> base2_t;
- typedef ipcdetail::basic_managed_memory_impl
+ typedef ipcdetail::basic_managed_memory_impl
<CharType, AllocationAlgorithm, IndexType,
base2_t::ManagedOpenOrCreateUserOffset> base_t;
@@ -92,12 +92,12 @@ class basic_managed_xsi_shared_memory
basic_managed_xsi_shared_memory()
{}
- //!Creates shared memory and creates and places the segment manager.
+ //!Creates shared memory and creates and places the segment manager.
//!This can throw.
basic_managed_xsi_shared_memory(create_only_t create_only, const xsi_key &key,
std::size_t size, const void *addr = 0, const permissions& perm = permissions())
: base_t()
- , base2_t(create_only, key, size, read_write, addr,
+ , base2_t(create_only, key, size, read_write, addr,
create_open_func_t(get_this_pointer(), ipcdetail::DoCreate), perm)
{}
@@ -106,32 +106,32 @@ class basic_managed_xsi_shared_memory
//!segment.
//!This can throw.
basic_managed_xsi_shared_memory (open_or_create_t open_or_create,
- const xsi_key &key, std::size_t size,
+ const xsi_key &key, std::size_t size,
const void *addr = 0, const permissions& perm = permissions())
: base_t()
- , base2_t(open_or_create, key, size, read_write, addr,
- create_open_func_t(get_this_pointer(),
+ , base2_t(open_or_create, key, size, read_write, addr,
+ create_open_func_t(get_this_pointer(),
ipcdetail::DoOpenOrCreate), perm)
{}
//!Connects to a created shared memory and its segment manager.
//!in read-only mode.
//!This can throw.
- basic_managed_xsi_shared_memory (open_read_only_t, const xsi_key &key,
+ basic_managed_xsi_shared_memory (open_read_only_t, const xsi_key &key,
const void *addr = 0)
: base_t()
- , base2_t(open_only, key, read_only, addr,
- create_open_func_t(get_this_pointer(),
+ , base2_t(open_only, key, read_only, addr,
+ create_open_func_t(get_this_pointer(),
ipcdetail::DoOpen))
{}
//!Connects to a created shared memory and its segment manager.
//!This can throw.
- basic_managed_xsi_shared_memory (open_only_t open_only, const xsi_key &key,
+ basic_managed_xsi_shared_memory (open_only_t open_only, const xsi_key &key,
const void *addr = 0)
: base_t()
- , base2_t(open_only, key, read_write, addr,
- create_open_func_t(get_this_pointer(),
+ , base2_t(open_only, key, read_write, addr,
+ create_open_func_t(get_this_pointer(),
ipcdetail::DoOpen))
{}
diff --git a/boost/interprocess/mapped_region.hpp b/boost/interprocess/mapped_region.hpp
index eae3f36220..522c1e403a 100644
--- a/boost/interprocess/mapped_region.hpp
+++ b/boost/interprocess/mapped_region.hpp
@@ -20,10 +20,11 @@
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/detail/os_file_functions.hpp>
#include <string>
-#include <limits>
+#include <boost/cstdint.hpp>
-#if (defined BOOST_INTERPROCESS_WINDOWS)
+#if defined (BOOST_INTERPROCESS_WINDOWS)
# include <boost/interprocess/detail/win32_api.hpp>
+# include <boost/interprocess/sync/windows/sync_utils.hpp>
#else
# ifdef BOOST_HAS_UNISTD_H
# include <fcntl.h>
@@ -55,6 +56,10 @@ namespace ipcdetail{ class raw_mapped_region_creator; }
//!The mapped_region class represents a portion or region created from a
//!memory_mappable object.
+//!
+//!The OS can map a region bigger than the requested one, as region must
+//!be multiple of the page size, but mapped_region will always refer to
+//!the region specified by the user.
class mapped_region
{
/// @cond
@@ -65,9 +70,15 @@ class mapped_region
public:
//!Creates a mapping region of the mapped memory "mapping", starting in
- //!offset "offset", and the mapping's size will be "size". The mapping
- //!can be opened for read-only "read_only" or read-write
- //!"read_write.
+ //!offset "offset", and the mapping's size will be "size". The mapping
+ //!can be opened for read only, read-write or copy-on-write.
+ //!
+ //!If an address is specified, both the offset and the address must be
+ //!multiples of the page size.
+ //!
+ //!The OS could allocate more pages than size/page_size(), but get_address()
+ //!will always return the address passed in this function (if not null) and
+ //!get_size() will return the specified size.
template<class MemoryMappable>
mapped_region(const MemoryMappable& mapping
,mode_t mode
@@ -75,8 +86,8 @@ class mapped_region
,std::size_t size = 0
,const void *address = 0);
- //!Default constructor. Default constructor. Address will be 0 (nullptr).
- //!Size and offset will be 0.
+ //!Default constructor. Address will be 0 (nullptr).
+ //!Size will be 0.
//!Does not throw
mapped_region();
@@ -84,12 +95,12 @@ class mapped_region
//!region and "other" will be left in default constructor state.
mapped_region(BOOST_RV_REF(mapped_region) other)
#if defined (BOOST_INTERPROCESS_WINDOWS)
- : m_base(0), m_size(0), m_offset(0)
- , m_extra_offset(0)
+ : m_base(0), m_size(0)
+ , m_page_offset(0)
, m_mode(read_only)
- , m_file_mapping_hnd(ipcdetail::invalid_file())
+ , m_file_or_mapping_hnd(ipcdetail::invalid_file())
#else
- : m_base(0), m_size(0), m_offset(0), m_extra_offset(0), m_mode(read_only), m_is_xsi(false)
+ : m_base(0), m_size(0), m_page_offset(0), m_mode(read_only), m_is_xsi(false)
#endif
{ this->swap(other); }
@@ -106,33 +117,31 @@ class mapped_region
return *this;
}
- //!Returns the size of the mapping. Note for windows users: If
- //!windows_shared_memory is mapped using 0 as the size, it returns 0
- //!because the size is unknown. Never throws.
+ //!Returns the size of the mapping. Never throws.
std::size_t get_size() const;
//!Returns the base address of the mapping.
//!Never throws.
void* get_address() const;
- //!Returns the offset of the mapping from the beginning of the
- //!mapped memory. Never throws.
- offset_t get_offset() const;
-
- //!Returns the mode of the mapping used to construct the mapped file.
+ //!Returns the mode of the mapping used to construct the mapped region.
//!Never throws.
mode_t get_mode() const;
- //!Flushes to the disk a byte range within the mapped memory.
- //!Never throws
- bool flush(std::size_t mapping_offset = 0, std::size_t numbytes = 0);
+ //!Flushes to the disk a byte range within the mapped memory.
+ //!If 'async' is true, the function will return before flushing operation is completed
+ //!If 'async' is false, function will return once data has been written into the underlying
+ //!device (i.e., in mapped files OS cached information is written to disk).
+ //!Never throws. Returns false if operation could not be performed.
+ bool flush(std::size_t mapping_offset = 0, std::size_t numbytes = 0, bool async = true);
//!Swaps the mapped_region with another
//!mapped region
void swap(mapped_region &other);
//!Returns the size of the page. This size is the minimum memory that
- //!will be used by the system when mapping a memory mappable source.
+ //!will be used by the system when mapping a memory mappable source and
+ //!will restrict the address and the offset to map.
static std::size_t get_page_size();
/// @cond
@@ -140,6 +149,13 @@ class mapped_region
//!Closes a previously opened memory mapping. Never throws
void priv_close();
+ void* priv_map_address() const;
+ std::size_t priv_map_size() const;
+ bool priv_flush_param_check(std::size_t mapping_offset, void *&addr, std::size_t &numbytes) const;
+ static void priv_size_from_mapping_size
+ (offset_t mapping_size, offset_t offset, offset_t page_offset, std::size_t &size);
+ static offset_t priv_page_offset_addr_fixup(offset_t page_offset, const void *&addr);
+
template<int dummy>
struct page_size_holder
{
@@ -149,11 +165,10 @@ class mapped_region
void* m_base;
std::size_t m_size;
- offset_t m_offset;
- offset_t m_extra_offset;
+ std::size_t m_page_offset;
mode_t m_mode;
- #if (defined BOOST_INTERPROCESS_WINDOWS)
- file_handle_t m_file_mapping_hnd;
+ #if defined(BOOST_INTERPROCESS_WINDOWS)
+ file_handle_t m_file_or_mapping_hnd;
#else
bool m_is_xsi;
#endif
@@ -161,6 +176,10 @@ class mapped_region
friend class ipcdetail::interprocess_tester;
friend class ipcdetail::raw_mapped_region_creator;
void dont_close_on_destruction();
+ #if defined(BOOST_INTERPROCESS_WINDOWS) && !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION)
+ template<int Dummy>
+ static void destroy_syncs_in_range(const void *addr, std::size_t size);
+ #endif
/// @endcond
};
@@ -175,20 +194,74 @@ inline mapped_region::~mapped_region()
inline std::size_t mapped_region::get_size() const
{ return m_size; }
-inline offset_t mapped_region::get_offset() const
-{ return m_offset; }
-
inline mode_t mapped_region::get_mode() const
{ return m_mode; }
inline void* mapped_region::get_address() const
{ return m_base; }
+inline void* mapped_region::priv_map_address() const
+{ return static_cast<char*>(m_base) - m_page_offset; }
+
+inline std::size_t mapped_region::priv_map_size() const
+{ return m_size + m_page_offset; }
+
+inline bool mapped_region::priv_flush_param_check
+ (std::size_t mapping_offset, void *&addr, std::size_t &numbytes) const
+{
+ //Check some errors
+ if(m_base == 0)
+ return false;
+
+ if(mapping_offset >= m_size || (mapping_offset + numbytes) > m_size){
+ return false;
+ }
+
+ //Update flush size if the user does not provide it
+ if(numbytes == 0){
+ numbytes = m_size - mapping_offset;
+ }
+ addr = (char*)this->priv_map_address() + mapping_offset;
+ numbytes += m_page_offset;
+ return true;
+}
+
+inline void mapped_region::priv_size_from_mapping_size
+ (offset_t mapping_size, offset_t offset, offset_t page_offset, std::size_t &size)
+{
+ //Check if mapping size fits in the user address space
+ //as offset_t is the maximum file size and its signed.
+ if(mapping_size < offset ||
+ boost::uintmax_t(mapping_size - (offset - page_offset)) >
+ boost::uintmax_t(std::size_t(-1))){
+ error_info err(size_error);
+ throw interprocess_exception(err);
+ }
+ size = static_cast<std::size_t>(mapping_size - (offset - page_offset));
+}
+
+inline offset_t mapped_region::priv_page_offset_addr_fixup(offset_t offset, const void *&address)
+{
+ //We can't map any offset so we have to obtain system's
+ //memory granularity
+ const std::size_t page_size = mapped_region::get_page_size();
+
+ //We calculate the difference between demanded and valid offset
+ //(always less than a page in std::size_t, thus, representable by std::size_t)
+ const std::size_t page_offset =
+ static_cast<std::size_t>(offset - (offset / page_size) * page_size);
+ //Update the mapping address
+ if(address){
+ address = static_cast<const char*>(address) - page_offset;
+ }
+ return page_offset;
+}
+
#if defined (BOOST_INTERPROCESS_WINDOWS)
inline mapped_region::mapped_region()
- : m_base(0), m_size(0), m_offset(0), m_extra_offset(0), m_mode(read_only)
- , m_file_mapping_hnd(ipcdetail::invalid_file())
+ : m_base(0), m_size(0), m_page_offset(0), m_mode(read_only)
+ , m_file_or_mapping_hnd(ipcdetail::invalid_file())
{}
template<int dummy>
@@ -206,169 +279,146 @@ inline mapped_region::mapped_region
,offset_t offset
,std::size_t size
,const void *address)
- : m_base(0), m_size(0), m_offset(0), m_extra_offset(0), m_mode(mode)
- , m_file_mapping_hnd(ipcdetail::invalid_file())
+ : m_base(0), m_size(0), m_page_offset(0), m_mode(mode)
+ , m_file_or_mapping_hnd(ipcdetail::invalid_file())
{
mapping_handle_t mhandle = mapping.get_mapping_handle();
- file_handle_t native_mapping_handle = 0;
-
- //Set accesses
- unsigned long file_map_access = 0;
- unsigned long map_access = 0;
-
- switch(mode)
{
- case read_only:
- case read_private:
- file_map_access |= winapi::page_readonly;
- map_access |= winapi::file_map_read;
- break;
- case read_write:
- file_map_access |= winapi::page_readwrite;
- map_access |= winapi::file_map_write;
- break;
- case copy_on_write:
- file_map_access |= winapi::page_writecopy;
- map_access |= winapi::file_map_copy;
- break;
- default:
- {
- error_info err(mode_error);
- throw interprocess_exception(err);
- }
- break;
- }
-
- if(!mhandle.is_shm){
- //Update mapping size if the user does not specify it
- if(size == 0){
- __int64 total_size;
- if(!winapi::get_file_size
- (ipcdetail::file_handle_from_mapping_handle
- (mapping.get_mapping_handle()), total_size)){
- error_info err(winapi::get_last_error());
- throw interprocess_exception(err);
- }
+ file_handle_t native_mapping_handle = 0;
+
+ //Set accesses
+ //For "create_file_mapping"
+ unsigned long protection = 0;
+ //For "mapviewoffile"
+ unsigned long map_access = 0;
+
+ switch(mode)
+ {
+ case read_only:
+ case read_private:
+ protection |= winapi::page_readonly;
+ map_access |= winapi::file_map_read;
+ break;
+ case read_write:
+ protection |= winapi::page_readwrite;
+ map_access |= winapi::file_map_write;
+ break;
+ case copy_on_write:
+ protection |= winapi::page_writecopy;
+ map_access |= winapi::file_map_copy;
+ break;
+ default:
+ {
+ error_info err(mode_error);
+ throw interprocess_exception(err);
+ }
+ break;
+ }
- if(static_cast<unsigned __int64>(total_size) >
- (std::numeric_limits<std::size_t>::max)()){
- error_info err(size_error);
+ //For file mapping (including emulated shared memory through temporary files),
+ //the device is a file handle so we need to obtain file's size and call create_file_mapping
+ //to obtain the mapping handle.
+ //For files we don't need the file mapping after mapping the memory, as the file is there
+ //so we'll program the handle close
+ void * handle_to_close = winapi::invalid_handle_value;
+ if(!mhandle.is_shm){
+ //Create mapping handle
+ native_mapping_handle = winapi::create_file_mapping
+ ( ipcdetail::file_handle_from_mapping_handle(mapping.get_mapping_handle())
+ , protection, 0, 0, 0);
+
+ //Check if all is correct
+ if(!native_mapping_handle){
+ error_info err = winapi::get_last_error();
throw interprocess_exception(err);
}
- size = static_cast<std::size_t>(total_size - offset);
+ handle_to_close = native_mapping_handle;
}
-
- //Create file mapping
- native_mapping_handle =
- winapi::create_file_mapping
- (ipcdetail::file_handle_from_mapping_handle(mapping.get_mapping_handle()), file_map_access, 0, 0, 0, 0);
-
- //Check if all is correct
- if(!native_mapping_handle){
- error_info err = winapi::get_last_error();
- this->priv_close();
- throw interprocess_exception(err);
+ else{
+ //For windows_shared_memory the device handle is already a mapping handle
+ //and we need to maintain it
+ native_mapping_handle = mhandle.handle;
}
- }
+ //RAII handle close on scope exit
+ const winapi::handle_closer close_handle(handle_to_close);
+ (void)close_handle;
- //We can't map any offset so we have to obtain system's
- //memory granularity
- unsigned long granularity = 0;
- unsigned long foffset_low;
- unsigned long foffset_high;
+ const offset_t page_offset = priv_page_offset_addr_fixup(offset, address);
- winapi::system_info info;
- get_system_info(&info);
- granularity = info.dwAllocationGranularity;
-
- //Now we calculate valid offsets
- foffset_low = (unsigned long)(offset / granularity) * granularity;
- foffset_high = (unsigned long)(((offset / granularity) * granularity) >> 32);
-
- //We calculate the difference between demanded and valid offset
- m_extra_offset = (offset - (offset / granularity) * granularity);
-
- //Store user values in memory
- m_offset = offset;
- m_size = size;
+ //Obtain mapping size if user provides 0 size
+ if(size == 0){
+ offset_t mapping_size;
+ if(!winapi::get_file_mapping_size(native_mapping_handle, mapping_size)){
+ error_info err = winapi::get_last_error();
+ throw interprocess_exception(err);
+ }
+ //This can throw
+ priv_size_from_mapping_size(mapping_size, offset, page_offset, size);
+ }
- //Update the mapping address
- if(address){
- address = static_cast<const char*>(address) - m_extra_offset;
- }
- if(mhandle.is_shm){
- //Windows shared memory needs the duplication of the handle if we want to
- //make mapped_region independent from the mappable device
- if(!winapi::duplicate_current_process_handle(mhandle.handle, &m_file_mapping_hnd)){
+ //Map with new offsets and size
+ void *base = winapi::map_view_of_file_ex
+ (native_mapping_handle,
+ map_access,
+ offset - page_offset,
+ static_cast<std::size_t>(page_offset + size),
+ const_cast<void*>(address));
+ //Check error
+ if(!base){
error_info err = winapi::get_last_error();
- this->priv_close();
throw interprocess_exception(err);
}
- native_mapping_handle = m_file_mapping_hnd;
- }
- //Map with new offsets and size
- m_base = winapi::map_view_of_file_ex
- (native_mapping_handle,
- map_access,
- foffset_high,
- foffset_low,
- m_size ? static_cast<std::size_t>(m_extra_offset + m_size) : 0,
- const_cast<void*>(address));
-
- if(!mhandle.is_shm){
- //For files we don't need the file mapping anymore
- winapi::close_handle(native_mapping_handle);
+ //Calculate new base for the user
+ m_base = static_cast<char*>(base) + page_offset;
+ m_page_offset = page_offset;
+ m_size = size;
}
-
- //Check error
- if(!m_base){
+ //Windows shared memory needs the duplication of the handle if we want to
+ //make mapped_region independent from the mappable device
+ //
+ //For mapped files, we duplicate the file handle to be able to FlushFileBuffers
+ if(!winapi::duplicate_current_process_handle(mhandle.handle, &m_file_or_mapping_hnd)){
error_info err = winapi::get_last_error();
this->priv_close();
throw interprocess_exception(err);
}
-
- //Calculate new base for the user
- m_base = static_cast<char*>(m_base) + m_extra_offset;
}
-inline bool mapped_region::flush(std::size_t mapping_offset, std::size_t numbytes)
+inline bool mapped_region::flush(std::size_t mapping_offset, std::size_t numbytes, bool async)
{
- //Check some errors
- if(m_base == 0)
+ void *addr;
+ if(!this->priv_flush_param_check(mapping_offset, addr, numbytes)){
return false;
-
- if(mapping_offset >= m_size || (mapping_offset + numbytes) > m_size){
+ }
+ //Flush it all
+ if(!winapi::flush_view_of_file(addr, numbytes)){
return false;
}
-
- //Update flush size if the user does not provide it
- if(m_size == 0){
- numbytes = 0;
+ //m_file_or_mapping_hnd can be a file handle or a mapping handle.
+ //so flushing file buffers has only sense for files...
+ else if(async && m_file_or_mapping_hnd != winapi::invalid_handle_value &&
+ winapi::get_file_type(m_file_or_mapping_hnd) == winapi::file_type_disk){
+ return winapi::flush_file_buffers(m_file_or_mapping_hnd);
}
- else if(numbytes == 0){
- numbytes = m_size - mapping_offset;
- }
-
- //Flush it all
- return winapi::flush_view_of_file
- (static_cast<char*>(m_base)+mapping_offset,
- static_cast<std::size_t>(numbytes));
+ return true;
}
inline void mapped_region::priv_close()
{
if(m_base){
- winapi::unmap_view_of_file(static_cast<char*>(m_base) - m_extra_offset);
+ void *addr = this->priv_map_address();
+ #if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION)
+ mapped_region::destroy_syncs_in_range<0>(addr, m_size);
+ #endif
+ winapi::unmap_view_of_file(addr);
m_base = 0;
}
- #if (defined BOOST_INTERPROCESS_WINDOWS)
- if(m_file_mapping_hnd != ipcdetail::invalid_file()){
- winapi::close_handle(m_file_mapping_hnd);
- m_file_mapping_hnd = ipcdetail::invalid_file();
- }
- #endif
+ if(m_file_or_mapping_hnd != ipcdetail::invalid_file()){
+ winapi::close_handle(m_file_or_mapping_hnd);
+ m_file_or_mapping_hnd = ipcdetail::invalid_file();
+ }
}
inline void mapped_region::dont_close_on_destruction()
@@ -377,7 +427,7 @@ inline void mapped_region::dont_close_on_destruction()
#else //#if (defined BOOST_INTERPROCESS_WINDOWS)
inline mapped_region::mapped_region()
- : m_base(0), m_size(0), m_offset(0), m_extra_offset(0), m_mode(read_only), m_is_xsi(false)
+ : m_base(0), m_size(0), m_page_offset(0), m_mode(read_only), m_is_xsi(false)
{}
template<int dummy>
@@ -391,7 +441,7 @@ inline mapped_region::mapped_region
, offset_t offset
, std::size_t size
, const void *address)
- : m_base(0), m_size(0), m_offset(0), m_extra_offset(0), m_mode(mode), m_is_xsi(false)
+ : m_base(0), m_size(0), m_page_offset(0), m_mode(mode), m_is_xsi(false)
{
mapping_handle_t map_hnd = mapping.get_mapping_handle();
@@ -430,28 +480,25 @@ inline mapped_region::mapped_region
}
//Update members
m_base = base;
- m_offset = offset;
m_size = size;
m_mode = mode;
- m_extra_offset = 0;
+ m_page_offset = 0;
m_is_xsi = true;
return;
}
#endif //ifdef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
+
+ //We calculate the difference between demanded and valid offset
+ const offset_t page_offset = priv_page_offset_addr_fixup(offset, address);
+
if(size == 0){
struct ::stat buf;
if(0 != fstat(map_hnd.handle, &buf)){
error_info err(system_error_code());
throw interprocess_exception(err);
}
- std::size_t filesize = (std::size_t)buf.st_size;
- if((std::size_t)offset >= filesize){
- error_info err(size_error);
- throw interprocess_exception(err);
- }
-
- filesize -= offset;
- size = filesize;
+ //This can throw
+ priv_size_from_mapping_size(buf.st_size, offset, page_offset, size);
}
//Create new mapping
@@ -488,35 +535,23 @@ inline mapped_region::mapped_region
break;
}
- //We calculate the difference between demanded and valid offset
- const std::size_t page_size = this->get_page_size();
- const offset_t extra_offset = offset - (offset / page_size) * page_size;
-
-
- //Update the mapping address
- if(address){
- address = static_cast<const char*>(address) - extra_offset;
- }
-
//Map it to the address space
void* base = mmap ( const_cast<void*>(address)
- , static_cast<std::size_t>(extra_offset + size)
+ , static_cast<std::size_t>(page_offset + size)
, prot
, flags
, mapping.get_mapping_handle().handle
- , offset - extra_offset);
+ , offset - page_offset);
//Check if mapping was successful
if(base == MAP_FAILED){
error_info err = system_error_code();
- this->priv_close();
throw interprocess_exception(err);
}
//Calculate new base for the user
- m_base = static_cast<char*>(base) + extra_offset;
- m_extra_offset = extra_offset;
- m_offset = offset;
+ m_base = static_cast<char*>(base) + page_offset;
+ m_page_offset = page_offset;
m_size = size;
//Check for fixed mapping error
@@ -527,17 +562,14 @@ inline mapped_region::mapped_region
}
}
-inline bool mapped_region::flush(std::size_t mapping_offset, std::size_t numbytes)
+inline bool mapped_region::flush(std::size_t mapping_offset, std::size_t numbytes, bool async)
{
- if(mapping_offset >= m_size || (mapping_offset+numbytes)> m_size){
+ void *addr;
+ if(!this->priv_flush_param_check(mapping_offset, addr, numbytes)){
return false;
}
-
- if(numbytes == 0){
- numbytes = m_size - mapping_offset;
- }
//Flush it all
- return msync(static_cast<char*>(m_base)+mapping_offset, numbytes, MS_ASYNC) == 0;
+ return msync( addr, numbytes, async ? MS_ASYNC : MS_SYNC) == 0;
}
inline void mapped_region::priv_close()
@@ -551,7 +583,7 @@ inline void mapped_region::priv_close()
return;
}
#endif //#ifdef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
- munmap(static_cast<char*>(m_base) - m_extra_offset, m_size + m_extra_offset);
+ munmap(this->priv_map_address(), this->priv_map_size());
m_base = 0;
}
}
@@ -577,11 +609,10 @@ inline void mapped_region::swap(mapped_region &other)
{
ipcdetail::do_swap(this->m_base, other.m_base);
ipcdetail::do_swap(this->m_size, other.m_size);
- ipcdetail::do_swap(this->m_offset, other.m_offset);
- ipcdetail::do_swap(this->m_extra_offset, other.m_extra_offset);
+ ipcdetail::do_swap(this->m_page_offset, other.m_page_offset);
ipcdetail::do_swap(this->m_mode, other.m_mode);
#if (defined BOOST_INTERPROCESS_WINDOWS)
- ipcdetail::do_swap(this->m_file_mapping_hnd, other.m_file_mapping_hnd);
+ ipcdetail::do_swap(this->m_file_or_mapping_hnd, other.m_file_or_mapping_hnd);
#else
ipcdetail::do_swap(this->m_is_xsi, other.m_is_xsi);
#endif
@@ -603,3 +634,32 @@ struct null_mapped_region_function
#endif //BOOST_INTERPROCESS_MAPPED_REGION_HPP
+#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
+#ifndef BOOST_INTERPROCESS_MAPPED_REGION_EXT_HPP
+#define BOOST_INTERPROCESS_MAPPED_REGION_EXT_HPP
+
+#if defined(BOOST_INTERPROCESS_WINDOWS) && !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION)
+# include <boost/interprocess/sync/windows/sync_utils.hpp>
+# include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
+
+namespace boost {
+namespace interprocess {
+
+template<int Dummy>
+inline void mapped_region::destroy_syncs_in_range(const void *addr, std::size_t size)
+{
+ ipcdetail::sync_handles &handles =
+ ipcdetail::windows_intermodule_singleton<ipcdetail::sync_handles>::get();
+ handles.destroy_syncs_in_range(addr, size);
+}
+
+} //namespace interprocess {
+} //namespace boost {
+
+#endif //defined(BOOST_INTERPROCESS_WINDOWS) && !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION)
+
+#endif //#ifdef BOOST_INTERPROCESS_MAPPED_REGION_EXT_HPP
+
+#endif //#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+
diff --git a/boost/interprocess/mem_algo/detail/mem_algo_common.hpp b/boost/interprocess/mem_algo/detail/mem_algo_common.hpp
index d609f46aee..91d798145b 100644
--- a/boost/interprocess/mem_algo/detail/mem_algo_common.hpp
+++ b/boost/interprocess/mem_algo/detail/mem_algo_common.hpp
@@ -117,7 +117,7 @@ class memory_algorithm_common
lcm_val = max;
//If we want to use minbytes data to get a buffer between maxbytes
- //and minbytes if maxbytes can't be achieved, calculate the
+ //and minbytes if maxbytes can't be achieved, calculate the
//biggest of all possibilities
current_forward = get_truncated_size_po2(received_size, backwards_multiple);
needs_backwards = size_to_achieve - current_forward;
@@ -176,7 +176,7 @@ class memory_algorithm_common
lcm_val = lcm(max, min);
}
//If we want to use minbytes data to get a buffer between maxbytes
- //and minbytes if maxbytes can't be achieved, calculate the
+ //and minbytes if maxbytes can't be achieved, calculate the
//biggest of all possibilities
current_forward = get_truncated_size(received_size, backwards_multiple);
needs_backwards = size_to_achieve - current_forward;
@@ -199,7 +199,7 @@ class memory_algorithm_common
static void* allocate_aligned
(MemoryAlgorithm *memory_algo, size_type nbytes, size_type alignment)
{
-
+
//Ensure power of 2
if ((alignment & (alignment - size_type(1u))) != 0){
//Alignment is not power of two
@@ -215,7 +215,7 @@ class memory_algorithm_common
if(nbytes > UsableByPreviousChunk)
nbytes -= UsableByPreviousChunk;
-
+
//We can find a aligned portion if we allocate a block that has alignment
//nbytes + alignment bytes or more.
size_type minimum_allocation = max_value
@@ -223,13 +223,13 @@ class memory_algorithm_common
//Since we will split that block, we must request a bit more memory
//if the alignment is near the beginning of the buffer, because otherwise,
//there is no space for a new block before the alignment.
- //
+ //
// ____ Aligned here
// |
// -----------------------------------------------------
- // | MBU |
+ // | MBU |
// -----------------------------------------------------
- size_type request =
+ size_type request =
minimum_allocation + (2*MinBlockUnits*Alignment - AllocatedCtrlBytes
//prevsize - UsableByPreviousChunk
);
@@ -263,7 +263,7 @@ class memory_algorithm_common
}
//Buffer not aligned, find the aligned part.
- //
+ //
// ____ Aligned here
// |
// -----------------------------------------------------
@@ -324,7 +324,7 @@ class memory_algorithm_common
return memory_algo->priv_get_user_buffer(second);
}
- static bool try_shrink
+ static bool try_shrink
(MemoryAlgorithm *memory_algo, void *ptr
,const size_type max_size, const size_type preferred_size
,size_type &received_size)
@@ -361,8 +361,8 @@ class memory_algorithm_common
if(old_user_units == preferred_user_units)
return true;
- size_type shrunk_user_units =
- ((BlockCtrlUnits - AllocatedCtrlUnits) > preferred_user_units)
+ size_type shrunk_user_units =
+ ((BlockCtrlUnits - AllocatedCtrlUnits) >= preferred_user_units)
? (BlockCtrlUnits - AllocatedCtrlUnits)
: preferred_user_units;
@@ -380,7 +380,7 @@ class memory_algorithm_common
return true;
}
- static bool shrink
+ static bool shrink
(MemoryAlgorithm *memory_algo, void *ptr
,const size_type max_size, const size_type preferred_size
,size_type &received_size)
@@ -389,7 +389,7 @@ class memory_algorithm_common
block_ctrl *block = memory_algo->priv_get_block(ptr);
size_type old_block_units = (size_type)block->m_size;
- if(!try_shrink
+ if(!try_shrink
(memory_algo, ptr, max_size, preferred_size, received_size)){
return false;
}
@@ -479,7 +479,7 @@ class memory_algorithm_common
//The last block should take all the remaining space
if((low_idx + 1) == n_elements ||
- (total_used_units + elem_units +
+ (total_used_units + elem_units +
((!sizeof_element)
? elem_units
: std::max(memory_algo->priv_get_total_units(elem_sizes[low_idx+1]*sizeof_element), ptr_size_units))
@@ -528,7 +528,7 @@ class memory_algorithm_common
//Sanity check
BOOST_ASSERT(total_used_units == received_units);
}
-
+
if(low_idx != n_elements){
priv_deallocate_many(memory_algo, boost::move(chain));
}
diff --git a/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp b/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp
index 378cd82fd5..c36916b72f 100644
--- a/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp
+++ b/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp
@@ -60,7 +60,7 @@ class simple_seq_fit_impl
simple_seq_fit_impl();
simple_seq_fit_impl(const simple_seq_fit_impl &);
simple_seq_fit_impl &operator=(const simple_seq_fit_impl &);
-
+
typedef typename boost::intrusive::
pointer_traits<VoidPointer>::template
rebind_pointer<char>::type char_ptr;
@@ -93,10 +93,10 @@ class simple_seq_fit_impl
public:
//!Offset pointer to the next block.
block_ctrl_ptr m_next;
- //!This block's memory size (including block_ctrl
+ //!This block's memory size (including block_ctrl
//!header) in BasicSize units
size_type m_size;
-
+
size_type get_user_bytes() const
{ return this->m_size*Alignment - BlockCtrlBytes; }
@@ -126,7 +126,7 @@ class simple_seq_fit_impl
typedef ipcdetail::memory_algorithm_common<simple_seq_fit_impl> algo_impl_t;
public:
- //!Constructor. "size" is the total size of the managed memory segment,
+ //!Constructor. "size" is the total size of the managed memory segment,
//!"extra_hdr_bytes" indicates the extra bytes beginning in the sizeof(simple_seq_fit_impl)
//!offset that the allocator should not use at all.
simple_seq_fit_impl (size_type size, size_type extra_hdr_bytes);
@@ -197,12 +197,12 @@ class simple_seq_fit_impl
template<class T>
std::pair<T *, bool>
allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
- size_type preferred_size,size_type &received_size,
+ size_type preferred_size,size_type &received_size,
T *reuse_ptr = 0);
std::pair<void *, bool>
raw_allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
- size_type preferred_size,size_type &received_size,
+ size_type preferred_size,size_type &received_size,
void *reuse_ptr = 0, size_type sizeof_object = 1);
//!Returns the size of the buffer previously allocated pointed by ptr
@@ -306,7 +306,7 @@ simple_seq_fit_impl<MutexFamily, VoidPointer>
size_type uint_this = (std::size_t)this_ptr;
size_type uint_aligned_this = uint_this/Alignment*Alignment;
size_type this_disalignment = (uint_this - uint_aligned_this);
- size_type block1_off =
+ size_type block1_off =
ipcdetail::get_rounded_size(sizeof(simple_seq_fit_impl) + extra_hdr_bytes + this_disalignment, Alignment)
- this_disalignment;
algo_impl_t::assert_alignment(this_disalignment + block1_off);
@@ -322,7 +322,7 @@ simple_seq_fit_impl<MutexFamily, VoidPointer>
size_type uint_this = (std::size_t)this;
size_type uint_aligned_this = uint_this/Alignment*Alignment;
size_type this_disalignment = (uint_this - uint_aligned_this);
- size_type old_end =
+ size_type old_end =
ipcdetail::get_truncated_size(m_header.m_size + this_disalignment, Alignment)
- this_disalignment;
algo_impl_t::assert_alignment(old_end + this_disalignment);
@@ -426,7 +426,7 @@ void simple_seq_fit_impl<MutexFamily, VoidPointer>::shrink_to_fit()
(void)addr;
BOOST_ASSERT(addr);
BOOST_ASSERT(received_size == last_units*Alignment - AllocatedCtrlBytes);
-
+
//Shrink it
m_header.m_size /= Alignment;
m_header.m_size -= last->m_size;
@@ -463,7 +463,7 @@ void *simple_seq_fit_impl<MutexFamily, VoidPointer>::
template<class MutexFamily, class VoidPointer>
inline void simple_seq_fit_impl<MutexFamily, VoidPointer>::priv_add_segment(void *addr, size_type size)
-{
+{
algo_impl_t::assert_alignment(addr);
//Check size
BOOST_ASSERT(!(size < MinBlockSize));
@@ -474,7 +474,7 @@ inline void simple_seq_fit_impl<MutexFamily, VoidPointer>::priv_add_segment(void
new_block->m_size = size/Alignment;
new_block->m_next = 0;
//Simulate this block was previously allocated
- m_header.m_allocated += new_block->m_size*Alignment;
+ m_header.m_allocated += new_block->m_size*Alignment;
//Return block and insert it in the free block list
this->priv_deallocate(priv_get_user_buffer(new_block));
}
@@ -488,7 +488,7 @@ template<class MutexFamily, class VoidPointer>
inline typename simple_seq_fit_impl<MutexFamily, VoidPointer>::size_type
simple_seq_fit_impl<MutexFamily, VoidPointer>::get_free_memory() const
{
- return m_header.m_size - m_header.m_allocated -
+ return m_header.m_size - m_header.m_allocated -
algo_impl_t::multiple_of_units(sizeof(*this) + m_header.m_extra_hdr_bytes);
}
@@ -523,7 +523,7 @@ inline void simple_seq_fit_impl<MutexFamily, VoidPointer>::zero_free_memory()
//Iterate through all free portions
do{
- //Just clear user the memory part reserved for the user
+ //Just clear user the memory part reserved for the user
std::memset( priv_get_user_buffer(block)
, 0
, block->get_user_bytes());
@@ -583,19 +583,19 @@ inline void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
template<class MutexFamily, class VoidPointer>
inline void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
allocate_aligned(size_type nbytes, size_type alignment)
-{
+{
//-----------------------
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
return algo_impl_t::
- allocate_aligned(this, nbytes, alignment);
+ allocate_aligned(this, nbytes, alignment);
}
template<class MutexFamily, class VoidPointer>
template<class T>
inline std::pair<T*, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
- size_type preferred_size,size_type &received_size,
+ size_type preferred_size,size_type &received_size,
T *reuse_ptr)
{
std::pair<void*, bool> ret = priv_allocation_command
@@ -608,7 +608,7 @@ inline std::pair<T*, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
template<class MutexFamily, class VoidPointer>
inline std::pair<void*, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
raw_allocation_command (boost::interprocess::allocation_type command, size_type limit_objects,
- size_type preferred_objects,size_type &received_objects,
+ size_type preferred_objects,size_type &received_objects,
void *reuse_ptr, size_type sizeof_object)
{
if(!sizeof_object)
@@ -627,7 +627,7 @@ inline std::pair<void*, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
template<class MutexFamily, class VoidPointer>
inline std::pair<void*, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
priv_allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
- size_type preferred_size, size_type &received_size,
+ size_type preferred_size, size_type &received_size,
void *reuse_ptr, size_type sizeof_object)
{
command &= ~boost::interprocess::expand_bwd;
@@ -696,9 +696,9 @@ void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
return 0;
}
- size_type needs_backwards =
+ size_type needs_backwards =
ipcdetail::get_rounded_size(preferred_size - extra_forward, Alignment);
-
+
if(!only_preferred_backwards){
max_value(ipcdetail::get_rounded_size(min_size - extra_forward, Alignment)
,min_value(prev->get_user_bytes(), needs_backwards));
@@ -710,16 +710,16 @@ void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
if(!priv_expand(reuse_ptr, received_size, received_size, received_size)){
BOOST_ASSERT(0);
}
-
+
//We need a minimum size to split the previous one
if((prev->get_user_bytes() - needs_backwards) > 2*BlockCtrlBytes){
block_ctrl *new_block = reinterpret_cast<block_ctrl*>
(reinterpret_cast<char*>(reuse) - needs_backwards - BlockCtrlBytes);
new_block->m_next = 0;
- new_block->m_size =
+ new_block->m_size =
BlockCtrlUnits + (needs_backwards + extra_forward)/Alignment;
- prev->m_size =
+ prev->m_size =
(prev->get_total_bytes() - needs_backwards)/Alignment - BlockCtrlUnits;
received_size = needs_backwards + extra_forward;
m_header.m_allocated += needs_backwards + BlockCtrlBytes;
@@ -775,7 +775,7 @@ std::pair<void *, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
,void *reuse_ptr)
{
if(command & boost::interprocess::shrink_in_place){
- bool success =
+ bool success =
algo_impl_t::shrink(this, reuse_ptr, limit_size, preferred_size, received_size);
return std::pair<void *, bool> ((success ? reuse_ptr : 0), true);
}
@@ -885,7 +885,7 @@ inline typename simple_seq_fit_impl<MutexFamily, VoidPointer>::block_ctrl *
}
template<class MutexFamily, class VoidPointer>
-inline
+inline
std::pair<typename simple_seq_fit_impl<MutexFamily, VoidPointer>::block_ctrl *
,typename simple_seq_fit_impl<MutexFamily, VoidPointer>::block_ctrl *>
simple_seq_fit_impl<MutexFamily, VoidPointer>::
@@ -969,7 +969,7 @@ inline bool simple_seq_fit_impl<MutexFamily, VoidPointer>::
//We can fill expand. Merge both blocks,
block->m_next = next_block->m_next;
block->m_size = merged_size;
-
+
//Find the previous free block of next_block
block_ctrl *prev = &m_header.m_root;
while(ipcdetail::to_raw_pointer(prev->m_next) != next_block){
@@ -978,7 +978,7 @@ inline bool simple_seq_fit_impl<MutexFamily, VoidPointer>::
//Now insert merged block in the free list
//This allows reusing allocation logic in this function
- m_header.m_allocated -= old_block_size*Alignment;
+ m_header.m_allocated -= old_block_size*Alignment;
prev->m_next = block;
//Now use check and allocate to do the allocation logic
@@ -992,7 +992,7 @@ inline bool simple_seq_fit_impl<MutexFamily, VoidPointer>::
BOOST_ASSERT(0);
return false;
}
- return true;
+ return true;
}
template<class MutexFamily, class VoidPointer> inline
@@ -1006,7 +1006,7 @@ void* simple_seq_fit_impl<MutexFamily, VoidPointer>::priv_check_and_allocate
bool found = false;
if (block->m_size > upper_nunits){
- //This block is bigger than needed, split it in
+ //This block is bigger than needed, split it in
//two blocks, the first's size will be "units"
//the second's size will be "block->m_size-units"
size_type total_size = block->m_size;
@@ -1057,7 +1057,7 @@ void simple_seq_fit_impl<MutexFamily, VoidPointer>::priv_deallocate(void* addr)
//Let's get free block list. List is always sorted
//by memory address to allow block merging.
- //Pointer next always points to the first
+ //Pointer next always points to the first
//(lower address) block
block_ctrl * prev = &m_header.m_root;
block_ctrl * pos = ipcdetail::to_raw_pointer(m_header.m_root.m_next);
@@ -1071,9 +1071,9 @@ void simple_seq_fit_impl<MutexFamily, VoidPointer>::priv_deallocate(void* addr)
size_type total_size = Alignment*block->m_size;
BOOST_ASSERT(m_header.m_allocated >= total_size);
-
+
//Update used memory count
- m_header.m_allocated -= total_size;
+ m_header.m_allocated -= total_size;
//Let's find the previous and the next block of the block to deallocate
//This ordering comparison must be done with original pointers
@@ -1087,7 +1087,7 @@ void simple_seq_fit_impl<MutexFamily, VoidPointer>::priv_deallocate(void* addr)
//Try to combine with upper block
char *block_char_ptr = reinterpret_cast<char*>(ipcdetail::to_raw_pointer(block));
- if ((block_char_ptr + Alignment*block->m_size) ==
+ if ((block_char_ptr + Alignment*block->m_size) ==
reinterpret_cast<char*>(ipcdetail::to_raw_pointer(pos))){
block->m_size += pos->m_size;
block->m_next = pos->m_next;
@@ -1098,7 +1098,7 @@ void simple_seq_fit_impl<MutexFamily, VoidPointer>::priv_deallocate(void* addr)
//Try to combine with lower block
if ((reinterpret_cast<char*>(ipcdetail::to_raw_pointer(prev))
- + Alignment*prev->m_size) ==
+ + Alignment*prev->m_size) ==
block_char_ptr){
diff --git a/boost/interprocess/mem_algo/rbtree_best_fit.hpp b/boost/interprocess/mem_algo/rbtree_best_fit.hpp
index f6f0c03a17..7ccc642e29 100644
--- a/boost/interprocess/mem_algo/rbtree_best_fit.hpp
+++ b/boost/interprocess/mem_algo/rbtree_best_fit.hpp
@@ -105,7 +105,7 @@ class rbtree_best_fit
struct SizeHolder
{
- //!This block's memory size (including block_ctrl
+ //!This block's memory size (including block_ctrl
//!header) in Alignment units
size_type m_prev_size : sizeof(size_type)*CHAR_BIT;
size_type m_size : sizeof(size_type)*CHAR_BIT - 2;
@@ -132,7 +132,7 @@ class rbtree_best_fit
{ return size < block.m_size; }
bool operator()(const block_ctrl &block, size_type size) const
- { return block.m_size < size; }
+ { return block.m_size < size; }
};
//!Shared mutex to protect memory allocate/deallocate
@@ -157,13 +157,13 @@ class rbtree_best_fit
} m_header;
friend class ipcdetail::memory_algorithm_common<rbtree_best_fit>;
-
+
typedef ipcdetail::memory_algorithm_common<rbtree_best_fit> algo_impl_t;
public:
/// @endcond
- //!Constructor. "size" is the total size of the managed memory segment,
+ //!Constructor. "size" is the total size of the managed memory segment,
//!"extra_hdr_bytes" indicates the extra bytes beginning in the sizeof(rbtree_best_fit)
//!offset that the allocator should not use at all.
rbtree_best_fit (size_type size, size_type extra_hdr_bytes);
@@ -238,12 +238,12 @@ class rbtree_best_fit
template<class T>
std::pair<T *, bool>
allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
- size_type preferred_size,size_type &received_size,
+ size_type preferred_size,size_type &received_size,
T *reuse_ptr = 0);
std::pair<void *, bool>
raw_allocation_command (boost::interprocess::allocation_type command, size_type limit_object,
- size_type preferred_object,size_type &received_object,
+ size_type preferred_object,size_type &received_object,
void *reuse_ptr = 0, size_type sizeof_object = 1);
//!Returns the size of the buffer previously allocated pointed by ptr
@@ -263,7 +263,7 @@ class rbtree_best_fit
std::pair<void*, bool>
priv_allocation_command(boost::interprocess::allocation_type command, size_type limit_size,
- size_type preferred_size,size_type &received_size,
+ size_type preferred_size,size_type &received_size,
void *reuse_ptr, size_type sizeof_object);
@@ -339,7 +339,7 @@ class rbtree_best_fit
void priv_add_segment(void *addr, size_type size);
public:
-
+
static const size_type Alignment = !MemAlignment
? size_type(::boost::alignment_of< ::boost::detail::max_align>::value)
: size_type(MemAlignment)
@@ -370,7 +370,7 @@ class rbtree_best_fit
/// @cond
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
-inline typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::size_type
+inline typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::size_type
rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>
::priv_first_block_offset_from_this(const void *this_ptr, size_type extra_hdr_bytes)
{
@@ -386,7 +386,7 @@ inline typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::size_ty
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
priv_add_segment(void *addr, size_type size)
-{
+{
//Check alignment
algo_impl_t::check_alignment(addr);
//Check size
@@ -398,16 +398,16 @@ void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
BOOST_ASSERT(first_big_block->m_size >= BlockCtrlUnits);
//The "end" node is just a node of size 0 with the "end" bit set
- block_ctrl *end_block = static_cast<block_ctrl*>
+ block_ctrl *end_block = static_cast<block_ctrl*>
(new (reinterpret_cast<char*>(addr) + first_big_block->m_size*Alignment)SizeHolder);
//This will overwrite the prev part of the "end" node
priv_mark_as_free_block (first_big_block);
#ifdef BOOST_INTERPROCESS_RBTREE_BEST_FIT_ABI_V1_HPP
- first_big_block->m_prev_size = end_block->m_size =
+ first_big_block->m_prev_size = end_block->m_size =
(reinterpret_cast<char*>(first_big_block) - reinterpret_cast<char*>(end_block))/Alignment;
#else
- first_big_block->m_prev_size = end_block->m_size =
+ first_big_block->m_prev_size = end_block->m_size =
(reinterpret_cast<char*>(end_block) - reinterpret_cast<char*>(first_big_block))/Alignment;
#endif
end_block->m_allocated = 1;
@@ -444,7 +444,7 @@ inline typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::block_c
{
size_type block1_off = priv_first_block_offset_from_this(this, m_header.m_extra_hdr_bytes);
const size_type original_first_block_size = m_header.m_size/Alignment*Alignment - block1_off/Alignment*Alignment - EndCtrlBlockBytes;
- block_ctrl *end_block = reinterpret_cast<block_ctrl*>
+ block_ctrl *end_block = reinterpret_cast<block_ctrl*>
(reinterpret_cast<char*>(this) + block1_off + original_first_block_size);
return end_block;
}
@@ -479,7 +479,7 @@ void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::grow(size_type ext
//Get the address of the first block
block_ctrl *first_block = priv_first_block();
block_ctrl *old_end_block = priv_end_block();
- size_type old_border_offset = (size_type)(reinterpret_cast<char*>(old_end_block) -
+ size_type old_border_offset = (size_type)(reinterpret_cast<char*>(old_end_block) -
reinterpret_cast<char*>(this)) + EndCtrlBlockBytes;
//Update managed buffer's size
@@ -500,10 +500,10 @@ void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::grow(size_type ext
//between them
new_end_block->m_allocated = 1;
#ifdef BOOST_INTERPROCESS_RBTREE_BEST_FIT_ABI_V1_HPP
- new_end_block->m_size = (reinterpret_cast<char*>(first_block) -
+ new_end_block->m_size = (reinterpret_cast<char*>(first_block) -
reinterpret_cast<char*>(new_end_block))/Alignment;
#else
- new_end_block->m_size = (reinterpret_cast<char*>(new_end_block) -
+ new_end_block->m_size = (reinterpret_cast<char*>(new_end_block) -
reinterpret_cast<char*>(first_block))/Alignment;
#endif
first_block->m_prev_size = new_end_block->m_size;
@@ -512,7 +512,7 @@ void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::grow(size_type ext
//The old end block is the new block
block_ctrl *new_block = old_end_block;
- new_block->m_size = (reinterpret_cast<char*>(new_end_block) -
+ new_block->m_size = (reinterpret_cast<char*>(new_end_block) -
reinterpret_cast<char*>(new_block))/Alignment;
BOOST_ASSERT(new_block->m_size >= BlockCtrlUnits);
priv_mark_as_allocated_block(new_block);
@@ -568,18 +568,18 @@ void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::shrink_to_fit()
//Erase block from the free tree, since we will erase it
m_header.m_imultiset.erase(Imultiset::s_iterator_to(*last_block));
- size_type shrunk_border_offset = (size_type)(reinterpret_cast<char*>(last_block) -
+ size_type shrunk_border_offset = (size_type)(reinterpret_cast<char*>(last_block) -
reinterpret_cast<char*>(this)) + EndCtrlBlockBytes;
-
+
block_ctrl *new_end_block = last_block;
algo_impl_t::assert_alignment(new_end_block);
//Write new end block attributes
#ifdef BOOST_INTERPROCESS_RBTREE_BEST_FIT_ABI_V1_HPP
- new_end_block->m_size = first_block->m_prev_size =
+ new_end_block->m_size = first_block->m_prev_size =
(reinterpret_cast<char*>(first_block) - reinterpret_cast<char*>(new_end_block))/Alignment;
#else
- new_end_block->m_size = first_block->m_prev_size =
+ new_end_block->m_size = first_block->m_prev_size =
(reinterpret_cast<char*>(new_end_block) - reinterpret_cast<char*>(first_block))/Alignment;
#endif
@@ -604,7 +604,7 @@ template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::size_type
rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::get_free_memory() const
{
- return m_header.m_size - m_header.m_allocated -
+ return m_header.m_size - m_header.m_allocated -
priv_first_block_offset_from_this(this, m_header.m_extra_hdr_bytes);
}
@@ -614,7 +614,7 @@ rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
get_min_size (size_type extra_hdr_bytes)
{
return (algo_impl_t::ceil_units(sizeof(rbtree_best_fit)) +
- algo_impl_t::ceil_units(extra_hdr_bytes) +
+ algo_impl_t::ceil_units(extra_hdr_bytes) +
MinBlockUnits + EndCtrlBlockUnits)*Alignment;
}
@@ -625,13 +625,13 @@ inline bool rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
//-----------------------
boost::interprocess::scoped_lock<mutex_type> guard(m_header);
//-----------------------
- size_type block1_off =
+ size_type block1_off =
priv_first_block_offset_from_this(this, m_header.m_extra_hdr_bytes);
- return m_header.m_allocated == 0 &&
+ return m_header.m_allocated == 0 &&
m_header.m_imultiset.begin() != m_header.m_imultiset.end() &&
(++m_header.m_imultiset.begin()) == m_header.m_imultiset.end()
- && m_header.m_imultiset.begin()->m_size ==
+ && m_header.m_imultiset.begin()->m_size ==
(m_header.m_size - block1_off - EndCtrlBlockBytes)/Alignment;
}
@@ -659,7 +659,7 @@ bool rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
return false;
}
- size_type block1_off =
+ size_type block1_off =
priv_first_block_offset_from_this(this, m_header.m_extra_hdr_bytes);
//Check free bytes are less than size
@@ -672,7 +672,7 @@ bool rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
inline void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
allocate(size_type nbytes)
-{
+{
//-----------------------
boost::interprocess::scoped_lock<mutex_type> guard(m_header);
//-----------------------
@@ -684,18 +684,18 @@ inline void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
inline void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
allocate_aligned(size_type nbytes, size_type alignment)
-{
+{
//-----------------------
boost::interprocess::scoped_lock<mutex_type> guard(m_header);
//-----------------------
- return algo_impl_t::allocate_aligned(this, nbytes, alignment);
+ return algo_impl_t::allocate_aligned(this, nbytes, alignment);
}
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
template<class T>
inline std::pair<T*, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
- size_type preferred_size,size_type &received_size,
+ size_type preferred_size,size_type &received_size,
T *reuse_ptr)
{
std::pair<void*, bool> ret = priv_allocation_command
@@ -708,7 +708,7 @@ inline std::pair<T*, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignmen
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
inline std::pair<void*, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
raw_allocation_command (boost::interprocess::allocation_type command, size_type limit_objects,
- size_type preferred_objects,size_type &received_objects,
+ size_type preferred_objects,size_type &received_objects,
void *reuse_ptr, size_type sizeof_object)
{
if(!sizeof_object)
@@ -728,7 +728,7 @@ inline std::pair<void*, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlign
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
inline std::pair<void*, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
priv_allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
- size_type preferred_size,size_type &received_size,
+ size_type preferred_size,size_type &received_size,
void *reuse_ptr, size_type sizeof_object)
{
std::pair<void*, bool> ret;
@@ -815,7 +815,7 @@ void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
//Obtain the real size of the block
block_ctrl *reuse = priv_get_block(reuse_ptr);
- //Sanity check
+ //Sanity check
//BOOST_ASSERT(reuse->m_size == priv_tail_size(reuse));
algo_impl_t::assert_alignment(reuse);
@@ -859,12 +859,12 @@ void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
(reinterpret_cast<char*>(reuse) - needs_backwards_aligned);
//Free old previous buffer
- new_block->m_size =
+ new_block->m_size =
AllocatedCtrlUnits + (needs_backwards_aligned + (received_size - UsableByPreviousChunk))/Alignment;
BOOST_ASSERT(new_block->m_size >= BlockCtrlUnits);
priv_mark_as_allocated_block(new_block);
- prev_block->m_size = (reinterpret_cast<char*>(new_block) -
+ prev_block->m_size = (reinterpret_cast<char*>(new_block) -
reinterpret_cast<char*>(prev_block))/Alignment;
BOOST_ASSERT(prev_block->m_size >= BlockCtrlUnits);
priv_mark_as_free_block(prev_block);
@@ -875,7 +875,7 @@ void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
{
imultiset_iterator prev_block_it(Imultiset::s_iterator_to(*prev_block));
imultiset_iterator was_smaller_it(prev_block_it);
- if(prev_block_it != m_header.m_imultiset.begin() &&
+ if(prev_block_it != m_header.m_imultiset.begin() &&
(--(was_smaller_it = prev_block_it))->m_size > prev_block->m_size){
m_header.m_imultiset.erase(prev_block_it);
m_header.m_imultiset.insert(m_header.m_imultiset.begin(), *prev_block);
@@ -884,7 +884,7 @@ void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
received_size = needs_backwards_aligned + received_size;
m_header.m_allocated += needs_backwards_aligned;
-
+
//Check alignment
algo_impl_t::assert_alignment(new_block);
@@ -951,7 +951,7 @@ std::pair<void *, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>:
//command &= (~boost::interprocess::expand_bwd);
if(command & boost::interprocess::shrink_in_place){
- bool success =
+ bool success =
algo_impl_t::shrink(this, reuse_ptr, limit_size, preferred_size, received_size);
return std::pair<void *, bool> ((success ? reuse_ptr : 0), true);
}
@@ -1044,7 +1044,7 @@ bool rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
//The block must be marked as allocated and the sizes must be equal
BOOST_ASSERT(priv_is_allocated_block(block));
//BOOST_ASSERT(old_block_units == priv_tail_size(block));
-
+
//Put this to a safe value
received_size = (old_block_units - AllocatedCtrlUnits)*Alignment + UsableByPreviousChunk;
if(received_size >= preferred_size || received_size >= min_size)
@@ -1084,7 +1084,7 @@ bool rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
//Check if we can split the next one in two parts
if((merged_units - intended_units) >= BlockCtrlUnits){
- //This block is bigger than needed, split it in
+ //This block is bigger than needed, split it in
//two blocks, the first one will be merged and
//the second's size will be the remaining space
BOOST_ASSERT(next_block->m_size == priv_next_block(next_block)->m_prev_size);
@@ -1098,9 +1098,9 @@ bool rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
//overwrite the tree hook of the old next block. So we first erase the
//old if needed and we'll insert the new one after creating the new next
imultiset_iterator old_next_block_it(Imultiset::s_iterator_to(*next_block));
- const bool size_invariants_broken =
+ const bool size_invariants_broken =
(next_block->m_size - rem_units ) < BlockCtrlUnits ||
- (old_next_block_it != m_header.m_imultiset.begin() &&
+ (old_next_block_it != m_header.m_imultiset.begin() &&
(--imultiset_iterator(old_next_block_it))->m_size > rem_units);
if(size_invariants_broken){
m_header.m_imultiset.erase(old_next_block_it);
@@ -1267,7 +1267,7 @@ void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::priv_check_and_al
algo_impl_t::assert_alignment(block);
if (block->m_size >= upper_nunits){
- //This block is bigger than needed, split it in
+ //This block is bigger than needed, split it in
//two blocks, the first's size will be "units" and
//the second's size "block->m_size-units"
size_type block_old_size = block->m_size;
@@ -1298,7 +1298,7 @@ void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::priv_check_and_al
m_header.m_imultiset.erase(it_old);
m_header.m_imultiset.insert(m_header.m_imultiset.begin(), *rem_block);
}
-
+
}
else if (block->m_size >= nunits){
m_header.m_imultiset.erase(it_old);
@@ -1318,9 +1318,9 @@ void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::priv_check_and_al
//Clear the memory occupied by the tree hook, since this won't be
//cleared with zero_free_memory
TreeHook *t = static_cast<TreeHook*>(block);
- //Just clear the memory part reserved for the user
+ //Just clear the memory part reserved for the user
std::size_t tree_hook_offset_in_block = (char*)t - (char*)block;
- //volatile char *ptr =
+ //volatile char *ptr =
char *ptr = reinterpret_cast<char*>(block)+tree_hook_offset_in_block;
const std::size_t s = BlockCtrlBytes - tree_hook_offset_in_block;
std::memset(ptr, 0, s);
@@ -1344,7 +1344,7 @@ void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::priv_deallocate(vo
if(!addr) return;
block_ctrl *block = priv_get_block(addr);
-
+
//The blocks must be marked as allocated and the sizes must be equal
BOOST_ASSERT(priv_is_allocated_block(block));
// BOOST_ASSERT(block->m_size == priv_tail_size(block));
diff --git a/boost/interprocess/mem_algo/simple_seq_fit.hpp b/boost/interprocess/mem_algo/simple_seq_fit.hpp
index 5cc92c1103..1085ca00ac 100644
--- a/boost/interprocess/mem_algo/simple_seq_fit.hpp
+++ b/boost/interprocess/mem_algo/simple_seq_fit.hpp
@@ -31,7 +31,7 @@ namespace interprocess {
//!This class implements the simple sequential fit algorithm with a simply
//!linked list of free buffers.
template<class MutexFamily, class VoidPointer>
-class simple_seq_fit
+class simple_seq_fit
: public ipcdetail::simple_seq_fit_impl<MutexFamily, VoidPointer>
{
/// @cond
@@ -41,7 +41,7 @@ class simple_seq_fit
public:
typedef typename base_t::size_type size_type;
- //!Constructor. "size" is the total size of the managed memory segment,
+ //!Constructor. "size" is the total size of the managed memory segment,
//!"extra_hdr_bytes" indicates the extra bytes beginning in the sizeof(simple_seq_fit)
//!offset that the allocator should not use at all.*/
simple_seq_fit (size_type size, size_type extra_hdr_bytes)
diff --git a/boost/interprocess/offset_ptr.hpp b/boost/interprocess/offset_ptr.hpp
index 4187543d57..ac8da2c292 100644
--- a/boost/interprocess/offset_ptr.hpp
+++ b/boost/interprocess/offset_ptr.hpp
@@ -82,19 +82,19 @@ class offset_ptr
//!Never throws.
template <class T>
offset_ptr( T *ptr
- , typename ipcdetail::enable_if< ipcdetail::is_convertible<T*, PointedType*> >::type * = 0)
+ , typename ipcdetail::enable_if< ipcdetail::is_convertible<T*, PointedType*> >::type * = 0)
{ this->set_offset(static_cast<PointedType*>(ptr)); }
//!Constructor from other offset_ptr
//!Never throws.
- offset_ptr(const offset_ptr& ptr)
+ offset_ptr(const offset_ptr& ptr)
{ this->set_offset(ptr.get()); }
- //!Constructor from other offset_ptr. If pointers of pointee types are
+ //!Constructor from other offset_ptr. If pointers of pointee types are
//!convertible, offset_ptrs will be convertibles. Never throws.
template<class T2, class P2, class O2, std::size_t A2>
offset_ptr( const offset_ptr<T2, P2, O2, A2> &ptr
- , typename ipcdetail::enable_if< ipcdetail::is_convertible<T2*, PointedType*> >::type * = 0)
+ , typename ipcdetail::enable_if< ipcdetail::is_convertible<T2*, PointedType*> >::type * = 0)
{ this->set_offset(static_cast<PointedType*>(ptr.get())); }
//!Emulates static_cast operator.
@@ -131,12 +131,12 @@ class offset_ptr
//!Pointer-like -> operator. It can return 0 pointer.
//!Never throws.
- pointer operator->() const
+ pointer operator->() const
{ return this->get(); }
- //!Dereferencing operator, if it is a null offset_ptr behavior
+ //!Dereferencing operator, if it is a null offset_ptr behavior
//! is undefined. Never throws.
- reference operator* () const
+ reference operator* () const
{
pointer p = this->get();
reference r = *p;
@@ -146,7 +146,7 @@ class offset_ptr
//!Indexing operator.
//!Never throws.
template<class T>
- reference operator[](T idx) const
+ reference operator[](T idx) const
{ return this->get()[idx]; }
//!Assignment from pointer (saves extra conversion).
@@ -159,13 +159,13 @@ class offset_ptr
offset_ptr& operator= (const offset_ptr & pt)
{ pointer p(pt.get()); (void)p; this->set_offset(p); return *this; }
- //!Assignment from related offset_ptr. If pointers of pointee types
+ //!Assignment from related offset_ptr. If pointers of pointee types
//! are assignable, offset_ptrs will be assignable. Never throws.
template<class T2, class P2, class O2, std::size_t A2>
typename ipcdetail::enable_if<ipcdetail::is_convertible<T2*, PointedType*>, offset_ptr&>::type
operator= (const offset_ptr<T2, P2, O2, A2> & ptr)
{ this->set_offset(static_cast<PointedType*>(ptr.get())); return *this; }
-
+
//!offset_ptr += difference_type.
//!Never throws.
offset_ptr &operator+= (difference_type offset)
@@ -179,7 +179,7 @@ class offset_ptr
//!++offset_ptr.
//!Never throws.
- offset_ptr& operator++ (void)
+ offset_ptr& operator++ (void)
{ this->inc_offset(sizeof (PointedType)); return *this; }
//!offset_ptr++.
@@ -189,7 +189,7 @@ class offset_ptr
//!--offset_ptr.
//!Never throws.
- offset_ptr& operator-- (void)
+ offset_ptr& operator-- (void)
{ this->dec_offset(sizeof (PointedType)); return *this; }
//!offset_ptr--.
@@ -199,10 +199,10 @@ class offset_ptr
//!safe bool conversion operator.
//!Never throws.
- operator unspecified_bool_type() const
+ operator unspecified_bool_type() const
{ return this->get()? &self_t::unspecified_bool_type_func : 0; }
- //!Not operator. Not needed in theory, but improves portability.
+ //!Not operator. Not needed in theory, but improves portability.
//!Never throws
bool operator! () const
{ return this->get() == 0; }
@@ -345,8 +345,8 @@ class offset_ptr
#endif
return static_cast<PointedType *>(
static_cast<void*>(
- (internal.m_offset == 1) ?
- 0 :
+ (internal.m_offset == 1) ?
+ 0 :
(const_cast<char*>(reinterpret_cast<const char*>(this)) + internal.m_offset)
)
);
@@ -371,52 +371,52 @@ class offset_ptr
//!operator<<
//!for offset ptr
-template<class E, class T, class W, class X, class Y, std::size_t Z>
-inline std::basic_ostream<E, T> & operator<<
+template<class E, class T, class W, class X, class Y, std::size_t Z>
+inline std::basic_ostream<E, T> & operator<<
(std::basic_ostream<E, T> & os, offset_ptr<W, X, Y, Z> const & p)
{ return os << p.get_offset(); }
-//!operator>>
+//!operator>>
//!for offset ptr
-template<class E, class T, class W, class X, class Y, std::size_t Z>
-inline std::basic_istream<E, T> & operator>>
+template<class E, class T, class W, class X, class Y, std::size_t Z>
+inline std::basic_istream<E, T> & operator>>
(std::basic_istream<E, T> & is, offset_ptr<W, X, Y, Z> & p)
{ return is >> p.get_offset(); }
//!Simulation of static_cast between pointers. Never throws.
template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
-inline boost::interprocess::offset_ptr<T1, P1, O1, A1>
+inline boost::interprocess::offset_ptr<T1, P1, O1, A1>
static_pointer_cast(const boost::interprocess::offset_ptr<T2, P2, O2, A2> & r)
-{
+{
return boost::interprocess::offset_ptr<T1, P1, O1, A1>
- (r, boost::interprocess::ipcdetail::static_cast_tag());
+ (r, boost::interprocess::ipcdetail::static_cast_tag());
}
//!Simulation of const_cast between pointers. Never throws.
template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
inline boost::interprocess::offset_ptr<T1, P1, O1, A1>
const_pointer_cast(const boost::interprocess::offset_ptr<T2, P2, O2, A2> & r)
-{
+{
return boost::interprocess::offset_ptr<T1, P1, O1, A1>
- (r, boost::interprocess::ipcdetail::const_cast_tag());
+ (r, boost::interprocess::ipcdetail::const_cast_tag());
}
//!Simulation of dynamic_cast between pointers. Never throws.
template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
-inline boost::interprocess::offset_ptr<T1, P1, O1, A1>
+inline boost::interprocess::offset_ptr<T1, P1, O1, A1>
dynamic_pointer_cast(const boost::interprocess::offset_ptr<T2, P2, O2, A2> & r)
-{
+{
return boost::interprocess::offset_ptr<T1, P1, O1, A1>
- (r, boost::interprocess::ipcdetail::dynamic_cast_tag());
+ (r, boost::interprocess::ipcdetail::dynamic_cast_tag());
}
//!Simulation of reinterpret_cast between pointers. Never throws.
template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
inline boost::interprocess::offset_ptr<T1, P1, O1, A1>
reinterpret_pointer_cast(const boost::interprocess::offset_ptr<T2, P2, O2, A2> & r)
-{
+{
return boost::interprocess::offset_ptr<T1, P1, O1, A1>
- (r, boost::interprocess::ipcdetail::reinterpret_cast_tag());
+ (r, boost::interprocess::ipcdetail::reinterpret_cast_tag());
}
} //namespace interprocess {
@@ -425,14 +425,14 @@ inline boost::interprocess::offset_ptr<T1, P1, O1, A1>
//!has_trivial_constructor<> == true_type specialization for optimizations
template <class T, class P, class O, std::size_t A>
-struct has_trivial_constructor< boost::interprocess::offset_ptr<T, P, O, A> >
+struct has_trivial_constructor< boost::interprocess::offset_ptr<T, P, O, A> >
{
static const bool value = true;
};
///has_trivial_destructor<> == true_type specialization for optimizations
template <class T, class P, class O, std::size_t A>
-struct has_trivial_destructor< boost::interprocess::offset_ptr<T, P, O, A> >
+struct has_trivial_destructor< boost::interprocess::offset_ptr<T, P, O, A> >
{
static const bool value = true;
};
@@ -440,7 +440,7 @@ struct has_trivial_destructor< boost::interprocess::offset_ptr<T, P, O, A> >
//#if !defined(_MSC_VER) || (_MSC_VER >= 1400)
namespace interprocess {
//#endif
-//!to_raw_pointer() enables boost::mem_fn to recognize offset_ptr.
+//!to_raw_pointer() enables boost::mem_fn to recognize offset_ptr.
//!Never throws.
template <class T, class P, class O, std::size_t A>
inline T * to_raw_pointer(boost::interprocess::offset_ptr<T, P, O, A> const & p)
@@ -482,7 +482,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 std::size_t Mask = ((std::size_t(1) << NumBits)-1)<<1u;
+ static const std::size_t Mask = ((std::size_t(1) << NumBits)-1)<<1u;
static pointer get_pointer(const pointer &n)
{ return reinterpret_cast<T*>(std::size_t(n.get()) & ~std::size_t(Mask)); }
diff --git a/boost/interprocess/segment_manager.hpp b/boost/interprocess/segment_manager.hpp
index 4424695992..8680a953e2 100644
--- a/boost/interprocess/segment_manager.hpp
+++ b/boost/interprocess/segment_manager.hpp
@@ -69,9 +69,9 @@ class segment_manager_base
typedef typename MemoryAlgorithm::void_pointer void_pointer;
typedef typename MemoryAlgorithm::mutex_family mutex_family;
typedef MemoryAlgorithm memory_algorithm;
-
+
/// @cond
-
+
//Experimental. Don't use
typedef typename MemoryAlgorithm::multiallocation_chain multiallocation_chain;
typedef typename MemoryAlgorithm::difference_type difference_type;
@@ -88,7 +88,7 @@ class segment_manager_base
//!"size" is the size of the memory segment where
//!the basic segment manager is being constructed.
//!
- //!"reserved_bytes" is the number of bytes
+ //!"reserved_bytes" is the number of bytes
//!after the end of the memory algorithm object itself
//!that the memory algorithm will exclude from
//!dynamic allocation
@@ -115,7 +115,7 @@ class segment_manager_base
static size_type get_min_size (size_type size)
{ return MemoryAlgorithm::get_min_size(size); }
- //!Allocates nbytes bytes. This function is only used in
+ //!Allocates nbytes bytes. This function is only used in
//!single-segment management. Never throws
void * allocate (size_type nbytes, std::nothrow_t)
{ return MemoryAlgorithm::allocate(nbytes); }
@@ -165,22 +165,22 @@ class segment_manager_base
//!Allocates nbytes bytes. Throws boost::interprocess::bad_alloc
//!on failure
void * allocate(size_type nbytes)
- {
+ {
void * ret = MemoryAlgorithm::allocate(nbytes);
if(!ret)
throw bad_alloc();
return ret;
}
- //!Allocates nbytes bytes. This function is only used in
+ //!Allocates nbytes bytes. This function is only used in
//!single-segment management. Never throws
void * allocate_aligned (size_type nbytes, size_type alignment, std::nothrow_t)
{ return MemoryAlgorithm::allocate_aligned(nbytes, alignment); }
- //!Allocates nbytes bytes. This function is only used in
+ //!Allocates nbytes bytes. This function is only used in
//!single-segment management. Throws bad_alloc when fails
void * allocate_aligned(size_type nbytes, size_type alignment)
- {
+ {
void * ret = MemoryAlgorithm::allocate_aligned(nbytes, alignment);
if(!ret)
throw bad_alloc();
@@ -269,7 +269,7 @@ class segment_manager_base
throw bad_alloc();
}
else{
- return 0;
+ return 0;
}
}
@@ -293,7 +293,7 @@ class segment_manager_base
void prot_anonymous_destroy(const void *object, ipcdetail::in_place_interface &table)
{
- //Get control data from associated with this object
+ //Get control data from associated with this object
typedef ipcdetail::block_header<size_type> block_header_t;
block_header_t *ctrl_data = block_header_t::block_header_from_value(object, table.size, table.alignment);
@@ -318,9 +318,9 @@ class segment_manager_base
//!This object is placed in the beginning of memory segment and
//!implements the allocation (named or anonymous) of portions
//!of the segment. This object contains two indexes that
-//!maintain an association between a name and a portion of the segment.
+//!maintain an association between a name and a portion of the segment.
//!
-//!The first index contains the mappings for normal named objects using the
+//!The first index contains the mappings for normal named objects using the
//!char type specified in the template parameter.
//!
//!The second index contains the association for unique instances. The key will
@@ -336,7 +336,7 @@ template<class CharType
,template<class IndexConfig> class IndexType>
class segment_manager
: public segment_manager_base<MemoryAlgorithm>
-{
+{
/// @cond
//Non-copyable
segment_manager();
@@ -446,7 +446,7 @@ class segment_manager
//!Returns throwing "construct" proxy
//!object
template <class T>
- typename construct_proxy<T>::type
+ typename construct_proxy<T>::type
construct(char_ptr_holder_t name)
{ return typename construct_proxy<T>::type (this, name, false, true); }
@@ -466,39 +466,39 @@ class segment_manager
//!Returns no throwing "search or construct"
//!proxy object
template <class T>
- typename construct_proxy<T>::type
+ typename construct_proxy<T>::type
find_or_construct(char_ptr_holder_t name, std::nothrow_t)
{ return typename construct_proxy<T>::type (this, name, true, false); }
//!Returns throwing "construct from iterators" proxy object
template <class T>
- typename construct_iter_proxy<T>::type
+ typename construct_iter_proxy<T>::type
construct_it(char_ptr_holder_t name)
{ return typename construct_iter_proxy<T>::type (this, name, false, true); }
//!Returns throwing "search or construct from iterators"
//!proxy object
template <class T>
- typename construct_iter_proxy<T>::type
+ typename construct_iter_proxy<T>::type
find_or_construct_it(char_ptr_holder_t name)
{ return typename construct_iter_proxy<T>::type (this, name, true, true); }
//!Returns no throwing "construct from iterators"
//!proxy object
template <class T>
- typename construct_iter_proxy<T>::type
+ typename construct_iter_proxy<T>::type
construct_it(char_ptr_holder_t name, std::nothrow_t)
{ return typename construct_iter_proxy<T>::type (this, name, false, false); }
//!Returns no throwing "search or construct from iterators"
//!proxy object
template <class T>
- typename construct_iter_proxy<T>::type
+ typename construct_iter_proxy<T>::type
find_or_construct_it(char_ptr_holder_t name, std::nothrow_t)
{ return typename construct_iter_proxy<T>::type (this, name, true, false); }
- //!Calls object function blocking recursive interprocess_mutex and guarantees that
- //!no new named_alloc or destroy will be executed by any process while
+ //!Calls object function blocking recursive interprocess_mutex and guarantees that
+ //!no new named_alloc or destroy will be executed by any process while
//!executing the object function call*/
template <class Func>
void atomic_func(Func &f)
@@ -571,22 +571,22 @@ class segment_manager
static instance_type get_instance_type(const T *ptr)
{ return priv_get_instance_type(block_header_t::block_header_from_value(ptr)); }
- //!Preallocates needed index resources to optimize the
+ //!Preallocates needed index resources to optimize the
//!creation of "num" named objects in the managed memory segment.
//!Can throw boost::interprocess::bad_alloc if there is no enough memory.
void reserve_named_objects(size_type num)
- {
+ {
//-------------------------------
scoped_lock<rmutex> guard(m_header);
//-------------------------------
- m_header.m_named_index.reserve(num);
+ m_header.m_named_index.reserve(num);
}
- //!Preallocates needed index resources to optimize the
+ //!Preallocates needed index resources to optimize the
//!creation of "num" unique objects in the managed memory segment.
//!Can throw boost::interprocess::bad_alloc if there is no enough memory.
void reserve_unique_objects(size_type num)
- {
+ {
//-------------------------------
scoped_lock<rmutex> guard(m_header);
//-------------------------------
@@ -596,32 +596,32 @@ class segment_manager
//!Calls shrink_to_fit in both named and unique object indexes
//!to try to free unused memory from those indexes.
void shrink_to_fit_indexes()
- {
+ {
//-------------------------------
scoped_lock<rmutex> guard(m_header);
//-------------------------------
- m_header.m_named_index.shrink_to_fit();
- m_header.m_unique_index.shrink_to_fit();
+ m_header.m_named_index.shrink_to_fit();
+ m_header.m_unique_index.shrink_to_fit();
}
//!Returns the number of named objects stored in
//!the segment.
size_type get_num_named_objects()
- {
+ {
//-------------------------------
scoped_lock<rmutex> guard(m_header);
//-------------------------------
- return m_header.m_named_index.size();
+ return m_header.m_named_index.size();
}
//!Returns the number of unique objects stored in
//!the segment.
size_type get_num_unique_objects()
- {
+ {
//-------------------------------
scoped_lock<rmutex> guard(m_header);
//-------------------------------
- return m_header.m_unique_index.size();
+ return m_header.m_unique_index.size();
}
//!Obtains the minimum size needed by the
@@ -693,13 +693,13 @@ class segment_manager
/// @cond
- //!Generic named/anonymous new function. Offers all the possibilities,
- //!such as throwing, search before creating, and the constructor is
+ //!Generic named/anonymous new function. Offers all the possibilities,
+ //!such as throwing, search before creating, and the constructor is
//!encapsulated in an object function.
template<class T>
- T *generic_construct(const CharType *name,
- size_type num,
- bool try2find,
+ T *generic_construct(const CharType *name,
+ size_type num,
+ bool try2find,
bool dothrow,
ipcdetail::in_place_interface &table)
{
@@ -713,7 +713,7 @@ class segment_manager
//!returned pair is 0.
template <class T>
std::pair<T*, size_type> priv_find_impl (const CharType* name, bool lock)
- {
+ {
//The name can't be null, no anonymous object can be found by name
BOOST_ASSERT(name != 0);
ipcdetail::placement_destroy<T> table;
@@ -737,13 +737,13 @@ class segment_manager
{
ipcdetail::placement_destroy<T> table;
size_type size;
- void *ret = priv_generic_find<char>(name, m_header.m_unique_index, table, size, is_intrusive_t(), lock);
+ void *ret = priv_generic_find<char>(name, m_header.m_unique_index, table, size, is_intrusive_t(), lock);
return std::pair<T*, size_type>(static_cast<T*>(ret), size);
}
- void *priv_generic_construct(const CharType *name,
- size_type num,
- bool try2find,
+ void *priv_generic_construct(const CharType *name,
+ size_type num,
+ bool try2find,
bool dothrow,
ipcdetail::in_place_interface &table)
{
@@ -805,7 +805,7 @@ class segment_manager
return 0;
}
CharType *name = static_cast<CharType*>(ctrl_data->template name<CharType>());
-
+
//Sanity checks
BOOST_ASSERT(ctrl_data->sizeof_char() == sizeof(CharType));
BOOST_ASSERT(ctrl_data->m_num_char == std::char_traits<CharType>::length(name));
@@ -837,7 +837,7 @@ class segment_manager
template <class CharT>
void *priv_generic_find
- (const CharT* name,
+ (const CharT* name,
IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
ipcdetail::in_place_interface &table,
size_type &length,
@@ -877,7 +877,7 @@ class segment_manager
template <class CharT>
void *priv_generic_find
- (const CharT* name,
+ (const CharT* name,
IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
ipcdetail::in_place_interface &table,
size_type &length,
@@ -941,7 +941,7 @@ class segment_manager
}
template <class CharT>
- bool priv_generic_named_destroy(const CharT *name,
+ bool priv_generic_named_destroy(const CharT *name,
IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
ipcdetail::in_place_interface &table,
ipcdetail::true_ is_intrusive_index)
@@ -951,7 +951,7 @@ class segment_manager
typedef ipcdetail::index_key<CharT, void_pointer> index_key_t;
typedef typename index_type::iterator index_it;
typedef typename index_type::value_type intrusive_value_type;
-
+
//-------------------------------
scoped_lock<rmutex> guard(m_header);
//-------------------------------
@@ -972,7 +972,7 @@ class segment_manager
void *memory = iv;
void *values = ctrl_data->value();
std::size_t num = ctrl_data->m_value_bytes/table.size;
-
+
//Sanity check
BOOST_ASSERT((ctrl_data->m_value_bytes % table.size) == 0);
BOOST_ASSERT(sizeof(CharT) == ctrl_data->sizeof_char());
@@ -992,7 +992,7 @@ class segment_manager
}
template <class CharT>
- bool priv_generic_named_destroy(const CharT *name,
+ bool priv_generic_named_destroy(const CharT *name,
IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
ipcdetail::in_place_interface &table,
ipcdetail::false_ is_intrusive_index)
@@ -1006,7 +1006,7 @@ class segment_manager
scoped_lock<rmutex> guard(m_header);
//-------------------------------
//Try to find the name in the index
- index_it it = index.find(key_type (name,
+ index_it it = index.find(key_type (name,
std::char_traits<CharT>::length(name)));
//If not found, return false
@@ -1033,7 +1033,7 @@ class segment_manager
char *stored_name = static_cast<char*>(static_cast<void*>(const_cast<CharT*>(it->first.name())));
(void)stored_name;
- //Check if the distance between the name pointer and the memory pointer
+ //Check if the distance between the name pointer and the memory pointer
//is correct (this can detect incorrect type in destruction)
std::size_t num = ctrl_data->m_value_bytes/table.size;
void *values = ctrl_data->value();
@@ -1070,8 +1070,8 @@ class segment_manager
template<class CharT>
void * priv_generic_named_construct(unsigned char type,
const CharT *name,
- size_type num,
- bool try2find,
+ size_type num,
+ bool try2find,
bool dothrow,
ipcdetail::in_place_interface &table,
IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
@@ -1095,12 +1095,12 @@ class segment_manager
//-------------------------------
//Insert the node. This can throw.
//First, we want to know if the key is already present before
- //we allocate any memory, and if the key is not present, we
+ //we allocate any memory, and if the key is not present, we
//want to allocate all memory in a single buffer that will
//contain the name and the user buffer.
//
//Since equal_range(key) + insert(hint, value) approach is
- //quite inefficient in container implementations
+ //quite inefficient in container implementations
//(they re-test if the position is correct), I've chosen
//to insert the node, do an ugly un-const cast and modify
//the key (which is a smart pointer) to an equivalent one
@@ -1138,7 +1138,7 @@ class segment_manager
}
//Allocates buffer for name + data, this can throw (it hurts)
- void *buffer_ptr;
+ void *buffer_ptr;
//Check if there is enough memory
if(dothrow){
@@ -1149,7 +1149,7 @@ class segment_manager
buffer_ptr = this->allocate
(block_info.template total_size_with_header<intrusive_value_type>(), std::nothrow_t());
if(!buffer_ptr)
- return 0;
+ return 0;
}
//Now construct the intrusive hook plus the header
@@ -1184,7 +1184,7 @@ class segment_manager
//the memory allocation as the intrusive value is built in that
//memory
value_eraser<index_type> v_eraser(index, it);
-
+
//Construct array, this can throw
ipcdetail::array_construct(ptr, num, table);
@@ -1197,10 +1197,10 @@ class segment_manager
//!Generic named new function for
//!named functions
template<class CharT>
- void * priv_generic_named_construct(unsigned char type,
+ void * priv_generic_named_construct(unsigned char type,
const CharT *name,
- size_type num,
- bool try2find,
+ size_type num,
+ bool try2find,
bool dothrow,
ipcdetail::in_place_interface &table,
IndexType<ipcdetail::index_config<CharT, MemoryAlgorithm> > &index,
@@ -1227,12 +1227,12 @@ class segment_manager
//-------------------------------
//Insert the node. This can throw.
//First, we want to know if the key is already present before
- //we allocate any memory, and if the key is not present, we
+ //we allocate any memory, and if the key is not present, we
//want to allocate all memory in a single buffer that will
//contain the name and the user buffer.
//
//Since equal_range(key) + insert(hint, value) approach is
- //quite inefficient in container implementations
+ //quite inefficient in container implementations
//(they re-test if the position is correct), I've chosen
//to insert the node, do an ugly un-const cast and modify
//the key (which is a smart pointer) to an equivalent one
@@ -1265,7 +1265,7 @@ class segment_manager
value_eraser<index_type> v_eraser(index, it);
//Allocates buffer for name + data, this can throw (it hurts)
- void *buffer_ptr;
+ void *buffer_ptr;
block_header_t * hdr;
//Allocate and construct the headers
@@ -1277,7 +1277,7 @@ class segment_manager
else{
buffer_ptr = this->allocate(total_size, std::nothrow_t());
if(!buffer_ptr)
- return 0;
+ return 0;
}
index_it *idr = new(buffer_ptr) index_it(it);
hdr = block_header_t::template from_first_header<index_it>(idr);
@@ -1289,7 +1289,7 @@ class segment_manager
else{
buffer_ptr = this->allocate(block_info.total_size(), std::nothrow_t());
if(!buffer_ptr)
- return 0;
+ return 0;
}
hdr = static_cast<block_header_t*>(buffer_ptr);
}
@@ -1303,7 +1303,7 @@ class segment_manager
std::char_traits<CharT>::copy(name_ptr, name, namelen+1);
//Do the ugly cast, please mama, forgive me!
- //This new key points to an identical string, so it must have the
+ //This new key points to an identical string, so it must have the
//same position than the overwritten key according to the predicate
const_cast<key_type &>(it->first).name(name_ptr);
it->second.m_ptr = hdr;
@@ -1346,7 +1346,7 @@ class segment_manager
{
named_index_t m_named_index;
unique_index_t m_unique_index;
-
+
header_t(Base *restricted_segment_mngr)
: m_named_index (restricted_segment_mngr)
, m_unique_index(restricted_segment_mngr)
diff --git a/boost/interprocess/shared_memory_object.hpp b/boost/interprocess/shared_memory_object.hpp
index 7c8fcf61bd..f3bc7ba173 100644
--- a/boost/interprocess/shared_memory_object.hpp
+++ b/boost/interprocess/shared_memory_object.hpp
@@ -28,7 +28,7 @@
#if defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS_ONLY)
# include <sys/shm.h> //System V shared memory...
#elif defined(BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS)
-# include <fcntl.h> //O_CREAT, O_*...
+# include <fcntl.h> //O_CREAT, O_*...
# include <sys/mman.h> //shm_xxx
# include <unistd.h> //ftruncate, close
# include <sys/stat.h> //mode_t, S_IRWXG, S_IRWXO, S_IRWXU,
@@ -71,26 +71,26 @@ class shared_memory_object
shared_memory_object(open_or_create_t, const char *name, mode_t mode, const permissions &perm = permissions())
{ this->priv_open_or_create(ipcdetail::DoOpenOrCreate, name, mode, perm); }
- //!Tries to open a shared memory object with name "name", with the access mode "mode".
+ //!Tries to open a shared memory object with name "name", with the access mode "mode".
//!If the file does not previously exist, it throws an error.
shared_memory_object(open_only_t, const char *name, mode_t mode)
{ this->priv_open_or_create(ipcdetail::DoOpen, name, mode, permissions()); }
- //!Moves the ownership of "moved"'s shared memory object to *this.
- //!After the call, "moved" does not represent any shared memory object.
+ //!Moves the ownership of "moved"'s shared memory object to *this.
+ //!After the call, "moved" does not represent any shared memory object.
//!Does not throw
shared_memory_object(BOOST_RV_REF(shared_memory_object) moved)
: m_handle(file_handle_t(ipcdetail::invalid_file()))
{ this->swap(moved); }
//!Moves the ownership of "moved"'s shared memory to *this.
- //!After the call, "moved" does not represent any shared memory.
+ //!After the call, "moved" does not represent any shared memory.
//!Does not throw
shared_memory_object &operator=(BOOST_RV_REF(shared_memory_object) moved)
- {
+ {
shared_memory_object tmp(boost::move(moved));
this->swap(tmp);
- return *this;
+ return *this;
}
//!Swaps the shared_memory_objects. Does not throw
@@ -99,7 +99,7 @@ class shared_memory_object
//!Erases a shared memory object from the system.
//!Returns false on error. Never throws
static bool remove(const char *name);
-
+
//!Sets the size of the shared memory mapping
void truncate(offset_t length);
@@ -142,11 +142,11 @@ class shared_memory_object
/// @cond
-inline shared_memory_object::shared_memory_object()
+inline shared_memory_object::shared_memory_object()
: m_handle(file_handle_t(ipcdetail::invalid_file()))
{}
-inline shared_memory_object::~shared_memory_object()
+inline shared_memory_object::~shared_memory_object()
{ this->priv_close(); }
@@ -157,10 +157,10 @@ inline bool shared_memory_object::get_size(offset_t &size) const
{ return ipcdetail::get_file_size((file_handle_t)m_handle, size); }
inline void shared_memory_object::swap(shared_memory_object &other)
-{
+{
std::swap(m_handle, other.m_handle);
std::swap(m_mode, other.m_mode);
- m_filename.swap(other.m_filename);
+ m_filename.swap(other.m_filename);
}
inline mapping_handle_t shared_memory_object::get_mapping_handle() const
@@ -268,7 +268,7 @@ inline bool use_filesystem_based_posix()
} //shared_memory_object_detail
inline bool shared_memory_object::priv_open_or_create
- (ipcdetail::create_enum_t type,
+ (ipcdetail::create_enum_t type,
const char *filename,
mode_t mode, const permissions &perm)
{
diff --git a/boost/interprocess/smart_ptr/deleter.hpp b/boost/interprocess/smart_ptr/deleter.hpp
index 4aba772975..3a07ccd8f4 100644
--- a/boost/interprocess/smart_ptr/deleter.hpp
+++ b/boost/interprocess/smart_ptr/deleter.hpp
@@ -26,9 +26,9 @@
//!Describes the functor to delete objects from the segment.
namespace boost {
-namespace interprocess {
+namespace interprocess {
-//!A deleter that uses the segment manager's destroy_ptr
+//!A deleter that uses the segment manager's destroy_ptr
//!function to destroy the passed pointer resource.
//!
//!This deleter is used
@@ -56,7 +56,7 @@ class deleter
{ mp_mngr->destroy_ptr(ipcdetail::to_raw_pointer(p)); }
};
-} //namespace interprocess {
+} //namespace interprocess {
} //namespace boost {
#include <boost/interprocess/detail/config_end.hpp>
diff --git a/boost/interprocess/smart_ptr/detail/shared_count.hpp b/boost/interprocess/smart_ptr/detail/shared_count.hpp
index 0150ef6c00..7daaee6ea4 100644
--- a/boost/interprocess/smart_ptr/detail/shared_count.hpp
+++ b/boost/interprocess/smart_ptr/detail/shared_count.hpp
@@ -28,7 +28,7 @@
#include <boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp>
#include <boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp>
#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <functional> // std::less
@@ -99,7 +99,7 @@ class shared_count
counted_impl_allocator alloc(a);
m_pi = alloc.allocate(1);
//Anti-exception deallocator
- scoped_ptr<counted_impl,
+ scoped_ptr<counted_impl,
scoped_ptr_dealloc_functor<counted_impl_allocator> >
deallocator(m_pi, alloc);
//It's more correct to use VoidAllocator::construct but
@@ -116,7 +116,7 @@ class shared_count
}
~shared_count() // nothrow
- {
+ {
if(m_pi)
m_pi->release();
}
diff --git a/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp b/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp
index 4e2e664c86..6a46bb75e6 100644
--- a/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp
+++ b/boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp
@@ -26,7 +26,7 @@
#include <boost/interprocess/smart_ptr/detail/sp_counted_base.hpp>
#include <boost/interprocess/smart_ptr/scoped_ptr.hpp>
#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/container/allocator/allocator_traits.hpp>
+#include <boost/container/allocator_traits.hpp>
#include <boost/intrusive/pointer_traits.hpp>
namespace boost {
@@ -63,10 +63,10 @@ struct scoped_ptr_dealloc_functor
{ if (ptr) priv_deallocate(ptr, alloc_version()); }
};
-
+
template<class A, class D>
-class sp_counted_impl_pd
+class sp_counted_impl_pd
: public sp_counted_base
, boost::container::allocator_traits<A>::template
portable_rebind_alloc< sp_counted_impl_pd<A, D> >::type
diff --git a/boost/interprocess/smart_ptr/intrusive_ptr.hpp b/boost/interprocess/smart_ptr/intrusive_ptr.hpp
index 3f086f5360..f6d5c8b77c 100644
--- a/boost/interprocess/smart_ptr/intrusive_ptr.hpp
+++ b/boost/interprocess/smart_ptr/intrusive_ptr.hpp
@@ -33,12 +33,12 @@ namespace interprocess {
//!The intrusive_ptr class template stores a pointer to an object
//!with an embedded reference count. intrusive_ptr is parameterized on
-//!T (the type of the object pointed to) and VoidPointer(a void pointer type
+//!T (the type of the object pointed to) and VoidPointer(a void pointer type
//!that defines the type of pointer that intrusive_ptr will store).
//!intrusive_ptr<T, void *> defines a class with a T* member whereas
//!intrusive_ptr<T, offset_ptr<void> > defines a class with a offset_ptr<T> member.
//!Relies on unqualified calls to:
-//!
+//!
//! void intrusive_ptr_add_ref(T * p);
//! void intrusive_ptr_release(T * p);
//!
@@ -69,7 +69,7 @@ class intrusive_ptr
intrusive_ptr(): m_ptr(0)
{}
- //!Constructor. Copies pointer and if "p" is not zero and
+ //!Constructor. Copies pointer and if "p" is not zero and
//!"add_ref" is true calls intrusive_ptr_add_ref(to_raw_pointer(p)).
//!Does not throw
intrusive_ptr(const pointer &p, bool add_ref = true): m_ptr(p)
@@ -101,7 +101,7 @@ class intrusive_ptr
if(m_ptr != 0) intrusive_ptr_release(ipcdetail::to_raw_pointer(m_ptr));
}
- //!Assignment operator. Equivalent to intrusive_ptr(r).swap(*this).
+ //!Assignment operator. Equivalent to intrusive_ptr(r).swap(*this).
//!Does not throw
intrusive_ptr & operator=(intrusive_ptr const & rhs)
{
@@ -109,7 +109,7 @@ class intrusive_ptr
return *this;
}
- //!Assignment from related. Equivalent to intrusive_ptr(r).swap(*this).
+ //!Assignment from related. Equivalent to intrusive_ptr(r).swap(*this).
//!Does not throw
template<class U> intrusive_ptr & operator=
(intrusive_ptr<U, VP> const & rhs)
@@ -118,14 +118,14 @@ class intrusive_ptr
return *this;
}
- //!Assignment from pointer. Equivalent to intrusive_ptr(r).swap(*this).
+ //!Assignment from pointer. Equivalent to intrusive_ptr(r).swap(*this).
//!Does not throw
intrusive_ptr & operator=(pointer rhs)
{
this_type(rhs).swap(*this);
return *this;
}
-
+
//!Returns a reference to the internal pointer.
//!Does not throw
pointer &get()
@@ -175,7 +175,7 @@ class intrusive_ptr
//!Returns a.get() == b.get().
//!Does not throw
template<class T, class U, class VP> inline
-bool operator==(intrusive_ptr<T, VP> const & a,
+bool operator==(intrusive_ptr<T, VP> const & a,
intrusive_ptr<U, VP> const & b)
{ return a.get() == b.get(); }
@@ -217,11 +217,11 @@ bool operator!=(const typename intrusive_ptr<T, VP>::pointer &a,
//!Returns a.get() < b.get().
//!Does not throw
template<class T, class VP> inline
-bool operator<(intrusive_ptr<T, VP> const & a,
+bool operator<(intrusive_ptr<T, VP> const & a,
intrusive_ptr<T, VP> const & b)
-{
+{
return std::less<typename intrusive_ptr<T, VP>::pointer>()
- (a.get(), b.get());
+ (a.get(), b.get());
}
//!Exchanges the contents of the two intrusive_ptrs.
@@ -233,7 +233,7 @@ void swap(intrusive_ptr<T, VP> & lhs,
// operator<<
template<class E, class T, class Y, class VP>
-inline std::basic_ostream<E, T> & operator<<
+inline std::basic_ostream<E, T> & operator<<
(std::basic_ostream<E, T> & os, intrusive_ptr<Y, VP> const & p)
{ os << p.get(); return os; }
diff --git a/boost/interprocess/smart_ptr/scoped_ptr.hpp b/boost/interprocess/smart_ptr/scoped_ptr.hpp
index 1885838ffe..a3755d3592 100644
--- a/boost/interprocess/smart_ptr/scoped_ptr.hpp
+++ b/boost/interprocess/smart_ptr/scoped_ptr.hpp
@@ -27,14 +27,14 @@
namespace boost {
namespace interprocess {
-//!scoped_ptr stores a pointer to a dynamically allocated object.
+//!scoped_ptr stores a pointer to a dynamically allocated object.
//!The object pointed to is guaranteed to be deleted, either on destruction
//!of the scoped_ptr, or via an explicit reset. The user can avoid this
//!deletion using release().
-//!scoped_ptr is parameterized on T (the type of the object pointed to) and
+//!scoped_ptr is parameterized on T (the type of the object pointed to) and
//!Deleter (the functor to be executed to delete the internal pointer).
-//!The internal pointer will be of the same pointer type as typename
-//!Deleter::pointer type (that is, if typename Deleter::pointer is
+//!The internal pointer will be of the same pointer type as typename
+//!Deleter::pointer type (that is, if typename Deleter::pointer is
//!offset_ptr<void>, the internal pointer will be offset_ptr<T>).
template<class T, class Deleter>
class scoped_ptr
@@ -60,10 +60,10 @@ class scoped_ptr
: Deleter(d), m_ptr(p) // throws if pointer/Deleter copy ctor throws
{}
- //!If the stored pointer is not 0, destroys the object pointed to by the stored pointer.
+ //!If the stored pointer is not 0, destroys the object pointed to by the stored pointer.
//!calling the operator() of the stored deleter. Never throws
~scoped_ptr()
- {
+ {
if(m_ptr){
Deleter &del = static_cast<Deleter&>(*this);
del(m_ptr);
diff --git a/boost/interprocess/smart_ptr/shared_ptr.hpp b/boost/interprocess/smart_ptr/shared_ptr.hpp
index 61829078e8..5ede547a3f 100644
--- a/boost/interprocess/smart_ptr/shared_ptr.hpp
+++ b/boost/interprocess/smart_ptr/shared_ptr.hpp
@@ -52,7 +52,7 @@ inline void sp_enable_shared_from_this
(shared_count<T, VoidAllocator, Deleter> const & pn
,enable_shared_from_this<T, VoidAllocator, Deleter> *pe
,T *ptr)
-
+
{
(void)ptr;
if(pe != 0){
@@ -66,17 +66,17 @@ inline void sp_enable_shared_from_this(shared_count<T, VoidAllocator, Deleter> c
} // namespace ipcdetail
-//!shared_ptr stores a pointer to a dynamically allocated object.
-//!The object pointed to is guaranteed to be deleted when the last shared_ptr pointing to
+//!shared_ptr stores a pointer to a dynamically allocated object.
+//!The object pointed to is guaranteed to be deleted when the last shared_ptr pointing to
//!it is destroyed or reset.
//!
-//!shared_ptr is parameterized on
+//!shared_ptr is parameterized on
//!T (the type of the object pointed to), VoidAllocator (the void allocator to be used
-//!to allocate the auxiliary data) and Deleter (the deleter whose
+//!to allocate the auxiliary data) and Deleter (the deleter whose
//!operator() will be used to delete the object.
//!
-//!The internal pointer will be of the same pointer type as typename
-//!VoidAllocator::pointer type (that is, if typename VoidAllocator::pointer is
+//!The internal pointer will be of the same pointer type as typename
+//!VoidAllocator::pointer type (that is, if typename VoidAllocator::pointer is
//!offset_ptr<void>, the internal pointer will be offset_ptr<T>).
//!
//!Because the implementation uses reference counting, cycles of shared_ptr
@@ -125,7 +125,7 @@ class shared_ptr
//!Requirements: Deleter and A's copy constructor must not throw.
explicit shared_ptr(const pointer&p, const VoidAllocator &a = VoidAllocator(), const Deleter &d = Deleter())
: m_pn(p, a, d)
- {
+ {
//Check that the pointer passed is of the same type that
//the pointer the allocator defines or it's a raw pointer
typedef typename boost::intrusive::
@@ -134,25 +134,30 @@ class shared_ptr
BOOST_STATIC_ASSERT((ipcdetail::is_same<pointer, ParameterPointer>::value) ||
(ipcdetail::is_pointer<pointer>::value));
- ipcdetail::sp_enable_shared_from_this<T, VoidAllocator, Deleter>( m_pn, ipcdetail::to_raw_pointer(p), ipcdetail::to_raw_pointer(p) );
+ ipcdetail::sp_enable_shared_from_this<T, VoidAllocator, Deleter>( m_pn, ipcdetail::to_raw_pointer(p), ipcdetail::to_raw_pointer(p) );
}
+ //!Copy constructs a shared_ptr. If r is empty, constructs an empty shared_ptr. Otherwise, constructs
+ //!a shared_ptr that shares ownership with r. Never throws.
+ shared_ptr(const shared_ptr &r)
+ : m_pn(r.m_pn) // never throws
+ {}
- //!Constructs a shared_ptr that shares ownership with r and stores p.
+ //!Constructs a shared_ptr that shares ownership with other and stores p.
//!Postconditions: get() == p && use_count() == r.use_count().
//!Throws: nothing.
shared_ptr(const shared_ptr &other, const pointer &p)
: m_pn(other.m_pn, p)
{}
- //!If r is empty, constructs an empty shared_ptr. Otherwise, constructs
+ //!If r is empty, constructs an empty shared_ptr. Otherwise, constructs
//!a shared_ptr that shares ownership with r. Never throws.
template<class Y>
shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r)
: m_pn(r.m_pn) // never throws
{}
- //!Constructs a shared_ptr that shares ownership with r and stores
+ //!Constructs a shared_ptr that shares ownership with r and stores
//!a copy of the pointer stored in r.
template<class Y>
explicit shared_ptr(weak_ptr<Y, VoidAllocator, Deleter> const & r)
@@ -170,19 +175,19 @@ class shared_ptr
template<class Y>
shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, ipcdetail::static_cast_tag)
: m_pn( pointer(static_cast<T*>(ipcdetail::to_raw_pointer(r.m_pn.to_raw_pointer())))
- , r.m_pn)
+ , r.m_pn)
{}
template<class Y>
shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, ipcdetail::const_cast_tag)
: m_pn( pointer(const_cast<T*>(ipcdetail::to_raw_pointer(r.m_pn.to_raw_pointer())))
- , r.m_pn)
+ , r.m_pn)
{}
template<class Y>
shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, ipcdetail::dynamic_cast_tag)
: m_pn( pointer(dynamic_cast<T*>(ipcdetail::to_raw_pointer(r.m_pn.to_raw_pointer())))
- , r.m_pn)
+ , r.m_pn)
{
if(!m_pn.to_raw_pointer()){ // need to allocate new counter -- the cast failed
m_pn = ipcdetail::shared_count<T, VoidAllocator, Deleter>();
@@ -218,15 +223,15 @@ class shared_ptr
//!This is equivalent to:
//!this_type().swap(*this);
void reset()
- {
- this_type().swap(*this);
+ {
+ this_type().swap(*this);
}
//!This is equivalent to:
//!this_type(p, a, d).swap(*this);
template<class Pointer>
void reset(const Pointer &p, const VoidAllocator &a = VoidAllocator(), const Deleter &d = Deleter())
- {
+ {
//Check that the pointer passed is of the same type that
//the pointer the allocator defines or it's a raw pointer
typedef typename boost::intrusive::
@@ -234,7 +239,7 @@ class shared_ptr
rebind_pointer<T>::type ParameterPointer;
BOOST_STATIC_ASSERT((ipcdetail::is_same<pointer, ParameterPointer>::value) ||
(ipcdetail::is_pointer<Pointer>::value));
- this_type(p, a, d).swap(*this);
+ this_type(p, a, d).swap(*this);
}
template<class Y>
@@ -248,12 +253,12 @@ class shared_ptr
reference operator* () const // never throws
{ BOOST_ASSERT(m_pn.to_raw_pointer() != 0); return *m_pn.to_raw_pointer(); }
- //!Returns the pointer pointing
+ //!Returns the pointer pointing
//!to the owned object
pointer operator-> () const // never throws
{ BOOST_ASSERT(m_pn.to_raw_pointer() != 0); return m_pn.to_raw_pointer(); }
- //!Returns the pointer pointing
+ //!Returns the pointer pointing
//!to the owned object
pointer get() const // never throws
{ return m_pn.to_raw_pointer(); }
@@ -292,7 +297,7 @@ class shared_ptr
/// @cond
- template<class T2, class A2, class Deleter2>
+ template<class T2, class A2, class Deleter2>
bool _internal_less(shared_ptr<T2, A2, Deleter2> const & rhs) const
{ return m_pn < rhs.m_pn; }
@@ -311,19 +316,19 @@ class shared_ptr
/// @endcond
}; // shared_ptr
-template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline
+template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline
bool operator==(shared_ptr<T, VoidAllocator, Deleter> const & a, shared_ptr<U, VoidAllocator2, Deleter2> const & b)
{ return a.get() == b.get(); }
-template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline
+template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline
bool operator!=(shared_ptr<T, VoidAllocator, Deleter> const & a, shared_ptr<U, VoidAllocator2, Deleter2> const & b)
{ return a.get() != b.get(); }
-template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline
+template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline
bool operator<(shared_ptr<T, VoidAllocator, Deleter> const & a, shared_ptr<U, VoidAllocator2, Deleter2> const & b)
{ return a._internal_less(b); }
-template<class T, class VoidAllocator, class Deleter> inline
+template<class T, class VoidAllocator, class Deleter> inline
void swap(shared_ptr<T, VoidAllocator, Deleter> & a, shared_ptr<T, VoidAllocator, Deleter> & b)
{ a.swap(b); }
@@ -331,11 +336,11 @@ template<class T, class VoidAllocator, class Deleter, class U> inline
shared_ptr<T, VoidAllocator, Deleter> static_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
{ return shared_ptr<T, VoidAllocator, Deleter>(r, ipcdetail::static_cast_tag()); }
-template<class T, class VoidAllocator, class Deleter, class U> inline
+template<class T, class VoidAllocator, class Deleter, class U> inline
shared_ptr<T, VoidAllocator, Deleter> const_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
{ return shared_ptr<T, VoidAllocator, Deleter>(r, ipcdetail::const_cast_tag()); }
-template<class T, class VoidAllocator, class Deleter, class U> inline
+template<class T, class VoidAllocator, class Deleter, class U> inline
shared_ptr<T, VoidAllocator, Deleter> dynamic_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
{ return shared_ptr<T, VoidAllocator, Deleter>(r, ipcdetail::dynamic_cast_tag()); }
@@ -346,7 +351,7 @@ T * to_raw_pointer(shared_ptr<T, VoidAllocator, Deleter> const & p)
// operator<<
template<class E, class T, class Y, class VoidAllocator, class Deleter> inline
-std::basic_ostream<E, T> & operator<<
+std::basic_ostream<E, T> & operator<<
(std::basic_ostream<E, T> & os, shared_ptr<Y, VoidAllocator, Deleter> const & p)
{ os << p.get(); return os; }
diff --git a/boost/interprocess/smart_ptr/unique_ptr.hpp b/boost/interprocess/smart_ptr/unique_ptr.hpp
index 547038b69b..89cdb1e6e2 100644
--- a/boost/interprocess/smart_ptr/unique_ptr.hpp
+++ b/boost/interprocess/smart_ptr/unique_ptr.hpp
@@ -272,20 +272,20 @@ class unique_ptr
//!Returns: A reference to the stored deleter.
//!
//!Throws: nothing.
- deleter_reference get_deleter()
+ deleter_reference get_deleter()
{ return ptr_.second(); }
//!Returns: A const reference to the stored deleter.
//!
//!Throws: nothing.
- deleter_const_reference get_deleter() const
+ deleter_const_reference get_deleter() const
{ return ptr_.second(); }
//!Returns: An unspecified value that, when used in boolean
//!contexts, is equivalent to get() != 0.
//!
//!Throws: nothing.
- operator int nat::*() const
+ operator int nat::*() const
{ return ptr_.first() ? &nat::for_bool_ : 0; }
//!Postcondition: get() == 0.
@@ -328,7 +328,7 @@ class unique_ptr
BOOST_MOVABLE_BUT_NOT_COPYABLE(unique_ptr)
template <class U, class E> unique_ptr(unique_ptr<U, E>&);
template <class U> unique_ptr(U&, typename ipcdetail::unique_ptr_error<U>::type = 0);
-
+
template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&);
template <class U> typename ipcdetail::unique_ptr_error<U>::type operator=(U&);
/// @endcond
@@ -539,7 +539,7 @@ template<class T, class ManagedMemory>
inline typename managed_unique_ptr<T, ManagedMemory>::type
make_managed_unique_ptr(T *constructed_object, ManagedMemory &managed_memory)
{
- return typename managed_unique_ptr<T, ManagedMemory>::type
+ return typename managed_unique_ptr<T, ManagedMemory>::type
(constructed_object, managed_memory.template get_deleter<T>());
}
diff --git a/boost/interprocess/smart_ptr/weak_ptr.hpp b/boost/interprocess/smart_ptr/weak_ptr.hpp
index 7126d055aa..5202ede91c 100644
--- a/boost/interprocess/smart_ptr/weak_ptr.hpp
+++ b/boost/interprocess/smart_ptr/weak_ptr.hpp
@@ -31,7 +31,7 @@ namespace boost{
namespace interprocess{
//!The weak_ptr class template stores a "weak reference" to an object
-//!that's already managed by a shared_ptr. To access the object, a weak_ptr
+//!that's already managed by a shared_ptr. To access the object, a weak_ptr
//!can be converted to a shared_ptr using the shared_ptr constructor or the
//!member function lock. When the last shared_ptr to the object goes away
//!and the object is deleted, the attempt to obtain a shared_ptr from the
@@ -99,11 +99,11 @@ class weak_ptr
template<class Y>
weak_ptr(weak_ptr<Y, A, D> const & r)
: m_pn(r.m_pn) // never throws
- {
+ {
//Construct a temporary shared_ptr so that nobody
//can destroy the value while constructing this
const shared_ptr<T, A, D> &ref = r.lock();
- m_pn.set_pointer(ref.get());
+ m_pn.set_pointer(ref.get());
}
//!Effects: If r is empty, constructs an empty weak_ptr; otherwise,
@@ -126,7 +126,7 @@ class weak_ptr
//!implied guarantees) via different means, without creating a temporary.
template<class Y>
weak_ptr & operator=(weak_ptr<Y, A, D> const & r) // never throws
- {
+ {
//Construct a temporary shared_ptr so that nobody
//can destroy the value while constructing this
const shared_ptr<T, A, D> &ref = r.lock();
@@ -174,7 +174,7 @@ class weak_ptr
//!testing purposes, not for production code.
long use_count() const // never throws
{ return m_pn.use_count(); }
-
+
//!Returns: Returns: use_count() == 0.
//!
//!Throws: nothing.
@@ -196,10 +196,10 @@ class weak_ptr
{ ipcdetail::do_swap(m_pn, other.m_pn); }
/// @cond
- template<class T2, class A2, class D2>
+ template<class T2, class A2, class D2>
bool _internal_less(weak_ptr<T2, A2, D2> const & rhs) const
{ return m_pn < rhs.m_pn; }
-
+
template<class Y>
void _internal_assign(const ipcdetail::shared_count<Y, A, D> & pn2)
{
@@ -216,7 +216,7 @@ class weak_ptr
/// @endcond
}; // weak_ptr
-template<class T, class A, class D, class U, class A2, class D2> inline
+template<class T, class A, class D, class U, class A2, class D2> inline
bool operator<(weak_ptr<T, A, D> const & a, weak_ptr<U, A2, D2> const & b)
{ return a._internal_less(b); }
diff --git a/boost/interprocess/streams/bufferstream.hpp b/boost/interprocess/streams/bufferstream.hpp
index 834b3d1e01..3ae9f5e2dc 100644
--- a/boost/interprocess/streams/bufferstream.hpp
+++ b/boost/interprocess/streams/bufferstream.hpp
@@ -42,7 +42,7 @@
#include <ios>
#include <istream>
#include <ostream>
-#include <string> // char traits
+#include <string> // char traits
#include <cstddef> // ptrdiff_t
#include <boost/assert.hpp>
#include <boost/interprocess/interprocess_fwd.hpp>
@@ -53,7 +53,7 @@ namespace boost { namespace interprocess {
//!a basic_xbufferstream. The elements are transmitted from a to a fixed
//!size buffer
template <class CharT, class CharTraits>
-class basic_bufferbuf
+class basic_bufferbuf
: public std::basic_streambuf<CharT, CharTraits>
{
public:
@@ -74,7 +74,7 @@ class basic_bufferbuf
//!Constructor. Assigns formatting buffer.
//!Does not throw.
- explicit basic_bufferbuf(CharT *buffer, std::size_t length,
+ explicit basic_bufferbuf(CharT *buffer, std::size_t length,
std::ios_base::openmode mode
= std::ios_base::in | std::ios_base::out)
: base_t(), m_mode(mode), m_buffer(buffer), m_length(length)
@@ -83,7 +83,7 @@ class basic_bufferbuf
virtual ~basic_bufferbuf(){}
public:
- //!Returns the pointer and size of the internal buffer.
+ //!Returns the pointer and size of the internal buffer.
//!Does not throw.
std::pair<CharT *, std::size_t> buffer() const
{ return std::pair<CharT *, std::size_t>(m_buffer, m_length); }
@@ -172,13 +172,13 @@ class basic_bufferbuf
}
virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir,
- std::ios_base::openmode mode
+ std::ios_base::openmode mode
= std::ios_base::in | std::ios_base::out)
{
bool in = false;
bool out = false;
-
- const std::ios_base::openmode inout =
+
+ const std::ios_base::openmode inout =
std::ios_base::in | std::ios_base::out;
if((mode & inout) == inout) {
@@ -205,7 +205,7 @@ class basic_bufferbuf
newoff = static_cast<std::streamoff>(m_length);
break;
case std::ios_base::cur:
- newoff = in ? static_cast<std::streamoff>(this->gptr() - this->eback())
+ newoff = in ? static_cast<std::streamoff>(this->gptr() - this->eback())
: static_cast<std::streamoff>(this->pptr() - this->pbase());
break;
default:
@@ -237,7 +237,7 @@ class basic_bufferbuf
return pos_type(off);
}
- virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode
+ virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode
= std::ios_base::in | std::ios_base::out)
{ return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode); }
@@ -277,7 +277,7 @@ class basic_ibufferstream
//!Does not throw.
basic_ibufferstream(const CharT *buffer, std::size_t length,
std::ios_base::openmode mode = std::ios_base::in)
- : basic_ios_t(), base_t(0),
+ : basic_ios_t(), base_t(0),
m_buf(const_cast<CharT*>(buffer), length, mode | std::ios_base::in)
{ basic_ios_t::init(&m_buf); }
@@ -289,12 +289,12 @@ class basic_ibufferstream
basic_bufferbuf<CharT, CharTraits>* rdbuf() const
{ return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&m_buf); }
- //!Returns the pointer and size of the internal buffer.
+ //!Returns the pointer and size of the internal buffer.
//!Does not throw.
std::pair<const CharT *, std::size_t> buffer() const
{ return m_buf.buffer(); }
- //!Sets the underlying buffer to a new value. Resets
+ //!Sets the underlying buffer to a new value. Resets
//!stream position. Does not throw.
void buffer(const CharT *buffer, std::size_t length)
{ m_buf.buffer(const_cast<CharT*>(buffer), length); }
@@ -335,7 +335,7 @@ class basic_obufferstream
//!Does not throw.
basic_obufferstream(CharT *buffer, std::size_t length,
std::ios_base::openmode mode = std::ios_base::out)
- : basic_ios_t(), base_t(0),
+ : basic_ios_t(), base_t(0),
m_buf(buffer, length, mode | std::ios_base::out)
{ basic_ios_t::init(&m_buf); }
@@ -347,12 +347,12 @@ class basic_obufferstream
basic_bufferbuf<CharT, CharTraits>* rdbuf() const
{ return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&m_buf); }
- //!Returns the pointer and size of the internal buffer.
+ //!Returns the pointer and size of the internal buffer.
//!Does not throw.
std::pair<CharT *, std::size_t> buffer() const
{ return m_buf.buffer(); }
- //!Sets the underlying buffer to a new value. Resets
+ //!Sets the underlying buffer to a new value. Resets
//!stream position. Does not throw.
void buffer(CharT *buffer, std::size_t length)
{ m_buf.buffer(buffer, length); }
@@ -367,7 +367,7 @@ class basic_obufferstream
//!A basic_iostream class that uses a fixed size character buffer
//!as its formatting buffer.
template <class CharT, class CharTraits>
-class basic_bufferstream
+class basic_bufferstream
: public std::basic_iostream<CharT, CharTraits>
{
@@ -388,7 +388,7 @@ class basic_bufferstream
public:
//!Constructor.
//!Does not throw.
- basic_bufferstream(std::ios_base::openmode mode
+ basic_bufferstream(std::ios_base::openmode mode
= std::ios_base::in | std::ios_base::out)
: basic_ios_t(), base_t(0), m_buf(mode)
{ basic_ios_t::init(&m_buf); }
@@ -409,12 +409,12 @@ class basic_bufferstream
basic_bufferbuf<CharT, CharTraits>* rdbuf() const
{ return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&m_buf); }
- //!Returns the pointer and size of the internal buffer.
+ //!Returns the pointer and size of the internal buffer.
//!Does not throw.
std::pair<CharT *, std::size_t> buffer() const
{ return m_buf.buffer(); }
- //!Sets the underlying buffer to a new value. Resets
+ //!Sets the underlying buffer to a new value. Resets
//!stream position. Does not throw.
void buffer(CharT *buffer, std::size_t length)
{ m_buf.buffer(buffer, length); }
diff --git a/boost/interprocess/streams/vectorstream.hpp b/boost/interprocess/streams/vectorstream.hpp
index 83041f2b2e..3cee7200ab 100644
--- a/boost/interprocess/streams/vectorstream.hpp
+++ b/boost/interprocess/streams/vectorstream.hpp
@@ -30,7 +30,7 @@
//!This file defines basic_vectorbuf, basic_ivectorstream,
//!basic_ovectorstream, and basic_vectorstreamclasses. These classes
//!represent streamsbufs and streams whose sources or destinations are
-//!STL-like vectors that can be swapped with external vectors to avoid
+//!STL-like vectors that can be swapped with external vectors to avoid
//!unnecessary allocations/copies.
#ifndef BOOST_INTERPROCESS_VECTORSTREAM_HPP
@@ -43,7 +43,7 @@
#include <ios>
#include <istream>
#include <ostream>
-#include <string> // char traits
+#include <string> // char traits
#include <cstddef> // ptrdiff_t
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/assert.hpp>
@@ -51,9 +51,9 @@
namespace boost { namespace interprocess {
//!A streambuf class that controls the transmission of elements to and from
-//!a basic_ivectorstream, basic_ovectorstream or basic_vectorstream.
+//!a basic_ivectorstream, basic_ovectorstream or basic_vectorstream.
//!It holds a character vector specified by CharVector template parameter
-//!as its formatting buffer. The vector must have contiguous storage, like
+//!as its formatting buffer. The vector must have contiguous storage, like
//!std::vector, boost::interprocess::vector or boost::interprocess::basic_string
template <class CharVector, class CharTraits>
class basic_vectorbuf
@@ -96,11 +96,11 @@ class basic_vectorbuf
public:
- //!Swaps the underlying vector with the passed vector.
+ //!Swaps the underlying vector with the passed vector.
//!This function resets the read/write position in the stream.
//!Does not throw.
void swap_vector(vector_type &vect)
- {
+ {
if (this->m_mode & std::ios_base::out){
//Update high water if necessary
//And resize vector to remove extra size
@@ -118,8 +118,8 @@ class basic_vectorbuf
//!Returns a const reference to the internal vector.
//!Does not throw.
- const vector_type &vector() const
- {
+ const vector_type &vector() const
+ {
if (this->m_mode & std::ios_base::out){
if (mp_high_water < base_t::pptr()){
//Restore the vector's size if necessary
@@ -137,13 +137,13 @@ class basic_vectorbuf
const_cast<basic_vectorbuf*>(this)->base_t::pbump(old_pos);
}
}
- return m_vect;
+ return m_vect;
}
//!Preallocates memory from the internal vector.
//!Resets the stream to the first position.
//!Throws if the internals vector's memory allocation throws.
- void reserve(typename vector_type::size_type size)
+ void reserve(typename vector_type::size_type size)
{
if (this->m_mode & std::ios_base::out && size > m_vect.size()){
typename vector_type::difference_type write_pos = base_t::pptr() - base_t::pbase();
@@ -282,7 +282,7 @@ class basic_vectorbuf
}
virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir,
- std::ios_base::openmode mode
+ std::ios_base::openmode mode
= std::ios_base::in | std::ios_base::out)
{
//Get seek mode
@@ -325,7 +325,7 @@ class basic_vectorbuf
newoff = limit;
break;
case std::ios_base::cur:
- newoff = in ? static_cast<std::streamoff>(this->gptr() - this->eback())
+ newoff = in ? static_cast<std::streamoff>(this->gptr() - this->eback())
: static_cast<std::streamoff>(this->pptr() - this->pbase());
break;
default:
@@ -350,7 +350,7 @@ class basic_vectorbuf
return pos_type(newoff);
}
- virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode
+ virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode
= std::ios_base::in | std::ios_base::out)
{ return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode); }
@@ -413,7 +413,7 @@ class basic_ivectorstream
basic_vectorbuf<CharVector, CharTraits>* rdbuf() const
{ return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&m_buf()); }
- //!Swaps the underlying vector with the passed vector.
+ //!Swaps the underlying vector with the passed vector.
//!This function resets the read position in the stream.
//!Does not throw.
void swap_vector(vector_type &vect)
@@ -421,18 +421,18 @@ class basic_ivectorstream
//!Returns a const reference to the internal vector.
//!Does not throw.
- const vector_type &vector() const
+ const vector_type &vector() const
{ return m_buf().vector(); }
//!Calls reserve() method of the internal vector.
//!Resets the stream to the first position.
//!Throws if the internals vector's reserve throws.
- void reserve(typename vector_type::size_type size)
+ void reserve(typename vector_type::size_type size)
{ m_buf().reserve(size); }
//!Calls clear() method of the internal vector.
//!Resets the stream to the first position.
- void clear()
+ void clear()
{ m_buf().clear(); }
};
@@ -488,7 +488,7 @@ class basic_ovectorstream
basic_vectorbuf<CharVector, CharTraits>* rdbuf() const
{ return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&m_buf()); }
- //!Swaps the underlying vector with the passed vector.
+ //!Swaps the underlying vector with the passed vector.
//!This function resets the write position in the stream.
//!Does not throw.
void swap_vector(vector_type &vect)
@@ -496,13 +496,13 @@ class basic_ovectorstream
//!Returns a const reference to the internal vector.
//!Does not throw.
- const vector_type &vector() const
+ const vector_type &vector() const
{ return m_buf().vector(); }
//!Calls reserve() method of the internal vector.
//!Resets the stream to the first position.
//!Throws if the internals vector's reserve throws.
- void reserve(typename vector_type::size_type size)
+ void reserve(typename vector_type::size_type size)
{ m_buf().reserve(size); }
};
@@ -534,7 +534,7 @@ class basic_vectorstream
public:
//!Constructor. Throws if vector_type default
//!constructor throws.
- basic_vectorstream(std::ios_base::openmode mode
+ basic_vectorstream(std::ios_base::openmode mode
= std::ios_base::in | std::ios_base::out)
: basic_ios_t(), base_t(0), m_buf(mode)
{ basic_ios_t::init(&m_buf); }
@@ -554,7 +554,7 @@ class basic_vectorstream
basic_vectorbuf<CharVector, CharTraits>* rdbuf() const
{ return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&m_buf); }
- //!Swaps the underlying vector with the passed vector.
+ //!Swaps the underlying vector with the passed vector.
//!This function resets the read/write position in the stream.
//!Does not throw.
void swap_vector(vector_type &vect)
@@ -562,18 +562,18 @@ class basic_vectorstream
//!Returns a const reference to the internal vector.
//!Does not throw.
- const vector_type &vector() const
+ const vector_type &vector() const
{ return m_buf.vector(); }
//!Calls reserve() method of the internal vector.
//!Resets the stream to the first position.
//!Throws if the internals vector's reserve throws.
- void reserve(typename vector_type::size_type size)
+ void reserve(typename vector_type::size_type size)
{ m_buf.reserve(size); }
//!Calls clear() method of the internal vector.
//!Resets the stream to the first position.
- void clear()
+ void clear()
{ m_buf.clear(); }
/// @cond
diff --git a/boost/interprocess/sync/detail/condition_algorithm_8a.hpp b/boost/interprocess/sync/detail/condition_algorithm_8a.hpp
new file mode 100644
index 0000000000..eaad671cdf
--- /dev/null
+++ b/boost/interprocess/sync/detail/condition_algorithm_8a.hpp
@@ -0,0 +1,316 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_DETAIL_CONDITION_ALGORITHM_8A_HPP
+#define BOOST_INTERPROCESS_DETAIL_CONDITION_ALGORITHM_8A_HPP
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <limits>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+//
+// Condition variable algorithm taken from pthreads-win32 discussion.
+//
+// The algorithm was developed by Alexander Terekhov in colaboration with
+// Louis Thomas.
+//
+// Algorithm 8a / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL
+//
+// semBlockLock - bin.semaphore
+// semBlockQueue - semaphore
+// mtxExternal - mutex or CS
+// mtxUnblockLock - mutex or CS
+// nWaitersGone - int
+// nWaitersBlocked - int
+// nWaitersToUnblock - int
+//
+// wait( timeout ) {
+//
+// [auto: register int result ] // error checking omitted
+// [auto: register int nSignalsWasLeft ]
+// [auto: register int nWaitersWasGone ]
+//
+// sem_wait( semBlockLock );
+// nWaitersBlocked++;
+// sem_post( semBlockLock );
+//
+// unlock( mtxExternal );
+// bTimedOut = sem_wait( semBlockQueue,timeout );
+//
+// lock( mtxUnblockLock );
+// if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) {
+// if ( bTimedOut ) { // timeout (or canceled)
+// if ( 0 != nWaitersBlocked ) {
+// nWaitersBlocked--;
+// }
+// else {
+// nWaitersGone++; // count spurious wakeups.
+// }
+// }
+// if ( 0 == --nWaitersToUnblock ) {
+// if ( 0 != nWaitersBlocked ) {
+// sem_post( semBlockLock ); // open the gate.
+// nSignalsWasLeft = 0; // do not open the gate
+// // below again.
+// }
+// else if ( 0 != (nWaitersWasGone = nWaitersGone) ) {
+// nWaitersGone = 0;
+// }
+// }
+// }
+// else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or
+// // spurious semaphore :-)
+// sem_wait( semBlockLock );
+// nWaitersBlocked -= nWaitersGone; // something is going on here
+// // - test of timeouts? :-)
+// sem_post( semBlockLock );
+// nWaitersGone = 0;
+// }
+// unlock( mtxUnblockLock );
+//
+// if ( 1 == nSignalsWasLeft ) {
+// if ( 0 != nWaitersWasGone ) {
+// // sem_adjust( semBlockQueue,-nWaitersWasGone );
+// while ( nWaitersWasGone-- ) {
+// sem_wait( semBlockQueue ); // better now than spurious later
+// }
+// } sem_post( semBlockLock ); // open the gate
+// }
+//
+// lock( mtxExternal );
+//
+// return ( bTimedOut ) ? ETIMEOUT : 0;
+// }
+//
+// signal(bAll) {
+//
+// [auto: register int result ]
+// [auto: register int nSignalsToIssue]
+//
+// lock( mtxUnblockLock );
+//
+// if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
+// if ( 0 == nWaitersBlocked ) { // NO-OP
+// return unlock( mtxUnblockLock );
+// }
+// if (bAll) {
+// nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked;
+// nWaitersBlocked = 0;
+// }
+// else {
+// nSignalsToIssue = 1;
+// nWaitersToUnblock++;
+// nWaitersBlocked--;
+// }
+// }
+// else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
+// sem_wait( semBlockLock ); // close the gate
+// if ( 0 != nWaitersGone ) {
+// nWaitersBlocked -= nWaitersGone;
+// nWaitersGone = 0;
+// }
+// if (bAll) {
+// nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked;
+// nWaitersBlocked = 0;
+// }
+// else {
+// nSignalsToIssue = nWaitersToUnblock = 1;
+// nWaitersBlocked--;
+// }
+// }
+// else { // NO-OP
+// return unlock( mtxUnblockLock );
+// }
+//
+// unlock( mtxUnblockLock );
+// sem_post( semBlockQueue,nSignalsToIssue );
+// return result;
+// }
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+
+// Required interface for ConditionMembers
+// class ConditionMembers
+// {
+// typedef implementation_defined semaphore_type;
+// typedef implementation_defined mutex_type;
+// typedef implementation_defined integer_type;
+//
+// integer_type &get_nwaiters_blocked()
+// integer_type &get_nwaiters_gone()
+// integer_type &get_nwaiters_to_unblock()
+// semaphore_type &get_sem_block_queue()
+// semaphore_type &get_sem_block_lock()
+// mutex_type &get_mtx_unblock_lock()
+// };
+//
+template<class ConditionMembers>
+class condition_algorithm_8a
+{
+ private:
+ condition_algorithm_8a();
+ ~condition_algorithm_8a();
+ condition_algorithm_8a(const condition_algorithm_8a &);
+ condition_algorithm_8a &operator=(const condition_algorithm_8a &);
+
+ typedef typename ConditionMembers::semaphore_type semaphore_type;
+ typedef typename ConditionMembers::mutex_type mutex_type;
+ typedef typename ConditionMembers::integer_type integer_type;
+
+ // nwaiters_blocked == 0
+ // nwaiters_gone() == 0
+ // nwaiters_to_unblock == 0
+ // sem_block_queue() == initial count 0
+ // sem_block_lock() == initial count 1
+ // mtx_unblock_lock (unlocked)
+
+ public:
+ template<class InterprocessMutex>
+ static bool wait (ConditionMembers &data, bool timeout_enabled, const boost::posix_time::ptime &abs_time, InterprocessMutex &mut);
+ static void signal(ConditionMembers &data, bool broadcast);
+};
+
+template<class ConditionMembers>
+inline void condition_algorithm_8a<ConditionMembers>::signal(ConditionMembers &data, bool broadcast)
+{
+ integer_type nsignals_to_issue;
+
+ {
+ scoped_lock<mutex_type> locker(data.get_mtx_unblock_lock());
+
+ if ( 0 != data.get_nwaiters_to_unblock() ) { // the gate is closed!!!
+ if ( 0 == data.get_nwaiters_blocked() ) { // NO-OP
+ //locker's destructor triggers data.get_mtx_unblock_lock().unlock()
+ return;
+ }
+ if (broadcast) {
+ data.get_nwaiters_to_unblock() += nsignals_to_issue = data.get_nwaiters_blocked();
+ data.get_nwaiters_blocked() = 0;
+ }
+ else {
+ nsignals_to_issue = 1;
+ data.get_nwaiters_to_unblock()++;
+ data.get_nwaiters_blocked()--;
+ }
+ }
+ else if ( data.get_nwaiters_blocked() > data.get_nwaiters_gone() ) { // HARMLESS RACE CONDITION!
+ data.get_sem_block_lock().wait(); // close the gate
+ if ( 0 != data.get_nwaiters_gone() ) {
+ data.get_nwaiters_blocked() -= data.get_nwaiters_gone();
+ data.get_nwaiters_gone() = 0;
+ }
+ if (broadcast) {
+ nsignals_to_issue = data.get_nwaiters_to_unblock() = data.get_nwaiters_blocked();
+ data.get_nwaiters_blocked() = 0;
+ }
+ else {
+ nsignals_to_issue = data.get_nwaiters_to_unblock() = 1;
+ data.get_nwaiters_blocked()--;
+ }
+ }
+ else { // NO-OP
+ //locker's destructor triggers data.get_mtx_unblock_lock().unlock()
+ return;
+ }
+ //locker's destructor triggers data.get_mtx_unblock_lock().unlock()
+ }
+ data.get_sem_block_queue().post(nsignals_to_issue);
+}
+
+template<class ConditionMembers>
+template<class InterprocessMutex>
+inline bool condition_algorithm_8a<ConditionMembers>::wait
+ (ConditionMembers &data, bool tout_enabled, const boost::posix_time::ptime &abs_time, InterprocessMutex &mtxExternal)
+{
+ //Initialize to avoid warnings
+ integer_type nsignals_was_left = 0;
+ integer_type nwaiters_was_gone = 0;
+
+ data.get_sem_block_lock().wait();
+ ++data.get_nwaiters_blocked();
+ data.get_sem_block_lock().post();
+
+ struct scoped_unlock
+ {
+ InterprocessMutex & mut;
+ scoped_unlock(InterprocessMutex & m)
+ : mut(m)
+ { m.unlock(); }
+
+ ~scoped_unlock()
+ { mut.lock(); }
+ } unlocker(mtxExternal);
+
+
+ bool bTimedOut = tout_enabled ? !data.get_sem_block_queue().timed_wait(abs_time) : (data.get_sem_block_queue().wait(), false);
+
+ {
+ scoped_lock<mutex_type> locker(data.get_mtx_unblock_lock());
+ if ( 0 != (nsignals_was_left = data.get_nwaiters_to_unblock()) ) {
+ if ( bTimedOut ) { // timeout (or canceled)
+ if ( 0 != data.get_nwaiters_blocked() ) {
+ data.get_nwaiters_blocked()--;
+ }
+ else {
+ data.get_nwaiters_gone()++; // count spurious wakeups.
+ }
+ }
+ if ( 0 == --data.get_nwaiters_to_unblock() ) {
+ if ( 0 != data.get_nwaiters_blocked() ) {
+ data.get_sem_block_lock().post(); // open the gate.
+ nsignals_was_left = 0; // do not open the gate below again.
+ }
+ else if ( 0 != (nwaiters_was_gone = data.get_nwaiters_gone()) ) {
+ data.get_nwaiters_gone() = 0;
+ }
+ }
+ }
+ else if ( (std::numeric_limits<integer_type>::max)()/2
+ == ++data.get_nwaiters_gone() ) { // timeout/canceled or spurious semaphore :-)
+ data.get_sem_block_lock().wait();
+ data.get_nwaiters_blocked() -= data.get_nwaiters_gone(); // something is going on here - test of timeouts? :-)
+ data.get_sem_block_lock().post();
+ data.get_nwaiters_gone() = 0;
+ }
+ //locker's destructor triggers data.get_mtx_unblock_lock().unlock()
+ }
+
+ if ( 1 == nsignals_was_left ) {
+ if ( 0 != nwaiters_was_gone ) {
+ // sem_adjust( data.get_sem_block_queue(),-nwaiters_was_gone );
+ while ( nwaiters_was_gone-- ) {
+ data.get_sem_block_queue().wait(); // better now than spurious later
+ }
+ }
+ data.get_sem_block_lock().post(); // open the gate
+ }
+
+ //mtxExternal.lock(); called from unlocker
+
+ return ( bTimedOut ) ? false : true;
+}
+
+} //namespace ipcdetail
+} //namespace interprocess
+} //namespace boost
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_DETAIL_CONDITION_ALGORITHM_8A_HPP
diff --git a/boost/interprocess/sync/file_lock.hpp b/boost/interprocess/sync/file_lock.hpp
index a60b814a4f..e0f75465fb 100644
--- a/boost/interprocess/sync/file_lock.hpp
+++ b/boost/interprocess/sync/file_lock.hpp
@@ -53,21 +53,21 @@ class file_lock
//!exist or there are no operating system resources.
file_lock(const char *name);
- //!Moves the ownership of "moved"'s file mapping object to *this.
- //!After the call, "moved" does not represent any file mapping object.
+ //!Moves the ownership of "moved"'s file mapping object to *this.
+ //!After the call, "moved" does not represent any file mapping object.
//!Does not throw
file_lock(BOOST_RV_REF(file_lock) moved)
: m_file_hnd(file_handle_t(ipcdetail::invalid_file()))
{ this->swap(moved); }
//!Moves the ownership of "moved"'s file mapping to *this.
- //!After the call, "moved" does not represent any file mapping.
+ //!After the call, "moved" does not represent any file mapping.
//!Does not throw
file_lock &operator=(BOOST_RV_REF(file_lock) moved)
- {
+ {
file_lock tmp(boost::move(moved));
this->swap(tmp);
- return *this;
+ return *this;
}
//!Closes a file lock. Does not throw.
@@ -81,7 +81,7 @@ class file_lock
m_file_hnd = other.m_file_hnd;
other.m_file_hnd = tmp;
}
-
+
//Exclusive locking
//!Effects: The calling thread tries to obtain exclusive ownership of the mutex,
@@ -101,12 +101,12 @@ class file_lock
//!Effects: The calling thread tries to acquire exclusive ownership of the mutex
//! waiting if necessary until no other thread has exclusive, or sharable
//! ownership of the mutex or abs_time is reached.
- //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: interprocess_exception on error.
bool timed_lock(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have exclusive ownership of the mutex.
- //!Effects: The calling thread releases the exclusive ownership of the mutex.
+ //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Effects: The calling thread releases the exclusive ownership of the mutex.
//!Throws: An exception derived from interprocess_exception on error.
void unlock();
@@ -120,21 +120,21 @@ class file_lock
//!Effects: The calling thread tries to acquire sharable ownership of the mutex
//! without waiting. If no other thread has exclusive ownership of the
- //! mutex this succeeds.
+ //! mutex this succeeds.
//!Returns: If it can acquire sharable ownership immediately returns true. If it
- //! has to wait, returns false.
+ //! has to wait, returns false.
//!Throws: interprocess_exception on error.
bool try_lock_sharable();
//!Effects: The calling thread tries to acquire sharable ownership of the mutex
//! waiting if necessary until no other thread has exclusive ownership of
- //! the mutex or abs_time is reached.
- //!Returns: If acquires sharable ownership, returns true. Otherwise returns false.
+ //! the mutex or abs_time is reached.
+ //!Returns: If acquires sharable ownership, returns true. Otherwise returns false.
//!Throws: interprocess_exception on error.
bool timed_lock_sharable(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have sharable ownership of the mutex.
- //!Effects: The calling thread releases the sharable ownership of the mutex.
+ //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Effects: The calling thread releases the sharable ownership of the mutex.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_sharable();
/// @cond
@@ -171,7 +171,7 @@ class file_lock
bool timed_acquire_file_lock_sharable
(file_handle_t hnd, bool &acquired, const boost::posix_time::ptime &abs_time)
- {
+ {
//Obtain current count and target time
boost::posix_time::ptime now = microsec_clock::universal_time();
using namespace boost::detail;
diff --git a/boost/interprocess/sync/interprocess_condition.hpp b/boost/interprocess/sync/interprocess_condition.hpp
index b0e74fc342..9d0bea640e 100644
--- a/boost/interprocess/sync/interprocess_condition.hpp
+++ b/boost/interprocess/sync/interprocess_condition.hpp
@@ -30,9 +30,9 @@
#include <boost/interprocess/sync/posix/condition.hpp>
#define BOOST_INTERPROCESS_USE_POSIX
//Experimental...
-//#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
-// #include <boost/interprocess/sync/windows/condition.hpp>
-// #define BOOST_INTERPROCESS_USE_WINDOWS
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/condition.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
#elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
#include <boost/interprocess/sync/spin/condition.hpp>
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
@@ -70,7 +70,7 @@ class interprocess_condition
//!liberating system resources.
~interprocess_condition(){}
- //!If there is a thread waiting on *this, change that
+ //!If there is a thread waiting on *this, change that
//!thread's state to ready. Otherwise there is no effect.
void notify_one()
{ m_condition.notify_one(); }
@@ -80,8 +80,8 @@ class interprocess_condition
void notify_all()
{ m_condition.notify_all(); }
- //!Releases the lock on the interprocess_mutex object associated with lock, blocks
- //!the current thread of execution until readied by a call to
+ //!Releases the lock on the interprocess_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
//!this->notify_one() or this->notify_all(), and then reacquires the lock.
template <typename L>
void wait(L& lock)
@@ -103,9 +103,9 @@ class interprocess_condition
this->do_wait(*lock.mutex());
}
- //!Releases the lock on the interprocess_mutex object associated with lock, blocks
- //!the current thread of execution until readied by a call to
- //!this->notify_one() or this->notify_all(), or until time abs_time is reached,
+ //!Releases the lock on the interprocess_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
+ //!this->notify_one() or this->notify_all(), or until time abs_time is reached,
//!and then reacquires the lock.
//!Returns: false if time abs_time is reached, otherwise true.
template <typename L>
@@ -120,8 +120,8 @@ class interprocess_condition
return this->do_timed_wait(abs_time, *lock.mutex());
}
- //!The same as: while (!pred()) {
- //! if (!timed_wait(lock, abs_time)) return pred();
+ //!The same as: while (!pred()) {
+ //! if (!timed_wait(lock, abs_time)) return pred();
//! } return true;
template <typename L, typename Pr>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
diff --git a/boost/interprocess/sync/interprocess_mutex.hpp b/boost/interprocess/sync/interprocess_mutex.hpp
index 478cf78cc3..8110c8472b 100644
--- a/boost/interprocess/sync/interprocess_mutex.hpp
+++ b/boost/interprocess/sync/interprocess_mutex.hpp
@@ -31,9 +31,9 @@
#include <boost/interprocess/sync/posix/mutex.hpp>
#define BOOST_INTERPROCESS_USE_POSIX
//Experimental...
-//#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
-// #include <boost/interprocess/sync/windows/mutex.hpp>
-// #define BOOST_INTERPROCESS_USE_WINDOWS
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/mutex.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
#elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
#include <boost/interprocess/sync/spin/mutex.hpp>
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
@@ -61,7 +61,7 @@ namespace interprocess {
class interprocess_condition;
-//!Wraps a interprocess_mutex that can be placed in shared memory and can be
+//!Wraps a interprocess_mutex that can be placed in shared memory and can be
//!shared between processes. Allows timed lock tries
class interprocess_mutex
{
@@ -98,9 +98,9 @@ class interprocess_mutex
//!Effects: The calling thread will try to obtain exclusive ownership of the
//! mutex if it can do so in until the specified time is reached. If the
//! mutex supports recursive locking, the mutex must be unlocked the same
- //! number of times it is locked.
+ //! number of times it is locked.
//!Returns: If the thread acquires ownership of the mutex, returns true, if
- //! the timeout expires returns false.
+ //! the timeout expires returns false.
//!Throws: interprocess_exception on error.
bool timed_lock(const boost::posix_time::ptime &abs_time);
diff --git a/boost/interprocess/sync/interprocess_recursive_mutex.hpp b/boost/interprocess/sync/interprocess_recursive_mutex.hpp
index 308819ff27..3079108645 100644
--- a/boost/interprocess/sync/interprocess_recursive_mutex.hpp
+++ b/boost/interprocess/sync/interprocess_recursive_mutex.hpp
@@ -43,9 +43,9 @@
#include <boost/interprocess/sync/posix/recursive_mutex.hpp>
#define BOOST_INTERPROCESS_USE_POSIX
//Experimental...
-//#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
-// #include <boost/interprocess/sync/windows/recursive_mutex.hpp>
-// #define BOOST_INTERPROCESS_USE_WINDOWS
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/recursive_mutex.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
#elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
#include <boost/interprocess/sync/spin/recursive_mutex.hpp>
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
@@ -72,8 +72,8 @@ class mutex_traits;
namespace boost {
namespace interprocess {
-//!Wraps a interprocess_mutex that can be placed in shared memory and can be
-//!shared between processes. Allows several locking calls by the same
+//!Wraps a interprocess_mutex that can be placed in shared memory and can be
+//!shared between processes. Allows several locking calls by the same
//!process. Allows timed lock tries
class interprocess_recursive_mutex
{
@@ -99,7 +99,7 @@ class interprocess_recursive_mutex
//!Throws: interprocess_exception on error.
void lock();
- //!Tries to lock the interprocess_mutex, returns false when interprocess_mutex
+ //!Tries to lock the interprocess_mutex, returns false when interprocess_mutex
//!is already locked, returns true when success. The mutex must be unlocked
//!the same number of times it is locked.
//!Throws: interprocess_exception if a severe error is found
diff --git a/boost/interprocess/sync/interprocess_semaphore.hpp b/boost/interprocess/sync/interprocess_semaphore.hpp
index 4ffcdcf691..2a2f34fdcf 100644
--- a/boost/interprocess/sync/interprocess_semaphore.hpp
+++ b/boost/interprocess/sync/interprocess_semaphore.hpp
@@ -29,9 +29,9 @@
#include <boost/interprocess/sync/posix/semaphore.hpp>
#define BOOST_INTERPROCESS_USE_POSIX
//Experimental...
-//#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
-// #include <boost/interprocess/sync/windows/semaphore.hpp>
-// #define BOOST_INTERPROCESS_USE_WINDOWS
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/semaphore.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
#elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
#include <boost/interprocess/sync/spin/semaphore.hpp>
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
@@ -45,7 +45,7 @@
namespace boost {
namespace interprocess {
-//!Wraps a interprocess_semaphore that can be placed in shared memory and can be
+//!Wraps a interprocess_semaphore that can be placed in shared memory and can be
//!shared between processes. Allows timed lock tries
class interprocess_semaphore
{
@@ -55,7 +55,7 @@ class interprocess_semaphore
interprocess_semaphore &operator=(const interprocess_semaphore &);
/// @endcond
public:
- //!Creates a interprocess_semaphore with the given initial count.
+ //!Creates a interprocess_semaphore with the given initial count.
//!interprocess_exception if there is an error.*/
interprocess_semaphore(unsigned int initialCount);
@@ -69,7 +69,7 @@ class interprocess_semaphore
void post();
//!Decrements the interprocess_semaphore. If the interprocess_semaphore value is not greater than zero,
- //!then the calling process/thread blocks until it can decrement the counter.
+ //!then the calling process/thread blocks until it can decrement the counter.
//!If there is an error an interprocess_exception exception is thrown.
void wait();
@@ -95,7 +95,7 @@ class interprocess_semaphore
#elif defined(BOOST_INTERPROCESS_USE_WINDOWS)
#undef BOOST_INTERPROCESS_USE_WINDOWS
ipcdetail::windows_semaphore m_sem;
- #else
+ #else
#undef BOOST_INTERPROCESS_USE_POSIX
ipcdetail::posix_semaphore m_sem;
#endif //#if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
diff --git a/boost/interprocess/sync/interprocess_upgradable_mutex.hpp b/boost/interprocess/sync/interprocess_upgradable_mutex.hpp
index 048407f4b3..8d5a452626 100644
--- a/boost/interprocess/sync/interprocess_upgradable_mutex.hpp
+++ b/boost/interprocess/sync/interprocess_upgradable_mutex.hpp
@@ -30,7 +30,7 @@
namespace boost {
namespace interprocess {
-//!Wraps a interprocess_upgradable_mutex that can be placed in shared memory and can be
+//!Wraps a interprocess_upgradable_mutex that can be placed in shared memory and can be
//!shared between processes. Allows timed lock tries
class interprocess_upgradable_mutex
{
@@ -67,13 +67,13 @@ class interprocess_upgradable_mutex
//!Effects: The calling thread tries to acquire exclusive ownership of the mutex
//! waiting if necessary until no other thread has exclusive, sharable or
- //! upgradable ownership of the mutex or abs_time is reached.
- //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //! upgradable ownership of the mutex or abs_time is reached.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: interprocess_exception on error.
bool timed_lock(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have exclusive ownership of the mutex.
- //!Effects: The calling thread releases the exclusive ownership of the mutex.
+ //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Effects: The calling thread releases the exclusive ownership of the mutex.
//!Throws: An exception derived from interprocess_exception on error.
void unlock();
@@ -87,21 +87,21 @@ class interprocess_upgradable_mutex
//!Effects: The calling thread tries to acquire sharable ownership of the mutex
//! without waiting. If no other thread has exclusive ownership
- //! of the mutex this succeeds.
+ //! of the mutex this succeeds.
//!Returns: If it can acquire sharable ownership immediately returns true. If it
- //! has to wait, returns false.
+ //! has to wait, returns false.
//!Throws: interprocess_exception on error.
bool try_lock_sharable();
//!Effects: The calling thread tries to acquire sharable ownership of the mutex
//! waiting if necessary until no other thread has exclusive
- //! ownership of the mutex or abs_time is reached.
- //!Returns: If acquires sharable ownership, returns true. Otherwise returns false.
+ //! ownership of the mutex or abs_time is reached.
+ //!Returns: If acquires sharable ownership, returns true. Otherwise returns false.
//!Throws: interprocess_exception on error.
bool timed_lock_sharable(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have sharable ownership of the mutex.
- //!Effects: The calling thread releases the sharable ownership of the mutex.
+ //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Effects: The calling thread releases the sharable ownership of the mutex.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_sharable();
@@ -115,7 +115,7 @@ class interprocess_upgradable_mutex
//!Effects: The calling thread tries to acquire upgradable ownership of the mutex
//! without waiting. If no other thread has exclusive or upgradable ownership
- //! of the mutex this succeeds.
+ //! of the mutex this succeeds.
//!Returns: If it can acquire upgradable ownership immediately returns true.
//! If it has to wait, returns false.
//!Throws: interprocess_exception on error.
@@ -124,74 +124,74 @@ class interprocess_upgradable_mutex
//!Effects: The calling thread tries to acquire upgradable ownership of the mutex
//! waiting if necessary until no other thread has exclusive or upgradable
//! ownership of the mutex or abs_time is reached.
- //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
+ //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
//!Throws: interprocess_exception on error.
bool timed_lock_upgradable(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have upgradable ownership of the mutex.
- //!Effects: The calling thread releases the upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Effects: The calling thread releases the upgradable ownership of the mutex.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable();
//Demotions
- //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Precondition: The thread must have exclusive ownership of the mutex.
//!Effects: The thread atomically releases exclusive ownership and acquires
- //! upgradable ownership. This operation is non-blocking.
+ //! upgradable ownership. This operation is non-blocking.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_and_lock_upgradable();
- //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Precondition: The thread must have exclusive ownership of the mutex.
//!Effects: The thread atomically releases exclusive ownership and acquires
- //! sharable ownership. This operation is non-blocking.
+ //! sharable ownership. This operation is non-blocking.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_and_lock_sharable();
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and acquires
- //! sharable ownership. This operation is non-blocking.
+ //! sharable ownership. This operation is non-blocking.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable_and_lock_sharable();
//Promotions
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and acquires
//! exclusive ownership. This operation will block until all threads with
- //! sharable ownership release their sharable lock.
+ //! sharable ownership release their sharable lock.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable_and_lock();
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and tries to
//! acquire exclusive ownership. This operation will fail if there are threads
- //! with sharable ownership, but it will maintain upgradable ownership.
+ //! with sharable ownership, but it will maintain upgradable ownership.
//!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_upgradable_and_lock();
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and tries to acquire
//! exclusive ownership, waiting if necessary until abs_time. This operation will
//! fail if there are threads with sharable ownership or timeout reaches, but it
- //! will maintain upgradable ownership.
- //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //! will maintain upgradable ownership.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: An exception derived from interprocess_exception on error. */
bool timed_unlock_upgradable_and_lock(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Precondition: The thread must have sharable ownership of the mutex.
//!Effects: The thread atomically releases sharable ownership and tries to acquire
//! exclusive ownership. This operation will fail if there are threads with sharable
//! or upgradable ownership, but it will maintain sharable ownership.
- //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_sharable_and_lock();
- //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Precondition: The thread must have sharable ownership of the mutex.
//!Effects: The thread atomically releases sharable ownership and tries to acquire
//! upgradable ownership. This operation will fail if there are threads with sharable
- //! or upgradable ownership, but it will maintain sharable ownership.
- //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
+ //! or upgradable ownership, but it will maintain sharable ownership.
+ //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
//!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_sharable_and_lock_upgradable();
@@ -249,7 +249,7 @@ class interprocess_upgradable_mutex
if(mp_ctrl){
//Recover upgradable lock
mp_ctrl->upgradable_in = 1;
- ++mp_ctrl->num_upr_shar;
+ ++mp_ctrl->num_upr_shar;
//Execute the second half of exclusive locking
mp_ctrl->exclusive_in = 0;
}
@@ -260,7 +260,7 @@ class interprocess_upgradable_mutex
template<int Dummy>
struct base_constants_t
{
- static const unsigned max_readers
+ static const unsigned max_readers
= ~(unsigned(3) << (sizeof(unsigned)*CHAR_BIT-2));
};
typedef base_constants_t<0> constants;
@@ -309,10 +309,10 @@ inline bool interprocess_upgradable_mutex::try_lock()
{
scoped_lock_t lock(m_mut, try_to_lock);
- //If we can't lock or any has there is any exclusive, upgradable
+ //If we can't lock or any has there is any exclusive, upgradable
//or sharable mark return false;
- if(!lock.owns()
- || this->m_ctrl.exclusive_in
+ if(!lock.owns()
+ || this->m_ctrl.exclusive_in
|| this->m_ctrl.num_upr_shar){
return false;
}
@@ -387,9 +387,9 @@ inline bool interprocess_upgradable_mutex::try_lock_upgradable()
//The upgradable lock must fail
//if an exclusive or upgradable lock has been acquired
//or there are too many sharable locks
- if(!lock.owns()
- || this->m_ctrl.exclusive_in
- || this->m_ctrl.upgradable_in
+ if(!lock.owns()
+ || this->m_ctrl.exclusive_in
+ || this->m_ctrl.upgradable_in
|| this->m_ctrl.num_upr_shar == constants::max_readers){
return false;
}
@@ -414,11 +414,11 @@ inline bool interprocess_upgradable_mutex::timed_lock_upgradable
//The upgradable lock must block in the first gate
//if an exclusive or upgradable lock has been acquired
//or there are too many sharable locks
- while(this->m_ctrl.exclusive_in
+ while(this->m_ctrl.exclusive_in
|| this->m_ctrl.upgradable_in
|| this->m_ctrl.num_upr_shar == constants::max_readers){
if(!this->m_first_gate.timed_wait(lock, abs_time)){
- return!(this->m_ctrl.exclusive_in
+ return!(this->m_ctrl.exclusive_in
|| this->m_ctrl.upgradable_in
|| this->m_ctrl.num_upr_shar == constants::max_readers);
}
@@ -561,7 +561,7 @@ inline void interprocess_upgradable_mutex::unlock_upgradable_and_lock()
//Simulate unlock_upgradable() without
//notifying sharables.
this->m_ctrl.upgradable_in = 0;
- --this->m_ctrl.num_upr_shar;
+ --this->m_ctrl.num_upr_shar;
//Execute the second half of exclusive locking
this->m_ctrl.exclusive_in = 1;
@@ -584,7 +584,7 @@ inline bool interprocess_upgradable_mutex::try_unlock_upgradable_and_lock()
}
//Now unlock upgradable and mark exclusive
this->m_ctrl.upgradable_in = 0;
- --this->m_ctrl.num_upr_shar;
+ --this->m_ctrl.num_upr_shar;
this->m_ctrl.exclusive_in = 1;
return true;
}
@@ -598,7 +598,7 @@ inline bool interprocess_upgradable_mutex::timed_unlock_upgradable_and_lock
//Simulate unlock_upgradable() without
//notifying sharables.
this->m_ctrl.upgradable_in = 0;
- --this->m_ctrl.num_upr_shar;
+ --this->m_ctrl.num_upr_shar;
//Execute the second half of exclusive locking
this->m_ctrl.exclusive_in = 1;
@@ -618,10 +618,10 @@ inline bool interprocess_upgradable_mutex::try_unlock_sharable_and_lock()
{
scoped_lock_t lock(m_mut, try_to_lock);
- //If we can't lock or any has there is any exclusive, upgradable
+ //If we can't lock or any has there is any exclusive, upgradable
//or sharable mark return false;
- if(!lock.owns()
- || this->m_ctrl.exclusive_in
+ if(!lock.owns()
+ || this->m_ctrl.exclusive_in
|| this->m_ctrl.upgradable_in
|| this->m_ctrl.num_upr_shar != 1){
return false;
@@ -638,7 +638,7 @@ inline bool interprocess_upgradable_mutex::try_unlock_sharable_and_lock_upgradab
//The upgradable lock must fail
//if an exclusive or upgradable lock has been acquired
if(!lock.owns()
- || this->m_ctrl.exclusive_in
+ || this->m_ctrl.exclusive_in
|| this->m_ctrl.upgradable_in){
return false;
}
diff --git a/boost/interprocess/sync/mutex_family.hpp b/boost/interprocess/sync/mutex_family.hpp
index a9215e24fe..b153ffea3e 100644
--- a/boost/interprocess/sync/mutex_family.hpp
+++ b/boost/interprocess/sync/mutex_family.hpp
@@ -29,7 +29,7 @@ namespace boost {
namespace interprocess {
-//!Describes interprocess_mutex family to use with Interprocess framework
+//!Describes interprocess_mutex family to use with Interprocess framework
//!based on boost::interprocess synchronization objects.
struct mutex_family
{
@@ -37,7 +37,7 @@ struct mutex_family
typedef boost::interprocess::interprocess_recursive_mutex recursive_mutex_type;
};
-//!Describes interprocess_mutex family to use with Interprocess frameworks
+//!Describes interprocess_mutex family to use with Interprocess frameworks
//!based on null operation synchronization objects.
struct null_mutex_family
{
diff --git a/boost/interprocess/sync/named_condition.hpp b/boost/interprocess/sync/named_condition.hpp
index c5529eda6c..ca0205ad73 100644
--- a/boost/interprocess/sync/named_condition.hpp
+++ b/boost/interprocess/sync/named_condition.hpp
@@ -22,7 +22,12 @@
#include <boost/interprocess/detail/interprocess_tester.hpp>
#include <boost/interprocess/permissions.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
-#include <boost/interprocess/sync/shm/named_condition.hpp>
+#if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/named_condition.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
+#else
+ #include <boost/interprocess/sync/shm/named_condition.hpp>
+#endif
//!\file
//!Describes a named condition class for inter-process synchronization
@@ -50,7 +55,7 @@ class named_condition
//!If the condition can't be created throws interprocess_exception
named_condition(create_only_t create_only, const char *name, const permissions &perm = permissions());
- //!Opens or creates a global condition with a name.
+ //!Opens or creates a global condition with a name.
//!If the condition is created, this call is equivalent to
//!named_condition(create_only_t, ... )
//!If the condition is already created, this call is equivalent
@@ -71,7 +76,7 @@ class named_condition
//!use remove().
~named_condition();
- //!If there is a thread waiting on *this, change that
+ //!If there is a thread waiting on *this, change that
//!thread's state to ready. Otherwise there is no effect.*/
void notify_one();
@@ -79,8 +84,8 @@ class named_condition
//!If there are no waiting threads, notify_all() has no effect.
void notify_all();
- //!Releases the lock on the named_mutex object associated with lock, blocks
- //!the current thread of execution until readied by a call to
+ //!Releases the lock on the named_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
//!this->notify_one() or this->notify_all(), and then reacquires the lock.
template <typename L>
void wait(L& lock);
@@ -90,16 +95,16 @@ class named_condition
template <typename L, typename Pr>
void wait(L& lock, Pr pred);
- //!Releases the lock on the named_mutex object associated with lock, blocks
- //!the current thread of execution until readied by a call to
- //!this->notify_one() or this->notify_all(), or until time abs_time is reached,
+ //!Releases the lock on the named_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
+ //!this->notify_one() or this->notify_all(), or until time abs_time is reached,
//!and then reacquires the lock.
//!Returns: false if time abs_time is reached, otherwise true.
template <typename L>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time);
- //!The same as: while (!pred()) {
- //! if (!timed_wait(lock, abs_time)) return pred();
+ //!The same as: while (!pred()) {
+ //! if (!timed_wait(lock, abs_time)) return pred();
//! } return true;
template <typename L, typename Pr>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred);
@@ -110,7 +115,12 @@ class named_condition
/// @cond
private:
- ipcdetail::shm_named_condition m_cond;
+ #if defined(BOOST_INTERPROCESS_USE_WINDOWS)
+ typedef ipcdetail::windows_named_condition condition_type;
+ #else
+ typedef ipcdetail::shm_named_condition condition_type;
+ #endif
+ condition_type m_cond;
friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction()
@@ -160,7 +170,7 @@ inline bool named_condition::timed_wait
{ return m_cond.timed_wait(lock, abs_time, pred); }
inline bool named_condition::remove(const char *name)
-{ return ipcdetail::shm_named_condition::remove(name); }
+{ return condition_type::remove(name); }
/// @endcond
diff --git a/boost/interprocess/sync/named_mutex.hpp b/boost/interprocess/sync/named_mutex.hpp
index 3e56b81794..c34193c697 100644
--- a/boost/interprocess/sync/named_mutex.hpp
+++ b/boost/interprocess/sync/named_mutex.hpp
@@ -24,7 +24,11 @@
#include <boost/interprocess/permissions.hpp>
#if defined(BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
-#include <boost/interprocess/sync/posix/named_mutex.hpp>
+ #include <boost/interprocess/sync/posix/named_mutex.hpp>
+ #define BOOST_INTERPROCESS_USE_POSIX_SEMAPHORES
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/named_mutex.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
#else
#include <boost/interprocess/sync/shm/named_mutex.hpp>
#endif
@@ -37,7 +41,7 @@ namespace interprocess {
class named_condition;
-//!A mutex with a global name, so it can be found from different
+//!A mutex with a global name, so it can be found from different
//!processes. This mutex can't be placed in shared memory, and
//!each process should have it's own named_mutex.
class named_mutex
@@ -56,7 +60,7 @@ class named_mutex
//!Throws interprocess_exception on error.
named_mutex(create_only_t create_only, const char *name, const permissions &perm = permissions());
- //!Opens or creates a global mutex with a name.
+ //!Opens or creates a global mutex with a name.
//!If the mutex is created, this call is equivalent to
//!named_mutex(create_only_t, ... )
//!If the mutex is already created, this call is equivalent
@@ -85,7 +89,7 @@ class named_mutex
//!Throws interprocess_exception if a severe error is found
void lock();
- //!Tries to lock the interprocess_mutex, returns false when interprocess_mutex
+ //!Tries to lock the interprocess_mutex, returns false when interprocess_mutex
//!is already locked, returns true when success.
//!Throws interprocess_exception if a severe error is found
bool try_lock();
@@ -104,15 +108,20 @@ class named_mutex
friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction();
- #if defined(BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
- typedef ipcdetail::posix_named_mutex impl_t;
- impl_t m_mut;
+ #if defined(BOOST_INTERPROCESS_USE_POSIX_SEMAPHORES)
+ typedef ipcdetail::posix_named_mutex impl_t;
+ impl_t m_mut;
+ #undef BOOST_INTERPROCESS_USE_POSIX_SEMAPHORES
+ #elif defined(BOOST_INTERPROCESS_USE_WINDOWS)
+ typedef ipcdetail::windows_named_mutex impl_t;
+ impl_t m_mut;
+ #undef BOOST_INTERPROCESS_USE_WINDOWS
#else
- typedef ipcdetail::shm_named_mutex impl_t;
- impl_t m_mut;
- public:
- interprocess_mutex *mutex() const
- { return m_mut.mutex(); }
+ typedef ipcdetail::shm_named_mutex impl_t;
+ impl_t m_mut;
+ public:
+ interprocess_mutex *mutex() const
+ { return m_mut.mutex(); }
#endif
/// @endcond
diff --git a/boost/interprocess/sync/named_recursive_mutex.hpp b/boost/interprocess/sync/named_recursive_mutex.hpp
index 28768cea6f..2d4b9b2416 100644
--- a/boost/interprocess/sync/named_recursive_mutex.hpp
+++ b/boost/interprocess/sync/named_recursive_mutex.hpp
@@ -20,7 +20,12 @@
#include <boost/interprocess/creation_tags.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/permissions.hpp>
-#include <boost/interprocess/sync/shm/named_recursive_mutex.hpp>
+#if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/named_recursive_mutex.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
+#else
+ #include <boost/interprocess/sync/shm/named_recursive_mutex.hpp>
+#endif
//!\file
//!Describes a named named_recursive_mutex class for inter-process synchronization
@@ -32,7 +37,7 @@ namespace interprocess {
namespace ipcdetail{ class interprocess_tester; }
/// @endcond
-//!A recursive mutex with a global name, so it can be found from different
+//!A recursive mutex with a global name, so it can be found from different
//!processes. This mutex can't be placed in shared memory, and
//!each process should have it's own named_recursive_mutex.
class named_recursive_mutex
@@ -49,7 +54,7 @@ class named_recursive_mutex
//!If the recursive_mutex can't be created throws interprocess_exception
named_recursive_mutex(create_only_t create_only, const char *name, const permissions &perm = permissions());
- //!Opens or creates a global recursive_mutex with a name.
+ //!Opens or creates a global recursive_mutex with a name.
//!If the recursive_mutex is created, this call is equivalent to
//!named_recursive_mutex(create_only_t, ... )
//!If the recursive_mutex is already created, this call is equivalent
@@ -78,7 +83,7 @@ class named_recursive_mutex
//!Throws interprocess_exception if a severe error is found.
void lock();
- //!Tries to lock the named_recursive_mutex, returns false when named_recursive_mutex
+ //!Tries to lock the named_recursive_mutex, returns false when named_recursive_mutex
//!is already locked, returns true when success.
//!Throws interprocess_exception if a severe error is found.
bool try_lock();
@@ -97,7 +102,12 @@ class named_recursive_mutex
friend class ipcdetail::interprocess_tester;
void dont_close_on_destruction();
- typedef ipcdetail::shm_named_recursive_mutex impl_t;
+ #if defined(BOOST_INTERPROCESS_USE_WINDOWS)
+ typedef ipcdetail::windows_named_recursive_mutex impl_t;
+ #undef BOOST_INTERPROCESS_USE_WINDOWS
+ #else
+ typedef ipcdetail::shm_named_recursive_mutex impl_t;
+ #endif
impl_t m_mut;
/// @endcond
diff --git a/boost/interprocess/sync/named_semaphore.hpp b/boost/interprocess/sync/named_semaphore.hpp
index 33e06964f9..39c9096fb6 100644
--- a/boost/interprocess/sync/named_semaphore.hpp
+++ b/boost/interprocess/sync/named_semaphore.hpp
@@ -25,6 +25,10 @@
#if defined(BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES)
#include <boost/interprocess/sync/posix/named_semaphore.hpp>
+//Experimental...
+#elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
+ #include <boost/interprocess/sync/windows/named_semaphore.hpp>
+ #define BOOST_INTERPROCESS_USE_WINDOWS
#else
#include <boost/interprocess/sync/shm/named_semaphore.hpp>
#endif
@@ -35,8 +39,8 @@
namespace boost {
namespace interprocess {
-//!A semaphore with a global name, so it can be found from different
-//!processes. Allows several resource sharing patterns and efficient
+//!A semaphore with a global name, so it can be found from different
+//!processes. Allows several resource sharing patterns and efficient
//!acknowledgment mechanisms.
class named_semaphore
{
@@ -49,11 +53,11 @@ class named_semaphore
/// @endcond
public:
- //!Creates a global semaphore with a name, and an initial count.
+ //!Creates a global semaphore with a name, and an initial count.
//!If the semaphore can't be created throws interprocess_exception
named_semaphore(create_only_t, const char *name, unsigned int initialCount, const permissions &perm = permissions());
- //!Opens or creates a global semaphore with a name, and an initial count.
+ //!Opens or creates a global semaphore with a name, and an initial count.
//!If the semaphore is created, this call is equivalent to
//!named_semaphore(create_only_t, ...)
//!If the semaphore is already created, this call is equivalent to
@@ -80,7 +84,7 @@ class named_semaphore
void post();
//!Decrements the semaphore. If the semaphore value is not greater than zero,
- //!then the calling process/thread blocks until it can decrement the counter.
+ //!then the calling process/thread blocks until it can decrement the counter.
//!If there is an error an interprocess_exception exception is thrown.
void wait();
@@ -106,9 +110,12 @@ class named_semaphore
void dont_close_on_destruction();
#if defined(BOOST_INTERPROCESS_NAMED_SEMAPHORE_USES_POSIX_SEMAPHORES)
- typedef ipcdetail::posix_named_semaphore impl_t;
+ typedef ipcdetail::posix_named_semaphore impl_t;
+ #elif defined(BOOST_INTERPROCESS_USE_WINDOWS)
+ #undef BOOST_INTERPROCESS_USE_WINDOWS
+ typedef ipcdetail::windows_named_semaphore impl_t;
#else
- typedef ipcdetail::shm_named_semaphore impl_t;
+ typedef ipcdetail::shm_named_semaphore impl_t;
#endif
impl_t m_sem;
/// @endcond
diff --git a/boost/interprocess/sync/named_upgradable_mutex.hpp b/boost/interprocess/sync/named_upgradable_mutex.hpp
index 61c6bb4086..c45fd08270 100644
--- a/boost/interprocess/sync/named_upgradable_mutex.hpp
+++ b/boost/interprocess/sync/named_upgradable_mutex.hpp
@@ -38,7 +38,7 @@ namespace ipcdetail{ class interprocess_tester; }
class named_condition;
-//!A upgradable mutex with a global name, so it can be found from different
+//!A upgradable mutex with a global name, so it can be found from different
//!processes. This mutex can't be placed in shared memory, and
//!each process should have it's own named upgradable mutex.
class named_upgradable_mutex
@@ -52,11 +52,11 @@ class named_upgradable_mutex
/// @endcond
public:
- //!Creates a global upgradable mutex with a name.
+ //!Creates a global upgradable mutex with a name.
//!If the upgradable mutex can't be created throws interprocess_exception
named_upgradable_mutex(create_only_t create_only, const char *name, const permissions &perm = permissions());
- //!Opens or creates a global upgradable mutex with a name, and an initial count.
+ //!Opens or creates a global upgradable mutex with a name, and an initial count.
//!If the upgradable mutex is created, this call is equivalent to
//!named_upgradable_mutex(create_only_t, ...)
//!If the upgradable mutex is already created, this call is equivalent to
@@ -95,13 +95,13 @@ class named_upgradable_mutex
//!Effects: The calling thread tries to acquire exclusive ownership of the mutex
//! waiting if necessary until no other thread has exclusive, sharable or
- //! upgradable ownership of the mutex or abs_time is reached.
- //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //! upgradable ownership of the mutex or abs_time is reached.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: interprocess_exception on error.
bool timed_lock(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have exclusive ownership of the mutex.
- //!Effects: The calling thread releases the exclusive ownership of the mutex.
+ //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Effects: The calling thread releases the exclusive ownership of the mutex.
//!Throws: An exception derived from interprocess_exception on error.
void unlock();
@@ -115,21 +115,21 @@ class named_upgradable_mutex
//!Effects: The calling thread tries to acquire sharable ownership of the mutex
//! without waiting. If no other thread has exclusive ownership
- //! of the mutex this succeeds.
+ //! of the mutex this succeeds.
//!Returns: If it can acquire sharable ownership immediately returns true. If it
- //! has to wait, returns false.
+ //! has to wait, returns false.
//!Throws: interprocess_exception on error.
bool try_lock_sharable();
//!Effects: The calling thread tries to acquire sharable ownership of the mutex
//! waiting if necessary until no other thread has exclusive
- //! ownership of the mutex or abs_time is reached.
- //!Returns: If acquires sharable ownership, returns true. Otherwise returns false.
+ //! ownership of the mutex or abs_time is reached.
+ //!Returns: If acquires sharable ownership, returns true. Otherwise returns false.
//!Throws: interprocess_exception on error.
bool timed_lock_sharable(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have sharable ownership of the mutex.
- //!Effects: The calling thread releases the sharable ownership of the mutex.
+ //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Effects: The calling thread releases the sharable ownership of the mutex.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_sharable();
@@ -143,7 +143,7 @@ class named_upgradable_mutex
//!Effects: The calling thread tries to acquire upgradable ownership of the mutex
//! without waiting. If no other thread has exclusive or upgradable ownership
- //! of the mutex this succeeds.
+ //! of the mutex this succeeds.
//!Returns: If it can acquire upgradable ownership immediately returns true.
//! If it has to wait, returns false.
//!Throws: interprocess_exception on error.
@@ -152,66 +152,66 @@ class named_upgradable_mutex
//!Effects: The calling thread tries to acquire upgradable ownership of the mutex
//! waiting if necessary until no other thread has exclusive or upgradable
//! ownership of the mutex or abs_time is reached.
- //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
+ //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
//!Throws: interprocess_exception on error.
bool timed_lock_upgradable(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have upgradable ownership of the mutex.
- //!Effects: The calling thread releases the upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Effects: The calling thread releases the upgradable ownership of the mutex.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable();
//Demotions
- //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Precondition: The thread must have exclusive ownership of the mutex.
//!Effects: The thread atomically releases exclusive ownership and acquires
- //! upgradable ownership. This operation is non-blocking.
+ //! upgradable ownership. This operation is non-blocking.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_and_lock_upgradable();
- //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Precondition: The thread must have exclusive ownership of the mutex.
//!Effects: The thread atomically releases exclusive ownership and acquires
- //! sharable ownership. This operation is non-blocking.
+ //! sharable ownership. This operation is non-blocking.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_and_lock_sharable();
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and acquires
- //! sharable ownership. This operation is non-blocking.
+ //! sharable ownership. This operation is non-blocking.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable_and_lock_sharable();
//Promotions
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and acquires
//! exclusive ownership. This operation will block until all threads with
- //! sharable ownership release it.
+ //! sharable ownership release it.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable_and_lock();
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and tries to
//! acquire exclusive ownership. This operation will fail if there are threads
- //! with sharable ownership, but it will maintain upgradable ownership.
+ //! with sharable ownership, but it will maintain upgradable ownership.
//!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_upgradable_and_lock();
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and tries to acquire
//! exclusive ownership, waiting if necessary until abs_time. This operation will
//! fail if there are threads with sharable ownership or timeout reaches, but it
- //! will maintain upgradable ownership.
- //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //! will maintain upgradable ownership.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: An exception derived from interprocess_exception on error.
bool timed_unlock_upgradable_and_lock(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Precondition: The thread must have sharable ownership of the mutex.
//!Effects: The thread atomically releases sharable ownership and tries to acquire
//! exclusive ownership. This operation will fail if there are threads with sharable
//! or upgradable ownership, but it will maintain sharable ownership.
- //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_sharable_and_lock();
diff --git a/boost/interprocess/sync/posix/condition.hpp b/boost/interprocess/sync/posix/condition.hpp
index 213e4ce8b5..48be099f60 100644
--- a/boost/interprocess/sync/posix/condition.hpp
+++ b/boost/interprocess/sync/posix/condition.hpp
@@ -19,7 +19,7 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <pthread.h>
-#include <errno.h>
+#include <errno.h>
#include <boost/interprocess/sync/posix/pthread_helpers.hpp>
#include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
@@ -44,7 +44,7 @@ class posix_condition
//!liberating system resources.
~posix_condition();
- //!If there is a thread waiting on *this, change that
+ //!If there is a thread waiting on *this, change that
//!thread's state to ready. Otherwise there is no effect.
void notify_one();
@@ -52,8 +52,8 @@ class posix_condition
//!If there are no waiting threads, notify_all() has no effect.
void notify_all();
- //!Releases the lock on the posix_mutex object associated with lock, blocks
- //!the current thread of execution until readied by a call to
+ //!Releases the lock on the posix_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
//!this->notify_one() or this->notify_all(), and then reacquires the lock.
template <typename L>
void wait(L& lock)
@@ -75,9 +75,9 @@ class posix_condition
this->do_wait(*lock.mutex());
}
- //!Releases the lock on the posix_mutex object associated with lock, blocks
- //!the current thread of execution until readied by a call to
- //!this->notify_one() or this->notify_all(), or until time abs_time is reached,
+ //!Releases the lock on the posix_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
+ //!this->notify_one() or this->notify_all(), or until time abs_time is reached,
//!and then reacquires the lock.
//!Returns: false if time abs_time is reached, otherwise true.
template <typename L>
@@ -92,8 +92,8 @@ class posix_condition
return this->do_timed_wait(abs_time, *lock.mutex());
}
- //!The same as: while (!pred()) {
- //! if (!timed_wait(lock, abs_time)) return pred();
+ //!The same as: while (!pred()) {
+ //! if (!timed_wait(lock, abs_time)) return pred();
//! } return true;
template <typename L, typename Pr>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
diff --git a/boost/interprocess/sync/posix/mutex.hpp b/boost/interprocess/sync/posix/mutex.hpp
index 22e2ec04b9..393807c97a 100644
--- a/boost/interprocess/sync/posix/mutex.hpp
+++ b/boost/interprocess/sync/posix/mutex.hpp
@@ -35,7 +35,7 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <pthread.h>
-#include <errno.h>
+#include <errno.h>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
@@ -80,7 +80,7 @@ inline posix_mutex::posix_mutex()
mut.release();
}
-inline posix_mutex::~posix_mutex()
+inline posix_mutex::~posix_mutex()
{
int res = pthread_mutex_destroy(&m_mut);
BOOST_ASSERT(res == 0);(void)res;
@@ -88,7 +88,7 @@ inline posix_mutex::~posix_mutex()
inline void posix_mutex::lock()
{
- if (pthread_mutex_lock(&m_mut) != 0)
+ if (pthread_mutex_lock(&m_mut) != 0)
throw lock_exception();
}
diff --git a/boost/interprocess/sync/posix/pthread_helpers.hpp b/boost/interprocess/sync/posix/pthread_helpers.hpp
index c09ce200cf..bcbc44be33 100644
--- a/boost/interprocess/sync/posix/pthread_helpers.hpp
+++ b/boost/interprocess/sync/posix/pthread_helpers.hpp
@@ -19,8 +19,8 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <pthread.h>
-#include <errno.h>
-#include <boost/interprocess/exceptions.hpp>
+#include <errno.h>
+#include <boost/interprocess/exceptions.hpp>
namespace boost {
namespace interprocess {
@@ -29,7 +29,7 @@ namespace ipcdetail{
#if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
//!Makes pthread_mutexattr_t cleanup easy when using exceptions
- struct mutexattr_wrapper
+ struct mutexattr_wrapper
{
//!Constructor
mutexattr_wrapper(bool recursive = false)
@@ -51,7 +51,7 @@ namespace ipcdetail{
};
//!Makes pthread_condattr_t cleanup easy when using exceptions
- struct condattr_wrapper
+ struct condattr_wrapper
{
//!Constructor
condattr_wrapper()
@@ -86,7 +86,7 @@ namespace ipcdetail{
void release() {mp_mut = 0; }
- private:
+ private:
pthread_mutex_t *mp_mut;
};
@@ -94,7 +94,7 @@ namespace ipcdetail{
class condition_initializer
{
public:
- condition_initializer(pthread_cond_t &cond, pthread_condattr_t &cond_attr)
+ condition_initializer(pthread_cond_t &cond, pthread_condattr_t &cond_attr)
: mp_cond(&cond)
{
if(pthread_cond_init(mp_cond, &cond_attr)!= 0)
@@ -105,7 +105,7 @@ namespace ipcdetail{
void release() { mp_cond = 0; }
- private:
+ private:
pthread_cond_t *mp_cond;
};
@@ -114,7 +114,7 @@ namespace ipcdetail{
#if defined(BOOST_INTERPROCESS_POSIX_BARRIERS) && defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED)
//!Makes pthread_barrierattr_t cleanup easy when using exceptions
- struct barrierattr_wrapper
+ struct barrierattr_wrapper
{
//!Constructor
barrierattr_wrapper()
@@ -138,8 +138,8 @@ namespace ipcdetail{
{
public:
//!Constructor. Takes barrier attributes to initialize the barrier
- barrier_initializer(pthread_barrier_t &mut,
- pthread_barrierattr_t &mut_attr,
+ barrier_initializer(pthread_barrier_t &mut,
+ pthread_barrierattr_t &mut_attr,
int count)
: mp_barrier(&mut)
{
@@ -151,7 +151,7 @@ namespace ipcdetail{
void release() {mp_barrier = 0; }
- private:
+ private:
pthread_barrier_t *mp_barrier;
};
diff --git a/boost/interprocess/sync/posix/recursive_mutex.hpp b/boost/interprocess/sync/posix/recursive_mutex.hpp
index baa670fa9a..456c9a4874 100644
--- a/boost/interprocess/sync/posix/recursive_mutex.hpp
+++ b/boost/interprocess/sync/posix/recursive_mutex.hpp
@@ -31,7 +31,7 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <pthread.h>
-#include <errno.h>
+#include <errno.h>
#include <boost/interprocess/sync/posix/pthread_helpers.hpp>
#include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
@@ -78,7 +78,7 @@ inline posix_recursive_mutex::~posix_recursive_mutex()
inline void posix_recursive_mutex::lock()
{
- if (pthread_mutex_lock(&m_mut) != 0)
+ if (pthread_mutex_lock(&m_mut) != 0)
throw lock_exception();
}
diff --git a/boost/interprocess/sync/posix/semaphore_wrapper.hpp b/boost/interprocess/sync/posix/semaphore_wrapper.hpp
index 1aeef47662..22184cda9d 100644
--- a/boost/interprocess/sync/posix/semaphore_wrapper.hpp
+++ b/boost/interprocess/sync/posix/semaphore_wrapper.hpp
@@ -18,7 +18,7 @@
#include <boost/interprocess/detail/tmp_dir_helpers.hpp>
#include <boost/interprocess/permissions.hpp>
-#include <fcntl.h> //O_CREAT, O_*...
+#include <fcntl.h> //O_CREAT, O_*...
#include <unistd.h> //close
#include <string> //std::string
#include <semaphore.h> //sem_* family, SEM_VALUE_MAX
@@ -42,7 +42,7 @@ namespace interprocess {
namespace ipcdetail {
inline bool semaphore_open
- (sem_t *&handle, create_enum_t type, const char *origname,
+ (sem_t *&handle, create_enum_t type, const char *origname,
unsigned int count = 0, const permissions &perm = permissions())
{
std::string name;
@@ -103,7 +103,7 @@ inline bool semaphore_open
inline void semaphore_close(sem_t *handle)
{
int ret = sem_close(handle);
- if(ret != 0){
+ if(ret != 0){
BOOST_ASSERT(0);
}
}
@@ -138,7 +138,7 @@ inline void semaphore_init(sem_t *handle, unsigned int initialCount)
inline void semaphore_destroy(sem_t *handle)
{
int ret = sem_destroy(handle);
- if(ret != 0){
+ if(ret != 0){
BOOST_ASSERT(0);
}
}
diff --git a/boost/interprocess/sync/scoped_lock.hpp b/boost/interprocess/sync/scoped_lock.hpp
index bfef63a30a..61fe93e5b3 100644
--- a/boost/interprocess/sync/scoped_lock.hpp
+++ b/boost/interprocess/sync/scoped_lock.hpp
@@ -89,7 +89,7 @@ class scoped_lock
: mp_mutex(&m), m_locked(true)
{}
- //!Effects: m.try_lock().
+ //!Effects: m.try_lock().
//!Postconditions: mutex() == &m. owns() == the return value of the
//! m.try_lock() executed within the constructor.
//!Notes: The constructor will take ownership of the mutex if it can do
@@ -101,7 +101,7 @@ class scoped_lock
: mp_mutex(&m), m_locked(mp_mutex->try_lock())
{}
- //!Effects: m.timed_lock(abs_time).
+ //!Effects: m.timed_lock(abs_time).
//!Postconditions: mutex() == &m. owns() == the return value of the
//! m.timed_lock(abs_time) executed within the constructor.
//!Notes: The constructor will take ownership of the mutex if it can do
@@ -128,7 +128,7 @@ class scoped_lock
{ mp_mutex = scop.release(); }
//!Effects: If upgr.owns() then calls unlock_upgradable_and_lock() on the
- //! referenced mutex. upgr.release() is called.
+ //! referenced mutex. upgr.release() is called.
//!Postconditions: mutex() == the value upgr.mutex() had before the construction.
//! upgr.mutex() == 0. owns() == upgr.owns() before the construction.
//! upgr.owns() == false after the construction.
@@ -155,12 +155,12 @@ class scoped_lock
//!Effects: If upgr.owns() then calls try_unlock_upgradable_and_lock() on the
//!referenced mutex:
//! a)if try_unlock_upgradable_and_lock() returns true then mutex() obtains
- //! the value from upgr.release() and owns() is set to true.
+ //! the value from upgr.release() and owns() is set to true.
//! b)if try_unlock_upgradable_and_lock() returns false then upgr is
- //! unaffected and this scoped_lock construction as the same effects as
- //! a default construction.
+ //! unaffected and this scoped_lock construction as the same effects as
+ //! a default construction.
//! c)Else upgr.owns() is false. mutex() obtains the value from upgr.release()
- //! and owns() is set to false
+ //! and owns() is set to false
//!Notes: This construction will not block. It will try to obtain mutex
//! ownership from upgr immediately, while changing the lock type from a
//! "read lock" to a "write lock". If the "read lock" isn't held in the
@@ -186,12 +186,12 @@ class scoped_lock
//!Effects: If upgr.owns() then calls timed_unlock_upgradable_and_lock(abs_time)
//! on the referenced mutex:
//! a)if timed_unlock_upgradable_and_lock(abs_time) returns true then mutex()
- //! obtains the value from upgr.release() and owns() is set to true.
+ //! obtains the value from upgr.release() and owns() is set to true.
//! b)if timed_unlock_upgradable_and_lock(abs_time) returns false then upgr
//! is unaffected and this scoped_lock construction as the same effects
//! as a default construction.
//! c)Else upgr.owns() is false. mutex() obtains the value from upgr.release()
- //! and owns() is set to false
+ //! and owns() is set to false
//!Notes: This construction will not block. It will try to obtain mutex ownership
//! from upgr immediately, while changing the lock type from a "read lock" to a
//! "write lock". If the "read lock" isn't held in the first place, the mutex
@@ -214,14 +214,14 @@ class scoped_lock
}
//!Effects: If shar.owns() then calls try_unlock_sharable_and_lock() on the
- //!referenced mutex.
+ //!referenced mutex.
//! a)if try_unlock_sharable_and_lock() returns true then mutex() obtains
- //! the value from shar.release() and owns() is set to true.
+ //! the value from shar.release() and owns() is set to true.
//! b)if try_unlock_sharable_and_lock() returns false then shar is
//! unaffected and this scoped_lock construction has the same
- //! effects as a default construction.
+ //! effects as a default construction.
//! c)Else shar.owns() is false. mutex() obtains the value from
- //! shar.release() and owns() is set to false
+ //! shar.release() and owns() is set to false
//!Notes: This construction will not block. It will try to obtain mutex
//! ownership from shar immediately, while changing the lock type from a
//! "read lock" to a "write lock". If the "read lock" isn't held in the
@@ -253,13 +253,13 @@ class scoped_lock
}
//!Effects: If owns() before the call, then unlock() is called on mutex().
- //! *this gets the state of scop and scop gets set to a default constructed state.
+ //! *this gets the state of scop and scop gets set to a default constructed state.
//!Notes: With a recursive mutex it is possible that both this and scop own
//! the same mutex before the assignment. In this case, this will own the
//! mutex after the assignment (and scop will not), but the mutex's lock
//! count will be decremented by one.
scoped_lock &operator=(BOOST_RV_REF(scoped_lock) scop)
- {
+ {
if(this->owns())
this->unlock();
m_locked = scop.owns();
@@ -281,7 +281,7 @@ class scoped_lock
}
//!Effects: If mutex() == 0 or if already locked, throws a lock_exception()
- //! exception. Calls try_lock() on the referenced mutex.
+ //! exception. Calls try_lock() on the referenced mutex.
//!Postconditions: owns() == the value returned from mutex()->try_lock().
//!Notes: The scoped_lock changes from a state of not owning the mutex, to
//! owning the mutex, but only if blocking was not required. If the
@@ -348,8 +348,8 @@ class scoped_lock
m_locked = false;
return mut;
}
-
- //!Effects: Swaps state with moved lock.
+
+ //!Effects: Swaps state with moved lock.
//!Throws: Nothing.
void swap( scoped_lock<mutex_type> &other)
{
@@ -359,7 +359,7 @@ class scoped_lock
/// @cond
private:
- mutex_type *mp_mutex;
+ mutex_type *mp_mutex;
bool m_locked;
/// @endcond
};
diff --git a/boost/interprocess/sync/sharable_lock.hpp b/boost/interprocess/sync/sharable_lock.hpp
index c8b7c1d26e..9342e45a46 100644
--- a/boost/interprocess/sync/sharable_lock.hpp
+++ b/boost/interprocess/sync/sharable_lock.hpp
@@ -67,7 +67,7 @@ class sharable_lock
{}
//!Effects: m.lock_sharable().
- //!Postconditions: owns() == true and mutex() == &m.
+ //!Postconditions: owns() == true and mutex() == &m.
//!Notes: The constructor will take sharable-ownership of the mutex. If
//! another thread already owns the mutex with exclusive ownership
//! (scoped_lock), this thread will block until the mutex is released.
@@ -104,7 +104,7 @@ class sharable_lock
: mp_mutex(&m), m_locked(false)
{ m_locked = mp_mutex->try_lock_sharable(); }
- //!Effects: m.timed_lock_sharable(abs_time)
+ //!Effects: m.timed_lock_sharable(abs_time)
//!Postconditions: mutex() == &m. owns() == the return value of the
//! m.timed_lock_sharable() executed within the constructor.
//!Notes: The constructor will take sharable-ownership of the mutex if it
@@ -132,7 +132,7 @@ class sharable_lock
//! referenced mutex.
//!Postconditions: mutex() == the value upgr.mutex() had before the construction.
//! upgr.mutex() == 0 owns() == the value of upgr.owns() before construction.
- //! upgr.owns() == false after the construction.
+ //! upgr.owns() == false after the construction.
//!Notes: If upgr is locked, this constructor will lock this sharable_lock while
//! unlocking upgr. Only a moved sharable_lock's will match this
//! signature. An non-moved upgradable_lock can be moved with the expression:
@@ -156,7 +156,7 @@ class sharable_lock
//! scop.mutex() == 0 owns() == scop.owns() before the constructor. After the
//! construction, scop.owns() == false.
//!Notes: If scop is locked, this constructor will transfer the exclusive ownership
- //! to a sharable-ownership of this sharable_lock.
+ //! to a sharable-ownership of this sharable_lock.
//! Only a moved scoped_lock's will match this
//! signature. An non-moved scoped_lock can be moved with the expression:
//! "boost::move(lock);".
@@ -184,12 +184,12 @@ class sharable_lock
}
//!Effects: If owns() before the call, then unlock_sharable() is called on mutex().
- //! *this gets the state of upgr and upgr gets set to a default constructed state.
+ //! *this gets the state of upgr and upgr gets set to a default constructed state.
//!Notes: With a recursive mutex it is possible that both this and upgr own the mutex
//! before the assignment. In this case, this will own the mutex after the assignment
//! (and upgr will not), but the mutex's lock count will be decremented by one.
sharable_lock &operator=(BOOST_RV_REF(sharable_lock<mutex_type>) upgr)
- {
+ {
if(this->owns())
this->unlock();
m_locked = upgr.owns();
@@ -203,7 +203,7 @@ class sharable_lock
//!Notes: The sharable_lock changes from a state of not owning the
//! mutex, to owning the mutex, blocking if necessary.
void lock()
- {
+ {
if(!mp_mutex || m_locked)
throw lock_exception();
mp_mutex->lock_sharable();
@@ -219,7 +219,7 @@ class sharable_lock
//! mutex_type does not support try_lock_sharable(), this function will
//! fail at compile time if instantiated, but otherwise have no effect.
bool try_lock()
- {
+ {
if(!mp_mutex || m_locked)
throw lock_exception();
m_locked = mp_mutex->try_lock_sharable();
@@ -236,7 +236,7 @@ class sharable_lock
//! timed_lock_sharable(), this function will fail at compile time if
//! instantiated, but otherwise have no effect.
bool timed_lock(const boost::posix_time::ptime& abs_time)
- {
+ {
if(!mp_mutex || m_locked)
throw lock_exception();
m_locked = mp_mutex->timed_lock_sharable(abs_time);
@@ -282,7 +282,7 @@ class sharable_lock
return mut;
}
- //!Effects: Swaps state with moved lock.
+ //!Effects: Swaps state with moved lock.
//!Throws: Nothing.
void swap(sharable_lock<mutex_type> &other)
{
diff --git a/boost/interprocess/sync/shm/named_condition.hpp b/boost/interprocess/sync/shm/named_condition.hpp
index 0d67c25757..9d7cd77e11 100644
--- a/boost/interprocess/sync/shm/named_condition.hpp
+++ b/boost/interprocess/sync/shm/named_condition.hpp
@@ -28,7 +28,7 @@
#include <boost/interprocess/sync/shm/named_creation_functor.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/interprocess/permissions.hpp>
-#if defined BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES
+#if defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#endif
@@ -42,7 +42,7 @@ namespace interprocess {
namespace ipcdetail {
/// @cond
-namespace ipcdetail{ class interprocess_tester; }
+class interprocess_tester;
/// @endcond
//! A global condition variable that can be created by name.
@@ -61,7 +61,7 @@ class shm_named_condition
//!If the condition can't be created throws interprocess_exception
shm_named_condition(create_only_t create_only, const char *name, const permissions &perm = permissions());
- //!Opens or creates a global condition with a name.
+ //!Opens or creates a global condition with a name.
//!If the condition is created, this call is equivalent to
//!shm_named_condition(create_only_t, ... )
//!If the condition is already created, this call is equivalent
@@ -82,7 +82,7 @@ class shm_named_condition
//!use remove().
~shm_named_condition();
- //!If there is a thread waiting on *this, change that
+ //!If there is a thread waiting on *this, change that
//!thread's state to ready. Otherwise there is no effect.*/
void notify_one();
@@ -90,8 +90,8 @@ class shm_named_condition
//!If there are no waiting threads, notify_all() has no effect.
void notify_all();
- //!Releases the lock on the named_mutex object associated with lock, blocks
- //!the current thread of execution until readied by a call to
+ //!Releases the lock on the named_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
//!this->notify_one() or this->notify_all(), and then reacquires the lock.
template <typename L>
void wait(L& lock);
@@ -101,16 +101,16 @@ class shm_named_condition
template <typename L, typename Pr>
void wait(L& lock, Pr pred);
- //!Releases the lock on the named_mutex object associated with lock, blocks
- //!the current thread of execution until readied by a call to
- //!this->notify_one() or this->notify_all(), or until time abs_time is reached,
+ //!Releases the lock on the named_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
+ //!this->notify_one() or this->notify_all(), or until time abs_time is reached,
//!and then reacquires the lock.
//!Returns: false if time abs_time is reached, otherwise true.
template <typename L>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time);
- //!The same as: while (!pred()) {
- //! if (!timed_wait(lock, abs_time)) return pred();
+ //!The same as: while (!pred()) {
+ //! if (!timed_wait(lock, abs_time)) return pred();
//! } return true;
template <typename L, typename Pr>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred);
@@ -147,6 +147,9 @@ class shm_named_condition
void unlock() { l_.lock(); }
};
+ //If named mutex uses POSIX semaphores, then the shm based condition variable
+ //must use it's internal lock to wait, as sem_t does not store a pthread_mutex_t
+ //instance needed by pthread_mutex_cond_t
#if defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
interprocess_mutex *mutex() const
{ return &static_cast<condition_holder*>(m_shmem.get_user_address())->mutex_; }
@@ -156,7 +159,7 @@ class shm_named_condition
{
//shm_named_condition only works with named_mutex
BOOST_STATIC_ASSERT((is_convertible<typename Lock::mutex_type&, named_mutex&>::value == true));
-
+
//lock internal before unlocking external to avoid race with a notifier
scoped_lock<interprocess_mutex> internal_lock(*this->mutex());
lock_inverter<Lock> inverted_lock(lock);
@@ -173,18 +176,18 @@ class shm_named_condition
{
//shm_named_condition only works with named_mutex
BOOST_STATIC_ASSERT((is_convertible<typename Lock::mutex_type&, named_mutex&>::value == true));
- //lock internal before unlocking external to avoid race with a notifier
- scoped_lock<interprocess_mutex> internal_lock(*this->mutex(), abs_time);
+ //lock internal before unlocking external to avoid race with a notifier
+ scoped_lock<interprocess_mutex> internal_lock(*this->mutex(), abs_time);
if(!internal_lock) return false;
- lock_inverter<Lock> inverted_lock(lock);
- scoped_lock<lock_inverter<Lock> > external_unlock(inverted_lock);
+ lock_inverter<Lock> inverted_lock(lock);
+ scoped_lock<lock_inverter<Lock> > external_unlock(inverted_lock);
- //unlock internal first to avoid deadlock with near simultaneous waits
- scoped_lock<interprocess_mutex> internal_unlock;
- internal_lock.swap(internal_unlock);
- return this->condition()->timed_wait(internal_unlock, abs_time);
+ //unlock internal first to avoid deadlock with near simultaneous waits
+ scoped_lock<interprocess_mutex> internal_unlock;
+ internal_lock.swap(internal_unlock);
+ return this->condition()->timed_wait(internal_unlock, abs_time);
}
- #else
+ #else //defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
template<class Lock>
class lock_wrapper
{
@@ -210,7 +213,7 @@ class shm_named_condition
private:
Lock &l_;
};
- #endif
+ #endif //defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
friend class boost::interprocess::ipcdetail::interprocess_tester;
void dont_close_on_destruction();
diff --git a/boost/interprocess/sync/shm/named_creation_functor.hpp b/boost/interprocess/sync/shm/named_creation_functor.hpp
index 11a1db1d6f..9d752c837a 100644
--- a/boost/interprocess/sync/shm/named_creation_functor.hpp
+++ b/boost/interprocess/sync/shm/named_creation_functor.hpp
@@ -38,7 +38,7 @@ class named_creation_functor
{ new(address)T(m_arg); }
bool operator()(void *address, std::size_t, bool created) const
- {
+ {
switch(m_creation_type){
case DoOpen:
return true;
diff --git a/boost/interprocess/sync/shm/named_mutex.hpp b/boost/interprocess/sync/shm/named_mutex.hpp
index a71eb4fe68..f32fa70044 100644
--- a/boost/interprocess/sync/shm/named_mutex.hpp
+++ b/boost/interprocess/sync/shm/named_mutex.hpp
@@ -37,7 +37,7 @@ namespace ipcdetail {
class named_condition;
-//!A mutex with a global name, so it can be found from different
+//!A mutex with a global name, so it can be found from different
//!processes. This mutex can't be placed in shared memory, and
//!each process should have it's own named mutex.
class shm_named_mutex
@@ -56,7 +56,7 @@ class shm_named_mutex
//!Throws interprocess_exception on error.
shm_named_mutex(create_only_t create_only, const char *name, const permissions &perm = permissions());
- //!Opens or creates a global mutex with a name.
+ //!Opens or creates a global mutex with a name.
//!If the mutex is created, this call is equivalent to
//!shm_named_mutex(create_only_t, ... )
//!If the mutex is already created, this call is equivalent
@@ -85,7 +85,7 @@ class shm_named_mutex
//!Throws interprocess_exception if a severe error is found
void lock();
- //!Tries to lock the interprocess_mutex, returns false when interprocess_mutex
+ //!Tries to lock the interprocess_mutex, returns false when interprocess_mutex
//!is already locked, returns true when success.
//!Throws interprocess_exception if a severe error is found
bool try_lock();
diff --git a/boost/interprocess/sync/shm/named_recursive_mutex.hpp b/boost/interprocess/sync/shm/named_recursive_mutex.hpp
index 461c97eb32..7235571254 100644
--- a/boost/interprocess/sync/shm/named_recursive_mutex.hpp
+++ b/boost/interprocess/sync/shm/named_recursive_mutex.hpp
@@ -51,7 +51,7 @@ class shm_named_recursive_mutex
//!If the recursive_mutex can't be created throws interprocess_exception
shm_named_recursive_mutex(create_only_t create_only, const char *name, const permissions &perm = permissions());
- //!Opens or creates a global recursive_mutex with a name.
+ //!Opens or creates a global recursive_mutex with a name.
//!If the recursive_mutex is created, this call is equivalent to
//!shm_named_recursive_mutex(create_only_t, ... )
//!If the recursive_mutex is already created, this call is equivalent
@@ -80,7 +80,7 @@ class shm_named_recursive_mutex
//!Throws interprocess_exception if a severe error is found.
void lock();
- //!Tries to lock the shm_named_recursive_mutex, returns false when shm_named_recursive_mutex
+ //!Tries to lock the shm_named_recursive_mutex, returns false when shm_named_recursive_mutex
//!is already locked, returns true when success.
//!Throws interprocess_exception if a severe error is found.
bool try_lock();
diff --git a/boost/interprocess/sync/shm/named_upgradable_mutex.hpp b/boost/interprocess/sync/shm/named_upgradable_mutex.hpp
index 338fa98f7d..0975a6ed2b 100644
--- a/boost/interprocess/sync/shm/named_upgradable_mutex.hpp
+++ b/boost/interprocess/sync/shm/named_upgradable_mutex.hpp
@@ -38,7 +38,7 @@ namespace ipcdetail{ class interprocess_tester; }
class named_condition;
-//!A upgradable mutex with a global name, so it can be found from different
+//!A upgradable mutex with a global name, so it can be found from different
//!processes. This mutex can't be placed in shared memory, and
//!each process should have it's own named upgradable mutex.
class named_upgradable_mutex
@@ -52,11 +52,11 @@ class named_upgradable_mutex
/// @endcond
public:
- //!Creates a global upgradable mutex with a name.
+ //!Creates a global upgradable mutex with a name.
//!If the upgradable mutex can't be created throws interprocess_exception
named_upgradable_mutex(create_only_t create_only, const char *name, const permissions &perm = permissions());
- //!Opens or creates a global upgradable mutex with a name, and an initial count.
+ //!Opens or creates a global upgradable mutex with a name, and an initial count.
//!If the upgradable mutex is created, this call is equivalent to
//!named_upgradable_mutex(create_only_t, ...)
//!If the upgradable mutex is already created, this call is equivalent to
@@ -95,13 +95,13 @@ class named_upgradable_mutex
//!Effects: The calling thread tries to acquire exclusive ownership of the mutex
//! waiting if necessary until no other thread has exclusive, sharable or
- //! upgradable ownership of the mutex or abs_time is reached.
- //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //! upgradable ownership of the mutex or abs_time is reached.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: interprocess_exception on error.
bool timed_lock(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have exclusive ownership of the mutex.
- //!Effects: The calling thread releases the exclusive ownership of the mutex.
+ //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Effects: The calling thread releases the exclusive ownership of the mutex.
//!Throws: An exception derived from interprocess_exception on error.
void unlock();
@@ -115,21 +115,21 @@ class named_upgradable_mutex
//!Effects: The calling thread tries to acquire sharable ownership of the mutex
//! without waiting. If no other thread has exclusive ownership
- //! of the mutex this succeeds.
+ //! of the mutex this succeeds.
//!Returns: If it can acquire sharable ownership immediately returns true. If it
- //! has to wait, returns false.
+ //! has to wait, returns false.
//!Throws: interprocess_exception on error.
bool try_lock_sharable();
//!Effects: The calling thread tries to acquire sharable ownership of the mutex
//! waiting if necessary until no other thread has exclusive
- //! ownership of the mutex or abs_time is reached.
- //!Returns: If acquires sharable ownership, returns true. Otherwise returns false.
+ //! ownership of the mutex or abs_time is reached.
+ //!Returns: If acquires sharable ownership, returns true. Otherwise returns false.
//!Throws: interprocess_exception on error.
bool timed_lock_sharable(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have sharable ownership of the mutex.
- //!Effects: The calling thread releases the sharable ownership of the mutex.
+ //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Effects: The calling thread releases the sharable ownership of the mutex.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_sharable();
@@ -143,7 +143,7 @@ class named_upgradable_mutex
//!Effects: The calling thread tries to acquire upgradable ownership of the mutex
//! without waiting. If no other thread has exclusive or upgradable ownership
- //! of the mutex this succeeds.
+ //! of the mutex this succeeds.
//!Returns: If it can acquire upgradable ownership immediately returns true.
//! If it has to wait, returns false.
//!Throws: interprocess_exception on error.
@@ -152,66 +152,66 @@ class named_upgradable_mutex
//!Effects: The calling thread tries to acquire upgradable ownership of the mutex
//! waiting if necessary until no other thread has exclusive or upgradable
//! ownership of the mutex or abs_time is reached.
- //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
+ //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
//!Throws: interprocess_exception on error.
bool timed_lock_upgradable(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have upgradable ownership of the mutex.
- //!Effects: The calling thread releases the upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Effects: The calling thread releases the upgradable ownership of the mutex.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable();
//Demotions
- //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Precondition: The thread must have exclusive ownership of the mutex.
//!Effects: The thread atomically releases exclusive ownership and acquires
- //! upgradable ownership. This operation is non-blocking.
+ //! upgradable ownership. This operation is non-blocking.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_and_lock_upgradable();
- //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Precondition: The thread must have exclusive ownership of the mutex.
//!Effects: The thread atomically releases exclusive ownership and acquires
- //! sharable ownership. This operation is non-blocking.
+ //! sharable ownership. This operation is non-blocking.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_and_lock_sharable();
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and acquires
- //! sharable ownership. This operation is non-blocking.
+ //! sharable ownership. This operation is non-blocking.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable_and_lock_sharable();
//Promotions
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and acquires
//! exclusive ownership. This operation will block until all threads with
- //! sharable ownership release it.
+ //! sharable ownership release it.
//!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable_and_lock();
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and tries to
//! acquire exclusive ownership. This operation will fail if there are threads
- //! with sharable ownership, but it will maintain upgradable ownership.
+ //! with sharable ownership, but it will maintain upgradable ownership.
//!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_upgradable_and_lock();
- //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Precondition: The thread must have upgradable ownership of the mutex.
//!Effects: The thread atomically releases upgradable ownership and tries to acquire
//! exclusive ownership, waiting if necessary until abs_time. This operation will
//! fail if there are threads with sharable ownership or timeout reaches, but it
- //! will maintain upgradable ownership.
- //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //! will maintain upgradable ownership.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: An exception derived from interprocess_exception on error.
bool timed_unlock_upgradable_and_lock(const boost::posix_time::ptime &abs_time);
- //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Precondition: The thread must have sharable ownership of the mutex.
//!Effects: The thread atomically releases sharable ownership and tries to acquire
//! exclusive ownership. This operation will fail if there are threads with sharable
//! or upgradable ownership, but it will maintain sharable ownership.
- //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
//!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_sharable_and_lock();
diff --git a/boost/interprocess/sync/spin/condition.hpp b/boost/interprocess/sync/spin/condition.hpp
index 5a37d9be2d..55dd79b406 100644
--- a/boost/interprocess/sync/spin/condition.hpp
+++ b/boost/interprocess/sync/spin/condition.hpp
@@ -110,7 +110,7 @@ inline spin_condition::spin_condition()
}
inline spin_condition::~spin_condition()
-{
+{
//Trivial destructor
}
@@ -126,15 +126,15 @@ inline void spin_condition::notify_all()
inline void spin_condition::notify(boost::uint32_t command)
{
- //This mutex guarantees that no other thread can enter to the
+ //This mutex guarantees that no other thread can enter to the
//do_timed_wait method logic, so that thread count will be
//constant until the function writes a NOTIFY_ALL command.
- //It also guarantees that no other notification can be signaled
+ //It also guarantees that no other notification can be signaled
//on this spin_condition before this one ends
m_enter_mut.lock();
//Return if there are no waiters
- if(!atomic_read32(&m_num_waiters)) {
+ if(!atomic_read32(&m_num_waiters)) {
m_enter_mut.unlock();
return;
}
@@ -167,18 +167,18 @@ inline bool spin_condition::do_timed_wait
template<class InterprocessMutex>
inline bool spin_condition::do_timed_wait(bool tout_enabled,
- const boost::posix_time::ptime &abs_time,
+ const boost::posix_time::ptime &abs_time,
InterprocessMutex &mut)
{
boost::posix_time::ptime now = microsec_clock::universal_time();
-
+
if(tout_enabled){
if(now >= abs_time) return false;
}
typedef boost::interprocess::scoped_lock<spin_mutex> InternalLock;
- //The enter mutex guarantees that while executing a notification,
- //no other thread can execute the do_timed_wait method.
+ //The enter mutex guarantees that while executing a notification,
+ //no other thread can execute the do_timed_wait method.
{
//---------------------------------------------------------------
InternalLock lock;
@@ -205,8 +205,8 @@ inline bool spin_condition::do_timed_wait(bool tout_enabled,
//By default, we suppose that no timeout has happened
bool timed_out = false, unlock_enter_mut= false;
-
- //Loop until a notification indicates that the thread should
+
+ //Loop until a notification indicates that the thread should
//exit or timeout occurs
while(1){
//The thread sleeps/spins until a spin_condition commands a notification
@@ -229,8 +229,8 @@ inline bool spin_condition::do_timed_wait(bool tout_enabled,
//There is an ongoing notification, we will try again later
continue;
}
- //No notification in execution, since enter mutex is locked.
- //We will execute time-out logic, so we will decrement count,
+ //No notification in execution, since enter mutex is locked.
+ //We will execute time-out logic, so we will decrement count,
//release the enter mutex and return false.
break;
}
@@ -253,7 +253,7 @@ inline bool spin_condition::do_timed_wait(bool tout_enabled,
continue;
}
else if(result == NOTIFY_ONE){
- //If it was a NOTIFY_ONE command, only this thread should
+ //If it was a NOTIFY_ONE command, only this thread should
//exit. This thread has atomically marked command as sleep before
//so no other thread will exit.
//Decrement wait count.
@@ -262,8 +262,8 @@ inline bool spin_condition::do_timed_wait(bool tout_enabled,
break;
}
else{
- //If it is a NOTIFY_ALL command, all threads should return
- //from do_timed_wait function. Decrement wait count.
+ //If it is a NOTIFY_ALL command, all threads should return
+ //from do_timed_wait function. Decrement wait count.
unlock_enter_mut = 1 == atomic_dec32(const_cast<boost::uint32_t*>(&m_num_waiters));
//Check if this is the last thread of notify_all waiters
//Only the last thread will release the mutex
@@ -275,7 +275,7 @@ inline bool spin_condition::do_timed_wait(bool tout_enabled,
}
}
- //Unlock the enter mutex if it is a single notification, if this is
+ //Unlock the enter mutex if it is a single notification, if this is
//the last notified thread in a notify_all or a timeout has occurred
if(unlock_enter_mut){
m_enter_mut.unlock();
diff --git a/boost/interprocess/sync/spin/mutex.hpp b/boost/interprocess/sync/spin/mutex.hpp
index ef0b47d95a..926f7237c0 100644
--- a/boost/interprocess/sync/spin/mutex.hpp
+++ b/boost/interprocess/sync/spin/mutex.hpp
@@ -45,15 +45,15 @@ class spin_mutex
volatile boost::uint32_t m_s;
};
-inline spin_mutex::spin_mutex()
- : m_s(0)
+inline spin_mutex::spin_mutex()
+ : m_s(0)
{
//Note that this class is initialized to zero.
//So zeroed memory can be interpreted as an
//initialized mutex
}
-inline spin_mutex::~spin_mutex()
+inline spin_mutex::~spin_mutex()
{
//Trivial destructor
}
@@ -73,7 +73,7 @@ inline void spin_mutex::lock(void)
inline bool spin_mutex::try_lock(void)
{
- boost::uint32_t prev_s = ipcdetail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 1, 0);
+ boost::uint32_t prev_s = ipcdetail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 1, 0);
return m_s == 1 && prev_s == 0;
}
diff --git a/boost/interprocess/sync/spin/recursive_mutex.hpp b/boost/interprocess/sync/spin/recursive_mutex.hpp
index 05ad65eac0..a763f9c72d 100644
--- a/boost/interprocess/sync/spin/recursive_mutex.hpp
+++ b/boost/interprocess/sync/spin/recursive_mutex.hpp
@@ -68,7 +68,7 @@ class spin_recursive_mutex
volatile boost::uint32_t m_s;
};
-inline spin_recursive_mutex::spin_recursive_mutex()
+inline spin_recursive_mutex::spin_recursive_mutex()
: m_nLockCount(0), m_nOwner(ipcdetail::get_invalid_systemwide_thread_id()){}
inline spin_recursive_mutex::~spin_recursive_mutex(){}
@@ -83,7 +83,7 @@ inline void spin_recursive_mutex::lock()
if((unsigned int)(m_nLockCount+1) == 0){
//Overflow, throw an exception
throw interprocess_exception("boost::interprocess::spin_recursive_mutex recursive lock overflow");
- }
+ }
++m_nLockCount;
}
else{
@@ -103,7 +103,7 @@ inline bool spin_recursive_mutex::try_lock()
if((unsigned int)(m_nLockCount+1) == 0){
//Overflow, throw an exception
throw interprocess_exception("boost::interprocess::spin_recursive_mutex recursive lock overflow");
- }
+ }
++m_nLockCount;
return true;
}
@@ -129,7 +129,7 @@ inline bool spin_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs
if((unsigned int)(m_nLockCount+1) == 0){
//Overflow, throw an exception
throw interprocess_exception("boost::interprocess::spin_recursive_mutex recursive lock overflow");
- }
+ }
++m_nLockCount;
return true;
}
diff --git a/boost/interprocess/sync/upgradable_lock.hpp b/boost/interprocess/sync/upgradable_lock.hpp
index 93c2ed6bc4..fb86374ca1 100644
--- a/boost/interprocess/sync/upgradable_lock.hpp
+++ b/boost/interprocess/sync/upgradable_lock.hpp
@@ -85,7 +85,7 @@ class upgradable_lock
: mp_mutex(&m), m_locked(true)
{}
- //!Effects: m.try_lock_upgradable().
+ //!Effects: m.try_lock_upgradable().
//!Postconditions: mutex() == &m. owns() == the return value of the
//! m.try_lock_upgradable() executed within the constructor.
//!Notes: The constructor will take upgradable-ownership of the mutex
@@ -97,7 +97,7 @@ class upgradable_lock
: mp_mutex(&m), m_locked(false)
{ m_locked = mp_mutex->try_lock_upgradable(); }
- //!Effects: m.timed_lock_upgradable(abs_time)
+ //!Effects: m.timed_lock_upgradable(abs_time)
//!Postconditions: mutex() == &m. owns() == the return value of the
//! m.timed_lock_upgradable() executed within the constructor.
//!Notes: The constructor will take upgradable-ownership of the mutex if it
@@ -123,7 +123,7 @@ class upgradable_lock
: mp_mutex(0), m_locked(upgr.owns())
{ mp_mutex = upgr.release(); }
- //!Effects: If scop.owns(), m_.unlock_and_lock_upgradable().
+ //!Effects: If scop.owns(), m_.unlock_and_lock_upgradable().
//!Postconditions: mutex() == the value scop.mutex() had before the construction.
//! scop.mutex() == 0. owns() == scop.owns() before the constructor. After the
//! construction, scop.owns() == false.
@@ -146,12 +146,12 @@ class upgradable_lock
}
//!Effects: If shar.owns() then calls try_unlock_sharable_and_lock_upgradable()
- //! on the referenced mutex.
+ //! on the referenced mutex.
//! a)if try_unlock_sharable_and_lock_upgradable() returns true then mutex()
- //! obtains the value from shar.release() and owns() is set to true.
+ //! obtains the value from shar.release() and owns() is set to true.
//! b)if try_unlock_sharable_and_lock_upgradable() returns false then shar is
//! unaffected and this upgradable_lock construction has the same
- //! effects as a default construction.
+ //! effects as a default construction.
//! c)Else shar.owns() is false. mutex() obtains the value from shar.release()
//! and owns() is set to false.
//!Notes: This construction will not block. It will try to obtain mutex
@@ -207,7 +207,7 @@ class upgradable_lock
//!Notes: The sharable_lock changes from a state of not owning the mutex,
//! to owning the mutex, blocking if necessary.
void lock()
- {
+ {
if(!mp_mutex || m_locked)
throw lock_exception();
mp_mutex->lock_upgradable();
@@ -223,7 +223,7 @@ class upgradable_lock
//! mutex_type does not support try_lock_upgradable(), this function will
//! fail at compile time if instantiated, but otherwise have no effect.
bool try_lock()
- {
+ {
if(!mp_mutex || m_locked)
throw lock_exception();
m_locked = mp_mutex->try_lock_upgradable();
@@ -240,7 +240,7 @@ class upgradable_lock
//! timed_lock_upgradable(abs_time), this function will fail at compile
//! time if instantiated, but otherwise have no effect.
bool timed_lock(const boost::posix_time::ptime& abs_time)
- {
+ {
if(!mp_mutex || m_locked)
throw lock_exception();
m_locked = mp_mutex->timed_lock_upgradable(abs_time);
@@ -286,7 +286,7 @@ class upgradable_lock
return mut;
}
- //!Effects: Swaps state with moved lock.
+ //!Effects: Swaps state with moved lock.
//!Throws: Nothing.
void swap(upgradable_lock<mutex_type> &other)
{
diff --git a/boost/interprocess/sync/windows/condition.hpp b/boost/interprocess/sync/windows/condition.hpp
index 167b8730c3..9695c21044 100644
--- a/boost/interprocess/sync/windows/condition.hpp
+++ b/boost/interprocess/sync/windows/condition.hpp
@@ -20,133 +20,8 @@
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/sync/windows/semaphore.hpp>
#include <boost/interprocess/sync/windows/mutex.hpp>
-#include <boost/cstdint.hpp>
-#include <limits>
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-//
-// Condition variable algorithm taken from pthreads-win32 discussion.
-//
-// The algorithm was developed by Alexander Terekhov in colaboration with
-// Louis Thomas.
-//
-// Algorithm 8a / IMPL_SEM,UNBLOCK_STRATEGY == UNBLOCK_ALL
-//
-// semBlockLock - bin.semaphore
-// semBlockQueue - semaphore
-// mtxExternal - mutex or CS
-// mtxUnblockLock - mutex or CS
-// nWaitersGone - int
-// nWaitersBlocked - int
-// nWaitersToUnblock - int
-//
-// wait( timeout ) {
-//
-// [auto: register int result ] // error checking omitted
-// [auto: register int nSignalsWasLeft ]
-// [auto: register int nWaitersWasGone ]
-//
-// sem_wait( semBlockLock );
-// nWaitersBlocked++;
-// sem_post( semBlockLock );
-//
-// unlock( mtxExternal );
-// bTimedOut = sem_wait( semBlockQueue,timeout );
-//
-// lock( mtxUnblockLock );
-// if ( 0 != (nSignalsWasLeft = nWaitersToUnblock) ) {
-// if ( bTimedOut ) { // timeout (or canceled)
-// if ( 0 != nWaitersBlocked ) {
-// nWaitersBlocked--;
-// }
-// else {
-// nWaitersGone++; // count spurious wakeups.
-// }
-// }
-// if ( 0 == --nWaitersToUnblock ) {
-// if ( 0 != nWaitersBlocked ) {
-// sem_post( semBlockLock ); // open the gate.
-// nSignalsWasLeft = 0; // do not open the gate
-// // below again.
-// }
-// else if ( 0 != (nWaitersWasGone = nWaitersGone) ) {
-// nWaitersGone = 0;
-// }
-// }
-// }
-// else if ( INT_MAX/2 == ++nWaitersGone ) { // timeout/canceled or
-// // spurious semaphore :-)
-// sem_wait( semBlockLock );
-// nWaitersBlocked -= nWaitersGone; // something is going on here
-// // - test of timeouts? :-)
-// sem_post( semBlockLock );
-// nWaitersGone = 0;
-// }
-// unlock( mtxUnblockLock );
-//
-// if ( 1 == nSignalsWasLeft ) {
-// if ( 0 != nWaitersWasGone ) {
-// // sem_adjust( semBlockQueue,-nWaitersWasGone );
-// while ( nWaitersWasGone-- ) {
-// sem_wait( semBlockQueue ); // better now than spurious later
-// }
-// } sem_post( semBlockLock ); // open the gate
-// }
-//
-// lock( mtxExternal );
-//
-// return ( bTimedOut ) ? ETIMEOUT : 0;
-// }
-//
-// signal(bAll) {
-//
-// [auto: register int result ]
-// [auto: register int nSignalsToIssue]
-//
-// lock( mtxUnblockLock );
-//
-// if ( 0 != nWaitersToUnblock ) { // the gate is closed!!!
-// if ( 0 == nWaitersBlocked ) { // NO-OP
-// return unlock( mtxUnblockLock );
-// }
-// if (bAll) {
-// nWaitersToUnblock += nSignalsToIssue=nWaitersBlocked;
-// nWaitersBlocked = 0;
-// }
-// else {
-// nSignalsToIssue = 1;
-// nWaitersToUnblock++;
-// nWaitersBlocked--;
-// }
-// }
-// else if ( nWaitersBlocked > nWaitersGone ) { // HARMLESS RACE CONDITION!
-// sem_wait( semBlockLock ); // close the gate
-// if ( 0 != nWaitersGone ) {
-// nWaitersBlocked -= nWaitersGone;
-// nWaitersGone = 0;
-// }
-// if (bAll) {
-// nSignalsToIssue = nWaitersToUnblock = nWaitersBlocked;
-// nWaitersBlocked = 0;
-// }
-// else {
-// nSignalsToIssue = nWaitersToUnblock = 1;
-// nWaitersBlocked--;
-// }
-// }
-// else { // NO-OP
-// return unlock( mtxUnblockLock );
-// }
-//
-// unlock( mtxUnblockLock );
-// sem_post( semBlockQueue,nSignalsToIssue );
-// return result;
-// }
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
+#include <boost/interprocess/sync/detail/condition_algorithm_8a.hpp>
+
namespace boost {
namespace interprocess {
@@ -156,6 +31,7 @@ class windows_condition
{
windows_condition(const windows_condition &);
windows_condition &operator=(const windows_condition &);
+
public:
windows_condition();
~windows_condition();
@@ -217,162 +93,71 @@ class windows_condition
private:
- template<class InterprocessMutex>
- bool do_timed_wait(bool timeout_enabled, const boost::posix_time::ptime &abs_time, InterprocessMutex &mut);
- void do_signal (bool broadcast);
-
- boost::int32_t m_nwaiters_blocked;
- boost::int32_t m_nwaiters_gone;
- boost::int32_t m_nwaiters_to_unblock;
- windows_semaphore m_sem_block_queue;
- windows_semaphore m_sem_block_lock;
- windows_mutex m_mtx_unblock_lock;
+ struct condition_data
+ {
+ typedef boost::int32_t integer_type;
+ typedef windows_semaphore semaphore_type;
+ typedef windows_mutex mutex_type;
+
+ condition_data()
+ : m_nwaiters_blocked(0)
+ , m_nwaiters_gone(0)
+ , m_nwaiters_to_unblock(0)
+ , m_sem_block_queue(0)
+ , m_sem_block_lock(1)
+ , m_mtx_unblock_lock()
+ {}
+
+ integer_type &get_nwaiters_blocked()
+ { return m_nwaiters_blocked; }
+
+ integer_type &get_nwaiters_gone()
+ { return m_nwaiters_gone; }
+
+ integer_type &get_nwaiters_to_unblock()
+ { return m_nwaiters_to_unblock; }
+
+ semaphore_type &get_sem_block_queue()
+ { return m_sem_block_queue; }
+
+ semaphore_type &get_sem_block_lock()
+ { return m_sem_block_lock; }
+
+ mutex_type &get_mtx_unblock_lock()
+ { return m_mtx_unblock_lock; }
+
+ boost::int32_t m_nwaiters_blocked;
+ boost::int32_t m_nwaiters_gone;
+ boost::int32_t m_nwaiters_to_unblock;
+ windows_semaphore m_sem_block_queue;
+ windows_semaphore m_sem_block_lock;
+ windows_mutex m_mtx_unblock_lock;
+ } m_condition_data;
+
+ typedef condition_algorithm_8a<condition_data> algorithm_type;
};
inline windows_condition::windows_condition()
- : m_nwaiters_blocked(0)
- , m_nwaiters_gone(0)
- , m_nwaiters_to_unblock(0)
- , m_sem_block_queue(0)
- , m_sem_block_lock(1)
- , m_mtx_unblock_lock()
+ : m_condition_data()
{}
inline windows_condition::~windows_condition()
{}
inline void windows_condition::notify_one()
-{ this->do_signal(false); }
+{ algorithm_type::signal(m_condition_data, false); }
inline void windows_condition::notify_all()
-{ this->do_signal(true); }
-
-inline void windows_condition::do_signal(bool broadcast)
-{
- boost::int32_t nsignals_to_issue;
-
- {
- scoped_lock<windows_mutex> locker(m_mtx_unblock_lock);
-
- if ( 0 != m_nwaiters_to_unblock ) { // the gate is closed!!!
- if ( 0 == m_nwaiters_blocked ) { // NO-OP
- //locker's destructor triggers m_mtx_unblock_lock.unlock()
- return;
- }
- if (broadcast) {
- m_nwaiters_to_unblock += nsignals_to_issue = m_nwaiters_blocked;
- m_nwaiters_blocked = 0;
- }
- else {
- nsignals_to_issue = 1;
- m_nwaiters_to_unblock++;
- m_nwaiters_blocked--;
- }
- }
- else if ( m_nwaiters_blocked > m_nwaiters_gone ) { // HARMLESS RACE CONDITION!
- m_sem_block_lock.wait(); // close the gate
- if ( 0 != m_nwaiters_gone ) {
- m_nwaiters_blocked -= m_nwaiters_gone;
- m_nwaiters_gone = 0;
- }
- if (broadcast) {
- nsignals_to_issue = m_nwaiters_to_unblock = m_nwaiters_blocked;
- m_nwaiters_blocked = 0;
- }
- else {
- nsignals_to_issue = m_nwaiters_to_unblock = 1;
- m_nwaiters_blocked--;
- }
- }
- else { // NO-OP
- //locker's destructor triggers m_mtx_unblock_lock.unlock()
- return;
- }
- //locker's destructor triggers m_mtx_unblock_lock.unlock()
- }
- m_sem_block_queue.post(nsignals_to_issue);
-}
+{ algorithm_type::signal(m_condition_data, true); }
template<class InterprocessMutex>
inline void windows_condition::do_wait(InterprocessMutex &mut)
-{ this->do_timed_wait(false, boost::posix_time::ptime(), mut); }
+{ algorithm_type::wait(m_condition_data, false, boost::posix_time::ptime(), mut); }
template<class InterprocessMutex>
inline bool windows_condition::do_timed_wait
(const boost::posix_time::ptime &abs_time, InterprocessMutex &mut)
-{ return this->do_timed_wait(true, abs_time, mut); }
-
-template<class InterprocessMutex>
-inline bool windows_condition::do_timed_wait
- (bool tout_enabled, const boost::posix_time::ptime &abs_time, InterprocessMutex &mtxExternal)
-{
- //Initialize to avoid warnings
- boost::int32_t nsignals_was_left = 0;
- boost::int32_t nwaiters_was_gone = 0;
-
- m_sem_block_lock.wait();
- ++m_nwaiters_blocked;
- m_sem_block_lock.post();
-
- struct scoped_unlock
- {
- InterprocessMutex & mut;
- scoped_unlock(InterprocessMutex & m)
- : mut(m)
- { m.unlock(); }
-
- ~scoped_unlock()
- { mut.lock(); }
- } unlocker(mtxExternal);
-
-
- bool bTimedOut = tout_enabled ? !m_sem_block_queue.timed_wait(abs_time) : (m_sem_block_queue.wait(), false);
-
- {
- scoped_lock<windows_mutex> locker(m_mtx_unblock_lock);
- if ( 0 != (nsignals_was_left = m_nwaiters_to_unblock) ) {
- if ( bTimedOut ) { // timeout (or canceled)
- if ( 0 != m_nwaiters_blocked ) {
- m_nwaiters_blocked--;
- }
- else {
- m_nwaiters_gone++; // count spurious wakeups.
- }
- }
- if ( 0 == --m_nwaiters_to_unblock ) {
- if ( 0 != m_nwaiters_blocked ) {
- m_sem_block_lock.post(); // open the gate.
- nsignals_was_left = 0; // do not open the gate below again.
- }
- else if ( 0 != (nwaiters_was_gone = m_nwaiters_gone) ) {
- m_nwaiters_gone = 0;
- }
- }
- }
- else if ( (std::numeric_limits<boost::int32_t>::max)()/2
- == ++m_nwaiters_gone ) { // timeout/canceled or spurious semaphore :-)
- m_sem_block_lock.wait();
- m_nwaiters_blocked -= m_nwaiters_gone; // something is going on here - test of timeouts? :-)
- m_sem_block_lock.post();
- m_nwaiters_gone = 0;
- }
- //locker's destructor triggers m_mtx_unblock_lock.unlock()
- }
-
- if ( 1 == nsignals_was_left ) {
- if ( 0 != nwaiters_was_gone ) {
- // sem_adjust( m_sem_block_queue,-nwaiters_was_gone );
- while ( nwaiters_was_gone-- ) {
- m_sem_block_queue.wait(); // better now than spurious later
- }
- }
- m_sem_block_lock.post(); // open the gate
- }
-
- //mtxExternal.lock(); called from unlocker
-
- return ( bTimedOut ) ? false : true;
-}
+{ return algorithm_type::wait(m_condition_data, true, abs_time, mut); }
} //namespace ipcdetail
} //namespace interprocess
diff --git a/boost/interprocess/sync/windows/mutex.hpp b/boost/interprocess/sync/windows/mutex.hpp
index 5eca522339..477acd396a 100644
--- a/boost/interprocess/sync/windows/mutex.hpp
+++ b/boost/interprocess/sync/windows/mutex.hpp
@@ -19,8 +19,9 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/detail/win32_api.hpp>
-#include <boost/interprocess/detail/intermodule_singleton.hpp>
+#include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
#include <boost/interprocess/sync/windows/sync_utils.hpp>
+#include <boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp>
#include <boost/interprocess/exceptions.hpp>
@@ -47,85 +48,61 @@ class windows_mutex
const sync_id id_;
};
-inline windows_mutex::windows_mutex()
- : id_()
+inline windows_mutex::windows_mutex()
+ : id_(this)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//Create mutex with the initial count
bool open_or_created;
- handles.obtain_mutex(this->id_, &open_or_created);
+ (void)handles.obtain_mutex(this->id_, &open_or_created);
//The mutex must be created, never opened
assert(open_or_created);
assert(open_or_created && winapi::get_last_error() != winapi::error_already_exists);
(void)open_or_created;
}
-inline windows_mutex::~windows_mutex()
+inline windows_mutex::~windows_mutex()
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
handles.destroy_handle(this->id_);
}
inline void windows_mutex::lock(void)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_mutex(this->id_);
- unsigned long ret = winapi::wait_for_single_object(hnd, winapi::infinite_time);
- if(ret == winapi::wait_failed){
- error_info err(winapi::get_last_error());
- throw interprocess_exception(err);
- }
+ winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
+ mut.lock();
}
inline bool windows_mutex::try_lock(void)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_mutex(this->id_);
- unsigned long ret = winapi::wait_for_single_object(hnd, 0);
- if(ret == winapi::wait_failed){
- error_info err(winapi::get_last_error());
- throw interprocess_exception(err);
- }
- return ret != winapi::wait_timeout;
+ winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
+ return mut.try_lock();
}
inline bool windows_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
{
- if(abs_time == boost::posix_time::pos_infin){
- this->lock();
- return true;
- }
- boost::posix_time::ptime now
- = boost::posix_time::microsec_clock::universal_time();
-
- unsigned long ms = (unsigned long)(abs_time-now).total_milliseconds();
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_mutex(this->id_);
- unsigned long ret = winapi::wait_for_single_object(hnd, ms);
- if(ret == winapi::wait_failed){
- error_info err(winapi::get_last_error());
- throw interprocess_exception(err);
- }
- return ret != winapi::wait_timeout;
+ winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
+ return mut.timed_lock(abs_time);
}
inline void windows_mutex::unlock(void)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_mutex(this->id_);
- int ret = winapi::release_mutex(hnd);
- (void)ret;
- assert(ret);
+ winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
+ return mut.unlock();
}
} //namespace ipcdetail {
diff --git a/boost/interprocess/sync/windows/named_condition.hpp b/boost/interprocess/sync/windows/named_condition.hpp
new file mode 100644
index 0000000000..403e826178
--- /dev/null
+++ b/boost/interprocess/sync/windows/named_condition.hpp
@@ -0,0 +1,334 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_HPP
+#define BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/creation_tags.hpp>
+#include <boost/interprocess/permissions.hpp>
+#include <boost/interprocess/detail/interprocess_tester.hpp>
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/sync/windows/named_sync.hpp>
+#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
+#include <boost/interprocess/sync/detail/condition_algorithm_8a.hpp>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+class windows_named_condition
+{
+ /// @cond
+
+ //Non-copyable
+ windows_named_condition();
+ windows_named_condition(const windows_named_condition &);
+ windows_named_condition &operator=(const windows_named_condition &);
+ /// @endcond
+
+ public:
+ windows_named_condition(create_only_t, const char *name, const permissions &perm = permissions());
+
+ windows_named_condition(open_or_create_t, const char *name, const permissions &perm = permissions());
+
+ windows_named_condition(open_only_t, const char *name);
+
+ ~windows_named_condition();
+
+ //!If there is a thread waiting on *this, change that
+ //!thread's state to ready. Otherwise there is no effect.*/
+ void notify_one();
+
+ //!Change the state of all threads waiting on *this to ready.
+ //!If there are no waiting threads, notify_all() has no effect.
+ void notify_all();
+
+ //!Releases the lock on the named_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
+ //!this->notify_one() or this->notify_all(), and then reacquires the lock.
+ template <typename L>
+ void wait(L& lock);
+
+ //!The same as:
+ //!while (!pred()) wait(lock)
+ template <typename L, typename Pr>
+ void wait(L& lock, Pr pred);
+
+ //!Releases the lock on the named_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
+ //!this->notify_one() or this->notify_all(), or until time abs_time is reached,
+ //!and then reacquires the lock.
+ //!Returns: false if time abs_time is reached, otherwise true.
+ template <typename L>
+ bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time);
+
+ //!The same as: while (!pred()) {
+ //! if (!timed_wait(lock, abs_time)) return pred();
+ //! } return true;
+ template <typename L, typename Pr>
+ bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred);
+
+ static bool remove(const char *name);
+
+ /// @cond
+ private:
+ friend class interprocess_tester;
+ void dont_close_on_destruction();
+
+ template <class InterprocessMutex>
+ void do_wait(InterprocessMutex& lock);
+
+ template <class InterprocessMutex>
+ bool do_timed_wait(const boost::posix_time::ptime &abs_time, InterprocessMutex& lock);
+
+ struct condition_data
+ {
+ typedef boost::int32_t integer_type;
+ typedef winapi_semaphore_wrapper semaphore_type;
+ typedef winapi_mutex_wrapper mutex_type;
+
+ integer_type &get_nwaiters_blocked()
+ { return m_nwaiters_blocked; }
+
+ integer_type &get_nwaiters_gone()
+ { return m_nwaiters_gone; }
+
+ integer_type &get_nwaiters_to_unblock()
+ { return m_nwaiters_to_unblock; }
+
+ semaphore_type &get_sem_block_queue()
+ { return m_sem_block_queue; }
+
+ semaphore_type &get_sem_block_lock()
+ { return m_sem_block_lock; }
+
+ mutex_type &get_mtx_unblock_lock()
+ { return m_mtx_unblock_lock; }
+
+ integer_type m_nwaiters_blocked;
+ integer_type m_nwaiters_gone;
+ integer_type m_nwaiters_to_unblock;
+ winapi_semaphore_wrapper m_sem_block_queue;
+ winapi_semaphore_wrapper m_sem_block_lock;
+ winapi_mutex_wrapper m_mtx_unblock_lock;
+ } m_condition_data;
+
+ typedef condition_algorithm_8a<condition_data> algorithm_type;
+
+ class named_cond_callbacks : public windows_named_sync_interface
+ {
+ typedef __int64 sem_count_t;
+ mutable sem_count_t sem_counts [2];
+
+ public:
+ named_cond_callbacks(condition_data &cond_data)
+ : m_condition_data(cond_data)
+ {}
+
+ virtual std::size_t get_data_size() const
+ { return sizeof(sem_counts); }
+
+ virtual const void *buffer_with_final_data_to_file()
+ {
+ sem_counts[0] = m_condition_data.m_sem_block_queue.value();
+ sem_counts[1] = m_condition_data.m_sem_block_lock.value();
+ return &sem_counts;
+ }
+
+ virtual const void *buffer_with_init_data_to_file()
+ {
+ sem_counts[0] = 0;
+ sem_counts[1] = 1;
+ return &sem_counts;
+ }
+
+ virtual void *buffer_to_store_init_data_from_file()
+ { return &sem_counts; }
+
+ virtual bool open(create_enum_t, const char *id_name)
+ {
+ m_condition_data.m_nwaiters_blocked = 0;
+ m_condition_data.m_nwaiters_gone = 0;
+ m_condition_data.m_nwaiters_to_unblock = 0;
+
+ //Now open semaphores and mutex.
+ //Use local variables + swap to guarantee consistent
+ //initialization and cleanup in case any opening fails
+ permissions perm;
+ perm.set_unrestricted();
+ std::string aux_str = "Global\\bipc.cond.";
+ aux_str += id_name;
+ std::size_t pos = aux_str.size();
+
+ //sem_block_queue
+ aux_str += "_bq";
+ winapi_semaphore_wrapper sem_block_queue;
+ bool created;
+ if(!sem_block_queue.open_or_create
+ (aux_str.c_str(), sem_counts[0], winapi_semaphore_wrapper::MaxCount, perm, created))
+ return false;
+ aux_str.erase(pos);
+
+ //sem_block_lock
+ aux_str += "_bl";
+ winapi_semaphore_wrapper sem_block_lock;
+ if(!sem_block_lock.open_or_create
+ (aux_str.c_str(), sem_counts[1], winapi_semaphore_wrapper::MaxCount, perm, created))
+ return false;
+ aux_str.erase(pos);
+
+ //mtx_unblock_lock
+ aux_str += "_ul";
+ winapi_mutex_wrapper mtx_unblock_lock;
+ if(!mtx_unblock_lock.open_or_create(aux_str.c_str(), perm))
+ return false;
+
+ //All ok, commit data
+ m_condition_data.m_sem_block_queue.swap(sem_block_queue);
+ m_condition_data.m_sem_block_lock.swap(sem_block_lock);
+ m_condition_data.m_mtx_unblock_lock.swap(mtx_unblock_lock);
+ return true;
+ }
+
+ virtual void close()
+ {
+ m_condition_data.m_sem_block_queue.close();
+ m_condition_data.m_sem_block_lock.close();
+ m_condition_data.m_mtx_unblock_lock.close();
+ m_condition_data.m_nwaiters_blocked = 0;
+ m_condition_data.m_nwaiters_gone = 0;
+ m_condition_data.m_nwaiters_to_unblock = 0;
+ }
+
+ virtual ~named_cond_callbacks()
+ {}
+
+ private:
+ condition_data &m_condition_data;
+ };
+
+ windows_named_sync m_named_sync;
+ /// @endcond
+};
+
+inline windows_named_condition::~windows_named_condition()
+{
+ named_cond_callbacks callbacks(m_condition_data);
+ m_named_sync.close(callbacks);
+}
+
+inline void windows_named_condition::dont_close_on_destruction()
+{}
+
+inline windows_named_condition::windows_named_condition
+ (create_only_t, const char *name, const permissions &perm)
+ : m_condition_data()
+{
+ named_cond_callbacks callbacks(m_condition_data);
+ m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
+}
+
+inline windows_named_condition::windows_named_condition
+ (open_or_create_t, const char *name, const permissions &perm)
+ : m_condition_data()
+{
+ named_cond_callbacks callbacks(m_condition_data);
+ m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
+}
+
+inline windows_named_condition::windows_named_condition(open_only_t, const char *name)
+ : m_condition_data()
+{
+ named_cond_callbacks callbacks(m_condition_data);
+ m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
+}
+
+inline void windows_named_condition::notify_one()
+{ algorithm_type::signal(m_condition_data, false); }
+
+inline void windows_named_condition::notify_all()
+{ algorithm_type::signal(m_condition_data, true); }
+
+template<class InterprocessMutex>
+inline void windows_named_condition::do_wait(InterprocessMutex &mut)
+{ algorithm_type::wait(m_condition_data, false, boost::posix_time::ptime(), mut); }
+
+template<class InterprocessMutex>
+inline bool windows_named_condition::do_timed_wait
+ (const boost::posix_time::ptime &abs_time, InterprocessMutex &mut)
+{ return algorithm_type::wait(m_condition_data, true, abs_time, mut); }
+
+template <typename L>
+inline void windows_named_condition::wait(L& lock)
+{
+ if (!lock)
+ throw lock_exception();
+ this->do_wait(*lock.mutex());
+}
+
+template <typename L, typename Pr>
+inline void windows_named_condition::wait(L& lock, Pr pred)
+{
+ if (!lock)
+ throw lock_exception();
+ while (!pred())
+ this->do_wait(*lock.mutex());
+}
+
+template <typename L>
+inline bool windows_named_condition::timed_wait
+ (L& lock, const boost::posix_time::ptime &abs_time)
+{
+ if(abs_time == boost::posix_time::pos_infin){
+ this->wait(lock);
+ return true;
+ }
+ if (!lock)
+ throw lock_exception();
+ return this->do_timed_wait(abs_time, *lock.mutex());
+}
+
+template <typename L, typename Pr>
+inline bool windows_named_condition::timed_wait
+ (L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
+{
+ if(abs_time == boost::posix_time::pos_infin){
+ this->wait(lock, pred);
+ return true;
+ }
+ if (!lock)
+ throw lock_exception();
+
+ while (!pred()){
+ if(!this->do_timed_wait(abs_time, *lock.mutex())){
+ return pred();
+ }
+ }
+ return true;
+}
+
+inline bool windows_named_condition::remove(const char *name)
+{
+ return windows_named_sync::remove(name);
+}
+
+} //namespace ipcdetail {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_WINDOWS_NAMED_CONDITION_HPP
diff --git a/boost/interprocess/sync/windows/named_mutex.hpp b/boost/interprocess/sync/windows/named_mutex.hpp
new file mode 100644
index 0000000000..8ea6b3e1e4
--- /dev/null
+++ b/boost/interprocess/sync/windows/named_mutex.hpp
@@ -0,0 +1,175 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-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.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_INTERPROCESS_WINDOWS_NAMED_MUTEX_HPP
+#define BOOST_INTERPROCESS_WINDOWS_NAMED_MUTEX_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/creation_tags.hpp>
+#include <boost/interprocess/permissions.hpp>
+#include <boost/interprocess/detail/interprocess_tester.hpp>
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/sync/windows/sync_utils.hpp>
+#include <boost/interprocess/sync/windows/named_sync.hpp>
+#include <boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp>
+#include <boost/interprocess/errors.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <limits>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+
+
+class windows_named_mutex
+{
+ /// @cond
+
+ //Non-copyable
+ windows_named_mutex();
+ windows_named_mutex(const windows_named_mutex &);
+ windows_named_mutex &operator=(const windows_named_mutex &);
+ /// @endcond
+
+ public:
+ windows_named_mutex(create_only_t, const char *name, const permissions &perm = permissions());
+
+ windows_named_mutex(open_or_create_t, const char *name, const permissions &perm = permissions());
+
+ windows_named_mutex(open_only_t, const char *name);
+
+ ~windows_named_mutex();
+
+ void unlock();
+ void lock();
+ bool try_lock();
+ bool timed_lock(const boost::posix_time::ptime &abs_time);
+
+ static bool remove(const char *name);
+
+ /// @cond
+ private:
+ friend class interprocess_tester;
+ void dont_close_on_destruction();
+ winapi_mutex_wrapper m_mtx_wrapper;
+ windows_named_sync m_named_sync;
+
+ class named_mut_callbacks : public windows_named_sync_interface
+ {
+ public:
+ named_mut_callbacks(winapi_mutex_wrapper &mtx_wrapper)
+ : m_mtx_wrapper(mtx_wrapper)
+ {}
+
+ virtual std::size_t get_data_size() const
+ { return 0u; }
+
+ virtual const void *buffer_with_init_data_to_file()
+ { return 0; }
+
+ virtual const void *buffer_with_final_data_to_file()
+ { return 0; }
+
+ virtual void *buffer_to_store_init_data_from_file()
+ { return 0; }
+
+ virtual bool open(create_enum_t, const char *id_name)
+ {
+ std::string aux_str = "Global\\bipc.mut.";
+ aux_str += id_name;
+ //
+ permissions mut_perm;
+ mut_perm.set_unrestricted();
+ return m_mtx_wrapper.open_or_create(aux_str.c_str(), mut_perm);
+ }
+
+ virtual void close()
+ {
+ m_mtx_wrapper.close();
+ }
+
+ virtual ~named_mut_callbacks()
+ {}
+
+ private:
+ winapi_mutex_wrapper& m_mtx_wrapper;
+ };
+ /// @endcond
+};
+
+inline windows_named_mutex::~windows_named_mutex()
+{
+ named_mut_callbacks callbacks(m_mtx_wrapper);
+ m_named_sync.close(callbacks);
+}
+
+inline void windows_named_mutex::dont_close_on_destruction()
+{}
+
+inline windows_named_mutex::windows_named_mutex
+ (create_only_t, const char *name, const permissions &perm)
+ : m_mtx_wrapper()
+{
+ named_mut_callbacks callbacks(m_mtx_wrapper);
+ m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
+}
+
+inline windows_named_mutex::windows_named_mutex
+ (open_or_create_t, const char *name, const permissions &perm)
+ : m_mtx_wrapper()
+{
+ named_mut_callbacks callbacks(m_mtx_wrapper);
+ m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
+}
+
+inline windows_named_mutex::windows_named_mutex(open_only_t, const char *name)
+ : m_mtx_wrapper()
+{
+ named_mut_callbacks callbacks(m_mtx_wrapper);
+ m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
+}
+
+inline void windows_named_mutex::unlock()
+{
+ m_mtx_wrapper.unlock();
+}
+
+inline void windows_named_mutex::lock()
+{
+ m_mtx_wrapper.lock();
+}
+
+inline bool windows_named_mutex::try_lock()
+{
+ return m_mtx_wrapper.try_lock();
+}
+
+inline bool windows_named_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
+{
+ return m_mtx_wrapper.timed_lock(abs_time);
+}
+
+inline bool windows_named_mutex::remove(const char *name)
+{
+ return windows_named_sync::remove(name);
+}
+
+} //namespace ipcdetail {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_WINDOWS_NAMED_MUTEX_HPP \ No newline at end of file
diff --git a/boost/interprocess/sync/windows/named_recursive_mutex.hpp b/boost/interprocess/sync/windows/named_recursive_mutex.hpp
new file mode 100644
index 0000000000..cb2ef79ac1
--- /dev/null
+++ b/boost/interprocess/sync/windows/named_recursive_mutex.hpp
@@ -0,0 +1,58 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-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.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_INTERPROCESS_WINDOWS_RECURSIVE_NAMED_MUTEX_HPP
+#define BOOST_INTERPROCESS_WINDOWS_RECURSIVE_NAMED_MUTEX_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/sync/windows/named_mutex.hpp>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+
+class windows_named_recursive_mutex
+ //Windows mutexes based on CreateMutex are already recursive...
+ : public windows_named_mutex
+{
+ /// @cond
+
+ //Non-copyable
+ windows_named_recursive_mutex();
+ windows_named_recursive_mutex(const windows_named_mutex &);
+ windows_named_recursive_mutex &operator=(const windows_named_mutex &);
+ /// @endcond
+
+ public:
+ windows_named_recursive_mutex(create_only_t, const char *name, const permissions &perm = permissions())
+ : windows_named_mutex(create_only_t(), name, perm)
+ {}
+
+ windows_named_recursive_mutex(open_or_create_t, const char *name, const permissions &perm = permissions())
+ : windows_named_mutex(open_or_create_t(), name, perm)
+ {}
+
+ windows_named_recursive_mutex(open_only_t, const char *name)
+ : windows_named_mutex(open_only_t(), name)
+ {}
+};
+
+} //namespace ipcdetail {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_WINDOWS_RECURSIVE_NAMED_MUTEX_HPP
diff --git a/boost/interprocess/sync/windows/named_semaphore.hpp b/boost/interprocess/sync/windows/named_semaphore.hpp
new file mode 100644
index 0000000000..8f48d4df96
--- /dev/null
+++ b/boost/interprocess/sync/windows/named_semaphore.hpp
@@ -0,0 +1,178 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_WINDOWS_NAMED_SEMAPHORE_HPP
+#define BOOST_INTERPROCESS_WINDOWS_NAMED_SEMAPHORE_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/creation_tags.hpp>
+#include <boost/interprocess/permissions.hpp>
+#include <boost/interprocess/detail/interprocess_tester.hpp>
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/sync/windows/named_sync.hpp>
+#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+
+
+class windows_named_semaphore
+{
+ /// @cond
+
+ //Non-copyable
+ windows_named_semaphore();
+ windows_named_semaphore(const windows_named_semaphore &);
+ windows_named_semaphore &operator=(const windows_named_semaphore &);
+ /// @endcond
+
+ public:
+ windows_named_semaphore(create_only_t, const char *name, unsigned int initialCount, const permissions &perm = permissions());
+
+ windows_named_semaphore(open_or_create_t, const char *name, unsigned int initialCount, const permissions &perm = permissions());
+
+ windows_named_semaphore(open_only_t, const char *name);
+
+ ~windows_named_semaphore();
+
+ void post();
+ void wait();
+ bool try_wait();
+ bool timed_wait(const boost::posix_time::ptime &abs_time);
+
+ static bool remove(const char *name);
+
+ /// @cond
+ private:
+ friend class interprocess_tester;
+ void dont_close_on_destruction();
+ winapi_semaphore_wrapper m_sem_wrapper;
+ windows_named_sync m_named_sync;
+
+ class named_sem_callbacks : public windows_named_sync_interface
+ {
+ public:
+ typedef __int64 sem_count_t;
+ named_sem_callbacks(winapi_semaphore_wrapper &sem_wrapper, sem_count_t sem_cnt)
+ : m_sem_wrapper(sem_wrapper), m_sem_count(sem_cnt)
+ {}
+
+ virtual std::size_t get_data_size() const
+ { return sizeof(sem_count_t); }
+
+ virtual const void *buffer_with_final_data_to_file()
+ { return &m_sem_count; }
+
+ virtual const void *buffer_with_init_data_to_file()
+ { return &m_sem_count; }
+
+ virtual void *buffer_to_store_init_data_from_file()
+ { return &m_sem_count; }
+
+ virtual bool open(create_enum_t, const char *id_name)
+ {
+ std::string aux_str = "Global\\bipc.sem.";
+ aux_str += id_name;
+ //
+ permissions sem_perm;
+ sem_perm.set_unrestricted();
+ bool created;
+ return m_sem_wrapper.open_or_create
+ ( aux_str.c_str(), static_cast<long>(m_sem_count)
+ , winapi_semaphore_wrapper::MaxCount, sem_perm, created);
+ }
+
+ virtual void close()
+ {
+ m_sem_wrapper.close();
+ }
+
+ virtual ~named_sem_callbacks()
+ {}
+
+ private:
+ sem_count_t m_sem_count;
+ winapi_semaphore_wrapper& m_sem_wrapper;
+ };
+
+ /// @endcond
+};
+
+inline windows_named_semaphore::~windows_named_semaphore()
+{
+ named_sem_callbacks callbacks(m_sem_wrapper, m_sem_wrapper.value());
+ m_named_sync.close(callbacks);
+}
+
+inline void windows_named_semaphore::dont_close_on_destruction()
+{}
+
+inline windows_named_semaphore::windows_named_semaphore
+ (create_only_t, const char *name, unsigned int initial_count, const permissions &perm)
+ : m_sem_wrapper()
+{
+ named_sem_callbacks callbacks(m_sem_wrapper, initial_count);
+ m_named_sync.open_or_create(DoCreate, name, perm, callbacks);
+}
+
+inline windows_named_semaphore::windows_named_semaphore
+ (open_or_create_t, const char *name, unsigned int initial_count, const permissions &perm)
+ : m_sem_wrapper()
+{
+ named_sem_callbacks callbacks(m_sem_wrapper, initial_count);
+ m_named_sync.open_or_create(DoOpenOrCreate, name, perm, callbacks);
+}
+
+inline windows_named_semaphore::windows_named_semaphore(open_only_t, const char *name)
+ : m_sem_wrapper()
+{
+ named_sem_callbacks callbacks(m_sem_wrapper, 0);
+ m_named_sync.open_or_create(DoOpen, name, permissions(), callbacks);
+}
+
+inline void windows_named_semaphore::post()
+{
+ m_sem_wrapper.post();
+}
+
+inline void windows_named_semaphore::wait()
+{
+ m_sem_wrapper.wait();
+}
+
+inline bool windows_named_semaphore::try_wait()
+{
+ return m_sem_wrapper.try_wait();
+}
+
+inline bool windows_named_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
+{
+ return m_sem_wrapper.timed_wait(abs_time);
+}
+
+inline bool windows_named_semaphore::remove(const char *name)
+{
+ return windows_named_sync::remove(name);
+}
+
+} //namespace ipcdetail {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_WINDOWS_NAMED_SEMAPHORE_HPP
diff --git a/boost/interprocess/sync/windows/named_sync.hpp b/boost/interprocess/sync/windows/named_sync.hpp
new file mode 100644
index 0000000000..41f299f8eb
--- /dev/null
+++ b/boost/interprocess/sync/windows/named_sync.hpp
@@ -0,0 +1,215 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_WINDOWS_NAMED_SYNC_HPP
+#define BOOST_INTERPROCESS_WINDOWS_NAMED_SYNC_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/creation_tags.hpp>
+#include <boost/interprocess/permissions.hpp>
+#include <boost/interprocess/detail/tmp_dir_helpers.hpp>
+#include <boost/interprocess/sync/windows/sync_utils.hpp>
+#include <boost/interprocess/errors.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <string>
+#include <cassert>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+class windows_named_sync_interface
+{
+ public:
+ virtual std::size_t get_data_size() const = 0;
+ virtual const void *buffer_with_final_data_to_file() = 0;
+ virtual const void *buffer_with_init_data_to_file() = 0;
+ virtual void *buffer_to_store_init_data_from_file() = 0;
+ virtual bool open(create_enum_t creation_type, const char *id_name) = 0;
+ virtual void close() = 0;
+ virtual ~windows_named_sync_interface() = 0;
+};
+
+inline windows_named_sync_interface::~windows_named_sync_interface()
+{}
+
+class windows_named_sync
+{
+ /// @cond
+
+ //Non-copyable
+ windows_named_sync(const windows_named_sync &);
+ windows_named_sync &operator=(const windows_named_sync &);
+ /// @endcond
+
+ public:
+ windows_named_sync();
+ void open_or_create(create_enum_t creation_type, const char *name, const permissions &perm, windows_named_sync_interface &sync_interface);
+ void close(windows_named_sync_interface &sync_interface);
+
+ static bool remove(const char *name);
+
+ /// @cond
+ private:
+ void *m_file_hnd;
+
+ /// @endcond
+};
+
+inline windows_named_sync::windows_named_sync()
+ : m_file_hnd(winapi::invalid_handle_value)
+{}
+
+inline void windows_named_sync::close(windows_named_sync_interface &sync_interface)
+{
+ const std::size_t buflen = sync_interface.get_data_size();
+ const std::size_t sizeof_file_info = sizeof(sync_id::internal_type) + buflen;
+ winapi::interprocess_overlapped overlapped;
+ if(winapi::lock_file_ex
+ (m_file_hnd, winapi::lockfile_exclusive_lock, 0, sizeof_file_info, 0, &overlapped)){
+ if(winapi::set_file_pointer_ex(m_file_hnd, sizeof(sync_id::internal_type), 0, winapi::file_begin)){
+ const void *buf = sync_interface.buffer_with_final_data_to_file();
+
+ unsigned long written_or_read = 0;
+ if(winapi::write_file(m_file_hnd, buf, buflen, &written_or_read, 0)){
+ //...
+ }
+ }
+ }
+ sync_interface.close();
+ if(m_file_hnd != winapi::invalid_handle_value){
+ winapi::close_handle(m_file_hnd);
+ m_file_hnd = winapi::invalid_handle_value;
+ }
+}
+
+inline void windows_named_sync::open_or_create
+ ( create_enum_t creation_type
+ , const char *name
+ , const permissions &perm
+ , windows_named_sync_interface &sync_interface)
+{
+ std::string aux_str(name);
+ m_file_hnd = winapi::invalid_handle_value;
+ //Use a file to emulate POSIX lifetime semantics. After this logic
+ //we'll obtain the ID of the native handle to open in aux_str
+ {
+ create_tmp_and_clean_old_and_get_filename(name, aux_str);
+ //Create a file with required permissions.
+ m_file_hnd = winapi::create_file
+ ( aux_str.c_str()
+ , winapi::generic_read | winapi::generic_write
+ , creation_type == DoOpen ? winapi::open_existing :
+ (creation_type == DoCreate ? winapi::create_new : winapi::open_always)
+ , 0
+ , (winapi::interprocess_security_attributes*)perm.get_permissions());
+
+ //Obtain OS error in case something has failed
+ error_info err;
+ bool success = false;
+ if(m_file_hnd != winapi::invalid_handle_value){
+ //Now lock the file
+ const std::size_t buflen = sync_interface.get_data_size();
+ typedef __int64 unique_id_type;
+ const std::size_t sizeof_file_info = sizeof(unique_id_type) + buflen;
+ winapi::interprocess_overlapped overlapped;
+ if(winapi::lock_file_ex
+ (m_file_hnd, winapi::lockfile_exclusive_lock, 0, sizeof_file_info, 0, &overlapped)){
+ __int64 filesize = 0;
+ //Obtain the unique id to open the native semaphore.
+ //If file size was created
+ if(winapi::get_file_size(m_file_hnd, filesize)){
+ unsigned long written_or_read = 0;
+ unique_id_type unique_id_val;
+ if(static_cast<std::size_t>(filesize) != sizeof_file_info){
+ winapi::set_end_of_file(m_file_hnd);
+ winapi::query_performance_counter(&unique_id_val);
+ const void *buf = sync_interface.buffer_with_init_data_to_file();
+ //Write unique ID in file. This ID will be used to calculate the semaphore name
+ if(winapi::write_file(m_file_hnd, &unique_id_val, sizeof(unique_id_val), &written_or_read, 0) &&
+ written_or_read == sizeof(unique_id_val) &&
+ winapi::write_file(m_file_hnd, buf, buflen, &written_or_read, 0) &&
+ written_or_read == buflen ){
+ success = true;
+ }
+ winapi::get_file_size(m_file_hnd, filesize);
+ assert(std::size_t(filesize) == sizeof_file_info);
+ }
+ else{
+ void *buf = sync_interface.buffer_to_store_init_data_from_file();
+ if(winapi::read_file(m_file_hnd, &unique_id_val, sizeof(unique_id_val), &written_or_read, 0) &&
+ written_or_read == sizeof(unique_id_val) &&
+ winapi::read_file(m_file_hnd, buf, buflen, &written_or_read, 0) &&
+ written_or_read == buflen ){
+ success = true;
+ }
+ }
+ if(success){
+ //Now create a global semaphore name based on the unique id
+ char unique_id_name[sizeof(unique_id_val)*2+1];
+ std::size_t name_suffix_length = sizeof(unique_id_name);
+ bytes_to_str(&unique_id_val, sizeof(unique_id_val), &unique_id_name[0], name_suffix_length);
+ success = sync_interface.open(creation_type, unique_id_name);
+ }
+ }
+
+ //Obtain OS error in case something has failed
+ err = system_error_code();
+
+ //If this fails we have no possible rollback so don't check the return
+ if(!winapi::unlock_file_ex(m_file_hnd, 0, sizeof_file_info, 0, &overlapped)){
+ err = system_error_code();
+ }
+ }
+ else{
+ //Obtain OS error in case something has failed
+ err = system_error_code();
+ }
+ }
+ else{
+ err = system_error_code();
+ }
+
+ if(!success){
+ if(m_file_hnd != winapi::invalid_handle_value){
+ winapi::close_handle(m_file_hnd);
+ m_file_hnd = winapi::invalid_handle_value;
+ }
+ //Throw as something went wrong
+ throw interprocess_exception(err);
+ }
+ }
+}
+
+inline bool windows_named_sync::remove(const char *name)
+{
+ try{
+ //Make sure a temporary path is created for shared memory
+ std::string semfile;
+ ipcdetail::tmp_filename(name, semfile);
+ return winapi::unlink_file(semfile.c_str());
+ }
+ catch(...){
+ return false;
+ }
+}
+
+} //namespace ipcdetail {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_WINDOWS_NAMED_SYNC_HPP
diff --git a/boost/interprocess/sync/windows/semaphore.hpp b/boost/interprocess/sync/windows/semaphore.hpp
index d5835ceec7..af336df48a 100644
--- a/boost/interprocess/sync/windows/semaphore.hpp
+++ b/boost/interprocess/sync/windows/semaphore.hpp
@@ -19,8 +19,9 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/detail/win32_api.hpp>
-#include <boost/interprocess/detail/intermodule_singleton.hpp>
+#include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
#include <boost/interprocess/sync/windows/sync_utils.hpp>
+#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
#include <boost/interprocess/exceptions.hpp>
@@ -46,11 +47,11 @@ class windows_semaphore
const sync_id id_;
};
-inline windows_semaphore::windows_semaphore(unsigned int initialCount)
- : id_()
+inline windows_semaphore::windows_semaphore(unsigned int initialCount)
+ : id_(this)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//Force smeaphore creation with the initial count
bool open_or_created;
handles.obtain_semaphore(this->id_, initialCount, &open_or_created);
@@ -60,72 +61,46 @@ inline windows_semaphore::windows_semaphore(unsigned int initialCount)
(void)open_or_created;
}
-inline windows_semaphore::~windows_semaphore()
+inline windows_semaphore::~windows_semaphore()
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
handles.destroy_handle(this->id_);
}
inline void windows_semaphore::wait(void)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_semaphore(this->id_, 0);
- unsigned long ret = winapi::wait_for_single_object(hnd, winapi::infinite_time);
- if(ret == winapi::wait_failed){
- error_info err(winapi::get_last_error());
- throw interprocess_exception(err);
- }
+ winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
+ sem.wait();
}
inline bool windows_semaphore::try_wait(void)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_semaphore(this->id_, 0);
- unsigned long ret = winapi::wait_for_single_object(hnd, 0);
- if(ret == winapi::wait_failed){
- error_info err(winapi::get_last_error());
- throw interprocess_exception(err);
- }
- return ret != winapi::wait_timeout;
+ winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
+ return sem.try_wait();
}
inline bool windows_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
{
- if(abs_time == boost::posix_time::pos_infin){
- this->wait();
- return true;
- }
- boost::posix_time::ptime now
- = boost::posix_time::microsec_clock::universal_time();
-
- unsigned long ms = (unsigned long)(abs_time-now).total_milliseconds();
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
+ windows_intermodule_singleton<sync_handles>::get();
//This can throw
- void *hnd = handles.obtain_semaphore(this->id_, 0);
- unsigned long ret = winapi::wait_for_single_object(hnd, ms);
- if(ret == winapi::wait_failed){
- error_info err(winapi::get_last_error());
- throw interprocess_exception(err);
- }
- return ret != winapi::wait_timeout;
+ winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
+ return sem.timed_wait(abs_time);
}
inline void windows_semaphore::post(long release_count)
{
sync_handles &handles =
- intermodule_singleton<sync_handles>::get();
- //This can throw
- void *hnd = handles.obtain_semaphore(this->id_, 0);
- long prev_count;
- int ret = winapi::release_semaphore(hnd, release_count, &prev_count);
- (void)ret;
- assert(ret);
+ windows_intermodule_singleton<sync_handles>::get();
+ winapi_semaphore_functions sem(handles.obtain_semaphore(this->id_, 0));
+ sem.post(release_count);
}
} //namespace ipcdetail {
diff --git a/boost/interprocess/sync/windows/sync_utils.hpp b/boost/interprocess/sync/windows/sync_utils.hpp
index 89c4aeda0b..0281da1266 100644
--- a/boost/interprocess/sync/windows/sync_utils.hpp
+++ b/boost/interprocess/sync/windows/sync_utils.hpp
@@ -21,7 +21,10 @@
#include <boost/interprocess/sync/spin/mutex.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp>
+#include <boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp>
#include <boost/unordered/unordered_map.hpp>
+#include <boost/container/map.hpp>
#include <cstddef>
namespace boost {
@@ -32,6 +35,7 @@ inline bool bytes_to_str(const void *mem, const std::size_t mem_length, char *ou
{
const std::size_t need_mem = mem_length*2+1;
if(out_length < need_mem){
+ out_length = need_mem;
return false;
}
@@ -49,40 +53,57 @@ inline bool bytes_to_str(const void *mem, const std::size_t mem_length, char *ou
return true;
}
-struct sync_id
+class sync_id
{
- sync_id()
- { winapi::query_performance_counter(&rand); }
+ public:
+ typedef __int64 internal_type;
+ sync_id(const void *map_addr)
+ : map_addr_(map_addr)
+ { winapi::query_performance_counter(&rand_); }
+
+ explicit sync_id(internal_type val, const void *map_addr)
+ : map_addr_(map_addr)
+ { rand_ = val; }
+
+ const internal_type &internal_pod() const
+ { return rand_; }
- __int64 rand;
+ internal_type &internal_pod()
+ { return rand_; }
+
+ const void *map_addr() const
+ { return map_addr_; }
friend std::size_t hash_value(const sync_id &m)
- { return boost::hash_value(m.rand); }
+ { return boost::hash_value(m.rand_); }
friend bool operator==(const sync_id &l, const sync_id &r)
- { return l.rand == r.rand; }
-};
-/*
-#define BOOST_NO_LONG_LONG ss
+ { return l.rand_ == r.rand_ && l.map_addr_ == r.map_addr_; }
-#if defined(BOOST_NO_LONG_LONG)
+ private:
+ internal_type rand_;
+ const void * const map_addr_;
+};
-#error "defined(BOOST_NO_LONG_LONG)"
-#else
-#error "NOT defined(BOOST_NO_LONG_LONG)"
-#endif
-*/
class sync_handles
{
public:
enum type { MUTEX, SEMAPHORE };
private:
- typedef boost::unordered_map<sync_id, void*> map_type;
+ struct address_less
+ {
+ bool operator()(sync_id const * const l, sync_id const * const r) const
+ { return l->map_addr() < r->map_addr(); }
+ };
+
+ typedef boost::unordered_map<sync_id, void*> umap_type;
+ typedef boost::container::map<const sync_id*, umap_type::iterator, address_less> map_type;
static const std::size_t LengthOfGlobal = sizeof("Global\\boost.ipc")-1;
static const std::size_t StrSize = LengthOfGlobal + (sizeof(sync_id)*2+1);
typedef char NameBuf[StrSize];
+
void fill_name(NameBuf &name, const sync_id &id)
{
const char *n = "Global\\boost.ipc";
@@ -92,13 +113,12 @@ class sync_handles
++i;
} while(n[i]);
std::size_t len = sizeof(NameBuf) - LengthOfGlobal;
- bytes_to_str(&id.rand, sizeof(id.rand), &name[LengthOfGlobal], len);
+ bytes_to_str(&id.internal_pod(), sizeof(id.internal_pod()), &name[LengthOfGlobal], len);
}
- void erase_and_throw_if_error(void *hnd_val, const sync_id &id)
+ void throw_if_error(void *hnd_val)
{
if(!hnd_val){
- map_.erase(id);
error_info err(winapi::get_last_error());
throw interprocess_exception(err);
}
@@ -108,27 +128,36 @@ class sync_handles
{
NameBuf name;
fill_name(name, id);
- void *hnd_val = winapi::open_or_create_semaphore
- (name, (long)initial_count, (long)(((unsigned long)(-1))>>1), unrestricted_security.get_attributes());
- erase_and_throw_if_error(hnd_val, id);
- return hnd_val;
+ permissions unrestricted_security;
+ unrestricted_security.set_unrestricted();
+ winapi_semaphore_wrapper sem_wrapper;
+ bool created;
+ sem_wrapper.open_or_create
+ (name, (long)initial_count, winapi_semaphore_wrapper::MaxCount, unrestricted_security, created);
+ throw_if_error(sem_wrapper.handle());
+ return sem_wrapper.release();
}
void* open_or_create_mutex(const sync_id &id)
{
NameBuf name;
fill_name(name, id);
- void *hnd_val = winapi::open_or_create_mutex
- (name, false, unrestricted_security.get_attributes());
- erase_and_throw_if_error(hnd_val, id);
- return hnd_val;
+ permissions unrestricted_security;
+ unrestricted_security.set_unrestricted();
+ winapi_mutex_wrapper mtx_wrapper;
+ mtx_wrapper.open_or_create(name, unrestricted_security);
+ throw_if_error(mtx_wrapper.handle());
+ return mtx_wrapper.release();
}
public:
void *obtain_mutex(const sync_id &id, bool *popen_created = 0)
{
+ umap_type::value_type v(id, (void*)0);
scoped_lock<spin_mutex> lock(mtx_);
- void *&hnd_val = map_[id];
+ umap_type::iterator it = umap_.insert(v).first;
+ map_[&it->first] = it;
+ void *&hnd_val = it->second;
if(!hnd_val){
hnd_val = open_or_create_mutex(id);
if(popen_created) *popen_created = true;
@@ -138,8 +167,11 @@ class sync_handles
void *obtain_semaphore(const sync_id &id, unsigned int initial_count, bool *popen_created = 0)
{
+ umap_type::value_type v(id, (void*)0);
scoped_lock<spin_mutex> lock(mtx_);
- void *&hnd_val = map_[id];
+ umap_type::iterator it = umap_.insert(v).first;
+ map_[&it->first] = it;
+ void *&hnd_val = it->second;
if(!hnd_val){
hnd_val = open_or_create_semaphore(id, initial_count);
if(popen_created) *popen_created = true;
@@ -150,16 +182,35 @@ class sync_handles
void destroy_handle(const sync_id &id)
{
scoped_lock<spin_mutex> lock(mtx_);
- map_type::iterator it = map_.find(id);
- if(it != map_.end()){
+ umap_type::iterator it = umap_.find(id);
+ umap_type::iterator itend = umap_.end();
+
+ if(it != itend){
winapi::close_handle(it->second);
- map_.erase(it);
+ const map_type::key_type &k = &it->first;
+ map_.erase(k);
+ umap_.erase(it);
+ }
+ }
+
+ void destroy_syncs_in_range(const void *addr, std::size_t size)
+ {
+ sync_id low_id(addr);
+ sync_id hig_id(static_cast<const char*>(addr)+size);
+ scoped_lock<spin_mutex> lock(mtx_);
+ map_type::iterator itlow(map_.lower_bound(&low_id)),
+ ithig(map_.lower_bound(&hig_id));
+ while(itlow != ithig){
+ void *hnd = umap_[*itlow->first];
+ winapi::close_handle(hnd);
+ umap_.erase(*itlow->first);
+ itlow = map_.erase(itlow);
}
}
private:
- winapi::interprocess_all_access_security unrestricted_security;
spin_mutex mtx_;
+ umap_type umap_;
map_type map_;
};
diff --git a/boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp b/boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp
new file mode 100644
index 0000000000..0be96011cf
--- /dev/null
+++ b/boost/interprocess/sync/windows/winapi_mutex_wrapper.hpp
@@ -0,0 +1,163 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_DETAIL_WINAPI_MUTEX_WRAPPER_HPP
+#define BOOST_INTERPROCESS_DETAIL_WINAPI_MUTEX_WRAPPER_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/creation_tags.hpp>
+#include <boost/interprocess/permissions.hpp>
+#include <boost/interprocess/detail/win32_api.hpp>
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/errors.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <limits>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+class winapi_mutex_functions
+{
+ /// @cond
+
+ //Non-copyable
+ winapi_mutex_functions(const winapi_mutex_functions &);
+ winapi_mutex_functions &operator=(const winapi_mutex_functions &);
+ /// @endcond
+
+ public:
+ winapi_mutex_functions(void *mtx_hnd)
+ : m_mtx_hnd(mtx_hnd)
+ {}
+
+ void unlock()
+ {
+ winapi::release_mutex(m_mtx_hnd);
+ }
+
+ void lock()
+ {
+ if(winapi::wait_for_single_object(m_mtx_hnd, winapi::infinite_time) != winapi::wait_object_0){
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
+ }
+ }
+
+ bool try_lock()
+ {
+ unsigned long ret = winapi::wait_for_single_object(m_mtx_hnd, 0);
+ if(ret == winapi::wait_object_0){
+ return true;
+ }
+ else if(ret == winapi::wait_timeout){
+ return false;
+ }
+ else{
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
+ }
+ }
+
+ bool timed_lock(const boost::posix_time::ptime &abs_time)
+ {
+ if(abs_time == boost::posix_time::pos_infin){
+ this->lock();
+ return true;
+ }
+
+ unsigned long ret = winapi::wait_for_single_object
+ (m_mtx_hnd, (abs_time - microsec_clock::universal_time()).total_milliseconds());
+ if(ret == winapi::wait_object_0){
+ return true;
+ }
+ else if(ret == winapi::wait_timeout){
+ return false;
+ }
+ else{
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
+ }
+ }
+
+ /// @cond
+ protected:
+ void *m_mtx_hnd;
+ /// @endcond
+};
+
+//Swappable mutex wrapper
+class winapi_mutex_wrapper
+ : public winapi_mutex_functions
+{
+ /// @cond
+
+ //Non-copyable
+ winapi_mutex_wrapper(const winapi_mutex_wrapper &);
+ winapi_mutex_wrapper &operator=(const winapi_mutex_wrapper &);
+ /// @endcond
+
+ public:
+ winapi_mutex_wrapper(void *mtx_hnd = winapi::invalid_handle_value)
+ : winapi_mutex_functions(mtx_hnd)
+ {}
+
+ ~winapi_mutex_wrapper()
+ { this->close(); }
+
+ void *release()
+ {
+ void *hnd = m_mtx_hnd;
+ m_mtx_hnd = winapi::invalid_handle_value;
+ return hnd;
+ }
+
+ void *handle() const
+ { return m_mtx_hnd; }
+
+ bool open_or_create(const char *name, const permissions &perm)
+ {
+ if(m_mtx_hnd == winapi::invalid_handle_value){
+ m_mtx_hnd = winapi::open_or_create_mutex
+ ( name
+ , false
+ , (winapi::interprocess_security_attributes*)perm.get_permissions()
+ );
+ return m_mtx_hnd != winapi::invalid_handle_value;
+ }
+ else{
+ return false;
+ }
+ }
+
+ void close()
+ {
+ if(m_mtx_hnd != winapi::invalid_handle_value){
+ winapi::close_handle(m_mtx_hnd);
+ m_mtx_hnd = winapi::invalid_handle_value;
+ }
+ }
+
+ void swap(winapi_mutex_wrapper &other)
+ { void *tmp = m_mtx_hnd; m_mtx_hnd = other.m_mtx_hnd; other.m_mtx_hnd = tmp; }
+};
+
+} //namespace ipcdetail {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_DETAIL_WINAPI_MUTEX_WRAPPER_HPP
diff --git a/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp b/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp
new file mode 100644
index 0000000000..2dd7845627
--- /dev/null
+++ b/boost/interprocess/sync/windows/winapi_semaphore_wrapper.hpp
@@ -0,0 +1,198 @@
+ //////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_DETAIL_WINAPI_SEMAPHORE_WRAPPER_HPP
+#define BOOST_INTERPROCESS_DETAIL_WINAPI_SEMAPHORE_WRAPPER_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/creation_tags.hpp>
+#include <boost/interprocess/permissions.hpp>
+#include <boost/interprocess/detail/win32_api.hpp>
+#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/errors.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <limits>
+
+namespace boost {
+namespace interprocess {
+namespace ipcdetail {
+
+class winapi_semaphore_functions
+{
+ /// @cond
+
+ //Non-copyable
+ winapi_semaphore_functions(const winapi_semaphore_functions &);
+ winapi_semaphore_functions &operator=(const winapi_semaphore_functions &);
+ /// @endcond
+
+ public:
+ winapi_semaphore_functions(void *hnd)
+ : m_sem_hnd(hnd)
+ {}
+
+ void post(long count = 1)
+ {
+ long prev_count;
+ winapi::release_semaphore(m_sem_hnd, count, &prev_count);
+ }
+
+ void wait()
+ {
+ if(winapi::wait_for_single_object(m_sem_hnd, winapi::infinite_time) != winapi::wait_object_0){
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
+ }
+ }
+
+ bool try_wait()
+ {
+ unsigned long ret = winapi::wait_for_single_object(m_sem_hnd, 0);
+ if(ret == winapi::wait_object_0){
+ return true;
+ }
+ else if(ret == winapi::wait_timeout){
+ return false;
+ }
+ else{
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
+ }
+ }
+
+ bool timed_wait(const boost::posix_time::ptime &abs_time)
+ {
+ if(abs_time == boost::posix_time::pos_infin){
+ this->wait();
+ return true;
+ }
+
+ unsigned long ret = winapi::wait_for_single_object
+ (m_sem_hnd, (abs_time - microsec_clock::universal_time()).total_milliseconds());
+ if(ret == winapi::wait_object_0){
+ return true;
+ }
+ else if(ret == winapi::wait_timeout){
+ return false;
+ }
+ else{
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
+ }
+ }
+
+ long value() const
+ {
+ long count, limit;
+ if(!winapi::get_semaphore_info(m_sem_hnd, count, limit))
+ return 0;
+ return count;
+ }
+
+ long limit() const
+ {
+ long count, limit;
+ if(!winapi::get_semaphore_info(m_sem_hnd, count, limit))
+ return 0;
+ return limit;
+ }
+
+ /// @cond
+ protected:
+ void *m_sem_hnd;
+ /// @endcond
+};
+
+
+//Swappable semaphore wrapper
+class winapi_semaphore_wrapper
+ : public winapi_semaphore_functions
+{
+ winapi_semaphore_wrapper(const winapi_semaphore_wrapper &);
+ winapi_semaphore_wrapper &operator=(const winapi_semaphore_wrapper &);
+
+ public:
+
+ //Long is 32 bits in windows
+ static const long MaxCount = long(0x7FFFFFFF);
+
+ winapi_semaphore_wrapper(void *hnd = winapi::invalid_handle_value)
+ : winapi_semaphore_functions(hnd)
+ {}
+
+ ~winapi_semaphore_wrapper()
+ { this->close(); }
+
+ void *release()
+ {
+ void *hnd = m_sem_hnd;
+ m_sem_hnd = winapi::invalid_handle_value;
+ return hnd;
+ }
+
+ void *handle() const
+ { return m_sem_hnd; }
+
+ bool open_or_create( const char *name
+ , long sem_count
+ , long max_count
+ , const permissions &perm
+ , bool &created)
+ {
+ if(m_sem_hnd == winapi::invalid_handle_value){
+ m_sem_hnd = winapi::open_or_create_semaphore
+ ( name
+ , sem_count
+ , max_count
+ , (winapi::interprocess_security_attributes*)perm.get_permissions()
+ );
+ created = winapi::get_last_error() != winapi::error_already_exists;
+ return m_sem_hnd != winapi::invalid_handle_value;
+ }
+ else{
+ return false;
+ }
+ }
+
+ bool open_semaphore(const char *name)
+ {
+ if(m_sem_hnd == winapi::invalid_handle_value){
+ m_sem_hnd = winapi::open_semaphore(name);
+ return m_sem_hnd != winapi::invalid_handle_value;
+ }
+ else{
+ return false;
+ }
+ }
+
+ void close()
+ {
+ if(m_sem_hnd != winapi::invalid_handle_value){
+ winapi::close_handle(m_sem_hnd);
+ m_sem_hnd = winapi::invalid_handle_value;
+ }
+ }
+
+ void swap(winapi_semaphore_wrapper &other)
+ { void *tmp = m_sem_hnd; m_sem_hnd = other.m_sem_hnd; other.m_sem_hnd = tmp; }
+};
+
+} //namespace ipcdetail {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_DETAIL_WINAPI_SEMAPHORE_WRAPPER_HPP
diff --git a/boost/interprocess/sync/xsi/xsi_named_mutex.hpp b/boost/interprocess/sync/xsi/xsi_named_mutex.hpp
index 3dffdcc2ed..485b1ac101 100644
--- a/boost/interprocess/sync/xsi/xsi_named_mutex.hpp
+++ b/boost/interprocess/sync/xsi/xsi_named_mutex.hpp
@@ -62,20 +62,20 @@ class xsi_named_mutex
xsi_named_mutex(open_or_create_t, const char *path, boost::uint8_t id, int perm = 0666)
{ this->priv_open_or_create(ipcdetail::DoOpenOrCreate, path, id, perm); }
- //!Moves the ownership of "moved"'s named mutex to *this.
- //!After the call, "moved" does not represent any named mutex
+ //!Moves the ownership of "moved"'s named mutex to *this.
+ //!After the call, "moved" does not represent any named mutex
//!Does not throw
xsi_named_mutex(BOOST_RV_REF(xsi_named_mutex) moved)
{ this->swap(moved); }
//!Moves the ownership of "moved"'s named mutex to *this.
- //!After the call, "moved" does not represent any named mutex.
+ //!After the call, "moved" does not represent any named mutex.
//!Does not throw
xsi_named_mutex &operator=(BOOST_RV_REF(xsi_named_mutex) moved)
- {
+ {
xsi_named_mutex tmp(boost::move(moved));
this->swap(tmp);
- return *this;
+ return *this;
}
//!Swaps two xsi_named_mutex. Does not throw
@@ -126,11 +126,11 @@ class xsi_named_mutex
/// @cond
-inline xsi_named_mutex::xsi_named_mutex()
+inline xsi_named_mutex::xsi_named_mutex()
: m_semid(-1), m_key(-1), m_id(0), m_perm(0), m_path()
{}
-inline xsi_named_mutex::~xsi_named_mutex()
+inline xsi_named_mutex::~xsi_named_mutex()
{ this->priv_close(); }
inline const char *xsi_named_mutex::get_path() const
@@ -142,7 +142,7 @@ inline void xsi_named_mutex::swap(xsi_named_mutex &other)
std::swap(m_id, other.m_id);
std::swap(m_semid, other.m_semid);
std::swap(m_perm, other.m_perm);
- m_path.swap(other.m_path);
+ m_path.swap(other.m_path);
}
inline mapping_handle_t xsi_named_mutex::get_mapping_handle() const
diff --git a/boost/interprocess/windows_shared_memory.hpp b/boost/interprocess/windows_shared_memory.hpp
index 9a8b3f47dd..76601bb363 100644
--- a/boost/interprocess/windows_shared_memory.hpp
+++ b/boost/interprocess/windows_shared_memory.hpp
@@ -72,26 +72,26 @@ class windows_shared_memory
windows_shared_memory(open_or_create_t, const char *name, mode_t mode, std::size_t size, const permissions& perm = permissions())
{ this->priv_open_or_create(ipcdetail::DoOpenOrCreate, name, mode, size, perm); }
- //!Tries to open a shared memory object with name "name", with the access mode "mode".
+ //!Tries to open a shared memory object with name "name", with the access mode "mode".
//!If the file does not previously exist, it throws an error.
windows_shared_memory(open_only_t, const char *name, mode_t mode)
{ this->priv_open_or_create(ipcdetail::DoOpen, name, mode, 0, permissions()); }
- //!Moves the ownership of "moved"'s shared memory object to *this.
- //!After the call, "moved" does not represent any shared memory object.
+ //!Moves the ownership of "moved"'s shared memory object to *this.
+ //!After the call, "moved" does not represent any shared memory object.
//!Does not throw
windows_shared_memory(BOOST_RV_REF(windows_shared_memory) moved)
: m_handle(0)
{ this->swap(moved); }
//!Moves the ownership of "moved"'s shared memory to *this.
- //!After the call, "moved" does not represent any shared memory.
+ //!After the call, "moved" does not represent any shared memory.
//!Does not throw
windows_shared_memory &operator=(BOOST_RV_REF(windows_shared_memory) moved)
- {
+ {
windows_shared_memory tmp(boost::move(moved));
this->swap(tmp);
- return *this;
+ return *this;
}
//!Swaps to shared_memory_objects. Does not throw
@@ -129,21 +129,21 @@ class windows_shared_memory
/// @cond
-inline windows_shared_memory::windows_shared_memory()
+inline windows_shared_memory::windows_shared_memory()
: m_handle(0)
{}
-inline windows_shared_memory::~windows_shared_memory()
+inline windows_shared_memory::~windows_shared_memory()
{ this->priv_close(); }
inline const char *windows_shared_memory::get_name() const
{ return m_name.c_str(); }
inline void windows_shared_memory::swap(windows_shared_memory &other)
-{
+{
std::swap(m_handle, other.m_handle);
std::swap(m_mode, other.m_mode);
- m_name.swap(other.m_name);
+ m_name.swap(other.m_name);
}
inline mapping_handle_t windows_shared_memory::get_mapping_handle() const
@@ -157,22 +157,26 @@ inline bool windows_shared_memory::priv_open_or_create
{
m_name = filename ? filename : "";
- unsigned long file_map_access = 0;
+ unsigned long protection = 0;
unsigned long map_access = 0;
switch(mode)
{
+ //"protection" is for "create_file_mapping"
+ //"map_access" is for "open_file_mapping"
+ //Add section query (strange that read or access does not grant it...)
+ //to obtain the size of the mapping. copy_on_write is equal to section_query.
case read_only:
- file_map_access |= winapi::page_readonly;
- map_access |= winapi::file_map_read;
+ protection |= winapi::page_readonly;
+ map_access |= winapi::file_map_read | winapi::section_query;
break;
case read_write:
- file_map_access |= winapi::page_readwrite;
- map_access |= winapi::file_map_write;
+ protection |= winapi::page_readwrite;
+ map_access |= winapi::file_map_write | winapi::section_query;
break;
case copy_on_write:
- file_map_access |= winapi::page_writecopy;
- map_access |= winapi::file_map_copy;
+ protection |= winapi::page_writecopy;
+ map_access |= winapi::file_map_copy;
break;
default:
{
@@ -184,16 +188,13 @@ inline bool windows_shared_memory::priv_open_or_create
switch(type){
case ipcdetail::DoOpen:
- m_handle = winapi::open_file_mapping
- (map_access, filename);
+ m_handle = winapi::open_file_mapping(map_access, filename);
break;
case ipcdetail::DoCreate:
case ipcdetail::DoOpenOrCreate:
{
- __int64 s = size;
- unsigned long high_size(s >> 32), low_size((boost::uint32_t)s);
m_handle = winapi::create_file_mapping
- ( winapi::invalid_handle_value, file_map_access, high_size, low_size, filename
+ ( winapi::invalid_handle_value, protection, size, filename
, (winapi::interprocess_security_attributes*)perm.get_permissions());
}
break;
diff --git a/boost/interprocess/xsi_shared_memory.hpp b/boost/interprocess/xsi_shared_memory.hpp
index 3d09c77399..e84d9b1c54 100644
--- a/boost/interprocess/xsi_shared_memory.hpp
+++ b/boost/interprocess/xsi_shared_memory.hpp
@@ -78,21 +78,21 @@ class xsi_shared_memory
xsi_shared_memory(open_only_t, const xsi_key &key)
{ this->priv_open_or_create(ipcdetail::DoOpen, key, permissions(), 0); }
- //!Moves the ownership of "moved"'s shared memory object to *this.
- //!After the call, "moved" does not represent any shared memory object.
+ //!Moves the ownership of "moved"'s shared memory object to *this.
+ //!After the call, "moved" does not represent any shared memory object.
//!Does not throw
xsi_shared_memory(BOOST_RV_REF(xsi_shared_memory) moved)
: m_shmid(-1)
{ this->swap(moved); }
//!Moves the ownership of "moved"'s shared memory to *this.
- //!After the call, "moved" does not represent any shared memory.
+ //!After the call, "moved" does not represent any shared memory.
//!Does not throw
xsi_shared_memory &operator=(BOOST_RV_REF(xsi_shared_memory) moved)
- {
+ {
xsi_shared_memory tmp(boost::move(moved));
this->swap(tmp);
- return *this;
+ return *this;
}
//!Swaps two xsi_shared_memorys. Does not throw
@@ -129,11 +129,11 @@ class xsi_shared_memory
/// @cond
-inline xsi_shared_memory::xsi_shared_memory()
+inline xsi_shared_memory::xsi_shared_memory()
: m_shmid(-1)
{}
-inline xsi_shared_memory::~xsi_shared_memory()
+inline xsi_shared_memory::~xsi_shared_memory()
{}
inline int xsi_shared_memory::get_shmid() const