forked from boostorg/smart_ptr
Fixed a subtle problem in counted_base::release (report and test case by Per Kristensen)
[SVN r16211]
This commit is contained in:
@ -120,19 +120,28 @@ public:
|
||||
void release() // nothrow
|
||||
{
|
||||
long new_use_count;
|
||||
long new_weak_count;
|
||||
long new_weak_count = 0;
|
||||
|
||||
{
|
||||
#ifdef BOOST_HAS_THREADS
|
||||
mutex_type::scoped_lock lock(mtx_);
|
||||
#endif
|
||||
new_use_count = --use_count_;
|
||||
new_weak_count = --weak_count_;
|
||||
|
||||
if(new_use_count != 0)
|
||||
{
|
||||
new_weak_count = --weak_count_;
|
||||
}
|
||||
}
|
||||
|
||||
if(new_use_count == 0)
|
||||
{
|
||||
dispose();
|
||||
|
||||
#ifdef BOOST_HAS_THREADS
|
||||
mutex_type::scoped_lock lock(mtx_);
|
||||
#endif
|
||||
new_weak_count = --weak_count_;
|
||||
}
|
||||
|
||||
if(new_weak_count == 0)
|
||||
|
@ -196,6 +196,45 @@ template<class T> void test_is_nonzero(boost::shared_ptr<T> const & p)
|
||||
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()
|
||||
{
|
||||
using namespace boost;
|
||||
@ -368,5 +407,12 @@ int main()
|
||||
|
||||
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();
|
||||
}
|
||||
|
Reference in New Issue
Block a user