mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-25 12:43:09 +00:00
remote object
This commit is contained in:
4
Makefile
4
Makefile
@@ -48,8 +48,8 @@ service/snlua.so : service-src/service_lua.c
|
|||||||
service/gate.so : gate/mread.c gate/ringbuffer.c gate/main.c
|
service/gate.so : gate/mread.c gate/ringbuffer.c gate/main.c
|
||||||
gcc $(CFLAGS) $(SHARED) $^ -o $@ -Igate -Iskynet-src
|
gcc $(CFLAGS) $(SHARED) $^ -o $@ -Igate -Iskynet-src
|
||||||
|
|
||||||
lualib/skynet.so : lualib-src/lua-skynet.c lua-serialize/serialize.c
|
lualib/skynet.so : lualib-src/lua-skynet.c lualib-src/lua-seri.c lualib-src/lua-remoteobj.c
|
||||||
gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src -Ilua-serialize
|
gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src
|
||||||
|
|
||||||
service/client.so : service-src/service_client.c
|
service/client.so : service-src/service_client.c
|
||||||
gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src
|
gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
all : luaseri.so
|
|
||||||
|
|
||||||
luaseri.so : serialize.c
|
|
||||||
gcc -Wall -fPIC -O2 -D LUAMODULE -o $@ --shared $^
|
|
||||||
|
|
||||||
clean :
|
|
||||||
rm luaseri.so
|
|
||||||
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
see https://github.com/cloudwu/lua-serialize
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
s = require "luaseri"
|
|
||||||
|
|
||||||
a = s.pack { hello={3,4}, false, 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9 }
|
|
||||||
|
|
||||||
s.dump(a)
|
|
||||||
|
|
||||||
a = s.append(a, 42,4.2,-1,1000,80000,"hello",true,false,nil,"1234567890123456789012345678901234567890")
|
|
||||||
|
|
||||||
s.dump(a)
|
|
||||||
print(a)
|
|
||||||
|
|
||||||
function pr(t,...)
|
|
||||||
for k,v in pairs(t) do
|
|
||||||
print(k,v)
|
|
||||||
end
|
|
||||||
print(...)
|
|
||||||
end
|
|
||||||
|
|
||||||
print ("------")
|
|
||||||
|
|
||||||
local seri, length = s.serialize(a)
|
|
||||||
print(seri, length)
|
|
||||||
|
|
||||||
pr(s.unpack(a))
|
|
||||||
|
|
||||||
print("-------")
|
|
||||||
|
|
||||||
pr(s.deserialize(seri, length))
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
local s = require "luaseri"
|
|
||||||
|
|
||||||
addressbook = {
|
|
||||||
name = "Alice",
|
|
||||||
id = 12345,
|
|
||||||
phone = {
|
|
||||||
{ number = "1301234567" },
|
|
||||||
{ number = "87654321", type = "WORK" },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i=1,100000 do
|
|
||||||
local u = s.pack (addressbook)
|
|
||||||
local t = s.unpack(u)
|
|
||||||
end
|
|
||||||
180
lualib-src/lua-remoteobj.c
Normal file
180
lualib-src/lua-remoteobj.c
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
#include <lua.h>
|
||||||
|
#include <lauxlib.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#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;i<MAX_REMOTE_OBJECT;i++) {
|
||||||
|
if (r->addr[i].address == address) {
|
||||||
|
r->addr[i].address = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_alloc(struct remote_objects *r, uint32_t address) {
|
||||||
|
int i = 0;
|
||||||
|
for (i=0;i<MAX_REMOTE_OBJECT;i++) {
|
||||||
|
int handle = __sync_add_and_fetch(&r->handle_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 uint32_t
|
||||||
|
_getaddr(lua_State *L, int index) {
|
||||||
|
size_t sz;
|
||||||
|
const char * addr = luaL_checklstring(L,index,&sz);
|
||||||
|
if (addr[0] != ':') {
|
||||||
|
luaL_error(L, "Invalid address %s",addr);
|
||||||
|
}
|
||||||
|
return strtoul(addr+1, NULL, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_id_to_hex(char * str, uint32_t id) {
|
||||||
|
int i;
|
||||||
|
static char hex[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
|
||||||
|
str[0] = ':';
|
||||||
|
for (i=0;i<8;i++) {
|
||||||
|
str[i+1] = hex[(id >> ((7-i) * 4))&0xf];
|
||||||
|
}
|
||||||
|
str[9] = '\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);
|
||||||
|
}
|
||||||
|
char tmp[10];
|
||||||
|
_id_to_hex(tmp, old);
|
||||||
|
lua_pushlstring(L,tmp,9);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
char tmp[10];
|
||||||
|
_id_to_hex(tmp, addr);
|
||||||
|
lua_pushlstring(L,tmp,9);
|
||||||
|
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 = _getaddr(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
|
/*
|
||||||
|
https://github.com/cloudwu/lua-serialize
|
||||||
|
*/
|
||||||
|
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -15,6 +19,7 @@
|
|||||||
// hibits 0~31 : len
|
// hibits 0~31 : len
|
||||||
#define TYPE_LONG_STRING 5
|
#define TYPE_LONG_STRING 5
|
||||||
#define TYPE_TABLE 6
|
#define TYPE_TABLE 6
|
||||||
|
#define TYPE_REMOTE 7
|
||||||
|
|
||||||
#define MAX_COOKIE 32
|
#define MAX_COOKIE 32
|
||||||
#define COMBINE_TYPE(t,v) ((t) | (v) << 3)
|
#define COMBINE_TYPE(t,v) ((t) | (v) << 3)
|
||||||
@@ -123,20 +128,6 @@ rball_init(struct read_block * rb, char * buffer, int size) {
|
|||||||
rb->ptr = 0;
|
rb->ptr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LUAMODULE
|
|
||||||
|
|
||||||
static int
|
|
||||||
rb_init(struct read_block *rb, struct block *b) {
|
|
||||||
rb->buffer = NULL;
|
|
||||||
rb->current = b;
|
|
||||||
memcpy(&(rb->len),b->buffer,sizeof(rb->len));
|
|
||||||
rb->ptr = sizeof(rb->len);
|
|
||||||
rb->len -= rb->ptr;
|
|
||||||
return rb->len;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
rb_read(struct read_block *rb, void *buffer, int sz) {
|
rb_read(struct read_block *rb, void *buffer, int sz) {
|
||||||
if (rb->len < sz) {
|
if (rb->len < sz) {
|
||||||
@@ -215,26 +206,26 @@ wb_boolean(struct write_block *wb, int boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
wb_integer(struct write_block *wb, int v) {
|
wb_integer(struct write_block *wb, int v, int type) {
|
||||||
if (v == 0) {
|
if (v == 0) {
|
||||||
int n = COMBINE_TYPE(TYPE_NUMBER , 0);
|
int n = COMBINE_TYPE(type , 0);
|
||||||
wb_push(wb, &n, 1);
|
wb_push(wb, &n, 1);
|
||||||
} else if (v<0) {
|
} else if (v<0) {
|
||||||
int n = COMBINE_TYPE(TYPE_NUMBER , 4);
|
int n = COMBINE_TYPE(type , 4);
|
||||||
wb_push(wb, &n, 1);
|
wb_push(wb, &n, 1);
|
||||||
wb_push(wb, &v, 4);
|
wb_push(wb, &v, 4);
|
||||||
} else if (v<0x100) {
|
} else if (v<0x100) {
|
||||||
int n = COMBINE_TYPE(TYPE_NUMBER , 1);
|
int n = COMBINE_TYPE(type , 1);
|
||||||
wb_push(wb, &n, 1);
|
wb_push(wb, &n, 1);
|
||||||
uint8_t byte = (uint8_t)v;
|
uint8_t byte = (uint8_t)v;
|
||||||
wb_push(wb, &byte, 1);
|
wb_push(wb, &byte, 1);
|
||||||
} else if (v<0x10000) {
|
} else if (v<0x10000) {
|
||||||
int n = COMBINE_TYPE(TYPE_NUMBER , 2);
|
int n = COMBINE_TYPE(type , 2);
|
||||||
wb_push(wb, &n, 1);
|
wb_push(wb, &n, 1);
|
||||||
uint16_t word = (uint16_t)v;
|
uint16_t word = (uint16_t)v;
|
||||||
wb_push(wb, &word, 2);
|
wb_push(wb, &word, 2);
|
||||||
} else {
|
} else {
|
||||||
int n = COMBINE_TYPE(TYPE_NUMBER , 4);
|
int n = COMBINE_TYPE(type , 4);
|
||||||
wb_push(wb, &n, 1);
|
wb_push(wb, &n, 1);
|
||||||
wb_push(wb, &v, 4);
|
wb_push(wb, &v, 4);
|
||||||
}
|
}
|
||||||
@@ -280,7 +271,7 @@ wb_table_array(lua_State *L, struct write_block * wb, int index, int depth) {
|
|||||||
if (array_size > MAX_COOKIE-1) {
|
if (array_size > MAX_COOKIE-1) {
|
||||||
int n = COMBINE_TYPE(TYPE_TABLE, MAX_COOKIE-1);
|
int n = COMBINE_TYPE(TYPE_TABLE, MAX_COOKIE-1);
|
||||||
wb_push(wb, &n, 1);
|
wb_push(wb, &n, 1);
|
||||||
wb_integer(wb, array_size);
|
wb_integer(wb, array_size,TYPE_NUMBER);
|
||||||
} else {
|
} else {
|
||||||
int n = COMBINE_TYPE(TYPE_TABLE, array_size);
|
int n = COMBINE_TYPE(TYPE_TABLE, array_size);
|
||||||
wb_push(wb, &n, 1);
|
wb_push(wb, &n, 1);
|
||||||
@@ -339,7 +330,7 @@ _pack_one(lua_State *L, struct write_block *b, int index, int depth) {
|
|||||||
lua_Integer x = lua_tointeger(L,index);
|
lua_Integer x = lua_tointeger(L,index);
|
||||||
lua_Number n = lua_tonumber(L,index);
|
lua_Number n = lua_tonumber(L,index);
|
||||||
if ((lua_Number)x==n) {
|
if ((lua_Number)x==n) {
|
||||||
wb_integer(b, x);
|
wb_integer(b, x, TYPE_NUMBER);
|
||||||
} else {
|
} else {
|
||||||
wb_number(b,n);
|
wb_number(b,n);
|
||||||
}
|
}
|
||||||
@@ -361,9 +352,21 @@ _pack_one(lua_State *L, struct write_block *b, int index, int depth) {
|
|||||||
case LUA_TLIGHTUSERDATA:
|
case LUA_TLIGHTUSERDATA:
|
||||||
wb_pointer(b, lua_touserdata(L,index));
|
wb_pointer(b, lua_touserdata(L,index));
|
||||||
break;
|
break;
|
||||||
case LUA_TTABLE:
|
case LUA_TTABLE: {
|
||||||
|
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 {
|
||||||
wb_table(L, b, index, depth+1);
|
wb_table(L, b, index, depth+1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
wb_free(b);
|
wb_free(b);
|
||||||
luaL_error(L, "Unsupport type %s to serialize", lua_typename(L, type));
|
luaL_error(L, "Unsupport type %s to serialize", lua_typename(L, type));
|
||||||
@@ -379,30 +382,6 @@ _pack_from(lua_State *L, struct write_block *b, int from) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LUAMODULE
|
|
||||||
|
|
||||||
static int
|
|
||||||
_pack(lua_State *L) {
|
|
||||||
struct write_block b;
|
|
||||||
wb_init(&b, NULL);
|
|
||||||
_pack_from(L,&b,0);
|
|
||||||
struct block * ret = wb_close(&b);
|
|
||||||
lua_pushlightuserdata(L,ret);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
_append(lua_State *L) {
|
|
||||||
struct write_block b;
|
|
||||||
wb_init(&b, lua_touserdata(L,1));
|
|
||||||
_pack_from(L,&b,1);
|
|
||||||
struct block * ret = wb_close(&b);
|
|
||||||
lua_pushlightuserdata(L,ret);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
__invalid_stream(lua_State *L, struct read_block *rb, int line) {
|
__invalid_stream(lua_State *L, struct read_block *rb, int line) {
|
||||||
int len = rb->len;
|
int len = rb->len;
|
||||||
@@ -414,8 +393,8 @@ __invalid_stream(lua_State *L, struct read_block *rb, int line) {
|
|||||||
|
|
||||||
#define _invalid_stream(L,rb) __invalid_stream(L,rb,__LINE__)
|
#define _invalid_stream(L,rb) __invalid_stream(L,rb,__LINE__)
|
||||||
|
|
||||||
static double
|
static int
|
||||||
_get_number(lua_State *L, struct read_block *rb, int cookie) {
|
_get_integer(lua_State *L, struct read_block *rb, int cookie) {
|
||||||
switch (cookie) {
|
switch (cookie) {
|
||||||
case 0:
|
case 0:
|
||||||
return 0;
|
return 0;
|
||||||
@@ -440,16 +419,22 @@ _get_number(lua_State *L, struct read_block *rb, int cookie) {
|
|||||||
_invalid_stream(L,rb);
|
_invalid_stream(L,rb);
|
||||||
return *pn;
|
return *pn;
|
||||||
}
|
}
|
||||||
case 8: {
|
default:
|
||||||
|
_invalid_stream(L,rb);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static double
|
||||||
|
_get_number(lua_State *L, struct read_block *rb, int cookie) {
|
||||||
|
if (cookie == 8) {
|
||||||
double n = 0;
|
double n = 0;
|
||||||
double * pn = rb_read(rb,&n,8);
|
double * pn = rb_read(rb,&n,8);
|
||||||
if (pn == NULL)
|
if (pn == NULL)
|
||||||
_invalid_stream(L,rb);
|
_invalid_stream(L,rb);
|
||||||
return *pn;
|
return *pn;
|
||||||
}
|
} else {
|
||||||
default:
|
return (double)_get_integer(L,rb,cookie);
|
||||||
_invalid_stream(L,rb);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -530,6 +515,23 @@ _push_value(lua_State *L, struct read_block *rb, int type, int cookie) {
|
|||||||
_unpack_table(L,rb,cookie);
|
_unpack_table(L,rb,cookie);
|
||||||
break;
|
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);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,65 +545,6 @@ _unpack_one(lua_State *L, struct read_block *rb) {
|
|||||||
_push_value(L, rb, *t & 0x7, *t>>3);
|
_push_value(L, rb, *t & 0x7, *t>>3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LUAMODULE
|
|
||||||
|
|
||||||
static int
|
|
||||||
_unpack(lua_State *L) {
|
|
||||||
struct block * blk = lua_touserdata(L,1);
|
|
||||||
if (blk == NULL) {
|
|
||||||
return luaL_error(L, "Need a block to unpack");
|
|
||||||
}
|
|
||||||
lua_settop(L,0);
|
|
||||||
struct read_block rb;
|
|
||||||
rb_init(&rb, blk);
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for (i=0;;i++) {
|
|
||||||
if (i%16==15) {
|
|
||||||
lua_checkstack(L,i);
|
|
||||||
}
|
|
||||||
uint8_t type = 0;
|
|
||||||
uint8_t *t = rb_read(&rb, &type, 1);
|
|
||||||
if (t==NULL)
|
|
||||||
break;
|
|
||||||
_push_value(L, &rb, *t & 0x7, *t>>3);
|
|
||||||
}
|
|
||||||
|
|
||||||
rb_close(&rb);
|
|
||||||
|
|
||||||
return lua_gettop(L);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
_dump_mem(const char * buffer, int len, int size) {
|
|
||||||
int i;
|
|
||||||
for (i=0;i<len && i<size;i++) {
|
|
||||||
printf("%02x ",(unsigned char)buffer[i]);
|
|
||||||
}
|
|
||||||
return size - len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
_dump(lua_State *L) {
|
|
||||||
struct block *b = lua_touserdata(L,1);
|
|
||||||
if (b==NULL) {
|
|
||||||
return luaL_error(L, "dump null pointer");
|
|
||||||
}
|
|
||||||
int len = 0;
|
|
||||||
memcpy(&len, b->buffer ,sizeof(len));
|
|
||||||
len -= sizeof(len);
|
|
||||||
printf("Len = %d\n",len);
|
|
||||||
len = _dump_mem(b->buffer + sizeof(len), BLOCK_SIZE - sizeof(len) , len);
|
|
||||||
while (len > 0) {
|
|
||||||
b=b->next;
|
|
||||||
len = _dump_mem(b->buffer, BLOCK_SIZE , len);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_seri(lua_State *L, struct block *b) {
|
_seri(lua_State *L, struct block *b) {
|
||||||
uint32_t len = 0;
|
uint32_t len = 0;
|
||||||
@@ -636,22 +579,6 @@ _seri(lua_State *L, struct block *b) {
|
|||||||
lua_pushinteger(L, sz);
|
lua_pushinteger(L, sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LUAMODULE
|
|
||||||
|
|
||||||
static int
|
|
||||||
_serialize(lua_State *L) {
|
|
||||||
struct block *b = lua_touserdata(L,1);
|
|
||||||
if (b==NULL) {
|
|
||||||
return luaL_error(L, "dump null pointer");
|
|
||||||
}
|
|
||||||
|
|
||||||
_seri(L,b);
|
|
||||||
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
int
|
||||||
_luaseri_unpack(lua_State *L) {
|
_luaseri_unpack(lua_State *L) {
|
||||||
if (lua_isnoneornil(L,1)) {
|
if (lua_isnoneornil(L,1)) {
|
||||||
@@ -700,22 +627,3 @@ _luaseri_pack(lua_State *L) {
|
|||||||
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LUAMODULE
|
|
||||||
|
|
||||||
int
|
|
||||||
luaopen_luaseri(lua_State *L) {
|
|
||||||
luaL_Reg l[] = {
|
|
||||||
{ "pack", _pack },
|
|
||||||
{ "unpack", _unpack },
|
|
||||||
{ "append", _append },
|
|
||||||
{ "serialize", _serialize },
|
|
||||||
{ "deserialize", _luaseri_unpack },
|
|
||||||
{ "dump", _dump },
|
|
||||||
{ NULL, NULL },
|
|
||||||
};
|
|
||||||
luaL_newlib(L,l);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "skynet.h"
|
#include "skynet.h"
|
||||||
#include "luaseri.h"
|
#include "lua-seri.h"
|
||||||
|
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
@@ -184,9 +184,19 @@ _tostring(lua_State *L) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// define in lua-remoteobj.c
|
||||||
|
int remoteobj_init(lua_State *L);
|
||||||
|
|
||||||
int
|
int
|
||||||
luaopen_skynet_c(lua_State *L) {
|
luaopen_skynet_c(lua_State *L) {
|
||||||
luaL_checkversion(L);
|
luaL_checkversion(L);
|
||||||
|
|
||||||
|
luaL_Reg pack[] = {
|
||||||
|
{ "pack", _luaseri_pack },
|
||||||
|
{ "unpack", _luaseri_unpack },
|
||||||
|
{ NULL, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
luaL_Reg l[] = {
|
luaL_Reg l[] = {
|
||||||
{ "send" , _send },
|
{ "send" , _send },
|
||||||
{ "genid", _genid },
|
{ "genid", _genid },
|
||||||
@@ -195,11 +205,13 @@ luaopen_skynet_c(lua_State *L) {
|
|||||||
{ "callback" , _callback },
|
{ "callback" , _callback },
|
||||||
{ "error", _error },
|
{ "error", _error },
|
||||||
{ "tostring", _tostring },
|
{ "tostring", _tostring },
|
||||||
{ "pack", _luaseri_pack },
|
|
||||||
{ "unpack", _luaseri_unpack },
|
|
||||||
{ NULL, NULL },
|
{ NULL, NULL },
|
||||||
};
|
};
|
||||||
luaL_newlibtable(L,l);
|
|
||||||
|
lua_createtable(L, 0, (sizeof(pack) + sizeof(l))/sizeof(luaL_Reg)-2);
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_pushstring(L,"__remote");
|
||||||
|
luaL_setfuncs(L,pack,2);
|
||||||
|
|
||||||
lua_getfield(L, LUA_REGISTRYINDEX, "skynet_context");
|
lua_getfield(L, LUA_REGISTRYINDEX, "skynet_context");
|
||||||
struct skynet_context * ctx = lua_touserdata(L,-1);
|
struct skynet_context * ctx = lua_touserdata(L,-1);
|
||||||
@@ -209,5 +221,8 @@ luaopen_skynet_c(lua_State *L) {
|
|||||||
|
|
||||||
luaL_setfuncs(L,l,1);
|
luaL_setfuncs(L,l,1);
|
||||||
|
|
||||||
|
lua_pushcfunction(L, remoteobj_init);
|
||||||
|
lua_setfield(L, -2, "remote_init");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,4 +216,78 @@ function skynet.newservice(name, ...)
|
|||||||
return handle
|
return handle
|
||||||
end
|
end
|
||||||
|
|
||||||
|
------ remote object --------
|
||||||
|
|
||||||
|
do
|
||||||
|
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)
|
||||||
|
setmetatable(meta, weak_meta)
|
||||||
|
|
||||||
|
local _send = assert(c.send)
|
||||||
|
local _yield = coroutine.yield
|
||||||
|
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)
|
||||||
|
local session = _send(addr, -1, _pack(t,method,...))
|
||||||
|
local msg, sz = _yield("CALL", session)
|
||||||
|
return select(2,assert(_unpack(msg,sz)))
|
||||||
|
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 _yield("RETURN", _pack(false, "Invalid call"))
|
||||||
|
end
|
||||||
|
local f = obj[method]
|
||||||
|
if type(f) ~= "function" then
|
||||||
|
return _yield("RETURN", _pack(false, "Object has not method " .. method))
|
||||||
|
end
|
||||||
|
return _yield("RETURN", _pack(pcall(f,...)))
|
||||||
|
end
|
||||||
|
|
||||||
|
function skynet.remote_service(unknown)
|
||||||
|
local function f(msg,sz)
|
||||||
|
return remote_call(_unpack(msg,sz))
|
||||||
|
end
|
||||||
|
c.callback(default_dispatch(f,unknown))
|
||||||
|
end
|
||||||
|
|
||||||
|
function skynet.remote_root()
|
||||||
|
return skynet.remote_bind(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return skynet
|
return skynet
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ skynet.start(function()
|
|||||||
print("lualog",lualog)
|
print("lualog",lualog)
|
||||||
local launcher = skynet.launch("snlua","launcher")
|
local launcher = skynet.launch("snlua","launcher")
|
||||||
print("launcher", launcher)
|
print("launcher", launcher)
|
||||||
|
local remoteroot = skynet.launch("snlua","remote_root")
|
||||||
|
print("remoteroot", remoteroot)
|
||||||
local console = skynet.launch("snlua","console")
|
local console = skynet.launch("snlua","console")
|
||||||
print("console",console)
|
print("console",console)
|
||||||
local watchdog = skynet.launch("snlua","watchdog","8888 4 0")
|
local watchdog = skynet.launch("snlua","watchdog","8888 4 0")
|
||||||
|
|||||||
20
service/remote_root.lua
Normal file
20
service/remote_root.lua
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
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.remote_service()
|
||||||
24
service/testrobj.lua
Normal file
24
service/testrobj.lua
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
local skynet = require "skynet"
|
||||||
|
|
||||||
|
skynet.remote_service()
|
||||||
|
|
||||||
|
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())
|
||||||
|
end)
|
||||||
Reference in New Issue
Block a user