Skip to content

Commit

Permalink
corrected singleton and ran test_dll_exported on unix,mingv,windows a…
Browse files Browse the repository at this point in the history
…nd osx
  • Loading branch information
robertramey committed Nov 23, 2017
1 parent f94da2c commit 7d216b4
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 44 deletions.
2 changes: 1 addition & 1 deletion include/boost/archive/detail/common_iarchive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class extended_type_info;

// note: referred to as Curiously Recurring Template Patter (CRTP)
template<class Archive>
class BOOST_ARCHIVE_OR_WARCHIVE_DECL common_iarchive :
class BOOST_SYMBOL_VISIBLE common_iarchive :
public basic_iarchive,
public interface_iarchive<Archive>
{
Expand Down
2 changes: 1 addition & 1 deletion include/boost/archive/detail/common_oarchive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace detail {
// note: referred to as Curiously Recurring Template Patter (CRTP)
template<class Archive>

class BOOST_ARCHIVE_OR_WARCHIVE_DECL common_oarchive :
class BOOST_SYMBOL_VISIBLE common_oarchive :
public basic_oarchive,
public interface_oarchive<Archive>
{
Expand Down
6 changes: 2 additions & 4 deletions include/boost/archive/detail/iserializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ namespace std{
#include <boost/archive/detail/archive_serializer_map.hpp>
#include <boost/archive/detail/check.hpp>

#include <boost/core/addressof.hpp>

namespace boost {

namespace serialization {
Expand Down Expand Up @@ -405,11 +407,7 @@ struct load_non_pointer_type {
struct load_standard {
template<class T>
static void invoke(Archive &ar, const T & t){
#ifdef BOOST_NO_CXX11_ADDRESSOF
void * x = boost::addressof(const_cast<T &>(t));
#else
void * x = std::addressof(const_cast<T &>(t));
#endif
ar.load_object(
x,
boost::serialization::singleton<
Expand Down
8 changes: 0 additions & 8 deletions include/boost/archive/detail/oserializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,7 @@
#include <boost/archive/detail/archive_serializer_map.hpp>
#include <boost/archive/detail/check.hpp>

#ifdef BOOST_NO_CXX11_ADDRESSOF
#include <boost/core/addressof.hpp>
#else
#include <memory> // std::addressof
#endif

namespace boost {

Expand Down Expand Up @@ -260,11 +256,7 @@ struct save_non_pointer_type {
template<class T>
static void invoke(Archive &ar, const T & t){
ar.save_object(
#ifdef BOOST_NO_CXX11_ADDRESSOF
boost::addressof(t),
#else
std::addressof(t),
#endif
boost::serialization::singleton<
oserializer<Archive, T>
>::get_const_instance()
Expand Down
8 changes: 0 additions & 8 deletions include/boost/serialization/nvp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,7 @@
#include <boost/serialization/traits.hpp>
#include <boost/serialization/wrapper.hpp>

#ifdef BOOST_NO_CXX11_ADDRESSOF
#include <boost/core/addressof.hpp>
#else
#include <memory> // std::addressof
#endif

namespace boost {
namespace serialization {
Expand All @@ -49,11 +45,7 @@ struct nvp :
public:
explicit nvp(const char * name_, T & t) :
// note: added _ to suppress useless gcc warning
#ifdef BOOST_NO_CXX11_ADDRESSOF
std::pair<const char *, T *>(name_, boost::addressof(t))
#else
std::pair<const char *, T *>(name_, std::addressof(t))
#endif
{}

const char * name() const {
Expand Down
47 changes: 32 additions & 15 deletions include/boost/serialization/singleton.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,25 @@ namespace serialization {
// attempt to retieve a mutable instances while locked will
// generate a assertion if compiled for debug.

class BOOST_SERIALIZATION_DECL singleton_module :
// note usage of BOOST_DLLEXPORT. These functions are in danger of
// being eliminated by the optimizer when building an application in
// release mode. Usage of the macro is meant to signal the compiler/linker
// to avoid dropping these functions which seem to be unreferenced.
// This usage is not related to autolinking.

class BOOST_SYMBOL_VISIBLE singleton_module :
public boost::noncopyable
{
private:
static bool & get_lock() BOOST_USED;
BOOST_DLLEXPORT static bool & get_lock() BOOST_USED;
public:
static void lock(){
BOOST_DLLEXPORT static void lock(){
get_lock() = true;
}
static void unlock(){
BOOST_DLLEXPORT static void unlock(){
get_lock() = false;
}
static bool is_locked(){
BOOST_DLLEXPORT static bool is_locked(){
return get_lock();
}
};
Expand All @@ -109,41 +115,52 @@ class singleton : public singleton_module
// use a wrapper so that types T with protected constructors
// can be used
class singleton_wrapper : public T {};
static singleton_wrapper t;

// Use a heap-allocated instance to work around static variable
// destruction order issues: this inner singleton_wrapper<>
// instance may be destructed before the singleton<> instance.
// Using a 'dumb' static variable lets us precisely choose the
// time destructor is invoked.
static singleton_wrapper *t = 0;

// refer to instance, causing it to be instantiated (and
// initialized at startup on working compilers)
BOOST_ASSERT(! is_destroyed());

// note that the following is absolutely essential.
// Without this, compilers/linkers will strip out "dead code"
// as it looks like it is never referred to. But it is.
// commenting out this statement will cause compilers to fail to
// construct the instance at pre-execution time. This would prevent
// our usage/implementation of "locking" and introduce uncertainty into
// the sequence of object initializaition.
use(& m_instance);
return static_cast<T &>(t);

if (!t)
t = new singleton_wrapper;
return static_cast<T &>(*t);
}
static bool & get_is_destroyed(){
static bool is_destroyed;
return is_destroyed;
}

public:
static T & get_mutable_instance(){
BOOST_DLLEXPORT static T & get_mutable_instance(){
BOOST_ASSERT(! is_locked());
return get_instance();
}
static const T & get_const_instance(){
BOOST_DLLEXPORT static const T & get_const_instance(){
return get_instance();
}
static bool is_destroyed(){
BOOST_DLLEXPORT static bool is_destroyed(){
return get_is_destroyed();
}
singleton(){
BOOST_DLLEXPORT singleton(){
get_is_destroyed() = false;
unlock();
}
~singleton() {
BOOST_DLLEXPORT ~singleton() {
if (!get_is_destroyed()) {
delete &(get_instance());
}
get_is_destroyed() = true;
}
};
Expand Down
16 changes: 9 additions & 7 deletions test/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -30,31 +30,33 @@ import ../util/test :

BOOST_ARCHIVE_LIST = [ modules.peek : BOOST_ARCHIVE_LIST ] ;

lib dll_a_lib
lib dll_a
:
dll_a.cpp
../build//boost_serialization
:
;

lib dll_base_lib
lib dll_base
:
dll_base.cpp
../build//boost_serialization
:
;

lib dll_derived2_lib
lib dll_derived2
:
dll_derived2.cpp
dll_base_lib
dll_base
../build//boost_serialization
:
;

lib polymorphic_derived2
:
polymorphic_derived2.cpp
polymorphic_derived2.cpp
polymorphic_base.cpp
../build//boost_serialization
:
;

Expand Down Expand Up @@ -140,9 +142,9 @@ if ! $(BOOST_ARCHIVE_LIST) {
# the application is. On some platforms (e.g windows) this is required to avoid
# problems of linking incompatible versions of the runtime library. So
# we suppress tests of our dlls when using static libraries
[ test-bsl-run test_dll_exported : polymorphic_base : polymorphic_derived2 : <link>static:<build>no ]
[ test-bsl-run test_dll_exported : : polymorphic_derived2 : <link>static:<build>no ]
# [ test-bsl-run test_dll_plugin : : polymorphic_derived2 : <link>static:<build>no <target-os>linux:<linkflags>-ldl ]
[ test-bsl-run test_dll_simple : : dll_a_lib : <link>static:<build>no ]
[ test-bsl-run test_dll_simple : : dll_a : <link>static:<build>no ]
[ test-bsl-run test_private_ctor ]
[ test-bsl-run test_reset_object_address : A ]
[ test-bsl-run test_void_cast ]
Expand Down

0 comments on commit 7d216b4

Please sign in to comment.