diff options
Diffstat (limited to 'dev-lua/luaevent/files/gc-anchoring.patch')
-rw-r--r-- | dev-lua/luaevent/files/gc-anchoring.patch | 172 |
1 files changed, 0 insertions, 172 deletions
diff --git a/dev-lua/luaevent/files/gc-anchoring.patch b/dev-lua/luaevent/files/gc-anchoring.patch deleted file mode 100644 index 991aab1..0000000 --- a/dev-lua/luaevent/files/gc-anchoring.patch +++ /dev/null @@ -1,172 +0,0 @@ -From f31efa83bd76ac375c00b31c30eb731cf4fd2226 Mon Sep 17 00:00:00 2001 -From: Matthew Wild <mwild1@gmail.com> -Date: Sat, 15 Jun 2013 22:51:03 +0100 -Subject: [PATCH] Ensure that callback object is always anchored to prevent the - possibility of it being garbage-collected before/while the C callback runs - ---- - include/event_callback.h | 2 + - src/event_callback.c | 110 ++++++++++++++++++++++++----------------------- - 2 files changed, 59 insertions(+), 53 deletions(-) - -diff --git a/include/event_callback.h b/include/event_callback.h -index 9d68b26..6d7a2f1 100644 ---- a/include/event_callback.h -+++ b/include/event_callback.h -@@ -28,7 +28,9 @@ - typedef struct { - struct event ev; - le_base* base; -+ int selfRef; - int callbackRef; -+ int running; - struct timeval timeout; - } le_callback; - -diff --git a/src/event_callback.c b/src/event_callback.c -index afe8773..9e705be 100644 ---- a/src/event_callback.c -+++ b/src/event_callback.c -@@ -27,11 +27,10 @@ - - #define EVENT_CALLBACK_ARG_MT "EVENT_CALLBACK_ARG_MT" - --void freeCallbackArgs(le_callback* arg, lua_State* L) { -- if(arg->base) { -- arg->base = NULL; -- event_del(&arg->ev); -- luaL_unref(L, LUA_REGISTRYINDEX, arg->callbackRef); -+void freeCallback(le_callback* cb, lua_State* L) { -+ if(cb->callbackRef != LUA_NOREF) { -+ luaL_unref(L, LUA_REGISTRYINDEX, cb->callbackRef); -+ cb->callbackRef = LUA_NOREF; - } - } - /* le_callback is allocated at the beginning of the coroutine in which it -@@ -40,60 +39,62 @@ is used, no need to manually de-allocate */ - /* Index for coroutine is fd as integer for *nix, as lightuserdata for Win */ - void luaevent_callback(int fd, short event, void* p) { - le_callback* cb = p; -+ struct event *ev = &cb->ev; - lua_State* L; -- int ret; -+ int ret = -1; - struct timeval new_tv = { 0, 0 }; -- le_base* base; -- assert(cb); -- if(!cb->base) -- return; /* Event has already been collected + destroyed */ -- assert(cb->base->loop_L); -- L = cb->base->loop_L; -- lua_rawgeti(L, LUA_REGISTRYINDEX, cb->callbackRef); -- lua_pushinteger(L, event); -- /* cb->base may be NULL after the pcall, if the event is destroyed */ -- base = cb->base; -- if(lua_pcall(L, 1, 2, 0)) -- { -- base->errorMessage = luaL_ref(L, LUA_REGISTRYINDEX); -- event_base_loopbreak(base->base); -- lua_pop(L, 1); -- return; -- } -- if(!cb->base) { -- lua_pop(L, 2); -- return; /* event was destroyed during callback */ -- } -- /* If nothing is returned, re-use the old event value */ -- ret = luaL_optinteger(L, -2, event); -- /* Clone the old timeout value in case a new one wasn't set */ -- memcpy(&new_tv, &cb->timeout, sizeof(new_tv)); -- if(lua_isnumber(L, -1)) { -- double newTimeout = lua_tonumber(L, -1); -- if(newTimeout > 0) { -- load_timeval(newTimeout, &new_tv); -+ if(cb->callbackRef != LUA_NOREF) { -+ L = cb->base->loop_L; -+ lua_rawgeti(L, LUA_REGISTRYINDEX, cb->callbackRef); -+ lua_pushinteger(L, event); -+ cb->running = 1; -+ if(lua_pcall(L, 1, 2, 0)) -+ { -+ cb->running = 0; -+ cb->base->errorMessage = luaL_ref(L, LUA_REGISTRYINDEX); -+ event_base_loopbreak(cb->base->base); -+ lua_pop(L, 1); /* Pop the 'false' from pcall */ -+ return; - } -+ cb->running = 0; -+ /* If nothing is returned, re-use the old event value */ -+ ret = luaL_optinteger(L, -2, event); - } -- lua_pop(L, 2); -- if(ret == -1) { -- freeCallbackArgs(cb, L); -- } else { -- struct event *ev = &cb->ev; -- int newEvent = ret; -- if( newEvent != event || (cb->timeout.tv_sec != new_tv.tv_sec || cb->timeout.tv_usec != new_tv.tv_usec) ) { -- struct timeval *ptv = &cb->timeout; -- cb->timeout = new_tv; -- event_del(ev); -- event_set(ev, fd, EV_PERSIST | newEvent, luaevent_callback, cb); -- /* Assume cannot set a new timeout.. */ -- event_add(ev, ptv); -+ if(ret == -1 || cb->callbackRef == LUA_NOREF) { -+ event_del(ev); -+ freeCallback(cb, L); -+ assert(cb->selfRef != LUA_NOREF); -+ luaL_unref(L, LUA_REGISTRYINDEX, cb->selfRef); -+ cb->selfRef = LUA_NOREF; -+ } else if( ret != event || (cb->timeout.tv_sec != new_tv.tv_sec || cb->timeout.tv_usec != new_tv.tv_usec) ) { -+ /* Clone the old timeout value in case a new one wasn't set */ -+ memcpy(&new_tv, &cb->timeout, sizeof(new_tv)); -+ if(lua_isnumber(L, -1)) { -+ double newTimeout = lua_tonumber(L, -1); -+ if(newTimeout > 0) { -+ load_timeval(newTimeout, &new_tv); -+ } - } -+ struct timeval *ptv = &cb->timeout; -+ cb->timeout = new_tv; -+ event_del(ev); -+ event_set(ev, fd, EV_PERSIST | ret, luaevent_callback, cb); -+ /* Assume cannot set a new timeout.. */ -+ event_add(ev, ptv); - } -+ lua_pop(L, 2); /* Pop two results from call */ - } - - static int luaevent_cb_gc(lua_State* L) { -- le_callback* arg = luaL_checkudata(L, 1, EVENT_CALLBACK_ARG_MT); -- freeCallbackArgs(arg, L); -+ freeCallback(luaL_checkudata(L, 1, EVENT_CALLBACK_ARG_MT), L); -+ return 0; -+} -+ -+static int luaevent_cb_close(lua_State* L) { -+ le_callback *cb = luaL_checkudata(L, 1, EVENT_CALLBACK_ARG_MT); -+ if(!cb->running) -+ event_del(&cb->ev); -+ freeCallback(cb, L); // Release reference to Lua callback - return 0; - } - -@@ -104,6 +105,9 @@ le_callback* event_callback_push(lua_State* L, int baseIdx, int callbackIdx) { - le_base *base = event_base_get(L, baseIdx); - luaL_checktype(L, callbackIdx, LUA_TFUNCTION); - cb = lua_newuserdata(L, sizeof(*cb)); -+ lua_pushvalue(L, -1); -+ cb->selfRef = luaL_ref(L, LUA_REGISTRYINDEX); -+ cb->running = 0; - luaL_getmetatable(L, EVENT_CALLBACK_ARG_MT); - lua_setmetatable(L, -2); - -@@ -119,7 +123,7 @@ void event_callback_register(lua_State* L) { - lua_pushcfunction(L, luaevent_cb_gc); - lua_setfield(L, -2, "__gc"); - lua_newtable(L); -- lua_pushcfunction(L, luaevent_cb_gc); -+ lua_pushcfunction(L, luaevent_cb_close); - lua_setfield(L, -2, "close"); - lua_setfield(L, -2, "__index"); - lua_pop(L, 1); |