mirror of
https://github.com/boostorg/interprocess.git
synced 2026-01-19 04:12:13 +00:00
Trailing spaces and Phoenix singleton for intermodule_singleton
[SVN r78514]
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -92,13 +92,13 @@ 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);
|
||||
|
||||
@@ -390,96 +390,96 @@ inline boost::uint32_t atomic_cas32(
|
||||
} //namespace interprocess{
|
||||
} //namespace boost{
|
||||
|
||||
#elif defined(__IBMCPP__) && (__IBMCPP__ >= 800) && defined(_AIX)
|
||||
#elif defined(__IBMCPP__) && (__IBMCPP__ >= 800) && defined(_AIX)
|
||||
|
||||
#include <builtins.h>
|
||||
#include <builtins.h>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace ipcdetail{
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace ipcdetail{
|
||||
|
||||
//first define boost::uint32_t versions of __lwarx and __stwcx to avoid poluting
|
||||
//all the functions with casts
|
||||
//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)));
|
||||
}
|
||||
//! 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" : 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;
|
||||
}
|
||||
//! "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 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 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; }
|
||||
//! 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));
|
||||
//! 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;
|
||||
}
|
||||
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; }
|
||||
//! 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 ipcdetail
|
||||
} //namespace interprocess
|
||||
} //namespace boost
|
||||
|
||||
#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
|
||||
@@ -552,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>
|
||||
|
||||
@@ -287,7 +287,7 @@ inline bool compare_file_serial(int fd, const locking_file_serial_id &id)
|
||||
id.st_ino == info.st_ino;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
} //namespace ipcdetail{
|
||||
} //namespace interprocess{
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -30,12 +30,12 @@ namespace ipcdetail{
|
||||
//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
|
||||
{};
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <boost/assert.hpp>
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
@@ -61,9 +62,8 @@ struct managed_sh_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 reference counted shared memory
|
||||
//to be used by all instances
|
||||
|
||||
//code just once per module. This class also holds a shared memory manager
|
||||
//to be used by all instances protected with a reference count
|
||||
template<class ManagedGlobalMemory>
|
||||
class intermodule_singleton_common
|
||||
{
|
||||
@@ -75,12 +75,115 @@ class intermodule_singleton_common
|
||||
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;
|
||||
|
||||
static void finalize_singleton_logic(void *ptr, singleton_destructor_t destructor)
|
||||
//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.
|
||||
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 shared memory
|
||||
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 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_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_shm());
|
||||
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 shm destruction.
|
||||
//Note: singletons are destroyed when the module is unloaded
|
||||
@@ -92,22 +195,88 @@ class intermodule_singleton_common
|
||||
}
|
||||
}
|
||||
|
||||
static void initialize_singleton_logic
|
||||
(void *&ptr, volatile boost::uint32_t &this_module_singleton_initialized, singleton_constructor_t ini_func);
|
||||
|
||||
private:
|
||||
static ManagedGlobalMemory &get_shm()
|
||||
{
|
||||
return *static_cast<ManagedGlobalMemory *>(static_cast<void *>(&mem_holder.shm_mem));
|
||||
}
|
||||
|
||||
static void initialize_shm();
|
||||
static void destroy_shm();
|
||||
static void 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<ManagedGlobalMemory>::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())ManagedGlobalMemory(open_or_create, ShmName, ShmSize);
|
||||
//Use shared memory internal lock to initialize the lock file
|
||||
//that will mark this gmem as "in use".
|
||||
typename intermodule_singleton_helpers::managed_sh_dependant<ManagedGlobalMemory>::
|
||||
lock_file_logic 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().~ManagedGlobalMemory();
|
||||
atomic_write32(&this_module_shm_initialized, Destroyed);
|
||||
}
|
||||
else{
|
||||
//Locking succeeded, so this shared memory module-instance is ready
|
||||
atomic_write32(&this_module_shm_initialized, Initialized);
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch(...){
|
||||
//
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void 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
|
||||
typename intermodule_singleton_helpers::managed_sh_dependant<ManagedGlobalMemory>::
|
||||
unlink_shmlogic f(get_shm());
|
||||
(get_shm()).~ManagedGlobalMemory();
|
||||
atomic_write32(&this_module_shm_initialized, Destroyed);
|
||||
//Do some cleanup for other processes old gmem instances
|
||||
intermodule_singleton_helpers::managed_sh_dependant<ManagedGlobalMemory>::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_shm_initialized is the state of this module's shm class object
|
||||
|
||||
//this_module_shm_initialized is the state of this module's shm class object.
|
||||
//Values: Uninitialized, Initializing, Initialized, Broken
|
||||
static volatile boost::uint32_t this_module_shm_initialized;
|
||||
|
||||
//Raw memory to construct the shared memory manager
|
||||
static struct mem_holder_t
|
||||
{
|
||||
::boost::detail::max_align aligner;
|
||||
@@ -125,189 +294,42 @@ template<class ManagedGlobalMemory>
|
||||
typename intermodule_singleton_common<ManagedGlobalMemory>::mem_holder_t
|
||||
intermodule_singleton_common<ManagedGlobalMemory>::mem_holder;
|
||||
|
||||
template<class ManagedGlobalMemory>
|
||||
void intermodule_singleton_common<ManagedGlobalMemory>::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<ManagedGlobalMemory>::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())ManagedGlobalMemory(open_or_create, ShmName, ShmSize);
|
||||
//Use shared memory internal lock to initialize the lock file
|
||||
//that will mark this gmem as "in use".
|
||||
typename intermodule_singleton_helpers::managed_sh_dependant<ManagedGlobalMemory>::
|
||||
lock_file_logic 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().~ManagedGlobalMemory();
|
||||
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 ManagedGlobalMemory>
|
||||
void intermodule_singleton_common<ManagedGlobalMemory>::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
|
||||
typename intermodule_singleton_helpers::managed_sh_dependant<ManagedGlobalMemory>::
|
||||
unlink_shmlogic f(get_shm());
|
||||
(get_shm()).~ManagedGlobalMemory();
|
||||
atomic_write32(&this_module_shm_initialized, Uninitialized);
|
||||
//Do some cleanup for other processes old gmem instances
|
||||
intermodule_singleton_helpers::managed_sh_dependant<ManagedGlobalMemory>::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 ManagedGlobalMemory>
|
||||
void intermodule_singleton_common<ManagedGlobalMemory>::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 ManagedGlobalMemory>
|
||||
template<typename C, bool LazyInit, bool Phoenix, class ManagedGlobalMemory>
|
||||
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<ManagedGlobalMemory>::initialize_singleton_logic
|
||||
(this_module_singleton_ptr, this_module_singleton_initialized, singleton_constructor);
|
||||
if(lifetime.dummy_function()){ //This forces lifetime instantiation, for reference counted destruction
|
||||
atentry_work();
|
||||
}
|
||||
}
|
||||
return *static_cast<C*>(this_module_singleton_ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
struct ref_count_ptr
|
||||
static void atentry_work()
|
||||
{
|
||||
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;
|
||||
};
|
||||
intermodule_singleton_common<ManagedGlobalMemory>::initialize_singleton_logic
|
||||
(this_module_singleton_ptr, this_module_singleton_initialized, singleton_constructor, Phoenix);
|
||||
}
|
||||
|
||||
static void atexit_work()
|
||||
{
|
||||
intermodule_singleton_common<ManagedGlobalMemory>::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.
|
||||
@@ -321,9 +343,11 @@ class intermodule_singleton_impl
|
||||
|
||||
~lifetime_type_lazy()
|
||||
{
|
||||
intermodule_singleton_common<ManagedGlobalMemory>::finalize_singleton_logic
|
||||
(this_module_singleton_ptr, singleton_destructor);
|
||||
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;
|
||||
@@ -333,10 +357,7 @@ class intermodule_singleton_impl
|
||||
: public lifetime_type_lazy
|
||||
{
|
||||
lifetime_type_static()
|
||||
{
|
||||
intermodule_singleton_common<ManagedGlobalMemory>::initialize_singleton_logic
|
||||
(this_module_singleton_ptr, this_module_singleton_initialized, singleton_constructor);
|
||||
}
|
||||
{ atentry_work(); }
|
||||
};
|
||||
|
||||
typedef typename if_c
|
||||
@@ -344,6 +365,20 @@ class intermodule_singleton_impl
|
||||
|
||||
static lifetime_type lifetime;
|
||||
|
||||
//A reference count to be stored in shared memory holding the number
|
||||
//of singletons (one per module) attached to the instance pointed by
|
||||
//the internal ptr.
|
||||
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;
|
||||
};
|
||||
|
||||
//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
|
||||
@@ -366,6 +401,9 @@ class intermodule_singleton_impl
|
||||
throw;
|
||||
}
|
||||
}
|
||||
if(Phoenix){
|
||||
std::atexit(&atexit_work);
|
||||
}
|
||||
atomic_inc32(&rcount->singleton_ref_count);
|
||||
ret_ptr = rcount->ptr;
|
||||
}
|
||||
@@ -416,19 +454,19 @@ class intermodule_singleton_impl
|
||||
}
|
||||
};
|
||||
|
||||
template <typename C, bool L, class ManagedGlobalMemory>
|
||||
volatile int intermodule_singleton_impl<C, L, ManagedGlobalMemory>::lifetime_type_lazy::m_dummy = 0;
|
||||
template <typename C, bool L, bool P, class ManagedGlobalMemory>
|
||||
volatile int intermodule_singleton_impl<C, L, P, ManagedGlobalMemory>::lifetime_type_lazy::m_dummy = 0;
|
||||
|
||||
//These will be zero-initialized by the loader
|
||||
template <typename C, bool L, class ManagedGlobalMemory>
|
||||
void *intermodule_singleton_impl<C, L, ManagedGlobalMemory>::this_module_singleton_ptr = 0;
|
||||
template <typename C, bool L, bool P, class ManagedGlobalMemory>
|
||||
void *intermodule_singleton_impl<C, L, P, ManagedGlobalMemory>::this_module_singleton_ptr = 0;
|
||||
|
||||
template <typename C, bool L, class ManagedGlobalMemory>
|
||||
volatile boost::uint32_t intermodule_singleton_impl<C, L, ManagedGlobalMemory>::this_module_singleton_initialized = 0;
|
||||
template <typename C, bool L, bool P, class ManagedGlobalMemory>
|
||||
volatile boost::uint32_t intermodule_singleton_impl<C, L, P, ManagedGlobalMemory>::this_module_singleton_initialized = 0;
|
||||
|
||||
template <typename C, bool L, class ManagedGlobalMemory>
|
||||
typename intermodule_singleton_impl<C, L, ManagedGlobalMemory>::lifetime_type
|
||||
intermodule_singleton_impl<C, L, ManagedGlobalMemory>::lifetime;
|
||||
template <typename C, bool L, bool P, class ManagedGlobalMemory>
|
||||
typename intermodule_singleton_impl<C, L, P, ManagedGlobalMemory>::lifetime_type
|
||||
intermodule_singleton_impl<C, L, P, ManagedGlobalMemory>::lifetime;
|
||||
|
||||
} //namespace ipcdetail{
|
||||
} //namespace interprocess{
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#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/mem_algo/rbtree_best_fit.hpp>
|
||||
#include <boost/interprocess/indexes/iset_index.hpp>
|
||||
#include <boost/interprocess/creation_tags.hpp>
|
||||
#include <boost/interprocess/permissions.hpp>
|
||||
@@ -53,7 +53,7 @@ struct intermodule_types
|
||||
|
||||
//we must implement our own managed shared memory to avoid circular dependencies
|
||||
template<class Device, bool FileBased>
|
||||
class basic_managed_global_memory
|
||||
class basic_managed_global_memory
|
||||
: public basic_managed_memory_impl
|
||||
< char
|
||||
, intermodule_types::mem_algo
|
||||
@@ -88,19 +88,19 @@ class basic_managed_global_memory
|
||||
public: //functions
|
||||
|
||||
basic_managed_global_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(),
|
||||
DoOpenOrCreate), perm)
|
||||
{}
|
||||
|
||||
basic_managed_global_memory (open_only_t open_only, const char* name,
|
||||
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(),
|
||||
, base2_t(open_only, name, read_write, addr,
|
||||
create_open_func_t(get_this_pointer(),
|
||||
DoOpen))
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 ®ion, 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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
|
||||
/*!\file
|
||||
Describes a named shared memory allocation user class.
|
||||
Describes a named shared memory allocation user class.
|
||||
*/
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
@@ -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,7 +189,7 @@ 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 = ~((unsigned long)(0u));
|
||||
// winapi::interprocess_overlapped overlapped;
|
||||
@@ -199,22 +199,22 @@ 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 = ~((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 = ~((unsigned long)(0u));
|
||||
winapi::interprocess_overlapped overlapped;
|
||||
std::memset(&overlapped, 0, sizeof(overlapped));
|
||||
@@ -222,7 +222,7 @@ inline bool release_file_lock(file_handle_t hnd)
|
||||
}
|
||||
|
||||
inline bool acquire_file_lock_sharable(file_handle_t hnd)
|
||||
{
|
||||
{
|
||||
const unsigned long len = ~((unsigned long)(0u));
|
||||
winapi::interprocess_overlapped overlapped;
|
||||
std::memset(&overlapped, 0, sizeof(overlapped));
|
||||
@@ -230,13 +230,13 @@ inline bool acquire_file_lock_sharable(file_handle_t hnd)
|
||||
}
|
||||
|
||||
inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired)
|
||||
{
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ struct pointer_type
|
||||
};
|
||||
|
||||
} //namespace ipcdetail {
|
||||
} //namespace interprocess {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
@@ -54,7 +54,7 @@ static void create_tmp_subdir_and_get_pid_based_filepath
|
||||
s += "/";
|
||||
s += file_prefix;
|
||||
if(creation_time){
|
||||
std::string sstamp;
|
||||
std::string sstamp;
|
||||
get_pid_creation_time_str(sstamp);
|
||||
s += sstamp;
|
||||
}
|
||||
@@ -137,13 +137,12 @@ struct managed_sh_dependant<managed_global_memory>
|
||||
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_;
|
||||
};
|
||||
|
||||
public:
|
||||
//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)
|
||||
{
|
||||
@@ -183,6 +182,8 @@ struct managed_sh_dependant<managed_global_memory>
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static bool remove_old_gmem()
|
||||
{
|
||||
std::string refcstrRootDirectory;
|
||||
@@ -307,9 +308,9 @@ struct managed_sh_dependant<managed_global_memory>
|
||||
|
||||
} //namespace intermodule_singleton_helpers {
|
||||
|
||||
template<typename C, bool LazyInit = false>
|
||||
template<typename C, bool LazyInit = true, bool Phoenix = true>
|
||||
class portable_intermodule_singleton
|
||||
: public intermodule_singleton_impl<C, LazyInit, managed_global_memory>
|
||||
: public intermodule_singleton_impl<C, LazyInit, Phoenix, managed_global_memory>
|
||||
{};
|
||||
|
||||
} //namespace ipcdetail{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace ipcdetail {
|
||||
|
||||
inline void get_bootstamp(std::string &s, bool add = false)
|
||||
{
|
||||
const windows_bootstamp &bootstamp = windows_intermodule_singleton<windows_bootstamp, true>::get();
|
||||
const windows_bootstamp &bootstamp = windows_intermodule_singleton<windows_bootstamp>::get();
|
||||
if(add){
|
||||
s += bootstamp.stamp;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)> >
|
||||
{};
|
||||
|
||||
@@ -214,158 +214,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 +373,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 +531,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 +554,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;
|
||||
@@ -581,8 +581,8 @@ struct interprocess_semaphore_basic_information
|
||||
};
|
||||
|
||||
struct interprocess_filetime
|
||||
{
|
||||
unsigned long dwLowDateTime;
|
||||
{
|
||||
unsigned long dwLowDateTime;
|
||||
unsigned long dwHighDateTime;
|
||||
};
|
||||
|
||||
@@ -628,7 +628,7 @@ struct system_info {
|
||||
|
||||
typedef struct _interprocess_memory_basic_information
|
||||
{
|
||||
void * BaseAddress;
|
||||
void * BaseAddress;
|
||||
void * AllocationBase;
|
||||
unsigned long AllocationProtect;
|
||||
unsigned long RegionSize;
|
||||
@@ -837,8 +837,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 *);
|
||||
@@ -900,10 +900,10 @@ 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 *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);
|
||||
@@ -1018,7 +1018,7 @@ inline int release_semaphore(void *handle, long release_count, long *prev_count)
|
||||
class interprocess_all_access_security
|
||||
{
|
||||
interprocess_security_attributes sa;
|
||||
interprocess_security_descriptor sd;
|
||||
interprocess_security_descriptor sd;
|
||||
bool initialized;
|
||||
|
||||
public:
|
||||
@@ -1041,7 +1041,7 @@ class interprocess_all_access_security
|
||||
|
||||
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)
|
||||
{
|
||||
return CreateFileMappingA (handle, psec, access, high_size, low_size, name);
|
||||
return CreateFileMappingA (handle, psec, access, high_size, low_size, name);
|
||||
}
|
||||
|
||||
inline void * open_file_mapping (unsigned long access, const char *name)
|
||||
@@ -1087,9 +1087,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)
|
||||
@@ -1279,7 +1279,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;
|
||||
@@ -1310,7 +1310,7 @@ inline bool get_file_name_from_handle_function
|
||||
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);
|
||||
@@ -1322,7 +1322,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);
|
||||
@@ -1416,81 +1415,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)){
|
||||
// (...)
|
||||
//
|
||||
|
||||
NtQueryObject_t pNtQueryObject =
|
||||
//(NtQueryObject_t)get_proc_address(get_module_handle("ntdll.dll"), "NtQueryObject");
|
||||
(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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
//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);
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
//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;
|
||||
|
||||
//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(...){
|
||||
//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)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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
//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);
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
//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;
|
||||
|
||||
//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(...){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1508,112 +1518,59 @@ 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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
//}
|
||||
//}
|
||||
//}
|
||||
//}
|
||||
//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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
//}
|
||||
//}
|
||||
//}
|
||||
//}
|
||||
//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
|
||||
@@ -1638,21 +1595,21 @@ inline bool get_wmi_class_attribute( std::wstring& strValue, const wchar_t *wmi_
|
||||
|
||||
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,
|
||||
@@ -1660,7 +1617,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;
|
||||
@@ -1692,7 +1649,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();
|
||||
@@ -1772,9 +1729,9 @@ inline bool is_directory(const char *path)
|
||||
(attrib & file_attribute_directory));
|
||||
}
|
||||
|
||||
} //namespace winapi
|
||||
} //namespace winapi
|
||||
} //namespace interprocess
|
||||
} //namespace boost
|
||||
} //namespace boost
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
|
||||
@@ -63,11 +63,12 @@ struct managed_sh_dependant<windows_managed_global_memory>
|
||||
|
||||
} //namespace intermodule_singleton_helpers {
|
||||
|
||||
template<typename C, bool LazyInit = false>
|
||||
template<typename C, bool LazyInit = true, bool Phoenix = true>
|
||||
class windows_intermodule_singleton
|
||||
: public intermodule_singleton_impl
|
||||
< C
|
||||
, LazyInit
|
||||
, Phoenix
|
||||
, windows_managed_global_memory
|
||||
>
|
||||
{};
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#define BOOST_INTERPROCESS_WINDOWS
|
||||
//#define BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION
|
||||
#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
|
||||
#else
|
||||
#else
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(_POSIX_THREAD_PROCESS_SHARED) && ((_POSIX_THREAD_PROCESS_SHARED - 0) > 0)
|
||||
@@ -27,7 +27,7 @@
|
||||
#define BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_POSIX_BARRIERS) && ((_POSIX_BARRIERS - 0) > 0)
|
||||
#define BOOST_INTERPROCESS_POSIX_BARRIERS
|
||||
#endif
|
||||
@@ -39,8 +39,8 @@
|
||||
#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)) ||\
|
||||
@@ -81,14 +81,14 @@
|
||||
|
||||
#if defined(_POSIX_TIMEOUTS) && ((_POSIX_TIMEOUTS - 0) > 0)
|
||||
#define BOOST_INTERPROCESS_POSIX_TIMEOUTS
|
||||
#endif
|
||||
#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))
|
||||
#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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
{}
|
||||
|
||||
|
||||
@@ -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))
|
||||
{}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ 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
|
||||
//!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.
|
||||
template<class MemoryMappable>
|
||||
@@ -123,7 +123,7 @@ class mapped_region
|
||||
//!Never throws.
|
||||
mode_t get_mode() const;
|
||||
|
||||
//!Flushes to the disk a byte range within the mapped memory.
|
||||
//!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);
|
||||
|
||||
@@ -175,7 +175,7 @@ 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
|
||||
inline offset_t mapped_region::get_offset() const
|
||||
{ return m_offset; }
|
||||
|
||||
inline mode_t mapped_region::get_mode() const
|
||||
@@ -514,7 +514,7 @@ inline mapped_region::mapped_region
|
||||
}
|
||||
|
||||
//Calculate new base for the user
|
||||
m_base = static_cast<char*>(base) + extra_offset;
|
||||
m_base = static_cast<char*>(base) + extra_offset;
|
||||
m_extra_offset = extra_offset;
|
||||
m_offset = offset;
|
||||
m_size = size;
|
||||
|
||||
@@ -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,7 +361,7 @@ class memory_algorithm_common
|
||||
if(old_user_units == preferred_user_units)
|
||||
return true;
|
||||
|
||||
size_type shrunk_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));
|
||||
}
|
||||
|
||||
@@ -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){
|
||||
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)); }
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,10 +134,10 @@ 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
|
||||
//!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
|
||||
@@ -150,14 +150,14 @@ class shared_ptr
|
||||
: 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)
|
||||
@@ -175,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>();
|
||||
@@ -223,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::
|
||||
@@ -239,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>
|
||||
@@ -253,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(); }
|
||||
@@ -297,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; }
|
||||
|
||||
@@ -316,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); }
|
||||
|
||||
@@ -336,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()); }
|
||||
|
||||
@@ -351,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; }
|
||||
|
||||
|
||||
@@ -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>());
|
||||
}
|
||||
|
||||
|
||||
@@ -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); }
|
||||
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -23,12 +23,12 @@ 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
|
||||
@@ -38,20 +38,20 @@ namespace ipcdetail {
|
||||
// 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)
|
||||
@@ -82,7 +82,7 @@ namespace ipcdetail {
|
||||
// nWaitersGone = 0;
|
||||
// }
|
||||
// unlock( mtxUnblockLock );
|
||||
//
|
||||
//
|
||||
// if ( 1 == nSignalsWasLeft ) {
|
||||
// if ( 0 != nWaitersWasGone ) {
|
||||
// // sem_adjust( semBlockQueue,-nWaitersWasGone );
|
||||
@@ -91,19 +91,19 @@ namespace ipcdetail {
|
||||
// }
|
||||
// } 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 );
|
||||
@@ -136,7 +136,7 @@ namespace ipcdetail {
|
||||
// else { // NO-OP
|
||||
// return unlock( mtxUnblockLock );
|
||||
// }
|
||||
//
|
||||
//
|
||||
// unlock( mtxUnblockLock );
|
||||
// sem_post( semBlockQueue,nSignalsToIssue );
|
||||
// return result;
|
||||
@@ -160,7 +160,7 @@ namespace ipcdetail {
|
||||
// semaphore_type &get_sem_block_lock()
|
||||
// mutex_type &get_mtx_unblock_lock()
|
||||
// };
|
||||
//
|
||||
//
|
||||
template<class ConditionMembers>
|
||||
class condition_algorithm_8a
|
||||
{
|
||||
@@ -197,7 +197,7 @@ inline void condition_algorithm_8a<ConditionMembers>::signal(ConditionMembers &d
|
||||
|
||||
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()
|
||||
//locker's destructor triggers data.get_mtx_unblock_lock().unlock()
|
||||
return;
|
||||
}
|
||||
if (broadcast) {
|
||||
@@ -226,10 +226,10 @@ inline void condition_algorithm_8a<ConditionMembers>::signal(ConditionMembers &d
|
||||
}
|
||||
}
|
||||
else { // NO-OP
|
||||
//locker's destructor triggers data.get_mtx_unblock_lock().unlock()
|
||||
//locker's destructor triggers data.get_mtx_unblock_lock().unlock()
|
||||
return;
|
||||
}
|
||||
//locker's destructor triggers data.get_mtx_unblock_lock().unlock()
|
||||
//locker's destructor triggers data.get_mtx_unblock_lock().unlock()
|
||||
}
|
||||
data.get_sem_block_queue().post(nsignals_to_issue);
|
||||
}
|
||||
@@ -242,7 +242,7 @@ inline bool condition_algorithm_8a<ConditionMembers>::wait
|
||||
//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();
|
||||
@@ -257,10 +257,10 @@ inline bool condition_algorithm_8a<ConditionMembers>::wait
|
||||
~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()) ) {
|
||||
@@ -289,9 +289,9 @@ inline bool condition_algorithm_8a<ConditionMembers>::wait
|
||||
data.get_sem_block_lock().post();
|
||||
data.get_nwaiters_gone() = 0;
|
||||
}
|
||||
//locker's destructor triggers data.get_mtx_unblock_lock().unlock()
|
||||
}
|
||||
|
||||
//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 );
|
||||
@@ -301,9 +301,9 @@ inline bool condition_algorithm_8a<ConditionMembers>::wait
|
||||
}
|
||||
data.get_sem_block_lock().post(); // open the gate
|
||||
}
|
||||
|
||||
|
||||
//mtxExternal.lock(); called from unlocker
|
||||
|
||||
|
||||
return ( bTimedOut ) ? false : true;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -55,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
|
||||
@@ -76,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();
|
||||
|
||||
@@ -84,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);
|
||||
@@ -95,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);
|
||||
|
||||
@@ -41,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
|
||||
@@ -60,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
|
||||
@@ -89,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();
|
||||
|
||||
@@ -37,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
|
||||
@@ -54,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
|
||||
@@ -83,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();
|
||||
|
||||
@@ -39,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
|
||||
{
|
||||
@@ -53,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
|
||||
@@ -84,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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
@@ -159,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);
|
||||
@@ -176,16 +176,16 @@ 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 //defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES)
|
||||
template<class Lock>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user