From 06eef6f4e820a489e8442f4d6d8ba3f5a3e215d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 14 Jul 2014 23:34:17 +0200 Subject: [PATCH] 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. --- .../detail/intermodule_singleton.hpp | 2 +- .../detail/intermodule_singleton_common.hpp | 10 +++---- .../detail/portable_intermodule_singleton.hpp | 2 +- .../detail/windows_intermodule_singleton.hpp | 11 ++++---- test/intermodule_singleton_test.cpp | 26 ++++++++++--------- 5 files changed, 27 insertions(+), 24 deletions(-) diff --git a/include/boost/interprocess/detail/intermodule_singleton.hpp b/include/boost/interprocess/detail/intermodule_singleton.hpp index 7d9dcd5..a999348 100644 --- a/include/boost/interprocess/detail/intermodule_singleton.hpp +++ b/include/boost/interprocess/detail/intermodule_singleton.hpp @@ -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 +template class intermodule_singleton #ifdef BOOST_INTERPROCESS_WINDOWS : public windows_intermodule_singleton diff --git a/include/boost/interprocess/detail/intermodule_singleton_common.hpp b/include/boost/interprocess/detail/intermodule_singleton_common.hpp index ef3a0bf..10c9ece 100644 --- a/include/boost/interprocess/detail/intermodule_singleton_common.hpp +++ b/include/boost/interprocess/detail/intermodule_singleton_common.hpp @@ -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; } diff --git a/include/boost/interprocess/detail/portable_intermodule_singleton.hpp b/include/boost/interprocess/detail/portable_intermodule_singleton.hpp index 5a62b42..80897f2 100644 --- a/include/boost/interprocess/detail/portable_intermodule_singleton.hpp +++ b/include/boost/interprocess/detail/portable_intermodule_singleton.hpp @@ -343,7 +343,7 @@ struct thread_safe_global_map_dependant } //namespace intermodule_singleton_helpers { -template +template class portable_intermodule_singleton : public intermodule_singleton_impl {}; diff --git a/include/boost/interprocess/detail/windows_intermodule_singleton.hpp b/include/boost/interprocess/detail/windows_intermodule_singleton.hpp index 041557a..5810268 100644 --- a/include/boost/interprocess/detail/windows_intermodule_singleton.hpp +++ b/include/boost/interprocess/detail/windows_intermodule_singleton.hpp @@ -17,6 +17,7 @@ #include #include +#include #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 map_type; + typedef boost::container::map map_type; public: windows_semaphore_based_map() @@ -182,7 +183,7 @@ class windows_semaphore_based_map { scoped_lock 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 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 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 @@ -290,7 +291,7 @@ struct thread_safe_global_map_dependant } //namespace intermodule_singleton_helpers { -template +template class windows_intermodule_singleton : public intermodule_singleton_impl < C diff --git a/test/intermodule_singleton_test.cpp b/test/intermodule_singleton_test.cpp index c66fa98..ce1e59c 100644 --- a/test/intermodule_singleton_test.cpp +++ b/test/intermodule_singleton_test.cpp @@ -47,20 +47,20 @@ class MyThrowingClass }; -template < template class IntermoduleType > +template < template class IntermoduleType > int intermodule_singleton_test() { bool exception_thrown = false; bool exception_2_thrown = false; try{ - IntermoduleType::get(); + IntermoduleType::get(); } catch(int &){ exception_thrown = true; //Second try try{ - IntermoduleType::get(); + IntermoduleType::get(); } catch(interprocess_exception &){ exception_2_thrown = true; @@ -71,15 +71,15 @@ int intermodule_singleton_test() return 1; } - MyClass & mc = IntermoduleType::get(); + MyClass & mc = IntermoduleType::get(); mc.shout(); - IntermoduleType::get().shout(); - IntermoduleType::get().shout(); + IntermoduleType::get().shout(); + IntermoduleType::get().shout(); //Second try exception_2_thrown = false; try{ - IntermoduleType::get(); + IntermoduleType::get(); } catch(interprocess_exception &){ exception_2_thrown = true; @@ -222,7 +222,7 @@ class LogDeadReferenceUser } }; -template < template class IntermoduleType > +template < template class IntermoduleType > int phoenix_singleton_test() { typedef int DummyType; @@ -254,7 +254,7 @@ int phoenix_singleton_test() return 0; } -template < template class IntermoduleType > +template < template class IntermoduleType > int dead_reference_singleton_test() { typedef int DummyType; @@ -280,13 +280,13 @@ int dead_reference_singleton_test() } //reduce name length -template +template class port_singleton : public ipcdetail::portable_intermodule_singleton {}; #ifdef BOOST_INTERPROCESS_WINDOWS -template +template 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(); #ifdef BOOST_INTERPROCESS_WINDOWS phoenix_singleton_test(); #endif + #endif //Dead reference singletons are tested after main ends, //LogDeadReferenceUser does the work @@ -322,4 +325,3 @@ int main () } #include -