Skip to content

Commit

Permalink
fix(worker): do not clean up workers in loop __gc
Browse files Browse the repository at this point in the history
When setting up luv with luaopen_luv(), instead of cleaning up workers
in the __gc of the loop (which luv may not own), instead create an empty
userdata with a worker __gc and attach it to the lua_State.

Fixes #754
  • Loading branch information
lewis6991 committed Jan 29, 2025
1 parent 1b29585 commit 1a96b46
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 9 deletions.
11 changes: 5 additions & 6 deletions src/luv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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");
Expand Down
17 changes: 14 additions & 3 deletions src/work.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand All @@ -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");
Expand All @@ -314,5 +315,15 @@ 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) {
lua_newuserdata(L, 0);
luaL_newmetatable(L, "luv_work.meta");
lua_pushcfunction(L, luv_work_gc);
lua_setfield(L, -2, "__gc");
lua_setmetatable(L, -2);
lua_setfield(L, LUA_REGISTRYINDEX, "luv_work");
}

uv_once(&once_vmkey, luv_key_init_once);
}

0 comments on commit 1a96b46

Please sign in to comment.