Compare commits

...

46 Commits

Author SHA1 Message Date
Cloud Wu
6c43e90708 release alpha6 2015-05-18 12:02:08 +08:00
云风
1f25b79722 Merge pull request #272 from antsmallant/patch-1
Update inject.lua
2015-05-15 17:04:27 +08:00
Cloud Wu
6a9080157f need require skynet.manager 2015-05-15 16:24:01 +08:00
antsmallant
5cc2ef3ac8 Update inject.lua
免得变量i污染全局空间
2015-05-15 15:59:47 +08:00
Cloud Wu
3baeb62b0b move some api from skynet.lua to skynet/manager.lua 2015-05-13 11:04:25 +08:00
Cloud Wu
9e27f59033 remove task overload warning 2015-05-13 09:50:53 +08:00
Cloud Wu
82fa2f979c skynet.exit will call every unresponse handle 2015-05-12 23:15:03 +08:00
Cloud Wu
07d7324332 Merge branch 'master' of github.com:cloudwu/skynet 2015-05-12 22:53:16 +08:00
Cloud Wu
d92adda2c9 If skynet.wakeup a skynet.call, raise an error 2015-05-12 22:53:03 +08:00
Cloud Wu
0587400e2d update sproto: handle empty protocol 2015-05-12 10:20:16 +08:00
Cloud Wu
35c8c63793 update sproto, bugfix sproto_dump 2015-05-11 21:39:56 +08:00
Cloud Wu
c7f5145e9e update sproto , add new api sproto:default 2015-05-11 18:20:17 +08:00
Cloud Wu
9452169f0a remove unused comment 2015-05-07 18:17:46 +08:00
云风
a15f43e0f8 Merge pull request #267 from gaopan461/master
fix:udp and udp_send
2015-05-07 18:18:36 +08:00
gaopan
0eb4754b31 @fix udp_address, in big-endian machine maybe error 2015-05-07 16:52:48 +08:00
gaopan
f987ff8199 fix:udp and udp_send 2015-05-07 15:25:47 +08:00
云风
64a5d1ca24 Merge pull request #266 from xiyanxiyan10/master
错误注释更正
2015-05-06 23:27:13 +08:00
xiyanxiyan10
fa17081012 错误注释更正 2015-05-06 23:13:06 +08:00
Cloud Wu
856cb0737d Merge branch 'master' of github.com:cloudwu/skynet 2015-05-02 20:47:29 +08:00
Cloud Wu
f61e3f46e8 fix issue #265 2015-05-02 20:47:15 +08:00
云风
6b6b943b73 Merge pull request #262 from flashjay/patch-3
fix: httpc.get
2015-04-29 22:19:31 +08:00
HuaYang Huang
75d9b07158 fix: httpc.get
:-(
此错误会导致httpc.get无法找到正确的虚拟主机
2015-04-29 20:18:13 +08:00
Cloud Wu
8682f7f82f response error when return/response package is too large 2015-04-27 16:23:12 +08:00
Cloud Wu
35a5b99bed release alpha5 2015-04-27 10:45:31 +08:00
Cloud Wu
98af25d109 better error log, see pr #260 2015-04-24 14:31:18 +08:00
Cloud Wu
cd3391461c add skynet.pcall for hotfix use (call a function with require) 2015-04-22 17:01:03 +08:00
Cloud Wu
e3b7f86075 cluster reload should reset old connection to update address:port 2015-04-21 15:35:29 +08:00
Cloud Wu
86d5865457 bugfix: wunlock first, and then release context. (may dead lock) 2015-04-18 21:11:57 +08:00
Cloud Wu
7b783076e5 use hmac_hash 2015-04-16 10:41:23 +08:00
Cloud Wu
57c0ad694c add hmac_hash to simplify hmac64(hashkey(d), key) 2015-04-16 10:35:47 +08:00
Cloud Wu
f55a31c24f sproto.request_decode returns name 2015-04-15 22:01:01 +08:00
Cloud Wu
843095afc6 add snax.printf 2015-04-15 16:52:55 +08:00
Cloud Wu
a6bad52181 add sproto new api 2015-04-14 23:38:49 +08:00
Cloud Wu
012d98380d merge lua bugfix from lua offical bugs page 2015-04-13 17:14:08 +08:00
Cloud Wu
0298997d23 release alpha 4 2015-04-13 13:04:39 +08:00
Cloud Wu
678a94bf71 update license 2015-04-10 11:35:47 +08:00
Cloud Wu
03399e86a9 udp api changed, callback recv the string 2015-04-09 12:49:40 +08:00
Cloud Wu
22364bac89 bugfix: memory leak 2015-04-09 12:14:28 +08:00
Cloud Wu
9188b5451c bugfix 1 , from http://www.lua.org/bugs.html#5.3.0-1 2015-04-09 11:55:07 +08:00
Cloud Wu
c7ed527911 add const to sproto C api 2015-04-08 11:42:06 +08:00
Cloud Wu
5a1132101b share sproto C struct 2015-04-08 11:23:52 +08:00
Cloud Wu
ca33bf8b3e bugfix sproto : support empty string 2015-04-05 20:19:30 +08:00
Cloud Wu
7d8c80c9a0 fix Issue #256 2015-04-03 11:07:11 +08:00
Cloud Wu
c6f993428e bugfix #257 2015-04-03 11:03:37 +08:00
云风
f6118b858d Merge pull request #255 from flashjay/patch-1
fix: httpc.post
2015-04-03 09:35:41 +08:00
HuaYang Huang
ec1bca238e fix: httpc.post
调用httpc.post时,如果没有在header里面设置host时有问题
2015-04-01 17:54:22 +08:00
45 changed files with 502 additions and 253 deletions

View File

@@ -94,6 +94,7 @@ typedef struct CallInfo {
#define CIST_YPCALL (1<<4) /* call is a yieldable protected call */
#define CIST_TAIL (1<<5) /* call was tail called */
#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */
#define CIST_LEQ (1<<7) /* using __lt for __le */
#define isLua(ci) ((ci)->callstatus & CIST_LUA)

View File

@@ -798,7 +798,8 @@ static int str_gsub (lua_State *L) {
*/
/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
#define MAX_ITEM 512
#define MAX_ITEM \
(sizeof(lua_Number) <= 4 ? 150 : sizeof(lua_Number) <= 8 ? 450 : 5050)
/* valid flags in a format specification */
#define FLAGS "-+ #0"

View File

@@ -303,12 +303,18 @@ int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
return l_strcmp(tsvalue(l), tsvalue(r)) <= 0;
else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* first try 'le' */
return res;
else if ((res = luaT_callorderTM(L, r, l, TM_LT)) < 0) /* else try 'lt' */
luaG_ordererror(L, l, r);
return !res;
else { /* try 'lt': */
L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */
res = luaT_callorderTM(L, r, l, TM_LT);
L->ci->callstatus ^= CIST_LEQ; /* clear mark */
if (res < 0)
luaG_ordererror(L, l, r);
return !res; /* result is negated */
}
}
/*
** Main operation for equality of Lua values; return 't1 == t2'.
** L == NULL means raw equality (no metamethods)
@@ -564,11 +570,11 @@ void luaV_finishOp (lua_State *L) {
case OP_LE: case OP_LT: case OP_EQ: {
int res = !l_isfalse(L->top - 1);
L->top--;
/* metamethod should not be called when operand is K */
lua_assert(!ISK(GETARG_B(inst)));
if (op == OP_LE && /* "<=" using "<" instead? */
ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE)))
res = !res; /* invert result */
if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */
lua_assert(op == OP_LE);
ci->callstatus ^= CIST_LEQ; /* clear mark */
res = !res; /* negate result */
}
lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
if (res != GETARG_A(inst)) /* condition failed? */
ci->u.l.savedpc++; /* skip jump instruction */

View File

@@ -1,3 +1,31 @@
v1.0.0-alpha6 (2015-5-18)
-----------
* bugfix: httpc.get
* bugfix: seri lib stack overflow
* bugfix: udp send
* bugfix: udp address
* bugfix: sproto dump
* add: sproto default
* improve: skynet.wakeup (can wakeup skynet.call by raise an error)
* improve: skynet.exit (raise error when uncall response)
* remove: task overload warning
* move: some skynet api move into skynet.manager
v1.0.0-alpha5 (2015-4-27)
-----------
* merge lua 5.3 offical bugfix
* improve sproto rpc api
* fix a deadlock bug when service retire
* improve cluster config reload
* add skynet.pcall for calling a function with `require`
* better error log in loginserver
v1.0.0-alpha4 (2015-4-13)
-----------
* sproto can share c struct between states
* udp api changed (use lua string now)
* fix memory leak in dns module
v1.0.0-alpha3 (2015-3-30)
-----------
* Update sproto (bugfix)

View File

@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2012-2014 codingnow.com
Copyright (c) 2012-2015 codingnow.com
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in

View File

@@ -1,3 +1,4 @@
local skynet = require "skynet"
require "skynet.manager" -- import skynet.abort
skynet.abort()

View File

@@ -1,10 +1,14 @@
local skynet = require "skynet"
local cluster = require "cluster"
require "skynet.manager" -- import skynet.name
skynet.start(function()
local sdb = skynet.newservice("simpledb")
skynet.name(".simpledb", sdb)
print(skynet.call(".simpledb", "lua", "SET", "a", "foobar"))
print(skynet.call(".simpledb", "lua", "SET", "b", "foobar2"))
print(skynet.call(".simpledb", "lua", "GET", "a"))
print(skynet.call(".simpledb", "lua", "GET", "b"))
cluster.open "db"
cluster.open "db2"
end)

View File

@@ -5,4 +5,5 @@ skynet.start(function()
local proxy = cluster.proxy("db", ".simpledb")
print(skynet.call(proxy, "lua", "GET", "a"))
print(cluster.call("db", ".simpledb", "GET", "a"))
print(cluster.call("db2", ".simpledb", "GET", "b"))
end)

View File

@@ -1 +1,2 @@
db = "127.0.0.1:2528"
db2 = "127.0.0.1:2529"

View File

@@ -1,4 +1,5 @@
local skynet = require "skynet"
require "skynet.manager" -- import skynet.register
skynet.start(function()
skynet.dispatch("lua", function(session, address, ...)

View File

@@ -1,5 +1,6 @@
local skynet = require "skynet"
local harbor = require "skynet.harbor"
require "skynet.manager" -- import skynet.monitor
local function monitor_master()
harbor.linkmaster()

View File

@@ -1,4 +1,5 @@
local skynet = require "skynet"
require "skynet.manager" -- import skynet.register
local db = {}
local command = {}

View File

@@ -602,11 +602,7 @@ read64(lua_State *L, uint32_t xx[2], uint32_t yy[2]) {
}
static int
lhmac64(lua_State *L) {
uint32_t x[2], y[2];
read64(L, x, y);
uint32_t result[2];
hmac(x,y,result);
pushqword(lua_State *L, uint32_t result[2]) {
uint8_t tmp[8];
tmp[0] = result[0] & 0xff;
tmp[1] = (result[0] >> 8 )& 0xff;
@@ -621,6 +617,40 @@ lhmac64(lua_State *L) {
return 1;
}
static int
lhmac64(lua_State *L) {
uint32_t x[2], y[2];
read64(L, x, y);
uint32_t result[2];
hmac(x,y,result);
return pushqword(L, result);
}
/*
8bytes key
string text
*/
static int
lhmac_hash(lua_State *L) {
uint32_t key[2];
size_t sz = 0;
const uint8_t *x = (const uint8_t *)luaL_checklstring(L, 1, &sz);
if (sz != 8) {
luaL_error(L, "Invalid uint64 key");
}
key[0] = x[0] | x[1]<<8 | x[2]<<16 | x[3]<<24;
key[1] = x[4] | x[5]<<8 | x[6]<<16 | x[7]<<24;
const char * text = luaL_checklstring(L, 2, &sz);
uint8_t h[8];
Hash(text,(int)sz,h);
uint32_t htext[2];
htext[0] = h[0] | h[1]<<8 | h[2]<<16 | h[3]<<24;
htext[1] = h[4] | h[5]<<8 | h[6]<<16 | h[7]<<24;
uint32_t result[2];
hmac(htext,key,result);
return pushqword(L, result);
}
// powmodp64 for DH-key exchange
// The biggest 64bit prime
@@ -858,6 +888,7 @@ luaopen_crypt(lua_State *L) {
{ "base64decode", lb64decode },
{ "sha1", lsha1 },
{ "hmac_sha1", lhmac_sha1 },
{ "hmac_hash", lhmac_hash },
{ NULL, NULL },
};
luaL_newlib(L,l);

View File

@@ -256,6 +256,7 @@ wb_table_hash(lua_State *L, struct write_block * wb, int index, int depth, int a
static void
wb_table(lua_State *L, struct write_block *wb, int index, int depth) {
luaL_checkstack(L, LUA_MINSTACK, NULL);
if (index < 0) {
index = lua_gettop(L) + index + 1;
}
@@ -416,6 +417,7 @@ unpack_table(lua_State *L, struct read_block *rb, int array_size) {
}
array_size = get_integer(L,rb,cookie);
}
luaL_checkstack(L,LUA_MINSTACK,NULL);
lua_createtable(L,array_size,0);
int i;
for (i=1;i<=array_size;i++) {
@@ -549,8 +551,8 @@ _luaseri_unpack(lua_State *L) {
int i;
for (i=0;;i++) {
if (i%16==15) {
lua_checkstack(L,i);
if (i%8==7) {
luaL_checkstack(L,LUA_MINSTACK,NULL);
}
uint8_t type = 0;
uint8_t *t = rb_read(&rb, sizeof(type));

View File

@@ -534,12 +534,6 @@ lnodelay(lua_State *L) {
skynet_socket_nodelay(ctx,id);
return 0;
}
/*
int skynet_socket_udp(struct skynet_context *ctx, const char * addr, int port);
int skynet_socket_udp_connect(struct skynet_context *ctx, int id, const char * addr, int port);
int skynet_socket_udp_send(struct skynet_context *ctx, int id, const char * address, const void *buffer, int sz);
const char * skynet_socket_udp_address(struct skynet_context *ctx, struct skynet_socket_message *, int *addrsz);
*/
static int
ludp(lua_State *L) {
@@ -599,7 +593,9 @@ static int
ludp_address(lua_State *L) {
size_t sz = 0;
const uint8_t * addr = (const uint8_t *)luaL_checklstring(L, 1, &sz);
int port = addr[1] * 256 + addr[2];
uint16_t port = 0;
memcpy(&port, addr+1, sizeof(uint16_t));
port = ntohs(port);
const void * src = addr+3;
char tmp[256];
int family;

View File

@@ -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);
@@ -199,7 +193,7 @@ encode(const struct sproto_arg *args) {
return -1;
memcpy(args->value, str, sz);
lua_pop(L,1);
return sz;
return sz + 1; // The length of empty string is 1.
}
case SPROTO_TSTRUCT: {
struct encode_ud sub;
@@ -545,48 +539,87 @@ 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;
}
static int
encode_default(const struct sproto_arg *args) {
lua_State *L = args->ud;
lua_pushstring(L, args->tagname);
if (args->index > 0) {
lua_newtable(L);
} else {
switch(args->type) {
case SPROTO_TINTEGER:
lua_pushinteger(L, 0);
break;
case SPROTO_TBOOLEAN:
lua_pushboolean(L, 0);
break;
case SPROTO_TSTRING:
lua_pushliteral(L, "");
break;
case SPROTO_TSTRUCT:
lua_createtable(L, 0, 1);
lua_pushstring(L, sproto_name(args->subtype));
lua_setfield(L, -2, "__type");
break;
}
}
lua_rawset(L, -3);
return 0;
}
/*
lightuserdata sproto_type
return default table
*/
static int
ldefault(lua_State *L) {
int ret;
// 32 is enough for dummy buffer, because ldefault encode nothing but the header.
char dummy[32];
struct sproto_type * st = lua_touserdata(L, 1);
if (st == NULL) {
return luaL_argerror(L, 1, "Need a sproto_type object");
}
lua_newtable(L);
ret = sproto_encode(st, dummy, sizeof(dummy), encode_default, L);
if (ret<0) {
return luaL_error(L, "dummy buffer (%d) is too small", (int)sizeof(dummy));
}
return 1;
}
int
@@ -603,6 +636,7 @@ luaopen_sproto_core(lua_State *L) {
{ "protocol", lprotocol },
{ "loadproto", lloadproto },
{ "saveproto", lsaveproto },
{ "default", ldefault },
{ NULL, NULL },
};
luaL_newlib(L,l);

View File

@@ -500,7 +500,11 @@ sproto_dump(struct sproto *s) {
printf("=== %d protocol ===\n", s->protocol_n);
for (i=0;i<s->protocol_n;i++) {
struct protocol *p = &s->proto[i];
printf("\t%s (%d) request:%s", p->name, p->tag, p->p[SPROTO_REQUEST]->name);
if (p->p[SPROTO_REQUEST]) {
printf("\t%s (%d) request:%s", p->name, p->tag, p->p[SPROTO_REQUEST]->name);
} else {
printf("\t%s (%d) request:(null)", p->name, p->tag);
}
if (p->p[SPROTO_RESPONSE]) {
printf(" response:%s", p->p[SPROTO_RESPONSE]->name);
}
@@ -510,7 +514,7 @@ sproto_dump(struct sproto *s) {
// query
int
sproto_prototag(struct sproto *sp, const char * name) {
sproto_prototag(const struct sproto *sp, const char * name) {
int i;
for (i=0;i<sp->protocol_n;i++) {
if (strcmp(name, sp->proto[i].name) == 0) {
@@ -521,7 +525,7 @@ sproto_prototag(struct sproto *sp, const char * name) {
}
static struct protocol *
query_proto(struct sproto *sp, int tag) {
query_proto(const struct sproto *sp, int tag) {
int begin = 0, end = sp->protocol_n;
while(begin<end) {
int mid = (begin+end)/2;
@@ -539,7 +543,7 @@ query_proto(struct sproto *sp, int tag) {
}
struct sproto_type *
sproto_protoquery(struct sproto *sp, int proto, int what) {
sproto_protoquery(const struct sproto *sp, int proto, int what) {
struct protocol * p;
if (what <0 || what >1) {
return NULL;
@@ -552,7 +556,7 @@ sproto_protoquery(struct sproto *sp, int proto, int what) {
}
const char *
sproto_protoname(struct sproto *sp, int proto) {
sproto_protoname(const struct sproto *sp, int proto) {
struct protocol * p = query_proto(sp, proto);
if (p) {
return p->name;
@@ -561,7 +565,7 @@ sproto_protoname(struct sproto *sp, int proto) {
}
struct sproto_type *
sproto_type(struct sproto *sp, const char * type_name) {
sproto_type(const struct sproto *sp, const char * type_name) {
int i;
for (i=0;i<sp->type_n;i++) {
if (strcmp(type_name, sp->type[i].name) == 0) {
@@ -577,7 +581,7 @@ sproto_name(struct sproto_type * st) {
}
static struct field *
findtag(struct sproto_type *st, int tag) {
findtag(const struct sproto_type *st, int tag) {
int begin, end;
if (st->base >=0 ) {
tag -= st->base;
@@ -609,10 +613,6 @@ findtag(struct sproto_type *st, int tag) {
static inline int
fill_size(uint8_t * data, int sz) {
if (sz < 0)
return -1;
if (sz == 0)
return 0;
data[0] = sz & 0xff;
data[1] = (sz >> 8) & 0xff;
data[2] = (sz >> 16) & 0xff;
@@ -677,6 +677,11 @@ encode_object(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int si
args->value = data+SIZEOF_LENGTH;
args->length = size-SIZEOF_LENGTH;
sz = cb(args);
if (sz <= 0)
return sz;
if (args->type == SPROTO_TSTRING) {
--sz; // the length of null string is 1
}
return fill_size(data, sz);
}
@@ -718,7 +723,7 @@ encode_integer_array(sproto_callback cb, struct sproto_arg *args, uint8_t *buffe
sz = cb(args);
if (sz < 0)
return NULL;
if (sz == 0)
if (sz == 0) // nil object, end of array
break;
if (size < sizeof(uint64_t))
return NULL;
@@ -798,7 +803,7 @@ encode_array(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int siz
sz = cb(args);
if (sz < 0)
return -1;
if (sz == 0)
if (sz == 0) // nil object , end of array
break;
if (size < 1)
return -1;
@@ -817,10 +822,13 @@ encode_array(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int siz
args->value = buffer+SIZEOF_LENGTH;
args->length = size;
sz = cb(args);
if (sz < 0)
return -1;
if (sz == 0)
break;
if (sz < 0)
return -1;
if (args->type == SPROTO_TSTRING) {
--sz;
}
fill_size(buffer, sz);
buffer += SIZEOF_LENGTH+sz;
size -=sz;
@@ -829,13 +837,13 @@ encode_array(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int siz
break;
}
sz = buffer - (data + SIZEOF_LENGTH);
if (sz == 0)
if (sz == 0) // empty array
return 0;
return fill_size(data, sz);
}
int
sproto_encode(struct sproto_type *st, void * buffer, int size, sproto_callback cb, void *ud) {
sproto_encode(const struct sproto_type *st, void * buffer, int size, sproto_callback cb, void *ud) {
struct sproto_arg args;
uint8_t * header = buffer;
uint8_t * data;
@@ -878,7 +886,7 @@ sproto_encode(struct sproto_type *st, void * buffer, int size, sproto_callback c
sz = cb(&args);
if (sz < 0)
return -1;
if (sz == 0)
if (sz == 0) // nil object
continue;
if (sz == sizeof(uint32_t)) {
if (u.u32 < 0x7fff) {
@@ -895,11 +903,10 @@ sproto_encode(struct sproto_type *st, void * buffer, int size, sproto_callback c
break;
}
case SPROTO_TSTRUCT:
case SPROTO_TSTRING: {
case SPROTO_TSTRING:
sz = encode_object(cb, &args, data, size);
break;
}
}
}
if (sz < 0)
return -1;
@@ -1032,7 +1039,7 @@ decode_array(sproto_callback cb, struct sproto_arg *args, uint8_t * stream) {
}
int
sproto_decode(struct sproto_type *st, const void * data, int size, sproto_callback cb, void *ud) {
sproto_decode(const struct sproto_type *st, const void * data, int size, sproto_callback cb, void *ud) {
struct sproto_arg args;
int total = size;
uint8_t * stream;

View File

@@ -17,12 +17,12 @@ struct sproto_type;
struct sproto * sproto_create(const void * proto, size_t sz);
void sproto_release(struct sproto *);
int sproto_prototag(struct sproto *, const char * name);
const char * sproto_protoname(struct sproto *, int proto);
int sproto_prototag(const struct sproto *, const char * name);
const char * sproto_protoname(const struct sproto *, int proto);
// SPROTO_REQUEST(0) : request, SPROTO_RESPONSE(1): response
struct sproto_type * sproto_protoquery(struct sproto *, int proto, int what);
struct sproto_type * sproto_protoquery(const struct sproto *, int proto, int what);
struct sproto_type * sproto_type(struct sproto *, const char * type_name);
struct sproto_type * sproto_type(const struct sproto *, const char * type_name);
int sproto_pack(const void * src, int srcsz, void * buffer, int bufsz);
int sproto_unpack(const void * src, int srcsz, void * buffer, int bufsz);
@@ -41,8 +41,8 @@ struct sproto_arg {
typedef int (*sproto_callback)(const struct sproto_arg *args);
int sproto_decode(struct sproto_type *, const void * data, int size, sproto_callback cb, void *ud);
int sproto_encode(struct sproto_type *, void * buffer, int size, sproto_callback cb, void *ud);
int sproto_decode(const struct sproto_type *, const void * data, int size, sproto_callback cb, void *ud);
int sproto_encode(const struct sproto_type *, void * buffer, int size, sproto_callback cb, void *ud);
// for debug use
void sproto_dump(struct sproto *);

View File

@@ -249,8 +249,8 @@ function dns.server(server, port)
end
assert(server, "Can't get nameserver")
end
dns_server = socket.udp(function(data, sz, from)
resolve(skynet.tostring(data,sz))
dns_server = socket.udp(function(str, from)
resolve(str)
end)
socket.udp_connect(dns_server, server, port or 53)
return server

View File

@@ -11,21 +11,21 @@ local function request(fd, method, host, url, recvheader, header, content)
local write = socket.writefunc(fd)
local header_content = ""
if header then
if not header.host then
header.host = host
end
for k,v in pairs(header) do
header_content = string.format("%s%s:%s\r\n", header_content, k, v)
end
if header.host then
host = ""
end
else
host = string.format("host:%s\r\n",host)
header_content = string.format("host:%s\r\n",host)
end
if content then
local data = string.format("%s %s HTTP/1.1\r\n%scontent-length:%d\r\n%s\r\n%s", method, url, host, #content, header_content, content)
local data = string.format("%s %s HTTP/1.1\r\n%scontent-length:%d\r\n\r\n%s", method, url, header_content, #content, content)
write(data)
else
local request_header = string.format("%s %s HTTP/1.1\r\nhost:%s\r\ncontent-length:0\r\n%s\r\n", method, url, host, header_content)
local request_header = string.format("%s %s HTTP/1.1\r\n%scontent-length:0\r\n\r\n", method, url, header_content)
write(request_header)
end

View File

@@ -30,12 +30,14 @@ function sharemap.writer(typename, obj)
local sp = loadsp()
obj = obj or {}
local stmobj = stm.new(sp:encode(typename,obj))
obj.__typename = typename
obj.__obj = stmobj
obj.__data = obj
obj.commit = sharemap.commit
obj.copy = sharemap.copy
return setmetatable(obj, { __index = obj.__data, __newindex = obj.__data })
local ret = {
__typename = typename,
__obj = stmobj,
__data = obj,
commit = sharemap.commit,
copy = sharemap.copy,
}
return setmetatable(ret, { __index = obj, __newindex = obj })
end
local function decode(msg, sz, self)
@@ -63,7 +65,7 @@ function sharemap.reader(typename, stmcpy)
__data = data,
update = sharemap.update,
}
return setmetatable(obj, { __index = obj.__data, __newindex = error })
return setmetatable(obj, { __index = data, __newindex = error })
end
return sharemap

View File

@@ -44,6 +44,7 @@ local session_id_coroutine = {}
local session_coroutine_id = {}
local session_coroutine_address = {}
local session_response = {}
local unresponse = {}
local wakeup_session = {}
local sleep_session = {}
@@ -96,7 +97,6 @@ end
local coroutine_pool = {}
local coroutine_yield = coroutine.yield
local coroutine_count = 0
local function co_create(f)
local co = table.remove(coroutine_pool)
@@ -110,11 +110,6 @@ local function co_create(f)
f(coroutine_yield())
end
end)
coroutine_count = coroutine_count + 1
if coroutine_count > 1024 then
skynet.error("May overload, create 1024 task")
coroutine_count = 0
end
else
coroutine.resume(co, f)
end
@@ -128,7 +123,7 @@ local function dispatch_wakeup()
local session = sleep_session[co]
if session then
session_id_coroutine[session] = "BREAK"
return suspend(co, coroutine.resume(co, true, "BREAK"))
return suspend(co, coroutine.resume(co, false, "BREAK"))
end
end
end
@@ -175,6 +170,10 @@ function suspend(co, result, command, param, size)
local ret
if not dead_service[co_address] then
ret = c.send(co_address, skynet.PTYPE_RESPONSE, co_session, param, size) ~= nil
if not ret then
-- If the package is too large, returns nil. so we should report error back
c.send(co_address, skynet.PTYPE_ERROR, co_session, "")
end
elseif size == nil then
c.trash(param, size)
ret = false
@@ -209,6 +208,10 @@ function suspend(co, result, command, param, size)
if not dead_service[co_address] then
if ok then
ret = c.send(co_address, skynet.PTYPE_RESPONSE, co_session, f(...)) ~= nil
if not ret then
-- If the package is too large, returns false. so we should report error back
c.send(co_address, skynet.PTYPE_ERROR, co_session, "")
end
else
ret = c.send(co_address, skynet.PTYPE_ERROR, co_session, "") ~= nil
end
@@ -216,11 +219,13 @@ function suspend(co, result, command, param, size)
ret = false
end
release_watching(co_address)
unresponse[response] = nil
f = nil
return ret
end
watching_service[co_address] = watching_service[co_address] + 1
session_response[co] = response
unresponse[response] = true
return suspend(co, coroutine.resume(co, response))
elseif command == "EXIT" then
-- coroutine exit
@@ -257,9 +262,13 @@ function skynet.sleep(ti)
session = tonumber(session)
local succ, ret = coroutine_yield("SLEEP", session)
sleep_session[coroutine.running()] = nil
assert(succ, ret)
if succ then
return
end
if ret == "BREAK" then
return "BREAK"
else
error(ret)
end
end
@@ -269,41 +278,12 @@ end
function skynet.wait()
local session = c.genid()
coroutine_yield("SLEEP", session)
local ret, msg = coroutine_yield("SLEEP", session)
local co = coroutine.running()
sleep_session[co] = nil
session_id_coroutine[session] = nil
end
local function globalname(name, handle)
local c = string.sub(name,1,1)
assert(c ~= ':')
if c == '.' then
return false
end
assert(#name <= 16) -- GLOBALNAME_LENGTH is 16, defined in skynet_harbor.h
assert(tonumber(name) == nil) -- global name can't be number
local harbor = require "skynet.harbor"
harbor.globalname(name, handle)
return true
end
function skynet.register(name)
if not globalname(name) then
c.command("REG", name)
end
end
function skynet.name(name, handle)
if not globalname(name, handle) then
c.command("NAME", name .. " " .. skynet.address(handle))
end
end
local self_handle
function skynet.self()
if self_handle then
@@ -320,13 +300,6 @@ function skynet.localname(name)
end
end
function skynet.launch(...)
local addr = c.command("LAUNCH", table.concat({...}," "))
if addr then
return string_to_handle(addr)
end
end
function skynet.now()
return tonumber(c.command("NOW"))
end
@@ -349,6 +322,9 @@ function skynet.exit()
c.redirect(address, 0, skynet.PTYPE_ERROR, session, "")
end
end
for resp in pairs(unresponse) do
resp(false)
end
-- report the sources I call but haven't return
local tmp = {}
for session, address in pairs(watching_session) do
@@ -362,14 +338,6 @@ function skynet.exit()
coroutine_yield "QUIT"
end
function skynet.kill(name)
if type(name) == "number" then
skynet.send(".launcher","lua","REMOVE",name, true)
name = skynet.address(name)
end
c.command("KILL",name)
end
function skynet.getenv(key)
local ret = c.command("GETENV",key)
if ret == "" then
@@ -398,13 +366,14 @@ skynet.pack = assert(c.pack)
skynet.packstring = assert(c.packstring)
skynet.unpack = assert(c.unpack)
skynet.tostring = assert(c.tostring)
skynet.trash = assert(c.trash)
local function yield_call(service, session)
watching_session[session] = service
local succ, msg, sz = coroutine_yield("CALL", session)
watching_session[session] = nil
if not succ then
error(debug.traceback())
error "call failed"
end
return msg,sz
end
@@ -515,7 +484,7 @@ local function raw_dispatch_message(prototype, msg, sz, session, source, ...)
end
end
local function dispatch_message(...)
function skynet.dispatch_message(...)
local succ, err = pcall(raw_dispatch_message,...)
while true do
local key,co = next(fork_queue)
@@ -619,8 +588,10 @@ end
local function init_all()
local funcs = init_func
init_func = nil
for k,v in pairs(funcs) do
v()
if funcs then
for k,v in pairs(funcs) do
v()
end
end
end
@@ -631,8 +602,12 @@ local function init_template(start)
init_all()
end
local function init_service(start)
local ok, err = xpcall(init_template, debug.traceback, start)
function skynet.pcall(start)
return xpcall(init_template, debug.traceback, start)
end
function skynet.init_service(start)
local ok, err = skynet.pcall(start)
if not ok then
skynet.error("init service failed: " .. tostring(err))
skynet.send(".launcher","lua", "ERROR")
@@ -643,33 +618,9 @@ local function init_service(start)
end
function skynet.start(start_func)
c.callback(dispatch_message)
c.callback(skynet.dispatch_message)
skynet.timeout(0, function()
init_service(start_func)
end)
end
function skynet.filter(f ,start_func)
c.callback(function(...)
dispatch_message(f(...))
end)
skynet.timeout(0, function()
init_service(start_func)
end)
end
function skynet.forward_type(map, start_func)
c.callback(function(ptype, msg, sz, ...)
local prototype = map[ptype]
if prototype then
dispatch_message(prototype, msg, sz, ...)
else
dispatch_message(ptype, msg, sz, ...)
c.trash(msg, sz)
end
end, true)
skynet.timeout(0, function()
init_service(start_func)
skynet.init_service(start_func)
end)
end
@@ -677,22 +628,6 @@ function skynet.endless()
return c.command("ENDLESS")~=nil
end
function skynet.abort()
c.command("ABORT")
end
function skynet.monitor(service, query)
local monitor
if query then
monitor = skynet.queryservice(true, service)
else
monitor = skynet.uniqueservice(true, service)
end
assert(monitor, "Monitor launch failed")
c.command("MONITOR", string.format(":%08x", monitor))
return monitor
end
function skynet.mqlen()
return tonumber(c.command "MQLEN")
end
@@ -719,7 +654,7 @@ end
-- Inject internal debug framework
local debug = require "skynet.debug"
debug(skynet, {
dispatch = dispatch_message,
dispatch = skynet.dispatch_message,
clear = clear_pool,
suspend = suspend,
})

View File

@@ -49,7 +49,7 @@ end
function dbgcmd.RUN(source, filename)
local inject = require "skynet.inject"
local output = inject(source, filename , export.dispatch, skynet.register_protocol)
local output = inject(skynet, source, filename , export.dispatch, skynet.register_protocol)
collectgarbage "collect"
skynet.ret(skynet.pack(table.concat(output, "\n")))
end

View File

@@ -1,5 +1,5 @@
local function getupvaluetable(u, func, unique)
i = 1
local i = 1
while true do
local name, value = debug.getupvalue(func, i)
if name == nil then
@@ -18,7 +18,7 @@ local function getupvaluetable(u, func, unique)
end
end
return function(source, filename , ...)
return function(skynet, source, filename , ...)
if filename then
filename = "@" .. filename
else
@@ -56,7 +56,7 @@ return function(source, filename , ...)
if not func then
return { err }
end
local ok, err = xpcall(func, debug.traceback)
local ok, err = skynet.pcall(func)
if not ok then
table.insert(output, err)
end

90
lualib/skynet/manager.lua Normal file
View File

@@ -0,0 +1,90 @@
local skynet = require "skynet"
local c = require "skynet.core"
function skynet.launch(...)
local addr = c.command("LAUNCH", table.concat({...}," "))
if addr then
return tonumber("0x" .. string.sub(addr , 2))
end
end
function skynet.kill(name)
if type(name) == "number" then
skynet.send(".launcher","lua","REMOVE",name, true)
name = skynet.address(name)
end
c.command("KILL",name)
end
function skynet.abort()
c.command("ABORT")
end
local function globalname(name, handle)
local c = string.sub(name,1,1)
assert(c ~= ':')
if c == '.' then
return false
end
assert(#name <= 16) -- GLOBALNAME_LENGTH is 16, defined in skynet_harbor.h
assert(tonumber(name) == nil) -- global name can't be number
local harbor = require "skynet.harbor"
harbor.globalname(name, handle)
return true
end
function skynet.register(name)
if not globalname(name) then
c.command("REG", name)
end
end
function skynet.name(name, handle)
if not globalname(name, handle) then
c.command("NAME", name .. " " .. skynet.address(handle))
end
end
local dispatch_message = skynet.dispatch_message
function skynet.forward_type(map, start_func)
c.callback(function(ptype, msg, sz, ...)
local prototype = map[ptype]
if prototype then
dispatch_message(prototype, msg, sz, ...)
else
dispatch_message(ptype, msg, sz, ...)
c.trash(msg, sz)
end
end, true)
skynet.timeout(0, function()
skynet.init_service(start_func)
end)
end
function skynet.filter(f ,start_func)
c.callback(function(...)
dispatch_message(f(...))
end)
skynet.timeout(0, function()
skynet.init_service(start_func)
end)
end
function skynet.monitor(service, query)
local monitor
if query then
monitor = skynet.queryservice(true, service)
else
monitor = skynet.uniqueservice(true, service)
end
assert(monitor, "Monitor launch failed")
c.command("MONITOR", string.format(":%08x", monitor))
return monitor
end
return skynet

View File

@@ -162,4 +162,8 @@ function snax.hotfix(obj, source, ...)
return test_result(skynet_call(obj.handle, "snax", t.system.hotfix, source, ...))
end
function snax.printf(fmt, ...)
skynet.error(string.format(fmt, ...))
end
return snax

View File

@@ -1,4 +1,5 @@
local skynet = require "skynet"
require "skynet.manager"
local socket = require "socket"
local crypt = require "crypt"
local table = table
@@ -33,17 +34,17 @@ Success:
]]
local socket_error = {}
local function assert_socket(v, fd)
local function assert_socket(service, v, fd)
if v then
return v
else
skynet.error(string.format("auth failed: socket (fd = %d) closed", fd))
skynet.error(string.format("%s failed: socket (fd = %d) closed", service, fd))
error(socket_error)
end
end
local function write(fd, text)
assert_socket(socket.write(fd, text), fd)
local function write(service, fd, text)
assert_socket(service, socket.write(fd, text), fd)
end
local function launch_slave(auth_handler)
@@ -57,27 +58,27 @@ local function launch_slave(auth_handler)
socket.limit(fd, 8192)
local challenge = crypt.randomkey()
write(fd, crypt.base64encode(challenge).."\n")
write("auth", fd, crypt.base64encode(challenge).."\n")
local handshake = assert_socket(socket.readline(fd), fd)
local handshake = assert_socket("auth", socket.readline(fd), fd)
local clientkey = crypt.base64decode(handshake)
if #clientkey ~= 8 then
error "Invalid client key"
end
local serverkey = crypt.randomkey()
write(fd, crypt.base64encode(crypt.dhexchange(serverkey)).."\n")
write("auth", fd, crypt.base64encode(crypt.dhexchange(serverkey)).."\n")
local secret = crypt.dhsecret(clientkey, serverkey)
local response = assert_socket(socket.readline(fd), fd)
local response = assert_socket("auth", socket.readline(fd), fd)
local hmac = crypt.hmac64(challenge, secret)
if hmac ~= crypt.base64decode(response) then
write(fd, "400 Bad Request\n")
write("auth", fd, "400 Bad Request\n")
error "challenge failed"
end
local etoken = assert_socket(socket.readline(fd),fd)
local etoken = assert_socket("auth", socket.readline(fd),fd)
local token = crypt.desdecode(secret, crypt.base64decode(etoken))
@@ -91,7 +92,11 @@ local function launch_slave(auth_handler)
if ok then
skynet.ret(skynet.pack(err, ...))
else
error(err)
if err == socket_error then
skynet.ret(skynet.pack(nil, "socket error"))
else
skynet.ret(skynet.pack(false, err))
end
end
end
@@ -108,13 +113,15 @@ local function accept(conf, s, fd, addr)
socket.start(fd)
if not ok then
write(fd, "401 Unauthorized\n")
if ok ~= nil then
write("response 401", fd, "401 Unauthorized\n")
end
error(server)
end
if not conf.multilogin then
if user_login[uid] then
write(fd, "406 Not Acceptable\n")
write("response 406", fd, "406 Not Acceptable\n")
error(string.format("User %s is already login", uid))
end
@@ -127,9 +134,9 @@ local function accept(conf, s, fd, addr)
if ok then
err = err or ""
write(fd, "200 "..crypt.base64encode(err).."\n")
write("response 200",fd, "200 "..crypt.base64encode(err).."\n")
else
write(fd, "403 Forbidden\n")
write("response 403",fd, "403 Forbidden\n")
error(err)
end
end

View File

@@ -178,7 +178,7 @@ function server.start(conf)
end
local text = string.format("%s:%s", username, index)
local v = crypt.hmac64(crypt.hashkey(text), u.secret)
local v = crypt.hmac_hash(u.secret, text) -- equivalent to crypt.hmac64(crypt.hashkey(text), u.secret)
if v ~= hmac then
return "401 Unauthorized"
end

View File

@@ -1,5 +1,6 @@
local driver = require "socketdriver"
local skynet = require "skynet"
local skynet_core = require "skynet.core"
local assert = assert
local socket = {} -- api
@@ -127,7 +128,9 @@ socket_message[6] = function(id, size, data, address)
driver.drop(data, size)
return
end
s.callback(data, size, address)
local str = skynet.tostring(data, size)
skynet_core.trash(data, size)
s.callback(str, address)
end
skynet.register_protocol {

View File

@@ -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)
@@ -90,6 +99,66 @@ local function queryproto(self, pname)
return v
end
function sproto:request_encode(protoname, tbl)
local p = queryproto(self, protoname)
local request = p.request
if request then
return core.encode(request,tbl) , p.tag
else
return "" , p.tag
end
end
function sproto:response_encode(protoname, tbl)
local p = queryproto(self, protoname)
local response = p.response
if response then
return core.encode(response,tbl)
else
return ""
end
end
function sproto:request_decode(protoname, ...)
local p = queryproto(self, protoname)
local request = p.request
if request then
return core.decode(request,...) , p.name
else
return nil, p.name
end
end
function sproto:response_decode(protoname, ...)
local p = queryproto(self, protoname)
local response = p.response
if response then
return core.decode(response,...)
end
end
sproto.pack = core.pack
sproto.unpack = core.unpack
function sproto:default(typename, type)
if type == nil then
return core.default(querytype(self, typename))
else
local p = queryproto(self, typename)
if type == "REQUEST" then
if p.request then
return core.default(p.request)
end
elseif type == "RESPONSE" then
if p.response then
return core.default(p.response)
end
else
error "Invalid type"
end
end
end
local header_tmp = {}
local function gen_response(self, response, session)

View File

@@ -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

View File

@@ -194,7 +194,7 @@ local function check_protocol(r)
local request = v.request
local response = v.response
local p = map[tag]
if p then
error(string.format("redefined protocol tag %d at %s", tag, name))
end
@@ -340,9 +340,6 @@ local function packtype(name, t, alltypes)
end
local function packproto(name, p, alltypes)
-- if p.request == nil then
-- error(string.format("Protocol %s need request", name))
-- end
if p.request then
local request = alltypes[p.request]
if request == nil then

View File

@@ -1,5 +1,6 @@
local skynet = require "skynet"
local harbor = require "skynet.harbor"
require "skynet.manager" -- import skynet.launch, ...
skynet.start(function()
local standalone = skynet.getenv "standalone"

View File

@@ -1,4 +1,5 @@
local skynet = require "skynet"
require "skynet.manager" -- import skynet.launch, ...
local globalname = {}
local queryname = {}

View File

@@ -5,14 +5,6 @@ local cluster = require "cluster.core"
local config_name = skynet.getenv "cluster"
local node_address = {}
local function loadconfig()
local f = assert(io.open(config_name))
local source = f:read "*a"
f:close()
assert(load(source, "@"..config_name, "t", node_address))()
end
local node_session = {}
local command = {}
@@ -37,6 +29,24 @@ end
local node_channel = setmetatable({}, { __index = open_channel })
local function loadconfig()
local f = assert(io.open(config_name))
local source = f:read "*a"
f:close()
local tmp = {}
assert(load(source, "@"..config_name, "t", tmp))()
for name,address in pairs(tmp) do
assert(type(address) == "string")
if node_address[name] ~= address then
-- address changed
if rawget(node_channel, name) then
node_channel[name] = nil -- reset connection
end
node_address[name] = address
end
end
end
function command.reload()
loadconfig()
skynet.ret(skynet.pack(nil))

View File

@@ -1,5 +1,6 @@
local skynet = require "skynet"
local cluster = require "cluster"
require "skynet.manager" -- inject skynet.forward_type
local node, address = ...

View File

@@ -1,5 +1,6 @@
local skynet = require "skynet"
local socket = require "socket"
require "skynet.manager" -- import skynet.launch, ...
local table = table
local slaves = {}

View File

@@ -1,5 +1,6 @@
local skynet = require "skynet"
local core = require "skynet.core"
require "skynet.manager" -- import manager apis
local string = string
local services = {}

View File

@@ -1,4 +1,5 @@
local skynet = require "skynet"
require "skynet.manager" -- import skynet.register
local snax = require "snax"
local cmd = {}

View File

@@ -44,7 +44,7 @@ function CMD.new(name, t)
elseif dt == "string" then
value = setmetatable({}, env_mt)
local f = load(t, "=" .. name, "t", value)
f()
assert(skynet.pcall(f))
setmetatable(value, nil)
elseif dt == "nil" then
value = {}

View File

@@ -1,5 +1,5 @@
#ifndef __MALLOC_HOOK_H
#define __MALLOC_HOOK_H
#ifndef SKYNET_MALLOC_HOOK_H
#define SKYNET_MALLOC_HOOK_H
#include <stdlib.h>
@@ -10,5 +10,5 @@ extern size_t mallctl_int64(const char* name, size_t* newval);
extern int mallctl_opt(const char* name, int* newval);
extern void dump_c_mem(void);
#endif /* __MALLOC_HOOK_H */
#endif /* SKYNET_MALLOC_HOOK_H */

View File

@@ -1,5 +1,5 @@
#ifndef _RWLOCK_H_
#define _RWLOCK_H_
#ifndef SKYNET_RWLOCK_H
#define SKYNET_RWLOCK_H
struct rwlock {
int write;

View File

@@ -77,7 +77,6 @@ skynet_handle_retire(uint32_t handle) {
struct skynet_context * ctx = s->slot[hash];
if (ctx != NULL && skynet_context_handle(ctx) == handle) {
skynet_context_release(ctx);
s->slot[hash] = NULL;
ret = 1;
int i;
@@ -92,10 +91,17 @@ skynet_handle_retire(uint32_t handle) {
++j;
}
s->name_count = j;
} else {
ctx = NULL;
}
rwlock_wunlock(&s->lock);
if (ctx) {
// release ctx may call skynet_handle_* , so wunlock first.
skynet_context_release(ctx);
}
return ret;
}

View File

@@ -508,7 +508,7 @@ udp_socket_address(struct socket *s, const uint8_t udp_address[UDP_ADDRESS_SIZE]
memset(&sa->v6, 0, sizeof(sa->v6));
sa->s.sa_family = AF_INET6;
sa->v6.sin6_port = port;
memcpy(&sa->v6.sin6_addr, udp_address + 1 + sizeof(uint16_t), sizeof(sa->v6.sin6_addr)); // ipv4 address is 128 bits
memcpy(&sa->v6.sin6_addr, udp_address + 1 + sizeof(uint16_t), sizeof(sa->v6.sin6_addr)); // ipv6 address is 128 bits
return sizeof(sa->v6);
}
return 0;
@@ -720,6 +720,7 @@ send_socket(struct socket_server *ss, struct request_send * request, struct sock
append_sendbuffer_udp(ss,s,priority,request,udp_address);
} else {
so.free_func(request->buffer);
return -1;
}
}
sp_write(ss->event_fd, s->fd, s, true);
@@ -887,6 +888,7 @@ add_udp_socket(struct socket_server *ss, struct request_udp *udp) {
if (ns == NULL) {
close(udp->fd);
ss->slot[HASH_ID(id)].type = SOCKET_TYPE_INVALID;
return;
}
ns->type = SOCKET_TYPE_CONNECTED;
memset(ns->p.udp_address, 0, sizeof(ns->p.udp_address));

View File

@@ -3,16 +3,15 @@ local socket = require "socket"
local function server()
local host
host = socket.udp(function(data, sz, from)
local str = skynet.tostring(data,sz) -- skynet.tostring should call only once, because it will free the pointer data
host = socket.udp(function(str, from)
print("server recv", str, socket.udp_address(from))
socket.sendto(host, from, "OK " .. str)
end , "127.0.0.1", 8765) -- bind an address
end
local function client()
local c = socket.udp(function(data, sz, from)
print("client recv", skynet.tostring(data,sz), socket.udp_address(from))
local c = socket.udp(function(str, from)
print("client recv", str, socket.udp_address(from))
end)
socket.udp_connect(c, "127.0.0.1", 8765)
for i=1,20 do