Compare commits

..

12 Commits

Author SHA1 Message Date
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
16 changed files with 100 additions and 87 deletions

View File

@@ -798,7 +798,8 @@ static int str_gsub (lua_State *L) {
*/ */
/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ /* 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 */ /* valid flags in a format specification */
#define FLAGS "-+ #0" #define FLAGS "-+ #0"

View File

@@ -1,3 +1,9 @@
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) v1.0.0-alpha3 (2015-3-30)
----------- -----------
* Update sproto (bugfix) * Update sproto (bugfix)

View File

@@ -1,6 +1,6 @@
The MIT License (MIT) 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 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 this software and associated documentation files (the "Software"), to deal in

View File

@@ -48,15 +48,9 @@ LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
static int static int
lnewproto(lua_State *L) { lnewproto(lua_State *L) {
size_t sz = 0;
void * buffer;
struct sproto * sp; struct sproto * sp;
if (lua_isuserdata(L,1)) { size_t sz;
buffer = lua_touserdata(L,1); void * buffer = (void *)luaL_checklstring(L,1,&sz);
sz = luaL_checkinteger(L,2);
} else {
buffer = (void *)luaL_checklstring(L,1,&sz);
}
sp = sproto_create(buffer, sz); sp = sproto_create(buffer, sz);
if (sp) { if (sp) {
lua_pushlightuserdata(L, sp); lua_pushlightuserdata(L, sp);
@@ -199,7 +193,7 @@ encode(const struct sproto_arg *args) {
return -1; return -1;
memcpy(args->value, str, sz); memcpy(args->value, str, sz);
lua_pop(L,1); lua_pop(L,1);
return sz; return sz + 1; // The length of empty string is 1.
} }
case SPROTO_TSTRUCT: { case SPROTO_TSTRUCT: {
struct encode_ud sub; struct encode_ud sub;
@@ -545,48 +539,38 @@ lprotocol(lua_State *L) {
return 3; return 3;
} }
/* global sproto pointer for multi states */ /* global sproto pointer for multi states
struct sproto_bin { NOTICE : It is not thread safe
void *ptr; */
size_t sz; static struct sproto * G_sproto[MAX_GLOBALSPROTO];
};
static struct sproto_bin G_sproto[MAX_GLOBALSPROTO];
static int static int
lsaveproto(lua_State *L) { lsaveproto(lua_State *L) {
size_t sz; struct sproto * sp = lua_touserdata(L, 1);
void * buffer = (void *)luaL_checklstring(L,1,&sz);
int index = luaL_optinteger(L, 2, 0); int index = luaL_optinteger(L, 2, 0);
void * tmp;
struct sproto_bin * sbin = &G_sproto[index];
if (index < 0 || index >= MAX_GLOBALSPROTO) { if (index < 0 || index >= MAX_GLOBALSPROTO) {
return luaL_error(L, "Invalid global slot index %d", index); return luaL_error(L, "Invalid global slot index %d", index);
} }
tmp = malloc(sz); /* TODO : release old object (memory leak now, but thread safe)*/
memcpy(tmp, buffer, sz); G_sproto[index] = sp;
if (sbin->ptr) {
free(sbin->ptr);
}
sbin->ptr = tmp;
sbin->sz = sz;
return 0; return 0;
} }
static int static int
lloadproto(lua_State *L) { lloadproto(lua_State *L) {
int index = luaL_optinteger(L, 1, 0); int index = luaL_optinteger(L, 1, 0);
struct sproto_bin * sbin = &G_sproto[index]; struct sproto * sp;
if (index < 0 || index >= MAX_GLOBALSPROTO) { if (index < 0 || index >= MAX_GLOBALSPROTO) {
return luaL_error(L, "Invalid global slot index %d", index); 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); return luaL_error(L, "nil sproto at index %d", index);
} }
lua_pushlightuserdata(L, sbin->ptr); lua_pushlightuserdata(L, sp);
lua_pushinteger(L, sbin->sz);
return 2; return 1;
} }
int int

View File

@@ -510,7 +510,7 @@ sproto_dump(struct sproto *s) {
// query // query
int int
sproto_prototag(struct sproto *sp, const char * name) { sproto_prototag(const struct sproto *sp, const char * name) {
int i; int i;
for (i=0;i<sp->protocol_n;i++) { for (i=0;i<sp->protocol_n;i++) {
if (strcmp(name, sp->proto[i].name) == 0) { if (strcmp(name, sp->proto[i].name) == 0) {
@@ -521,7 +521,7 @@ sproto_prototag(struct sproto *sp, const char * name) {
} }
static struct protocol * 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; int begin = 0, end = sp->protocol_n;
while(begin<end) { while(begin<end) {
int mid = (begin+end)/2; int mid = (begin+end)/2;
@@ -539,7 +539,7 @@ query_proto(struct sproto *sp, int tag) {
} }
struct sproto_type * 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; struct protocol * p;
if (what <0 || what >1) { if (what <0 || what >1) {
return NULL; return NULL;
@@ -552,7 +552,7 @@ sproto_protoquery(struct sproto *sp, int proto, int what) {
} }
const char * const char *
sproto_protoname(struct sproto *sp, int proto) { sproto_protoname(const struct sproto *sp, int proto) {
struct protocol * p = query_proto(sp, proto); struct protocol * p = query_proto(sp, proto);
if (p) { if (p) {
return p->name; return p->name;
@@ -561,7 +561,7 @@ sproto_protoname(struct sproto *sp, int proto) {
} }
struct sproto_type * struct sproto_type *
sproto_type(struct sproto *sp, const char * type_name) { sproto_type(const struct sproto *sp, const char * type_name) {
int i; int i;
for (i=0;i<sp->type_n;i++) { for (i=0;i<sp->type_n;i++) {
if (strcmp(type_name, sp->type[i].name) == 0) { if (strcmp(type_name, sp->type[i].name) == 0) {
@@ -577,7 +577,7 @@ sproto_name(struct sproto_type * st) {
} }
static struct field * static struct field *
findtag(struct sproto_type *st, int tag) { findtag(const struct sproto_type *st, int tag) {
int begin, end; int begin, end;
if (st->base >=0 ) { if (st->base >=0 ) {
tag -= st->base; tag -= st->base;
@@ -609,10 +609,6 @@ findtag(struct sproto_type *st, int tag) {
static inline int static inline int
fill_size(uint8_t * data, int sz) { fill_size(uint8_t * data, int sz) {
if (sz < 0)
return -1;
if (sz == 0)
return 0;
data[0] = sz & 0xff; data[0] = sz & 0xff;
data[1] = (sz >> 8) & 0xff; data[1] = (sz >> 8) & 0xff;
data[2] = (sz >> 16) & 0xff; data[2] = (sz >> 16) & 0xff;
@@ -677,6 +673,11 @@ encode_object(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int si
args->value = data+SIZEOF_LENGTH; args->value = data+SIZEOF_LENGTH;
args->length = size-SIZEOF_LENGTH; args->length = size-SIZEOF_LENGTH;
sz = cb(args); 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); return fill_size(data, sz);
} }
@@ -718,7 +719,7 @@ encode_integer_array(sproto_callback cb, struct sproto_arg *args, uint8_t *buffe
sz = cb(args); sz = cb(args);
if (sz < 0) if (sz < 0)
return NULL; return NULL;
if (sz == 0) if (sz == 0) // nil object, end of array
break; break;
if (size < sizeof(uint64_t)) if (size < sizeof(uint64_t))
return NULL; return NULL;
@@ -798,7 +799,7 @@ encode_array(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int siz
sz = cb(args); sz = cb(args);
if (sz < 0) if (sz < 0)
return -1; return -1;
if (sz == 0) if (sz == 0) // nil object , end of array
break; break;
if (size < 1) if (size < 1)
return -1; return -1;
@@ -817,10 +818,13 @@ encode_array(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int siz
args->value = buffer+SIZEOF_LENGTH; args->value = buffer+SIZEOF_LENGTH;
args->length = size; args->length = size;
sz = cb(args); sz = cb(args);
if (sz < 0)
return -1;
if (sz == 0) if (sz == 0)
break; break;
if (sz < 0)
return -1;
if (args->type == SPROTO_TSTRING) {
--sz;
}
fill_size(buffer, sz); fill_size(buffer, sz);
buffer += SIZEOF_LENGTH+sz; buffer += SIZEOF_LENGTH+sz;
size -=sz; size -=sz;
@@ -829,13 +833,13 @@ encode_array(sproto_callback cb, struct sproto_arg *args, uint8_t *data, int siz
break; break;
} }
sz = buffer - (data + SIZEOF_LENGTH); sz = buffer - (data + SIZEOF_LENGTH);
if (sz == 0) if (sz == 0) // empty array
return 0; return 0;
return fill_size(data, sz); return fill_size(data, sz);
} }
int 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; struct sproto_arg args;
uint8_t * header = buffer; uint8_t * header = buffer;
uint8_t * data; uint8_t * data;
@@ -878,7 +882,7 @@ sproto_encode(struct sproto_type *st, void * buffer, int size, sproto_callback c
sz = cb(&args); sz = cb(&args);
if (sz < 0) if (sz < 0)
return -1; return -1;
if (sz == 0) if (sz == 0) // nil object
continue; continue;
if (sz == sizeof(uint32_t)) { if (sz == sizeof(uint32_t)) {
if (u.u32 < 0x7fff) { if (u.u32 < 0x7fff) {
@@ -895,11 +899,10 @@ sproto_encode(struct sproto_type *st, void * buffer, int size, sproto_callback c
break; break;
} }
case SPROTO_TSTRUCT: case SPROTO_TSTRUCT:
case SPROTO_TSTRING: { case SPROTO_TSTRING:
sz = encode_object(cb, &args, data, size); sz = encode_object(cb, &args, data, size);
break; break;
} }
}
} }
if (sz < 0) if (sz < 0)
return -1; return -1;
@@ -1032,7 +1035,7 @@ decode_array(sproto_callback cb, struct sproto_arg *args, uint8_t * stream) {
} }
int 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; struct sproto_arg args;
int total = size; int total = size;
uint8_t * stream; uint8_t * stream;

View File

@@ -17,12 +17,12 @@ struct sproto_type;
struct sproto * sproto_create(const void * proto, size_t sz); struct sproto * sproto_create(const void * proto, size_t sz);
void sproto_release(struct sproto *); void sproto_release(struct sproto *);
int sproto_prototag(struct sproto *, const char * name); int sproto_prototag(const struct sproto *, const char * name);
const char * sproto_protoname(struct sproto *, int proto); const char * sproto_protoname(const struct sproto *, int proto);
// SPROTO_REQUEST(0) : request, SPROTO_RESPONSE(1): response // 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_pack(const void * src, int srcsz, void * buffer, int bufsz);
int sproto_unpack(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); 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_decode(const 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_encode(const struct sproto_type *, void * buffer, int size, sproto_callback cb, void *ud);
// for debug use // for debug use
void sproto_dump(struct sproto *); void sproto_dump(struct sproto *);

View File

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

View File

@@ -16,6 +16,8 @@ local function request(fd, method, host, url, recvheader, header, content)
end end
if header.host then if header.host then
host = "" host = ""
else
host = string.format("host:%s\r\n", host)
end end
else else
host = string.format("host:%s\r\n",host) host = string.format("host:%s\r\n",host)

View File

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

View File

@@ -398,6 +398,7 @@ skynet.pack = assert(c.pack)
skynet.packstring = assert(c.packstring) skynet.packstring = assert(c.packstring)
skynet.unpack = assert(c.unpack) skynet.unpack = assert(c.unpack)
skynet.tostring = assert(c.tostring) skynet.tostring = assert(c.tostring)
skynet.trash = assert(c.trash)
local function yield_call(service, session) local function yield_call(service, session)
watching_session[session] = service watching_session[session] = service

View File

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

View File

@@ -13,14 +13,23 @@ function sproto_mt:__gc()
core.deleteproto(self.__cobj) core.deleteproto(self.__cobj)
end end
function sproto.new(bin,sz,nogc) function sproto.new(bin)
local cobj = assert(core.newproto(bin,sz)) local cobj = assert(core.newproto(bin))
local self = { local self = {
__cobj = cobj, __cobj = cobj,
__tcache = setmetatable( {} , weak_mt ), __tcache = setmetatable( {} , weak_mt ),
__pcache = 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 end
function sproto.parse(ptext) function sproto.parse(ptext)

View File

@@ -8,16 +8,19 @@ function loader.register(filename, index)
local f = assert(io.open(filename), "Can't open sproto file") local f = assert(io.open(filename), "Can't open sproto file")
local data = f:read "a" local data = f:read "a"
f:close() f:close()
local bin = parser.parse(data) local sp = core.newproto(parser.parse(data))
core.saveproto(bin, index) core.saveproto(sp, index)
end end
loader.save = core.saveproto function loader.save(bin, index)
local sp = core.newproto(bin)
core.saveproto(sp, index)
end
function loader.load(index) function loader.load(index)
local bin, sz = core.loadproto(index) local sp = core.loadproto(index)
-- no __gc in metatable -- no __gc in metatable
return sproto.new(bin,sz, true) return sproto.sharenew(sp)
end end
return loader return loader

View File

@@ -1,5 +1,5 @@
#ifndef __MALLOC_HOOK_H #ifndef SKYNET_MALLOC_HOOK_H
#define __MALLOC_HOOK_H #define SKYNET_MALLOC_HOOK_H
#include <stdlib.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 int mallctl_opt(const char* name, int* newval);
extern void dump_c_mem(void); extern void dump_c_mem(void);
#endif /* __MALLOC_HOOK_H */ #endif /* SKYNET_MALLOC_HOOK_H */

View File

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

View File

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