Skip to content

Instantly share code, notes, and snippets.

@dotnwat
Created February 26, 2013 19:59
Show Gist options
  • Save dotnwat/5041626 to your computer and use it in GitHub Desktop.
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.
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, &reg_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, &reg_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