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 <xfguo@credosemi.com>
This commit is contained in:
parent
3c92274bee
commit
39a8fae441
1 changed files with 22 additions and 3 deletions
25
lua/uloop.c
25
lua/uloop.c
|
@ -77,8 +77,15 @@ static int ul_timer_set(lua_State *L)
|
||||||
static int ul_timer_free(lua_State *L)
|
static int ul_timer_free(lua_State *L)
|
||||||
{
|
{
|
||||||
struct lua_uloop_timeout *tout = lua_touserdata(L, 1);
|
struct lua_uloop_timeout *tout = lua_touserdata(L, 1);
|
||||||
|
|
||||||
uloop_timeout_cancel(&tout->t);
|
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");
|
lua_getglobal(state, "__uloop_cb");
|
||||||
luaL_unref(state, -1, tout->r);
|
luaL_unref(state, -1, tout->r);
|
||||||
|
|
||||||
|
@ -150,7 +157,6 @@ static void ul_ufd_cb(struct uloop_fd *fd, unsigned int events)
|
||||||
|
|
||||||
/* push events */
|
/* push events */
|
||||||
lua_pushinteger(state, events);
|
lua_pushinteger(state, events);
|
||||||
|
|
||||||
lua_call(state, 2, 0);
|
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)
|
static int ul_ufd_delete(lua_State *L)
|
||||||
{
|
{
|
||||||
struct lua_uloop_fd *ufd = lua_touserdata(L, 1);
|
struct lua_uloop_fd *ufd = lua_touserdata(L, 1);
|
||||||
|
|
||||||
uloop_fd_delete(&ufd->fd);
|
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");
|
lua_getglobal(state, "__uloop_cb");
|
||||||
luaL_unref(state, -1, ufd->r);
|
luaL_unref(state, -1, ufd->r);
|
||||||
lua_remove(state, -1);
|
lua_remove(state, -1);
|
||||||
|
@ -345,12 +357,19 @@ static int ul_run(lua_State *L)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ul_end(lua_State *L)
|
||||||
|
{
|
||||||
|
uloop_end();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static luaL_reg uloop_func[] = {
|
static luaL_reg uloop_func[] = {
|
||||||
{"init", ul_init},
|
{"init", ul_init},
|
||||||
{"run", ul_run},
|
{"run", ul_run},
|
||||||
{"timer", ul_timer},
|
{"timer", ul_timer},
|
||||||
{"process", ul_process},
|
{"process", ul_process},
|
||||||
{"fd_add", ul_ufd_add},
|
{"fd_add", ul_ufd_add},
|
||||||
|
{"end", ul_end},
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue