From 48f6d42264e47206b938431894c3a95f830377b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=91=E9=A3=8E?= Date: Mon, 16 Dec 2013 11:05:49 +0800 Subject: [PATCH] remove feature: remote object. Issue #58 --- Makefile | 2 +- lualib-src/lua-remoteobj.c | 156 ------------------------------------- lualib-src/lua-seri.c | 29 +------ lualib-src/lua-skynet.c | 17 +--- lualib/skynet.lua | 81 ------------------- service/main.lua | 1 - service/remote_root.lua | 21 ----- service/testrobj.lua | 23 ------ 8 files changed, 7 insertions(+), 323 deletions(-) delete mode 100644 lualib-src/lua-remoteobj.c delete mode 100644 service/remote_root.lua delete mode 100644 service/testrobj.lua diff --git a/Makefile b/Makefile index 51d9de98..f8ae90d5 100644 --- a/Makefile +++ b/Makefile @@ -80,7 +80,7 @@ service/gate.so : service-src/service_gate.c service/localcast.so : service-src/service_localcast.c gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src -luaclib/skynet.so : lualib-src/lua-skynet.c lualib-src/lua-seri.c lualib-src/lua-remoteobj.c lualib-src/trace_service.c | luaclib +luaclib/skynet.so : lualib-src/lua-skynet.c lualib-src/lua-seri.c lualib-src/trace_service.c | luaclib gcc $(CFLAGS) $(SHARED) -Iluacompat $^ -o $@ -Iskynet-src -Iservice-src -Ilualib-src service/client.so : service-src/service_client.c diff --git a/lualib-src/lua-remoteobj.c b/lualib-src/lua-remoteobj.c deleted file mode 100644 index 21610734..00000000 --- a/lualib-src/lua-remoteobj.c +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include -#include "luacompat52.h" - -#include -#include -#include - -#define MAX_REMOTE_OBJECT 0x40000 - -struct remote_address { - int handle; - uint32_t address; -}; - -struct remote_objects { - int handle_index; - struct remote_address addr[MAX_REMOTE_OBJECT]; -}; - -static struct remote_objects * _R = NULL; - -static struct remote_objects * -_create() { - struct remote_objects * r = malloc(sizeof(*r)); - r->handle_index = 0; - memset(r, 0, sizeof(*r)); - r->addr[0].address = 0xffffffff; - return r; -} - -static void -_remove(struct remote_objects *r, uint32_t address) { - int i; - for (i=0;iaddr[i].address == address) { - r->addr[i].address = 0; - } - } -} - -static int -_alloc(struct remote_objects *r, uint32_t address) { - int i = 0; - for (i=0;ihandle_index, 1); - struct remote_address * slot = r->addr + handle % MAX_REMOTE_OBJECT; - if (slot->address == 0) { - if (__sync_bool_compare_and_swap(&slot->address, 0, address)) { - slot->handle = handle; - return handle; - } - } - } - - return -1; -} - -static int -_bind(struct remote_objects *r, int handle, uint32_t address) { - struct remote_address * slot = r->addr + handle % MAX_REMOTE_OBJECT; - if (slot->handle != handle) { - return 0; - } - for (;;) { - uint32_t old = slot->address; - if (__sync_bool_compare_and_swap(&slot->address, old, address)) { - return old; - } - } -} - -static uint32_t -_query(struct remote_objects *r, int handle) { - struct remote_address * slot = r->addr + handle % MAX_REMOTE_OBJECT; - if (slot->handle == handle) { - return slot->address; - } - return 0; -} - -static int -lbind(lua_State *L) { - uint32_t addr = lua_tounsigned(L,lua_upvalueindex(1)); - int handle = luaL_checkinteger(L,1); - uint32_t old = _bind(_R, handle, addr); - if (old == 0) { - luaL_error(L, "handle %d is not exist", handle); - } - lua_pushnumber(L, old); - return 1; -} - -static int -lremove(lua_State *L) { - uint32_t * addr = lua_touserdata(L,1); - _remove(_R, *addr); - return 0; -} - -static int -lalloc(lua_State *L) { - uint32_t addr = lua_tounsigned(L,lua_upvalueindex(1)); - int handle = _alloc(_R, addr); - if (handle < 0) { - return luaL_error(L, "Too many remote object"); - } - lua_pushinteger(L,handle); - return 1; -} - -static int -lquery(lua_State *L) { - int handle = luaL_checkinteger(L,1); - uint32_t addr = _query(_R, handle); - if (addr == 0) { - return 0; - } - lua_pushnumber(L, addr); - return 1; -} - -int -remoteobj_init(lua_State *L) { - if (_R == NULL) { - struct remote_objects * r = _create(); - if (!__sync_bool_compare_and_swap(&_R, NULL, r)) { - free(r); - } - } - - uint32_t address = luaL_checkunsigned(L, -1); - lua_pushcfunction(L, lquery); - lua_pushnumber(L, address); - - uint32_t * addr = lua_newuserdata(L, sizeof(*addr)); - *addr = address; - lua_createtable(L, 0, 1); - lua_pushcfunction(L, lremove); - lua_setfield(L, -2, "__gc"); - lua_setmetatable(L,-2); - - lua_pushcclosure(L, lalloc, 2); - lua_pushnumber(L, address); - lua_pushcclosure(L, lbind, 1); - - return 3; -} - - - - - - - - diff --git a/lualib-src/lua-seri.c b/lualib-src/lua-seri.c index a8ace5d0..23413cf5 100644 --- a/lualib-src/lua-seri.c +++ b/lualib-src/lua-seri.c @@ -20,7 +20,6 @@ // hibits 0~31 : len #define TYPE_LONG_STRING 5 #define TYPE_TABLE 6 -#define TYPE_REMOTE 7 #define MAX_COOKIE 32 #define COMBINE_TYPE(t,v) ((t) | (v) << 3) @@ -360,16 +359,7 @@ _pack_one(lua_State *L, struct write_block *b, int index, int depth) { if (index < 0) { index = lua_gettop(L) + index + 1; } - lua_pushvalue(L, lua_upvalueindex(2)); // __remote - lua_rawget(L, index); - if (lua_isnumber(L,-1)) { - int handle = lua_tointeger(L,-1); - lua_pop(L,1); - wb_integer(b, handle, TYPE_REMOTE); - } else { - lua_pop(L,1); - wb_table(L, b, index, depth+1); - } + wb_table(L, b, index, depth+1); break; } default: @@ -531,21 +521,8 @@ _push_value(lua_State *L, struct read_block *rb, int type, int cookie) { _unpack_table(L,rb,cookie); break; } - case TYPE_REMOTE: { - lua_pushvalue(L,lua_upvalueindex(1)); // metatable - int handle = _get_integer(L,rb,cookie); - lua_rawgeti(L,-1,handle); - if (lua_isnil(L,-1)) { - lua_pop(L,2); - lua_createtable(L,0,1); - lua_pushvalue(L,lua_upvalueindex(2)); // __remote - lua_pushinteger(L,handle); - lua_rawset(L,-3); - lua_pushvalue(L,lua_upvalueindex(1)); // metatable - lua_setmetatable(L,-2); - } else { - lua_replace(L, -2); - } + default: { + _invalid_stream(L,rb); break; } } diff --git a/lualib-src/lua-skynet.c b/lualib-src/lua-skynet.c index 4e23233d..1b086078 100644 --- a/lualib-src/lua-skynet.c +++ b/lualib-src/lua-skynet.c @@ -454,19 +454,10 @@ _reload(lua_State *L) { return 0; } -// define in lua-remoteobj.c -int remoteobj_init(lua_State *L); - int luaopen_skynet_c(lua_State *L) { luaL_checkversion(L); - luaL_Reg pack[] = { - { "pack", _luaseri_pack }, - { "unpack", _luaseri_unpack }, - { NULL, NULL }, - }; - luaL_Reg l[] = { { "send" , _send }, { "genid", _genid }, @@ -477,12 +468,13 @@ luaopen_skynet_c(lua_State *L) { { "tostring", _tostring }, { "harbor", _harbor }, { "context", _context }, + { "pack", _luaseri_pack }, + { "unpack", _luaseri_unpack }, { NULL, NULL }, }; luaL_Reg l2[] = { { "stat", _stat }, - { "remote_init", remoteobj_init }, { "trace_new", _trace_new }, { "trace_delete", _trace_delete }, { "trace_switch", _trace_switch }, @@ -491,10 +483,7 @@ luaopen_skynet_c(lua_State *L) { { NULL, NULL }, }; - lua_createtable(L, 0, (sizeof(pack) + sizeof(l) + sizeof(l2))/sizeof(luaL_Reg)-1); - lua_newtable(L); - lua_pushstring(L,"__remote"); - luaL_setfuncs(L,pack,2); + lua_createtable(L, 0, (sizeof(l) + sizeof(l2))/sizeof(luaL_Reg)-1); lua_getfield(L, LUA_REGISTRYINDEX, "skynet_lua"); struct snlua *lua = lua_touserdata(L,-1); diff --git a/lualib/skynet.lua b/lualib/skynet.lua index eb549f56..2756fefd 100644 --- a/lualib/skynet.lua +++ b/lualib/skynet.lua @@ -481,87 +481,6 @@ function skynet.harbor(addr) return c.harbor(addr) end ------- remote object -------- - -do - -- proto is 11 - - local remote_query, remote_alloc, remote_bind = c.remote_init(skynet.self()) - local weak_meta = { __mode = "kv" } - local meta = getmetatable(c.unpack(c.pack({ __remote = 0 }))) - local remote_call_func = setmetatable({}, weak_meta) - - local _send = assert(c.send) - local _pack = assert(c.pack) - local _unpack = assert(c.unpack) - local _local = skynet.self() - - function meta__index(t, method) - local f = remote_call_func[method] - if f == nil then - f = function(...) - local addr = remote_query(t.__remote) - -- the proto is 11 (lua is 10) - local session = assert(_send(addr, 11 , nil, _pack(t,method,...)), "call to invalid address") - local succ, msg, sz = coroutine_yield("CALL", session) - if succ then - return select(2,assert(_unpack(msg,sz))) - else - error "call to dead remote object" - end - end - remote_call_func[method] = f - end - rawset(t,method,f) - return f - end - - -- prevent gc - meta.__index = meta__index - - meta.__newindex = error - - function skynet.remote_create(t, handle) - t = t or {} - if handle then - remote_bind(handle) - else - handle = remote_alloc() - end - rawset(t, "__remote" , handle) - rawset(meta, handle, t) - return t - end - - function skynet.remote_bind(handle) - return setmetatable( { __remote = handle } , meta) - end - - local function remote_call(obj, method, ...) - if type(obj) ~= "table" or type(method) ~= "string" then - return coroutine_yield("RETURN", _pack(false, "Invalid call")) - end - local f = obj[method] - if type(f) ~= "function" then - return coroutine_yield("RETURN", _pack(false, "Object has not method " .. method)) - end - return coroutine_yield("RETURN", _pack(pcall(f,...))) - end - - function skynet.remote_root() - return skynet.remote_bind(0) - end - - skynet.register_protocol { - name = "remoteobj", - id = 11, - unpack = c.unpack, - dispatch = function (session, source, ...) - remote_call(...) - end - } -end - ----- debug local internal_info_func diff --git a/service/main.lua b/service/main.lua index d68ab888..a8e0e297 100644 --- a/service/main.lua +++ b/service/main.lua @@ -6,7 +6,6 @@ skynet.start(function() skynet.monitor "simplemonitor" local lualog = skynet.newservice("lualog") local console = skynet.newservice("console") - local remoteroot = skynet.newservice("remote_root") local watchdog = skynet.newservice("watchdog","8888 4 0") local db = skynet.newservice("simpledb") -- skynet.launch("snlua","testgroup") diff --git a/service/remote_root.lua b/service/remote_root.lua deleted file mode 100644 index dcbfc2b3..00000000 --- a/service/remote_root.lua +++ /dev/null @@ -1,21 +0,0 @@ -local skynet = require "skynet" - -local service = {} -local root = {} - -function root.register(name, obj) - service[name] = obj -end - -function root.query(name) - return service[name] -end - -function root.echo(hello) - return hello -end - -skynet.remote_create(root,0) - -skynet.start(function() end) - diff --git a/service/testrobj.lua b/service/testrobj.lua deleted file mode 100644 index 1f69f530..00000000 --- a/service/testrobj.lua +++ /dev/null @@ -1,23 +0,0 @@ -local skynet = require "skynet" - -local obj = { id = 0 } - -function obj.hello() - return "Hello" -end - -function obj:inc() - self.id = self.id + 1 - return self.id -end - -skynet.start(function() - skynet.remote_create(obj) - local root = skynet.remote_root() - print(root.echo("hello")) - root.register("test",obj) - local qobj = root.query "test" - print(qobj.hello()) - print(qobj:inc()) - skynet.exit() -end)