Fix shared_ptr of classes with private constructors and destructors.

Usually these use a custom deleter passed to the shared_ptr.
This also fixes the "unref" feature when used on classes with private destructors.
This commit is contained in:
William S Fulton 2015-05-14 18:38:32 +01:00
parent e796ecaa23
commit 54e2317b24
5 changed files with 53 additions and 0 deletions

View File

@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 3.0.6 (in progress)
===========================
2015-05-14: wsfulton
Fix seg fault wrapping shared_ptr of classes with private constructors and destructors.
This also fixes the "unref" feature when used on classes with private destructors.
2015-05-10: wsfulton
[Java] Fix multi-argument typemaps (char *STRING, size_t LENGTH)
so that they can be applied to a wider range of types. Fixes #385.

View File

@ -16,5 +16,12 @@ public class runme
HiddenDestructor hidden = HiddenDestructor.create();
hidden.Dispose();
HiddenPrivateDestructor hiddenPrivate = HiddenPrivateDestructor.create();
if (HiddenPrivateDestructor.DeleteCount != 0)
throw new ApplicationException("Count should be zero");
hiddenPrivate.Dispose();
if (HiddenPrivateDestructor.DeleteCount != 1)
throw new ApplicationException("Count should be one");
}
}

View File

@ -23,5 +23,12 @@ public class li_boost_shared_ptr_bits_runme {
HiddenDestructor hidden = HiddenDestructor.create();
hidden.delete();
HiddenPrivateDestructor hiddenPrivate = HiddenPrivateDestructor.create();
if (HiddenPrivateDestructor.getDeleteCount() != 0)
throw new RuntimeException("Count should be zero");
hiddenPrivate.delete();
if (HiddenPrivateDestructor.getDeleteCount() != 1)
throw new RuntimeException("Count should be one");
}
}

View File

@ -128,5 +128,36 @@ HiddenDestructor::~HiddenDestructor()
delete impl_;
}
%}
////////////////////////////
// As above but private instead of protected destructor
////////////////////////////
%shared_ptr(HiddenPrivateDestructor)
%inline %{
class HiddenPrivateDestructor {
private:
HiddenPrivateDestructor() {}
virtual ~HiddenPrivateDestructor() {
DeleteCount++;
}
class Deleter {
public:
void operator()(HiddenPrivateDestructor *hidden) {
delete hidden;
}
};
public:
static boost::shared_ptr<HiddenPrivateDestructor> create() {
boost::shared_ptr<HiddenPrivateDestructor> hidden( new HiddenPrivateDestructor(), HiddenPrivateDestructor::Deleter() );
return hidden;
}
static int DeleteCount;
};
int HiddenPrivateDestructor::DeleteCount = 0;
%}

View File

@ -371,6 +371,10 @@ static void add_symbols(Node *n) {
if ((Cmp(Getattr(n,"storage"),"virtual") == 0) && (Cmp(Getattr(n,"value"),"0") == 0)) {
only_csymbol = 0;
}
if (Cmp(nodeType(n),"destructor") == 0) {
/* Needed for "unref" feature */
only_csymbol = 0;
}
}
} else {
Setattr(n,"access", "public");