Compare commits

...

9 Commits

Author SHA1 Message Date
Cloud Wu
8b7ba7bdbe add testresponse 2014-09-01 11:17:16 +08:00
Cloud Wu
165bed46a8 only skynet.call response error 2014-08-27 18:54:46 +08:00
云风
9bb8099008 Merge pull request #160 from cloudwu/dev
release v0.6.1
2014-08-25 10:15:34 +08:00
Cloud Wu
98630badd5 update history for release v0.6.1 2014-08-25 10:13:04 +08:00
Cloud Wu
d0c4a4012a clear socket when connect failed 2014-08-22 15:41:05 +08:00
Cloud Wu
04688e98a7 improve seri lib 2014-08-20 23:34:23 +08:00
Cloud Wu
e0feea9995 fix issue #156 2014-08-19 23:44:07 +08:00
Cloud Wu
55ea556060 avoid issue #154 2014-08-19 23:26:42 +08:00
Cloud Wu
4803e50977 fix error log 2014-08-19 20:52:43 +08:00
8 changed files with 158 additions and 195 deletions

View File

@@ -1,3 +1,13 @@
v0.6.2 (2014-9-1)
-----------
* bugfix: only skynet.call response PTYPE_ERROR
v0.6.1 (2014-8-25)
-----------
* bugfix: datacenter.wakeup
* change struct msg name to avoid conflict in mac
* improve seri library
v0.6.0 (2014-8-18) v0.6.0 (2014-8-18)
----------- -----------
* add sharedata * add sharedata

View File

@@ -589,11 +589,11 @@ read64(lua_State *L, uint32_t xx[2], uint32_t yy[2]) {
size_t sz = 0; size_t sz = 0;
const uint8_t *x = (const uint8_t *)luaL_checklstring(L, 1, &sz); const uint8_t *x = (const uint8_t *)luaL_checklstring(L, 1, &sz);
if (sz != 8) { if (sz != 8) {
luaL_error(L, "Invalid hmac x"); luaL_error(L, "Invalid uint64 x");
} }
const uint8_t *y = (const uint8_t *)luaL_checklstring(L, 2, &sz); const uint8_t *y = (const uint8_t *)luaL_checklstring(L, 2, &sz);
if (sz != 8) { if (sz != 8) {
luaL_error(L, "Invalid hmac y"); luaL_error(L, "Invalid uint64 y");
} }
xx[0] = x[0] | x[1]<<8 | x[2]<<16 | x[3]<<24; xx[0] = x[0] | x[1]<<8 | x[2]<<16 | x[3]<<24;
xx[1] = x[4] | x[5]<<8 | x[6]<<16 | x[7]<<24; xx[1] = x[4] | x[5]<<8 | x[6]<<16 | x[7]<<24;
@@ -703,7 +703,7 @@ ldhexchange(lua_State *L) {
size_t sz = 0; size_t sz = 0;
const uint8_t *x = (const uint8_t *)luaL_checklstring(L, 1, &sz); const uint8_t *x = (const uint8_t *)luaL_checklstring(L, 1, &sz);
if (sz != 8) { if (sz != 8) {
luaL_error(L, "Invalid hmac x"); luaL_error(L, "Invalid dh uint64 key");
} }
uint32_t xx[2]; uint32_t xx[2];
xx[0] = x[0] | x[1]<<8 | x[2]<<16 | x[3]<<24; xx[0] = x[0] | x[1]<<8 | x[2]<<16 | x[3]<<24;

View File

@@ -1,5 +1,5 @@
/* /*
https://github.com/cloudwu/lua-serialize modify from https://github.com/cloudwu/lua-serialize
*/ */
#include "skynet_malloc.h" #include "skynet_malloc.h"
@@ -35,14 +35,13 @@ struct block {
struct write_block { struct write_block {
struct block * head; struct block * head;
int len;
struct block * current; struct block * current;
int len;
int ptr; int ptr;
}; };
struct read_block { struct read_block {
char * buffer; char * buffer;
struct block * current;
int len; int len;
int ptr; int ptr;
}; };
@@ -78,38 +77,17 @@ _again:
static void static void
wb_init(struct write_block *wb , struct block *b) { wb_init(struct write_block *wb , struct block *b) {
if (b==NULL) { wb->head = b;
wb->head = blk_alloc(); assert(b->next == NULL);
wb->len = 0; wb->len = 0;
wb->current = wb->head; wb->current = wb->head;
wb->ptr = 0; wb->ptr = 0;
wb_push(wb, &wb->len, sizeof(wb->len));
} else {
wb->head = b;
int * plen = (int *)b->buffer;
int sz = *plen;
wb->len = sz;
while (b->next) {
sz -= BLOCK_SIZE;
b = b->next;
}
wb->current = b;
wb->ptr = sz;
}
}
static struct block *
wb_close(struct write_block *b) {
b->current = b->head;
b->ptr = 0;
wb_push(b, &b->len, sizeof(b->len));
b->current = NULL;
return b->head;
} }
static void static void
wb_free(struct write_block *wb) { wb_free(struct write_block *wb) {
struct block *blk = wb->head; struct block *blk = wb->head;
blk = blk->next; // the first block is on stack
while (blk) { while (blk) {
struct block * next = blk->next; struct block * next = blk->next;
skynet_free(blk); skynet_free(blk);
@@ -124,7 +102,6 @@ wb_free(struct write_block *wb) {
static void static void
rball_init(struct read_block * rb, char * buffer, int size) { rball_init(struct read_block * rb, char * buffer, int size) {
rb->buffer = buffer; rb->buffer = buffer;
rb->current = NULL;
rb->len = size; rb->len = size;
rb->ptr = 0; rb->ptr = 0;
} }
@@ -135,65 +112,12 @@ rb_read(struct read_block *rb, void *buffer, int sz) {
return NULL; return NULL;
} }
if (rb->buffer) {
int ptr = rb->ptr; int ptr = rb->ptr;
rb->ptr += sz; rb->ptr += sz;
rb->len -= sz; rb->len -= sz;
return rb->buffer + ptr; return rb->buffer + ptr;
} }
if (rb->ptr == BLOCK_SIZE) {
struct block * next = rb->current->next;
skynet_free(rb->current);
rb->current = next;
rb->ptr = 0;
}
int copy = BLOCK_SIZE - rb->ptr;
if (sz <= copy) {
void * ret = rb->current->buffer + rb->ptr;
rb->ptr += sz;
rb->len -= sz;
return ret;
}
char * tmp = buffer;
memcpy(tmp, rb->current->buffer + rb->ptr, copy);
sz -= copy;
tmp += copy;
rb->len -= copy;
for (;;) {
struct block * next = rb->current->next;
skynet_free(rb->current);
rb->current = next;
if (sz < BLOCK_SIZE) {
memcpy(tmp, rb->current->buffer, sz);
rb->ptr = sz;
rb->len -= sz;
return buffer;
}
memcpy(tmp, rb->current->buffer, BLOCK_SIZE);
sz -= BLOCK_SIZE;
tmp += BLOCK_SIZE;
rb->len -= BLOCK_SIZE;
}
}
static void
rb_close(struct read_block *rb) {
while (rb->current) {
struct block * next = rb->current->next;
skynet_free(rb->current);
rb->current = next;
}
rb->len = 0;
rb->ptr = 0;
}
static inline void static inline void
wb_nil(struct write_block *wb) { wb_nil(struct write_block *wb) {
int n = TYPE_NIL; int n = TYPE_NIL;
@@ -271,7 +195,7 @@ wb_string(struct write_block *wb, const char *str, int len) {
} }
} }
static void _pack_one(lua_State *L, struct write_block *b, int index, int depth); static void pack_one(lua_State *L, struct write_block *b, int index, int depth);
static int static int
wb_table_array(lua_State *L, struct write_block * wb, int index, int depth) { wb_table_array(lua_State *L, struct write_block * wb, int index, int depth) {
@@ -288,7 +212,7 @@ wb_table_array(lua_State *L, struct write_block * wb, int index, int depth) {
int i; int i;
for (i=1;i<=array_size;i++) { for (i=1;i<=array_size;i++) {
lua_rawgeti(L,index,i); lua_rawgeti(L,index,i);
_pack_one(L, wb, -1, depth); pack_one(L, wb, -1, depth);
lua_pop(L,1); lua_pop(L,1);
} }
@@ -307,8 +231,8 @@ wb_table_hash(lua_State *L, struct write_block * wb, int index, int depth, int a
continue; continue;
} }
} }
_pack_one(L,wb,-2,depth); pack_one(L,wb,-2,depth);
_pack_one(L,wb,-1,depth); pack_one(L,wb,-1,depth);
lua_pop(L, 1); lua_pop(L, 1);
} }
wb_nil(wb); wb_nil(wb);
@@ -324,7 +248,7 @@ wb_table(lua_State *L, struct write_block *wb, int index, int depth) {
} }
static void static void
_pack_one(lua_State *L, struct write_block *b, int index, int depth) { pack_one(lua_State *L, struct write_block *b, int index, int depth) {
if (depth > MAX_DEPTH) { if (depth > MAX_DEPTH) {
wb_free(b); wb_free(b);
luaL_error(L, "serialize can't pack too depth table"); luaL_error(L, "serialize can't pack too depth table");
@@ -370,27 +294,24 @@ _pack_one(lua_State *L, struct write_block *b, int index, int depth) {
} }
static void static void
_pack_from(lua_State *L, struct write_block *b, int from) { pack_from(lua_State *L, struct write_block *b, int from) {
int n = lua_gettop(L) - from; int n = lua_gettop(L) - from;
int i; int i;
for (i=1;i<=n;i++) { for (i=1;i<=n;i++) {
_pack_one(L, b , from + i, 0); pack_one(L, b , from + i, 0);
} }
} }
static inline void static inline void
__invalid_stream(lua_State *L, struct read_block *rb, int line) { invalid_stream_line(lua_State *L, struct read_block *rb, int line) {
int len = rb->len; int len = rb->len;
if (rb->buffer == NULL) {
rb_close(rb);
}
luaL_error(L, "Invalid serialize stream %d (line:%d)", len, line); luaL_error(L, "Invalid serialize stream %d (line:%d)", len, line);
} }
#define _invalid_stream(L,rb) __invalid_stream(L,rb,__LINE__) #define invalid_stream(L,rb) invalid_stream_line(L,rb,__LINE__)
static int static int
_get_integer(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;
@@ -398,93 +319,93 @@ _get_integer(lua_State *L, struct read_block *rb, int cookie) {
uint8_t n = 0; uint8_t n = 0;
uint8_t * pn = rb_read(rb,&n,1); uint8_t * pn = rb_read(rb,&n,1);
if (pn == NULL) if (pn == NULL)
_invalid_stream(L,rb); invalid_stream(L,rb);
return *pn; return *pn;
} }
case 2: { case 2: {
uint16_t n = 0; uint16_t n = 0;
uint16_t * pn = rb_read(rb,&n,2); uint16_t * pn = rb_read(rb,&n,2);
if (pn == NULL) if (pn == NULL)
_invalid_stream(L,rb); invalid_stream(L,rb);
return *pn; return *pn;
} }
case 4: { case 4: {
int n = 0; int n = 0;
int * pn = rb_read(rb,&n,4); int * pn = rb_read(rb,&n,4);
if (pn == NULL) if (pn == NULL)
_invalid_stream(L,rb); invalid_stream(L,rb);
return *pn; return *pn;
} }
default: default:
_invalid_stream(L,rb); invalid_stream(L,rb);
return 0; return 0;
} }
} }
static double static double
_get_number(lua_State *L, struct read_block *rb, int cookie) { get_number(lua_State *L, struct read_block *rb, int cookie) {
if (cookie == 8) { 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 { } else {
return (double)_get_integer(L,rb,cookie); return (double)get_integer(L,rb,cookie);
} }
} }
static void * static void *
_get_pointer(lua_State *L, struct read_block *rb) { get_pointer(lua_State *L, struct read_block *rb) {
void * userdata = 0; void * userdata = 0;
void ** v = (void **)rb_read(rb,&userdata,sizeof(userdata)); void ** v = (void **)rb_read(rb,&userdata,sizeof(userdata));
if (v == NULL) { if (v == NULL) {
_invalid_stream(L,rb); invalid_stream(L,rb);
} }
return *v; return *v;
} }
static void static void
_get_buffer(lua_State *L, struct read_block *rb, int len) { get_buffer(lua_State *L, struct read_block *rb, int len) {
char tmp[len]; char tmp[len];
char * p = rb_read(rb,tmp,len); char * p = rb_read(rb,tmp,len);
if (p == NULL) { if (p == NULL) {
_invalid_stream(L,rb); invalid_stream(L,rb);
} }
lua_pushlstring(L,p,len); lua_pushlstring(L,p,len);
} }
static void _unpack_one(lua_State *L, struct read_block *rb); static void unpack_one(lua_State *L, struct read_block *rb);
static void static void
_unpack_table(lua_State *L, struct read_block *rb, int array_size) { unpack_table(lua_State *L, struct read_block *rb, int array_size) {
if (array_size == MAX_COOKIE-1) { if (array_size == MAX_COOKIE-1) {
uint8_t type = 0; uint8_t type = 0;
uint8_t *t = rb_read(rb, &type, 1); uint8_t *t = rb_read(rb, &type, 1);
if (t==NULL || (*t & 7) != TYPE_NUMBER) { if (t==NULL || (*t & 7) != TYPE_NUMBER) {
_invalid_stream(L,rb); invalid_stream(L,rb);
} }
array_size = (int)_get_number(L,rb,*t >> 3); array_size = (int)get_number(L,rb,*t >> 3);
} }
lua_createtable(L,array_size,0); lua_createtable(L,array_size,0);
int i; int i;
for (i=1;i<=array_size;i++) { for (i=1;i<=array_size;i++) {
_unpack_one(L,rb); unpack_one(L,rb);
lua_rawseti(L,-2,i); lua_rawseti(L,-2,i);
} }
for (;;) { for (;;) {
_unpack_one(L,rb); unpack_one(L,rb);
if (lua_isnil(L,-1)) { if (lua_isnil(L,-1)) {
lua_pop(L,1); lua_pop(L,1);
return; return;
} }
_unpack_one(L,rb); unpack_one(L,rb);
lua_rawset(L,-3); lua_rawset(L,-3);
} }
} }
static void static void
_push_value(lua_State *L, struct read_block *rb, int type, int cookie) { push_value(lua_State *L, struct read_block *rb, int type, int cookie) {
switch(type) { switch(type) {
case TYPE_NIL: case TYPE_NIL:
lua_pushnil(L); lua_pushnil(L);
@@ -493,83 +414,70 @@ _push_value(lua_State *L, struct read_block *rb, int type, int cookie) {
lua_pushboolean(L,cookie); lua_pushboolean(L,cookie);
break; break;
case TYPE_NUMBER: case TYPE_NUMBER:
lua_pushnumber(L,_get_number(L,rb,cookie)); lua_pushnumber(L,get_number(L,rb,cookie));
break; break;
case TYPE_USERDATA: case TYPE_USERDATA:
lua_pushlightuserdata(L,_get_pointer(L,rb)); lua_pushlightuserdata(L,get_pointer(L,rb));
break; break;
case TYPE_SHORT_STRING: case TYPE_SHORT_STRING:
_get_buffer(L,rb,cookie); get_buffer(L,rb,cookie);
break; break;
case TYPE_LONG_STRING: { case TYPE_LONG_STRING: {
uint32_t len; uint32_t len;
if (cookie == 2) { if (cookie == 2) {
uint16_t *plen = rb_read(rb, &len, 2); uint16_t *plen = rb_read(rb, &len, 2);
if (plen == NULL) { if (plen == NULL) {
_invalid_stream(L,rb); invalid_stream(L,rb);
} }
_get_buffer(L,rb,(int)*plen); get_buffer(L,rb,(int)*plen);
} else { } else {
if (cookie != 4) { if (cookie != 4) {
_invalid_stream(L,rb); invalid_stream(L,rb);
} }
uint32_t *plen = rb_read(rb, &len, 4); uint32_t *plen = rb_read(rb, &len, 4);
if (plen == NULL) { if (plen == NULL) {
_invalid_stream(L,rb); invalid_stream(L,rb);
} }
_get_buffer(L,rb,(int)*plen); get_buffer(L,rb,(int)*plen);
} }
break; break;
} }
case TYPE_TABLE: { case TYPE_TABLE: {
_unpack_table(L,rb,cookie); unpack_table(L,rb,cookie);
break; break;
} }
default: { default: {
_invalid_stream(L,rb); invalid_stream(L,rb);
break; break;
} }
} }
} }
static void static void
_unpack_one(lua_State *L, struct read_block *rb) { unpack_one(lua_State *L, struct read_block *rb) {
uint8_t type = 0; uint8_t type = 0;
uint8_t *t = rb_read(rb, &type, 1); uint8_t *t = rb_read(rb, &type, 1);
if (t==NULL) { if (t==NULL) {
_invalid_stream(L, rb); invalid_stream(L, rb);
} }
_push_value(L, rb, *t & 0x7, *t>>3); push_value(L, rb, *t & 0x7, *t>>3);
} }
static void static void
_seri(lua_State *L, struct block *b) { seri(lua_State *L, struct block *b, int len) {
uint32_t len = 0;
memcpy(&len, b->buffer ,sizeof(len));
len -= 4;
uint8_t * buffer = skynet_malloc(len); uint8_t * buffer = skynet_malloc(len);
uint8_t * ptr = buffer; uint8_t * ptr = buffer;
int sz = len; int sz = len;
if (len < BLOCK_SIZE - 4) {
memcpy(ptr, b->buffer+4, len);
} else {
memcpy(ptr, b->buffer+4, BLOCK_SIZE-4);
ptr += BLOCK_SIZE-4;
len -= BLOCK_SIZE-4;
b = b->next;
while(len>0) { while(len>0) {
if (len >= BLOCK_SIZE) { if (len >= BLOCK_SIZE) {
memcpy(ptr, b->buffer, BLOCK_SIZE); memcpy(ptr, b->buffer, BLOCK_SIZE);
ptr += BLOCK_SIZE; ptr += BLOCK_SIZE;
len -= BLOCK_SIZE; len -= BLOCK_SIZE;
b = b->next;
} else { } else {
memcpy(ptr, b->buffer, len); memcpy(ptr, b->buffer, len);
break; break;
} }
b = b->next;
}
} }
lua_pushlightuserdata(L, buffer); lua_pushlightuserdata(L, buffer);
@@ -611,7 +519,7 @@ _luaseri_unpack(lua_State *L) {
uint8_t *t = rb_read(&rb, &type, 1); uint8_t *t = rb_read(&rb, &type, 1);
if (t==NULL) if (t==NULL)
break; break;
_push_value(L, &rb, *t & 0x7, *t>>3); push_value(L, &rb, *t & 0x7, *t>>3);
} }
// Need not free buffer // Need not free buffer
@@ -621,17 +529,15 @@ _luaseri_unpack(lua_State *L) {
int int
_luaseri_pack(lua_State *L) { _luaseri_pack(lua_State *L) {
struct block temp;
temp.next = NULL;
struct write_block wb; struct write_block wb;
wb_init(&wb, NULL); wb_init(&wb, &temp);
_pack_from(L,&wb,0); pack_from(L,&wb,0);
struct block * b = wb_close(&wb); assert(wb.head == &temp);
_seri(L,b); seri(L, &temp, wb.len);
while (b) { wb_free(&wb);
struct block * next = b->next;
skynet_free(b);
b = next;
}
return 2; return 2;
} }

View File

@@ -144,7 +144,8 @@ function suspend(co, result, command, param, size)
if not result then if not result then
local session = session_coroutine_id[co] local session = session_coroutine_id[co]
local addr = session_coroutine_address[co] local addr = session_coroutine_address[co]
if session then if session ~= 0 then
-- only call response error
c.send(addr, skynet.PTYPE_ERROR, session, "") c.send(addr, skynet.PTYPE_ERROR, session, "")
end end
session_coroutine_id[co] = nil session_coroutine_id[co] = nil

View File

@@ -145,6 +145,8 @@ local function connect(id, func)
suspend(s) suspend(s)
if s.connected then if s.connected then
return id return id
else
socket_pool[id] = nil
end end
end end

View File

@@ -36,17 +36,17 @@ struct remote_message_header {
uint32_t session; uint32_t session;
}; };
struct msg { struct harbor_msg {
struct remote_message_header header; struct remote_message_header header;
void * buffer; void * buffer;
size_t size; size_t size;
}; };
struct msg_queue { struct harbor_msg_queue {
int size; int size;
int head; int head;
int tail; int tail;
struct msg * data; struct harbor_msg * data;
}; };
struct keyvalue { struct keyvalue {
@@ -54,7 +54,7 @@ struct keyvalue {
char key[GLOBALNAME_LENGTH]; char key[GLOBALNAME_LENGTH];
uint32_t hash; uint32_t hash;
uint32_t value; uint32_t value;
struct msg_queue * queue; struct harbor_msg_queue * queue;
}; };
struct hashmap { struct hashmap {
@@ -69,7 +69,7 @@ struct hashmap {
struct slave { struct slave {
int fd; int fd;
struct msg_queue *queue; struct harbor_msg_queue *queue;
int status; int status;
int length; int length;
int read; int read;
@@ -88,11 +88,11 @@ struct harbor {
// hash table // hash table
static void static void
push_queue_msg(struct msg_queue * queue, struct msg * m) { push_queue_msg(struct harbor_msg_queue * queue, struct harbor_msg * m) {
// If there is only 1 free slot which is reserved to distinguish full/empty // If there is only 1 free slot which is reserved to distinguish full/empty
// of circular buffer, expand it. // of circular buffer, expand it.
if (((queue->tail + 1) % queue->size) == queue->head) { if (((queue->tail + 1) % queue->size) == queue->head) {
struct msg * new_buffer = skynet_malloc(queue->size * 2 * sizeof(struct msg)); struct harbor_msg * new_buffer = skynet_malloc(queue->size * 2 * sizeof(struct harbor_msg));
int i; int i;
for (i=0;i<queue->size-1;i++) { for (i=0;i<queue->size-1;i++) {
new_buffer[i] = queue->data[(i+queue->head) % queue->size]; new_buffer[i] = queue->data[(i+queue->head) % queue->size];
@@ -103,46 +103,46 @@ push_queue_msg(struct msg_queue * queue, struct msg * m) {
queue->tail = queue->size - 1; queue->tail = queue->size - 1;
queue->size *= 2; queue->size *= 2;
} }
struct msg * slot = &queue->data[queue->tail]; struct harbor_msg * slot = &queue->data[queue->tail];
*slot = *m; *slot = *m;
queue->tail = (queue->tail + 1) % queue->size; queue->tail = (queue->tail + 1) % queue->size;
} }
static void static void
push_queue(struct msg_queue * queue, void * buffer, size_t sz, struct remote_message_header * header) { push_queue(struct harbor_msg_queue * queue, void * buffer, size_t sz, struct remote_message_header * header) {
struct msg m; struct harbor_msg m;
m.header = *header; m.header = *header;
m.buffer = buffer; m.buffer = buffer;
m.size = sz; m.size = sz;
push_queue_msg(queue, &m); push_queue_msg(queue, &m);
} }
static struct msg * static struct harbor_msg *
pop_queue(struct msg_queue * queue) { pop_queue(struct harbor_msg_queue * queue) {
if (queue->head == queue->tail) { if (queue->head == queue->tail) {
return NULL; return NULL;
} }
struct msg * slot = &queue->data[queue->head]; struct harbor_msg * slot = &queue->data[queue->head];
queue->head = (queue->head + 1) % queue->size; queue->head = (queue->head + 1) % queue->size;
return slot; return slot;
} }
static struct msg_queue * static struct harbor_msg_queue *
new_queue() { new_queue() {
struct msg_queue * queue = skynet_malloc(sizeof(*queue)); struct harbor_msg_queue * queue = skynet_malloc(sizeof(*queue));
queue->size = DEFAULT_QUEUE_SIZE; queue->size = DEFAULT_QUEUE_SIZE;
queue->head = 0; queue->head = 0;
queue->tail = 0; queue->tail = 0;
queue->data = skynet_malloc(DEFAULT_QUEUE_SIZE * sizeof(struct msg)); queue->data = skynet_malloc(DEFAULT_QUEUE_SIZE * sizeof(struct harbor_msg));
return queue; return queue;
} }
static void static void
release_queue(struct msg_queue *queue) { release_queue(struct harbor_msg_queue *queue) {
if (queue == NULL) if (queue == NULL)
return; return;
struct msg * m; struct harbor_msg * m;
while ((m=pop_queue(queue)) != NULL) { while ((m=pop_queue(queue)) != NULL) {
skynet_free(m->buffer); skynet_free(m->buffer);
} }
@@ -334,7 +334,7 @@ send_remote(struct skynet_context * ctx, int fd, const char * buffer, size_t sz,
static void static void
dispatch_name_queue(struct harbor *h, struct keyvalue * node) { dispatch_name_queue(struct harbor *h, struct keyvalue * node) {
struct msg_queue * queue = node->queue; struct harbor_msg_queue * queue = node->queue;
uint32_t handle = node->value; uint32_t handle = node->value;
int harbor_id = handle >> HANDLE_REMOTE_SHIFT; int harbor_id = handle >> HANDLE_REMOTE_SHIFT;
assert(harbor_id != 0); assert(harbor_id != 0);
@@ -352,7 +352,7 @@ dispatch_name_queue(struct harbor *h, struct keyvalue * node) {
s->queue = node->queue; s->queue = node->queue;
node->queue = NULL; node->queue = NULL;
} else { } else {
struct msg * m; struct harbor_msg * m;
while ((m = pop_queue(queue))!=NULL) { while ((m = pop_queue(queue))!=NULL) {
push_queue_msg(s->queue, m); push_queue_msg(s->queue, m);
} }
@@ -360,7 +360,7 @@ dispatch_name_queue(struct harbor *h, struct keyvalue * node) {
} }
return; return;
} }
struct msg * m; struct harbor_msg * m;
while ((m = pop_queue(queue)) != NULL) { while ((m = pop_queue(queue)) != NULL) {
m->header.destination |= (handle & HANDLE_MASK); m->header.destination |= (handle & HANDLE_MASK);
send_remote(context, fd, m->buffer, m->size, &m->header); send_remote(context, fd, m->buffer, m->size, &m->header);
@@ -373,11 +373,11 @@ dispatch_queue(struct harbor *h, int id) {
int fd = s->fd; int fd = s->fd;
assert(fd != 0); assert(fd != 0);
struct msg_queue *queue = s->queue; struct harbor_msg_queue *queue = s->queue;
if (queue == NULL) if (queue == NULL)
return; return;
struct msg * m; struct harbor_msg * m;
while ((m = pop_queue(queue)) != NULL) { while ((m = pop_queue(queue)) != NULL) {
send_remote(h->ctx, fd, m->buffer, m->size, &m->header); send_remote(h->ctx, fd, m->buffer, m->size, &m->header);
} }

View File

@@ -33,7 +33,7 @@ local function update(db, key, value, ...)
end end
end end
local function wakeup(db, key1, key2, value, ...) local function wakeup(db, key1, key2, ...)
if key1 == nil then if key1 == nil then
return return
end end
@@ -43,7 +43,7 @@ local function wakeup(db, key1, key2, value, ...)
end end
if q[mode] == "queue" then if q[mode] == "queue" then
db[key1] = nil db[key1] = nil
if value then if key2 then
-- throw error because can't wake up a branch -- throw error because can't wake up a branch
for _,response in ipairs(q) do for _,response in ipairs(q) do
response(false) response(false)
@@ -53,7 +53,7 @@ local function wakeup(db, key1, key2, value, ...)
end end
else else
-- it's branch -- it's branch
return wakeup(q , key2, value, ...) return wakeup(q , key2, ...)
end end
end end

44
test/testresponse.lua Normal file
View File

@@ -0,0 +1,44 @@
local skynet = require "skynet"
local mode = ...
if mode == "TICK" then
-- this service whould response the request every 1s.
local response_queue = {}
local function response()
while true do
skynet.sleep(100) -- sleep 1s
for k,v in ipairs(response_queue) do
v(true, skynet.now()) -- true means succ, false means error
response_queue[k] = nil
end
end
end
skynet.start(function()
skynet.fork(response)
skynet.dispatch("lua", function()
table.insert(response_queue, skynet.response())
end)
end)
else
local function request(tick, i)
print(i, "call", skynet.now())
print(i, "response", skynet.call(tick, "lua"))
print(i, "end", skynet.now())
end
skynet.start(function()
local tick = skynet.newservice(SERVICE_NAME, "TICK")
for i=1,5 do
skynet.fork(request, tick, i)
skynet.sleep(10)
end
end)
end