share sproto C struct

This commit is contained in:
Cloud Wu
2015-04-08 11:23:52 +08:00
parent ca33bf8b3e
commit 5a1132101b
3 changed files with 35 additions and 39 deletions

View File

@@ -48,15 +48,9 @@ LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
static int static int
lnewproto(lua_State *L) { lnewproto(lua_State *L) {
size_t sz = 0;
void * buffer;
struct sproto * sp; struct sproto * sp;
if (lua_isuserdata(L,1)) { size_t sz;
buffer = lua_touserdata(L,1); void * buffer = (void *)luaL_checklstring(L,1,&sz);
sz = luaL_checkinteger(L,2);
} else {
buffer = (void *)luaL_checklstring(L,1,&sz);
}
sp = sproto_create(buffer, sz); sp = sproto_create(buffer, sz);
if (sp) { if (sp) {
lua_pushlightuserdata(L, sp); lua_pushlightuserdata(L, sp);
@@ -545,48 +539,38 @@ lprotocol(lua_State *L) {
return 3; return 3;
} }
/* global sproto pointer for multi states */ /* global sproto pointer for multi states
struct sproto_bin { NOTICE : It is not thread safe
void *ptr; */
size_t sz; static struct sproto * G_sproto[MAX_GLOBALSPROTO];
};
static struct sproto_bin G_sproto[MAX_GLOBALSPROTO];
static int static int
lsaveproto(lua_State *L) { lsaveproto(lua_State *L) {
size_t sz; struct sproto * sp = lua_touserdata(L, 1);
void * buffer = (void *)luaL_checklstring(L,1,&sz);
int index = luaL_optinteger(L, 2, 0); int index = luaL_optinteger(L, 2, 0);
void * tmp;
struct sproto_bin * sbin = &G_sproto[index];
if (index < 0 || index >= MAX_GLOBALSPROTO) { if (index < 0 || index >= MAX_GLOBALSPROTO) {
return luaL_error(L, "Invalid global slot index %d", index); return luaL_error(L, "Invalid global slot index %d", index);
} }
tmp = malloc(sz); /* TODO : release old object (memory leak now, but thread safe)*/
memcpy(tmp, buffer, sz); G_sproto[index] = sp;
if (sbin->ptr) {
free(sbin->ptr);
}
sbin->ptr = tmp;
sbin->sz = sz;
return 0; return 0;
} }
static int static int
lloadproto(lua_State *L) { lloadproto(lua_State *L) {
int index = luaL_optinteger(L, 1, 0); int index = luaL_optinteger(L, 1, 0);
struct sproto_bin * sbin = &G_sproto[index]; struct sproto * sp;
if (index < 0 || index >= MAX_GLOBALSPROTO) { if (index < 0 || index >= MAX_GLOBALSPROTO) {
return luaL_error(L, "Invalid global slot index %d", index); return luaL_error(L, "Invalid global slot index %d", index);
} }
if (sbin->ptr == NULL) { sp = G_sproto[index];
if (sp == NULL) {
return luaL_error(L, "nil sproto at index %d", index); return luaL_error(L, "nil sproto at index %d", index);
} }
lua_pushlightuserdata(L, sbin->ptr); lua_pushlightuserdata(L, sp);
lua_pushinteger(L, sbin->sz);
return 2; return 1;
} }
int int

View File

@@ -13,14 +13,23 @@ function sproto_mt:__gc()
core.deleteproto(self.__cobj) core.deleteproto(self.__cobj)
end end
function sproto.new(bin,sz,nogc) function sproto.new(bin)
local cobj = assert(core.newproto(bin,sz)) local cobj = assert(core.newproto(bin))
local self = { local self = {
__cobj = cobj, __cobj = cobj,
__tcache = setmetatable( {} , weak_mt ), __tcache = setmetatable( {} , weak_mt ),
__pcache = setmetatable( {} , weak_mt ), __pcache = setmetatable( {} , weak_mt ),
} }
return setmetatable(self, nogc and sproto_nogc or sproto_mt) return setmetatable(self, sproto_mt)
end
function sproto.sharenew(cobj)
local self = {
__cobj = cobj,
__tcache = setmetatable( {} , weak_mt ),
__pcache = setmetatable( {} , weak_mt ),
}
return setmetatable(self, sproto_nogc)
end end
function sproto.parse(ptext) function sproto.parse(ptext)

View File

@@ -8,16 +8,19 @@ function loader.register(filename, index)
local f = assert(io.open(filename), "Can't open sproto file") local f = assert(io.open(filename), "Can't open sproto file")
local data = f:read "a" local data = f:read "a"
f:close() f:close()
local bin = parser.parse(data) local sp = core.newproto(parser.parse(data))
core.saveproto(bin, index) core.saveproto(sp, index)
end end
loader.save = core.saveproto function loader.save(bin, index)
local sp = core.newproto(bin)
core.saveproto(sp, index)
end
function loader.load(index) function loader.load(index)
local bin, sz = core.loadproto(index) local sp = core.loadproto(index)
-- no __gc in metatable -- no __gc in metatable
return sproto.new(bin,sz, true) return sproto.sharenew(sp)
end end
return loader return loader