mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 20:23:06 +00:00
Bugfix: mc.close may reference an invalid pointer. See pr #220
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user