Ticket #9601: 0001-Added-new-method-for-loading-tracked-pointers-which-.patch

File 0001-Added-new-method-for-loading-tracked-pointers-which-.patch, 4.5 KB (added by Brandon Kohn, 9 years ago)

Proposed patch to resolve issue

  • include/boost/archive/detail/basic_pointer_iserializer.hpp

    From c6e3c3fe52da6819cc16d385c70ae03edbef0b32 Mon Sep 17 00:00:00 2001
    From: Brandon Kohn <blkohn@hotmail.com>
    Date: Wed, 22 Jan 2014 15:52:19 -0500
    Subject: [PATCH] Added new method for loading tracked pointers which updates
     cached ptrs before deserializing.
    
    ---
     .../archive/detail/basic_pointer_iserializer.hpp   |  7 +++
     include/boost/archive/detail/iserializer.hpp       | 58 +++++++++++++++++++++-
     src/basic_iarchive.cpp                             |  3 +-
     3 files changed, 66 insertions(+), 2 deletions(-)
    
    diff --git a/include/boost/archive/detail/basic_pointer_iserializer.hpp b/include/boost/archive/detail/basic_pointer_iserializer.hpp
    index 5decea2..bd4ff40 100644
    a b public:  
    5858        void * & x,
    5959        const unsigned int file_version
    6060    ) const = 0;
     61       
     62        virtual void load_object_ptr_tracked(
     63        basic_iarchive & ar,
     64        void * & x,
     65                void * & tx,
     66        const unsigned int file_version
     67    ) const = 0;
    6168};
    6269
    6370} // namespace detail
  • include/boost/archive/detail/iserializer.hpp

    diff --git a/include/boost/archive/detail/iserializer.hpp b/include/boost/archive/detail/iserializer.hpp
    index 62aac9d..21e52bc 100644
    a b private:  
    206206            iserializer<Archive, T>
    207207        >::get_const_instance();
    208208    }
    209     BOOST_DLLEXPORT virtual void load_object_ptr(
     209    BOOST_DLLEXPORT virtual void load_object_ptr(       
    210210        basic_iarchive & ar,
    211211        void * & x,
    212212        const unsigned int file_version
    213213    ) const BOOST_USED;
     214       
     215        BOOST_DLLEXPORT virtual void load_object_ptr_tracked(
     216        basic_iarchive & ar,
     217        void * & x,
     218                void * & tx,
     219        const unsigned int file_version
     220    ) const BOOST_USED;
    214221protected:
    215222    // this should alway be a singleton so make the constructor protected
    216223    pointer_iserializer();
    BOOST_DLLEXPORT void pointer_iserializer<Archive, T>::load_object_ptr(  
    428435    h.release();
    429436}
    430437
     438// note: BOOST_DLLEXPORT is so that code for polymorphic class
     439// serialized only through base class won't get optimized out
     440template<class Archive, class T>
     441BOOST_DLLEXPORT void pointer_iserializer<Archive, T>::load_object_ptr_tracked(
     442    basic_iarchive & ar,
     443    void * & t,
     444        void * & tx,
     445    const unsigned int file_version
     446) const
     447{
     448    Archive & ar_impl =
     449        boost::serialization::smart_cast_reference<Archive &>(ar);
     450
     451    heap_allocation<T> h;
     452    t = NULL;
     453    // note that the above will throw std::bad_alloc if the allocation
     454    // fails so we don't have to address this contingency here.
     455
     456    // catch exception during load_construct_data so that we don't
     457    // automatically delete the t which is most likely not fully
     458    // constructed
     459    BOOST_TRY {
     460        // this addresses an obscure situation that occurs when
     461        // load_constructor de-serializes something through a pointer.
     462        ar.next_object_pointer(h.get());
     463        boost::serialization::load_construct_data_adl<Archive, T>(
     464            ar_impl,
     465            h.get(),
     466            file_version
     467        );
     468               
     469                //! Update the value of the stored pointer so cycles can use it.
     470                tx = h.get();//Assign to the tracker the newly constructed value.
     471    }
     472    BOOST_CATCH(...){
     473        // if we get here the load_construct failed.  The heap_allocation
     474        // will be automatically deleted so we don't have to do anything
     475        // special here.
     476        BOOST_RETHROW;
     477    }
     478    BOOST_CATCH_END
     479
     480    ar_impl >> boost::serialization::make_nvp(NULL, *h.get());
     481    // success !!! - release the heap allocation so it
     482    // doesn't delete the object we just loaded.
     483    t = h.get();
     484    h.release();
     485}
     486
    431487template<class Archive, class T>
    432488pointer_iserializer<Archive, T>::pointer_iserializer() :
    433489    basic_pointer_iserializer(
  • src/basic_iarchive.cpp

    diff --git a/src/basic_iarchive.cpp b/src/basic_iarchive.cpp
    index 6be5d9d..a066514 100644
    a b basic_iarchive_impl::load_pointer(  
    518518
    519519        // remember that that the address of these elements could change
    520520        // when we make another call so don't use the address
    521         bpis_ptr->load_object_ptr(
     521        bpis_ptr->load_object_ptr_tracked(
    522522            ar,
    523523            t,
     524                        object_id_vector[ui].address,
    524525            m_pending.version
    525526        );
    526527        BOOST_ASSERT(NULL != t);