Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The order of destruction of GDScriptLanguage::singleton prevents from freeing any script from unregister_voxel_types() #189

Open
Zylann opened this issue Aug 29, 2020 · 3 comments

Comments

@Zylann
Copy link
Owner

Zylann commented Aug 29, 2020

Writing this issue to keep track of the problem.

After introducing VoxelServer, which is a singleton created in register_voxel_types() and destroyed in unregister_voxel_types(), now all the threads used for voxel processing are shared between voxel nodes, using a thread pool (see #188). That pool is stored in the VoxelServer singleton. That means that when the game exits, a thread could still exist and task results not handled yet. These tasks are just waited for and then destroyed when the VoxelServer singleton is destroyed.

However, users can write custom world generators with GDScript. Such generators are resources that can be referenced by these tasks. And it's impossible to free scripts correctly in that case, because GDScriptLanguage::singleton is destroyed before the voxel module. A similar problem might occur for other languages.

There is no "pre-destroy" prepass of any sort that I'm aware of in Godot which could help freeing these dependencies between singletons.
So instead, I might rely on some sort of autoload which I'll shove into the scene tree somehow (this also requires awkward code to get in), and when that node is destroyed, will clear up all data VoxelServer is referencing.
I really don't like doing these workarounds so I hope something better can be done in the future...

@menip
Copy link
Contributor

menip commented Aug 29, 2020

Are we able to create a Godot proposal to address this issue? Or is there just no general solution?

@Zylann
Copy link
Owner Author

Zylann commented Aug 30, 2020

Something could be proposed, but I'm not sure what. One way would be to have a prepass before unregistration of modules, so that they can cleanup any ref they could be indirectly holding from others (even though modules likely don't depend on each other explicitely), then free their singletons in the second pass that we have currently.

For now I found a slightly better workaround which is to clear every pending tasks when the last voxel node is unregistered (which does happen on exit, but can also happen in game or editor).

@Xrayez
Copy link

Xrayez commented Sep 30, 2020

Godot 4.0 adds ability to preregister_types(), so Godot might as well add preunregister_types()? 😕

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants