Skip to content

Commit

Permalink
try safe handle external handle
Browse files Browse the repository at this point in the history
  • Loading branch information
zhaozg committed Nov 13, 2024
1 parent e2d3d18 commit 6f81745
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 2 deletions.
8 changes: 8 additions & 0 deletions src/handle.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,14 @@ static int luv_close(lua_State* L) {
static void luv_handle_free(uv_handle_t* handle) {
luv_handle_t* data = (luv_handle_t*)handle->data;
if (data) {
luv_ctx_t* ctx = data->ctx;
lua_State* L = ctx->L;
// release handle in ht_ref
lua_rawgeti(L, LUA_REGISTRYINDEX, ctx->ht_ref);
lua_pushnil(L);
lua_rawsetp(L, -2, data);
lua_pop(L, 1);

if (data->extra_gc)
data->extra_gc(data->extra);
free(data);
Expand Down
7 changes: 7 additions & 0 deletions src/lhandle.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ static luv_handle_t* luv_setup_handle(lua_State* L, luv_ctx_t* ctx) {
data->ctx = ctx;
data->extra = NULL;
data->extra_gc = NULL;

// record data in ht_ref
lua_rawgeti(L, LUA_REGISTRYINDEX, ctx->ht_ref);
lua_pushboolean(L, 1);
lua_rawsetp(L, -2, data);
lua_pop(L, 1);

return data;
}

Expand Down
14 changes: 12 additions & 2 deletions src/loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,18 @@ static int luv_update_time(lua_State* L) {
}

static void luv_walk_cb(uv_handle_t* handle, void* arg) {
lua_State* L = (lua_State*)arg;
luv_ctx_t* ctx = (luv_ctx_t*)arg;
lua_State* L = ctx->L;
luv_handle_t* data = (luv_handle_t*)handle->data;

// Skip foreign handles (shared event loop)
lua_rawgeti(L, LUA_REGISTRYINDEX, ctx->ht_ref);
lua_rawgetp(L, -1, data);
if (lua_isnil(L, -1)) {
lua_pop(L, 2);
return;
}

// Sanity check
// Most invalid values are large and refs are small, 0x1000000 is arbitrary.
assert(data && data->ref < 0x1000000);
Expand All @@ -103,8 +112,9 @@ static void luv_walk_cb(uv_handle_t* handle, void* arg) {
}

static int luv_walk(lua_State* L) {
luv_ctx_t* ctx = luv_context(L);
luaL_checktype(L, 1, LUA_TFUNCTION);
uv_walk(luv_loop(L), luv_walk_cb, L);
uv_walk(luv_loop(L), luv_walk_cb, ctx);
return 0;
}

Expand Down
3 changes: 3 additions & 0 deletions src/luv.c
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,9 @@ LUALIB_API luv_ctx_t* luv_context(lua_State* L) {
ctx = (luv_ctx_t*)lua_newuserdata(L, sizeof(*ctx));
memset(ctx, 0, sizeof(*ctx));
lua_rawset(L, LUA_REGISTRYINDEX);
// create table to contain internal handle
lua_newtable(L);
ctx->ht_ref = luaL_ref(L, LUA_REGISTRYINDEX);
} else {
ctx = (luv_ctx_t*)lua_touserdata(L, -1);
}
Expand Down
2 changes: 2 additions & 0 deletions src/luv.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ typedef struct {
luv_CFcpcall thrd_cpcall; /* luv thread c function in protected mode*/

int mode; /* the mode used to run the loop (-1 if not running) */
int ht_ref; /* bookkeeping: maintain table of luv_handle_t pointers,
to distinguish between internal and external handles */

void* extra; /* extra data */
} luv_ctx_t;
Expand Down

0 comments on commit 6f81745

Please sign in to comment.