YetAnotherForum
Welcome Guest Search | Active Topics | Log In | Register

Using sq_release in a sq_setreleasehook release hook
ianfernsby
#1 Posted : Monday, August 24, 2015 9:46:23 AM(UTC)
Rank: Newbie

Groups: Registered
Joined: 3/8/2014(UTC)
Posts: 4

Thanks: 0 times
Was thanked: 0 time(s) in 0 post(s)
I have a number of classes that support events like this:

my_instance.on_event = function(event_source, event) { ... }

The events are generated from C++, and as such the C++ code needs to keep a reference to the on_event closure (using sq_getstackobj and sq_addref) as well as a reference to "my_instance".

When sq_close is called, I use a release hook (set by sq_setreleasehook) to try to tear the reference to the closure and instance down. The problem is, by the time release hooks are called, in some cases the SQSharedState::_root_vm is already deleted:

SQSharedState::~SQSharedState()
{
...
_root_vm.Null();
...
_refs_table.Finalize();

This happens when the final reference to "my_instance" is in the refs (sq_addref) table.

One of the reasons this shows up for me is that the event "sources" in C++ often outlive the life of the Squirrel engine; the release hooks are thus partly to disconnect the engine and make sure it doesn't call into a deleted engine.

Working around it would involve:

1) Move the _refs_table finalization earlier, which *seems* harmless to me because it is only really used by sq_addref and sq_release.
2) Allowing sq_release calls during RefTable::Finalize.

Does that seem like a bad idea? I can't think of a simple way to tear down the references into the engine short of keeping them in a collection and releasing them before I call sq_close.
absence
#2 Posted : Wednesday, August 26, 2015 2:39:11 PM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 8/23/2014(UTC)
Posts: 109
Man
Location: Northern Germany & Lincolnshire, U.K.

Thanks: 1 times
Was thanked: 10 time(s) in 10 post(s)
Squirrel can not know what you're doing in your releashook.
Storing a HSQOBJECT and referencing it to release it in a releasehook is a bad idea for the very reason you experience.
At VM shutdown, it will nullify (delete) all objects HARD, like when a system process shuts down (like... your C++ code, when objects are still allocated, will simply remove them from memory)
The releasehook is for you to deallocate any memory allocated without the knowledge of the VM or deinitialisation stuff NOT related to the VM _only_.

To avoid implications that can get very, very complicated, the vm gets invalidated _before_ the teardown for a good reason i touched above.

Hence, to resolve your issue, you MUST NOT sq_addref any HSQOBJECT you're storing that way.
Unfortunately, you can't use sq_getref on that object, too (because as mentioned above, the vm itself is invalid for a good reason)

As a rough fix, you can, however, add a global C/C++ variable to set right before you call sq_close and check that. If it is set, do not sq_release your HSQOBJECT, because the VM takes care (or maybe already took care) of deallocating the HSQOBJECT:

...
bool _SHUTDOWN=false ;
...
v=sq_open() ;
... //do stuff
_SHUTDOWN=true ; sq_close(v) ; //shutdown

void myreleasehook(...)
{
if (!_SHUTDOWN) sq_release(m_myHSQOBJECT) ;
}




Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Clean Slate theme by Jaben Cargman (Tiny Gecko)
Powered by YAF 1.9.4 | YAF © 2003-2010, Yet Another Forum.NET
This page was generated in 0.122 seconds.