diff --git a/lualib-src/sproto/lsproto.c b/lualib-src/sproto/lsproto.c index 42eccd8c..c33118d4 100644 --- a/lualib-src/sproto/lsproto.c +++ b/lualib-src/sproto/lsproto.c @@ -48,15 +48,9 @@ LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { static int lnewproto(lua_State *L) { - size_t sz = 0; - void * buffer; struct sproto * sp; - if (lua_isuserdata(L,1)) { - buffer = lua_touserdata(L,1); - sz = luaL_checkinteger(L,2); - } else { - buffer = (void *)luaL_checklstring(L,1,&sz); - } + size_t sz; + void * buffer = (void *)luaL_checklstring(L,1,&sz); sp = sproto_create(buffer, sz); if (sp) { lua_pushlightuserdata(L, sp); @@ -545,48 +539,38 @@ lprotocol(lua_State *L) { return 3; } -/* global sproto pointer for multi states */ -struct sproto_bin { - void *ptr; - size_t sz; -}; - -static struct sproto_bin G_sproto[MAX_GLOBALSPROTO]; +/* global sproto pointer for multi states + NOTICE : It is not thread safe + */ +static struct sproto * G_sproto[MAX_GLOBALSPROTO]; static int lsaveproto(lua_State *L) { - size_t sz; - void * buffer = (void *)luaL_checklstring(L,1,&sz); + struct sproto * sp = lua_touserdata(L, 1); int index = luaL_optinteger(L, 2, 0); - void * tmp; - struct sproto_bin * sbin = &G_sproto[index]; if (index < 0 || index >= MAX_GLOBALSPROTO) { return luaL_error(L, "Invalid global slot index %d", index); } - tmp = malloc(sz); - memcpy(tmp, buffer, sz); - if (sbin->ptr) { - free(sbin->ptr); - } - sbin->ptr = tmp; - sbin->sz = sz; + /* TODO : release old object (memory leak now, but thread safe)*/ + G_sproto[index] = sp; return 0; } static int lloadproto(lua_State *L) { int index = luaL_optinteger(L, 1, 0); - struct sproto_bin * sbin = &G_sproto[index]; + struct sproto * sp; if (index < 0 || index >= MAX_GLOBALSPROTO) { 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); } - lua_pushlightuserdata(L, sbin->ptr); - lua_pushinteger(L, sbin->sz); - return 2; + lua_pushlightuserdata(L, sp); + + return 1; } int diff --git a/lualib/sproto.lua b/lualib/sproto.lua index 4c285222..7a722f55 100644 --- a/lualib/sproto.lua +++ b/lualib/sproto.lua @@ -13,14 +13,23 @@ function sproto_mt:__gc() core.deleteproto(self.__cobj) end -function sproto.new(bin,sz,nogc) - local cobj = assert(core.newproto(bin,sz)) +function sproto.new(bin) + local cobj = assert(core.newproto(bin)) local self = { __cobj = cobj, __tcache = 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 function sproto.parse(ptext) diff --git a/lualib/sprotoloader.lua b/lualib/sprotoloader.lua index 05d17293..e88a9260 100644 --- a/lualib/sprotoloader.lua +++ b/lualib/sprotoloader.lua @@ -8,16 +8,19 @@ function loader.register(filename, index) local f = assert(io.open(filename), "Can't open sproto file") local data = f:read "a" f:close() - local bin = parser.parse(data) - core.saveproto(bin, index) + local sp = core.newproto(parser.parse(data)) + core.saveproto(sp, index) end -loader.save = core.saveproto +function loader.save(bin, index) + local sp = core.newproto(bin) + core.saveproto(sp, index) +end function loader.load(index) - local bin, sz = core.loadproto(index) + local sp = core.loadproto(index) -- no __gc in metatable - return sproto.new(bin,sz, true) + return sproto.sharenew(sp) end return loader