From be4738f59c342879bd819966afa9248ac23cd69c Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 10 Jun 2013 14:48:59 -0400 Subject: [PATCH] remove weak_vector It seems that shared_ptr::use_count() does not include weak_ptr instances. Therefore shared_ptr::use_count()==1 (aka unique()) does *not* ensure exclusive ownership! This breaks the assumption used by shared_vector::make_unique() to avoid allocating a new array in some cases. --- pvDataApp/misc/sharedVector.h | 54 ++++--------------------------- testApp/misc/testSharedVector.cpp | 28 +++++++++++++++- 2 files changed, 34 insertions(+), 48 deletions(-) diff --git a/pvDataApp/misc/sharedVector.h b/pvDataApp/misc/sharedVector.h index 895e325..9bb50a2 100644 --- a/pvDataApp/misc/sharedVector.h +++ b/pvDataApp/misc/sharedVector.h @@ -232,6 +232,13 @@ namespace detail { * std::vector are outlined in @ref vectordiff . * * Also see @ref vectormem + * + * @warning Due to the implementation of std::tr1::shared_ptr, use of + * shared_vector should not be combined with use of weak_ptr. + * shared_ptr::unique() and shared_ptr::use_count() do @b not + * include weak_ptr instances. This breaks the assumption made + * by make_unique() that unique()==true implies exclusive + * ownership. */ template class shared_vector : public detail::shared_vector_base @@ -527,53 +534,6 @@ public: } }; -template -class weak_vector { - std::tr1::weak_ptr m_data; - //! Offset in the data array of first element - size_t m_offset; - //! Number of elements between m_offset and end of data - size_t m_count; - -public: - typedef E element_type; - - weak_vector() - :m_data() - ,m_offset(0) - ,m_count(0) - {} - weak_vector(const weak_vector& o) - :m_data(o.m_data) - ,m_offset(o.m_offset) - ,m_count(o.m_count) - {} - weak_vector(const shared_vector& o) - :m_data(o.dataPtr()) - ,m_offset(o.dataOffset()) - ,m_count(o.dataCount()) - {} - - bool expired() const{return m_data.expired();} - shared_vector lock() const - { - return shared_vector(m_data.lock(), m_offset, m_count); - } - - void reset() - { - m_data.reset(); - m_offset = m_count = 0; - } - - void swap(weak_vector& o) - { - m_data.swap(o); - std::swap(m_offset, o.m_offset); - std::swap(m_count, o.m_count); - } -}; - namespace detail { template struct shared_vector_caster {}; diff --git a/testApp/misc/testSharedVector.cpp b/testApp/misc/testSharedVector.cpp index 638c562..685b8f9 100644 --- a/testApp/misc/testSharedVector.cpp +++ b/testApp/misc/testSharedVector.cpp @@ -382,9 +382,34 @@ static void testNonPOD() testOk1(structs2[1].get()==temp); } +static void testWeak() +{ + testDiag("Test weak_ptr counting"); + + epics::pvData::shared_vector data(6); + + testOk1(data.unique()); + + std::tr1::shared_ptr pdata(data.dataPtr()); + + testOk1(!data.unique()); + + pdata.reset(); + + testOk1(data.unique()); + + std::tr1::weak_ptr wdata(data.dataPtr()); + + testOk1(data.unique()); // True, but I wish it wasn't!!! + + pdata = wdata.lock(); + + testOk1(!data.unique()); +} + MAIN(testSharedVector) { - testPlan(116); + testPlan(121); testDiag("Tests for shared_vector"); testDiag("sizeof(shared_vector)=%lu", @@ -399,5 +424,6 @@ MAIN(testSharedVector) testSlice(); testVoid(); testNonPOD(); + testWeak(); return testDone(); }