Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r58258 - in trunk/libs/serialization: src test
From: ramey_at_[hidden]
Date: 2009-12-09 19:30:53


Author: ramey
Date: 2009-12-09 19:30:51 EST (Wed, 09 Dec 2009)
New Revision: 58258
URL: http://svn.boost.org/trac/boost/changeset/58258

Log:
1. Fixed memory leak in shared_ptr loading
2. Fixed error in polymorphic archive implementation
Text files modified:
   trunk/libs/serialization/src/basic_iarchive.cpp | 28 +++++++++----
   trunk/libs/serialization/src/extended_type_info.cpp | 7 +++
   trunk/libs/serialization/src/extended_type_info_typeid.cpp | 10 +++-
   trunk/libs/serialization/src/shared_ptr_helper.cpp | 32 ++++++++++-----
   trunk/libs/serialization/test/Jamfile.v2 | 1
   trunk/libs/serialization/test/test_shared_ptr.cpp | 77 +++++++++++++++++++++++----------------
   trunk/libs/serialization/test/test_shared_ptr_multi_base.cpp | 53 +++++++++++++++++++++------
   7 files changed, 141 insertions(+), 67 deletions(-)

Modified: trunk/libs/serialization/src/basic_iarchive.cpp
==============================================================================
--- trunk/libs/serialization/src/basic_iarchive.cpp (original)
+++ trunk/libs/serialization/src/basic_iarchive.cpp 2009-12-09 19:30:51 EST (Wed, 09 Dec 2009)
@@ -51,7 +51,6 @@
     friend class basic_iarchive;
     version_type m_archive_library_version;
     unsigned int m_flags;
- const basic_iarchive * m_this;
 
     //////////////////////////////////////////////////////////////////////
     // information about each serialized object loaded
@@ -162,10 +161,9 @@
     const basic_iserializer * pending_bis;
     version_type pending_version;
 
- basic_iarchive_impl(const basic_iarchive * parent, unsigned int flags) :
+ basic_iarchive_impl(unsigned int flags) :
         m_archive_library_version(BOOST_ARCHIVE_VERSION()),
         m_flags(flags),
- m_this(parent),
         moveable_objects_start(0),
         moveable_objects_end(0),
         moveable_objects_recent(0),
@@ -214,7 +212,11 @@
     const basic_pointer_iserializer * load_pointer(
         basic_iarchive & ar,
         void * & t,
- const basic_pointer_iserializer * bpis
+ const basic_pointer_iserializer * bpis,
+ const basic_pointer_iserializer * (*finder)(
+ const boost::serialization::extended_type_info & type
+ )
+
     );
 };
 
@@ -402,7 +404,11 @@
 basic_iarchive_impl::load_pointer(
     basic_iarchive &ar,
     void * & t,
- const basic_pointer_iserializer * bpis_ptr
+ const basic_pointer_iserializer * bpis_ptr,
+ const basic_pointer_iserializer * (*finder)(
+ const boost::serialization::extended_type_info & type_
+ )
+
 ){
     class_id_type cid;
     load(ar, cid);
@@ -435,7 +441,7 @@
                 boost::serialization::throw_exception(
                     archive_exception(archive_exception::unregistered_class)
                 );
- bpis_ptr = m_this->find(*eti);
+ bpis_ptr = (*finder)(*eti);
         }
         assert(NULL != bpis_ptr);
         class_id_type new_cid = register_type(bpis_ptr->get_basic_serializer());
@@ -511,7 +517,7 @@
 
 BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
 basic_iarchive::basic_iarchive(unsigned int flags) :
- pimpl(new basic_iarchive_impl(this, flags))
+ pimpl(new basic_iarchive_impl(flags))
 {}
 
 BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
@@ -545,9 +551,13 @@
 BOOST_ARCHIVE_DECL(const basic_pointer_iserializer *)
 basic_iarchive::load_pointer(
     void * &t,
- const basic_pointer_iserializer * bpis_ptr
+ const basic_pointer_iserializer * bpis_ptr,
+ const basic_pointer_iserializer * (*finder)(
+ const boost::serialization::extended_type_info & type_
+ )
+
 ){
- return pimpl->load_pointer(*this, t, bpis_ptr);
+ return pimpl->load_pointer(*this, t, bpis_ptr, finder);
 }
 
 BOOST_ARCHIVE_DECL(void)

Modified: trunk/libs/serialization/src/extended_type_info.cpp
==============================================================================
--- trunk/libs/serialization/src/extended_type_info.cpp (original)
+++ trunk/libs/serialization/src/extended_type_info.cpp 2009-12-09 19:30:51 EST (Wed, 09 Dec 2009)
@@ -88,6 +88,13 @@
     virtual const char * get_debug_info() const {
         return get_key();
     }
+ virtual void * construct(unsigned int /*count*/, ...) const{
+ assert(false);
+ return NULL;
+ }
+ virtual void destroy(void const * const /*p*/) const {
+ assert(false);
+ }
 public:
     extended_type_info_arg(const char * key) :
         extended_type_info(0, key)

Modified: trunk/libs/serialization/src/extended_type_info_typeid.cpp
==============================================================================
--- trunk/libs/serialization/src/extended_type_info_typeid.cpp (original)
+++ trunk/libs/serialization/src/extended_type_info_typeid.cpp 2009-12-09 19:30:51 EST (Wed, 09 Dec 2009)
@@ -60,9 +60,6 @@
 extended_type_info_typeid_0::is_equal(
     const boost::serialization::extended_type_info & rhs
 ) const {
- // shortcut for common case
- if(this == & rhs)
- return true;
     return
         // note: std::type_info == operator returns an int !!!
         // the following permits conversion to bool without a warning.
@@ -122,6 +119,13 @@
 class extended_type_info_typeid_arg :
     public extended_type_info_typeid_0
 {
+ virtual void * construct(unsigned int /*count*/, ...) const{
+ assert(false);
+ return NULL;
+ }
+ virtual void destroy(void const * const /*p*/) const {
+ assert(false);
+ }
 public:
     extended_type_info_typeid_arg(const std::type_info & ti) :
         extended_type_info_typeid_0(NULL)

Modified: trunk/libs/serialization/src/shared_ptr_helper.cpp
==============================================================================
--- trunk/libs/serialization/src/shared_ptr_helper.cpp (original)
+++ trunk/libs/serialization/src/shared_ptr_helper.cpp 2009-12-09 19:30:51 EST (Wed, 09 Dec 2009)
@@ -35,18 +35,18 @@
 
 // returns pointer to object and an indicator whether this is a
 // new entry (true) or a previous one (false)
-BOOST_ARCHIVE_DECL(shared_ptr_helper::result_type)
+BOOST_ARCHIVE_DECL(shared_ptr<void>)
 shared_ptr_helper::get_od(
- void * od,
+ const void * t,
         const boost::serialization::extended_type_info * true_type,
         const boost::serialization::extended_type_info * this_type
 ){
     // get void pointer to the most derived type
     // this uniquely identifies the object referred to
- od = void_downcast(
+ const void * od = void_downcast(
         *true_type,
         *this_type,
- od
+ t
     );
     if(NULL == od)
         boost::serialization::throw_exception(
@@ -61,15 +61,21 @@
     if(NULL == m_pointers)
         m_pointers = new collection_type;
 
- shared_ptr<const void> sp(od, null_deleter());
- std::pair<collection_type::iterator, bool> result =
- m_pointers->insert(
- collection_type::value_type(od, sp)
- );
+ //shared_ptr<const void> sp(od, null_deleter());
+ shared_ptr<const void> sp(od, null_deleter());
+ collection_type::iterator i = m_pointers->find(sp);
+
+ if(i == m_pointers->end()){
+ std::pair<collection_type::iterator, bool> result;
+ shared_ptr<const void> sp(const_cast<void * >(od), void_deleter(true_type));
+ result = m_pointers->insert(sp);
+ assert(result.second);
+ i = result.first;
+ }
     od = void_upcast(
         *true_type,
         *this_type,
- result.first->first
+ i->get()
     );
     if(NULL == od)
         boost::serialization::throw_exception(
@@ -79,7 +85,11 @@
                 this_type->get_debug_info()
             )
         );
- return result_type(result.first, od);
+
+ return shared_ptr<void>(
+ const_pointer_cast<void>(*i),
+ const_cast<void *>(od)
+ );
 }
 
 // #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP

Modified: trunk/libs/serialization/test/Jamfile.v2
==============================================================================
--- trunk/libs/serialization/test/Jamfile.v2 (original)
+++ trunk/libs/serialization/test/Jamfile.v2 2009-12-09 19:30:51 EST (Wed, 09 Dec 2009)
@@ -106,6 +106,7 @@
      [ test-bsl-run_files test_shared_ptr_multi_base ]
      [ test-bsl-run_files test_shared_ptr_132 ]
      [ test-bsl-run_polymorphic_archive test_polymorphic : test_polymorphic_A A ]
+ [ test-bsl-run_polymorphic_archive test_polymorphic2 : test_polymorphic2imp ]
     ;
 
 if ! $(BOOST_ARCHIVE_LIST) {

Modified: trunk/libs/serialization/test/test_shared_ptr.cpp
==============================================================================
--- trunk/libs/serialization/test/test_shared_ptr.cpp (original)
+++ trunk/libs/serialization/test/test_shared_ptr.cpp 2009-12-09 19:30:51 EST (Wed, 09 Dec 2009)
@@ -38,6 +38,8 @@
     void serialize(Archive & ar, const unsigned int /* file_version */){
         ar & BOOST_SERIALIZATION_NVP(x);
     }
+ A(A const & rhs);
+ A& operator=(A const & rhs);
 public:
     static int count;
     bool operator==(const A & rhs) const {
@@ -250,39 +252,50 @@
 // This does the tests
 int test_main(int /* argc */, char * /* argv */[])
 {
- // These are our shared_ptrs
- boost::shared_ptr<A> spa;
-
- // trivial test 1
- save_and_load(spa);
+ {
+ boost::shared_ptr<A> spa;
+ // These are our shared_ptrs
+ spa = boost::shared_ptr<A>(new A);
+ boost::shared_ptr<A> spa1 = spa;
+ spa1 = spa;
+ }
+ {
+ // These are our shared_ptrs
+ boost::shared_ptr<A> spa;
 
- //trivival test 2
- spa = boost::shared_ptr<A>(new A);
- save_and_load(spa);
-
- // Try to save and load pointers to As
- spa = boost::shared_ptr<A>(new A);
- boost::shared_ptr<A> spa1 = spa;
- save_and_load2(spa, spa1);
-
- // test a weak pointer
- spa = boost::shared_ptr<A>(new A);
- spa1 = spa;
- boost::weak_ptr<A> wp = spa;
- save_and_load3(spa, spa1, wp);
+ // trivial test 1
+ save_and_load(spa);
     
- // Try to save and load pointers to Bs
- spa = boost::shared_ptr<A>(new B);
- spa1 = spa;
- save_and_load2(spa, spa1);
-
- // obj of type B gets destroyed
- // as smart_ptr goes out of scope
-
- // Try to save and load pointers to Bs
- boost::shared_ptr<C> spc;
- spc = boost::shared_ptr<C>(new C);
- save_and_load4(spc);
-
+ //trivival test 2
+ spa = boost::shared_ptr<A>(new A);
+ save_and_load(spa);
+
+ // Try to save and load pointers to As
+ spa = boost::shared_ptr<A>(new A);
+ boost::shared_ptr<A> spa1 = spa;
+ save_and_load2(spa, spa1);
+
+ // Try to save and load pointers to Bs
+ spa = boost::shared_ptr<A>(new B);
+ spa1 = spa;
+ save_and_load2(spa, spa1);
+
+ // test a weak pointer
+ spa = boost::shared_ptr<A>(new A);
+ spa1 = spa;
+ boost::weak_ptr<A> wp = spa;
+ save_and_load3(spa, spa1, wp);
+
+ // obj of type B gets destroyed
+ // as smart_ptr goes out of scope
+ }
+ BOOST_CHECK(A::count == 0);
+ {
+ // Try to save and load pointers to Cs
+ boost::shared_ptr<C> spc;
+ spc = boost::shared_ptr<C>(new C);
+ save_and_load4(spc);
+ }
+ BOOST_CHECK(C::count == 0);
     return EXIT_SUCCESS;
 }

Modified: trunk/libs/serialization/test/test_shared_ptr_multi_base.cpp
==============================================================================
--- trunk/libs/serialization/test/test_shared_ptr_multi_base.cpp (original)
+++ trunk/libs/serialization/test/test_shared_ptr_multi_base.cpp 2009-12-09 19:30:51 EST (Wed, 09 Dec 2009)
@@ -30,7 +30,8 @@
 struct Base1 {
     Base1() {}
     Base1(int x) : m_x(1 + x) {}
- virtual ~Base1() {}
+ virtual ~Base1(){
+ }
     int m_x;
     // serialize
     friend class boost::serialization::access;
@@ -41,13 +42,12 @@
     }
 };
 
-BOOST_SERIALIZATION_SHARED_PTR(Base1)
-
 struct Base2 {
     Base2() {}
     Base2(int x) : m_x(2 + x) {}
     int m_x;
- virtual ~Base2() {}
+ virtual ~Base2(){
+ }
     // serialize
     friend class boost::serialization::access;
     template<class Archive>
@@ -57,12 +57,11 @@
     }
 };
 
-BOOST_SERIALIZATION_SHARED_PTR(Base2)
-
 struct Base3 {
     Base3() {}
     Base3(int x) : m_x(3 + x) {}
- virtual ~Base3() {}
+ virtual ~Base3(){
+ }
     int m_x;
     // serialize
     friend class boost::serialization::access;
@@ -73,17 +72,28 @@
     }
 };
 
-BOOST_SERIALIZATION_SHARED_PTR(Base3)
-
 // Sub is a subclass of Base1, Base1 and Base3.
 struct Sub:public Base1, public Base2, public Base3 {
- Sub() {}
+ static int count;
+ Sub() {
+ ++count;
+ }
     Sub(int x) :
         Base1(x),
         Base2(x),
         m_x(x)
- {}
- virtual ~Sub() {}
+ {
+ ++count;
+ }
+ Sub(const Sub & rhs) :
+ m_x(rhs.m_x)
+ {
+ ++count;
+ }
+ virtual ~Sub() {
+ assert(0 < count);
+ --count;
+ }
     int m_x;
     // serialize
     friend class boost::serialization::access;
@@ -101,6 +111,8 @@
 BOOST_CLASS_EXPORT(Sub)
 BOOST_SERIALIZATION_SHARED_PTR(Sub)
 
+int Sub::count = 0;
+
 template <class FIRST, class SECOND>
 void save2(
     const char * testfile,
@@ -155,6 +167,7 @@
     // Check pointer to vtable
     BOOST_CHECK(boost::dynamic_pointer_cast<Sub>(first));
     BOOST_CHECK(boost::dynamic_pointer_cast<Sub>(second.lock()));
+
     std::remove(testfile);
 }
 
@@ -184,35 +197,45 @@
     // Check pointer to vtable
     BOOST_CHECK(boost::dynamic_pointer_cast<Sub>(first.lock()));
     BOOST_CHECK(boost::dynamic_pointer_cast<Sub>(second));
+
     std::remove(testfile);
 }
 
 // This does the tests
 int test_main(int /* argc */, char * /* argv */[])
 {
+
     // Both Sub
     boost::shared_ptr<Sub> tc1_sp(new Sub(10));
     boost::weak_ptr<Sub> tc1_wp(tc1_sp);
     shared_weak(tc1_sp, tc1_wp);
     weak_shared(tc1_wp, tc1_sp);
+ tc1_sp.reset();
+ BOOST_CHECK(0 == Sub::count);
 
     // Sub and Base1
     boost::shared_ptr<Sub> tc2_sp(new Sub(10));
     boost::weak_ptr<Base1> tc2_wp(tc2_sp);
     shared_weak(tc2_sp, tc2_wp);
     weak_shared(tc2_wp, tc2_sp);
+ tc2_sp.reset();
+ BOOST_CHECK(0 == Sub::count);
 
     // Sub and Base2
     boost::shared_ptr<Sub> tc3_sp(new Sub(10));
     boost::weak_ptr<Base2> tc3_wp(tc3_sp);
     shared_weak(tc3_sp, tc3_wp);
     weak_shared(tc3_wp, tc3_sp);
+ tc3_sp.reset();
+ BOOST_CHECK(0 == Sub::count);
 
     // Sub and Base3
     boost::shared_ptr<Sub> tc4_sp(new Sub(10));
     boost::weak_ptr<Base3> tc4_wp(tc4_sp);
     shared_weak(tc4_sp, tc4_wp);
     weak_shared(tc4_wp, tc4_sp);
+ tc4_sp.reset();
+ BOOST_CHECK(0 == Sub::count);
 
     // Base1 and Base2
     boost::shared_ptr<Sub> tc5_sp_tmp(new Sub(10));
@@ -221,6 +244,8 @@
     tc5_sp_tmp.reset();
     shared_weak(tc5_sp, tc5_wp);
     weak_shared(tc5_wp, tc5_sp);
+ tc5_sp.reset();
+ BOOST_CHECK(0 == Sub::count);
 
     // Base2 and Base3
     boost::shared_ptr<Sub> tc6_sp_tmp(new Sub(10));
@@ -229,6 +254,8 @@
     tc6_sp_tmp.reset();
     shared_weak(tc6_sp, tc6_wp);
     weak_shared(tc6_wp, tc6_sp);
+ tc6_sp.reset();
+ BOOST_CHECK(0 == Sub::count);
 
     // Base3 and Base1
     boost::shared_ptr<Sub> tc7_sp_tmp(new Sub(10));
@@ -237,6 +264,8 @@
     tc7_sp_tmp.reset();
     shared_weak(tc7_sp, tc7_wp);
     weak_shared(tc7_wp, tc7_sp);
+ tc7_sp.reset();
+ BOOST_CHECK(0 == Sub::count);
 
     return EXIT_SUCCESS;
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk