lua-users home
lua-l archive

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


Roberto Ierusalimschy <roberto@inf.puc-rio.br> 于2021年12月31日周五 17:59写道:
>
> > It's restrictive in my opinion, the limitation is unnecessary.
> >
> > Maybe there is a better solution :
> >
> > diff --git a/lgc.c b/lgc.c
> > [...]
> > -    o->next = g->finobj;  /* link it in 'finobj' list */
> > -    g->finobj = o;
> > +    if (g->gcstp & GCSTPCLS) {                   /* closing state? */
> > +      o->next = g->tobefnz;
> > +      g->tobefnz = o;
> > +    } else {
> > +      o->next = g->finobj;  /* link it in 'finobj' list */
> > +      g->finobj = o;
> > +    }
>
> Have you tried this change with the standard test suite?
>
> The test suite uses a nice hack, which I particularly enjoy, for
> tracking GC cycles:
>
>   local mt = {}
>   function mt.__gc (o)
>     stderr:write'.'    -- mark progress
>     setmetatable(o, mt)   -- remark object for finalization
>   end
>   setmetatable({}, mt)
>
> With this change, this code creates an infinite loop. So, we lose this
> kind of hack for gaining a flexibility that I am not sure can be useful
> in practice. (At least nobody ever asked for it.) Even if we find it to
> be more useful, it would create a gratuitously incompatibility for what
> is mainly a bug-fix release.

I agree. This behavior is already well documented,  "If any finalizer
marks objects for collection during that phase, these marks have no
effect."

Another small issue is the order of the finalizers. As the document
says " the first finalizer to be called is the one associated with the
object marked last in the program."
In this case, the new finalizer associated with a finalizer would be
called before the older one (_CLIBS). Is that a problem?

For example,
```lua
local function finalizer(name, f)
  print("Create", name)
  setmetatable({} , {
  __gc = function()
    print("Run", name)
    if f then f() end
  end
  })
end

finalizer "1"
finalizer ("2", function () finalizer "3" end)

collectgarbage "collect"
```

The output :
```
Create  1
Create  2
Run     2
Create  3
Run     1
Run     3
```

1 is marked first and 3 is marked last, but 3 is called after 1 .


--
http://blog.codingnow.com