Skip to content

Commit 5871a11

Browse files
truemedianzhaozg
authored andcommitted
more descriptive reasoning for luv_walk_cb
1 parent 87dcb76 commit 5871a11

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

src/loop.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,18 @@ static int luv_update_time(lua_State* L) {
9595
}
9696

9797
static void luv_walk_cb(uv_handle_t* handle, void* arg) {
98+
// This function expects to be passed a lua_State* with a callback function
99+
// at index 1 and the handle registry table at index 2. Libuv always calls
100+
// this function synchronously in uv_walk, so we can rely on the Lua state
101+
// from the caller of luv_walk instead of dispatching to the loop's main
102+
// thread both to avoid the xmove and to allow tracebacks to pass through
103+
// luv_walk.
104+
98105
lua_State* L = (lua_State*)arg;
99106
luv_handle_t* data = (luv_handle_t*)handle->data;
100107

101-
// Skip foreign handles (shared event loop)
108+
// check if registry[luv_handle_key][data] is not nil, which will only be true
109+
// if the data refers to a valid luv_handle_t* that is still in use.
102110
lua_rawgetp(L, 2, data);
103111
if (lua_isnil(L, -1)) {
104112
lua_pop(L, 1);
@@ -112,6 +120,10 @@ static void luv_walk_cb(uv_handle_t* handle, void* arg) {
112120
luv_find_handle(L, data); // Get the userdata
113121
uv_handle_t **udata = (uv_handle_t**)lua_touserdata(L, -1);
114122
if (udata == NULL || *udata != handle) {
123+
// This will only happen if someone forged a uv_handle_t* that points to a
124+
// uv_handle_t* created by luv. This is very unlikely, but if data does
125+
// happen to be unintentionally pointer-like we should avoid treating it
126+
// as valid.
115127
lua_pop(L, 2); // Pop the function and the userdata
116128
return;
117129
}
@@ -120,9 +132,9 @@ static void luv_walk_cb(uv_handle_t* handle, void* arg) {
120132
}
121133

122134
static int luv_walk(lua_State* L) {
123-
luaL_checktype(L, 1, LUA_TFUNCTION);
124-
lua_settop(L, 1);
125-
lua_getfield(L, LUA_REGISTRYINDEX, luv_handle_key);
135+
luaL_checktype(L, 1, LUA_TFUNCTION); // Ensure index 1 is a function
136+
lua_settop(L, 1); // Remove any extra arguments
137+
lua_getfield(L, LUA_REGISTRYINDEX, luv_handle_key); // Place the handle registry table at index 2
126138
uv_walk(luv_loop(L), luv_walk_cb, L);
127139
return 0;
128140
}

0 commit comments

Comments
 (0)