@@ -260,13 +260,6 @@ static int push_fs_result(lua_State* L, uv_fs_t* req) {
260260 }
261261
262262 if (req -> result < 0 ) {
263- if (req -> fs_type == UV_FS_SCANDIR ) {
264- // We need to unref the luv_fs_scandir_t userdata to allow it to be garbage collected.
265- // The scandir callback can only be called once, so we now know that the
266- // req can be safely garbage collected.
267- luaL_unref (L , LUA_REGISTRYINDEX , data -> data_ref );
268- data -> data_ref = LUA_NOREF ;
269- }
270263 lua_pushnil (L );
271264 if (fs_req_has_dest_path (req )) {
272265 lua_rawgeti (L , LUA_REGISTRYINDEX , data -> data_ref );
@@ -356,11 +349,6 @@ static int push_fs_result(lua_State* L, uv_fs_t* req) {
356349 // We want to return this instead of the uv_req_t because the
357350 // luv_fs_scandir_t userdata has a gc method.
358351 lua_rawgeti (L , LUA_REGISTRYINDEX , data -> data_ref );
359- // We now want to unref the userdata to allow it to be garbage collected.
360- // The scandir callback can only be called once, so we now know that the
361- // req can be safely garbage collected.
362- luaL_unref (L , LUA_REGISTRYINDEX , data -> data_ref );
363- data -> data_ref = LUA_NOREF ;
364352 return 1 ;
365353
366354#if LUV_UV_VERSION_GEQ (1 , 28 , 0 )
@@ -386,9 +374,6 @@ static int push_fs_result(lua_State* L, uv_fs_t* req) {
386374 return 1 ;
387375 }
388376 case UV_FS_READDIR : {
389- luaL_unref (L , LUA_REGISTRYINDEX , data -> data_ref );
390- data -> data_ref = LUA_NOREF ;
391-
392377 if (req -> result > 0 ) {
393378 size_t i ;
394379 uv_dir_t * dir = (uv_dir_t * )req -> ptr ;
@@ -400,6 +385,8 @@ static int push_fs_result(lua_State* L, uv_fs_t* req) {
400385 } else
401386 lua_pushnil (L );
402387
388+ luaL_unref (L , LUA_REGISTRYINDEX , data -> data_ref );
389+ data -> data_ref = LUA_NOREF ;
403390 return 1 ;
404391 }
405392 case UV_FS_CLOSEDIR :
@@ -438,6 +425,15 @@ static void luv_fs_cb(uv_fs_t* req) {
438425 }
439426 if (req -> fs_type == UV_FS_SCANDIR ) {
440427 luv_fulfill_req (L , data , nargs );
428+ // Regardless of whether or not we errored, we need to unref the
429+ // luv_fs_scandir_t userdata to allow it to be garbage collected.
430+ // The scandir callback can only be called once, so we now know that
431+ // the req can be safely garbage collected.
432+ //
433+ // Crucially, this needs to happen after the fulfill_req call to ensure
434+ // it doesn't get garbage collected beforehand.
435+ luaL_unref (L , LUA_REGISTRYINDEX , data -> data_ref );
436+ data -> data_ref = LUA_NOREF ;
441437 }
442438 else {
443439 // cleanup the uv_fs_t before the callback is called to avoid
0 commit comments