mirror of
https://github.com/boostorg/interprocess.git
synced 2026-01-19 04:12:13 +00:00
* Updated documentation to show rvalue-references funcions instead of emulation functions.
* More non-copyable classes are now movable. * Move-constructor and assignments now leave moved object in default-constructed state instead of just swapping contents. * Several bugfixes (#2391, #2431, #1390, #2570, #2528). [SVN r50258]
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
[/
|
||||
/ Copyright (c) 2007 Ion Gaztanaga
|
||||
/ Copyright (c) 2007-2008 Ion Gaztanaga
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -8,7 +8,7 @@
|
||||
[library Boost.Interprocess
|
||||
[quickbook 1.3]
|
||||
[authors [Gaztañaga, Ion]]
|
||||
[copyright 2005- 2007 Ion Gaztañaga]
|
||||
[copyright 2005- 2008 Ion Gaztañaga]
|
||||
[id interprocess]
|
||||
[dirname interprocess]
|
||||
[purpose Interprocess communication utilities]
|
||||
@@ -1516,11 +1516,11 @@ In the previous example, a mutex is used to ['lock] but we can't use it to
|
||||
can do two things:
|
||||
|
||||
* [*wait]: The thread is blocked until some other thread notifies that it can
|
||||
continue because the condition that lead to waiting has disapeared.
|
||||
continue because the condition that lead to waiting has disappeared.
|
||||
|
||||
* [*notify]: The thread sends a signal to one blocked thread or to all blocked
|
||||
threads to tell them that they the condition that provoked their wait has
|
||||
disapeared.
|
||||
disappeared.
|
||||
|
||||
Waiting in a condition variable is always associated with a mutex.
|
||||
The mutex must be locked prior to waiting on the condition. When waiting
|
||||
@@ -2178,7 +2178,7 @@ These operations can be managed more effectively using [*lock transfer operation
|
||||
A lock transfer operations explicitly indicates that a mutex owned by a lock is
|
||||
transferred to another lock executing atomic unlocking plus locking operations.
|
||||
|
||||
[section:lock_trnasfer_simple_transfer Simple Lock Transfer]
|
||||
[section:lock_transfer_simple_transfer Simple Lock Transfer]
|
||||
|
||||
Imagine that a thread modifies some data in the beginning but after that, it has to
|
||||
just read it in a long time. The code can acquire the exclusive lock, modify the data
|
||||
@@ -3668,10 +3668,10 @@ corrupted.
|
||||
As mentioned, the managed segment stores the information about named and unique
|
||||
objects in two indexes. Depending on the type of those indexes, the index must
|
||||
reallocate some auxiliary structures when new named or unique allocations are made.
|
||||
For some indexes, if the user knows how many maned or unique objects is going to
|
||||
create it's possible to preallocate some structures to obtain much better
|
||||
performance (if the index is an ordered vector it can preallocate memory to avoid
|
||||
reallocations, if the index is a hash structure it can preallocate the bucket array...).
|
||||
For some indexes, if the user knows how many named or unique objects are going to
|
||||
be created it's possible to preallocate some structures to obtain much better
|
||||
performance. (If the index is an ordered vector it can preallocate memory to avoid
|
||||
reallocations. If the index is a hash structure it can preallocate the bucket array).
|
||||
|
||||
The following functions reserve memory to make the subsequent allocation of
|
||||
named or unique objects more efficient. These functions are only useful for
|
||||
@@ -5671,7 +5671,7 @@ including creating containers of such objects:
|
||||
[section:basic_guidelines Basic guidelines]
|
||||
|
||||
When building [*Boost.Interprocess] architecture, I took some basic guidelines that can be
|
||||
resumed in these points:
|
||||
summarized by these points:
|
||||
|
||||
* [*Boost.Interprocess] should be portable at least in UNIX and Windows systems. That
|
||||
means unifying not only interfaces but also behaviour. This is why
|
||||
@@ -6541,6 +6541,16 @@ warranty.
|
||||
|
||||
[section:release_notes Release Notes]
|
||||
|
||||
[section:release_notes_boost_1_38_00 Boost 1.38 Release]
|
||||
|
||||
* Updated documentation to show rvalue-references funcions instead of emulation functions.
|
||||
* More non-copyable classes are now movable.
|
||||
* Move-constructor and assignments now leave moved object in default-constructed state
|
||||
instead of just swapping contents.
|
||||
* Several bugfixes (#2391, #2431, #1390, #2570, #2528).
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:release_notes_boost_1_37_00 Boost 1.37 Release]
|
||||
|
||||
* Containers can be used now in recursive types.
|
||||
|
||||
@@ -22,7 +22,6 @@ rule test_all
|
||||
for local fileb in [ glob *.cpp ]
|
||||
{
|
||||
all_rules += [ link $(fileb) /boost/thread//boost_thread
|
||||
# all_rules += [ compile $(fileb)
|
||||
: # additional args
|
||||
: # test-files
|
||||
: # requirements
|
||||
|
||||
@@ -52,3 +52,19 @@
|
||||
->find a way to pass security attributes to shared memory
|
||||
|
||||
->Explain in docs that shared memory can't be used between different users in windows
|
||||
|
||||
-> Implement vector with memcpy/memmove for trivially copyable types.
|
||||
|
||||
-> Update all swap() calls to work with rvalues in all classes
|
||||
|
||||
-> correct swap overloads for the documentation so that just appears a single rvalue swap
|
||||
|
||||
-> correct splice()/merg overloads for the documentation so that just appears a single rvalue splice
|
||||
|
||||
-> flat_xxx constructors are not documented
|
||||
|
||||
-> operator >> eta antzekoek moved_value behar dute
|
||||
|
||||
-> make file_lock movable
|
||||
|
||||
-> Add cmath workaround for Boost < 1.37
|
||||
|
||||
@@ -312,7 +312,7 @@
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Managed Memory Classes"
|
||||
Name="Public interface"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
<File
|
||||
|
||||
@@ -123,6 +123,17 @@ bool do_test()
|
||||
{
|
||||
deque<recursive_deque> recursive_deque_deque;
|
||||
}
|
||||
|
||||
{
|
||||
//Now test move semantics
|
||||
deque<recursive_deque> original;
|
||||
deque<recursive_deque> move_ctor(detail::move_impl(original));
|
||||
deque<recursive_deque> move_assign;
|
||||
move_assign = detail::move_impl(move_ctor);
|
||||
move_assign.swap(detail::move_impl(original));
|
||||
move_assign.swap(original);
|
||||
}
|
||||
|
||||
//Customize managed_shared_memory class
|
||||
typedef basic_managed_shared_memory
|
||||
<char,
|
||||
|
||||
@@ -49,7 +49,16 @@ int main ()
|
||||
{
|
||||
scoped_lock<file_lock> sl(flock, test::delay(1));
|
||||
}
|
||||
}
|
||||
}/*
|
||||
{
|
||||
//Now test move semantics
|
||||
file_lock mapping(test::get_process_id_name());
|
||||
file_lock move_ctor(detail::move_impl(mapping));
|
||||
file_lock move_assign;
|
||||
move_assign = detail::move_impl(move_ctor);
|
||||
mapping.swap(detail::move_impl(move_assign));
|
||||
mapping.swap(move_assign);
|
||||
}*/
|
||||
|
||||
//test::test_all_lock<file_lock_lock_test_wrapper>();
|
||||
//test::test_all_mutex<false, file_lock_lock_test_wrapper>();
|
||||
|
||||
@@ -128,6 +128,8 @@ int main ()
|
||||
file_mapping move_ctor(detail::move_impl(mapping));
|
||||
file_mapping move_assign;
|
||||
move_assign = detail::move_impl(move_ctor);
|
||||
mapping.swap(detail::move_impl(move_assign));
|
||||
mapping.swap(move_assign);
|
||||
}
|
||||
}
|
||||
catch(std::exception &exc){
|
||||
|
||||
@@ -51,6 +51,15 @@ void recursive_list_test()//Test for recursive types
|
||||
int main ()
|
||||
{
|
||||
recursive_list_test();
|
||||
{
|
||||
//Now test move semantics
|
||||
list<recursive_list> original;
|
||||
list<recursive_list> move_ctor(detail::move_impl(original));
|
||||
list<recursive_list> move_assign;
|
||||
move_assign = detail::move_impl(move_ctor);
|
||||
move_assign.swap(detail::move_impl(original));
|
||||
move_assign.swap(original);
|
||||
}
|
||||
if(test::list_test<managed_shared_memory, MyList, true>())
|
||||
return 1;
|
||||
|
||||
|
||||
@@ -206,6 +206,8 @@ int main ()
|
||||
managed_mapped_file move_ctor(detail::move_impl(original));
|
||||
managed_mapped_file move_assign;
|
||||
move_assign = detail::move_impl(move_ctor);
|
||||
move_assign.swap(detail::move_impl(original));
|
||||
move_assign.swap(original);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -202,6 +202,8 @@ int main ()
|
||||
managed_shared_memory move_ctor(detail::move_impl(original));
|
||||
managed_shared_memory move_assign;
|
||||
move_assign = detail::move_impl(move_ctor);
|
||||
move_assign.swap(detail::move_impl(original));
|
||||
move_assign.swap(original);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ class movable_int
|
||||
{}
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
movable_int(const detail::moved_object<movable_int> &mmi)
|
||||
movable_int(detail::moved_object<movable_int> mmi)
|
||||
: m_int(mmi.get().m_int)
|
||||
{ mmi.get().m_int = 0; }
|
||||
#else
|
||||
@@ -45,7 +45,7 @@ class movable_int
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
movable_int & operator= (const detail::moved_object<movable_int> &mmi)
|
||||
movable_int & operator= (detail::moved_object<movable_int> mmi)
|
||||
{ this->m_int = mmi.get().m_int; mmi.get().m_int = 0; return *this; }
|
||||
#else
|
||||
movable_int & operator= (movable_int &&mmi)
|
||||
@@ -109,7 +109,7 @@ class movable_and_copyable_int
|
||||
{ this->m_int = mi.m_int; return *this; }
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
movable_and_copyable_int(const detail::moved_object<movable_and_copyable_int> &mmi)
|
||||
movable_and_copyable_int(detail::moved_object<movable_and_copyable_int> mmi)
|
||||
: m_int(mmi.get().m_int)
|
||||
{ mmi.get().m_int = 0; }
|
||||
#else
|
||||
@@ -119,7 +119,7 @@ class movable_and_copyable_int
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
|
||||
movable_and_copyable_int & operator= (const detail::moved_object<movable_and_copyable_int> &mmi)
|
||||
movable_and_copyable_int & operator= (detail::moved_object<movable_and_copyable_int> mmi)
|
||||
{ this->m_int = mmi.get().m_int; mmi.get().m_int = 0; return *this; }
|
||||
#else
|
||||
movable_and_copyable_int & operator= (movable_and_copyable_int &&mmi)
|
||||
|
||||
@@ -51,6 +51,15 @@ void recursive_slist_test()//Test for recursive types
|
||||
int main ()
|
||||
{
|
||||
recursive_slist_test();
|
||||
{
|
||||
//Now test move semantics
|
||||
slist<recursive_slist> original;
|
||||
slist<recursive_slist> move_ctor(detail::move_impl(original));
|
||||
slist<recursive_slist> move_assign;
|
||||
move_assign = detail::move_impl(move_ctor);
|
||||
move_assign.swap(detail::move_impl(original));
|
||||
move_assign.swap(original);
|
||||
}
|
||||
|
||||
if(test::list_test<managed_shared_memory, MyList, false>())
|
||||
return 1;
|
||||
|
||||
@@ -158,6 +158,18 @@ public:
|
||||
{ return a.id_ < b.id_; }
|
||||
};
|
||||
|
||||
template<class C>
|
||||
void test_move_semantics()
|
||||
{
|
||||
//Now test move semantics
|
||||
C original;
|
||||
C move_ctor(detail::move_impl(original));
|
||||
C move_assign;
|
||||
move_assign = detail::move_impl(move_ctor);
|
||||
move_assign.swap(detail::move_impl(original));
|
||||
move_assign.swap(original);
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
//Recursive container instantiation
|
||||
@@ -167,6 +179,13 @@ int main ()
|
||||
map<recursive_map, recursive_map> map_;
|
||||
multimap<recursive_multimap, recursive_multimap> multimap_;
|
||||
}
|
||||
//Now test move semantics
|
||||
{
|
||||
test_move_semantics<set<recursive_set> >();
|
||||
test_move_semantics<multiset<recursive_multiset> >();
|
||||
test_move_semantics<map<recursive_map, recursive_map> >();
|
||||
test_move_semantics<multimap<recursive_multimap, recursive_multimap> >();
|
||||
}
|
||||
|
||||
using namespace boost::interprocess::detail;
|
||||
|
||||
|
||||
@@ -56,6 +56,25 @@ int main ()
|
||||
const int memsize = 65536/size_aligner*size_aligner;
|
||||
static detail::max_align static_buffer[memsize/size_aligner];
|
||||
|
||||
{
|
||||
//Now test move semantics
|
||||
managed_heap_memory original(memsize);
|
||||
managed_heap_memory move_ctor(detail::move_impl(original));
|
||||
managed_heap_memory move_assign;
|
||||
move_assign = detail::move_impl(move_ctor);
|
||||
original.swap(detail::move_impl(move_assign));
|
||||
original.swap(move_assign);
|
||||
}
|
||||
{
|
||||
//Now test move semantics
|
||||
managed_external_buffer original(create_only, static_buffer, memsize);
|
||||
managed_external_buffer move_ctor(detail::move_impl(original));
|
||||
managed_external_buffer move_assign;
|
||||
move_assign = detail::move_impl(move_ctor);
|
||||
original.swap(detail::move_impl(move_assign));
|
||||
original.swap(move_assign);
|
||||
}
|
||||
|
||||
//Named new capable user mem allocator
|
||||
wmanaged_external_buffer user_buffer(create_only, static_buffer, memsize);
|
||||
|
||||
|
||||
@@ -91,6 +91,15 @@ void recursive_vector_test()//Test for recursive types
|
||||
int main()
|
||||
{
|
||||
recursive_vector_test();
|
||||
{
|
||||
//Now test move semantics
|
||||
vector<recursive_vector> original;
|
||||
vector<recursive_vector> move_ctor(detail::move_impl(original));
|
||||
vector<recursive_vector> move_assign;
|
||||
move_assign = detail::move_impl(move_ctor);
|
||||
move_assign.swap(detail::move_impl(original));
|
||||
move_assign.swap(original);
|
||||
}
|
||||
typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;
|
||||
typedef vector<int, ShmemAllocator> MyVector;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user