Bugfix: mc.close may reference an invalid pointer. See pr #220

This commit is contained in:
Cloud Wu
2015-01-05 12:17:57 +08:00
parent 52134f9e57
commit ee3f9c6ecd
2 changed files with 12 additions and 7 deletions

View File

@@ -83,7 +83,7 @@ mc_unpacklocal(lua_State *L) {
if (sz != sizeof(*pack)) { if (sz != sizeof(*pack)) {
return luaL_error(L, "Invalid multicast package size %d", sz); return luaL_error(L, "Invalid multicast package size %d", sz);
} }
lua_settop(L, 1); lua_pushlightuserdata(L, *pack);
lua_pushlightuserdata(L, (*pack)->data); lua_pushlightuserdata(L, (*pack)->data);
lua_pushunsigned(L, (*pack)->size); lua_pushunsigned(L, (*pack)->size);
return 3; return 3;
@@ -92,6 +92,8 @@ mc_unpacklocal(lua_State *L) {
/* /*
lightuserdata struct mc_package ** lightuserdata struct mc_package **
integer reference integer reference
return mc_package *
*/ */
static int static int
mc_bindrefer(lua_State *L) { mc_bindrefer(lua_State *L) {
@@ -102,16 +104,17 @@ mc_bindrefer(lua_State *L) {
} }
(*pack)->reference = ref; (*pack)->reference = ref;
return 0; lua_pushlightuserdata(L, *pack);
return 1;
} }
/* /*
lightuserdata struct mc_package ** lightuserdata struct mc_package *
*/ */
static int static int
mc_closelocal(lua_State *L) { mc_closelocal(lua_State *L) {
struct mc_package **ptr = lua_touserdata(L,1); struct mc_package *pack = lua_touserdata(L,1);
struct mc_package *pack = *ptr;
int ref = __sync_sub_and_fetch(&pack->reference, 1); int ref = __sync_sub_and_fetch(&pack->reference, 1);
if (ref <= 0) { if (ref <= 0) {

View File

@@ -68,18 +68,20 @@ end
local function publish(c , source, pack, size) local function publish(c , source, pack, size)
local group = channel[c] local group = channel[c]
if group == nil then if group == nil then
-- dead channel, delete the pack -- dead channel, delete the pack. mc.bind returns the pointer in pack
mc.bind(pack, 1) local pack = mc.bind(pack, 1)
mc.close(pack) mc.close(pack)
return return
end end
mc.bind(pack, channel_n[c]) mc.bind(pack, channel_n[c])
local msg = skynet.tostring(pack, size) local msg = skynet.tostring(pack, size)
for k in pairs(group) do for k in pairs(group) do
-- the msg is a pointer to the real message, publish pointer in local is ok.
skynet.redirect(k, source, "multicast", c , msg) skynet.redirect(k, source, "multicast", c , msg)
end end
local remote = channel_remote[c] local remote = channel_remote[c]
if remote then if remote then
-- remote publish should unpack the pack, because we should not publish the pointer out.
local _, msg, sz = mc.unpack(pack, size) local _, msg, sz = mc.unpack(pack, size)
local msg = skynet.tostring(msg,sz) local msg = skynet.tostring(msg,sz)
for node in pairs(remote) do for node in pairs(remote) do