Created
February 26, 2013 19:59
-
-
Save dotnwat/5041626 to your computer and use it in GitHub Desktop.
Demonstrates how a weak table in Lua can be used to prevent GC on a C++ object that has other C++ object references to it.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/lua_rados.cc b/lua_rados.cc | |
index 33a7ab7..d48d525 100644 | |
--- a/lua_rados.cc | |
+++ b/lua_rados.cc | |
@@ -19,6 +19,8 @@ | |
#define LRAD_TIOCTX_T "Rados.IoctxT" | |
#define LRAD_BL_T "Rados.Bufferlist" | |
+static char reg_key_rados_refs; | |
+ | |
typedef enum { | |
CREATED, | |
CONNECTED, | |
@@ -267,6 +269,16 @@ static int lrad_open_ioctx(lua_State *L) | |
if (ret) | |
return lrad_pusherror(L, ret); | |
+ /* record IoCtx -> Rados reference in weak key table */ | |
+ lua_pushlightuserdata(L, ®_key_rados_refs); | |
+ lua_gettable(L, LUA_REGISTRYINDEX); | |
+ assert(!lua_isnil(L, -1)); | |
+ assert(lua_type(L, -1) == LUA_TTABLE); | |
+ lua_pushvalue(L, -2); /* key = ioctx */ | |
+ lua_pushvalue(L, 1); /* value = cluster */ | |
+ lua_settable(L, -3); | |
+ lua_pop(L, 1); | |
+ | |
/* return the userdata */ | |
return 1; | |
} | |
@@ -435,6 +447,15 @@ LUALIB_API int luaopen_rados(lua_State *L) | |
lua_setfield(L, -2, "__gc"); | |
lua_pop(L, 1); | |
+ /* weak table to protect IoCtx -> Rados refs */ | |
+ lua_pushlightuserdata(L, ®_key_rados_refs); | |
+ lua_newtable(L); | |
+ lua_pushstring(L, "k"); | |
+ lua_setfield(L, -2, "__mode"); | |
+ lua_pushvalue(L, -1); | |
+ lua_setmetatable(L, -2); | |
+ lua_settable(L, LUA_REGISTRYINDEX); | |
+ | |
luaL_register(L, "rados", radoslib_f); | |
return 0; | |
diff --git a/test.lua b/test.lua | |
index 779a30f..4722d4f 100644 | |
--- a/test.lua | |
+++ b/test.lua | |
@@ -121,6 +121,13 @@ describe("ioctx object", function() | |
ioctx = cluster:open_ioctx('data') | |
end) | |
+ it("is usable if cluster ref disappears", function() | |
+ cluster = nil | |
+ collectgarbage() | |
+ local data = 'wkjeflkwjelfkjwelfkjwef' | |
+ assert.is_equal(#data, ioctx:write('oid', data, #data, 0)) | |
+ end) | |
+ | |
describe("write method", function() | |
it("returns number of bytes written", function() | |
local data = 'wkjeflkwjelfkjwelfkjwef' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment