Fix leak in NasalObjectHolder

Thanks to Florent Rougon for spotting it.
This commit is contained in:
Thomas Geymayer 2017-11-12 22:39:26 +01:00
parent fed449a801
commit bd87d3963a
4 changed files with 59 additions and 4 deletions

View File

@ -787,6 +787,11 @@ void naGCRelease(int key)
naHash_delete(globals->save_hash, naNum(key));
}
int naNumSaved()
{
return naHash_size(globals->save_hash) + naVec_size(globals->save_hash);
}
void naClearSaved()
{
naContext c;

View File

@ -139,10 +139,9 @@ namespace nasal
template<class Base>
ObjectHolder<Base>::ObjectHolder(naRef obj):
_ref(obj),
_gc_key(0)
_gc_key(naIsNil(obj) ? 0 : naGCSave(obj))
{
if( !naIsNil(obj) )
naGCSave(obj);
}
//----------------------------------------------------------------------------
@ -159,7 +158,7 @@ namespace nasal
SGSharedPtr<ObjectHolder<Base> >
ObjectHolder<Base>::makeShared(naRef obj)
{
return SGSharedPtr<ObjectHolder<Base> >( new ObjectHolder<SGReferenced>(obj) );
return SGSharedPtr<ObjectHolder<Base> >( new ObjectHolder<Base>(obj) );
}
} // namespace nasal

View File

@ -2,6 +2,9 @@
#include <BoostTestTargetConfig.h>
#include "TestContext.hxx"
#include <simgear/nasal/cppbind/NasalObjectHolder.hxx>
#include <iostream>
#include <set>
@ -91,3 +94,47 @@ BOOST_AUTO_TEST_CASE( ghost_gc )
BOOST_REQUIRE(active_instances.empty());
}
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( object_holder_gc )
{
TestContext c;
BOOST_REQUIRE_EQUAL(naNumSaved(), 0);
BOOST_REQUIRE(active_instances.empty());
//-----------------------------------------------
// Put some ghosts in ObjectHolder and check if
// they are saved from gc
naRef g1 = createTestGhost(c, 1),
g2 = createTestGhost(c, 2);
nasal::ObjectHolder<> h1(g1);
BOOST_CHECK_EQUAL(naNumSaved(), 1);
BOOST_CHECK(naIsGhost(h1.get_naRef()));
nasal::ObjectHolder<> h2(g2);
BOOST_CHECK_EQUAL(naNumSaved(), 2);
BOOST_CHECK(naIsGhost(h2.get_naRef()));
c.runGC();
BOOST_CHECK_EQUAL(active_instances.size(), 2);
BOOST_CHECK_EQUAL(naNumSaved(), 2);
h1.reset(naNum(1));
h2.reset(naNum(2));
BOOST_CHECK_EQUAL(naNumSaved(), 2);
//-----------------------------------------------
// Check that the saved objects are released
h1.reset();
BOOST_CHECK_EQUAL(naNumSaved(), 1);
h2.reset();
BOOST_CHECK_EQUAL(naNumSaved(), 0);
c.runGC();
BOOST_CHECK_EQUAL(active_instances.size(), 0);
}

View File

@ -58,6 +58,10 @@ int naGCSave(naRef obj);
// by the garbage collector.
void naGCRelease(int key);
// Get the number of currently saved and not yet again released objects
// (saved by naSave or naGCSave)
int naNumSaved();
// Drop all saved references
void naClearSaved();