diff --git a/src/luv.c b/src/luv.c index aace3c27..43deaa58 100644 --- a/src/luv.c +++ b/src/luv.c @@ -852,11 +852,6 @@ static int loop_gc(lua_State *L) { while (uv_loop_close(loop)) { uv_run(loop, UV_RUN_DEFAULT); } - /* do cleanup in main thread */ - lua_getglobal(L, "_THREAD"); - if (lua_isnil(L, -1)) - luv_work_cleanup(); - lua_pop(L, 1); return 0; } @@ -925,7 +920,11 @@ LUALIB_API int luaopen_luv (lua_State* L) { luv_dir_init(L); #endif luv_thread_init(L); - luv_work_init(L); + + lua_getglobal(L, "_THREAD"); + int is_main = lua_isnil(L, -1); + lua_pop(L, 1); + luv_work_init(L, is_main); luv_constants(L); lua_setfield(L, -2, "constants"); diff --git a/src/work.c b/src/work.c index b51bfd11..006bd59e 100644 --- a/src/work.c +++ b/src/work.c @@ -287,12 +287,12 @@ static void luv_key_init_once(void) idx_vms = 0; } -static void luv_work_cleanup(void) +static int luv_work_gc(lua_State *L) { unsigned int i; if (nvms == 0) - return; + return 0; for (i = 0; i < nvms && vms[i]; i++) release_vm_cb(vms[i]); @@ -302,9 +302,10 @@ static void luv_work_cleanup(void) uv_mutex_destroy(&vm_mutex); nvms = 0; + return 0; } -static void luv_work_init(lua_State* L) { +static void luv_work_init(lua_State* L, int is_main) { luaL_newmetatable(L, "luv_work_ctx"); lua_pushcfunction(L, luv_work_ctx_tostring); lua_setfield(L, -2, "__tostring"); @@ -314,5 +315,18 @@ static void luv_work_init(lua_State* L) { lua_setfield(L, -2, "__index"); lua_pop(L, 1); + // do cleanup in main thread + if (is_main) { + luaL_newmetatable(L, "luv_work.meta"); + lua_pushcfunction(L, luv_work_gc); + lua_setfield(L, -2, "__gc"); + + lua_newuserdata(L, 0); + lua_setmetatable(L, -2); + + lua_setfield(L, LUA_REGISTRYINDEX, "luv_work"); + lua_pop(L, 1); + } + uv_once(&once_vmkey, luv_key_init_once); }