Fixed a subtle problem in counted_base::release (report and test case by Per Kristensen)

[SVN r16211]
This commit is contained in:
Peter Dimov
2002-11-12 13:14:50 +00:00
parent 57c0ad44f3
commit ff7410cad2
2 changed files with 57 additions and 2 deletions

View File

@@ -120,19 +120,28 @@ public:
void release() // nothrow void release() // nothrow
{ {
long new_use_count; long new_use_count;
long new_weak_count; long new_weak_count = 0;
{ {
#ifdef BOOST_HAS_THREADS #ifdef BOOST_HAS_THREADS
mutex_type::scoped_lock lock(mtx_); mutex_type::scoped_lock lock(mtx_);
#endif #endif
new_use_count = --use_count_; new_use_count = --use_count_;
if(new_use_count != 0)
{
new_weak_count = --weak_count_; new_weak_count = --weak_count_;
} }
}
if(new_use_count == 0) if(new_use_count == 0)
{ {
dispose(); dispose();
#ifdef BOOST_HAS_THREADS
mutex_type::scoped_lock lock(mtx_);
#endif
new_weak_count = --weak_count_;
} }
if(new_weak_count == 0) if(new_weak_count == 0)

View File

@@ -196,6 +196,45 @@ template<class T> void test_is_nonzero(boost::shared_ptr<T> const & p)
BOOST_TEST(p.get() != 0); BOOST_TEST(p.get() != 0);
} }
class foo
{
public:
void setWeak(boost::shared_ptr<foo> s)
{
w = s;
}
private:
boost::weak_ptr<foo> w;
};
class deleter
{
public:
deleter(): lock(0)
{
}
~deleter()
{
BOOST_TEST(lock == 0);
}
void operator() (foo * p)
{
++lock;
delete p;
--lock;
}
private:
int lock;
};
int main() int main()
{ {
using namespace boost; using namespace boost;
@@ -368,5 +407,12 @@ int main()
BOOST_TEST(cnt == 0); BOOST_TEST(cnt == 0);
// Test case by Per Kristensen
{
boost::shared_ptr<foo> s(new foo, deleter());
s->setWeak(s);
s.reset();
}
return boost::report_errors(); return boost::report_errors();
} }