diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-12-13 10:41:17 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-12-13 10:41:17 -0300 |
commit | 0bfc572e51d9035a615ef6e9523f736c9ffa8e57 (patch) | |
tree | 218f2bb13a873becf8fa657a296c8863f7e0e466 /lapi.c | |
parent | 1de95e97ef65632a88e08b6184bd9d1ceba7ec2f (diff) | |
download | lua-github-0bfc572e51d9035a615ef6e9523f736c9ffa8e57.tar.gz |
Bug: GC is not reentrant
As the GC is not reentrant, finalizers should not be able to invoke it.
Diffstat (limited to 'lapi.c')
-rw-r--r-- | lapi.c | 17 |
1 files changed, 9 insertions, 8 deletions
@@ -1136,18 +1136,19 @@ LUA_API int lua_status (lua_State *L) { LUA_API int lua_gc (lua_State *L, int what, ...) { va_list argp; int res = 0; - global_State *g; + global_State *g = G(L); + if (g->gcstp & GCSTPGC) /* internal stop? */ + return -1; /* all options are invalid when stopped */ lua_lock(L); - g = G(L); va_start(argp, what); switch (what) { case LUA_GCSTOP: { - g->gcrunning = 0; + g->gcstp = GCSTPUSR; /* stopeed by the user */ break; } case LUA_GCRESTART: { luaE_setdebt(g, 0); - g->gcrunning = 1; + g->gcstp = 0; /* (GCSTPGC must be already zero here) */ break; } case LUA_GCCOLLECT: { @@ -1166,8 +1167,8 @@ LUA_API int lua_gc (lua_State *L, int what, ...) { case LUA_GCSTEP: { int data = va_arg(argp, int); l_mem debt = 1; /* =1 to signal that it did an actual step */ - lu_byte oldrunning = g->gcrunning; - g->gcrunning = 1; /* allow GC to run */ + lu_byte oldstp = g->gcstp; + g->gcstp = 0; /* allow GC to run (GCSTPGC must be zero here) */ if (data == 0) { luaE_setdebt(g, 0); /* do a basic step */ luaC_step(L); @@ -1177,7 +1178,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) { luaE_setdebt(g, debt); luaC_checkGC(L); } - g->gcrunning = oldrunning; /* restore previous state */ + g->gcstp = oldstp; /* restore previous state */ if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */ res = 1; /* signal it */ break; @@ -1195,7 +1196,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) { break; } case LUA_GCISRUNNING: { - res = g->gcrunning; + res = gcrunning(g); break; } case LUA_GCGEN: { |