Skip to content

Instantly share code, notes, and snippets.

@kalamay
Last active August 29, 2015 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kalamay/e84e35af4cc309493120 to your computer and use it in GitHub Desktop.
Save kalamay/e84e35af4cc309493120 to your computer and use it in GitHub Desktop.
luajit ffi reference counting
local ffi = require('ffi')
ffi.cdef[[
typedef struct Other Other;
typedef struct Thing Thing;
struct Other {
Thing *thing;
int index;
};
struct Thing {
Other *others[2];
int ref;
};
void *malloc(size_t);
void free (void *);
]]
local C = ffi.C
local Thing = {}
Thing.__index = Thing
local function release(self)
self.ref = self.ref - 1
print("release", self)
if self.ref == 0 then
print("adios")
=C.free(self)
end
end
function Thing:new(a, b)
local self = ffi.gc(ffi.cast("Thing *", C.malloc(ffi.sizeof("Thing"))), release)
self.others[0] = a
self.others[1] = b
self.ref = 3
a.index = 0
b.index = 1
a.thing = self
b.thing = self
return self
end
function Thing:__tostring()
return string.format("Thing: others=[0x%08x,0x%08x], ref=%d",
tonumber(ffi.cast("uintptr_t", self.others[0])),
tonumber(ffi.cast("uintptr_t", self.others[1])),
self.ref)
end
ffi.metatype("Thing", Thing)
local Other = {}
Other.__index = Other
function Other:new()
return self.alloc(nil)
end
function Other:__gc()
self.thing.others[self.index] = nil
release(self.thing)
end
Other.alloc = ffi.metatype("Other", Other)
local a = Other:new()
local b = Other:new()
local t = Thing:new(a,b)
print(t)
t = nil
collectgarbage("collect")
print(a.thing)
print(b.thing)
a = nil
collectgarbage("collect")
print(b.thing)
b = nil
collectgarbage("collect")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment