lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Roberto:

On Mon, May 27, 2019 at 5:39 PM Roberto Ierusalimschy
<roberto@inf.puc-rio.br> wrote:

> I am not sure what you are trying to find in the docs. If an object is
> garbage (it cannot be accessed from Lua), it can be collected. 'pcall'
> has nothing to do with that.

I did not express myself too correctly. I receive a callback in C,
build a userdata with several pointers and do a pcall() with the
userdata as a parameter. The __gc method I set in the userdata frees
some C data ( as this kind of userdatas are sometimes built the other
way, lua code ask for the creation ). I need to avoid calling the __gc
method inside the pcall, to do some cleanup in C which depended on the
__gc method for the UD not being run.

At first I thought the lua code would keep it alive, as it is in the
arguments of the called function. Then I realized the function could
be "function(ud); ud=nil; collectgarbage(); end". Then I entered a
death spiral of documentation reading trying to find some thing.

After that i pulled out and decided to do it right, build the
userdata, push a copy to call the function, do my things, pop the
copy, let lua gc do its things however it wants.

> > I need to know this because the object I push has a __gc method which
> > destroys it, and I need to access some data inside it just after
> > return.
> How are going to access that data inside the object without a reference
> to it?

Just for illustration, it's a stupid thing I did, I've fixed it. The
UD HAS, among other things,  a pointer to a message. The UD destructor
frees it. I start the C callback with a pointer to a message, build
the userdata, do the pcall to the lua callback, read a field from the
message using the original ptr, return from the C callback. Now I just
dup the userdata before the callback and pop the copy after reading
the field. I did the old one in a hurry and it probably worked due to
low memory pressure. Then I began cleaning and thought "they cannot
collect it as it must be live in the parameters till the end of the
lua callback, and the return is not going to collect garbage", then I
though "but wait, someone may set the local parameter to nil and
collect"...., brain fart, death spiral. So do it in what seems to be a
guaranteed way, and use the usual pattern I try to do to avoid this
kind of a problem, "do not keep copies of pointers inside userdatas
across lua calls".

Francisco Olarte.