tl;dr version: is a garbage collection metamethod safe during a Lua state shutdown if it accesses global variables? What about local up-values?
When a lua_State
is closed with lua_close
, the Lua documentation says that all of the objects are deleted. And it says that any associated garbage-collection metamethods are guaranteed to be called.
Great.
However, there are two possible use cases of GC metamethods that are uncertain under this paradigm:
What if you have a GC metamethod that uses a local variable that stores a collectable value. Say, a string, a function, etc. That is, your GC metamethod is defined as this:
local some_string = "string"
function mt:__gc() --[[Do something with some_string]] end
What happens in this case? Is it possible for some_string
to be collected? I know that if the object the metatable is on is being collected under normal circumstances, then this isn't possible. Lua would guarantee that the value of some_string
would remain until the GC function itself is collected.
But since all objects are being destroyed by lua_close
, is it possible that upvalues of the GC function could be destroyed before the function is? I don't think it is (as this could cause all kinds of problems), but I'm looking for the real answer, not what I think.
I admit that it is unlikely that #1 will be a problem, as it would create many issues with GC metamethods. However, this is a completely different matter:
local some_string = "string"
function mt:__gc() print(some_string) end
This looks like #1, but it isn't. Why? Because it accesses a global variable. Namely, print
.
There is no direct association between the function and whatever value is stored in print
(unlike case 1, where some_string
is clearly an upvalue of the function). As such, it is possible for print
to be collected before calling the function during Lua state shutdown.
The question is this: is it safe for a garbage collection metamethod to ever use anything from the global table (ignoring the possibility of deliberate sabotage of the global table vis-a-vis print = nil
) during Lua state shutdown? Or, as a general rule, should they always explicitly make any functions or data they touch local? Will that be sufficient to avoid problems?
Any data that is accessible from the __gc
method is safe to access; this includes both locals and the tables that are accessible, like _G
, which contains print
.
What can be a problem are (un-)loaded C libraries; this affects Lua 5.1, and is fixed in Lua 5.2.1. See the patch for "Finalizers may call functions from a dynamic library after the library has been unloaded".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With