[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Unpicking require
- From: 云风 Cloud Wu <cloudwu@...>
- Date: Tue, 28 Dec 2021 08:23:39 +0800
Roberto Ierusalimschy <roberto@inf.puc-rio.br> 于2021年12月28日周二 02:25写道:
>
> > Roberto Ierusalimschy <roberto@inf.puc-rio.br> 于2021年12月22日周三 01:56写道:
> > >
> > > Serious? This bug is there for more than 10 years, and you wait to
> > > announce it one minute after we announce a new release candidate?
> >
> > I saw the patch
> > https://github.com/lua/lua/commit/597a53bbc681089d85b082b46c2e2428dec43b86,
> > It seems that we can't create a new finalizer when closing state.
> >
> > I think we can link the new finalizer at the beginning of 'tobefnz'
> > list immediately when closing state. The finalizer of _CLIBS is at
> > the end, so it can avoid this issue.
>
> I am not sure what is your point. Does the patch do not solve the
> problem? Is it too restrictive? Too complex?
It's restrictive in my opinion, the limitation is unnecessary.
Maybe there is a better solution :
diff --git a/lgc.c b/lgc.c
index 42a73d81..30a138d2 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1011,9 +1011,8 @@ static void correctpointers (global_State *g,
GCObject *o) {
void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
global_State *g = G(L);
if (tofinalize(o) || /* obj. is already marked... */
- gfasttm(g, mt, TM_GC) == NULL || /* or has no finalizer... */
- (g->gcstp & GCSTPCLS)) /* or closing state? */
- return; /* nothing to be done */
+ gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer... */
+ return; /* nothing to be done */
else { /* move 'o' to 'finobj' list */
GCObject **p;
if (issweepphase(g)) {
@@ -1026,8 +1025,13 @@ void luaC_checkfinalizer (lua_State *L,
GCObject *o, Table *mt) {
/* search for pointer pointing to 'o' */
for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ }
*p = o->next; /* remove 'o' from 'allgc' list */
- 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;
+ }
l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */
}
}
@@ -1503,10 +1507,10 @@ static void deletelist (lua_State *L, GCObject
*p, GCObject *limit) {
*/
void luaC_freeallobjects (lua_State *L) {
global_State *g = G(L);
- g->gcstp = GCSTPCLS; /* no extra finalizers after here */
luaC_changemode(L, KGC_INC);
separatetobefnz(g, 1); /* separate all objects with finalizers */
lua_assert(g->finobj == NULL);
+ g->gcstp = GCSTPCLS;
callallpendingfinalizers(L);
deletelist(L, g->allgc, obj2gco(g->mainthread));
lua_assert(g->finobj == NULL); /* no new finalizers */
We can link the finalizer to tobefnz list when closing state, because
all the objects will be collected immediately. We don't need wait them
in next GC cycle.
setmetatable({},{__gc=function()
-- Called as last finalizer during os.exit(0, true)
tl.test()
end})
This can be run in correct order (before the finalizer of _CLIBS)
rather than ignore it.
--
http://blog.codingnow.com