mirror of
https://github.com/boostorg/interprocess.git
synced 2026-01-19 04:12:13 +00:00
intermodule_singleton fixes for many platforms:
- Use Boost.Container to allow debug-release mixed code (in some platforms, std:: containers' ABI changes from Debug to Release) - By default non-Phoenix and Lazy singletons. - Use atexit instead of the global object destructor to obtain LIFO semantics. - Avoid testing Phoenix singletons, as in many plataforms calling atexit from atexit is not supported.
This commit is contained in:
@@ -31,7 +31,7 @@ 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 = true, bool Phoenix = true>
|
||||
template<typename C, bool LazyInit = true, bool Phoenix = false>
|
||||
class intermodule_singleton
|
||||
#ifdef BOOST_INTERPROCESS_WINDOWS
|
||||
: public windows_intermodule_singleton<C, LazyInit, Phoenix>
|
||||
|
||||
@@ -364,9 +364,9 @@ class intermodule_singleton_impl
|
||||
|
||||
~lifetime_type_lazy()
|
||||
{
|
||||
if(!Phoenix){
|
||||
atexit_work();
|
||||
}
|
||||
//if(!Phoenix){
|
||||
//atexit_work();
|
||||
//}
|
||||
}
|
||||
|
||||
//Dummy volatile so that the compiler can't resolve its value at compile-time
|
||||
@@ -413,9 +413,9 @@ class intermodule_singleton_impl
|
||||
throw;
|
||||
}
|
||||
}
|
||||
if(Phoenix){
|
||||
//if(Phoenix){
|
||||
std::atexit(&atexit_work);
|
||||
}
|
||||
//}
|
||||
atomic_inc32(&rcount->singleton_ref_count);
|
||||
ret_ptr = rcount->ptr;
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@ struct thread_safe_global_map_dependant<managed_global_memory>
|
||||
|
||||
} //namespace intermodule_singleton_helpers {
|
||||
|
||||
template<typename C, bool LazyInit = true, bool Phoenix = true>
|
||||
template<typename C, bool LazyInit = true, bool Phoenix = false>
|
||||
class portable_intermodule_singleton
|
||||
: public intermodule_singleton_impl<C, LazyInit, Phoenix, managed_global_memory>
|
||||
{};
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/container/string.hpp>
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_WINDOWS)
|
||||
#error "This header can't be included from non-windows operating systems"
|
||||
@@ -49,7 +50,7 @@ namespace intermodule_singleton_helpers {
|
||||
// max and current semaphore count.
|
||||
class windows_semaphore_based_map
|
||||
{
|
||||
typedef boost::container::map<std::string, ref_count_ptr> map_type;
|
||||
typedef boost::container::map<boost::container::string, ref_count_ptr> map_type;
|
||||
|
||||
public:
|
||||
windows_semaphore_based_map()
|
||||
@@ -182,7 +183,7 @@ class windows_semaphore_based_map
|
||||
{
|
||||
scoped_lock<winapi_mutex_wrapper> lck(m_mtx_lock);
|
||||
map_type &map = this->get_map_unlocked();
|
||||
map_type::iterator it = map.find(std::string(name));
|
||||
map_type::iterator it = map.find(boost::container::string(name));
|
||||
if(it != map.end()){
|
||||
return &it->second;
|
||||
}
|
||||
@@ -195,7 +196,7 @@ class windows_semaphore_based_map
|
||||
{
|
||||
scoped_lock<winapi_mutex_wrapper> lck(m_mtx_lock);
|
||||
map_type &map = this->get_map_unlocked();
|
||||
map_type::iterator it = map.insert(map_type::value_type(std::string(name), ref)).first;
|
||||
map_type::iterator it = map.insert(map_type::value_type(boost::container::string(name), ref)).first;
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
@@ -203,7 +204,7 @@ class windows_semaphore_based_map
|
||||
{
|
||||
scoped_lock<winapi_mutex_wrapper> lck(m_mtx_lock);
|
||||
map_type &map = this->get_map_unlocked();
|
||||
return map.erase(std::string(name)) != 0;
|
||||
return map.erase(boost::container::string(name)) != 0;
|
||||
}
|
||||
|
||||
template<class F>
|
||||
@@ -290,7 +291,7 @@ struct thread_safe_global_map_dependant<windows_semaphore_based_map>
|
||||
|
||||
} //namespace intermodule_singleton_helpers {
|
||||
|
||||
template<typename C, bool LazyInit = true, bool Phoenix = true>
|
||||
template<typename C, bool LazyInit = true, bool Phoenix = false>
|
||||
class windows_intermodule_singleton
|
||||
: public intermodule_singleton_impl
|
||||
< C
|
||||
|
||||
@@ -47,20 +47,20 @@ class MyThrowingClass
|
||||
};
|
||||
|
||||
|
||||
template < template<class T, bool LazyInit = false, bool Phoenix = true> class IntermoduleType >
|
||||
template < template<class T, bool LazyInit, bool Phoenix> class IntermoduleType >
|
||||
int intermodule_singleton_test()
|
||||
{
|
||||
bool exception_thrown = false;
|
||||
bool exception_2_thrown = false;
|
||||
|
||||
try{
|
||||
IntermoduleType<MyThrowingClass, true>::get();
|
||||
IntermoduleType<MyThrowingClass, true, false>::get();
|
||||
}
|
||||
catch(int &){
|
||||
exception_thrown = true;
|
||||
//Second try
|
||||
try{
|
||||
IntermoduleType<MyThrowingClass, true>::get();
|
||||
IntermoduleType<MyThrowingClass, true, false>::get();
|
||||
}
|
||||
catch(interprocess_exception &){
|
||||
exception_2_thrown = true;
|
||||
@@ -71,15 +71,15 @@ int intermodule_singleton_test()
|
||||
return 1;
|
||||
}
|
||||
|
||||
MyClass & mc = IntermoduleType<MyClass>::get();
|
||||
MyClass & mc = IntermoduleType<MyClass, true, false>::get();
|
||||
mc.shout();
|
||||
IntermoduleType<MyClass>::get().shout();
|
||||
IntermoduleType<MyDerivedClass>::get().shout();
|
||||
IntermoduleType<MyClass, true, false>::get().shout();
|
||||
IntermoduleType<MyDerivedClass, true, false>::get().shout();
|
||||
|
||||
//Second try
|
||||
exception_2_thrown = false;
|
||||
try{
|
||||
IntermoduleType<MyThrowingClass, true>::get();
|
||||
IntermoduleType<MyThrowingClass, true, false>::get();
|
||||
}
|
||||
catch(interprocess_exception &){
|
||||
exception_2_thrown = true;
|
||||
@@ -222,7 +222,7 @@ class LogDeadReferenceUser
|
||||
}
|
||||
};
|
||||
|
||||
template < template<class T, bool LazyInit = false, bool Phoenix = true> class IntermoduleType >
|
||||
template < template<class T, bool LazyInit, bool Phoenix> class IntermoduleType >
|
||||
int phoenix_singleton_test()
|
||||
{
|
||||
typedef int DummyType;
|
||||
@@ -254,7 +254,7 @@ int phoenix_singleton_test()
|
||||
return 0;
|
||||
}
|
||||
|
||||
template < template<class T, bool LazyInit = false, bool Phoenix = true> class IntermoduleType >
|
||||
template < template<class T, bool LazyInit, bool Phoenix> class IntermoduleType >
|
||||
int dead_reference_singleton_test()
|
||||
{
|
||||
typedef int DummyType;
|
||||
@@ -280,13 +280,13 @@ int dead_reference_singleton_test()
|
||||
}
|
||||
|
||||
//reduce name length
|
||||
template<typename C, bool LazyInit = true, bool Phoenix = true>
|
||||
template<typename C, bool LazyInit, bool Phoenix>
|
||||
class port_singleton
|
||||
: public ipcdetail::portable_intermodule_singleton<C, LazyInit, Phoenix>
|
||||
{};
|
||||
|
||||
#ifdef BOOST_INTERPROCESS_WINDOWS
|
||||
template<typename C, bool LazyInit = true, bool Phoenix = true>
|
||||
template<typename C, bool LazyInit, bool Phoenix>
|
||||
class win_singleton
|
||||
: public ipcdetail::windows_intermodule_singleton< C, LazyInit, Phoenix>
|
||||
{};
|
||||
@@ -304,12 +304,15 @@ int main ()
|
||||
}
|
||||
#endif
|
||||
|
||||
//Only few platforms support this
|
||||
#ifdef BOOST_INTERPROCESS_ATEXIT_CALLABLE_FROM_ATEXIT
|
||||
//Phoenix singletons are tested after main ends,
|
||||
//LogPhoenixTester does the work
|
||||
phoenix_singleton_test<port_singleton>();
|
||||
#ifdef BOOST_INTERPROCESS_WINDOWS
|
||||
phoenix_singleton_test<win_singleton>();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//Dead reference singletons are tested after main ends,
|
||||
//LogDeadReferenceUser does the work
|
||||
@@ -322,4 +325,3 @@ int main ()
|
||||
}
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user