[C++-sig] Bug and patch for boost.python with enable_shared_from_this
Ralf W. Grosse-Kunstleve
rwgk at yahoo.com
Wed Feb 13 21:27:13 CET 2008
Hi Chad,
Could you at least ask Peter Dimov if he thinks the
dont_enable_shared_from_this patch could be generally useful?
Maybe he's OK adding it, then it wouldn't be a big deal
fixing Boost.Python, which would probably prevent a lot of
confusion and lost time in the future.
http://www.boost.org/people/peter_dimov.htm
p-d-i-m-o-v-at-m-m-l-t-d-dot-n-e-t
Ralf
----- Original Message ----
From: Chad Austin <chad at imvu.com>
To: Development of Python/C++ integration <c++-sig at python.org>
Sent: Monday, February 11, 2008 10:10:31 PM
Subject: Re: [C++-sig] Bug and patch for boost.python with enable_shared_from_this
There probably is a way to prevent boost.python from creating
shared_ptrs with a null deleter like it does, but it would require far
more knowledge than I have. :)
I agree that it would be a better fix, though.
On 2/11/08, Ralf W. Grosse-Kunstleve <rwgk at yahoo.com> wrote:
>
>
>
> Thanks for the patch! I'd love to check this in for you, but for the
> change in shared_ptr.hpp you'll need Peter Dimov's approval, and the
> shared_ptr documentation would have to be updated. Also, your reproducer
> should be turned into a unit test (in boost/libs/python/test).
>
> Is there any chance that the shared_ptr patch could somehow be avoided?
>
> Ralf
>
>
>
> ----- Original Message ----
> From: Chad Austin <chad at imvu.com>
> To: c++-sig at python.org
> Sent: Sunday, February 10, 2008 5:14:45 PM
> Subject: [C++-sig] Bug and patch for boost.python with enable_shared_from_this
>
> Hi all,
>
> A month ago or so we discovered a bug in Boost.Python that manifests when using enable_shared_from_this. Here is a test case that demonstrates the bug:
>
>
> #include <boost/python.hpp>
> #include <boost/enable_shared_from_this.hpp>
>
> using namespace boost;
> using namespace boost::python;
>
> class Test;
> typedef shared_ptr<Test> TestPtr;
>
> class Test : public enable_shared_from_this<Test> {
> public:
> static TestPtr construct() {
> return TestPtr(new Test);
> }
>
> void act() {
> TestPtr kungFuDeathGrip(shared_from_this());
> }
>
> void take(TestPtr t) {
> }
> };
>
> void Export_test() {
> class_<Test, TestPtr, noncopyable>("Test")
> .def("construct", &Test::construct)
> .staticmethod("construct")
>
> .def("act", &Test::act)
> .def("take", &Test::take)
> ;
> }
>
> And here is the Python:
>
> x = Test.construct()
> x.take(x)
> x.act()
>
> The bug (as I understand it) is that the shared_ptr_from_python converter creates a new shared_ptr for the Test instance to pass it into C++. This new shared_ptr has a nop deleter, except that it keeps the Python object alive as long as the new shared_ptr is alive. The problem here is that creating a shared_ptr to an object of type T when T is enable_shared_from_this<T> resets the weak pointer inside of enable_shared_from_this<T>. (See shared_ptr's constructors for the details of the implementation.) A fix that passes the test above and has worked for us is to change shared_ptr's constructor to accept a dont_enable_shared_from_this argument and pass that in from the shared_ptr_from_python converter. The patch is attached (against boost 1.33, but the bug didn't look fixed in 1.34 either).
>
> Cheers,
> Chad
>
> p.s. I have seen other people with this problem as well. Googling for bad_weak_ptr turns up several results.
More information about the Cplusplus-sig
mailing list