From 39a8fae44186c074265482a09eaa8465334f8183 Mon Sep 17 00:00:00 2001 From: Xiongfei Guo Date: Fri, 20 Jun 2014 10:31:21 +0000 Subject: [PATCH] Fix bug of GC in fd and timeout objects for lua binding. fd and timeout lua object has a __gc method in its metatable. After the object is freed and the another new object use the same reference in __uloop_cb and __uloop_fds, the new object will be freed by the old __gc of the old object when garbag collecting. Signed-off-by: Xiongfei(Alex) Guo --- lua/uloop.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/lua/uloop.c b/lua/uloop.c index 89ce60c..4abc4c3 100644 --- a/lua/uloop.c +++ b/lua/uloop.c @@ -77,8 +77,15 @@ static int ul_timer_set(lua_State *L) static int ul_timer_free(lua_State *L) { struct lua_uloop_timeout *tout = lua_touserdata(L, 1); - + uloop_timeout_cancel(&tout->t); + + /* obj.__index.__gc = nil , make sure executing only once*/ + lua_getfield(L, -1, "__index"); + lua_pushstring(L, "__gc"); + lua_pushnil(L); + lua_settable(L, -3); + lua_getglobal(state, "__uloop_cb"); luaL_unref(state, -1, tout->r); @@ -150,7 +157,6 @@ static void ul_ufd_cb(struct uloop_fd *fd, unsigned int events) /* push events */ lua_pushinteger(state, events); - lua_call(state, 2, 0); } @@ -175,9 +181,15 @@ static int get_sock_fd(lua_State* L, int idx) { static int ul_ufd_delete(lua_State *L) { struct lua_uloop_fd *ufd = lua_touserdata(L, 1); - + uloop_fd_delete(&ufd->fd); + /* obj.__index.__gc = nil , make sure executing only once*/ + lua_getfield(L, -1, "__index"); + lua_pushstring(L, "__gc"); + lua_pushnil(L); + lua_settable(L, -3); + lua_getglobal(state, "__uloop_cb"); luaL_unref(state, -1, ufd->r); lua_remove(state, -1); @@ -345,12 +357,19 @@ static int ul_run(lua_State *L) return 1; } +static int ul_end(lua_State *L) +{ + uloop_end(); + return 1; +} + static luaL_reg uloop_func[] = { {"init", ul_init}, {"run", ul_run}, {"timer", ul_timer}, {"process", ul_process}, {"fd_add", ul_ufd_add}, + {"end", ul_end}, {NULL, NULL}, }; -- 2.11.0