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
|
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_;
|
||||||
new_weak_count = --weak_count_;
|
|
||||||
|
if(new_use_count != 0)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user